neovim/neovim
Options
Purpose
Vim has a single setting mechanism — the option — that scales from set tabstop=4 to per-window state like 'colorcolumn' and per-buffer state like 'fileencoding'. Neovim refactored Vim's hand-coded option tables into a single Lua data file (src/nvim/options.lua, ~10,956 lines) that drives code generation. This is the canonical place to change anything option-related.
Directory layout
src/nvim/
├── options.lua (~450k bytes) The Lua data file. Single source of truth.
├── option.c (~206k bytes) Generic option get/set, validation
├── option.h, option_defs.h
├── option_vars.h (~31k bytes) Macros for accessing each option from C
├── optionstr.c (~73k bytes) String-typed option handlers
├── optionstr.h
└── api/options.c The nvim_*_option API surface
build/src/nvim/auto/options.generated.h Generated table
build/src/nvim/auto/options_enum.generated.h Generated enumThe pattern is the same as for events, ex commands, eval functions, and v: variables — Lua data file, code-generator, regenerate on build.
Key abstractions
| Concept | Description |
|---|---|
| Scope | global, buffer, window. Some options have a "global-local" hybrid (set globally, override per buffer). |
| Type | boolean, number, string. Strings can be enums, comma-separated lists, or free-form. |
| Short name | Two-letter abbreviation (tabstop → ts). |
| Cb (callback) | A C function called when the value changes. Used for revalidation, side effects (e.g. switching the active syntax). |
| Enable_if | A compile-time gate; some options only exist if a feature is built in. |
Format of options.lua
Each option is a Lua table:
{
full_name = 'tabstop',
abbreviation = 'ts',
short_desc = N_("number of spaces a <Tab> in the file counts for"),
type = 'number',
scope = { 'buffer' },
varname = 'p_ts',
defaults = { if_true = 8 },
},
{
full_name = 'fileencoding',
abbreviation = 'fenc',
short_desc = N_("file encoding for multi-byte text"),
type = 'string',
scope = { 'buffer' },
varname = 'p_fenc',
alloced = true,
redraw = { 'statuslines' },
defaults = { if_true = "" },
cb = 'did_set_fileencoding',
},Fields are documented at the top of options.lua and in runtime/doc/dev_arch.txt. The generator (src/gen/gen_options.lua) consumes this and produces:
- An
OPT_*enum, one entry per option. - A C array of
vimoption_Tstructs with all metadata. - A header (
option_vars.h) that includes per-option access macros (e.g.,p_ts,curbuf->b_p_ts).
How it works
The runtime path:
graph LR
User[":set tabstop=4"]
User --> Parse[option.c#do_set]
Parse --> Lookup[lookup in vimoption_T table]
Parse --> Validate[validate type/value]
Validate --> Store[store in p_ts<br/>or curbuf->b_p_ts]
Validate --> CB[did_set_tabstop callback]
CB --> Side[Redraw, update internal state]option.c#do_set is the entry point for :set. It tokenizes the argument list, looks up each option, dispatches to option_set_value, and runs the per-option callback. For string options, the validation and side-effect code is mostly in optionstr.c#did_set_* functions — one per option that needs special handling.
Option scope
The scope of an option determines where the value lives:
| Scope | Storage | Examples |
|---|---|---|
global |
A p_* global in globals.h. |
'magic', 'shell', 'updatetime'. |
buffer |
b_p_* field on buf_T. |
'tabstop', 'filetype', 'modified'. |
window |
w_p_* field on win_T. |
'cursorline', 'foldenable', 'wrap'. |
global-local |
Both p_* and b_p_*/w_p_*; the latter shadows. |
'undolevels', 'colorcolumn'. |
When you :setlocal foo=..., only the local field changes; :setglobal only the global. Bare :set writes both.
Option callbacks
Most string options have a callback like did_set_filetype, did_set_completeopt, etc. Their job:
- Re-tokenize comma-separated values.
- Validate enum members.
- Trigger side effects (load syntax, update internal flags).
Callbacks live in optionstr.c and a small handful in option.c. They are looked up by name from the cb field in options.lua.
API surface
vim.o.tabstop = 4 -- vim.o = global view (read writes both global and current local)
vim.bo.tabstop = 4 -- vim.bo = current buffer-local
vim.wo.cursorline = true -- vim.wo = current window-local
vim.opt.list = true -- vim.opt = a table-with-methods view
vim.opt.listchars:append { tab = '> ' }The Lua wrappers (runtime/lua/vim/_options.lua and friends) call vim.api.nvim_get_option_value / nvim_set_option_value. The C side ends up in src/nvim/api/options.c, which delegates to the same option.c#option_set_value that :set uses.
Documentation generation
make doc runs src/gen/gen_eval_files.lua which parses options.lua and renders the user-facing help in runtime/doc/options.txt. The short_desc, desc, and metadata fields in each option entry become the documentation. Don't edit options.txt directly — it gets clobbered on the next make doc.
Integration points
:set—do_setinoption.ctokenizes and dispatches.:setlocal,:setglobal— same path, different scope flag.vim.opt,vim.o,vim.bo,vim.wo— Lua front ends that resolve tonvim_get/set_option_value.OptionSetautocmd — fired after every successful option change.- Modeline parsing —
src/nvim/main.c#chk_modelinecalls into option setting atBufReadPosttime. - Persistence — option values are NOT saved in shada; users persist them via
init.luaor session files.
Entry points for modification
- Change a default. Edit the
defaultstable inoptions.lua. Rebuild. - Add a new option. Append a new entry to
options.lua. Implement the callback inoptionstr.c(string) oroption.c(number/bool). Add doc text in the entry'sdescfield. Runmake. Runmake docto regenerateruntime/doc/options.txt. - Add a new flag to an existing comma-list option. Edit the option's
cb. Touch the relevant validator (e.g.expand_set_listchars). - Tweak
:setparser.option.c#do_setis dense but well-isolated.
Key source files
| File | Purpose |
|---|---|
src/nvim/options.lua |
Single source of truth — every option, its type/scope/default |
src/nvim/option.c |
:set parser, option lookup, generic get/set |
src/nvim/optionstr.c |
String-option validators and did_set_* callbacks |
src/nvim/option_vars.h |
Per-option C access macros (generated) |
src/nvim/api/options.c |
The nvim_*_option_value and nvim_*_option_info API |
src/gen/gen_options.lua |
Generator |
runtime/lua/vim/_options.lua |
Lua wrapper (vim.opt, vim.o, etc.) |
runtime/doc/options.txt |
User-facing docs (regenerated) |
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.