Repository: neovim/neovim
Pull request #33524: docs: make it more beginner-friendly
Author: login: brianhuster
Labels: name: documentation
name: defaults
description: Nvim defaults for options, colorscheme/theme, autocmds/events, etc.
name: ux
description: user experience
Created: 2025-04-18T03:28:41Z | Merged: 2025-04-27T15:11:02Z

Solution:
- Add `example_init.lua` and refer to it in `:h lua-guide-config`
- Refer to `lsp` in `:h nvim-quickstart`

I would like to give credit to [kickstart.nvim](https://github.com/nvim-lua/kickstart.nvim) for inspiration

Questions:
- Should I move lesson 7.2 to `nvim-quickstart`? The reason Vim puts it there (and before Lesson 7.3: Completion) is that Vim is in Vi-compatible mode by default, where many Vim features are disabled, including `cmdline-completion`. But if Vim detects a `vimrc` file, Vi-compatible will be disabled.
- Should there be an `example_init.vim`?
- Should I mention the plugin `nvim-lspconfig` in `lsp.txt`?

<!--
  Thank you for contributing to Neovim!
  If this is your first time, check out https://github.com/neovim/neovim/blob/master/CONTRIBUTING.md#pull-requests-prs
  for our PR guidelines.
-->



Diff:
diff --git a/runtime/doc/lua-guide.txt b/runtime/doc/lua-guide.txt
index 54e3eec70097a0..ce6766f6fa030f 100644
--- a/runtime/doc/lua-guide.txt
+++ b/runtime/doc/lua-guide.txt
@@ -93,10 +93,9 @@ Finally, you can include Lua code in a Vimscript file by putting it inside a
 Using Lua files on startup                                    *lua-guide-config*
 
 Nvim supports using `init.vim` or `init.lua` as the configuration file, but
-not both at the same time. This should be placed in your |config| directory,
-which is typically `~/.config/nvim` for Linux, BSD, or macOS, and
-`~/AppData/Local/nvim/` for Windows. Note that you can use Lua in `init.vim`
-and Vimscript in `init.lua`, which will be covered below.
+not both at the same time. This should be placed in your |config| directory
+(run `:echo stdpath('config')` to see where it is). Note that you can also use
+Lua in `init.vim` and Vimscript in `init.lua`, which will be covered below.
 
 If you'd like to run any other Lua script on |startup| automatically, then you
 can simply put it in `plugin/` in your |'runtimepath'|.
diff --git a/runtime/doc/nvim.txt b/runtime/doc/nvim.txt
index 9065fba701ac89..8189cad7c1d0a1 100644
--- a/runtime/doc/nvim.txt
+++ b/runtime/doc/nvim.txt
@@ -75,8 +75,16 @@ the same Nvim configuration on all of your machines, by creating
 ==============================================================================
 What next?                                                   *nvim-quickstart*
 
+If you want to use Lua to configure Nvim, you can copy an example
+configuration to your |init.lua|
+>vim
+    :exe 'edit' stdpath('config') .. '/init.lua'
+    :read $VIMRUNTIME/example_init.lua
+<
 See |lua-guide| for practical notes on using Lua to configure Nvim.
 
+"IDE" features in Nvim are provided by Language Server Protocol. See |lsp|
+
 If you are just trying out Nvim for a few minutes, and want to see the
 extremes of what it can do, try one of these popular "extension packs" or
 "distributions" (Note: Nvim is not affiliated with these projects, and does
diff --git a/runtime/example_init.lua b/runtime/example_init.lua
new file mode 100644
index 00000000000000..5a55ea8346039f
--- /dev/null
+++ b/runtime/example_init.lua
@@ -0,0 +1,88 @@
+-- Set <space> as the leader key
+-- See `:help mapleader`
+-- NOTE: Must happen before plugins are loaded (otherwise wrong leader will be used)
+vim.g.mapleader = ' '
+
+-- [[ Setting options ]] See `:h vim.o`
+-- NOTE: You can change these options as you wish!
+-- For more options, you can see `:help option-list`
+-- To see documentation for an option, you can use `:h 'optionname'`, for example `:h 'number'`
+-- (Note the single quotes)
+
+-- Print the line number in front of each line
+vim.o.number = true
+
+-- Use relative line numbers, so that it is easier to jump with j, k. This will affect the 'number'
+-- option above, see `:h number_relativenumber`
+vim.o.relativenumber = true
+
+-- Sync clipboard between OS and Neovim. Schedule the setting after `UiEnter` because it can
+-- increase startup-time. Remove this option if you want your OS clipboard to remain independent.
+-- See `:help 'clipboard'`
+vim.api.nvim_create_autocmd('UIEnter', {
+  callback = function()
+    vim.o.clipboard = 'unnamedplus'
+  end,
+})
+
+-- Case-insensitive searching UNLESS \C or one or more capital letters in the search term
+vim.o.ignorecase = true
+vim.o.smartcase = true
+
+-- Highlight the line where the cursor is on
+vim.o.cursorline = true
+
+-- Minimal number of screen lines to keep above and below the cursor.
+vim.o.scrolloff = 10
+
+-- Show <tab> and trailing spaces
+vim.o.list = true
+
+-- if performing an operation that would fail due to unsaved changes in the buffer (like `:q`),
+-- instead raise a dialog asking if you wish to save the current file(s) See `:help 'confirm'`
+vim.o.confirm = true
+
+-- [[ Set up keymaps ]] See `:h vim.keymap.set()`, `:h mapping`, `:h keycodes`
+
+-- Use <Esc> to exit terminal mode
+vim.keymap.set('t', '<Esc>', '<C-\\><C-n>')
+
+-- Map <A-j>, <A-k>, <A-h>, <A-l> to navigate between windows in any modes
+vim.keymap.set({ 't', 'i' }, '<A-h>', '<C-\\><C-n><C-w>h')
+vim.keymap.set({ 't', 'i' }, '<A-j>', '<C-\\><C-n><C-w>j')
+vim.keymap.set({ 't', 'i' }, '<A-k>', '<C-\\><C-n><C-w>k')
+vim.keymap.set({ 't', 'i' }, '<A-l>', '<C-\\><C-n><C-w>l')
+vim.keymap.set({ 'n' }, '<A-h>', '<C-w>h')
+vim.keymap.set({ 'n' }, '<A-j>', '<C-w>j')
+vim.keymap.set({ 'n' }, '<A-k>', '<C-w>k')
+vim.keymap.set({ 'n' }, '<A-l>', '<C-w>l')
+
+-- [[ Basic Autocommands ]].
+-- See `:h lua-guide-autocommands`, `:h autocmd`, `:h nvim_create_autocmd()`
+
+-- Highlight when yanking (copying) text.
+-- Try it with `yap` in normal mode. See `:h vim.hl.on_yank()`
+vim.api.nvim_create_autocmd('TextYankPost', {
+  desc = 'Highlight when yanking (copying) text',
+  callback = function()
+    vim.hl.on_yank()
+  end,
+})
+
+-- [[ Create user commands ]]
+-- See `:h nvim_create_user_command()` and `:h user-commands`
+
+-- Create a command `:GitBlameLine` that print the git blame for the current line
+vim.api.nvim_create_user_command('GitBlameLine', function()
+  local line_number = vim.fn.line('.') -- Get the current line number. See `:h line()`
+  local filename = vim.api.nvim_buf_get_name(0)
+  print(vim.fn.system({ 'git', 'blame', '-L', line_number .. ',+1', filename }))
+end, { desc = 'Print the git blame for the current line' })
+
+-- [[ Add optional packages ]]
+-- Nvim comes bundled with a set of packages that are not enabled by
+-- default. You can enable any of them by using the `:packadd` command.
+
+-- For example, to add the "nohlsearch" package to automatically turn off search highlighting after
+-- 'updatetime' and when going to insert mode
+vim.cmd('packadd! nohlsearch')
diff --git a/runtime/tutor/en/vim-01-beginner.tutor b/runtime/tutor/en/vim-01-beginner.tutor
index b2d17e1713078e..18be5ce9a0c916 100644
--- a/runtime/tutor/en/vim-01-beginner.tutor
+++ b/runtime/tutor/en/vim-01-beginner.tutor
@@ -967,6 +967,10 @@ NOTE: Completion works for many commands. It is especially useful for `:help`{vi
  6. While in command mode, press `<C-d>`{normal} to see possible completions.
     Press `<Tab>`{normal} to use the completion menu and select a match.
 
+# What's next?
+
+Run `:help nvim-quickstart`{vim} to get started with configuring or extending Nvim.
+
 # CONCLUSION
 
 This was intended to give a brief overview of the Neovim editor, just enough to
diff --git a/test/functional/plugin/tutor_spec.lua b/test/functional/plugin/tutor_spec.lua
index fd229c53ec218d..2a05bed4d415ee 100644
--- a/test/functional/plugin/tutor_spec.lua
+++ b/test/functional/plugin/tutor_spec.lua
@@ -131,7 +131,7 @@ describe(':Tutor', function()
       {0:  }University. E-mail: {2:bware@mines.colorado.edu}.                                  |
     ]]
 
-    feed(':969<CR>zt')
+    feed(':973<CR>zt')
     screen:expect(expected)
   end)
 end)


