Options Reference
Neovim has hundreds of settings. This lesson covers the most impactful options for daily development, organized by category.
Setting Options in Lua
-- Global option
vim.opt.number = true
-- Buffer-local option
vim.bo.tabstop = 4
-- Window-local option
vim.wo.wrap = false
-- Access current value
print(vim.opt.number:get())
print(vim.o.tabstop) -- global shortcut
Display Options
| Option | Recommended | Description |
|---|---|---|
| number | true | Show line numbers |
| relativenumber | true | Show relative line numbers |
| cursorline | true | Highlight current line |
| termguicolors | true | Enable 24-bit color |
| signcolumn | "yes" | Always show sign column (prevents layout shift) |
| colorcolumn | "80" | Show ruler at column 80 |
| wrap | false | Disable line wrapping |
| linebreak | true | If wrap enabled, break at word boundaries |
| showmode | false | Don't show "-- INSERT --" (use statusline instead) |
| scrolloff | 8 | Keep N lines visible above/below cursor |
| sidescrolloff | 8 | Keep N cols visible left/right |
| conceallevel | 2 | Conceal markdown syntax (for markdown editing) |
vim.opt.number = true
vim.opt.relativenumber = true
vim.opt.cursorline = true
vim.opt.termguicolors = true
vim.opt.signcolumn = "yes"
vim.opt.colorcolumn = "80"
vim.opt.wrap = false
vim.opt.scrolloff = 8
vim.opt.showmode = false
Indentation Options
| Option | Recommended | Description |
|---|---|---|
| tabstop | 2 or 4 | Width of a tab character |
| shiftwidth | same as tabstop | Width for >> / << indent |
| softtabstop | same as tabstop | Tab key inserts N spaces |
| expandtab | true | Use spaces instead of tabs |
| autoindent | true | Auto-indent new lines |
| smartindent | true | Smart auto-indenting |
| shiftround | true | Round indent to multiple of shiftwidth |
vim.opt.tabstop = 2
vim.opt.shiftwidth = 2
vim.opt.softtabstop = 2
vim.opt.expandtab = true
vim.opt.autoindent = true
vim.opt.smartindent = true
vim.opt.shiftround = true
Search Options
| Option | Recommended | Description |
|---|---|---|
| ignorecase | true | Case-insensitive search |
| smartcase | true | Switch to case-sensitive if uppercase |
| incsearch | true | Incremental search (show as you type) |
| hlsearch | true | Highlight all search results |
| inccommand | "split" | Live preview of substitute command |
vim.opt.ignorecase = true
vim.opt.smartcase = true
vim.opt.incsearch = true
vim.opt.hlsearch = true
vim.opt.inccommand = "split"
File and Encoding Options
| Option | Recommended | Description |
|---|---|---|
| encoding | "utf-8" | Internal encoding |
| fileencoding | "utf-8" | File encoding on disk |
| undofile | true | Persist undo history across sessions |
| swapfile | false | No swap files |
| backup | false | No backup files |
| writebackup | false | No write backup |
| autoread | true | Auto-reload files changed outside Neovim |
vim.opt.encoding = "utf-8"
vim.opt.fileencoding = "utf-8"
vim.opt.undofile = true
vim.opt.swapfile = false
vim.opt.backup = false
vim.opt.autoread = true
Performance and Timing Options
| Option | Recommended | Description |
|---|---|---|
| updatetime | 300 | Milliseconds before CursorHold events (lower = faster LSP) |
| timeoutlen | 300 | Key sequence timeout (ms) |
| ttimeoutlen | 0 | Terminal key sequence timeout |
| lazyredraw | false | Don't redraw during macros (can cause issues with some plugins) |
| synmaxcol | 300 | Max column for syntax highlighting (performance) |
vim.opt.updatetime = 300
vim.opt.timeoutlen = 300
vim.opt.ttimeoutlen = 0
Completion Options
| Option | Recommended | Description |
|---|---|---|
| completeopt | "menu,menuone,noselect" | Completion menu behavior |
| pumheight | 10 | Max items in popup menu |
| shortmess:c | true | Don't show completion messages |
vim.opt.completeopt = { "menu", "menuone", "noselect" }
vim.opt.pumheight = 10
vim.opt.shortmess:append("c")
Split and Window Options
| Option | Recommended | Description |
|---|---|---|
| splitright | true | Vertical splits open right |
| splitbelow | true | Horizontal splits open below |
| equalalways | false | Don't auto-equalize splits |
vim.opt.splitright = true
vim.opt.splitbelow = true
Clipboard
-- Sync Neovim clipboard with system clipboard
vim.opt.clipboard = "unnamedplus"
warning
Setting clipboard = "unnamedplus" means every yank/delete updates the system clipboard. If you don't want this, use "+y explicitly when you want to copy to clipboard.
Wild Menu (Command Completion)
vim.opt.wildmenu = true
vim.opt.wildmode = "longest:full,full"
vim.opt.wildignore:append({
"*.pyc", "*.o", "*.class", "node_modules/**",
".git/**", ".DS_Store", "*.swp",
})
Filetype-Specific Overrides
Use autocmds to override per filetype:
~/.config/nvim/lua/config/autocmds.lua
vim.api.nvim_create_autocmd("FileType", {
pattern = { "python" },
callback = function()
vim.bo.tabstop = 4
vim.bo.shiftwidth = 4
end,
})
vim.api.nvim_create_autocmd("FileType", {
pattern = { "markdown", "txt" },
callback = function()
vim.wo.wrap = true
vim.wo.linebreak = true
vim.wo.spell = true
end,
})
In LazyVim
LazyVim Context
LazyVim pre-configures almost all of these options with sensible defaults (like number = true, termguicolors = true, ignorecase = true). You only need to add options to lua/config/options.lua if you want to change LazyVim's default behavior.
| Aspect | Vanilla Neovim | LazyVim |
|---|---|---|
| Setting options | Add to your options.lua | Add to lua/config/options.lua (overrides LazyVim) |
| Default tabstop | 8 (Neovim default) | 2 (LazyVim default) |
| Default clipboard | Empty | "unnamedplus" (Syncs with system clipboard) |
| Default wrap | false | false |