Reviews:
user: login: clason
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-20T07:56:53Z
user: login: nenahp
state: COMMENTED
author_association: NONE
submitted_at: 2025-04-20T08:20:50Z
user: login: justinmk
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-21T21:24:39Z
user: login: justinmk
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-21T21:25:11Z
user: login: justinmk
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-21T21:27:50Z
user: login: justinmk
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-21T21:30:04Z
user: login: justinmk
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-21T21:33:24Z
user: login: zeertzjq
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-22T00:02:19Z
user: login: brianhuster
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-22T08:37:52Z
user: login: justinmk
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-27T15:00:19Z
user: login: justinmk
body: This is a good start, I have some docs tweaks I'll do as a followup.

 I'm hoping @feoh and friends will upstream important parts of kickstart. If we involve a plugin manager, it should be a minimal one like 

https://github.com/savq/paq-nvim/
https://github.com/lewis6991/pckr.nvim
https://github.com/echasnovski/mini.deps

the choice doesn't matter much since we'll have a builtin one eventually.
state: APPROVED
author_association: MEMBER
submitted_at: 2025-04-27T15:04:40Z

Review comments:
diff_hunk: @@ -0,0 +1 @@
+foo.bar
path: foo/bar
user: login: clason
body: @nenahp friendly warning: You've been leaving irrelevant comments on a number of issues over the last few days. Please refrain from doing so or you will get blocked from the Neovim org. We welcome contributions, but make sure they actually provide something valuable to the discussion instead of adding noise.
created_at: 2025-04-20T07:56:53Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1 @@
+foo.bar
path: foo/bar
user: login: nenahp
body: ok i'm sorry for that
created_at: 2025-04-20T08:20:50Z
author_association: NONE
diff_hunk: @@ -0,0 +1 @@
+foo.bar
path: test.vim
user: login: justinmk
body: ?
created_at: 2025-04-21T21:24:39Z
author_association: MEMBER
diff_hunk: @@ -125,10 +129,6 @@ describe(':Tutor', function()
       {0:  }                                                                               |
       {0:  }If you prefer a book, {6:Practical Vim} by Drew Neil is recommended often          |
       {0:  }(the sequel, {6:Modern Vim}, includes material specific to Neovim).                |
-      {0:  }                                                                               |
-      {0:  }This tutorial was written by Michael C. Pierce and Robert K. Ware, Colorado    |
-      {0:  }School of Mines using ideas supplied by Charles Smith, Colorado State          |
-      {0:  }University. E-mail: {2:bware@mines.colorado.edu}.                                  |
path: test/functional/plugin/tutor_spec.lua
user: login: justinmk
body: ? most of the tutorial, afaik, is still mostly from the original
created_at: 2025-04-21T21:25:11Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,85 @@
+-- Set <space> as the leader key See `:help mapleader` NOTE: Must happen before plugins are loaded
+-- (otherwise wrong leader will be used)
+vim.g.mapleader = ' '
+
+-- [[ Setting options ]] See `:h vim.o`
+-- NOTE: You can change these options as you wish!
+-- For more options, you can see `:help option-list`
+-- To see documentation for an option, you can use `:h 'optionname'`, for example `:h 'number'`
+-- (Note the single quotes)
+
+-- Print the line number in front of each line
+vim.o.number = true
+
+-- Use relative line numbers, so that it is easier to jump with j, k. This will affect the 'number'
+-- option above, see `:h number_relativenumber`
+vim.o.relativenumber = true
+
+-- Sync clipboard between OS and Neovim. Schedule the setting after `UiEnter` because it can
+-- increase startup-time. (see `:h vim.schedule()`). Remove this option if you want your OS
+-- clipboard to remain independent. See `:help 'clipboard'`
+vim.schedule(function()
path: runtime/example_init.lua
user: login: justinmk
body: this performance note seems kind of "in the weeds", but if we're going to keep it, do we want to use an actual UIEnter handler instead of this accidental feature of `vim.schedule()` (which introduces bad/confusing habits, the opposite of what we want to do in this sample config)
created_at: 2025-04-21T21:27:49Z
author_association: MEMBER
diff_hunk: @@ -75,8 +75,6 @@ the same Nvim configuration on all of your machines, by creating
 ==============================================================================
 What next?                                                   *nvim-quickstart*
 
-See |lua-guide| for practical notes on using Lua to configure Nvim.
path: runtime/doc/nvim.txt
user: login: justinmk
body: revert

and the "ide" note can go just below here.
created_at: 2025-04-21T21:30:04Z
author_association: MEMBER
diff_hunk: @@ -93,10 +93,11 @@ Finally, you can include Lua code in a Vimscript file by putting it inside a
 Using Lua files on startup                                    *lua-guide-config*
 
 Nvim supports using `init.vim` or `init.lua` as the configuration file, but
-not both at the same time. This should be placed in your |config| directory,
-which is typically `~/.config/nvim` for Linux, BSD, or macOS, and
-`~/AppData/Local/nvim/` for Windows. Note that you can use Lua in `init.vim`
-and Vimscript in `init.lua`, which will be covered below.
+not both at the same time. This should be placed in your |config| directory
+(run `:echo stdpath('config')` to see where it is). Note that you can also use
+Lua in `init.vim` and Vimscript in `init.lua`, which will be covered below.
+
+Run `:e $VIMRUNTIME/example_init.lua` to see an example of a Lua config file.
path: runtime/doc/lua-guide.txt
user: login: justinmk
body: probably want a one-liner codeblock to copy the config to the right location. similar to the steps from `:help nvim-from-vim`.

and this would probably go in `:help nvim-quickstart`
created_at: 2025-04-21T21:33:24Z
author_association: MEMBER
diff_hunk: @@ -125,10 +129,6 @@ describe(':Tutor', function()
       {0:  }                                                                               |
       {0:  }If you prefer a book, {6:Practical Vim} by Drew Neil is recommended often          |
       {0:  }(the sequel, {6:Modern Vim}, includes material specific to Neovim).                |
-      {0:  }                                                                               |
-      {0:  }This tutorial was written by Michael C. Pierce and Robert K. Ware, Colorado    |
-      {0:  }School of Mines using ideas supplied by Charles Smith, Colorado State          |
-      {0:  }University. E-mail: {2:bware@mines.colorado.edu}.                                  |
path: test/functional/plugin/tutor_spec.lua
user: login: zeertzjq
body: It's better to change the `969` below to `973`, as the email is also a link, while the "What's next" section doesn't contain any links.
created_at: 2025-04-22T00:02:19Z
author_association: MEMBER
diff_hunk: @@ -125,10 +129,6 @@ describe(':Tutor', function()
       {0:  }                                                                               |
       {0:  }If you prefer a book, {6:Practical Vim} by Drew Neil is recommended often          |
       {0:  }(the sequel, {6:Modern Vim}, includes material specific to Neovim).                |
-      {0:  }                                                                               |
-      {0:  }This tutorial was written by Michael C. Pierce and Robert K. Ware, Colorado    |
-      {0:  }School of Mines using ideas supplied by Charles Smith, Colorado State          |
-      {0:  }University. E-mail: {2:bware@mines.colorado.edu}.                                  |
path: test/functional/plugin/tutor_spec.lua
user: login: brianhuster
body: > ? most of the tutorial, afaik, is still mostly from the original

I'm sorry, I don't understand what you mean

> It's better to change the 969 below to 973

Is there a way I can automatically generate that string? I had to copy from CI result
created_at: 2025-04-22T08:37:52Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,88 @@
+-- Set <space> as the leader key
+-- See `:help mapleader`
+-- NOTE: Must happen before plugins are loaded (otherwise wrong leader will be used)
+vim.g.mapleader = ' '
+
+-- [[ Setting options ]] See `:h vim.o`
+-- NOTE: You can change these options as you wish!
+-- For more options, you can see `:help option-list`
+-- To see documentation for an option, you can use `:h 'optionname'`, for example `:h 'number'`
+-- (Note the single quotes)
+
+-- Print the line number in front of each line
+vim.o.number = true
+
+-- Use relative line numbers, so that it is easier to jump with j, k. This will affect the 'number'
+-- option above, see `:h number_relativenumber`
+vim.o.relativenumber = true
+
+-- Sync clipboard between OS and Neovim. Schedule the setting after `UiEnter` because it can
+-- increase startup-time. Remove this option if you want your OS clipboard to remain independent.
+-- See `:help 'clipboard'`
+vim.api.nvim_create_autocmd('UIEnter', {
+  callback = function()
+    vim.o.clipboard = 'unnamedplus'
+  end,
+})
+
+-- Case-insensitive searching UNLESS \C or one or more capital letters in the search term
+vim.o.ignorecase = true
+vim.o.smartcase = true
+
+-- Highlight the line where the cursor is on
+vim.o.cursorline = true
+
+-- Minimal number of screen lines to keep above and below the cursor.
+vim.o.scrolloff = 10
+
+-- Show <tab> and trailing spaces
+vim.o.list = true
+
+-- if performing an operation that would fail due to unsaved changes in the buffer (like `:q`),
+-- instead raise a dialog asking if you wish to save the current file(s) See `:help 'confirm'`
+vim.o.confirm = true
+
+-- [[ Set up keymaps ]] See `:h vim.keymap.set()`, `:h mapping`, `:h keycodes`
+
+-- Use <Esc> to exit terminal mode
+vim.keymap.set('t', '<Esc>', '<C-\\><C-n>')
+
+-- Map <A-j>, <A-k>, <A-h>, <A-l> to navigate between windows in any modes
path: runtime/example_init.lua
user: login: justinmk
body: off topic: these should really be defaults
created_at: 2025-04-27T15:00:19Z
author_association: MEMBER

PR comments:
user: login: brianhuster
created_at: 2025-04-23T07:45:16Z
body: @justinmk Should I remove lesson 7.2 in tutor? The reason Vim puts it there (and before Lesson 7.3: Completion) is that Vim is in Vi-compatible mode by default, where many Vim features are disabled, including `cmdline-completion`. But if Vim detects a `vimrc` file, Vi-compatible will be disabled.

I also think it would be confusing if in tutor we tell them to create an `init.vim`, but in `nvim-quickstart` we tell them to create `init.lua`
author_association: CONTRIBUTOR
user: login: justinmk
created_at: 2025-04-26T15:41:14Z
body: > remove lesson 7.2 in tutor? The reason Vim puts it there (and before Lesson 7.3: Completion) is that Vim is in Vi-compatible mode by default

SGTM. Separate PR though
author_association: MEMBER
user: login: brianhuster
created_at: 2025-04-27T15:29:50Z
body: Should this be backported to Nvim 0.11?
author_association: CONTRIBUTOR
user: login: neovim-backports[bot]
created_at: 2025-04-27T15:40:22Z
body: Backport failed for `release-0.11`, because it was unable to cherry-pick the commit(s).

Please cherry-pick the changes locally and resolve any conflicts.
```bash
git fetch origin release-0.11
git worktree add -d .worktree/backport-33524-to-release-0.11 origin/release-0.11
cd .worktree/backport-33524-to-release-0.11
git switch --create backport-33524-to-release-0.11
git cherry-pick -x 86b34ad073797da791348b97393d5d7b7ceca2e3
```
author_association: NONE
user: login: feoh
created_at: 2025-04-27T18:15:26Z
body: @justinmk I love this idea. Honestly I think kickstart needs to die. It's an impossible project in some sense, because everyone has Strong Feelings about what it should be and they're often going in conflicting directions.

I'll look into these more minimal plugin managers. I am not married to lazy, and agree that the extra complexity isn't great.

One thing that I think is important though is that plugin authors provide instructions for configuration to match whichever one we pick.
author_association: NONE
user: login: brianhuster
created_at: 2025-04-28T05:54:20Z
body: > It's an impossible project in some sense, because everyone has Strong Feelings about what it should be and they're often going in conflicting directions.

This is offtopic, but after reading some issue and PR comments in `kickstart.nvim`, I feel like some people confuse `kickstart.nvim` with a distro that users must regularly update (that's why some of them say things like changing this plugin will break users' habit). So I would suggest you to modify the README to tell users to copy relevant files to their config instead of forking the repo.
author_association: CONTRIBUTOR