Neovim 0.12.3 · the vi and Vim core first, then everything Neovim adds · 3419 entries

One sheet for using Neovim fully, in the order it is learned. Part I is the editor Neovim inherited: vi’s modes and survival keys, then Vim’s grammar of operators, motions and text objects, registers, the undo tree, buffers and windows, the ex language, patterns, completion, quickfix, folding, macros, options, mappings, autocommands and the runtime path — each card corrected where Neovim differs, because half of what a vimrc sets is already the default here. Part II is what Neovim is that Vim is not: an API server with LuaJIT inside. Setting it up on macOS (the terminal settings that decide which keys exist, the pasteboard, language servers from Homebrew), the shape of an init.lua, vim.pack — the plugin manager new in 0.12 — language servers in two calls, completion and snippets without a plugin, diagnostics, tree-sitter, the terminal, extmarks and floats, headless and remote use, exactly what 0.12 broke, and the traps for people arriving from Vim. Cards 1–31 are the guide. The index is 3419 entries, none retyped: 2323 in Index I, the complete command, option, function and event tables as this Neovim has them; 1096 in Index II, the Neovim-only surface — 71 default mappings, 216 Lua functions, 112 in vim.lsp, 261 API functions and 84 deprecations with their replacements. Press / to filter; hover a row for its help tag and, for options, Neovim’s default.

Dots: plain cursor movement — usable as a motion changes text — undoable, repeatable with . new or changed in 0.12 experimental deprecated or legacy — has a replacement Vim only — not in Neovim
Sources: the NVIM v0.12.3 binary (Release build, LuaJIT 2.1), asked headlessly with --clean for its mappings, options and defaults, functions, commands, events and API metadata; and the runtime documentation it ships — index.txt, quickref.txt, options.txt, vimfn.txt, autocmd.txt, news.txt, vim_diff.txt, lua.txt, lsp.txt, diagnostic.txt, treesitter.txt, pack.txt, api.txt, deprecated.txt. “Neovim only” is a set difference against Vim 9.1, computed, not remembered. Every Lua listing in the guide was run on that binary, on macOS.

Part I · The vi and Vim Core

The editing model Neovim inherited — modes, the operator grammar, registers, the undo tree, ex, patterns, macros, options, mappings — corrected wherever Neovim’s defaults differ

Modes and the Survival Keys

vi, 1976 — still all true

Neovim is a modal editor: the same key means different things depending on the mode, and you spend most of your time not inserting text. Everything on this card worked in Bill Joy’s vi and works unchanged here. Learn this card cold; the rest of Part I is what makes it fast.

ModeEnter withFor
Normal<Esc> — always gets you heremoving and issuing edits; where you live
Inserti a o I A O · c{motion} · styping text
Visualv chars · V lines · CTRL-V blockselecting, then one operator
Command-line: ex · / ? searchfiles, ranges, substitute, settings
Operator-pendingafter d c y > …waiting for the motion that completes the edit
ReplaceR · r{c} for one characterovertyping
Terminali in a :terminal bufferkeys go to the shell; CTRL-\ CTRL-N leaves

Getting out, and saving

:wwrite:qquit this window; refuses if the buffer is modified:wq · :x · ZZwrite and quit — :x and ZZ only write if something changed:q! · ZQquit and throw the changes away:wa · :qa · :wqathe same for all buffers:e {file} · :e!edit a file · reload this one, discarding changes:w {name} · :sav {name}write a copy · write a copy and switch to it:w !sudo tee %write a file you opened without permission

Moving

h j k lleft, down, up, right — all take a count: 5jw b e · W B Eword forward, back, end · the same over whitespace-delimited WORDs0 ^ $column 1, first non-blank, end of linegg G {n}Gfirst line, last line, line nCTRL-F CTRL-B · CTRL-D CTRL-Upage down / up · half a pageCTRL-E CTRL-Y · zz zt zbscroll a line · put the cursor line at centre / top / bottom{ } · ( )paragraph · sentence%matching bracket/pat ?pat · n Nsearch forward / back · next / previous match

Changing text

i a · I Ainsert before / after the cursor · at line start / endo Oopen a line below / abovex X · r{c} · ~delete char under / before · replace one char · flip casedd yy cc · D Cdelete, yank, change a line · delete / change to end of linep Pput after / before the cursor (or line)Jjoin the next line onto this oneu CTRL-Rundo, redo.repeat the last change — the most important key here>> << ==indent, dedent, reindent the lineCTRL-A CTRL-Xincrement / decrement the number under the cursor:s/old/new/g · :%s/old/new/gcsubstitute on this line · in the file, confirming each
The three habits. Leave Insert mode the moment you stop typing — Normal is home. Prefer a motion with a count or a search over holding a key. And when an edit repeats, make it once in a form . can replay. Those are vi’s; everything Vim and Neovim added rewards them.
What is different here, even at this level. Y yanks to end of line (y$) rather than the whole line; the mouse works; CTRL-L also clears search highlight; and in Normal mode Q replays the last recorded macro instead of entering Ex mode (that moved to gQ). All four are listed with the other defaults in Part II.

The Grammar

operator × count × motion

An edit is [count] {operator} [count] {motion}. The two counts multiply. The operator waits in operator-pending mode until a motion or text object completes it, which is why d alone appears to hang — it is a partially applied function.

Operators

OpDoesOpDoes
ddeletegu / gUlowercase / uppercase
cchange (delete + insert)g~swap case
yyankgq / gwformat to 'textwidth'; gw keeps the cursor
> / <indent / dedent one 'shiftwidth'g?rot13, because 1991
=reindent via 'equalprg' / 'indentexpr'zfcreate a fold
!filter through an external commandg@call 'operatorfunc' — how plugins add operators

Text objects — the half most people never learn

i = inner (the contents), a = around (contents plus delimiters or trailing space). They work from anywhere inside the object, so you never position the cursor first.

ciwchange inner word — cursor anywhere in itci" ci( ci{ ci[ citinside quotes, parens, braces, brackets, an HTML/XML tagdapdelete a paragraph and its trailing blank lineyi{yank a block body without the bracesvasselect a sentence, whitespace includeddatdelete a whole tag, open to close

Forcing the mode of an operator

dvjforce charwise: delete from the cursor to the same column one line downdVjforce linewise: both lines entirelyd<C-v>jforce blockwise

Worked examples

KeysReads as
d2}delete forward two paragraphs
y/END<CR>yank from here up to the next "END" — a search is a motion
c3awchange three words including their spaces
>i{indent the body of the block the cursor is in
!ip sortsort the paragraph under the cursor through sort(1)
gqiprewrap the paragraph to 'textwidth'
ct,change up to the next comma — t stops before, f lands on
. repeats the last change, not the last keystroke. That is the whole argument for composing edits rather than holding a key down: ciwfoo<Esc> then n. n. is a hand-driven search-and-replace with a diff you can see.
Neovim adds one operator and two objects. gc{motion} toggles comments (gcc a line, gcip a paragraph) and gc is also a text object, so dgc deletes a comment block. With a tree-sitter parser active, an and in in Visual mode select the enclosing / inner syntax node — see the Tree-sitter card.

Motions and Jumps

and the inclusive/exclusive rule

A motion used alone moves the cursor; used after an operator it defines a region. Whether the character under the destination is included is a property of the motion, and it is the single most common source of off-by-one surprise.

ClassMotionsRegion
charwise exclusiveh l w W b B ge 0 ^ $ (no), ) ( } {, /pat, ?patup to but not including the end
charwise inclusivee E f F t T $ % and `m when charwiseincludes the end character
linewisej k G gg H M L + - _ 'm :{n}whole lines only
dw vs dedw deletes the word and the space after it; de stops at the last letterd$ vs Didentical — D is just d$d/foodeletes up to foo; d/foo/e deletes through it

Two exceptions worth knowing

  • exclusive-linewise: if an exclusive motion ends on the first column, the end moves to the end of the previous line, and if the start was at or before the first non-blank the whole thing becomes linewise. This is why d} on a paragraph does what you want instead of leaving a stray blank line.
  • a count on % is not "do it n times" — 50% goes to 50% of the file.

Within the line

f{char} / F{char}to the next / previous occurrence, cursor on itt{char} / T{char}till: stops one short — the one you want with an operator; / ,repeat the last f/F/t/T forwards / backwards0 ^ g_ $column 1, first non-blank, last non-blank, end of lineg0 g^ g$ gj gkthe same, but on the screen line when text is wrapped

Between places

gg / G / {n}G / :{n}top, bottom, line nH M Ltop / middle / bottom of the visible windowCTRL-O / CTRL-Iback / forward through the jump list — :jumpsg; / g,back / forward through the change list — :changesCTRL-^to the alternate file; the fastest two-file toggle there is* / #search for the word under the cursor, forwards / backwardsg* / g#same, without the \< \> word boundaries% to the matching bracket — extended to language keywords (if/end, HTML tags) by matchit, which Neovim loads by default[m ]m [[ ]] [{ ]}method, section and block boundaries
Only "jumps" go on the jump list. h j k l and w b do not; searches, G, { }, %, marks, :N and tag jumps do. That is why CTRL-O reliably takes you back where you were looking, not where you last nudged the cursor.

Registers

ten of them matter

Every yank and delete writes to more than one place. Understanding which is the difference between "my paste got clobbered" being a mystery and being a keystroke.

y{motion}writes "" and "0d{motion} (multi-line)writes "" and shifts the ring "1…"9d{motion} (within a line)writes "" and "-, and does not touch the ring"xywrites "" and "x; the yank register "0 is skipped

The consequence, and the fix

yiw " yank a word -> "" and "0 diw " delete the target -> "" (and "-) p " pastes the DELETED text, not the yanked one "0p " pastes the yank. This is the whole trick. "_diw " delete into the black hole; "" survives " visual-paste replaces the selection, and swaps into "" viwp

Registers worth having in muscle memory

RegHoldsRegHolds
"0the last yank, immune to deletes"%current file name
"-the last small (sub-line) delete"#alternate file name
"_black hole; write-only".last inserted text
"+system clipboard":last command line
"*primary selection on X11; on macOS the same pasteboard as "+"/last search pattern — writable

Uses that are not obvious

" clear search highlight without :nohlsearch :let @/ = '' :let @a = @a . @b " concatenate registers " clear register a (record nothing into it) qaq "Ayy " APPEND this line to register a " (insert mode) insert register a literally CTRL-R a " (cmdline) insert the word under the cursor CTRL-R CTRL-W " expression register: insert today's date CTRL-R =strftime('%F')<CR> " yank the whole buffer to the clipboard :%y+
"+ is a program, not a compile flag. Neovim has no +clipboard feature; it shells out to a provider. On macOS that is pbcopy / pbpaste, which are always present, so "+y just works. To make every yank and put use the pasteboard, vim.o.clipboard = 'unnamedplus'. Over SSH there is no pasteboard to call — Neovim falls back to the OSC 52 terminal escape when the terminal supports it. :checkhealth vim.provider names the tool in use.
0.12 changed CTRL-R. In Insert mode CTRL-R {reg} now inserts the register literally, like a paste, instead of replaying it as typed keys — ten times faster and no auto-indent staircase. CTRL-R CTRL-R is no longer needed for that; <C-R>=@a gets the old behaviour.

Undo Is a Tree

and nobody tells you

Vim does not keep an undo stack. It keeps a tree: undo three changes, type something new, and the three you undid are still there on a sibling branch. u and CTRL-R walk the current branch; g- and g+ walk all states in chronological order, which is the only pair that can reach a branch you have left.

u / CTRL-Rundo / redo along the current branchg- / g+older / newer text state, across branches — the escape hatch:undolistthe leaves, with sequence numbers and timestamps:undo {n}jump to state n directly:earlier 10m / :later 1htime travel; also 10s, 5f (file writes):earlier 1fback to the text as it was at the previous write — a diff-free "what did I change"Uundo all recent changes on one line; itself undoable

Persistent undo — the one line everybody should have

vim.o.undofile = true -- init.lua; that is all of it

Vim needs an undodir and a mkdir. Neovim’s 'undodir' already defaults to ~/.local/state/nvim/undo// and is created on demand, so the one option is the whole setup. With it, closing and reopening a file keeps the whole tree: you can undo past the point where you quit last week. It is off by default.

Undo blocks

One u undoes one change, and a whole insert session is normally one change. Break it up so that undo has useful granularity:

" Neovim already maps CTRL-U and CTRL-W this way: " inoremap <C-U> <C-G>u<C-U> " one undo block per line typed -- yours to add inoremap <CR> <C-G>u<CR> " default 1000; 0 means one level, -1 none set undolevels=1000
:earlier 1f is the underrated one. "Show me the file as it was when I last saved" needs no git, no plugin and no scratch buffer, and :later 1f puts it back.
0.12 ships a tree viewer. :packadd nvim.undotree then :Undotree opens the branches as a navigable buffer — the built-in answer to the plugin everyone installed for this.

Buffers, Windows, Tabs, Args

four axes, not one

Other editors give you one list. Vim gives you four, and they are orthogonal. The confusion is nearly always someone treating tab pages as file tabs.

:ls / :buffersevery loaded buffer; the flags are the interesting part:b {n|name}switch — partial names work, <Tab> completes:bn :bp :bf :bl :bdnext, previous, first, last, deleteCTRL-^ / :b#the alternate buffer — toggle two files with one key:bufdo {cmd}run cmd in every buffer; add | update to save the changed ones
:ls flagMeans:ls flagMeans
%the current bufferaactive — loaded and displayed
#the alternate bufferhhidden — loaded, no window
+modified= -read-only / 'modifiable' off
uunlisted (help, terminal)xread errors
'hidden' is on by default in Neovim. You can leave a modified buffer freely, so :bn, :argdo and go-to-definition never fail with E37 the way they do in a bare Vim. The cost is that buffers stay loaded and unsaved: :ls shows them with +, and :q on the last window will refuse until you deal with them. Keep :wa in muscle memory, or set 'confirm' (off by default) to be asked instead of refused.

Windows

:sp / :vs [file]split horizontally / verticallyCTRL-W s v c o qsplit, vsplit, close, only, quitCTRL-W h j k lmove focus; CTRL-W w cyclesCTRL-W H J K Lmove the window to the far left/bottom/top/right — re-lays out the screenCTRL-W = _ |equalise, maximise height, maximise widthCTRL-W + - < >resize by one; prefix a countCTRL-W T / CTRL-W xmove this window to its own tab / exchange two windows

Tab pages and the argument list

:tabnew :tabc :tabonew, close, close othersgt / gT / {n}gtnext / previous / go to tab n:tabdo {cmd}run cmd in every tab:args *.c / :argadd / :argdeleteset and edit the argument list:argdo %s/foo/bar/ge | updateproject-wide substitute; e stops "not found" aborting the loop:next :prev :first :lastwalk the argument list

The right mental model: buffers are the files you have open, windows are how many you can see at once, and tabs are saved window layouts. Use :b for files and reach for tabs only when you actually want a second layout.

]b [b · ]B [BNeovim default maps: next / previous buffer · last / first]a [a · ]A [Athe same for the argument list

Ex Commands and Ranges

the other half of the editor

Everything after : is ex, a line editor from 1976 that never went away. Its shape is :[range] cmd [args] [flags], and once the range syntax is in your fingers a lot of edits stop needing motions at all.

Range atoms — they compose

:5,10dlines 5 to 10:.,$yhere to end of file:%s/a/b/g% is 1,$:'a,'bdbetween marks a and b:.,+5>this line and the next five, indented:/BEGIN/,/END/dfrom the next BEGIN to the next END:g/TODO/normal A # doneappend to every TODO line:'<,'>!column -tfilter the visual selection through a shell command

The two that pay for the whole page

:global and :normal compose into a scripting language you already know. :g runs in two passes — it marks every matching line first, then executes — so a command that deletes lines cannot invalidate its own iteration.

:g/^\s*$/d " delete every blank line " delete every line that is NOT an error :v/error/d " copy every TODO to the end of the file :g/TODO/t$ " reverse the file (move every line to the top) :g/^/m0 " comment out every line, using normal-mode keys :%norm! I// <Esc> :g/{/,/}/> " indent every brace block " arbitrary composition via :execute :g/pat/exe "norm! ddP"
Use :normal! with the bang in scripts. Without it your mappings apply, so a plugin that remaps I silently changes what your command does. The same bang rule holds for :g/…/norm!.

Command-line editing

CTRL-R CTRL-W / CTRL-R CTRL-Ainsert the word / WORD under the cursorCTRL-R %insert the current file name<Up> / <Down>history filtered by what you have typed so far — not a plain history walkq: / q/ / q?open the command / search history as an editable bufferCTRL-Fsame, from a command line already in progressCTRL-D / <Tab>list completions / complete; see 'wildmode':<C-R><C-R>"insert the unnamed register verbatim

Filename modifiers, which appear everywhere

%current file%:hits directory (head)%:tits basename (tail)%:rwithout extension (root)%:ethe extension%:pfull path%:.relative to the working directory%:~relative to home%:Sshell-escaped — always use it before !
:s previews live. Neovim’s 'inccommand' defaults to nosplit: as you type a :s or :%s command the buffer shows the result before you press Enter, and <Esc> abandons it. set inccommand=split adds a preview window listing off-screen matches too. 0.12 adds :iput (put, re-indented), :uniq and :retab -indentonly.

Patterns

why Vim regex feels wrong

Vim’s regex predates PCRE and escapes the opposite set of characters. In the default 'magic' level . * [ are special but + ? ( ) { | are not — they need backslashes. The fix is one atom.

" the same pattern, four ways \v(foo|bar)+\s*= " very magic -- read this one \m\(foo\|bar\)\+\s*= " magic (the default) \M\(foo\|bar\)\+\s*= " nomagic " very nomagic: only \ is special -- the literal escape \V...

Start every non-trivial pattern with \v and Vim regex becomes ordinary. Start a literal search with \V and you never escape a dot again.

What Vim has that PCRE does not

AtomMeans
\zs \zeset where the match starts / ends — variable-width lookaround, and far more readable
\%Vonly inside the visual selection — the only sane way to substitute in a block
\%23l \%>10lonly on line 23 / after line 10; also c for column, v for virtual column
\ka "keyword" character, as defined by 'iskeyword' for this filetype
\%(...\)non-capturing group ((...) with \v is capturing)
\{-}the non-greedy *; there is no *?
\&"branch and": both alternatives must match at this position

Substitute, with the flags that matter

:%s/\vold/new/g " every line, every occurrence " empty pattern = reuse the last SEARCH -- eyeball first :%s//new/g " n = count matches, change nothing :%s/\vfoo//gn " \u upcases the next character of the replacement :%s/\v(\w+)/\u\1/g " \= : the replacement is an expression :%s/\v\d+/\=submatch(0)*2/g :'<,'>s/\%Vfoo/bar/g " only inside the block selection " repeat the last :s WITH its flags (plain & drops them) :&&
& and ~ are special in the replacement. & inserts the whole match and ~ inserts the previous replacement, so :s/x/A&B/ does not produce A&B. Escape them, or set 'nomagic' for that command.

Search behaviour worth setting

-- init.lua. lowercase = insensitive; a capital = not vim.o.ignorecase = true vim.o.smartcase = true -- already on in Neovim: 'incsearch', 'hlsearch' -- already mapped: CTRL-L clears the highlight -- 'gdefault' still works but is deprecated: it inverts -- /g for every plugin too. Type the g.

'smartcase' only applies to typed patterns, not to * or # — those always respect 'ignorecase' alone.

Insert Mode

completion without a plugin

Insert mode has its own command set, reached through CTRL-X. Vim has had structured completion since long before language servers, and it still works with no plugin, no daemon and no network.

KeyCompletes from
CTRL-N / CTRL-Pkeywords, per 'complete' — this buffer, other buffers, tags, includes
CTRL-X CTRL-Ffile names, relative to the working directory
CTRL-X CTRL-Lwhole lines from open buffers
CTRL-X CTRL-K / CTRL-T'dictionary' / 'thesaurus'
CTRL-X CTRL-I / CTRL-Dincluded files / macro definitions, via 'path'
CTRL-X CTRL-]tags — ctags, and it is fast
CTRL-X CTRL-Oomni-completion — 'omnifunc', set by the filetype plugin
CTRL-X CTRL-U'completefunc' — where a plugin hooks in
CTRL-X CTRL-VVim command line, inside a vimrc
CTRL-X CTRL-Sspelling suggestions

Once the popup is open, CTRL-N/CTRL-P cycle and CTRL-E cancels back to what you typed. set completeopt=menuone,noinsert,noselect makes it behave the way a modern editor does.

Everything else in insert mode

CTRL-R {reg}insert a register; CTRL-R CTRL-R inserts it literallyCTRL-O {cmd}one normal-mode command, then back to insertCTRL-W / CTRL-Udelete the word / line before the cursorCTRL-T / CTRL-Dindent / dedent this line one 'shiftwidth'CTRL-V {code}literal character: CTRL-V u00e9, CTRL-V 065, CTRL-V <Tab>CTRL-K {a}{b}digraph: CTRL-K e' = é, CTRL-K -> = →. :digraphs lists themCTRL-A / CTRL-@insert the previously inserted text / that and stop insertingCTRL-E / CTRL-Ycopy the character below / above the cursorCTRL-G ubreak the undo sequence here — see the undo cardCTRL-\ CTRL-O {cmd}like CTRL-O but the cursor cannot move past the end

Abbreviations

iabbrev teh the iabbrev <expr> dts strftime('%F') " expands on any non-keyword char; CTRL-V stops it iabbrev adn and
Blockwise insert is the feature people leave for a multiple-cursor plugin. CTRL-V, select the lines, I (or A), type, <Esc> — the text lands on every line. $ before A appends at each line’s own end, ragged lengths and all. c in blockwise mode does the same for replacement.
Neovim can open this menu by itself. vim.o.autocomplete = true (0.12) triggers completion as you type from the same 'complete' sources, and a language server adds its own items through CTRL-X CTRL-O — both on the Completion card in Part II.

Quickfix and Location Lists

the compiler loop

The quickfix list is Vim’s error list: a global stack of file/line/message triples produced by anything that emits compiler-shaped output. The location list is the identical thing, but per window. This is how Vim does "problems panel" and "search results", and it predates both by decades.

:make [args]run 'makeprg', parse via 'errorformat', jump to the first error:cw / :copen / :ccloseopen the window if there are errors / always / close:cn :cp :cfirst :clastwalk the list; :cc {n} jumps to entry n:cnf / :cpfnext / previous file in the list:colder / :cnewerVim keeps the last ten lists — step back through them:cdo {cmd} / :cfdo {cmd}run cmd on every entry / on every file in the list:cexpr / :cgetexpr / :caddexprbuild a list from an expression or from system() output:cfile / :cgetfileread a list from a file of compiler output

Every :c… command has an :l… twin for the location list: :lmake, :lopen, :lnext, :ldo, :lgrep.

Grep without leaving Vim

" Neovim already uses ripgrep when it is installed: " grepprg=rg --vimgrep -uu (-uu: ignores NO files) " to respect .gitignore and smart-case instead: set grepprg=rg\ --vimgrep\ --smart-case :grep -w 'pattern' -- src/ " ripgrep -> quickfix " Vim's own; j = don't jump, g = every match :vimgrep /\vpat/gj **/*.py " confirm-substitute across every hit :cdo s/old/new/gc | update
:cdo plus :vimgrep is project-wide search and replace with a diff you can step through, no plugin involved. :cfdo %s/…/…/ge | update is the faster form when the change is per-file rather than per-match.

Compiler plugins

" sets makeprg + errorformat from $VIMRUNTIME/compiler/ :compiler gcc :compiler pytest :set makeprg=cargo\ build " ^= prepends a rule :set errorformat^=%f:%l:%c:\ %t%*[^:]:\ %m

'errorformat' is scanf-like, tried in order, and is the reason arbitrary tools drop into the loop. :h errorformat is worth twenty minutes once.

]q [q · ]Q [QNeovim default maps for :cnext / :cprev · :clast / :cfirst] CTRL-Q · [ CTRL-Q:cnfile / :cpfile — next / previous file]l [l ]L [Lthe same four for the location listvim.diagnostic.setqflist()every LSP diagnostic into the quickfix list

Folding

six methods, one that works

Folds are a display property of a window, not of the text, which is why two windows on one buffer can fold differently and why folds vanish when you close a window unless you save a view.

'foldmethod'Folds onVerdict
manualwhatever you mark with zfthe default; folds die with the window
indentindentation depthcheap and surprisingly good for Python and YAML
syntaxregions the syntax file marks foldablecorrect, and the classic cause of slow scrolling in large files
expr'foldexpr', evaluated per linethe flexible one; also the easiest to make slow
markerliteral {{{ / }}} in the textthe only method that survives everything, at the cost of noise
diffunchanged regions in diff modeset automatically by vimdiff
za / zAtoggle one fold / recursivelyzo zc zO zCopen, close, and their recursive formszR / zMopen every fold / close every foldzr / zmreduce / increase 'foldlevel' by onezj / zkto the start of the next / end of the previous foldzvopen just enough to see the cursor linezf{motion} / zd / zEcreate a fold / delete one / delete allzitoggle folding off and on entirely — the "get out of my way" key
set foldmethod=indent " start with everything open, not everything closed set foldlevelstart=99 set foldnestmax=3 " persist manual folds for a file: autocmd BufWinLeave *.c mkview autocmd BufWinEnter *.c silent! loadview
foldmethod=syntax or expr on a large file is the most common cause of "Vim got slow". Both re-evaluate on every change. Diagnose with :set foldmethod=manual and see if the lag goes; :syntime on then :syntime report attributes it properly.
The seventh method is a parser. With tree-sitter active, foldmethod=expr plus foldexpr=v:lua.vim.treesitter.foldexpr() folds on real syntax nodes and is incremental, so it does not have the cost this card warns about. A language server can supply folds too: v:lua.vim.lsp.foldexpr().

Macros

a register full of keystrokes

A macro is not a special object. qa records your keystrokes into register a as plain text, and @a feeds that text back to the input parser. Everything follows from that: you can yank a macro, paste it into the buffer, edit it, and yank it back.

qa " record into a " ... whatever the edit is, ending positioned for the next 0f,ci"new<Esc>j q " stop @a " run it once 5@a " run it five more times @@ " repeat the last @ " run it on EVERY line -- no count guessing :%normal @a

Editing a macro you got slightly wrong

" paste register a into the buffer as text "ap " ... fix the keystrokes, then ... 0"ay$ " yank the corrected line back into a dd " remove the scratch line

Rules that make macros reliable

  • Start from a known column. Begin the macro with 0 or ^; a macro that starts "wherever the cursor happens to be" fails on the third line.
  • End positioned for the next iteration — usually j. Then 99@a just works.
  • Let it fail. A macro stops when a command errors, so a f, that finds nothing terminates the loop cleanly. This is a feature: it is the loop condition.
  • Prefer :%normal @a to a count when the edit is per-line — no counting, and lines that do not match are skipped.
  • Use qA to append to an existing macro rather than re-recording it.
. beats a macro when the change is one edit. Macros are for multi-step edits that must be applied in bulk; the dot command with n is for repeating a single change with your eyes open. Recording a macro to do the work of ciw…<Esc> plus n. is the beginner move.
QNeovim: replay the last recorded register, with a count — no need to remember which letter{Visual}Q · {Visual}@aNeovim default: run the macro once on every selected lineRecordingEnter · RecordingLeaveevents, so a statusline can show "recording @a"; reg_recording() names the register

Options

scope is the whole story

Every option is global, buffer-local, window-local, or global-with-a-local-copy. Getting this wrong is why a setting "does not stick" when you open a second file.

CommandWrites
:set opt=xthe global value, and the local value of the current buffer/window
:setlocal opt=xonly this buffer or window
:setglobal opt=xonly the global default, used by buffers opened later
:set opt<reset the local value to the global one
:set opt& / :set all&reset to Vim’s built-in default
:verbose set opt?the value and the file and line that last set it

:verbose set is the debugger for configuration. Any "why is this on?" question ends there.

:set opt?show the value:set opt!toggle a boolean:set opt+=x / -=x / ^=xappend / remove / prepend to a comma list&opt / &l:opt / &g:optthe value as an expression: echo &tabstop:optionsan interactive, categorised browser of every option

The ones that actually change behaviour

-- init.lua: what is still worth setting in Neovim. -- NOT needed (already the default): hidden, autoindent, -- backspace, incsearch, hlsearch, wildmenu, smarttab, -- nrformats without octal, ttimeoutlen=50 vim.o.ignorecase = true; vim.o.smartcase = true vim.o.expandtab = true vim.o.shiftwidth = 4; vim.o.softtabstop = 4 vim.o.wildmode = 'longest:full,full' vim.o.scrolloff = 3; vim.o.sidescrolloff = 5 -- drives CursorHold and swap writes (default 4000) vim.o.updatetime = 300 vim.o.timeoutlen = 500 -- mapping wait (default 1000) vim.o.undofile = true -- undodir needs no setup vim.o.splitbelow = true; vim.o.splitright = true vim.o.number = true; vim.o.signcolumn = 'yes' vim.o.list = true vim.opt.listchars = { tab = '> ', trail = '·' }

The three ways to say it: :set sw=4 on the command line, vim.o.shiftwidth = 4 in Lua, and vim.opt.x when the option is a list you want to :append() to. vim.bo and vim.wo are :setlocal for buffer and window options.

tabstop is not indentation. 'tabstop' is how wide an existing tab character is drawn (leave it at 8, it is what everyone else’s tools assume), 'shiftwidth' is how far >> moves, and 'softtabstop' is what <Tab> inserts. 'expandtab' decides whether that is spaces. Setting only tabstop=4 makes your file look right and everyone else’s look wrong.

Modelines

/* vim: set ts=4 sw=4 et: */ -- first or last 5 lines

Handy, and a historic attack surface — Vim has had modeline CVEs. Only a safe subset of options is honoured, but if you open untrusted files, set nomodeline and move on.

Mappings

and why always nore

:map is recursive: the result of a mapping is re-scanned for further mappings. That is occasionally what you want and usually a way to hang the editor. Use the nore forms unless you are deliberately invoking another mapping.

PrefixModes it covers
:map :noremap :unmapnormal, visual, select and operator-pending — four at once, which is rarely what you meant
:n…normal
:v…visual and select
:x…visual only — the one you almost always want
:s…select only (typing replaces the selection)
:i…insert
:c…command line
:o…operator-pending — how you add a motion
:t…terminal-job
:l…the "lang-arg" subset: insert, command line and Lang-Arg

Each prefix takes all three suffixes: :nmap / :nnoremap / :nunmap, and so on. :mapclear and its per-mode twins remove the lot.

Arguments, in <> before the left-hand side

<buffer>this buffer only — what an ftplugin should always use<silent>do not echo the command being run<expr>the right-hand side is an expression whose result is the keys<nowait>fire immediately, do not wait for a longer mapping<unique>fail rather than clobber an existing mapping<script>only remap using mappings defined in this script
" set BEFORE any <leader> mapping let mapleader = ' ' nnoremap <leader>w :write<CR> nnoremap <silent> <leader>n :nohlsearch<CR> inoremap jk <Esc> " keep the selection after indenting xnoremap < <gv " count-aware wrapped-line movement nnoremap <expr> j v:count ? 'j' : 'gj' " leave terminal mode with Esc tnoremap <Esc> <C-\><C-n> nnoremap <buffer> <CR> :call Run()<CR> " ftplugin-scoped

Debugging

:mapevery mapping; :nmap <leader> filters:verbose nmap <C-p>which file and line defined it — the answer to "which plugin stole my key"CTRL-V {key}on the command line, insert the literal key code a terminal sends:h key-notationthe canonical spelling of every key name
Terminal Vim cannot see most modified keys. CTRL-I is <Tab>, CTRL-[ is <Esc>, CTRL-M is <CR>, and <C-S> is usually swallowed by terminal flow control (stty -ixon fixes that one). Mapping <Tab> also remaps CTRL-I — and with it your jump-forward key. Neovim asks the terminal at startup whether it speaks the "CSI u" / Kitty keyboard encoding and turns it on if so; in such a terminal <C-I> and <Tab>, <C-M> and <CR>, and <S-CR> are all distinct and mappable. In one that does not, the paragraph above still applies. The macOS card says which is which.
<Plug> mappings exist so plugins do not fight over keys. A plugin defines <Plug>SomeAction, which is unreachable from the keyboard, and you map to it: nmap <leader>s <Plug>SomeAction — and note that this one must be nmap, not nnoremap.
-- the Lua form. Non-recursive by DEFAULT (no "nore") vim.keymap.set('n', '<leader>w', '<cmd>write<cr>', { desc = 'Save', silent = true }) vim.keymap.set('n', 'j', function() return vim.v.count > 0 and 'j' or 'gj' end, { expr = true }) -- buffer-local, as an ftplugin should vim.keymap.set('n', '<CR>', Run, { buf = 0 }) -- to invoke a <Plug> map you need remap = true vim.keymap.set('n', '<leader>s', '<Plug>(Act)', { remap = true })

<cmd>…<cr> runs an ex command without leaving the current mode or touching the command-line history — prefer it to :…<CR> in every mapping. The desc is what :map and which-key style plugins display.

Autocommands

events, groups, and the reload trap

An autocommand runs an ex command when an event fires on a file matching a pattern. Everything filetype-specific in Vim is built out of them.

augroup my_config " CLEAR the group first -- see below autocmd! autocmd FileType python setlocal sw=4 sts=4 et autocmd BufWritePre *.go call Format() autocmd BufReadPost * if line("'\"") > 1 \ && line("'\"") <= line("$") " restore last cursor position \ | exe "normal! g`\"" | endif autocmd VimResized * wincmd = autocmd BufWritePost $MYVIMRC source $MYVIMRC augroup END
Without augroup + autocmd!, sourcing your vimrc twice registers every autocommand twice, and the third time three times. Symptoms: a formatter that runs repeatedly, a sluggish save, "why is this happening twice". :autocmd with no arguments lists them all, so you can see the duplicates.

The events that carry the weight

EventFires
BufReadPost / BufWritePre / BufWritePostafter load, before write, after write
BufNewFileediting a file that does not exist — skeleton templates
FileTypeafter 'filetype' is set — the right place for per-language settings
BufEnter / BufLeave / WinEnterfocus moves between buffers and windows
InsertEnter / InsertLeavemode changes — relative-number toggling lives here
TextChanged / TextChangedIthe buffer changed, in normal / insert mode
CursorHold / CursorHoldI'updatetime' ms with no typing — the idle hook
VimEnter / VimLeavePreafter startup / before exit
QuickFixCmdPostafter :make or :grep — auto-open the quickfix window
TermOpen / TermClosea :terminal job started / ended — Vim’s TerminalWinOpen does not exist here
LspAttach / TextYankPosta language server attached to a buffer / something was yanked
++oncedelete the autocommand after it fires once++nestedallow this command to trigger further autocommands (they are suppressed by default):doautocmd FileTypefire an event by hand — useful after changing an ftplugin:noautocmd {cmd}run cmd with all autocommands suppressed — the fast path for bulk edits:autocmd! my_group BufWritePreremove specific autocommands
Prefer an ftplugin file to a FileType autocommand when the settings are per-language: drop them in ~/.config/nvim/after/ftplugin/python.lua (or .vim) and they load automatically, in the right order, after the distributed one. Use setlocal there, never set.
-- the Lua form. clear = true IS the "autocmd!" local grp = vim.api.nvim_create_augroup('my.cfg', { clear = true }) vim.api.nvim_create_autocmd('FileType', { group = grp, pattern = { 'python', 'lua' }, callback = function(ev) -- ev.buf, ev.match, ev.file vim.bo[ev.buf].shiftwidth = 4 end, }) vim.api.nvim_create_autocmd('BufWritePre', { group = grp, pattern = '*.go', -- or an ex string instead of a callback command = 'lua vim.lsp.buf.format()', })

The Runtime Path

how Neovim finds anything

'runtimepath' is an ordered list of directories. For most kinds of file Vim sources every match in order; for a few (colour schemes, autoload) it takes the first. Understanding the order is understanding why your override does or does not win.

:lua =vim.opt.runtimepath:get() -- abridged ~/.config/nvim -- yours ~/.local/share/nvim/site -- plugins (pack/*/start|opt) $VIMRUNTIME -- what shipped with Neovim ~/.local/share/nvim/site/after ~/.config/nvim/after -- yours again, LAST

Yours first, the distribution’s in the middle, and after/ directories last — which is the whole point: ~/.config/nvim/after/ftplugin/python.lua is sourced after the shipped Python ftplugin, so it can undo it. Every directory in the table below may hold .lua files as well as .vim, and lua/ is searched by require().

DirectoryLoaded
plugin/*.vimonce at startup, always
autoload/foo.vimlazily, the first time foo#Bar() is called — the lazy-loading mechanism
ftplugin/{ft}.vimon FileType; use setlocal and <buffer> maps
indent/{ft}.vimon FileType, sets 'indentexpr'
syntax/{ft}.vimon FileType when :syntax on
ftdetect/*.vimat startup; where a plugin claims new file extensions
colors/*.vimon :colorscheme name — first match wins
compiler/*.vimon :compiler name
doc/*.txtafter :helptags generates the tags file
pack/*/start/*searched at startup — native packages. Neovim searches them without listing them in 'runtimepath'; nvim_list_runtime_paths() shows the real list
lua/{mod}.luaon require('mod'), cached afterwards
lsp/{name}.lua · queries/{lang}/*.scm · parser/{lang}.soLSP configs · tree-sitter queries · parsers — Neovim’s additions to the scheme
pack/*/opt/*only on :packadd name
:scriptnamesevery file sourced, in order — the load-order debugger:runtime! plugin/**/*.vimsource matching files from every rtp entry:filetype on / plugin on / indent onenable detection, ftplugins, indent files:syntax on / :syntax enableon overrides your colours, enable keeps them:set filetype?what Vim thinks this file is:verbose set indentexpr?and which file decided that
Packages need no plugin manager at all. git clone a plugin into ~/.local/share/nvim/site/pack/anything/start/ and it loads; into pack/anything/opt/ and :packadd loads it on demand. Neovim 0.12’s vim.pack is exactly that, automated, with a lockfile — its card is in Part II.

Part II · What Neovim Adds

An API server with an editor inside — macOS setup, the Lua config, the built-in plugin manager, LSP, completion, diagnostics and tree-sitter without plugins, and what 0.12 changed

What Neovim Actually Is

a server with an editor inside

Neovim is not "Vim with Lua plugins". It is Vim’s editing core rebuilt as an API server: every buffer, window, option and keystroke is reachable through one typed, versioned API, and the terminal screen you type into is just the first client of it. Lua, LSP, tree-sitter, remote UIs and the plugin ecosystem are all consequences of that one decision. The grammar — operators, motions, registers, the ex language — is Vim’s, unchanged, and lives on the Vim sheet; this page is everything else.

coreVim’s buffers, windows, grammar, ex commands and Vimscript — but not Vim9 scriptthe APInvim_* functions over msgpack-RPC; the same calls from Lua, Vimscript, or another processLuaLuaJIT 2.1 embedded; vim.* is the standard library and init.lua is a first-class configUIsthe built-in TUI is a client like any other — :detach, :connect, --remote-uibatteriesLSP client, diagnostics, tree-sitter, terminal, snippets, commenting, vim.pack

One API, three ways in

FromLooks likeUse it for
Luavim.api.nvim_buf_set_lines(0, 0, -1, false, t)config and plugins — no serialisation, no process hop
Vimscriptcall nvim_buf_set_lines(0, 0, -1, v:false, t)the same functions are Vimscript built-ins
RPCnvim --server $addr --remote-expr …GUIs, IDE embeds, test harnesses, scripts driving a live editor

The releases that changed how a config is written

0.5init.lua, the LSP client and tree-sitter arrive — the modern era starts here0.10new default colorscheme, built-in commenting (gc), inlay hints, vim.snippet, vim.system(), vim.iter, OSC 52 clipboard0.11vim.lsp.config() / vim.lsp.enable(), the gr* LSP maps, built-in LSP completion, 'winborder', virtual_lines, [q ]q list maps0.12vim.pack plugin manager, 'autocomplete', :lsp, :restart, inline completion, :Undotree, :DiffTool, experimental ui2
Nvim always includes every feature. Vim ships in tiny-to-huge builds with a hundred +feature flags; Neovim has one build. has("clipboard") debugging does not exist here — what can be missing is an external tool (a clipboard program, a language server, git, a C compiler for parsers), and :checkhealth names it.

Installing Neovim

macOS · Windows · Omarchy

Distribution packages lag. The question is never "is it installed" but "is it 0.12", because the config idioms on this page — vim.pack, vim.lsp.enable(), :restart — do not exist in the 0.9 or 0.10 that an LTS distribution still ships.

macOS

Nothing is preinstalled; Apple ships Vim only. Homebrew tracks the stable release closely and builds against LuaJIT.

brew install neovim nvim -v | head -3 # NVIM v0.12.3 / Build type: Release / LuaJIT 2.1 # what servers and formatters will want brew install ripgrep fd git node # the unstable line, side by side brew install --HEAD neovim
Windows — PowerShell

One installer, no GUI of its own — run it in Windows Terminal. 0.12 bundles tee.exe so :make and :grep work out of the box.

winget install --id Neovim.Neovim --exact # or: scoop install neovim # or: choco install neovim -y nvim -v | Select-Object -First 3 # config and data are NOT in ~\.config $env:LOCALAPPDATA\nvim\init.lua $env:LOCALAPPDATA\nvim-data\ # parsers need a C compiler winget install --id LLVM.LLVM
Omarchy / Arch

Omarchy installs Neovim as its default editor with a ready-made config; underneath it is Arch’s own neovim package, which follows the stable release.

sudo pacman -S neovim # clipboard on Wayland is an external tool sudo pacman -S wl-clipboard # servers, grep, parsers sudo pacman -S ripgrep fd git base-devel # try a clean config beside the shipped one NVIM_APPNAME=nvim-mine nvim

Where the files live

stdpath()macOS / LinuxWindows
config~/.config/nvim/~\AppData\Local\nvim\
data~/.local/share/nvim/~\AppData\Local\nvim-data\
state~/.local/state/nvim/ — shada, swap, undo, log~\AppData\Local\nvim-data\
cache~/.cache/nvim/~\AppData\Local\Temp\nvim-data\
plugins…/share/nvim/site/pack/core/opt/under nvim-data\site\
lockfile~/.config/nvim/nvim-pack-lock.jsonbeside init.lua

Every one of these honours $XDG_*_HOME, and $NVIM_APPNAME swaps the nvim path segment in all of them at once: NVIM_APPNAME=nvim-test nvim is a fully separate config, plugin set and history. It is the right way to try a distribution or bisect your own config.

Run :checkhealth before debugging anything. It reports the missing clipboard tool, the absent git, the provider that cannot find Python, the parser that failed to compile and — with :checkhealth vim.lsp — which servers are enabled and attached to which buffers.

Neovim on macOS

terminal · keys · clipboard · servers

Neovim is a terminal program, so on a Mac half of "using it fully" is decided by which terminal it runs in and two settings inside that terminal. The other half is knowing that everything external — clipboard, URL opening, compilers, language servers — is already on the machine or one brew away.

The terminal decides what keys exist

NeedWhyWhere
Option as Metaout of the box Option types å ∂ ƒ; Neovim never sees <M-x> / <A-x> maps until it is turned onTerminal: Settings › Profiles › Keyboard › Use Option as Meta key. iTerm2: Profiles › Keys › Left Option = Esc+
extended keys ("CSI u")makes <C-I>≠<Tab>, <S-CR>, <C-;> mappable; Neovim enables it by itself when the terminal offers itkitty, Ghostty, WezTerm and iTerm2 offer it; Apple’s Terminal does not
truecolor'termguicolors' turns itself on when the terminal reports 24-bit colour; colourschemes look wrong without it:lua =vim.o.termguicolors shows what Neovim decided
a Nerd Fontonly if plugins draw icons; tofu boxes mean the font lacks thembrew install --cask font-jetbrains-mono-nerd-font, then pick it in the terminal
Command-key mappings do not exist in a terminal. <D-s> is valid notation, but ⌘ never reaches a terminal program — the terminal app consumes it. Those maps only fire in a GUI front end (Neovide, VimR). ⌘V still pastes correctly: the terminal sends a bracketed paste and Neovim inserts it as one undoable block, no :set paste — that option is obsolete here. CTRL-S (signature help in Insert mode) needs stty -ixon only if your shell still has flow control on.

What is already wired up

"+y · "+pthe macOS pasteboard, through pbcopy / pbpaste — nothing to installgx · :Openopen the URL or file under the cursor with open(1): browser, Preview, Finder:!open -R %reveal the current file in Finder:Man ls · Kman pages in a buffer, with gO for an outlinecc / clangfrom the Xcode Command Line Tools (xcode-select --install) — needed to compile tree-sitter parsers/usr/bin/clangdships with the same tools: C, C++ and Objective-C need no server installxcrun --find sourcekit-lspSwift’s server, inside Xcodergif installed, :grep already uses it

Shell integration — ~/.zshrc

export EDITOR=nvim VISUAL=nvim alias vi=nvim vim=nvim vimdiff='nvim -d' # man pages in Neovim: search, follow links, gO outline export MANPAGER='nvim +Man!' # git commit, rebase -i, etc. git config --global core.editor nvim # a second, disposable profile for experiments alias nvt='NVIM_APPNAME=nvim-test nvim'

Language servers from Homebrew

brew install lua-language-server # lua_ls brew install pyright ruff # or basedpyright brew install gopls rust-analyzer brew install typescript-language-server brew install bash-language-server marksman jdtls brew install stylua # formatters too brew install tree-sitter-cli # for nvim-treesitter

Each is just a program on PATH (/opt/homebrew/bin on Apple silicon); the LSP card shows the two lines that connect one. :checkhealth vim.lsp tells you whether Neovim found it.

Keeping it current

brew upgrade neovimthen read :help news — the release notes ship inside the editorbrew pin neovimhold the version while a config or plugin catches up; brew unpin laternvim -vconfirm what PATH actually runs; which -a nvim finds a stray second copyuv tool install pynvim0.12’s one-step Python provider — only needed for Python remote plugins, not for LSP:checkhealthafter every upgrade: providers, clipboard, parsers, deprecated calls

init.lua: the Shape of a Config

vim.o · vim.keymap · autocmds

~/.config/nvim/init.lua (or init.vim — never both) runs once at startup. Everything in it is a call into the vim module. There are six namespaces worth knowing, and most configs are nothing but these.

NamespaceIsExample
vim.o vim.bo vim.wooptions as plain values: global-ish, buffer, windowvim.o.number = true
vim.optoptions as objects, for list/map/set optionsvim.opt.listchars:append({ tab = '> ' })
vim.g vim.b vim.w vim.envvariables: g:, b:, w:, $ENVvim.g.mapleader = ' '
vim.fnevery Vimscript functionvim.fn.expand('%:p')
vim.cmdevery ex commandvim.cmd.colorscheme('habamax')
vim.apithe nvim_* APIvim.api.nvim_create_autocmd(…)
vim.g.mapleader = ' ' -- BEFORE any <leader> map vim.o.number = true vim.o.winborder = 'rounded' -- every float, one option vim.o.clipboard = 'unnamedplus' -- vim.keymap.set is non-recursive by default vim.keymap.set('n', '<leader>w', '<cmd>write<cr>', { desc = 'Save' }) vim.keymap.set({ 'n', 'x' }, '<leader>y', '"+y') local grp = vim.api.nvim_create_augroup('my.cfg', { clear = true }) -- re-sourcing is safe vim.api.nvim_create_autocmd('TextYankPost', { group = grp, callback = function() vim.hl.on_yank() end, }) vim.api.nvim_create_user_command('Scratch', function() vim.cmd.new(); vim.bo.buftype = 'nofile' end, { desc = 'Throwaway buffer' })

The directory is the config

init.luathe entry pointlua/me/x.luarequire('me.x') — modules, cached after first loadplugin/*.luasourced automatically at startup, after init.lua, alphabeticallyafter/ftplugin/go.luaper-filetype settings that must win over the runtime’slsp/clangd.luaone LSP config per file; returns a table — see the LSP cardafter/lsp/clangd.luayour overrides on top of a plugin’s config for the same servernvim-pack-lock.jsonvim.pack’s lockfile — commit it

Trying things without restarting

:lua =vim.o.shadaevaluate and pretty-print; :=expr is the short form:lua vim.print(x)same, from code:source %run the current Lua or Vim file; with a range, runs just those lines:restartrestart the server and reattach this UI — ZR from Normal mode. New in 0.12:verbose map grawho defined this mapping, and in which file
Project-local config is built in. Set vim.o.exrc = true and Nvim runs .nvim.lua, .nvimrc or .exrc from the current directory and, since 0.12, every parent — but only files you have approved. An unknown file prompts; choose (v)iew, read it, then run :trust. There is deliberately no one-key "allow" any more.

Defaults You No Longer Set

delete half your vimrc

Most of a classic .vimrc is a list of settings everyone agrees on. Neovim made them the defaults. Read out of nvim --clean on 0.12.3:

Already onValueReplaces
syntax, filetype, indentenabledsyntax on, filetype plugin indent on
'hidden' 'autoread' 'autoindent' 'smarttab'onthe first four lines of everyone’s vimrc
'hlsearch' 'incsearch'on; CTRL-L clears the highlightthe :nohl mapping
'inccommand'nosplitlive preview of :s as you type — Vim has no equivalent
'mouse'nvi, right-click menuset mouse=a; type : to select text natively
'laststatus'2, with diagnostics, LSP progress and a busy flaga statusline plugin, for many people
'grepprg'rg --vimgrep -uu when ripgrep existsthe ripgrep snippet
'undodir' 'directory' 'backupdir'under ~/.local/state/nvim/, auto-createdthe mkdir -p dance; just set undofile
'completeopt'menu,popup
'diffopt'…,indent-heuristic,inline:char,linematch:40character-level diff inside changed lines
'termguicolors'on when the terminal reports truecolorset termguicolors
'history' 'wildoptions' 'ttimeoutlen'10000 · pum,tagfile · 50
pluginsmatchit, :Man, editorconfig, spellfile downloadpackadd! matchit; the editorconfig plugin

Default mappings worth knowing on day one

gcc · gc{motion}toggle comments; gc is also a text object (dgc)grn gra grr gri grt grx gOLSP: rename, action, references, implementation, type, codelens, symbolsK · CTRL-S (insert)hover · signature help]d [d ]D [D · CTRL-W dnext/prev/last/first diagnostic · show it in a float]q [q ]l [l ]b [b ]a [a ]t [tquickfix, location, buffer, argument and tag lists; capitals for first/last] Space · [ Spaceadd a blank line below / above, with a countan in ]n [n (visual)grow / shrink / walk the selection by syntax node. New in 0.12Y · & · Q @ (visual)y$ · :&& · run a macro on every selected linegxopen the path, URL or LSP document link under the cursor

The index below lists every one with its mode, read out of nvim_get_keymap(). To opt out of one, vim.keymap.del('n', 'grn'); of all, :mapclear early in the config.

0.12 changed a few defaults silently. 'shelltemp' is now off (filters use pipes, not temp files); CTRL-R in Insert mode pastes registers literally instead of replaying them as typed keys (faster, no auto-indent mangling — <C-R>=@x gets the old behaviour); 'shada' skips /tmp/ and /private/ so :oldfiles stays clean; and Markdown now highlights with tree-sitter out of the box.

vim.pack: the Built-in Plugin Manager

new in 0.12

vim.pack is a plugin manager that is part of the editor. It is deliberately small: it clones Git repositories into one directory, checks out a version, runs :packadd, and records what it did in a lockfile. There is no lazy-loading DSL, no build-step field, no UI beyond one confirmation buffer. The docs still call it experimental, yet stable enough for daily use.

vim.pack.add({ -- a URL is a complete spec 'https://github.com/neovim/nvim-lspconfig', -- follow a branch, tag or commit { src = 'https://github.com/user/plug', version = 'main' }, -- newest semver tag inside a range { src = 'https://github.com/user/other', version = vim.version.range('1.x') }, -- directory name, when the repo name is generic { src = 'https://github.com/user/nvim', name = 'theme' }, }) -- usable immediately after add() require('other').setup({})
DoHow
installadd the spec, :restart; missing plugins are cloned (it asks once) before add() returns
update:lua vim.pack.update() → a review buffer of pending commits. :write applies, :quit discards
inspectvim.pack.update(nil, { offline = true }) — the same buffer, no network; ]] [[ between plugins, gO outline, K details, gra per-plugin actions
pinset version to the rev from the lockfile
roll backgit checkout HEAD -- nvim-pack-lock.json, :restart, then vim.pack.update({'x'}, { offline = true, target = 'lockfile' })
removedelete the spec, :restart, vim.pack.del({ 'x' }) — removing the spec alone leaves it on disk
new machinepull the config with its lockfile; the first vim.pack call installs everything at the locked revisions

Build steps are an autocommand

-- define BEFORE vim.pack.add() to catch first installs vim.api.nvim_create_autocmd('PackChanged', { callback = function(ev) local d = ev.data -- kind, spec, path, active if d.spec.name == 'telescope-fzf-native.nvim' and d.kind ~= 'delete' then vim.system({ 'make' }, { cwd = d.path }) end end, })
Where it sits next to lazy.nvim. vim.pack owns exactly one directory, site/pack/core/opt, and assumes nothing else writes there; other managers use their own, so the two can coexist while you migrate. What you give up is lazy-loading by event, key or command. What you get is a manager that cannot be broken by a plugin-manager bug at startup, a lockfile in your dotfiles, and one fewer bootstrap snippet. For laziness, call vim.pack.add() later — inside an autocommand or a mapping — it loads immediately when called after startup.
It needs git on PATH and a writable data directory. Under nvim --clean the site directory is not on 'packpath', so plugins appear not to exist — that is the flag working, not a broken install.

LSP Without a Plugin

vim.lsp.config · vim.lsp.enable

The client is built in; the servers are separate programs you install yourself. Since 0.11 wiring one up takes two calls, and nvim-lspconfig has shrunk to what it always should have been: a directory of ready-made config files you may or may not want.

-- ~/.config/nvim/lsp/lua_ls.lua -- one file per server return { cmd = { 'lua-language-server' }, filetypes = { 'lua' }, -- nested list = equal priority root_markers = { { '.luarc.json', '.luarc.jsonc' }, '.git' }, settings = { Lua = { runtime = { version = 'LuaJIT' } }, }, } -- init.lua vim.lsp.config('*', { root_markers = { '.git' } }) vim.lsp.enable({ 'lua_ls', 'clangd', 'gopls' })

How a config is resolved — lowest to highest

1 · vim.lsp.config('*', …)defaults for every server2 · lsp/NAME.luaanywhere on 'runtimepath' — this is where nvim-lspconfig’s files land3 · after/lsp/NAME.luayour override of a plugin’s file4 · vim.lsp.config('NAME', …)anything set in code wins

Merging is vim.tbl_deep_extend('force', …): tables merge key by key, but a list replaces the whole list. Setting filetypes = { 'c' } drops cpp; it does not add to it.

What attaching does for you

Set on attachSo this works
'omnifunc'CTRL-X CTRL-O completes from the server
'tagfunc'CTRL-], :tjump, CTRL-W ] go to definition
'formatexpr'gq formats through the server; gw does not
Khover, unless you mapped K or set 'keywordprg'
diagnostics, document colourson by default

Off until you ask

vim.lsp.inlay_hint.enable(true) vim.lsp.codelens.enable(true) -- grx runs one vim.lsp.linked_editing_range.enable(true) vim.lsp.on_type_formatting.enable(true) vim.lsp.inline_completion.enable(true) -- ghost text

Operating it

:checkhealth vim.lspenabled configs, running clients, which buffers, log path, file-watcher backend:lsp restart [name]restart clients on this buffer — the answer to "the server went weird". New in 0.12:lsp stop · :lsp enable · :lsp disableinteractive twins of vim.lsp.enable():lua =vim.lsp.get_clients()[1].server_capabilitieswhat this server can actually dovim.lsp.log.set_level('debug')then read the file vim.lsp.log.get_filename() names
"Nothing happens" is almost always the root. A server attaches only when the buffer’s filetype is in filetypes and, for many servers, a root_markers file is found walking upward. A loose file in /tmp has no root. :checkhealth vim.lsp shows the config as enabled-but-not-attached, which is the tell. Set workspace_required = true to make that explicit rather than half-working.

Completion & Snippets, Built In

'autocomplete' · vim.lsp.completion

Three layers, all shipped, none on by default beyond the first. A completion plugin is now a preference, not a requirement.

LayerTurn onGives
Vim’s insert completionalways there: CTRL-N, CTRL-X CTRL-O …buffer words, omni, files, lines
'autocomplete' (0.12)vim.o.autocomplete = truethe menu opens as you type, from the 'complete' sources
LSP completionvim.lsp.completion.enable(true, id, buf, { autotrigger = true })server items, resolve-on-select docs, snippet expansion, auto-imports
vim.opt.completeopt = { 'menuone', 'noselect', 'popup', 'fuzzy', 'nearest' } -- 'nearest' is 0.12 vim.o.pumborder = 'rounded' -- 0.12 vim.o.pummaxwidth = 60 -- 0.12 vim.api.nvim_create_autocmd('LspAttach', { callback = function(ev) local c = vim.lsp.get_client_by_id(ev.data.client_id) if c:supports_method('textDocument/completion') then vim.lsp.completion.enable(true, c.id, ev.buf, { autotrigger = true }) end end, })
CTRL-Y · CTRL-Eaccept · dismiss. CTRL-N / CTRL-P moveTab · S-Tabjump between snippet tabstops while a snippet is active; otherwise a plain Tabvim.snippet.expand(body)expand LSP-syntax snippet text: ${1:name}, $0'complete' F{func} · o · ^N0.12: a function or 'omnifunc' as a source; .^5 caps a source at five matches

Inline completion — multi-line ghost text

0.12 implements LSP textDocument/inlineCompletion, the protocol behind AI suggestions. It is a plain LSP server like any other: install one (the docs’ quick-start uses copilot-language-server), give it a config, vim.lsp.enable() it, then call vim.lsp.inline_completion.enable(). Suggestions draw as overlay text; vim.lsp.inline_completion.get() accepts one, and you map it to whatever key you like.

What the built-ins still lack: sources beyond LSP and 'complete' (no path or snippet-library source), per-source ranking UI, and documentation beside the menu in every case. If you want those, keep your completion plugin; if you only ever used LSP items and buffer words, you can delete it.

Diagnostics

vim.diagnostic · one framework for every source

vim.diagnostic is independent of LSP: language servers publish into it, and so can a linter wrapper, a compiler-output parser, or ten lines of your own Lua. One configuration call governs how all of them are drawn.

Inline messages are off by default. Since 0.11 virtual_text defaults to false: you get signs, underlines and the statusline count, but no text beside the line until you ask for it. A fresh config that "shows no errors" is usually this.
local S = vim.diagnostic.severity vim.diagnostic.config({ -- text at end of line, only where the cursor is virtual_text = { current_line = true }, -- or whole messages on their own lines below the code virtual_lines = false, severity_sort = true, float = { source = true }, signs = { text = { [S.ERROR] = 'E', [S.WARN] = 'W' } }, })
]d [d · ]D [Dnext / previous · last / first in the bufferCTRL-W dopen the float for the cursor line; inside it, gf jumps to related locations (0.12)vim.diagnostic.jump({ count = 1, severity = S.ERROR })the function behind ]d; replaces goto_next()vim.diagnostic.setqflist() · setloclist()all diagnostics into the quickfix / location list; 0.12 adds a format filtervim.diagnostic.enable(false, { bufnr = 0 })mute a buffer; is_enabled() to togglevim.diagnostic.status()the E:2 W:1 string the default statusline shows (0.12)vim.diagnostic.set(ns, buf, list)publish your own — this is all a linter plugin does
Signs moved. Defining DiagnosticSignError with :sign define was deprecated in 0.10 and stopped working in 0.12. The glyphs go in vim.diagnostic.config({ signs = { text = … } }), as above.

Tree-sitter

a real parser, incrementally

Regex syntax files guess at structure line by line. Tree-sitter parses the buffer into a syntax tree and re-parses only what an edit touched. Highlighting is the least of it: folding, indentation, text objects, selection and "what is under the cursor" all become queries over one tree.

Ships with Nvim
parsersC, Lua, Markdown (+ inline), Vimscript, Vimdoc, Query
highlighting on by default forLua, Markdown (0.12), help files, query files
everything elseinstall a parser (parser/{lang}.so on 'runtimepath') — normally via the nvim-treesitter plugin, which needs a C compiler — then start it yourself
vim.api.nvim_create_autocmd('FileType', { pattern = { 'python', 'go', 'rust' }, callback = function(ev) -- pcall: no parser installed is not an error if pcall(vim.treesitter.start, ev.buf) then vim.wo.foldmethod = 'expr' vim.wo.foldexpr = 'v:lua.vim.treesitter.foldexpr()' end end, })
:InspectTreethe live syntax tree in a split; moving in either window moves the other:Inspectevery highlight, capture, semantic token and extmark under the cursor — "why is this red?":EditQuerywrite a query, see matches highlighted live in the source bufferv then an · inselect the enclosing node · shrink back. Falls back to LSP selection ranges without a parser (0.12)]n [n · ]N [N (visual)move the selection to the next / previous node · sibling (0.12)vim.treesitter.get_node()the node at the cursor; :type(), :parent(), :range():checkhealth vim.treesitterwhich parsers were found, and their ABI versions
0.12: get_parser() returns nil instead of throwing. Code that wrapped it in pcall keeps working; code that assumed a parser object will now index nil. Queries live in queries/{lang}/*.scm on 'runtimepath' and later files extend earlier ones with a ;; extends modeline — which is how you add a capture without forking.

Terminal, Jobs & Processes

:terminal · vim.system

Neovim has had a real terminal emulator and asynchronous jobs since long before Vim’s, and the interfaces differ. A terminal is a buffer: you can search it, yank from it, and leave it running in a hidden window.

:terminal [cmd]open one in the current window; :vs | term for a spliti · aenter Terminal mode — keys go to the programCTRL-\ CTRL-Nback to Normal mode; the buffer is now ordinary, read-only textCTRL-\ CTRL-Oone Normal-mode command, then back[[ · ]]jump between shell prompts, if the shell emits OSC 133 marks'scrollback'lines kept; the ceiling rose to 1,000,000 in 0.12

A shell started with plain :terminal closes its buffer when it exits cleanly. Anything else stays, with [Process exited] drawn as virtual text rather than written into the buffer, and the exit code in the statusline (both 0.12). Programs running inside see synchronized output (mode 2026), so full-screen TUIs no longer tear.

Running a program from Lua

-- synchronous: wait for the result local r = vim.system({ 'git', 'status', '-s' }, { text = true, cwd = vim.fn.getcwd() }):wait() print(r.code, r.stdout) -- asynchronous: callback runs in a fast context, -- so hop back to the main loop before touching buffers vim.system({ 'make' }, { text = true }, vim.schedule_wrap(function(res) vim.notify('make: ' .. res.code) end))
WantUse
run a command, get outputvim.system() — no shell, argv list, :wait() or callback
a PTY, a terminal buffer, or an RPC childjobstart(cmd, { term = true }) / { pty = true } / { rpc = true }
timers, file watchers, sockets, the event loopvim.uv — libuv itself (was vim.loop)
an HTTP GETvim.net.request(url, opts, cb) — new in 0.12
delay or debouncevim.defer_fn(fn, ms), vim.schedule(fn)
E5560 inside a callback. vim.uv callbacks run between editor ticks, where most of the API is forbidden. Wrap the body in vim.schedule() or the callback in vim.schedule_wrap(). Vim’s job_start(), ch_* and term_start() do not exist here at all — see the last index card.

The API: Extmarks, Floats & Namespaces

what plugins are made of

Almost everything a Neovim plugin draws is one of three primitives. Knowing them turns "how did they do that" into "which of the three".

PrimitiveIsUsed for
namespacean integer from nvim_create_namespace('name')ownership: clear everything you drew with one call, touch nobody else’s
extmarka position in a buffer that moves with the text, carrying decorationhighlights, virtual text, virtual lines, signs, conceal, inline hints, diagnostics
floating windowa window positioned by coordinates, not by the layouthover, completion docs, pickers, notifications
local ns = vim.api.nvim_create_namespace('demo') -- (buffer, ns, 0-based row, 0-based col, opts) vim.api.nvim_buf_set_extmark(0, ns, 0, 0, { virt_text = { { ' <- note', 'Comment' } }, virt_text_pos = 'eol', }) vim.api.nvim_buf_clear_namespace(0, ns, 0, -1) -- (listed, scratch) local buf = vim.api.nvim_create_buf(false, true) vim.api.nvim_open_win(buf, true, { relative = 'editor', row = 3, col = 10, width = 40, height = 8, title = ' hi ', -- border omitted: inherits 'winborder' })

Conventions that prevent most bugs

0 means "current"buffer 0, window 0, tabpage 0rows and cols are 0-based, end-exclusivein nvim_buf_*; but nvim_win_get_cursor() is (1,0)-based — row from 1, column from 0columns are bytesnot characters, not screen cells; vim.str_utfindex() convertshandles, not numbersa window ID survives layout changes; a window number does notnvim_get_option_value(name, { buf = 0 })the one option getter; nvim_buf_get_option and friends are deprecatedapi-level0.12 is level 14; vim.fn.has('nvim-0.12') is the readable check
0.12 renamed a key. The autocommand functions now take buf = where they took buffer =. The old spelling still works, so nothing breaks — but new code and the docs use buf, matching vim.keymap.set(…, { buf = 0 }) and the option getters.

Headless, Remote & Scripting

nvim -l · --listen · --server

Because the editor is a server, "running Neovim" and "looking at Neovim" are separable. That gives you a Lua interpreter with an editor attached, a scriptable batch tool, and an editor you can reattach to.

nvim -l script.lua [args]run a Lua script and exit; _G.arg holds the arguments. A LuaJIT with vim.* for freenvim --headless +'cmd' +qno UI; run ex commands against files, then quitnvim --cleanfactory defaults: no config, no plugins, no shada — the first step of every bug reportnvim -u NONE · -u min.luaskip or substitute the config, keep everything elsenvim --startuptime t.logper-file startup timingsnvim -V1 -vversion plus the compile-time paths it searchesnvim -d a bdiff mode, with 0.12’s inline character-level highlights

One server, many front ends

# start a server with a known address nvim --listen /tmp/nv.sock # open a file in it from another shell nvim --server /tmp/nv.sock --remote notes.md # send keys / evaluate an expression nvim --server /tmp/nv.sock --remote-send ':wa<CR>' nvim --server /tmp/nv.sock --remote-expr 'bufname()' # attach a second terminal UI to the same session nvim --server /tmp/nv.sock --remote-ui
$NVIMinside :terminal, the parent’s address — how a nested nvim or a git editor hook finds the outer onev:servernamethis instance’s address; every Nvim listens on one:detachdrop this UI, leave the server running:connect {addr}point this UI at a different server (0.12):restartrestart the server, reattach every UI (0.12)
--remote-wait is not implemented. The flag Vim users put in $GIT_EDITOR to block until the file is closed is documented here as "not yet supported". Tools that need to wait use a plugin or a plain nested nvim.

ui2 — the experimental message UI

0.12 ships a redesign of the message and command-line area, off by default: require('vim._core.ui2').enable({}). It removes "Press ENTER" prompts, highlights the command line as you type, and makes the pager an ordinary buffer. It is explicitly experimental and the module path has an underscore in it for a reason — expect it to move.

What 0.12 Changed

read before upgrading a config

From :help news as shipped with 0.12.3. The index marks every entry the release notes name.

New, and worth adopting

vim.packbuilt-in plugin manager with a lockfile'autocomplete'completion menu as you type, no plugin:lsp · :restart · ZR · :connectmanage servers and the editor process interactivelyinline completion, linked editing, on-type formatting, document colours, selection rangesfive more LSP capabilities; all but colours are opt-incode lenses as virtual lines · grx · grtreimplemented codelens; two new default maps:Undotree · :DiffToolbundled, opt-in with :packadd nvim.undotree / nvim.difftoolan in ]n [nincremental selection by syntax node'pumborder' 'pummaxwidth' · 'winborder' "bold"borders for the popup menu too:iput · :uniq · :retab -indentonly · :wall ++psmall ex additions:help!guess the help tag under the cursor; K in help buffers uses it, gx opens the online docsvim.net.request · vim.list.unique / bisect · vim.fs.ext · vim.json indent / sort_keysstandard-library fill-insstatuslinedefault now shows diagnostics, LSP progress, a busy flag and terminal exit codes; native OSC 9;4 progress bars

Breaking — check your config for these

If you haveDo
sign define DiagnosticSign*move to vim.diagnostic.config({ signs = { text = … } })
vim.diagnostic.disable() / is_disabled()enable(false, …) / is_enabled() — the old ones are gone
vim.diff()renamed vim.text.diff()
vim.lsp.semantic_tokens.start() / stop().enable(true|false)
== nil checks on LSP response fieldsJSON null is now vim.NIL; a missing field is still nil
:TOhtml:packadd nvim.tohtml first — now opt-in
vim.treesitter.get_parser() in a bare callcheck for nil; it no longer throws
mappings that relied on CTRL-R replaying a register as keys<C-R>=@x
'exrc' muscle memory for "(a)llow"(v)iew, then :trust
Deprecated is not removed. Everything on the Deprecations card still runs in 0.12.3; the removals are the short table above. :checkhealth vim.deprecated reports the deprecated functions your config and plugins actually called this session — far faster than reading the list.

Coming From Vim, and the Traps

what bites fluent people

Bringing a vimrc across

" ~/.config/nvim/init.vim -- the documented bridge set runtimepath^=~/.vim runtimepath+=~/.vim/after let &packpath = &runtimepath source ~/.vimrc

That runs unchanged unless the vimrc uses Vim9 script (vim9script, def, classes), which Neovim does not and will not implement, or Vim-only functions (popup_*, job_start, ch_*, prop_*). Guard the rest with if has('nvim').

VimNeovim
~/.vimrc, ~/.vim/~/.config/nvim/init.lua, ~/.config/nvim/
~/.viminfoshada, ~/.local/state/nvim/shada/main.shada; :rshada :wshada
+clipboard compiled ina provider: pbcopy, wl-copy, xclip, win32yank, or OSC 52 over SSH
popup_create(), text propertiesnvim_open_win() floats, extmarks
job_start(), channelsvim.system(), jobstart(), chansend()
:terminal + term_*():terminal, CTRL-\ CTRL-N, TermOpen / TermClose
Vim9 scriptLua
:hardcopy, cscope, :X encryption, netbeansremoved

The traps

vim.o assigns, vim.opt edits. vim.o.shortmess = 'c' replaces the whole value; vim.opt.shortmess:append('c') adds to it. And reading vim.opt.x returns an object — you want vim.o.x, or vim.opt.x:get().
mapleader is read when a mapping is defined, not when it is used. Set vim.g.mapleader on the first line of init.lua, above every plugin and every vim.pack.add(), or some maps bind to backslash.
require() caches. Editing lua/me/x.lua and re-sourcing init.lua re-runs nothing in it. Clear package.loaded['me.x'], or use :restart — which in 0.12 is finally quick enough to be the answer.
Clipboard "doesn’t work" over SSH or in a container. There is no pasteboard program to call. Nvim falls back to OSC 52 when the terminal advertises it, but a multiplexer in the middle can swallow the sequence; force it with vim.g.clipboard = 'osc52' (0.12 accepts the name as a string).
Snippets from the internet are dated by their API. vim.loop is vim.uv; vim.highlight is vim.hl; nvim_buf_set_option is vim.bo[buf].x =; vim.lsp.start_client, buf_get_clients, diagnostic.goto_next and require('lspconfig').x.setup{} are all the pre-0.11 way. They mostly still run — with a warning — and the Deprecations card gives each replacement.

Finding the culprit

nvim --cleandoes it still happen with no config at all?NVIM_APPNAME=nvim-bisect nvima scratch config to rebuild the problem from nothing:checkhealtheverything external; :checkhealth vim.deprecated for stale API calls:verbose set option?which file last set it:Inspectwhich highlight group, capture or extmark is colouring this cell:messages · g<what scrolled past:lua =vim.pack.get()what is installed, at which revision, and whether it is loaded

Index I · Every vi and Vim Command, as Neovim Has It

Every normal, insert, visual, window and command-line key, all 553 ex commands, all 374 options with Neovim’s defaults, 464 Vimscript functions and 145 events — read from this Neovim’s own index, not Vim’s. Type in the filter box, or press /

Normal Mode

204

Every normal-mode command, from Nvim’s index.txt

CTRL-Aadd N to number at/after cursor
CTRL-Bscroll N screens Backwards
CTRL-Cinterrupt current (search) command
CTRL-Dscroll Down N lines (default: half a screen)
CTRL-Escroll N lines upwards (N lines Extra)
CTRL-Fscroll N screens Forward
CTRL-Gdisplay current file name and position
<BS>same as "h"
CTRL-Hsame as "h"
<Tab>go to N newer entry in jump list
CTRL-Isame as <Tab>
<NL>same as "j"
<S-NL>same as CTRL-F
CTRL-Jsame as "j" CTRL-K not used
CTRL-Lredraw screen
<CR>cursor to the first CHAR N lines lower
<S-CR>same as CTRL-F
CTRL-Msame as <CR>
CTRL-Nsame as "j"
CTRL-Ogo to N older entry in jump list
CTRL-Psame as "k" CTRL-Q not used, or used for terminal control flow
CTRL-Rredo changes which were undone with 'u' CTRL-S not used, or used for terminal control flow
CTRL-Tjump to N older Tag in tag list
CTRL-Uscroll N lines Upwards (default: half a screen)
CTRL-Vstart blockwise Visual mode
CTRL-W {char}window commands, see CTRL-W
CTRL-Xsubtract N from number at/after cursor
CTRL-Yscroll N lines downwards
CTRL-Zsuspend program (or start new shell) CTRL-[ <Esc> not used
CTRL-\ CTRL-Ngo to Normal mode (no-op)
CTRL-\ CTRL-Ggo to Normal mode (no-op) CTRL-\ a - z reserved for extensions CTRL-\ others not used
CTRL-]:ta to ident under cursor
CTRL-^edit Nth alternate file (equivalent to ":e #N")
CTRL-<Tab>same as g<Tab> : go to last accessed tab page CTRL-_ not used
<Space>same as "l" 2 filter Nmove text through the {filter} command
!!{filter}filter N lines through the {filter} command
"{register}use {register} for next delete, yank or put ({.%#:} only work with put)
#search backward for the Nth occurrence of the ident under the cursor
$cursor to the end of Nth next line
%find the next (curly/square) bracket on this line and go to its match, or go to matching comment bracket, or go to matching preprocessor directive.
{count}%go to N percentage in the file
&repeat last :s
'{a-zA-Z0-9}cursor to the first CHAR on the line with mark {a-zA-Z0-9}
''cursor to the first CHAR of the line where the cursor was before the latest jump.
'(cursor to the first CHAR on the line of the start of the current sentence
')cursor to the first CHAR on the line of the end of the current sentence
'<cursor to the first CHAR of the line where highlighted area starts/started in the current buffer.
'>cursor to the first CHAR of the line where highlighted area ends/ended in the current buffer.
'[cursor to the first CHAR on the line of the start of last operated text or start of put text
']cursor to the first CHAR on the line of the end of last operated text or end of put text
'{cursor to the first CHAR on the line of the start of the current paragraph
'}cursor to the first CHAR on the line of the end of the current paragraph
(cursor N sentences backward
)cursor N sentences forward
*search forward for the Nth occurrence of the ident under the cursor
+same as <CR>
<S-+>same as CTRL-F
,repeat latest f, t, F or T in opposite direction N times
-cursor to the first CHAR N lines higher
<S-->same as CTRL-B
.repeat last change with count replaced with N
/{pattern}<CR>search forward for the Nth occurrence of {pattern}
/<CR>search forward for {pattern} of last search
0cursor to the first char of the line
1prepend to command to give a count
2"
3"
4"
5"
6"
7"
8"
9"
:start entering an Ex command
{count}:start entering an Ex command with range from current line to N-1 lines down
;repeat latest f, t, F or T N times
<{motion}shift Nmove lines one 'shiftwidth' leftwards
<<shift N lines one 'shiftwidth' leftwards
={motion}filter Nmove lines through "indent"
==filter N lines through "indent"
>{motion}shift Nmove lines one 'shiftwidth' rightwards
>>shift N lines one 'shiftwidth' rightwards
?{pattern}<CR>search backward for the Nth previous occurrence of {pattern}
?<CR>search backward for {pattern} of last search
@{a-z}execute the contents of register {a-z} N times
@:repeat the previous ":" command N times
@@repeat the previous @{a-z} N times
Aappend text after the end of the line N times
Bcursor N WORDS backward
["x]Cchange from the cursor position to the end of the line, and N-1 more lines [into register x]; synonym for "c$"
["x]Ddelete the characters under the cursor until the end of the line and N-1 more lines [into register x]; synonym for "d$"
Ecursor forward to the end of WORD N
F{char}cursor to the Nth occurrence of {char} to the left
Gcursor to line N, default last line
Hcursor to line N from top of screen
Iinsert text before the first CHAR on the line N times
JJoin N lines; default is 2
Klookup Keyword under the cursor with 'keywordprg'
Lcursor to line N from bottom of screen
Mcursor to middle line of screen
Nrepeat the latest '/' or '?' N times in opposite direction
Obegin a new line above the cursor and insert text, repeat N times
["x]Pput the text [from register x] before the cursor N times
Renter replace mode: overtype existing characters, repeat the entered text N-1 times
["x]Sdelete N lines [into register x] and start insert; synonym for "cc".
T{char}cursor till after Nth occurrence of {char} to the left
Uundo all latest changes on one line
Vstart linewise Visual mode
Wcursor N WORDS forward
["x]Xdelete N characters before the cursor [into register x]
["x]Yyank N lines [into register x]; synonym for "yy" Note: Mapped to "y$" by default. default-mappings
ZZwrite if buffer changed and close window
ZQclose window without writing
[{char}square bracket command (see [ below) \ not used
]{char}square bracket command (see ] below)
^cursor to the first CHAR of the line
_cursor to the first CHAR N - 1 lines lower
`{a-zA-Z0-9}cursor to the mark {a-zA-Z0-9}
`(cursor to the start of the current sentence
`)cursor to the end of the current sentence
`<cursor to the start of the highlighted area
`>cursor to the end of the highlighted area
`[cursor to the start of last operated text or start of putted text
`]cursor to the end of last operated text or end of putted text
"``"cursor to the position before latest jump
`{cursor to the start of the current paragraph
`}cursor to the end of the current paragraph
aappend text after the cursor N times
bcursor N words backward
["x]c{motion}delete Nmove text [into register x] and start insert
["x]ccdelete N lines [into register x] and start insert
["x]d{motion}delete Nmove text [into register x]
["x]dddelete N lines [into register x]
dosame as ":diffget"
dpsame as ":diffput"
ecursor forward to the end of word N
f{char}cursor to Nth occurrence of {char} to the right
g{char}extended commands, see g below
hcursor N chars to the left
iinsert text before the cursor N times
jcursor N lines downward
kcursor N lines upward
lcursor N chars to the right
m{A-Za-z}set mark {A-Za-z} at cursor position
nrepeat the latest '/' or '?' N times
obegin a new line below the cursor and insert text, repeat N times
["x]pput the text [from register x] after the cursor N times
q{0-9a-zA-Z"}record typed characters into named register {0-9a-zA-Z"} (uppercase to append)
q(while recording) stops recording
Qreplay last recorded register
q:edit : command-line in command-line window
q/edit / command-line in command-line window
q?edit ? command-line in command-line window
r{char}replace N chars with {char}
["x]s(substitute) delete N characters [into register x] and start insert
t{char}cursor till before Nth occurrence of {char} to the right
uundo changes
vstart charwise Visual mode
wcursor N words forward
["x]xdelete N characters under and after the cursor [into register x]
["x]y{motion}yank Nmove text [into register x]
["x]yyyank N lines [into register x]
z{char}commands starting with 'z', see z below
{cursor N paragraphs backward
|cursor to column N
}cursor N paragraphs forward
~'tildeop' off: switch case of N characters under cursor and move the cursor N characters to the right
~{motion}'tildeop' on: switch case of Nmove text
<C-End>same as "G"
<C-Home>same as "gg"
<C-Left>same as "b"
<C-LeftMouse>":ta" to the keyword at the mouse click
<C-Right>same as "w"
<C-Tab>same as "g<Tab>"
["x]<Del>same as "x"
{count}<Del>remove the last digit from {count}
<Down>same as "j"
<End>same as "$"
<F1>same as <Help>
<Help>open a help window
<Home>same as "0"
<Insert>same as "i"
<Left>same as "h"
<LeftMouse>move cursor to the mouse click position
<MiddleMouse>same as "gP" at the mouse click position
<PageDown>same as CTRL-F
<PageUp>same as CTRL-B
<Right>same as "l"
<RightMouse>start Visual mode, move cursor to the mouse click position
<S-Down>same as CTRL-F
<S-Left>same as "b"
<S-LeftMouse>same as "*" at the mouse click position
<S-Right>same as "w"
<S-Up>same as CTRL-B
<Undo>same as "u"
<Up>same as "k"
*<ScrollWheelDown>*<ScrollWheelDown> move window three lines down
*<S-ScrollWheelDown>*<S-ScrollWheelDown> move window one page down
*<ScrollWheelUp>*<ScrollWheelUp> move window three lines up
*<S-ScrollWheelUp>*<S-ScrollWheelUp> move window one page up
*<ScrollWheelLeft>*<ScrollWheelLeft> move window six columns left
*<S-ScrollWheelLeft>*<S-ScrollWheelLeft> move window one page left
*<ScrollWheelRight>*<ScrollWheelRight> move window six columns right
*<S-ScrollWheelRight>*<S-ScrollWheelRight> move window one page right

Text Objects & Operators

39

Text objects — after an operator or in visual mode

a"double quoted string
a'single quoted string
a(same as ab
a)same as ab
a<"a <>" from '<' to the matching '>'
a>same as a<
aB"a Block" from [{ to ]} (with brackets)
aW"a WORD" (with white space)
a["a []" from '[' to the matching ']'
a]same as a[
a`string in backticks
ab"a block" from "[(" to "])" (with braces)
ap"a paragraph" (with white space)
as"a sentence" (with white space)
at"a tag block" (with white space)
aw"a word" (with white space)
a{same as aB
a}same as aB
i"double quoted string without the quotes
i'single quoted string without the quotes
i(same as ib
i)same as ib
i<"inner <>" from '<' to the matching '>'
i>same as i<
iB"inner Block" from [{ and ]}
iW"inner WORD"
i["inner []" from '[' to the matching ']'
i]same as i[
i`string in backticks without the backticks
ib"inner block" from "[(" to "])"
ip"inner paragraph"
is"inner sentence"
it"inner tag block"
iw"inner word"
i{same as iB
i}same as iB

Operator-pending mode

vforce operator to work charwise
Vforce operator to work linewise
CTRL-Vforce operator to work blockwise

Insert Mode

85

Insert and replace mode

CTRL-@insert previously inserted text and stop insert
CTRL-Ainsert previously inserted text
CTRL-Cquit insert mode, without checking for abbreviation
CTRL-Ddelete one shiftwidth of indent in the current line
CTRL-Einsert the character which is below the cursor CTRL-F not used (but by default it's in 'cinkeys' to re-indent the current line)
CTRL-G CTRL-Jline down, to column where inserting started
CTRL-G jline down, to column where inserting started
CTRL-G <Down>line down, to column where inserting started
CTRL-G CTRL-Kline up, to column where inserting started
CTRL-G kline up, to column where inserting started
CTRL-G <Up>line up, to column where inserting started
CTRL-G ustart new undoable edit
CTRL-G Udon't break undo with next cursor movement
<BS>delete character before the cursor enter digraph (only when 'digraph' option set)
CTRL-Hsame as <BS>
<Tab>insert a <Tab> character
CTRL-Isame as <Tab>
<NL>same as <CR>
CTRL-Jsame as <CR> enter digraph
<CR>begin new line
CTRL-Msame as <CR>
CTRL-Nfind next match for keyword in front of the cursor
CTRL-Oexecute a single command and return to insert mode
CTRL-Pfind previous match for keyword in front of the cursor
CTRL-Qsame as CTRL-V, unless used for terminal control flow like CTRL-Q unless tui-modifyOtherKeys is active insert the contents of a register insert the contents of a register literally insert the contents of a register literally and don't auto-indent insert the contents of a register literally and fix indent. CTRL-S not used or used for terminal control flow
CTRL-Tinsert one shiftwidth of indent in current line
CTRL-Udelete all entered characters in the current line
CTRL-V {char}insert next non-digit literally like CTRL-V unless tui-modifyOtherKeys is active byte.
CTRL-Wdelete word before the cursor
CTRL-X {mode}enter CTRL-X sub mode, see i_CTRL-X_index
CTRL-Yinsert the character which is above the cursor
<Esc>end insert mode
CTRL-[same as <Esc> CTRL-\ a - z reserved for extensions CTRL-\ others not used
CTRL-]trigger abbreviation
CTRL-^toggle use of :lmap mappings
CTRL-_When 'allowrevins' set: toggle 'revins' <Space> to '~' not used, except '0' and '^' followed by CTRL-D
0 CTRL-Ddelete all indent in the current line
^ CTRL-Ddelete all indent in the current line, restore it in the next line
<Del>delete character under the cursor Meta characters (0x80 to 0xff, 128 to 255) not used
<Left>cursor one character left
<S-Left>cursor one word left
<C-Left>cursor one word left
<Right>cursor one character right
<S-Right>cursor one word right
<C-Right>cursor one word right
<Up>cursor one line up
<S-Up>same as <PageUp>
<Down>cursor one line down
<S-Down>same as <PageDown>
<Home>cursor to start of line
<C-Home>cursor to start of file
<End>cursor past end of line
<C-End>cursor past end of file
<PageUp>one screenful backward
<PageDown>one screenful forward
<F1>same as <Help>
<Help>stop insert mode and display help window
<Insert>toggle Insert/Replace mode
<LeftMouse>cursor at mouse click
<ScrollWheelDown>move window three lines down
<S-ScrollWheelDown>move window one page down
<ScrollWheelUp>move window three lines up
<S-ScrollWheelUp>move window one page up
<ScrollWheelLeft>move window six columns left
<S-ScrollWheelLeft>move window one page left
<ScrollWheelRight>move window six columns right
commands in CTRL-X submode*i_CTRL-X_index*
CTRL-X CTRL-Dcomplete defined identifiers
CTRL-X CTRL-Escroll up
CTRL-X CTRL-Fcomplete file names
CTRL-X CTRL-Icomplete identifiers
CTRL-X CTRL-Kcomplete identifiers from dictionary
CTRL-X CTRL-Lcomplete whole lines
CTRL-X CTRL-Nnext completion
CTRL-X CTRL-Oomni completion
CTRL-X CTRL-Pprevious completion
CTRL-X CTRL-Rcomplete contents from registers
CTRL-X CTRL-Sspelling suggestions
CTRL-X CTRL-Tcomplete identifiers from thesaurus
CTRL-X CTRL-Yscroll down
CTRL-X CTRL-Ucomplete with 'completefunc'
CTRL-X CTRL-Vcomplete like in : command line
CTRL-X CTRL-Zstop completion, text is unchanged
CTRL-X CTRL-]complete tags
CTRL-X sspelling suggestions CTRL-L insert one character from the current match <CR> insert currently selected match <BS> delete one character and redo search CTRL-H same as <BS> <Up> select the previous match <Down> select the next match <PageUp> select a match several entries back <PageDown> select a match several entries forward other stop completion and insert the typed character

Visual & Select Mode

81

Where visual differs from normal

CTRL-Aadd N to number in highlighted text
CTRL-Cstop Visual mode
CTRL-Gtoggle between Visual mode and Select mode
<BS>Select mode: delete highlighted area
CTRL-Hsame as <BS>
CTRL-Oswitch from Select to Visual mode for one command
CTRL-Vmake Visual mode blockwise or stop Visual mode
CTRL-Xsubtract N from number in highlighted text
<Esc>stop Visual mode
CTRL-]jump to highlighted tag
!{filter}filter the highlighted lines through the external command {filter}
:start a command-line with the highlighted lines as a range
<shift the highlighted lines one 'shiftwidth' left
=filter the highlighted lines through the external program given with the 'equalprg' option
>shift the highlighted lines one 'shiftwidth' right
Ablock mode: append same text in all lines, after the highlighted area
Cdelete the highlighted lines and start insert
Ddelete the highlighted lines
Iblock mode: insert same text in all lines, before the highlighted area
Jjoin the highlighted lines
Krun 'keywordprg' on the highlighted area
Omove horizontally to other corner of area
Preplace highlighted area with register contents; registers are unchanged
Rdelete the highlighted lines and start insert
Sdelete the highlighted lines and start insert
Umake highlighted area uppercase
Vmake Visual mode linewise or stop Visual mode
Xdelete the highlighted lines
Yyank the highlighted lines
a"extend highlighted area with a double quoted string
a'extend highlighted area with a single quoted string
a(same as ab
a)same as ab
a<extend highlighted area with a <> block
a>same as a<
aBextend highlighted area with a {} block
aWextend highlighted area with "a WORD"
a[extend highlighted area with a [] block
a]same as a[
a`extend highlighted area with a backtick quoted string
abextend highlighted area with a () block
apextend highlighted area with a paragraph
asextend highlighted area with a sentence
atextend highlighted area with a tag block
awextend highlighted area with "a word"
a{same as aB
a}same as aB
cdelete highlighted area and start insert
ddelete highlighted area
g CTRL-Aadd N to number in highlighted text
g CTRL-Xsubtract N from number in highlighted text
gJjoin the highlighted lines without inserting spaces
gqformat the highlighted lines
gvexchange current and previous highlighted area
i"extend highlighted area with a double quoted string (without quotes)
i'extend highlighted area with a single quoted string (without quotes)
i(same as ib
i)same as ib
i<extend highlighted area with inner <> block
i>same as i<
iBextend highlighted area with inner {} block
iWextend highlighted area with "inner WORD"
i[extend highlighted area with inner [] block
i]same as i[
i`extend highlighted area with a backtick quoted string (without the backticks)
ibextend highlighted area with inner () block
ipextend highlighted area with inner paragraph
isextend highlighted area with inner sentence
itextend highlighted area with inner tag block
iwextend highlighted area with "inner word"
i{same as iB
i}same as iB
omove cursor to other corner of area
preplace highlighted area with register contents; deleted text in unnamed register
rreplace highlighted area with a character
sdelete highlighted area and start insert
umake highlighted area lowercase
vmake Visual mode charwise or stop Visual mode
xdelete the highlighted area
yyank the highlighted area
~swap case for the highlighted area

Window Commands

73

CTRL-W — splits, sizes and movement

CTRL-W CTRL-Bsame as "CTRL-W b"
CTRL-W CTRL-Cno-op
CTRL-W CTRL-Dsame as "CTRL-W d"
CTRL-W CTRL-Fsame as "CTRL-W f" CTRL-W CTRL-G same as "CTRL-W g .."
CTRL-W CTRL-Hsame as "CTRL-W h"
CTRL-W CTRL-Isame as "CTRL-W i"
CTRL-W CTRL-Jsame as "CTRL-W j"
CTRL-W CTRL-Ksame as "CTRL-W k"
CTRL-W CTRL-Lsame as "CTRL-W l"
CTRL-W CTRL-Nsame as "CTRL-W n"
CTRL-W CTRL-Osame as "CTRL-W o"
CTRL-W CTRL-Psame as "CTRL-W p"
CTRL-W CTRL-Qsame as "CTRL-W q"
CTRL-W CTRL-Rsame as "CTRL-W r"
CTRL-W CTRL-Ssame as "CTRL-W s"
CTRL-W CTRL-Tsame as "CTRL-W t"
CTRL-W CTRL-Vsame as "CTRL-W v"
CTRL-W CTRL-Wsame as "CTRL-W w"
CTRL-W CTRL-Xsame as "CTRL-W x"
CTRL-W CTRL-Zsame as "CTRL-W z"
CTRL-W CTRL-]same as "CTRL-W ]"
CTRL-W CTRL-^same as "CTRL-W ^"
CTRL-W CTRL-_same as "CTRL-W _"
CTRL-W +increase current window height N lines
CTRL-W -decrease current window height N lines
CTRL-W <decrease current window width N columns
CTRL-W =make all windows the same height & width
CTRL-W >increase current window width N columns
CTRL-W Hmove current window to the far left
CTRL-W Jmove current window to the very bottom
CTRL-W Kmove current window to the very top
CTRL-W Lmove current window to the far right
CTRL-W Pgo to preview window
CTRL-W Rrotate windows upwards N times
CTRL-W Ssame as "CTRL-W s"
CTRL-W Tmove current window to a new tabpage
CTRL-W Wgo to N previous window (wrap around)
CTRL-W ]split window and jump to tag under cursor
CTRL-W ^split current window and edit alternate file N
CTRL-W _set current window height to N (default: very high)
CTRL-W bgo to bottom window
CTRL-W cclose current window (like :close)
CTRL-W dsplit window and jump to definition under the cursor
CTRL-W fsplit window and edit file name under the cursor
CTRL-W Fsplit window and edit file name under the cursor and jump to the line number following the file name. cursor
CTRL-W g ]split window and do :tselect for tag under cursor
CTRL-W g }do a :ptjump to the tag under the cursor
CTRL-W g fedit file name under the cursor in a new tabpage
CTRL-W g Fedit file name under the cursor in a new tabpage and jump to the line number following the file name.
CTRL-W g tsame as gt: go to next tabpage
CTRL-W g Tsame as gT: go to previous tabpage
CTRL-W g <Tab>same as g<Tab>: go to last accessed tab page
CTRL-W hgo to Nth left window (stop at first window)
CTRL-W isplit window and jump to declaration of identifier under the cursor
CTRL-W jgo N windows down (stop at last window)
CTRL-W kgo N windows up (stop at first window)
CTRL-W lgo to Nth right window (stop at last window)
CTRL-W nopen new window, N lines high
CTRL-W oclose all but current window (like :only)
CTRL-W pgo to previous (last accessed) window
CTRL-W qquit current window (like :quit)
CTRL-W rrotate windows downwards N times
CTRL-W ssplit current window in two parts, new window N lines high
CTRL-W tgo to top window
CTRL-W vsplit current window vertically, new window N columns wide
CTRL-W wgo to N next window (wrap around)
CTRL-W xexchange current window with window N (default: next window)
CTRL-W zclose preview window
CTRL-W |set window width to N columns
CTRL-W }show tag under cursor in preview window
CTRL-W <Down>same as "CTRL-W j"
CTRL-W <Up>same as "CTRL-W k"
CTRL-W <Left>same as "CTRL-W h"

Bracket Commands

44

[ and ]

[ CTRL-Djump to first #define found in current and included files matching the word under the cursor, start searching at beginning of current file
[ CTRL-Ijump to first line in current and included files that contains the word under the cursor, start searching at beginning of current file
[#cursor to N previous unmatched #if, #else or #ifdef
['cursor to previous lowercase mark, on first non-blank
[(cursor N times back to unmatched '('
[*same as "[/"
[`cursor to previous lowercase mark
[/cursor to N previous start of a C comment
[Dlist all defines found in current and included files matching the word under the cursor, start searching at beginning of current file
[Ilist all lines found in current and included files that contain the word under the cursor, start searching at beginning of current file
[Psame as "[p"
[[cursor N sections backward
[]cursor N SECTIONS backward
[ccursor N times backwards to start of change
[dshow first #define found in current and included files matching the word under the cursor, start searching at beginning of current file
[fsame as "gf"
[ishow first line found in current and included files that contains the word under the cursor, start searching at beginning of current file
[mcursor N times back to start of member function
[plike "P", but adjust indent to current line
[smove to the previous misspelled word
[zmove to start of open fold
[{cursor N times back to unmatched '{'
] CTRL-Djump to first #define found in current and included files matching the word under the cursor, start searching at cursor position
] CTRL-Ijump to first line in current and included files that contains the word under the cursor, start searching at cursor position
]#cursor to N next unmatched #endif or #else
]'cursor to next lowercase mark, on first non-blank
])cursor N times forward to unmatched ')'
]*same as "]/"
]`cursor to next lowercase mark
]/cursor to N next end of a C comment
]Dlist all #defines found in current and included files matching the word under the cursor, start searching at cursor position
]Ilist all lines found in current and included files that contain the word under the cursor, start searching at cursor position
]Psame as "[p"
][cursor N SECTIONS forward
]]cursor N sections forward
]ccursor N times forward to start of change
]dshow first #define found in current and included files matching the word under the cursor, start searching at cursor position
]fsame as "gf"
]ishow first line found in current and included files that contains the word under the cursor, start searching at cursor position
]mcursor N times forward to end of member function
]plike "p", but adjust indent to current line
]smove to next misspelled word
]zmove to end of open fold
]}cursor N times forward to unmatched '}'

g Commands

66

The second normal-mode namespace

g CTRL-Gshow information about current cursor position
g CTRL-Hstart Select block mode
g CTRL-]:tjump to the tag under the cursor
g#like "#", but without using "\<" and "\>"
g$when 'wrap' off go to rightmost character of the current line that is on the screen; when 'wrap' on go to the rightmost character of the current screen line
g&repeat last ":s" on all lines
g'{mark}like ' but without changing the jumplist
g`{mark}like ` but without changing the jumplist
g*like "*", but without using "\<" and "\>"
g+go to newer text state N times
g,go to N newer position in change list
g-go to older text state N times
g0when 'wrap' off go to leftmost character of the current line that is on the screen; when 'wrap' on go to the leftmost character of the current screen line
g8print hex value of bytes used in UTF-8 character under the cursor
g;go to N older position in change list
g<display previous command output
g?Rot13 encoding operator
g??Rot13 encode current line
g?g?Rot13 encode current line
gDgo to definition of word under the cursor in current file
gEgo backwards to the end of the previous WORD
gHstart Select line mode
gIlike "I", but always start in column 1
gJjoin lines without inserting space
gN1,2 find the previous match with the last used search pattern and Visually select it
["x]gPput the text [from register x] before the cursor N times, leave the cursor after it
gQswitch to "Ex" mode with Vim editing
gRenter Virtual Replace mode
gTgo to the previous tabpage
gU{motion}make Nmove text uppercase
gVdon't reselect the previous Visual area when executing a mapping or menu in Select mode
g]:tselect on the tag under the cursor
g^when 'wrap' off go to leftmost non-white character of the current line that is on the screen; when 'wrap' on go to the leftmost non-white character of the current screen line
g_cursor to the last CHAR N - 1 lines lower
gaprint ascii value of character under the cursor
gdgo to definition of word under the cursor in current function
gego backwards to the end of the previous word
gfstart editing the file whose name is under the cursor
gFstart editing the file whose name is under the cursor and jump to the line number following the filename.
ggcursor to line N, default first line
ghstart Select mode
gilike "i", but first move to the '^ mark
gjlike "j", but when 'wrap' on go N screen lines down
gklike "k", but when 'wrap' on go N screen lines up
gmgo to character at middle of the screenline
gMgo to character at middle of the text line
gn1,2 find the next match with the last used search pattern and Visually select it
gocursor to byte N in the buffer
["x]gpput the text [from register x] after the cursor N times, leave the cursor after it
gq{motion}format Nmove text
gr{char}virtual replace N chars with {char}
gsgo to sleep for N seconds (default 1)
gtgo to the next tabpage
gu{motion}make Nmove text lowercase
gvreselect the previous Visual area
gw{motion}format Nmove text and keep cursor
gxexecute application for filepath at cursor
g@{motion}call 'operatorfunc'
g~{motion}swap case for Nmove text
g<Down>same as "gj"
g<End>same as "g$" but go to the rightmost non-blank character instead
g<Home>same as "g0"
g<LeftMouse>same as <C-LeftMouse> g<MiddleMouse> same as <C-MiddleMouse>
g<RightMouse>same as <C-RightMouse>
g<Tab>go to last accessed tabpage
g<Up>same as "gk"

z Commands

52

Scrolling, folding and spelling

z<CR>redraw, cursor line to top of window, cursor on first non-blank
z{height}<CR>redraw, make window {height} lines high
z+cursor on line N (default line below window), otherwise like "z<CR>"
z-redraw, cursor line at bottom of window, cursor on first non-blank
z.redraw, cursor line to center of window, cursor on first non-blank
z=give spelling suggestions
zAopen a closed fold or close an open fold recursively
zCclose folds recursively
zDdelete folds recursively
zEeliminate all folds
zFcreate a fold for N lines
zGtemporarily mark word as correctly spelled
zHwhen 'wrap' off scroll half a screenwidth to the right
zLwhen 'wrap' off scroll half a screenwidth to the left
zMset 'foldlevel' to zero
zNset 'foldenable'
zOopen folds recursively
zRset 'foldlevel' to the deepest fold
zWtemporarily mark word as incorrectly spelled
zXre-apply 'foldlevel'
z^cursor on line N (default line above window), otherwise like "z-"
zaopen a closed fold, close an open fold
zbredraw, cursor line at bottom of window
zcclose a fold
zddelete a fold
zewhen 'wrap' off scroll horizontally to position the cursor at the end (right side) of the screen
zf{motion}create a fold for Nmove text
zgpermanently mark word as correctly spelled
zhwhen 'wrap' off scroll screen N characters to the right
zitoggle 'foldenable'
zjmove to the start of the next fold
zkmove to the end of the previous fold
zlwhen 'wrap' off scroll screen N characters to the left
zmsubtract one from 'foldlevel'
znreset 'foldenable'
zoopen fold
zppaste in block-mode without trailing spaces
zPpaste in block-mode without trailing spaces
zradd one to 'foldlevel'
zswhen 'wrap' off scroll horizontally to position the cursor at the start (left side) of the screen
ztredraw, cursor line at top of window
zuwundo zw
zugundo zg
zuWundo zW
zuGundo zG
zvopen enough folds to view the cursor line
zwpermanently mark word as incorrectly spelled
zxre-apply 'foldlevel' and do "zv"
zyyank without trailing spaces
zzredraw, cursor line at center of window
z<Left>same as "zh"
z<Right>same as "zl"

Command-line Editing

46

Keys while typing a : / or ? line

CTRL-Ado completion on the pattern in front of the cursor and insert all matches
CTRL-Bcursor to begin of command-line
CTRL-Csame as <Esc>
CTRL-Dlist completions that match the pattern in front of the cursor
CTRL-Ecursor to end of command-line
'cedit'CTRL-F default value for 'cedit': opens the command-line window; otherwise not used
CTRL-Gnext match when 'incsearch' is active
<BS>delete the character in front of the cursor enter digraph when 'digraph' is on
CTRL-Hsame as <BS>
<Tab>if 'wildchar' is <Tab>: Do completion on the pattern in front of the cursor
<S-Tab>same as CTRL-P
'wildchar'Do completion on the pattern in front of the cursor (default: <Tab>)
CTRL-Isame as <Tab>
<NL>same as <CR>
CTRL-Jsame as <CR> enter digraph
CTRL-Ldo completion on the pattern in front of the cursor and insert the longest common part
<CR>execute entered command
CTRL-Msame as <CR>
CTRL-Nafter using 'wildchar' with multiple matches: go to next match, otherwise: recall older command-line from history. CTRL-O not used
CTRL-Pafter using 'wildchar' with multiple matches: go to previous match, otherwise: recall older command-line from history.
CTRL-Qsame as CTRL-V, unless it's used for terminal control flow insert the contents of a register or object under the cursor as if typed insert the contents of a register or object under the cursor literally CTRL-S not used, or used for terminal control flow
CTRL-Tprevious match when 'incsearch' is active
CTRL-Uremove all characters between the cursor and beginning of command-line
CTRL-Vinsert next non-digit literally, insert three digit decimal number as a single byte.
CTRL-Wdelete the word in front of the cursor CTRL-X not used (reserved for completion) CTRL-Y copy (yank) modeless selection CTRL-Z not used (reserved for suspend)
<Esc>abandon command-line without executing it
CTRL-[same as <Esc> CTRL-\ a - d reserved for extensions {expr} CTRL-\ f - z reserved for extensions CTRL-\ others not used
CTRL-]trigger abbreviation
CTRL-^toggle use of :lmap mappings
<Del>delete the character under the cursor
<Left>cursor left
<S-Left>cursor one word left
<C-Left>cursor one word left
<Right>cursor right
<S-Right>cursor one word right
<C-Right>cursor one word right
<Up>recall previous command-line from history that matches pattern in front of the cursor
<S-Up>recall previous command-line from history
<Down>recall next command-line from history that matches pattern in front of the cursor
<S-Down>recall next command-line from history
<Home>cursor to start of command-line
<End>cursor to end of command-line
<PageDown>same as <S-Down>
<PageUp>same as <S-Up>
<Insert>toggle insert/overstrike mode
<LeftMouse>cursor at mouse click <Up> move up to parent <Down> move down to submenu <Left> select the previous match <Right> select the next match <CR> move into submenu when doing menu completion CTRL-E stop completion and go back to original text CTRL-Y accept selected match and stop completion other stop completion and insert the typed character <PageUp> select a match several entries back <PageDown> select a match several entries forward

Registers, Marks & Ranges

49

Registers

"a – "znamed registers; you fill them
"A – "Zappend to the matching lowercase register
""the unnamed register — last delete or yank
"0the yank register — last y only
"1 – "9delete ring; "1 is the newest multi-line delete
"-small delete register: deletes of less than one line
"_the black hole — write only
"+the system clipboard (CLIPBOARD selection)
"*the X11 primary selection (middle-click); same as "+ on Windows/macOS
"%name of the current file
"#name of the alternate file
".the last inserted text
":the last command line
"/the last search pattern
"=the expression register
:reg[isters] [x]show register contents
let @a = "text"set a register from script
q{reg} … qrecord keystrokes into a register
@{reg} / @@replay a register / replay the last replayed
:@aexecute register a as ex commands

Marks and jumps

m{a-zA-Z}set a mark; lowercase = file-local, uppercase = global
`a / 'ato mark a, exact position / first non-blank of its line
`` / ''to the position before the last jump
`.to the position of the last change
`^to where insert mode was last left
`[ / `]start / end of the last changed or yanked text
`< / `>start / end of the last visual selection
`"position when the file was last exited
:markslist all marks
:delm[arks] a b / :delm!delete marks / all lowercase marks
CTRL-O / CTRL-Iolder / newer position in the jump list

Range atoms for ex commands

{n}line n; 0 means "before the first line"
.the current line
$the last line of the file
%the whole file — shorthand for 1,$
*the last visual selection — same as '<,'>
'xthe line of mark x
/pat/ / ?pat?next / previous line matching pat
\/ / \?next / previous line matching the last search pattern
+n / -nn lines after / before the preceding address
;separator that moves the cursor to the first address first
:{range}norm[al] {keys}run normal-mode keys on every line in the range
:g/pat/{cmd}run cmd on every line matching pat
:v/pat/{cmd} / :g!run cmd on every line NOT matching pat
:g/pat/d _delete matching lines into the black hole
:{range}t {addr}copy the range to after addr (:co[py])
:{range}m {addr}move the range to after addr
:{range}!cmdfilter the range through an external command
:r !cmd / :w !cmdread command output in / write range to a command

Patterns & Substitute

22

Vim regex, offsets and :s

\vvery magic — almost PCRE: ( ) + ? { } | are special
\m / \M / \Vmagic (default) / nomagic / very nomagic
\< / \>start / end of word
\zs / \zeset start / end of the match
\@= \@! \@<= \@<!lookahead / negative / lookbehind / negative
\%Vinside the visual selection
\%d123 \%x7f \%u20acmatch a character by decimal, hex or Unicode value
\%23l \%23c \%23vonly on line 23 / column 23 / virtual column 23
\{n,m} \{-}count; \{-} is the non-greedy *
\(...\) / \1capture group / backreference
\%(...\)non-capturing group
\i \k \f \p \s \d \x \o \w \h \a \l \ucharacter classes; uppercase negates
[[:alpha:]]POSIX character classes inside []
\c / \Cforce case-insensitive / case-sensitive for the whole pattern
/pat/e /pat/s+2 /pat/;/pat2/search offsets and chained searches
:s/pat/rep/[flags]substitute in the range
& ~ \0 \1–\9in the replacement: whole match, previous replacement, groups
\u \l \U \L \Ecase-fold the rest of the replacement
\=exprthe replacement is a Vim expression
g c i I n e:s flags — all matches, confirm, ignore case, match case, count only, no error
:%s//rep/gempty pattern reuses the last search
:&& / g&repeat the last :s with its flags / on the whole file

Ex Commands

553

Every ":" command Neovim has

:nothing
:{range}go to last line in {range}
:!filter lines or execute an external command
:!!repeat last ":!" command
:#same as ":number"
:&repeat last ":substitute"
:*use the last Visual area, like ":'<,'>"
:<shift lines one 'shiftwidth' left
:=print the last line number
:>shift lines one 'shiftwidth' right
:@execute contents of a register
:@@repeat the previous ":@"
:2mat[ch]define a second match to highlight
:3mat[ch]define a third match to highlight
:N[ext]go to previous file in the argument list
:a[ppend]append text
:ab[breviate]enter abbreviation
:abc[lear]remove all abbreviations
:abo[veleft]make split window appear left or above
:al[l]open a window for each file in the argument list
:am[enu]enter new menu item for all modes
:an[oremenu]enter a new menu for all modes that will not be remapped
:ar[gs]print the argument list
:arga[dd]add items to the argument list
:argded[upe]remove duplicates from the argument list
:argd[elete]delete items from the argument list
:arge[dit]add item to the argument list and edit it
:argdodo a command on all items in the argument list
:argg[lobal]define the global argument list
:argl[ocal]define a local argument list
:argu[ment]go to specific file in the argument list
:as[cii]print ascii value of character under the cursor
:au[tocmd]enter or show autocommands
:aug[roup]select the autocommand group to use
:aun[menu]remove menu for all modes
:b[uffer]go to specific buffer in the buffer list
:bN[ext]go to previous buffer in the buffer list
:ba[ll]open a window for each buffer in the buffer list
:bad[d]add buffer to the buffer list
:baltlike ":badd" but also set the alternate file
:bd[elete]remove a buffer from the buffer list
:bel[owright]make split window appear right or below
:bf[irst]go to first buffer in the buffer list
:bl[ast]go to last buffer in the buffer list
:bm[odified]go to next buffer in the buffer list that has been modified
:bn[ext]go to next buffer in the buffer list
:bo[tright]make split window appear at bottom or far right
:bp[revious]go to previous buffer in the buffer list
:br[ewind]go to first buffer in the buffer list
:brea[k]break out of while loop
:breaka[dd]add a debugger breakpoint
:breakd[el]delete a debugger breakpoint
:breakl[ist]list debugger breakpoints
:bro[wse]use file selection dialog
:bufd[o]execute command in each listed buffer
:bufferslist all files in the buffer list
:bun[load]unload a specific buffer
:bw[ipeout]really delete a buffer
:c[hange]replace a line or series of lines
:cN[ext]go to previous error
:cNf[ile]go to last error in previous file
:ca[bbrev]like ":abbreviate" but for Command-line mode
:cabc[lear]clear all abbreviations for Command-line mode
:cabo[ve]go to error above current line
:cad[dbuffer]add errors from buffer
:cadde[xpr]add errors from expr
:caddf[ile]add error message to current quickfix list
:caf[ter]go to error after current cursor
:cal[l]call a function
:cat[ch]part of a :try command
:cbe[fore]go to error before current cursor
:cbel[ow]go to error below current line
:cbo[ttom]scroll to the bottom of the quickfix window
:cb[uffer]parse error messages and jump to first error
:ccgo to specific error
:ccl[ose]close quickfix window
:cdchange directory
:cdoexecute command in each valid error list entry
:cfd[o]execute command in each file in error list
:ce[nter]format lines at the center
:cex[pr]read errors from expr and jump to first
:cf[ile]read file with error messages and jump to first
:cfir[st]go to the specified error, default first one
:cgetb[uffer]get errors from buffer
:cgete[xpr]get errors from expr
:cg[etfile]read file with error messages
:changesprint the change list
:chd[ir]change directory
:che[ckhealth]run healthchecks
:checkp[ath]list included files
:checkt[ime]check timestamp of loaded buffers
:chi[story]list the error lists
:cla[st]go to the specified error, default last one
:cle[arjumps]clear the jump list
:cl[ist]list all errors
:clo[se]close current window
:cm[ap]like ":map" but for Command-line mode
:cmapc[lear]clear all mappings for Command-line mode
:cme[nu]add menu for Command-line mode
:cn[ext]go to next error
:cnew[er]go to newer error list
:cnf[ile]go to first error in next file
:cno[remap]like ":noremap" but for Command-line mode
:cnorea[bbrev]like ":noreabbrev" but for Command-line mode
:cnoreme[nu]like ":noremenu" but for Command-line mode
:co[py]copy lines
:col[der]go to older error list
:colo[rscheme]load a specific color scheme
:com[mand]create user-defined command
:comc[lear]clear all user-defined commands
:comp[iler]do settings for a specific compiler
:con[tinue]go back to :while
:conf[irm]prompt user when confirmation required
:cons[t]create a variable as a constant
:cope[n]open quickfix window
:cp[revious]go to previous error
:cpf[ile]go to last error in previous file
:cq[uit]quit Vim with an error code
:cr[ewind]go to the specified error, default first one
:cu[nmap]like ":unmap" but for Command-line mode
:cuna[bbrev]like ":unabbrev" but for Command-line mode
:cunme[nu]remove menu for Command-line mode
:cw[indow]open or close quickfix window
:d[elete]delete lines
:deb[ug]run a command in debugging mode
:debugg[reedy]read debug mode commands from normal input
:defe[r]call function when current function is done
:delc[ommand]delete user-defined command
:delf[unction]delete a user function
:delm[arks]delete marks
:detachdetach the current UI
:dif[fupdate]update 'diff' buffers
:diffg[et]remove differences in current buffer
:diffo[ff]switch off diff mode
:diffp[atch]apply a patch and show differences
:diffpu[t]remove differences in other buffer
:diffs[plit]show differences with another file
:difft[his]make current window a diff window
:dig[raphs]show or enter digraphs
:di[splay]display registers
:dj[ump]jump to #define
:dlshort for :delete with the 'l' flag
:dli[st]list #defines
:do[autocmd]apply autocommands to current buffer
:doautoa[ll]apply autocommands for all loaded buffers
:d[elete]pshort for :delete with the 'p' flag
:dr[op]jump to window editing file or edit file in current window
:ds[earch]list one #define
:dsp[lit]split window and jump to #define
:e[dit]edit a file
:ea[rlier]go to older change, undo
:ec[ho]echoes the result of expressions
:echoe[rr]like :echo, show like an error and use history
:echoh[l]set highlighting for echo commands
:echom[sg]same as :echo, put message in history
:echonsame as :echo, but without <EOL>
:el[se]part of an :if command
:elsei[f]part of an :if command
:em[enu]execute a menu by name
:en[dif]end previous :if
:endfo[r]end previous :for
:endf[unction]end of a user function started with :function
:endt[ry]end previous :try
:endw[hile]end previous :while
:ene[w]edit a new, unnamed buffer
:ev[al]evaluate an expression and discard the result
:exsame as ":edit"
:exe[cute]execute result of expressions
:exi[t]same as ":xit"
:exu[sage]overview of Ex commands
:fc[lose]close floating window
:f[ile]show or set the current file name
:fileslist all files in the buffer list
:filet[ype]switch file type detection on/off
:filt[er]filter output of following command
:fin[d]find file in 'path' and edit it
:fina[lly]part of a :try command
:fini[sh]quit sourcing a Vim script
:fir[st]go to the first file in the argument list
:fo[ld]create a fold
:foldc[lose]close folds
:foldd[oopen]execute command on lines not in a closed fold
:folddoc[losed]execute command on lines in a closed fold
:foldo[pen]open folds
:forfor loop
:fu[nction]define a user function
:g[lobal]execute commands for matching lines
:go[to]go to byte in the buffer
:gr[ep]run 'grepprg' and jump to first match
:grepa[dd]like :grep, but append to current list
:gu[i]start the GUI
:gv[im]start the GUI
:h[elp]open a help window
:helpc[lose]close one help window
:helpg[rep]like ":grep" but searches help files
:helpt[ags]generate help tags for a directory
:hi[ghlight]specify highlighting methods
:hid[e]hide current buffer for a command
:his[tory]print a history list
:hor[izontal]following window command work horizontally
:i[nsert]insert text
:ia[bbrev]like ":abbrev" but for Insert mode
:iabc[lear]like ":abclear" but for Insert mode
:ifexecute commands when condition met
:ij[ump]jump to definition of identifier
:il[ist]list lines where identifier matches
:im[ap]like ":map" but for Insert mode
:imapc[lear]like ":mapclear" but for Insert mode
:ime[nu]add menu for Insert mode
:ino[remap]like ":noremap" but for Insert mode
:inorea[bbrev]like ":noreabbrev" but for Insert mode
:inoreme[nu]like ":noremenu" but for Insert mode
:int[ro]print the introductory message
:ip[ut]like :put, but adjust the indent to the current line
:is[earch]list one line where identifier matches
:isp[lit]split window and jump to definition of identifier
:iu[nmap]like ":unmap" but for Insert mode
:iuna[bbrev]like ":unabbrev" but for Insert mode
:iunme[nu]remove menu for Insert mode
:j[oin]join lines
:ju[mps]print the jump list
:kset a mark
:keepa[lt]following command keeps the alternate file
:kee[pmarks]following command keeps marks where they are
:keepj[umps]following command keeps jumplist and marks
:keepp[atterns]following command keeps search pattern history
:lN[ext]go to previous entry in location list
:lNf[ile]go to last entry in previous file
:l[ist]print lines
:lab[ove]go to location above current line
:lad[dexpr]add locations from expr
:laddb[uffer]add locations from buffer
:laddf[ile]add locations to current location list
:laf[ter]go to location after current cursor
:la[st]go to the last file in the argument list
:lan[guage]set the language (locale)
:lat[er]go to newer change, redo
:lbe[fore]go to location before current cursor
:lbel[ow]go to location below current line
:lbo[ttom]scroll to the bottom of the location window
:lb[uffer]parse locations and jump to first location
:lc[d]change directory locally
:lch[dir]change directory locally
:lcl[ose]close location window
:ld[o]execute command in valid location list entries
:lfd[o]execute command in each file in location list
:le[ft]left align lines
:lefta[bove]make split window appear left or above
:letassign a value to a variable or option
:lex[pr]read locations from expr and jump to first
:lf[ile]read file with locations and jump to first
:lfir[st]go to the specified location, default first one
:lgetb[uffer]get locations from buffer
:lgete[xpr]get locations from expr
:lg[etfile]read file with locations
:lgr[ep]run 'grepprg' and jump to first match
:lgrepa[dd]like :grep, but append to current list
:lh[elpgrep]like ":helpgrep" but uses location list
:lhi[story]list the location lists
:llgo to specific location
:lla[st]go to the specified location, default last one
:lli[st]list all locations
:lmak[e]execute external command 'makeprg' and parse error messages
:lm[ap]like ":map!" but includes Lang-Arg mode
:lmapc[lear]like ":mapclear!" but includes Lang-Arg mode
:lne[xt]go to next location
:lnew[er]go to newer location list
:lnf[ile]go to first location in next file
:ln[oremap]like ":noremap!" but includes Lang-Arg mode
:loadk[eymap]load the following keymaps until EOF
:lo[adview]load view for current window from a file
:loc[kmarks]following command keeps marks where they are
:lockv[ar]lock variables
:lol[der]go to older location list
:lop[en]open location window
:lp[revious]go to previous location
:lpf[ile]go to last location in previous file
:lr[ewind]go to the specified location, default first one
:lslist all buffers
:lsplanguage server protocol
:lt[ag]jump to tag and add matching tags to the location list
:lu[nmap]like ":unmap!" but includes Lang-Arg mode
:luaexecute Lua command
:luad[o]execute Lua command for each line
:luaf[ile]execute Lua script file
:lv[imgrep]search for pattern in files
:lvimgrepa[dd]like :vimgrep, but append to current list
:lw[indow]open or close location window
:m[ove]move lines
:ma[rk]set a mark
:mak[e]execute external command 'makeprg' and parse error messages
:mapshow or enter a mapping
:mapc[lear]clear all mappings for Normal and Visual mode
:markslist all marks
:mat[ch]define a match to highlight
:me[nu]enter a new menu item
:mes[sages]view previously displayed messages
:mk[exrc]write current mappings and settings to a file
:mks[ession]write session info to a file
:mksp[ell]produce .spl spell file
:mkv[imrc]write current mappings and settings to a file
:mkvie[w]write view of current window to a file
:mod[e]show or change the screen mode
:n[ext]go to next file in the argument list
:newcreate a new empty window
:nm[ap]like ":map" but for Normal mode
:nmapc[lear]clear all mappings for Normal mode
:nme[nu]add menu for Normal mode
:nn[oremap]like ":noremap" but for Normal mode
:nnoreme[nu]like ":noremenu" but for Normal mode
:noa[utocmd]following commands don't trigger autocommands
:no[remap]enter a mapping that will not be remapped
:noh[lsearch]suspend 'hlsearch' highlighting
:norea[bbrev]enter an abbreviation that will not be remapped
:noreme[nu]enter a menu that will not be remapped
:norm[al]execute Normal mode commands
:nos[wapfile]following commands don't create a swap file
:nu[mber]print lines with line number
:nun[map]like ":unmap" but for Normal mode
:nunme[nu]remove menu for Normal mode
:ol[dfiles]list files that have marks in the shada file
:om[ap]like ":map" but for Operator-pending mode
:omapc[lear]remove all mappings for Operator-pending mode
:ome[nu]add menu for Operator-pending mode
:on[ly]close all windows except the current one
:ono[remap]like ":noremap" but for Operator-pending mode
:onoreme[nu]like ":noremenu" but for Operator-pending mode
:opt[ions]open the options-window
:ou[nmap]like ":unmap" but for Operator-pending mode
:ounme[nu]remove menu for Operator-pending mode
:pa[ckadd]add a plugin from 'packpath'
:packl[oadall]load all packages under 'packpath'
:pb[uffer]edit buffer in the preview window
:pc[lose]close preview window
:ped[it]edit file in the preview window
:pe[rl]execute perl command
:perld[o]execute perl command for each line
:perlf[ile]execute perl script file
:p[rint]print lines
:profd[el]stop profiling a function or script
:prof[ile]profiling functions and scripts
:po[p]jump to older entry in tag stack
:popu[p]popup a menu by name
:pp[op]":pop" in preview window
:pre[serve]write all text to swap file
:prev[ious]go to previous file in argument list
:ps[earch]like ":ijump" but shows match in preview window
:pt[ag]show tag in preview window
:ptN[ext]:tNext in preview window
:ptf[irst]:trewind in preview window
:ptj[ump]:tjump and show tag in preview window
:ptl[ast]:tlast in preview window
:ptn[ext]:tnext in preview window
:ptp[revious]:tprevious in preview window
:ptr[ewind]:trewind in preview window
:pts[elect]:tselect and show tag in preview window
:pu[t]insert contents of register in the text
:pw[d]print current directory
:py3execute Python 3 command
:python3same as :py3
:py3d[o]execute Python 3 command for each line
:py3f[ile]execute Python 3 script file
:py[thon]execute Python command
:pyd[o]execute Python command for each line
:pyf[ile]execute Python script file
:pyxexecute python_x command
:pythonxsame as :pyx
:pyxd[o]execute python_x command for each line
:pyxf[ile]execute python_x script file
:q[uit]quit current window (when one window quit Vim)
:quita[ll]quit Vim
:qa[ll]quit Vim
:r[ead]read file into the text
:rec[over]recover a file from a swap file
:red[o]redo one undone change
:redi[r]redirect messages to a file or register
:redr[aw]force a redraw of the display
:redraws[tatus]force a redraw of the status line(s) and window bar(s)
:reg[isters]display the contents of registers
:res[ize]change current window height
:restartrestart the Nvim server
:ret[ab]change tab size
:retu[rn]return from a user function
:rew[ind]go to the first file in the argument list
:ri[ght]right align text
:rightb[elow]make split window appear right or below
:rsh[ada]read from shada file
:rub[y]execute Ruby command
:rubyd[o]execute Ruby command for each line
:rubyf[ile]execute Ruby script file
:rund[o]read undo information from a file
:ru[ntime]source vim scripts in 'runtimepath'
:s[ubstitute]find and replace text
:sN[ext]split window and go to previous file in argument list
:san[dbox]execute a command in the sandbox
:sa[rgument]split window and go to specific file in argument list
:sal[l]open a window for each file in argument list
:sav[eas]save file under another name.
:sb[uffer]split window and go to specific file in the buffer list
:sbN[ext]split window and go to previous file in the buffer list
:sba[ll]open a window for each file in the buffer list
:sbf[irst]split window and go to first file in the buffer list
:sbl[ast]split window and go to last file in buffer list
:sbm[odified]split window and go to modified file in the buffer list
:sbn[ext]split window and go to next file in the buffer list
:sbp[revious]split window and go to previous file in the buffer list
:sbr[ewind]split window and go to first file in the buffer list
:scr[iptnames]list names of all sourced Vim scripts
:se[t]show or set options
:setf[iletype]set 'filetype', unless it was set already
:setg[lobal]show global values of options
:setl[ocal]show or set options locally
:sf[ind]split current window and edit file in 'path'
:sfir[st]split window and go to first file in the argument list
:sig[n]manipulate signs
:sil[ent]run a command silently
:sl[eep]do nothing for a few seconds
:sl[eep]!do nothing for a few seconds, without the cursor visible
:sla[st]split window and go to last file in the argument list
:sm[agic]:substitute with 'magic'
:smaplike ":map" but for Select mode
:smapc[lear]remove all mappings for Select mode
:sme[nu]add menu for Select mode
:sn[ext]split window and go to next file in the argument list
:sno[magic]:substitute with 'nomagic'
:snor[emap]like ":noremap" but for Select mode
:snoreme[nu]like ":noremenu" but for Select mode
:sor[t]sort lines
:so[urce]read Vim or Ex commands from a file
:spelld[ump]split window and fill with all correct words
:spe[llgood]add good word for spelling
:spelli[nfo]show info about loaded spell files
:spellra[re]add rare word for spelling
:spellr[epall]replace all bad words like last z=
:spellu[ndo]remove good or bad word
:spellw[rong]add spelling mistake
:sp[lit]split current window
:spr[evious]split window and go to previous file in the argument list
:sre[wind]split window and go to first file in the argument list
:st[op]suspend the editor or escape to a shell
:sta[g]split window and jump to a tag
:star[tinsert]start Insert mode
:startr[eplace]start Replace mode
:stopi[nsert]stop Insert mode
:stj[ump]do ":tjump" and split window
:sts[elect]do ":tselect" and split window
:sun[hide]same as ":unhide"
:sunm[ap]like ":unmap" but for Select mode
:sunme[nu]remove menu for Select mode
:sus[pend]same as ":stop"
:sv[iew]split window and edit file read-only
:sw[apname]show the name of the current swap file
:sy[ntax]syntax highlighting
:synti[me]measure syntax highlighting speed
:sync[bind]sync scroll binding
:tsame as ":copy"
:tN[ext]jump to previous matching tag
:tabN[ext]go to previous tabpage
:tabc[lose]close current tabpage
:tabd[o]execute command in each tabpage
:tabe[dit]edit a file in a new tabpage
:tabf[ind]find file in 'path', edit it in a new tabpage
:tabfir[st]go to first tabpage
:tabl[ast]go to last tabpage
:tabm[ove]move tabpage to other position
:tabnewedit a file in a new tabpage
:tabn[ext]go to next tabpage
:tabo[nly]close all tabpages except the current one
:tabp[revious]go to previous tabpage
:tabr[ewind]go to first tabpage
:tabslist the tabpages and what they contain
:tabcreate new tab when opening new window
:ta[g]jump to tag
:tagsshow the contents of the tag stack
:tc[d]change directory for tabpage
:tch[dir]change directory for tabpage
:te[rminal]open a terminal buffer
:tf[irst]jump to first matching tag
:th[row]throw an exception
:tj[ump]like ":tselect", but jump directly when there is only one match
:tl[ast]jump to last matching tag
:tlm[enu]add menu for Terminal-mode
:tln[oremenu]like ":noremenu" but for Terminal-mode
:tlu[nmenu]remove menu for Terminal-mode
:tmapc[lear]remove all mappings for Terminal-mode
:tma[p]like ":map" but for Terminal-mode
:tm[enu]define menu tooltip
:tn[ext]jump to next matching tag
:tno[remap]like ":noremap" but for Terminal-mode
:to[pleft]make split window appear at top or far left
:tp[revious]jump to previous matching tag
:tr[ewind]jump to first matching tag
:trustadd or remove file from trust database
:tryexecute commands, abort on error or exception
:ts[elect]list matching tags and select one
:tunma[p]like ":unmap" but for Terminal-mode
:tu[nmenu]remove menu tooltip
:u[ndo]undo last change(s)
:undoj[oin]join next change with previous undo block
:undol[ist]list leafs of the undo tree
:una[bbreviate]remove abbreviation
:unh[ide]open a window for each loaded file in the buffer list
:uni[q]uniq lines
:unl[et]delete variable
:unlo[ckvar]unlock variables
:unm[ap]remove mapping
:unme[nu]remove menu
:uns[ilent]run a command not silently
:up[date]write buffer if modified
:v[global]execute commands for not matching lines
:ve[rsion]print version number and other info
:verb[ose]execute command with 'verbose' set
:vert[ical]make following command split vertically
:vim[grep]search for pattern in files
:vimgrepa[dd]like :vimgrep, but append to current list
:vi[sual]same as ":edit", but turns off "Ex" mode
:viu[sage]overview of Normal mode commands
:vie[w]edit a file read-only
:vm[ap]like ":map" but for Visual+Select mode
:vmapc[lear]remove all mappings for Visual+Select mode
:vme[nu]add menu for Visual+Select mode
:vne[w]create a new empty window, vertically split
:vn[oremap]like ":noremap" but for Visual+Select mode
:vnoreme[nu]like ":noremenu" but for Visual+Select mode
:vs[plit]split current window vertically
:vu[nmap]like ":unmap" but for Visual+Select mode
:vunme[nu]remove menu for Visual+Select mode
:wind[o]execute command in each window
:w[rite]write to a file
:wN[ext]write to a file and go to previous file in argument list
:wa[ll]write all (changed) buffers
:wh[ile]execute loop for as long as condition met
:wi[nsize]get or set window size (obsolete)
:winc[md]execute a Window (CTRL-W) command
:winp[os]get or set window position
:wn[ext]write to a file and go to next file in argument list
:wp[revious]write to a file and go to previous file in argument list
:wqwrite to a file and quit window or Vim
:wqa[ll]write all changed buffers and quit Vim
:wsh[ada]write to ShaDa file
:wu[ndo]write undo information to a file
:x[it]write if buffer changed and close window
:xa[ll]same as ":wqall"
:xmapc[lear]remove all mappings for Visual mode
:xm[ap]like ":map" but for Visual mode
:xme[nu]add menu for Visual mode
:xn[oremap]like ":noremap" but for Visual mode
:xnoreme[nu]like ":noremenu" but for Visual mode
:xu[nmap]like ":unmap" but for Visual mode
:xunme[nu]remove menu for Visual mode
:y[ank]yank lines into a register
:zprint some lines
:~repeat last ":substitute" vim:tw=78:ts=8:noet:ft=help:norl:

Options

374

Every option, with its abbreviation; hover for Nvim’s default

'aleph' 'al'legacy name, still accepted so an old vimrc loads
'allowrevins' 'ari'allow CTRL-_ in Insert mode
'ambiwidth' 'ambw'what to do with Unicode chars of ambiguous width
'arabic' 'arab'for Arabic as a default second language
'arabicshape' 'arshape'do shaping for Arabic characters
'autochdir' 'acd'change directory to the file in the current window
'autocomplete' 'ac'enable automatic completion in insert mode
'autocompletedelay' 'acl'delay in msec before menu appears after typing
'autocompletetimeout' 'act'initial decay timeout for autocompletion algorithm
'autoindent' 'ai'take indent for new line from previous line
'autoread' 'ar'autom. read file when changed outside of Vim
'autowrite' 'aw'automatically write file if changed
'autowriteall' 'awa'as 'autowrite', but works with more commands
'background' 'bg'"dark" or "light", used for highlight colors
'backspace' 'bs'how backspace works at start of line
'backup' 'bk'keep backup file after overwriting a file
'backupcopy' 'bkc'make backup as a copy, don't rename the file
'backupdir' 'bdir'list of directories for the backup file
'backupext' 'bex'extension used for the backup file
'backupskip' 'bsk'no backup for files that match these patterns
'belloff' 'bo'do not ring the bell for these reasons
'binary' 'bin'read/write/edit file in binary mode
'bomb'prepend a Byte Order Mark to the file
'breakat' 'brk'characters that may cause a line break
'breakindent' 'bri'wrapped line repeats indent
'breakindentopt' 'briopt'settings for 'breakindent'
'browsedir' 'bsdir'which directory to start browsing in
'bufhidden' 'bh'what to do when buffer is no longer in window
'buflisted' 'bl'whether the buffer shows up in the buffer list
'buftype' 'bt'special type of buffer
'busy'Sets a buffer "busy" status.
'casemap' 'cmp'specifies how case of letters is changed
'cdhome' 'cdh'change directory to the home directory by ":cd"
'cdpath' 'cd'list of directories searched with ":cd"
'cedit'key used to open the command-line window
'channel'channel connected to the buffer, or 0 if no channel is connected.
'charconvert' 'ccv'expression for character encoding conversion
'chistory' 'chi'maximum number of quickfix lists in history
'cindent' 'cin'do C program indenting
'cinkeys' 'cink'keys that trigger indent when 'cindent' is set
'cinoptions' 'cino'how to do indenting when 'cindent' is set
'cinscopedecls' 'cinsd'words that are recognized by 'cino-g'
'cinwords' 'cinw'words where 'si' and 'cin' add an indent
'clipboard' 'cb'use the clipboard as the unnamed register
'cmdheight' 'ch'number of lines to use for the command-line
'cmdwinheight' 'cwh'height of the command-line window
'colorcolumn' 'cc'columns to highlight
'columns' 'co'number of columns in the display
'comments' 'com'patterns that can start a comment line
'commentstring' 'cms'template for comments; used for fold marker
'compatible' 'cp'legacy name, still accepted so an old vimrc loads — (Nvim is always "nocompatible".)
'complete' 'cpt'specify how Insert mode completion works
'completefunc' 'cfu'function to be used for Insert mode completion
'completeitemalign' 'cia'A comma-separated list of strings that controls the alignment and display order of items in the popup menu during Insert mode completion.
'completeopt' 'cot'options for Insert mode completion
'completeslash' 'csl'like 'shellslash' for completion
'completetimeout' 'cto'initial decay timeout for CTRL-N and CTRL-P
'concealcursor' 'cocu'whether concealable text is hidden in cursor line
'conceallevel' 'cole'whether concealable text is shown or hidden
'confirm' 'cf'ask what to do about unsaved/read-only files
'copyindent' 'ci'make 'autoindent' use existing indent structure
'cpoptions' 'cpo'flags for Vi-compatible behavior
'cursorbind' 'crb'move cursor in window as it moves in other windows
'cursorcolumn' 'cuc'highlight the screen column of the cursor
'cursorline' 'cul'highlight the screen line of the cursor
'cursorlineopt' 'culopt'settings for 'cursorline'
'debug'set to "msg" to see all error messages
'define' 'def'pattern to be used to find a macro definition
'delcombine' 'deco'delete combining characters on their own
'dictionary' 'dict'list of file names used for keyword completion
'diff'use diff mode for the current window
'diffanchors' 'dia'list of {address} to force anchoring of a diff
'diffexpr' 'dex'expression used to obtain a diff file
'diffopt' 'dip'options for using diff mode
'digraph' 'dg'enable the entering of digraphs in Insert mode
'directory' 'dir'list of directory names for the swap file
'display' 'dy'list of flags for how to display text
'eadirection' 'ead'in which direction 'equalalways' works
'edcompatible' 'ed'legacy name, still accepted so an old vimrc loads
'emoji' 'emo'When on all Unicode emoji characters are considered to be full width.
'encoding' 'enc'encoding used internally
'endoffile' 'eof'write CTRL-Z at end of the file
'endofline' 'eol'write <EOL> for last line in file
'equalalways' 'ea'windows are automatically made the same size
'equalprg' 'ep'external program to use for "=" command
'errorbells' 'eb'ring the bell for error messages
'errorfile' 'ef'name of the errorfile for the QuickFix mode
'errorformat' 'efm'description of the lines in the error file
'eventignore' 'ei'autocommand events that are ignored
'eventignorewin' 'eiw'autocommand events that are ignored in a window
'expandtab' 'et'use spaces when <Tab> is inserted
'exrc' 'ex'read init files in the current directory
'fileencoding' 'fenc'file encoding for multibyte text
'fileencodings' 'fencs'automatically detected character encodings
'fileformat' 'ff'file format used for file I/O
'fileformats' 'ffs'automatically detected values for 'fileformat'
'fileignorecase' 'fic'ignore case when using file names
'filetype' 'ft'type of file, used for autocommands
'fillchars' 'fcs'characters to use for displaying special items
'findfunc' 'ffu'function to be called for the :find command
'fixendofline' 'fixeol'make sure last line in file has <EOL>
'foldclose' 'fcl'close a fold when the cursor leaves it
'foldcolumn' 'fdc'width of the column used to indicate folds
'foldenable' 'fen'set to display all folds open
'foldexpr' 'fde'expression used when 'foldmethod' is "expr"
'foldignore' 'fdi'ignore lines when 'foldmethod' is "indent"
'foldlevel' 'fdl'close folds with a level higher than this
'foldlevelstart' 'fdls''foldlevel' when starting to edit a file
'foldmarker' 'fmr'markers used when 'foldmethod' is "marker"
'foldmethod' 'fdm'folding type
'foldminlines' 'fml'minimum number of lines for a fold to be closed
'foldnestmax' 'fdn'maximum fold depth
'foldopen' 'fdo'for which commands a fold will be opened
'foldtext' 'fdt'expression used to display for a closed fold
'formatexpr' 'fex'expression used with "gq" command
'formatlistpat' 'flp'pattern used to recognize a list header
'formatoptions' 'fo'how automatic formatting is to be done
'formatprg' 'fp'name of external program used with "gq" command
'fsync' 'fs'whether to invoke fsync() after file write
'gdefault' 'gd'deprecated, still works — Enables the :substitute "/g" flag by default.
'grepformat' 'gfm'format of 'grepprg' output
'grepprg' 'gp'program to use for ":grep"
'guicursor' 'gcr'GUI: settings for cursor shape and blinking
'guifont' 'gfn'GUI: Name(s) of font(s) to be used
'guifontwide' 'gfw'list of font names for double-wide characters
'guioptions' 'go'GUI: Which components and options are used
'guitablabel' 'gtl'GUI: custom label for a tabpage
'guitabtooltip' 'gtt'GUI: custom tooltip for a tabpage
'helpfile' 'hf'full path name of the main help file
'helpheight' 'hh'minimum height of a new help window
'helplang' 'hlg'preferred help languages
'hidden' 'hid'don't unload buffer when it is abandoned
'highlight' 'hl'legacy name, still accepted so an old vimrc loads — Names of builtin highlight-groups cannot be changed.
'history' 'hi'number of command-lines that are remembered
'hkmap' 'hk'legacy name, still accepted so an old vimrc loads — use set keymap=hebrew instead.
'hkmapp' 'hkp'legacy name, still accepted so an old vimrc loads — use set keymap=hebrewp instead.
'hlsearch' 'hls'highlight matches with last search pattern
'icon'let Vim set the text of the window icon
'iconstring'string to use for the Vim icon text
'ignorecase' 'ic'ignore case in search patterns
'imcmdline' 'imc'use IM when starting to edit a command line
'imdisable' 'imd'do not use the IM in any mode
'iminsert' 'imi'use :lmap or IM in Insert mode
'imsearch' 'ims'use :lmap or IM when typing a search pattern
'inccommand' 'icm'When nonempty, shows the effects of :substitute, :smagic, :snomagic and user commands with the :command-preview flag as you type.
'include' 'inc'pattern to be used to find an include file
'includeexpr' 'inex'expression used to process an include line
'incsearch' 'is'highlight match while typing search pattern
'indentexpr' 'inde'expression used to obtain the indent of a line
'indentkeys' 'indk'keys that trigger indenting with 'indentexpr'
'infercase' 'inf'adjust case of match for keyword completion
'insertmode' 'im'legacy name, still accepted so an old vimrc loads
'isfname' 'isf'characters included in file names and pathnames
'isident' 'isi'characters included in identifiers
'iskeyword' 'isk'characters included in keywords
'isprint' 'isp'printable characters
'joinspaces' 'js'two spaces after a period with a join command
'jumpoptions' 'jop'specifies how jumping is done
'keymap' 'kmp'name of a keyboard mapping
'keymodel' 'km'enable starting/stopping selection with keys
'keywordprg' 'kp'program to use for the "K" command
'langmap' 'lmap'alphabetic characters for other language mode
'langmenu' 'lm'language to be used for the menus
'langnoremap' 'lnr'legacy name, still accepted so an old vimrc loads — Deprecated alias to 'nolangremap'.
'langremap' 'lrm'do apply 'langmap' to mapped characters
'laststatus' 'ls'tells when last window has status lines
'lazyredraw' 'lz'don't redraw while executing macros
'lhistory' 'lhi'maximum number of location lists in history
'linebreak' 'lbr'wrap long lines at a blank
'lines'number of lines in the display
'linespace' 'lsp'number of pixel lines to use between characters
'lisp'automatic indenting for Lisp
'lispoptions' 'lop'changes how Lisp indenting is done
'lispwords' 'lw'words that change how lisp indenting works
'list'show <Tab> and <EOL>
'listchars' 'lcs'characters for displaying in list mode
'loadplugins' 'lpl'load plugin scripts when starting up
'magic'deprecated, still works — Changes the special characters in search patterns.
'makeef' 'mef'name of the errorfile for ":make"
'makeencoding' 'menc'encoding of external make/grep commands
'makeprg' 'mp'program to use for the ":make" command
'matchpairs' 'mps'pairs of characters that "%" can match
'matchtime' 'mat'tenths of a second to show matching paren
'maxcombine' 'mco'maximum nr of combining characters displayed
'maxfuncdepth' 'mfd'maximum recursive depth for user functions
'maxmapdepth' 'mmd'maximum recursive depth for mapping
'maxmempattern' 'mmp'maximum memory (in Kbyte) used for pattern search
'maxsearchcount' 'msc'Maximum number of matches shown for the search count status shm-S When the number of matches exceeds this value, Vim shows ">" instead of the exact count to keep searching fast.
'menuitems' 'mis'maximum number of items in a menu
'messagesopt' 'mopt'Option settings for outputting messages.
'mkspellmem' 'msm'memory used before :mkspell compresses the tree
'modeline' 'ml'recognize modelines at start or end of file
'modelineexpr' 'mle'allow setting expression options from a modeline
'modelines' 'mls'number of lines checked for modelines
'modifiable' 'ma'changes to the text are not possible
'modified' 'mod'buffer has been modified
'more'pause listings when the whole screen is filled
'mouse'enable the use of mouse clicks
'mousefocus' 'mousef'keyboard focus follows the mouse
'mousehide' 'mh'hide mouse pointer while typing
'mousemodel' 'mousem'changes meaning of mouse buttons
'mousemoveevent' 'mousemev'report mouse moves with <MouseMove>
'mousescroll'amount to scroll by when scrolling with a mouse
'mouseshape' 'mouses'shape of the mouse pointer in different modes
'mousetime' 'mouset'max time between mouse double-click
'nrformats' 'nf'number formats recognized for CTRL-A command
'number' 'nu'print the line number in front of each line
'numberwidth' 'nuw'number of columns used for the line number
'omnifunc' 'ofu'function for filetype-specific completion
'opendevice' 'odev'allow reading/writing devices on MS-Windows
'operatorfunc' 'opfunc'function to be called for g@ operator
'packpath' 'pp'list of directories used for packages
'paragraphs' 'para'nroff macros that separate paragraphs
'paste'legacy name, still accepted so an old vimrc loads — The 'paste' option is obsolete: paste is handled automatically when you paste text using your terminal's or GUI's paste feature (CTRL-SHIFT-v, CMD-v (macOS), middle-click, …).
'pastetoggle' 'pt'legacy name, still accepted so an old vimrc loads — paste is handled automatically when
'patchexpr' 'pex'expression used to patch a file
'patchmode' 'pm'keep the oldest version of a file
'path' 'pa'list of directories searched with "gf" et.al.
'preserveindent' 'pi'preserve the indent structure when reindenting
'previewheight' 'pvh'height of the preview window
'previewwindow' 'pvw'identifies the preview window
'prompt'legacy name, still accepted so an old vimrc loads
'pumblend' 'pb'Enables pseudo-transparency for the popup-menu.
'pumborder'Defines the default border style of popupmenu windows.
'pumheight' 'ph'maximum number of items to show in the popup menu
'pummaxwidth' 'pmw'Maximum width for the popup menu (ins-completion-menu).
'pumwidth' 'pw'minimum width of the popup menu
'pyxversion' 'pyx'Python version used for pyx* commands
'quickfixtextfunc' 'qftf'This option specifies a function to be used to get the text to display in the quickfix and location list windows.
'quoteescape' 'qe'escape characters used in a string
'readonly' 'ro'disallow writing the buffer
'redrawdebug' 'rdb'Flags to change the way redrawing works, for debugging purposes.
'redrawtime' 'rdt'timeout for 'hlsearch' and :match highlighting
'regexpengine' 're'default regexp engine to use
'relativenumber' 'rnu'show relative line number in front of each line
'remap'legacy name, still accepted so an old vimrc loads
'report'threshold for reporting nr. of lines changed
'revins' 'ri'inserting characters will work backwards
'rightleft' 'rl'window is right-to-left oriented
'rightleftcmd' 'rlc'commands for which editing works right-to-left
'ruler' 'ru'show cursor line and column in the status line
'rulerformat' 'ruf'custom format for the ruler
'runtimepath' 'rtp'list of directories used for runtime files
'scroll' 'scr'lines to scroll with CTRL-U and CTRL-D
'scrollback' 'scbk'Maximum number of lines kept beyond the visible screen.
'scrollbind' 'scb'scroll in window as other windows scroll
'scrolljump' 'sj'minimum number of lines to scroll
'scrolloff' 'so'minimum nr. of lines above and below cursor
'scrollopt' 'sbo'how 'scrollbind' should behave
'sections' 'sect'nroff macros that separate sections
'secure'secure mode for reading .vimrc in current dir
'selection' 'sel'what type of selection to use
'selectmode' 'slm'when to use Select mode instead of Visual mode
'sessionoptions' 'ssop'options for :mksession
'shada' 'sd'use shada file upon startup and exiting
'shadafile' 'sdf'When non-empty, overrides the file name used for shada (viminfo).
'shell' 'sh'name of shell to use for external commands
'shellcmdflag' 'shcf'flag to shell to execute one command
'shellpipe' 'sp'string to put output of ":make" in error file
'shellquote' 'shq'quote character(s) for around shell command
'shellredir' 'srr'string to put output of filter in a temp file
'shellslash' 'ssl'use forward slash for shell file names
'shelltemp' 'stmp'whether to use a temp file for shell commands
'shellxescape' 'sxe'characters to escape when 'shellxquote' is (
'shellxquote' 'sxq'like 'shellquote', but include redirection
'shiftround' 'sr'round indent to multiple of shiftwidth
'shiftwidth' 'sw'number of spaces to use for (auto)indent step
'shortmess' 'shm'list of flags, reduce length of messages
'showbreak' 'sbr'string to use at the start of wrapped lines
'showcmd' 'sc'show (partial) command somewhere
'showcmdloc' 'sloc'where to show (partial) command
'showfulltag' 'sft'show full tag pattern when completing tag
'showmatch' 'sm'briefly jump to matching bracket if insert one
'showmode' 'smd'message on status line to show current mode
'showtabline' 'stal'tells when the tabpages line is displayed
'sidescroll' 'ss'minimum number of columns to scroll horizontal
'sidescrolloff' 'siso'min. nr. of columns to left and right of cursor
'signcolumn' 'scl'when and how to display the sign column
'smartcase' 'scs'no ignore case when pattern has uppercase
'smartindent' 'si'smart autoindenting for C programs
'smarttab' 'sta'<Tab> in leading whitespace indents by 'shiftwidth'
'smoothscroll' 'sms'scroll by screen lines when 'wrap' is set
'softtabstop' 'sts'number of columns between two soft tab stops
'spell'enable spell checking
'spellcapcheck' 'spc'pattern to locate end of a sentence
'spellfile' 'spf'files where zg and zw store words
'spelllang' 'spl'language(s) to do spell checking for
'spelloptions' 'spo'options for spell checking
'spellsuggest' 'sps'method(s) used to suggest spelling corrections
'splitbelow' 'sb'new window from split is below the current one
'splitkeep' 'spk'determines scroll behavior for split windows
'splitright' 'spr'new window is put right of the current one
'startofline' 'sol'commands move cursor to first non-blank in line
'statuscolumn' 'stc'custom format for the status column
'statusline' 'stl'custom format for the status line
'suffixes' 'su'suffixes that are ignored with multiple match
'suffixesadd' 'sua'suffixes added when searching for a file
'swapfile' 'swf'whether to use a swapfile for a buffer
'switchbuf' 'swb'sets behavior when switching to another buffer
'synmaxcol' 'smc'maximum column to find syntax items
'syntax' 'syn'syntax to be loaded for current buffer
'tabclose' 'tcl'which tabpage to focus when closing a tab
'tabline' 'tal'custom format for the console tabpages line
'tabpagemax' 'tpm'maximum number of tabpages for -p and "tab all"
'tabstop' 'ts'number of columns between two tab stops
'tagbsearch' 'tbs'use binary searching in tags files
'tagcase' 'tc'how to handle case when searching in tags files
'tagfunc' 'tfu'function to get list of tag matches
'taglength' 'tl'number of significant characters for a tag
'tagrelative' 'tr'file names in tag file are relative
'tags' 'tag'list of file names used by the tag command
'tagstack' 'tgst'push tags onto the tag stack
'termbidi' 'tbidi'terminal takes care of bi-directionality
'termencoding' 'tenc'legacy name, still accepted so an old vimrc loads — (Vim 7.4.852 also removed this for Windows)
'termguicolors' 'tgc'enable 24-bit RGB color in the TUI
'termpastefilter' 'tpf'A comma-separated list of options for specifying control characters to be removed from the text pasted into the terminal window.
'termsync'If the host terminal supports it, buffer all screen updates made during a redraw cycle so that each screen is displayed in the terminal all at once.
'terse'legacy name, still accepted so an old vimrc loads — (Add "s" to 'shortmess' instead)
'textwidth' 'tw'maximum width of text that is being inserted
'thesaurus' 'tsr'list of thesaurus files for keyword completion
'thesaurusfunc' 'tsrfu'function to be used for thesaurus completion
'tildeop' 'top'tilde command "~" behaves like an operator
'timeout' 'to'time out on mappings and key codes
'timeoutlen' 'tm'time out time in milliseconds
'title'let Vim set the title of the window
'titlelen'percentage of 'columns' used for window title
'titleold'old title, restored when exiting
'titlestring'string to use for the Vim window title
'ttimeout'time out on mappings
'ttimeoutlen' 'ttm'time out time for key codes in milliseconds
'ttyfast' 'tf'Enables Nvim TUI features which assume a fast (usually local) host terminal.
'undodir' 'udir'where to store undo files
'undofile' 'udf'save undo information in a file
'undolevels' 'ul'maximum number of changes that can be undone
'undoreload' 'ur'max nr of lines to save for undo on a buffer reload
'updatecount' 'uc'after this many characters flush swap file
'updatetime' 'ut'after this many milliseconds flush swap file
'varsofttabstop' 'vsts'a list of number of columns between soft tab stops
'vartabstop' 'vts'a list of number of columns between tab stops
'verbose' 'vbs'give informative messages
'verbosefile' 'vfile'file to write messages in
'viewdir' 'vdir'directory where to store files with :mkview
'viewoptions' 'vop'specifies what to save for :mkview
'virtualedit' 've'when to use virtual editing
'visualbell' 'vb'use visual bell instead of beeping
'warn'warn for shell command when buffer was changed
'whichwrap' 'ww'allow specified keys to cross line boundaries
'wildchar' 'wc'command-line character for wildcard expansion
'wildcharm' 'wcm'like 'wildchar' but also works when mapped
'wildignore' 'wig'files matching these patterns are not completed
'wildignorecase' 'wic'ignore case when completing file names
'wildmenu' 'wmnu'use menu for command line completion
'wildmode' 'wim'mode for 'wildchar' command-line expansion
'wildoptions' 'wop'specifies how command line completion is done
'winaltkeys' 'wak'when the windows system handles ALT keys
'winbar' 'wbr'When non-empty, this option enables the window bar and determines its contents.
'winblend' 'winbl'Enables pseudo-transparency for a floating window.
'winborder'Defines the default border style of floating windows.
'window' 'wi'nr of lines to scroll for CTRL-F and CTRL-B
'winfixbuf' 'wfb'keep window focused on a single buffer
'winfixheight' 'wfh'keep window height when opening/closing windows
'winfixwidth' 'wfw'keep window width when opening/closing windows
'winheight' 'wh'minimum number of lines for the current window
'winhighlight' 'winhl'window-local highlighting
'winminheight' 'wmh'minimum number of lines for any window
'winminwidth' 'wmw'minimal number of columns for any window
'winwidth' 'wiw'minimal number of columns for current window
'wrap'long lines wrap and continue on the next line
'wrapmargin' 'wm'chars from the right where wrapping starts
'wrapscan' 'ws'searches wrap around the end of the file
'write'writing to a file is allowed
'writeany' 'wa'write to file with no need for "!" override
'writebackup' 'wb'make a backup before overwriting a file
'writedelay' 'wd'delay this many msec for each char (for debug)

Vimscript Functions

464

Every built-in, callable from Lua as vim.fn.name()

abs({expr})Return the absolute value of {expr}.
acos({expr})Return the arc cosine of {expr} measured in radians, as a Float in the range of [0, pi].
add({object}, {expr})Append the item {expr} to List or Blob {object}.
and({expr}, {expr})Bitwise AND on the two arguments.
api_info()Returns Dictionary of api-metadata.
append({lnum}, {text})When {text} is a List:
appendbufline({buf}, {lnum}, {text})Like append() but append the text in buffer {buf}.
argc([{winid}])The result is the number of files in the argument list.
argidx()The result is the current index in the argument list.
arglistid([{winnr} [, {tabnr}]])Return the argument list ID.
argv([{nr} [, {winid}]])The result is the {nr}th file in the argument list.
asin({expr})Return the arc sine of {expr} measured in radians, as a Float in the range of [-pi/2, pi/2].
assert_beeps({cmd})Run {cmd} and add an error message to v:errors if it does NOT produce a beep or visual bell.
assert_equal({expected}, {actual} [, {msg}])When {expected} and {actual} are not equal an error message is added to v:errors and 1 is returned.
assert_equalfile({fname_one}, {fname_two})When the files {fname_one} and {fname_two} do not contain exactly the same text an error message is added to v:errors.
assert_exception({error} [, {msg}])When v:exception does not contain the string {error} an error message is added to v:errors.
assert_fails({cmd} [, {error} [, {msg} [, {lnum} [, {context}]]]])Run {cmd} and add an error message to v:errors if it does NOT produce an error or when {error} is not found in the error message.
assert_false({actual} [, {msg}])When {actual} is not false an error message is added to v:errors, like with assert_equal().
assert_inrange({lower}, {upper}, {actual} [, {msg}])This asserts number and Float values.
assert_match({pattern}, {actual} [, {msg}])When {pattern} does not match {actual} an error message is added to v:errors.
assert_nobeep({cmd})Run {cmd} and add an error message to v:errors if it produces a beep or visual bell.
assert_notequal({expected}, {actual} [, {msg}])The opposite of assert_equal():
assert_notmatch({pattern}, {actual} [, {msg}])The opposite of assert_match():
assert_report({msg})Report a test failure directly, using String {msg}.
assert_true({actual} [, {msg}])When {actual} is not true an error message is added to v:errors, like with assert_equal().
atan({expr})Return the principal value of the arc tangent of {expr}, in the range [-pi/2, +pi/2] radians, as a Float.
atan2({expr1}, {expr2})Return the arc tangent of {expr1} / {expr2}, measured in radians, as a Float in the range [-pi, pi].
blob2list({blob})Return a List containing the number value of each byte in Blob {blob}.
browse({save}, {title}, {initdir}, {default})Put up a file requester.
browsedir({title}, {initdir})Put up a directory requester.
bufadd({name})Add a buffer to the buffer list with name {name} (must be a String).
bufexists({buf})Checks whether a buffer with the name or number {buf} exists.
buffer_exists()Obsolete name for bufexists().
buffer_name()Obsolete name for bufname().
buffer_number()Obsolete name for bufnr().
buflisted({buf})Checks whether a buffer called {buf} exists and is listed (has the 'buflisted' option set).
bufload({buf})Ensure the buffer {buf} is loaded.
bufloaded({buf})Checks whether a buffer called {buf} exists and is loaded (shown in a window or hidden).
bufname([{buf}])The result is the name of a buffer.
bufnr([{buf} [, {create}]])The result is the number of a buffer, as it is displayed by the :ls command.
bufwinid({buf})Returns the window-ID of the first window associated with buffer {buf}.
bufwinnr({buf})Like bufwinid() but returns a window-number instead of a window-ID.
byte2line({byte})Return the line number that contains the character at byte count {byte} in the current buffer.
byteidx({expr}, {nr} [, {utf16}])Return byte index of the {nr}th character in the String {expr}.
byteidxcomp({expr}, {nr} [, {utf16}])Like byteidx(), except that a composing character is counted as a separate character.
call({func}, {arglist} [, {dict}]) *E699*Call function {func} with the items in List {arglist} as arguments.
ceil({expr})Return the smallest integral value greater than or equal to {expr} as a Float (round up).
chanclose({id} [, {stream}])Close a channel or a specific stream associated with it.
changenr()Return the number of the most recent change.
chansend({id}, {data})Send data to channel {id}.
char2nr({string} [, {utf8}])Return Number value of the first char in {string}.
charclass({string})Return the character class of the first character in {string}.
charcol({expr} [, {winid}])Same as col() but returns the character index of the column position given with {expr} instead of the byte position.
charidx({string}, {idx} [, {countcc} [, {utf16}]])Return the character index of the byte at {idx} in {string}.
chdir({dir} [, {scope}])Changes the current working directory to {dir}.
cindent({lnum})Get the amount of indent for line {lnum} according the C-indenting rules, as with 'cindent'.
clearmatches([{win}])Clears all matches previously defined for the current window by matchadd() and the :match commands.
cmdcomplete_info()Returns a Dictionary with information about cmdline completion.
col({expr} [, {winid}])Returns the byte index of the column position given with {expr}.
complete({startcol}, {matches}) *E785*Set the matches for Insert mode completion.
complete_add({expr})Add {expr} to the list of matches.
complete_check()Check for a key typed while looking for completion matches.
complete_info([{what}])Returns a Dictionary with information about Insert mode completion.
confirm({msg} [, {choices} [, {default} [, {type}]]])confirm() offers the user a dialog, from which a choice can be made.
copy({expr})Make a copy of {expr}.
cos({expr})Return the cosine of {expr}, measured in radians, as a Float.
cosh({expr})Return the hyperbolic cosine of {expr} as a Float in the range [1, inf].
count({comp}, {expr} [, {ic} [, {start}]]) *E706*Return the number of times an item with value {expr} appears in String, List or Dictionary {comp}.
ctxget([{index}])Returns a Dictionary representing the context at {index} from the top of the context-stack (see context-dict).
ctxpop()Pops and restores the context at the top of the context-stack.
ctxpush([{types}])Pushes the current editor state (context) on the context-stack.
ctxset({context} [, {index}])Sets the context at {index} from the top of the context-stack to that represented by {context}.
ctxsize()Returns the size of the context-stack.
cursor({lnum}, {col} [, {off}])Positions the cursor at the column (byte count) {col} in the line {lnum}.
debugbreak({pid})Specifically used to interrupt a program being debugged.
deepcopy({expr} [, {noref}]) *E698*Make a copy of {expr}.
delete({fname} [, {flags}])Without {flags} or with {flags} empty:
deletebufline({buf}, {first} [, {last}])Delete lines {first} to {last} (inclusive) from buffer {buf}.
dictwatcheradd({dict}, {pattern}, {callback})Adds a watcher to a dictionary.
dictwatcherdel({dict}, {pattern}, {callback})Removes a watcher added with dictwatcheradd().
did_filetype()Returns TRUE when autocommands are being executed and the FileType event has been triggered at least once.
diff_filler({lnum})Returns the number of filler lines above line {lnum}.
diff_hlID({lnum}, {col})Returns the highlight ID for diff mode at line {lnum} column {col} (byte index).
digraph_get({chars}) *E1214*Return the digraph of {chars}.
digraph_getlist([{listall}])Return a list of digraphs.
digraph_set({chars}, {digraph})Add digraph {chars} to the list.
digraph_setlist({digraphlist})Similar to digraph_set() but this function can add multiple digraphs at once.
empty({expr})Return the Number 1 if {expr} is empty, zero otherwise.
environ()Return all of environment variables as dictionary.
escape({string}, {chars})Escape the characters in {chars} that occur in {string} with a backslash.
eval({string})Evaluate {string} and return the result.
eventhandler()Returns 1 when inside an event handler.
executable({expr})This function checks if an executable with the name {expr} exists.
execute({command} [, {silent}])Execute {command} and capture its output.
exepath({expr})Returns the full path of {expr} if it is an executable and given as a (partial or full) path or is found in $PATH.
exists({expr})Checks whether the expression {expr} is defined.
exp({expr})Return the exponential of {expr} as a Float in the range [0, inf].
expand({string} [, {nosuf} [, {list}]])Expand wildcards and the following special keywords in {string}.
expandcmd({string} [, {options}])Expand special items in String {string} like what is done for an Ex command such as :edit.
extend({expr1}, {expr2} [, {expr3}]){expr1} and {expr2} must be both Lists or both Dictionaries.
extendnew({expr1}, {expr2} [, {expr3}])Like extend() but instead of adding items to {expr1} a new List or Dictionary is created and returned.
feedkeys({string} [, {mode}])Characters in {string} are queued for processing as if they come from a mapping or were typed by the user.
file_readable()Obsolete name for filereadable().
filecopy({from}, {to})Copy the file pointed to by the name {from} to {to}.
filereadable({file})Returns TRUE if {file} exists, can be read, and is not a directory, else FALSE.
filewritable({file})Checks whether a file with the name {file} exists and can be written.
filter({expr1}, {expr2}){expr1} must be a List, String, Blob or Dictionary.
finddir({name} [, {path} [, {count}]])Find directory {name} in {path}.
findfile({name} [, {path} [, {count}]])Just like finddir(), but find a file instead of a directory.
flatten({list} [, {maxdepth}])Flatten {list} up to {maxdepth} levels.
flattennew({list} [, {maxdepth}])Like flatten() but first make a copy of {list}.
float2nr({expr})Convert {expr} to a Number by omitting the part after the decimal point.
floor({expr})Return the largest integral value less than or equal to {expr} as a Float (round down).
fmod({expr1}, {expr2})Return the remainder of {expr1} / {expr2}, even if the division is not representable.
fnameescape({string})Escape {string} for use as file name command argument.
fnamemodify({fname}, {mods})Modify file name {fname} according to {mods}.
foldclosed({lnum})Returns the first line number of the closed fold containing line {lnum}.
foldclosedend({lnum})Returns the last line number of the closed fold containing line {lnum}.
foldlevel({lnum})Returns the fold nesting level of line {lnum} in the current buffer.
foldtext()Returns a String, to be displayed for a closed fold.
foldtextresult({lnum})Returns the text that is displayed for the closed fold at line {lnum}.
foreach({expr1}, {expr2}){expr1} must be a List, String, Blob or Dictionary.
foreground()—
fullcommand({name})Get the full command name from a short abbreviated command name; see 20.2 for details on command abbreviations.
funcref({name} [, {arglist}] [, {dict}])Just like function(), but the returned Funcref will lookup the function by reference, not by name.
function({name} [, {arglist}] [, {dict}]) *partial* *E700* *E923*Return a Funcref variable that refers to function {name}.
garbagecollect([{atexit}])Cleanup unused Lists and Dictionaries that have circular references.
get({list}, {idx} [, {default}]) *get()-list*Get item {idx} from List {list}.
getbufinfo([{buf}])Get information about buffers as a List of Dictionaries.
getbufline({buf}, {lnum} [, {end}])Return a List with the lines starting from {lnum} to {end} (inclusive) in the buffer {buf}.
getbufoneline({buf}, {lnum})Just like getbufline() but only get one line and return it as a string.
getbufvar({buf}, {varname} [, {def}])The result is the value of option or local buffer variable {varname} in buffer {buf}.
getcellwidths()Returns a List of cell widths of character ranges overridden by setcellwidths().
getchangelist([{buf}])Returns the changelist for the buffer {buf}.
getchar([{expr} [, {opts}]])Get a single character from the user or input stream.
getcharmod()Returns the state of the keyboard modifiers for the last character obtained with getchar() or in another way.
getcharpos({expr})Get the position for String {expr}.
getcharsearch()Return the current character search information as a {dict} with the following entries:
getcharstr([{expr} [, {opts}]])The same as getchar(), except that this always returns a String, and "number" isn't allowed in {opts}.
getcmdcomplpat()Return completion pattern of the current command-line.
getcmdcompltype()Return the type of the current command-line completion.
getcmdline()Return the current command-line input.
getcmdpos()Return the position of the cursor in the command line as a byte count.
getcmdprompt()Return the current command-line prompt when using functions like input() or confirm().
getcmdscreenpos()Return the screen position of the cursor in the command line as a byte count.
getcmdtype()Return the current command-line type.
getcmdwintype()Return the current command-line-window type.
getcompletion({pat}, {type} [, {filtered}])Return a list of command-line completion matches.
getcompletiontype({pat})Return the type of the command-line completion using {pat}.
getcurpos([{winid}])Get the position of the cursor.
getcursorcharpos([{winid}])Same as getcurpos() but the column number in the returned List is a character index instead of a byte index.
getcwd([{winnr} [, {tabnr}]])With no arguments, returns the name of the effective current-directory.
getenv({name})Return the value of environment variable {name}.
getfontname([{name}])Without an argument returns the name of the normal font being used.
getfperm({fname})Returns the file permissions of the given file {fname} as a String.
getfsize({fname})Returns the size in bytes of the given file {fname}.
getftime({fname})Returns the last modification time ("mtime") of file {fname}.
getftype({fname})Returns a description of the type of file {fname} as a String.
getjumplist([{winnr} [, {tabnr}]])Returns the jumplist for the specified window.
getline({lnum} [, {end}])Without {end} the result is a String, which is line {lnum} from the current buffer.
getloclist({nr} [, {what}])Returns a List with all the entries in the location list for window {nr} (window-number or window-ID).
getmarklist([{buf}])Without the {buf} argument returns a List with information about all the global marks.
getmatches([{win}])Returns a List with all matches previously defined for the current window by matchadd() and the :match commands.
getmousepos()Returns a Dictionary with the last known position of the mouse.
getpid()Return a Number which is the process ID of the Vim process.
getpos({expr})Gets a position, where {expr} is one of:
getqflist([{what}])Returns a List with all the current quickfix errors.
getreg([{regname} [, 1 [, {list}]]])Returns the contents of register {regname} as a String.
getreginfo([{regname}])Returns detailed information about register {regname} as a Dictionary with the following entries:
getregion({pos1}, {pos2} [, {opts}])Returns the list of strings from {pos1} to {pos2} from a buffer.
getregionpos({pos1}, {pos2} [, {opts}])Same as getregion(), but returns a list of positions describing the buffer text segments bound by {pos1} and {pos2}.
getregtype([{regname}])Returns the type of register {regname} as a String.
getscriptinfo([{opts}])Returns a List with information about all the sourced Vim scripts in the order they were sourced, like what :scriptnames shows.
getstacktrace()Returns the current stack trace of Vim scripts.
gettabinfo([{tabnr}])If {tabnr} is not specified, then information about all the tabpages is returned as a List.
gettabvar({tabnr}, {varname} [, {def}])Get the value of a tab-local variable {varname} in tabpage {tabnr}.
gettabwinvar({tabnr}, {winnr}, {varname} [, {def}])Get the value of window-local variable {varname} in window {winnr} in tabpage {tabnr}.
gettagstack([{winnr}])Returns the tag stack of window {winnr} (window-number or window-ID) as a Dict.
gettext({text})Translate String {text} if possible.
getwininfo([{winid}])Returns information about windows as a List with Dictionaries.
getwinpos([{timeout}])Returns the [x, y] screen position of the Nvim GUI window as a List with two numbers (result of getwinposx() and getwinposy() combined).
getwinposx()Returns the X coordinate in pixels of the left hand side of the Nvim GUI window, or -1 if not available.
getwinposy()Returns the Y coordinate in pixels of the top of the Nvim GUI window, or -1 if not available.
getwinvar({winnr}, {varname} [, {def}])Like gettabwinvar() for the current tabpage.
glob({expr} [, {nosuf} [, {list} [, {alllinks}]]])Expand the file wildcards in {expr}.
glob2regpat({string})Convert a file pattern, as used by glob(), into a search pattern.
globpath({path}, {expr} [, {nosuf} [, {list} [, {allinks}]]])Perform glob() for String {expr} on all directories in {path} and concatenate the results.
has({feature})Returns 1 if {feature} is supported, 0 otherwise.
has_key({dict}, {key})Checks whether Dictionary {dict} has an entry with key {key}.
haslocaldir([{winnr} [, {tabnr}]])Checks whether the window or tabpage has set a local working directory.
hasmapto({what} [, {mode} [, {abbr}]])Checks whether a mapping exists whose rhs contains {what}.
highlightID()Obsolete name for hlID().
highlight_exists()Obsolete name for hlexists().
histadd({history}, {item})Add the String {item} to the history {history} which can be one of:
histdel({history} [, {item}])Clear {history}, i.e. delete all its entries. See hist-names for the possible values of {history}.
histget({history} [, {index}])Returns an entry from the specified command-line {history}.
histnr({history})The result is the Number of the current entry in {history}.
hlID({name})Returns the numeric ID of the highlight group with name {name}.
hlexists({name})Checks whether a highlight group called {name} exists.
hostname()Returns the hostname of the machine on which the Nvim server (not the UI client) is currently running.
iconv({string}, {from}, {to})Converts the encoding of {string} from {from} to {to}.
id({expr})Returns a String which is a unique identifier of the container type (List, Dict, Blob and Partial).
indent({lnum})Returns the indent of line {lnum} in the current buffer.
index({object}, {expr} [, {start} [, {ic}]])Find {expr} in {object} and return its index.
indexof({object}, {expr} [, {opts}])Returns the index of an item in {object} where {expr} is v:true.
input({prompt} [, {text} [, {completion}]])Prompts the user to enter text on the command-line, and returns the text as a String.
inputdialog()Use input() instead.
inputlist({textlist})Displays a list of strings and prompts the user to select one by entering a number.
inputrestore()Restore typeahead that was saved with a previous inputsave().
inputsave()Preserve typeahead (also from mappings) and clear it, so that a following prompt gets input from the user.
inputsecret({prompt} [, {text}])This function acts much like the input() function with but two exceptions:
insert({object}, {item} [, {idx}])When {object} is a List or a Blob insert {item} at the start of it.
interrupt()Interrupt script execution.
invert({expr})Bitwise invert.
isabsolutepath({path})Checks whether {path} is an absolute path.
isdirectory({directory})Returns TRUE if {directory} exists, or FALSE if it doesn't exist or isn't a directory.
isinf({expr})Return 1 if {expr} is a positive infinity, or -1 a negative infinity, otherwise 0. >vim echo isinf(1.0 / 0.0)
islocked({expr}) *E786*Returns TRUE if {expr} is the name of a locked variable, else FALSE.
isnan({expr})Return TRUE if {expr} is a float with value NaN.
items({expr})Return a List with all key/index and value pairs of {expr}.
jobclose()Obsolete name for chanclose()
jobpid({job})Return the PID (process id) of job-id {job}.
jobresize({job}, {width}, {height})Resize the pseudo terminal window of job-id {job} to {width} columns and {height} rows.
jobsend()Obsolete name for chansend()
jobstart({cmd} [, {opts}])Spawns {cmd} as a job.
jobstop({id})Stop job-id {id} by sending SIGTERM to the job process.
jobwait({jobs} [, {timeout}])Waits for jobs and their on_exit handlers to complete.
join({list} [, {sep}])Join the items in {list} together into one String.
json_decode({expr})Convert {expr} from JSON object.
json_encode({expr})Convert {expr} into a JSON string.
keys({dict})Return a List with all the keys of {dict}.
keytrans({string})Turn the internal byte representation of keys into a form that can be used for :map.
last_buffer_nr()Obsolete name for bufnr("$").
len({expr}) *E701*Returns the length of the argument.
libcall({libname}, {funcname}, {argument}) *E364* *E368*Call function {funcname} in the run-time library {libname} with single argument {argument}.
libcallnr({libname}, {funcname}, {argument})Just like libcall(), but used for a function that returns an int instead of a string.
line({expr} [, {winid}])See getpos() for accepted positions.
line2byte({lnum})Return the byte count from the start of the buffer for line {lnum}.
lispindent({lnum})Get the amount of indent for line {lnum} according the lisp indenting rules, as with 'lisp'.
list2blob({list})Return a Blob concatenating all the number values in {list}.
list2str({list} [, {utf8}])Convert each number in {list} to a character string can concatenate them all.
localtime()Return the current time, measured as seconds since 1st Jan 1970. See also strftime(), strptime() and getftime().
log({expr})Return the natural logarithm (base e) of {expr} as a Float.
log10({expr})Return the logarithm of Float {expr} to base 10 as a Float.
luaeval({expr} [, {expr}])Evaluate Lua expression {expr} and return its result converted to Vim data structures.
map({expr1}, {expr2}){expr1} must be a List, String, Blob or Dictionary.
maparg({name} [, {mode} [, {abbr} [, {dict}]]])When {dict} is omitted or zero:
mapcheck({name} [, {mode} [, {abbr}]])Check if there is a mapping that matches with {name} in mode {mode}.
maplist([{abbr}])Returns a List of all mappings.
mapnew({expr1}, {expr2})Like map() but instead of replacing items in {expr1} a new List or Dictionary is created and returned.
mapset({mode}, {abbr}, {dict})Restore a mapping from a dictionary, possibly returned by maparg() or maplist().
match({expr}, {pat} [, {start} [, {count}]])When {expr} is a List then this returns the index of the first item where {pat} matches.
matchadd()Defines a pattern to be highlighted in the current window (a "match").
matchaddpos({group}, {pos} [, {priority} [, {id} [, {dict}]]])Same as matchadd(), but requires a list of positions {pos} instead of a pattern.
matcharg({nr})Selects the {nr} match item, as set with a :match, :2match or :3match command.
matchbufline({buf}, {pat}, {lnum}, {end}, [, {dict}])Returns the List of matches in lines from {lnum} to {end} in buffer {buf} where {pat} matches.
matchdelete({id} [, {win}]) *E802* *E803*Deletes a match with ID {id} previously defined by matchadd() or one of the :match commands.
matchend({expr}, {pat} [, {start} [, {count}]])Same as match(), but return the index of first character after the match.
matchfuzzy({list}, {str} [, {dict}])If {list} is a list of strings, then returns a List with all the strings in {list} that fuzzy match {str}.
matchfuzzypos({list}, {str} [, {dict}])Same as matchfuzzy(), but returns the list of matched strings, the list of character positions where characters in {str} matches and a list of matching scores.
matchlist({expr}, {pat} [, {start} [, {count}]])Same as match(), but return a List.
matchstr({expr}, {pat} [, {start} [, {count}]])Same as match(), but return the matched string.
matchstrlist({list}, {pat} [, {dict}])Returns the List of matches in {list} where {pat} matches.
matchstrpos({expr}, {pat} [, {start} [, {count}]])Same as matchstr(), but return the matched string, the start position and the end position of the match.
max({expr})Return the maximum value of all items in {expr}.
menu_get({path} [, {modes}])Returns a List of Dictionaries describing menus (defined by :menu, :amenu, …), including hidden-menus.
menu_info({name} [, {mode}])Return information about the specified menu {name} in mode {mode}.
min({expr})Return the minimum value of all items in {expr}.
mkdir({name} [, {flags} [, {prot}]]) *E739*Create directory {name}.
mode([{expr}])Return a string that indicates the current mode.
msgpackdump({list} [, {type}])Convert a list of Vimscript objects to msgpack.
msgpackparse({data})Convert a readfile()-style list or a Blob to a list of Vimscript objects.
nextnonblank({lnum})Return the line number of the first line at or below {lnum} that is not blank.
nr2char({expr} [, {utf8}])Return a string with a single character, which has the number value {expr}.
or({expr}, {expr})Bitwise OR on the two arguments.
pathshorten({path} [, {len}])Shorten directory names in the path {path} and return the result.
perleval({expr})Evaluate perl expression {expr} and return its result converted to Vim data structures.
pow({x}, {y})Return the power of {x} to the exponent {y} as a Float.
preinserted()Returns non-zero if text has been inserted after the cursor because "preinsert" is present in 'completeopt', or because "longest" is present in 'completeopt' while 'autocomplete' is active.
prevnonblank({lnum})Return the line number of the first line at or above {lnum} that is not blank.
printf({fmt}, {expr1} ...)Return a String with {fmt}, where "%" items are replaced by the formatted form of their respective arguments.
prompt_appendbuf({buf}, {text})Appends text to prompt buffer before current prompt.
prompt_getinput({buf})Gets the current user-input in prompt-buffer {buf} without invoking prompt_callback.
prompt_getprompt({buf})Returns the effective prompt text for buffer {buf}.
prompt_setcallback({buf}, {expr})Set prompt callback for buffer {buf} to {expr}.
prompt_setinterrupt({buf}, {expr})Set a callback for buffer {buf} to {expr}.
prompt_setprompt({buf}, {text})Set prompt for buffer {buf} to {text}.
pum_getpos()If the popup menu (see ins-completion-menu) is not visible, returns an empty Dictionary, otherwise, returns a Dictionary with the following keys:
pumvisible()Returns non-zero when the popup menu is visible, zero otherwise.
py3eval({expr})Evaluate Python expression {expr} and return its result converted to Vim data structures.
pyeval({expr}) *E858* *E859*Evaluate Python expression {expr} and return its result converted to Vim data structures.
pyxeval({expr})Evaluate Python expression {expr} and return its result converted to Vim data structures.
rand([{expr}])Return a pseudo-random Number generated with an xoshiro128** algorithm using seed {expr}.
range({expr} [, {max} [, {stride}]]) *E726* *E727*Returns a List with Numbers:
readblob({fname} [, {offset} [, {size}]])Read file {fname} in binary mode and return a Blob.
readdir({directory} [, {expr}])Return a list with file and directory names in {directory}.
readfile({fname} [, {type} [, {max}]])Read file {fname} and return a List, each line of the file as an item.
reduce({object}, {func} [, {initial}]) *E998*{func} is called for every item in {object}, which can be a String, List or a Blob.
reg_executing()Returns the single letter name of the register being executed.
reg_recorded()Returns the single letter name of the last recorded register.
reg_recording()Returns the single letter name of the register being recorded.
reltime()Return an item that represents a time value.
reltimefloat({time})Return a Float that represents the time value of {time}.
reltimestr({time})Return a String that represents the time value of {time}.
remove({list}, {idx})Without {end}:
rename({from}, {to})Rename the file by the name {from} to the name {to}.
repeat({expr}, {count})Repeat {expr} {count} times and return the concatenated result.
resolve({filename}) *E655*On MS-Windows, when {filename} is a shortcut (a .lnk file), returns the path the shortcut points to in a simplified form.
reverse({object})Reverse the order of items in {object}.
round({expr})Round off {expr} to the nearest integral value and return it as a Float.
rpcnotify({channel}, {event} [, {args}...])Sends {event} to {channel} via RPC and returns immediately.
rpcrequest({channel}, {method} [, {args}...])Sends a request to {channel} to invoke {method} via RPC and blocks until a response is received.
rpcstart()Use jobstart() with {'rpc': v:true} instead.
rpcstop()Use jobstop() instead to stop any job, or chanclose(id, "rpc") to close RPC communication without stopping the job. Use chanclose(id) to close any socket.
rubyeval({expr})Evaluate Ruby expression {expr} and return its result converted to Vim data structures.
screenattr({row}, {col})Like screenchar(), but return the attribute.
screenchar({row}, {col})Returns the character at screen position [row, col] as a Number.
screenchars({row}, {col})Returns the character and any composing characters at screen position [row, col] as a List of Numbers.
screencol()Returns the current screen column of the cursor.
screenpos({winid}, {lnum}, {col})Returns the screen position of the text character in window {winid} at buffer line {lnum} and column {col} as a Dict.
screenrow()Returns the current screen row of the cursor.
screenstring({row}, {col})Returns the base character and any composing characters at screen position [row, col] as a String.
search({pattern} [, {flags} [, {stopline} [, {timeout} [, {skip}]]]])Search for regexp pattern {pattern}.
searchcount([{options}])Get or update the last search count, like what is displayed without the "S" flag in 'shortmess'.
searchdecl({name} [, {global} [, {thisblock}]])Search for the declaration of {name}.
searchpair({start}, {middle}, {end} [, {flags} [, {skip} [, {stopline} [, {timeout}]]]])Search for the match of a nested start-end pair.
searchpairpos({start}, {middle}, {end} [, {flags} [, {skip} [, {stopline} [, {timeout}]]]])Same as searchpair(), but returns a List with the line and column position of the match.
searchpos({pattern} [, {flags} [, {stopline} [, {timeout} [, {skip}]]]])Same as search(), but returns a List with the line and column position of the match.
serverlist([{opts}])Returns a list of server addresses, or empty if all servers were stopped.
serverstart([{address}])Opens a socket or named pipe at {address} and listens for RPC messages.
serverstop({address})Closes the pipe or socket at {address}.
setbufline({buf}, {lnum}, {text})Set line {lnum} to {text} in buffer {buf}.
setbufvar({buf}, {varname}, {val})Set option or local variable {varname} in buffer {buf} to {val}.
setcellwidths({list})Specify overrides for cell widths of character ranges.
setcharpos({expr}, {list})Same as setpos() but uses the specified column number as the character index instead of the byte index in the line.
setcharsearch({dict})Set the current character search information to {dict}, which contains one or more of the following entries:
setcmdline({str} [, {pos}])Set the command line to {str} and set the cursor position to {pos}.
setcmdpos({pos})Set the cursor position in the command line to byte position {pos}.
setcursorcharpos({lnum}, {col} [, {off}])Same as cursor() but uses the specified column number as the character index instead of the byte index in the line.
setenv({name}, {val})Set environment variable {name} to {val}.
setfperm({fname}, {mode}) *chmod*Set the file permissions for {fname} to {mode}.
setline({lnum}, {text})Set line {lnum} of the current buffer to {text}.
setloclist({nr}, {list} [, {action} [, {what}]])Create or replace or add to the location list for window {nr} (window-number or window-ID).
setmatches({list} [, {win}])Restores a list of matches saved by getmatches() for the current window.
setpos({expr}, {list})Set the position for String {expr}.
setqflist({list} [, {action} [, {what}]])Create or replace or add to the quickfix list.
setreg({regname}, {value} [, {options}])Set the register {regname} to {value}.
settabvar({tabnr}, {varname}, {val})Set tab-local variable {varname} to {val} in tabpage {tabnr}.
settabwinvar({tabnr}, {winnr}, {varname}, {val})Set option or local variable {varname} in window {winnr} to {val}.
settagstack({nr}, {dict} [, {action}])Modify the tag stack of the window {nr} (window-number or window-ID) using {dict}.
setwinvar({nr}, {varname}, {val})Like settabwinvar() for the current tabpage.
sha256({expr})Returns a String with 64 hex characters, which is the SHA256 checksum of {expr}.
shellescape({string} [, {special}])Escape {string} for use as a shell command argument.
shiftwidth([{col}])Returns the effective value of 'shiftwidth'.
sign_define({name} [, {dict}])Define a new sign named {name} or modify the attributes of an existing sign.
sign_getdefined([{name}])Get a list of defined signs and their attributes.
sign_getplaced([{buf} [, {dict}]])Return a list of signs placed in a buffer or all the buffers.
sign_jump({id}, {group}, {buf})Open the buffer {buf} or jump to the window that contains {buf} and position the cursor at sign {id} in group {group}.
sign_place({id}, {group}, {name}, {buf} [, {dict}])Place the sign defined as {name} at line {lnum} in file or buffer {buf} and assign {id} and {group} to sign.
sign_placelist({list})Place one or more signs.
sign_undefine([{name}])Deletes a previously defined sign {name}.
sign_unplace({group} [, {dict}])Remove a previously placed sign in one or more buffers.
sign_unplacelist({list})Remove previously placed signs from one or more buffers.
simplify({filename})Simplify the file name as much as possible without changing the meaning.
sin({expr})Return the sine of {expr}, measured in radians, as a Float.
sinh({expr})Return the hyperbolic sine of {expr} as a Float in the range [-inf, inf].
slice({expr}, {start} [, {end}])Similar to using a slice "expr[start :
sockconnect({mode}, {address} [, {opts}])Connect a socket to an address.
sort({list} [, {how} [, {dict}]]) *E702*Sort the items in {list} in-place.
soundfold({word})Return the sound-folded equivalent of {word}.
spellbadword([{sentence}])Without argument:
spellsuggest({word} [, {max} [, {capital}]])Return a List with spelling suggestions to replace {word}.
split({string} [, {pattern} [, {keepempty}]])Make a List out of {string}.
sqrt({expr})Return the non-negative square root of Float {expr} as a Float.
srand([{expr}])Initialize seed used by rand():
state([{what}])Return a string which contains characters indicating the current state.
stdioopen({opts})With --headless this opens stdin and stdout as a channel.
stdpath({what}) *E6100*Returns standard-path locations of various default files and directories.
str2float({string} [, {quoted}])Convert String {string} to a Float.
str2list({string} [, {utf8}])Return a list containing the number values which represent each character in String {string}.
str2nr({string} [, {base}])Convert string {string} to a number.
strcharlen({string})Returns the number of characters in String {string}, ignoring composing characters.
strcharpart({src}, {start} [, {len} [, {skipcc}]])Like strpart() but using character index and length instead of byte index and length.
strchars({string} [, {skipcc}])Returns the number of characters in String {string}.
strdisplaywidth({string} [, {col}])Returns the number of display cells String {string} occupies on the screen when it starts at {col} (first column is zero).
strftime({format} [, {time}])Formats a date and time String specified by {format}.
strgetchar({str}, {index})Get a Number corresponding to the character at {index} in {str}.
stridx({haystack}, {needle} [, {start}])Returns the byte index of the first occurrence of {needle} in {haystack}.
string({expr})Converts {expr} to a String.
strlen({string})Returns the length of String {string} in bytes.
strpart({src}, {start} [, {len} [, {chars}]])Gets a substring from {src}, starting from byte {start}, with byte length {len}.
strptime({format}, {timestring})Parses a date/time string and returns a unix timestamp.
strridx({haystack}, {needle} [, {start}])Returns the byte index of the last occurrence of {needle} in {haystack}.
strtrans({string})Translates all unprintable characters in {string} into printable characters 'isprint', like they are shown in a window.
strutf16len({string} [, {countcc}])Returns the number of UTF-16 code units in String {string} (after converting it to UTF-16).
strwidth({string})Returns the number of display cells String {string} occupies.
submatch({nr} [, {list}]) *E935*Only for an expression in a :substitute command or substitute() function.
substitute({string}, {pat}, {sub}, {flags})Performs string substitution.
swapfilelist()Returns a list of swap file names, like what "vim -r" shows.
swapinfo({fname})Returns information about the swapfile {fname} as a dictionary.
swapname({buf})The result is the swap file path of the buffer {buf}.
synID({lnum}, {col}, {trans})Returns the syntax ID at position {lnum} and {col} in the current window.
synIDattr({synID}, {what} [, {mode}])Returns the {what} attribute of syntax ID {synID} as a String.
synIDtrans({synID})Returns the translated syntax ID of {synID}, following highlight links.
synconcealed({lnum}, {col})Returns conceal information for the character at position {lnum} and {col} as a List with three items:
synstack({lnum}, {col})Return a List, which is the stack of syntax items at the position {lnum} and {col} in the current window.
system({cmd} [, {input}]) *E677*Gets the output of {cmd} as a string (systemlist() returns a List) and sets v:shell_error to the error code.
systemlist({cmd} [, {input} [, {keepempty}]])Same as system(), but returns a List with lines (parts of output separated by NL) with NULs transformed into NLs.
tabpagebuflist([{arg}])Returns a List of buffer numbers, one for each window in the specified tabpage.
tabpagenr([{arg}])Returns the current tabpage-number.
tabpagewinnr({tabarg} [, {arg}])Like winnr() but for tabpage {tabarg}.
tagfiles()Returns a List with the file names used to search for tags for the current buffer.
taglist({expr} [, {filename}])Returns a List of tags matching the regular expression {expr}.
tan({expr})Return the tangent of {expr}, measured in radians, as a Float in the range [-inf, inf].
tanh({expr})Return the hyperbolic tangent of {expr} as a Float in the range [-1, 1].
tempname()Generates a (non-existent) filename located in the Nvim root tempdir.
termopen()Use jobstart() with {term: v:true}.
timer_info([{id}])Return a list with information about timers.
timer_pause({timer}, {paused})Pause or unpause a timer.
timer_start({time}, {callback} [, {options}]) *timer*Create a timer and return the timer ID.
timer_stop({timer})Stop a timer.
timer_stopall()Stop all timers.
tolower({expr})Converts a String to lowercase (like applying gu).
toupper({expr})Converts a String to uppercase (like applying gU).
tr({src}, {fromstr}, {tostr})Translates characters in {src}, replacing each character that appears in {fromstr} with the corresponding character in {tostr}.
trim({text} [, {mask} [, {dir}]])Return {text} as a String where any character in {mask} is removed from the beginning and/or end of {text}.
trunc({expr})Return the largest integral value with magnitude less than or equal to {expr} as a Float (truncate towards zero).
type({expr})Returns the type of {expr} as a Number.
undofile({name})Return the name of the undo file that would be used for a file with name {name} when writing.
undotree([{buf}])Return the current state of the undo tree for the current buffer, or for a specific buffer if {buf} is given.
uniq({list} [, {func} [, {dict}]]) *E882*Remove second and succeeding copies of repeated adjacent {list} items in-place.
utf16idx({string}, {idx} [, {countcc} [, {charidx}]])Same as charidx() but returns the UTF-16 code unit index of the byte at {idx} in {string} (after converting it to UTF-16).
values({dict})Return a List with all the values of {dict}.
virtcol({expr} [, {list} [, {winid}]])Returns the virtual (screen) column of the file position given with {expr}.
virtcol2col({winid}, {lnum}, {col})Converts a virtual column to a byte index.
visualmode([{expr}])Returns a String describing the last Visual mode used in the current buffer.
wait({timeout}, {condition} [, {interval}])Waits until {condition} evaluates to TRUE, where {condition} is a Funcref or string containing an expression.
wildmenumode()Returns TRUE when the wildmenu is active and FALSE otherwise.
wildtrigger()Start wildcard expansion in the command-line, using the behavior defined by the 'wildmode' and 'wildoptions' settings.
win_execute({id}, {command} [, {silent}])Like execute() but in the context of window {id}.
win_findbuf({bufnr})Returns a List with window-IDs for windows that contain buffer {bufnr}.
win_getid([{win} [, {tab}]])Get the window-ID for the specified window.
win_gettype([{nr}])Return the type of the window:
win_gotoid({expr})Go to window-ID {expr}.
win_id2tabwin({expr})Return [tabnr, winnr] for window with window-ID {expr}, where tabnr is the tabpage-number and winnr is the window-number.
win_id2win({expr})Return the window-number of for the given window-ID {expr}.
win_move_separator({nr}, {offset})Move window {nr}'s vertical separator (i.e., the right border) by {offset} columns, as if being dragged by the mouse.
win_move_statusline({nr}, {offset})Move window {nr}'s status line (i.e., the bottom border) by {offset} rows, as if being dragged by the mouse.
win_screenpos({nr})Return the screen position of window {nr} as a list with two numbers:
win_splitmove({nr}, {target} [, {options}])Temporarily switch to window {target}, then move window {nr} to a new split adjacent to {target}.
winbufnr({nr})Returns the buffer number associated with window {nr} (window-number or window-ID).
wincol()Returns the virtual column of the cursor in the window.
windowsversion()Returns the Windows OS version as a String.
winheight({nr})Gets the height of window-ID {nr} (zero for "current window"), excluding any 'winbar' and 'statusline'.
winlayout([{tabnr}])Returns the layout of windows in a tabpage as a nested List.
winline()Returns the screen line of the cursor in the window.
winnr([{arg}])Returns the number of the current window.
winrestcmd()Returns a sequence of :resize commands that should restore the current window sizes.
winrestview({dict})Uses the Dictionary returned by winsaveview() to restore the view of the current window.
winsaveview()Returns a Dictionary that contains information to restore the view of the current window.
winwidth({nr})Gets the width of window-ID {nr} (zero for "current window"), including columns (sign-column, 'statuscolumn', etc.).
wordcount()Returns a dictionary of byte/chars/word statistics for the current buffer.
writefile({data}, {fname} [, {flags}])Writes {data} to file {fname}.
xor({expr}, {expr})Bitwise XOR on the two arguments.

Autocommand Events

145

Every event :autocmd and nvim_create_autocmd() can hook

BufAddAfter adding a new buffer or existing unlisted buffer to the buffer list (except during startup, see VimEnter), or renaming a listed buffer.
BufCreateUse BufAdd instead.
BufDeleteBefore deleting a buffer from the buffer list.
BufEnterAfter entering (visiting, switching-to) a new or existing buffer.
BufFilePostAfter changing the name of the current buffer with the ":file" or ":saveas" command.
BufFilePreBefore changing the name of the current buffer with the ":file" or ":saveas" command.
BufHiddenBefore a buffer becomes hidden:
BufLeaveBefore leaving to another buffer.
BufModifiedSetAfter the 'modified' value of a buffer has been changed.
BufNewAfter creating a new buffer (except during startup, see VimEnter) or renaming an existing buffer.
BufNewFileWhen starting to edit a file that doesn't exist.
BufReadWhen starting to edit a new buffer, after reading the file into the buffer, before processing modelines.
BufReadCmdBefore starting to edit a new buffer.
BufReadPostWhen starting to edit a new buffer, after reading the file into the buffer, before processing modelines.
BufReadPreWhen starting to edit a new buffer, before reading the file into the buffer.
BufUnloadBefore unloading a buffer, when the text in the buffer is going to be freed.
BufWinEnterAfter a buffer is displayed in a window.
BufWinLeaveBefore a buffer is removed from a window.
BufWipeoutBefore completely deleting a buffer.
BufWriteBefore writing the whole buffer to a file.
BufWriteCmdBefore writing the whole buffer to a file.
BufWritePostAfter writing the whole buffer to a file (should undo the commands for BufWritePre).
BufWritePreBefore writing the whole buffer to a file.
ChanInfoState of channel changed, for instance the client of a RPC channel described itself.
ChanOpenJust after a channel was opened.
CmdUndefinedWhen a user command is used but it isn't defined.
CmdlineChangedAfter EVERY change inside command line.
CmdlineEnterAfter entering the command-line (including non-interactive use of ":" in a mapping:
CmdlineLeaveBefore leaving the command-line (including non-interactive use of ":" in a mapping:
CmdlineLeavePreJust before leaving the command line, and before CmdlineLeave.
CmdwinEnterAfter entering the command-line window.
CmdwinLeaveBefore leaving the command-line window.
ColorSchemeAfter loading a color scheme.
ColorSchemePreBefore loading a color scheme.
CompleteChangedAfter each time the Insert mode completion menu changed.
CompleteDoneAfter Insert mode completion is done.
CompleteDonePreAfter Insert mode completion is done.
CursorHoldWhen there is no user input for 'updatetime' duration, in Normal-mode.
CursorHoldILike CursorHold, but in Insert mode.
CursorMovedAfter the cursor was moved in Normal or Visual mode or to another window.
CursorMovedCAfter the cursor was moved in the command line.
CursorMovedIAfter the cursor was moved in Insert mode.
DiagnosticChangedAfter diagnostics have changed.
DiffUpdatedAfter diffs have been updated.
DirChangedAfter the current-directory was changed.
DirChangedPreWhen the current-directory is going to be changed, as with DirChanged.
EncodingChangedNever fired; 'encoding' is always "utf-8".
ExitPreWhen using :quit, :wq in a way it makes Vim exit, or using :qall, just after QuitPre.
FileAppendCmdBefore appending to a file.
FileAppendPostAfter appending to a file.
FileAppendPreBefore appending to a file.
FileChangedROBefore making the first change to a read-only file.
FileChangedShellWhen Vim notices that the modification time of a file has changed since editing started.
FileChangedShellPostAfter handling a file that was changed outside of Vim.
FileEncodingNever fired; equivalent to EncodingChanged.
FileReadCmdBefore reading a file with a ":read" command.
FileReadPostAfter reading a file with a ":read" command.
FileReadPreBefore reading a file with a ":read" command.
FileTypeWhen the 'filetype' option has been set.
FileWriteCmdBefore writing to a file, when not writing the whole buffer.
FileWritePostAfter writing to a file, when not writing the whole buffer.
FileWritePreBefore writing to a file, when not writing the whole buffer.
FilterReadPostAfter reading a file from a filter command.
FilterReadPreBefore reading a file from a filter command.
FilterWritePostAfter writing a file for a filter command or making a diff with an external diff (see DiffUpdated for internal diff).
FilterWritePreBefore writing a file for a filter command or making a diff with an external diff.
FocusGainedNvim got focus.
FocusLostNvim lost focus.
FuncUndefinedWhen a user function is used but it isn't defined.
GUIEnterNever fired; use UIEnter instead.
GUIFailedNever fired.
InsertChangeWhen typing <Insert> while in Insert or Replace mode.
InsertCharPreWhen a character is typed in Insert mode, before inserting the char.
InsertEnterJust before starting Insert mode.
InsertLeaveJust after leaving Insert mode.
InsertLeavePreJust before leaving Insert mode.
LspAttachAfter an LSP client performs "initialize" and attaches to a buffer.
LspDetachJust before an LSP client detaches from a buffer.
LspNotifyThis event is triggered after each successful notification sent to an LSP server.
LspProgressUpon receipt of a progress notification from the server.
LspRequestFor each request sent to an LSP server, this event is triggered for every change to the request's status.
LspTokenUpdateWhen a visible semantic token is sent or updated by the LSP server, or when an existing token becomes visible for the first time.
MarkSetAfter a mark is set by m, :mark, and nvim_buf_set_mark(), or deleted by :delmarks and nvim_buf_del_mark().
MenuPopupJust before showing the popup menu (under the right mouse button).
ModeChangedAfter changing the mode.
OptionSetAfter setting an option (except during startup).
PackChangedAfter plugin's state has changed.
PackChangedPreBefore trying to change plugin's state.
ProgressAfter a progress-message is created or updated via nvim_echo.
QuickFixCmdPostLike QuickFixCmdPre, but after a quickfix command is run, before jumping to the first location.
QuickFixCmdPreBefore a quickfix command is run (:make, :lmake, :grep, :lgrep, :grepadd, :lgrepadd, :vimgrep, :lvimgrep, :vimgrepadd, :lvimgrepadd, :cfile, :cgetfile, :caddfile, :lfile, :lgetfile, :laddfile, :helpgrep,
QuitPreWhen using :quit, :wq or :qall, before deciding whether it closes the current window or quits Vim.
RecordingEnterWhen a macro starts recording.
RecordingLeaveWhen a macro stops recording.
RemoteReplyWhen a reply from a Vim that functions as server was received server2client().
SafeStateWhen nothing is pending, going to wait for the user to type a character.
SearchWrappedAfter making a search with n or N if the search wraps around the document back to the start/finish respectively.
SessionLoadPostAfter loading the session file created using the :mksession command.
SessionLoadPreBefore loading the session file created using the :mksession command.
SessionWritePostAfter writing a session file by calling the :mksession command.
ShellCmdPostAfter executing a shell command with :!cmd, :make and :grep.
ShellFilterPostAfter executing a shell command with ":{range}!cmd", ":w !cmd" or ":r !cmd".
SignalAfter Nvim receives a signal.
SourceCmdWhen sourcing a Vimscript/Lua file.
SourcePostAfter sourcing a Vimscript/Lua file.
SourcePreBefore sourcing a Vimscript/Lua file.
SpellFileMissingWhen trying to load a spell checking file and it can't be found.
StdinReadPostDuring startup, after reading from stdin into the buffer, before executing modelines.
StdinReadPreDuring startup, before reading from stdin into the buffer.
SwapExistsDetected an existing swap file when starting to edit a file.
SyntaxWhen the 'syntax' option has been set.
TabClosedAfter closing a tabpage.
TabClosedPreBefore closing a tabpage.
TabEnterJust after entering a tabpage.
TabLeaveJust before leaving a tabpage.
TabNewWhen creating a new tabpage.
TabNewEnteredAfter entering a new tabpage.
TermChangedaccepted for compatibility
TermCloseWhen a terminal job ends.
TermEnterAfter entering Terminal-mode.
TermLeaveAfter leaving Terminal-mode.
TermOpenWhen a terminal job is starting.
TermRequestWhen a :terminal child process emits an OSC, DCS, or APC sequence.
TermResponseWhen Nvim receives a DA1, OSC, DCS, or APC response from the host terminal.
TextChangedAfter a change was made to the text in the current buffer in Normal mode.
TextChangedIAfter a change was made to the text in the current buffer in Insert mode.
TextChangedPAfter a change was made to the text in the current buffer in Insert mode, only when the popup menu is visible.
TextChangedTAfter a change was made to the text in the current buffer in Terminal-mode.
TextYankPostJust after a yank or deleting command, but not if the black hole register quote_ is used nor for setreg().
UIEnterAfter a UI connects via nvim_ui_attach(), or after builtin TUI is started, after VimEnter.
UILeaveAfter a UI disconnects from Nvim, or after builtin TUI is stopped, after VimLeave.
UserNot executed automatically.
VimEnterAfter doing all the startup stuff, including loading vimrc files, executing the "-c cmd" arguments, creating all windows and loading the buffers in them.
VimLeaveBefore exiting Vim, just after writing the .shada file.
VimLeavePreBefore exiting Vim, just before writing the shada file.
VimResizedAfter the Vim window was resized, thus 'lines' and/or 'columns' changed.
VimResumeAfter Nvim resumes from suspend state.
VimSuspendBefore Nvim enters suspend state.
WinClosedWhen closing a window, just before it is removed from the window layout.
WinEnterAfter entering another window.
WinLeaveBefore leaving a window.
WinNewWhen a new window was created.
WinNewPreBefore creating a new window.
WinResizedAfter a window in the current tabpage changed width or height.
WinScrolledAfter any window in the current tabpage scrolled the text (horizontally or vertically) or changed width or height.

Starting Neovim

26

Command-line arguments and environment

nvim file …edit files; the first is shown, the rest are the argument list
nvim +{n} file · +/{pat} · +{cmd}open at line n · at the first match · run an ex command after loading
-c {cmd} · --cmd {cmd}ex command after / before the config is read
-ddiff mode: nvim -d a b
-o[N] · -O[N] · -p[N]open files in horizontal splits · vertical splits · tab pages
-Rread-only (view) mode
-nno swap file; memory only
-S {session}source a session file after loading — :mksession writes one
-s {scriptin}read Normal-mode keystrokes from a file
-u {config}use this file instead of init.lua; -u NONE skips config and plugins
-i {shada}use this shada file; -i NONE reads and writes none
--cleanfactory defaults: no user config, no plugins, no shada
-l {script} [args]run a Lua script and exit; ends option processing
-es · -Essilent batch (ex) mode, for scripted edits
--headlessstart no UI
--listen {addr}serve the RPC API on this socket or host:port
--server {addr} --remote[-send|-expr|-ui|-tab|-silent]act on a running instance
--embedspeak msgpack-RPC on stdin/stdout — how a GUI hosts Nvim
--api-infodump the API metadata as msgpack
--startuptime {file}write per-file startup timings
-V[N][file]verbosity; -V1 -v adds the compiled-in paths to the version
-v · -hversion · help
--only file names after this
$MYVIMRCthe config file that was actually read
$NVIM_APPNAMEreplaces the nvim segment of every standard path — a whole separate profile
$VIMRUNTIME · $NVIM · $NVIM_LOG_FILEthe runtime directory · the parent instance’s address inside :terminal · the log

Index II · Only in Neovim

What Neovim adds, changes or removes relative to Vim 9.1 — default mappings, the vim.* Lua library, vim.lsp, vim.treesitter, the nvim_* API, deprecations, and what Vim has that Neovim dropped

Default Mappings

71

LSP — created at startup, global

gOvim.lsp.buf.document_symbol()
grtvim.lsp.buf.type_definition()
grivim.lsp.buf.implementation()
grrvim.lsp.buf.references()
grxvim.lsp.codelens.run()
gravim.lsp.buf.code_action()
grnvim.lsp.buf.rename()
<C-S>vim.lsp.buf.signature_help()

Diagnostics

[DJump to the first diagnostic in the current buffer
[dJump to the previous diagnostic in the current buffer
]DJump to the last diagnostic in the current buffer
]dJump to the next diagnostic in the current buffer
<C-W><C-D>Show diagnostics under the cursor
<C-W>dShow diagnostics under the cursor

Tree-sitter node selection

[NSelect previous sibling node
[nSelect previous node
]NSelect next sibling node
]nSelect next node
anSelect parent (outer) node
inSelect child (inner) node

Editing

&repeat the last :s with its flags — mapped to :&&<CR>
Yyank to end of line — mapped to y$, consistent with D and C
[<Space>Add empty line above cursor
]<Space>Add empty line below cursor
gccToggle comment line
gcToggle comment
gxOpens filepath or URI under cursor with the system handler (file explorer, web browser, …)
<C-L>redraw, and also clear search highlighting (:nohlsearch) and update diffs (:diffupdate)
#search backward for the visual selection
*search forward for the visual selection
@linewise visual: execute the register once per selected line
Qlinewise visual: repeat the last recorded register once per selected line
gcComment textobject
<S-Tab>vim.snippet.jump if active, otherwise <S-Tab>
<C-W>delete the word before the cursor, setting an undo point first
<C-U>delete to start of line, setting an undo point first — u gets the text back
<Tab>vim.snippet.jump if active, otherwise <Tab>

Unimpaired-style list navigation

[B:brewind
[b:bprevious
[<C-T>:ptprevious
[T:trewind
[t:tprevious
[A:rewind
[a:previous
[<C-L>:lpfile
[L:lrewind
[l:lprevious
[<C-Q>:cpfile
[Q:crewind
[q:cprevious
]B:blast
]b:bnext
]<C-T>:ptnext
]T:tlast
]t:tnext
]A:last
]a:next
]<C-L>:lnfile
]L:llast
]l:lnext
]<C-Q>:cnfile
]Q:clast
]q:cnext

Built in or set on attach, so not in the map list

ZRrestart Nvim and reattach the UI — :restart
Kbuffer-local once a server attaches: vim.lsp.buf.hover(), unless 'keywordprg' or a K mapping is already set
CTRL-] CTRL-W ] CTRL-W }go to definition through the server — 'tagfunc' is set to vim.lsp.tagfunc() on attach
gqformats through the server: 'formatexpr' is set on attach. gw bypasses it
CTRL-X CTRL-OLSP completion: 'omnifunc' is set to vim.lsp.omnifunc() on attach
[[ ]]in a :terminal buffer, jump between shell prompts marked with OSC 133
CTRL-\ CTRL-Nleave Terminal mode for Normal mode
gOoutline: document symbols via LSP; a table of contents in help and man buffers

Commands Vim Does Not Have

19

Ex commands

:che[ckhealth]run healthchecks
:connectconnect the current UI to the Nvim server at the given address
:detachdetach the current UI
:fc[lose]close floating window
:lspmanage LSP clients: :lsp enable|disable|restart|stop [name]
:perlf[ile]execute perl script file
:restartrestart the Nvim server
:rsh[ada]read from shada file
:trustadd or remove file from trust database
:wsh[ada]write to ShaDa file

From the bundled runtime plugins

:Manopen a man page in a buffer; K uses it for man filetypes
:Inspectshow the highlight groups, tree-sitter captures, semantic tokens and extmarks under the cursor
:InspectTreeopen the tree-sitter syntax tree for the buffer in a split; follows the cursor
:EditQuerylive tree-sitter query editor against the current buffer; tab-completes the language
:Openopen a path or URL with the system handler — with no argument, the current file
:DiffToolcompare two directories or files — opt-in: :packadd nvim.difftool
:Undotreenavigate the undo tree visually — opt-in: :packadd nvim.undotree
:TOhtmlrender the window as HTML — opt-in since 0.12: :packadd nvim.tohtml
:UpdateRemotePluginsregenerate the manifest for Python/Node/Ruby remote plugins

Options

39

Nvim only

'busy'Sets a buffer "busy" status.
'channel'channel connected to the buffer, or 0 if no channel is connected.
'inccommand'When nonempty, shows the effects of :substitute, :smagic, :snomagic and user commands with the :command-preview flag as you type.
'mousescroll'amount to scroll by when scrolling with a mouse
'pumblend'Enables pseudo-transparency for the popup-menu.
'pumborder'Defines the default border style of popupmenu windows.
'redrawdebug'Flags to change the way redrawing works, for debugging purposes.
'scrollback'Maximum number of lines kept beyond the visible screen.
'shada'use shada file upon startup and exiting
'shadafile'When non-empty, overrides the file name used for shada (viminfo).
'statuscolumn'custom format for the status column
'termpastefilter'A comma-separated list of options for specifying control characters to be removed from the text pasted into the terminal window.
'termsync'If the host terminal supports it, buffer all screen updates made during a redraw cycle so that each screen is displayed in the terminal all at once.
'winbar'When non-empty, this option enables the window bar and determines its contents.
'winblend'Enables pseudo-transparency for a floating window.
'winborder'Defines the default border style of floating windows.
'winhighlight'window-local highlighting

New or changed in 0.12

'autocomplete'enable automatic completion in insert mode
'autowriteall'as 'autowrite', but works with more commands
'busy'Sets a buffer "busy" status.
'chistory'maximum number of quickfix lists in history
'complete'specify how Insert mode completion works
'completeopt'options for Insert mode completion
'diffanchors'list of {address} to force anchoring of a diff
'diffopt'options for using diff mode
'fillchars'characters to use for displaying special items
'fsync'whether to invoke fsync() after file write
'jumpoptions'specifies how jumping is done
'listchars'characters for displaying in list mode
'maxsearchcount'Maximum number of matches shown for the search count status shm-S When the number of matches exceeds this value, Vim shows ">" instead of the exact count to keep searching fast.
'messagesopt'Option settings for outputting messages.
'pumborder'Defines the default border style of popupmenu windows.
'pummaxwidth'Maximum width for the popup menu (ins-completion-menu).
'rulerformat'custom format for the ruler
'shada'use shada file upon startup and exiting
'statusline'custom format for the status line
'ttyfast'Enables Nvim TUI features which assume a fast (usually local) host terminal.
'wildchar'command-line character for wildcard expansion
'winborder'Defines the default border style of floating windows.

Events Vim Does Not Have

27

Autocommand events

BufModifiedSetAfter the 'modified' value of a buffer has been changed.
ChanInfoState of channel changed, for instance the client of a RPC channel described itself.
ChanOpenJust after a channel was opened.
DiagnosticChangedAfter diagnostics have changed.
LspAttachAfter an LSP client performs "initialize" and attaches to a buffer.
LspDetachJust before an LSP client detaches from a buffer.
LspNotifyThis event is triggered after each successful notification sent to an LSP server.
LspProgressUpon receipt of a progress notification from the server.
LspRequestFor each request sent to an LSP server, this event is triggered for every change to the request's status.
LspTokenUpdateWhen a visible semantic token is sent or updated by the LSP server, or when an existing token becomes visible for the first time.
MarkSetAfter a mark is set by m, :mark, and nvim_buf_set_mark(), or deleted by :delmarks and nvim_buf_del_mark().
PackChangedAfter plugin's state has changed.
PackChangedPreBefore trying to change plugin's state.
ProgressAfter a progress-message is created or updated via nvim_echo.
RecordingEnterWhen a macro starts recording.
RecordingLeaveWhen a macro stops recording.
SearchWrappedAfter making a search with n or N if the search wraps around the document back to the start/finish respectively.
SessionLoadPreBefore loading the session file created using the :mksession command.
SignalAfter Nvim receives a signal.
TabNewEnteredAfter entering a new tabpage.
TermCloseWhen a terminal job ends.
TermEnterAfter entering Terminal-mode.
TermLeaveAfter leaving Terminal-mode.
TermOpenWhen a terminal job is starting.
TermRequestWhen a :terminal child process emits an OSC, DCS, or APC sequence.
UIEnterAfter a UI connects via nvim_ui_attach(), or after builtin TUI is started, after VimEnter.
UILeaveAfter a UI disconnects from Nvim, or after builtin TUI is stopped, after VimLeave.

Vimscript Functions Vim Does Not Have

35

Jobs, channels, RPC, context, msgpack

api_info()Returns Dictionary of api-metadata.
chanclose({id} [, {stream}])Close a channel or a specific stream associated with it.
chansend({id}, {data})Send data to channel {id}.
ctxget([{index}])Returns a Dictionary representing the context at {index} from the top of the context-stack (see context-dict).
ctxpop()Pops and restores the context at the top of the context-stack.
ctxpush([{types}])Pushes the current editor state (context) on the context-stack.
ctxset({context} [, {index}])Sets the context at {index} from the top of the context-stack to that represented by {context}.
ctxsize()Returns the size of the context-stack.
dictwatcheradd({dict}, {pattern}, {callback})Adds a watcher to a dictionary.
dictwatcherdel({dict}, {pattern}, {callback})Removes a watcher added with dictwatcheradd().
jobclose()deprecated — see :h deprecated
jobpid({job})Return the PID (process id) of job-id {job}.
jobresize({job}, {width}, {height})Resize the pseudo terminal window of job-id {job} to {width} columns and {height} rows.
jobsend()deprecated — see :h deprecated
jobstart({cmd} [, {opts}])Spawns {cmd} as a job.
jobstop({id})Stop job-id {id} by sending SIGTERM to the job process.
jobwait({jobs} [, {timeout}])Waits for jobs and their on_exit handlers to complete.
menu_get({path} [, {modes}])Returns a List of Dictionaries describing menus (defined by :menu, :amenu, …), including hidden-menus.
msgpackdump({list} [, {type}])Convert a list of Vimscript objects to msgpack.
msgpackparse({data})Convert a readfile()-style list or a Blob to a list of Vimscript objects.
preinserted()Returns non-zero if text has been inserted after the cursor because "preinsert" is present in 'completeopt', or because "longest" is present in 'completeopt' while 'autocomplete' is active.
prompt_appendbuf({buf}, {text})Appends text to prompt buffer before current prompt.
prompt_getinput({buf})Gets the current user-input in prompt-buffer {buf} without invoking prompt_callback.
reg_recorded()Returns the single letter name of the last recorded register.
rpcnotify({channel}, {event} [, {args}...])Sends {event} to {channel} via RPC and returns immediately.
rpcrequest({channel}, {method} [, {args}...])Sends a request to {channel} to invoke {method} via RPC and blocks until a response is received.
rpcstart()deprecated — see :h deprecated
rpcstop()deprecated — see :h deprecated
serverstart([{address}])Opens a socket or named pipe at {address} and listens for RPC messages.
serverstop({address})Closes the pipe or socket at {address}.
sockconnect({mode}, {address} [, {opts}])Connect a socket to an address.
stdioopen({opts})With --headless this opens stdin and stdout as a channel.
stdpath({what}) *E6100*Returns standard-path locations of various default files and directories.
termopen()deprecated — see :h deprecated
wait({timeout}, {condition} [, {interval}])Waits until {condition} evaluates to TRUE, where {condition} is a Funcref or string containing an expression.

Lua: the vim Module

66

vim.* builtins (C)

vim.empty_dict()Creates a special empty table (marked with a metatable), which Nvim converts to an empty dictionary when translating Lua values to Vimscript or API types.
vim.iconv({str}, {from}, {to})The result is a String, which is the text {str} converted from encoding {from} to encoding {to}.
vim.in_fast_event()Returns true if the code is executing as part of a "fast" event handler, where most of the API is disabled.
vim.rpcnotify({channel}, {method}, {...})Sends {event} to {channel} via RPC and returns immediately.
vim.rpcrequest({channel}, {method}, {...})Invokes RPC method on channel and blocks until a response is received.
vim.schedule({fn})Schedules {fn} to be invoked soon by the main event-loop.
vim.str_utf_end({str}, {index})Gets the distance (in bytes) from the last byte of the codepoint (character) that {index} points to.
vim.str_utf_pos({str})Gets a list of the starting byte positions of each UTF-8 codepoint in the given string.
vim.str_utf_start({str}, {index})Gets the distance (in bytes) from the starting byte of the codepoint (character) that {index} points to.
vim.stricmp({a}, {b})Compares strings case-insensitively.
vim.ui_attach({ns}, {opts}, {callback})WARNING:
vim.ui_detach({ns})Detach a callback previously attached with vim.ui_attach() for the given namespace {ns}.
vim.wait({time}, {callback}, {interval}, {fast_only})Waits up to time milliseconds, until callback returns true (success).

Lua ↔ Vimscript bridge

vim.call({func}, {...})Invokes vim-function or user-function {func} with arguments {...}.
vim.opt:append({value})Append a value to string-style options.
vim.opt:get()Returns a Lua-representation of the option.
vim.opt:prepend({value})Prepend a value to string-style options.
vim.opt:remove({value})Remove a value from string-style options.

vim.* (Lua)

vim.cmd({cmd})Executes Vimscript (Ex-commands).
vim.defer_fn({fn}, {timeout})Defers calling {fn} until {timeout} ms passes.
vim.deprecate({name}, {alternative}, {version}, {plugin}, {backtrace})Shows a deprecation message to the user.
vim.inspect()Gets a human-readable representation of the given object.
vim.keycode({str})Translates keycodes.
vim.lua_omnifunc({find_start})Omnifunc for completing Lua values from the runtime Lua interpreter, similar to the builtin completion for the :lua command.
vim.notify({msg}, {level}, {opts})Displays a notification to the user.
vim.notify_once({msg}, {level}, {opts})Displays a notification only one time.
vim.on_key({fn}, {ns_id}, {opts})Adds Lua function {fn} with namespace id {ns_id} as a listener to every, yes every, input key.
vim.paste({lines}, {phase})Paste handler, invoked by nvim_paste().
vim.print({...})"Pretty prints" the given arguments and returns them unmodified.
vim.schedule_wrap({fn})Returns a function which calls {fn} via vim.schedule().
vim.str_byteindex({s}, {encoding}, {index}, {strict_indexing})Convert UTF-32, UTF-16 or UTF-8 {index} to byte index.
vim.str_utfindex({s}, {encoding}, {index}, {strict_indexing})Convert byte index to UTF-32, UTF-16 or UTF-8 indices.

vim.* tables, lists & strings

Ringbuf:clear()Clear all items
Ringbuf:peek()Returns the first unread item without removing it
Ringbuf:pop()Removes and returns the first unread item
Ringbuf:push({item})Adds an item, overriding the oldest item if the buffer is full.
vim.deep_equal({a}, {b})Deep compare values for equality
vim.deepcopy({orig}, {noref})Returns a deep copy of the given object.
vim.defaulttable({createfn})Creates a table whose missing keys are provided by {createfn} (like Python's "defaultdict").
vim.endswith({s}, {suffix})Tests if s ends with suffix.
vim.gsplit({s}, {sep}, {opts})Gets an iterator that splits a string at each instance of a separator, in "lazy" fashion (as opposed to vim.split() which is "eager").
vim.is_callable({f})Returns true if object f can be called as a function.
vim.isarray({t})Tests if t is an "array":
vim.islist({t})Tests if t is a "list":
vim.list.bisect({t}, {val}, {opts})Search for a position in a sorted lua-list {t} where {val} can be inserted while keeping the list sorted.
vim.list.unique({t}, {key})Removes duplicate values from a lua-list in-place.
vim.list_contains({t}, {value})Checks if a list-like table (integer keys without gaps) contains value.
vim.list_extend({dst}, {src}, {start}, {finish})Extends a list-like table with the values of another list-like table.
vim.list_slice({list}, {start}, {finish})Creates a copy of a table containing only elements from start to end (inclusive)
vim.pesc({s})Escapes magic chars in lua-patterns.
vim.ringbuf({size})Create a ring buffer limited to a maximal number of items.
vim.spairs({t})Enumerates key-value pairs of a table, ordered by key.
vim.split({s}, {sep}, {opts})Splits a string at each instance of a separator and returns the result as a table (unlike vim.gsplit()).
vim.startswith({s}, {prefix})Tests if s starts with prefix.
vim.tbl_contains({t}, {value}, {opts})Checks if a table contains a given value, specified either directly or via a predicate that is checked for each value.
vim.tbl_count({t})Counts the number of non-nil values in table t.
vim.tbl_deep_extend({behavior}, {...})Merges two or more tables recursively.
vim.tbl_extend({behavior}, {...})Merges two or more tables.
vim.tbl_filter({fn}, {t})Filter a table using a predicate function
vim.tbl_get({o}, {...})Gets a (nested) value from table o given by a sequence of keys ..., or nil if not found.
vim.tbl_isempty({t})Checks if a table is empty.
vim.tbl_keys({t})Return a list of all keys used in a table.
vim.tbl_map({fn}, {t})Applies function fn to all values of table t, in pairs() iteration order (which is not guaranteed to be stable, even when the data doesn't change).
vim.tbl_values({t})Return a list of all values used in a table.
vim.trim({s})Trim whitespace (Lua pattern "%s") from both sides of a string.
vim.validate({name}, {value}, {validator}, {optional}, {message})Validate function arguments.

Lua: Editor & System Modules

50

vim.inspector

vim.inspect_pos({buf}, {row}, {col}, {filter})Get all the items at a given buffer position.
vim.show_pos({buf}, {row}, {col}, {filter})Show all the items at a given buffer position.

vim.filetype

vim.filetype.add({filetypes})Add new filetype mappings.
vim.filetype.get_option({filetype}, {option})Get the default option value for a {filetype}.
vim.filetype.inspect()Inspect the current state of the filetype registry.
vim.filetype.match({args})Perform filetype detection.

vim.fs

vim.fs.copy()No such function. Use filecopy() or uv.fs_copyfile() to performantly copy an existing file.
vim.fs.exists()No such function. Use uv.fs_stat() to check a file's type, and whether it exists.
vim.fs.read()No such function. You can use readblob() to get a file's contents without explicitly opening/closing it.
vim.fs.write()No such function. You can use writefile() to write a file without explicitly opening/closing it.
vim.fs.abspath({path})Converts path to an absolute path.
vim.fs.basename({file})Gets the basename of the given path (not expanded/resolved).
vim.fs.dir({path}, {opts})Gets an iterator over items found in path (normalized via vim.fs.normalize()).
vim.fs.dirname({file})Gets the parent directory of the given path (not expanded/resolved, the caller must do that).
vim.fs.ext({file}, {opts})Return the file's last extension, if any.
vim.fs.find({names}, {opts})Find files or directories (or other items as specified by opts.type) in the given path.
vim.fs.joinpath({...})Concatenates partial paths (one absolute or relative path followed by zero or more relative paths).
vim.fs.normalize({path}, {opts})Normalize a path to a standard format.
vim.fs.parents({start})Iterate over all the parents of the given path (not expanded/resolved, the caller must do that).
vim.fs.relpath({base}, {target}, {opts})Gets target path relative to base, or nil if base is not an ancestor.
vim.fs.rm({path}, {opts})Removes a file or directory.
vim.fs.root({source}, {marker})Find the first parent directory containing a specific "marker", relative to a file path or buffer.

vim.hl

vim.hl.on_yank({opts})Highlight the yanked text during a TextYankPost event.
vim.hl.range({buf}, {ns}, {higroup}, {start}, {finish}, {opts})Apply highlight group to range of text.

vim.keymap

vim.keymap.del({modes}, {lhs}, {opts})Remove an existing mapping.
vim.keymap.set({modes}, {lhs}, {rhs}, {opts})Defines a mapping of keycodes to a function or keycodes.

vim.loader

vim.loader.enable({enable})WARNING:
vim.loader.find({modname}, {opts})WARNING:
vim.loader.reset({path})WARNING:

vim.net

vim.net.request({url}, {opts}, {on_response})Makes an HTTP GET request to the given URL, asynchronously passing the result to the specified on_response, outpath or outbuf.

vim.secure

vim.secure.read({path})If {path} is a file:
vim.secure.trust({opts})Manage the trust database.

vim.snippet

vim.snippet.active({filter})Returns true if there's an active snippet in the current buffer, applying the given filter if provided.
vim.snippet.expand({input})Expands the given snippet text.
vim.snippet.jump({direction})Jumps to the next (or previous) placeholder in the current snippet, if possible.
vim.snippet.stop()Exits the current snippet.

vim.spell

vim.spell.check({str})Check {str} for spelling errors.

vim.system

SystemObj:is_closing()Checks if the process handle is closing or already closed.
SystemObj:kill({signal})Sends a signal to the process.
SystemObj:wait({timeout})Waits for the process to complete or until the specified timeout elapses.
SystemObj:write({data})Writes data to the stdin of the process or closes stdin.
vim.system({cmd}, {opts}, {on_exit})Runs a system command or throws an error if {cmd} cannot be run.

vim.ui

vim.ui.input({opts}, {on_confirm})Prompts the user for input, allowing arbitrary (potentially asynchronous) work until on_confirm.
vim.ui.open({path}, {opt})Opens path with the system default handler (macOS open, Windows explorer.exe, Linux xdg-open, …), or returns (but does not show) an error message on failure.
vim.ui.progress_status()Gets a status description summarizing currently running progress messages.
vim.ui.select({items}, {opts}, {on_choice})Prompts the user to pick from a list of items, allowing arbitrary (potentially asynchronous) work until on_choice.

vim.pack — the plugin manager

vim.pack.add({specs}, {opts})Add plugin to current session
vim.pack.del({names}, {opts})Remove plugins from disk
vim.pack.get({names}, {opts})Gets vim.pack plugin info, optionally filtered by names.
vim.pack.update({names}, {opts})Update plugins

Lua: Data & Text Modules

100

vim.iter

vim.iter()Is an interface for iterables:
Iter:all({pred})Returns true if all items in the iterator match the given predicate.
Iter:any({pred})Returns true if any of the items in the iterator match the given predicate.
Iter:each({f})Calls a function once for each item in the pipeline, draining the iterator.
Iter:enumerate()Yields the item index (count) and value for each item of an iterator pipeline.
Iter:filter({f})Filters an iterator pipeline.
Iter:find({f})Find the first value in the iterator that satisfies the given predicate.
Iter:flatten({depth})Flattens a list-iterator, un-nesting nested values up to the given {depth}.
Iter:fold({init}, {f})Folds ("reduces") an iterator into a single value.
Iter:join({delim})Collect the iterator into a delimited string.
Iter:last()Drains the iterator and returns the last item.
Iter:map({f})Maps the items of an iterator pipeline to the values returned by f.
Iter:next()Gets the next value from the iterator.
Iter:nth({n})Gets the nth value of an iterator (and advances to it).
Iter:peek()Gets the next value from the iterator without consuming it.
Iter:pop()"Pops" a value from a list-iterator (gets the last value and decrements the tail).
Iter:rev()Reverses a list-iterator pipeline.
Iter:rfind({f})Gets the first value satisfying a predicate, from the end of a list-iterator.
Iter:rpeek()Gets the last value of a list-iterator without consuming it.
Iter:rskip({n})Discards n values from the end of a list-iterator pipeline.
Iter:skip({n})Skips n values of an iterator pipeline, or skips values while a predicate returns lua-truthy.
Iter:slice({first}, {last})Sets the start and end of a list-iterator pipeline.
Iter:take({n})Transforms an iterator to yield only the first n values, or all values satisfying a predicate.
Iter:totable()Collect the iterator into a table.
Iter:unique({key})Removes duplicate values from an iterator pipeline.

vim.json

vim.json.decode({str}, {opts})Decodes (or "unpacks") stringified JSON to a Lua object.
vim.json.encode({obj}, {opts})Encodes (or "packs") a Lua object to stringified JSON.

vim.text

vim.text.diff({a}, {b}, {opts})Run diff on strings {a} and {b}.
vim.text.hexdecode({enc})Hex decode a string.
vim.text.hexencode({str})Hex encode a string.
vim.text.indent({size}, {text}, {opts})Sets the indent (i.e. the common leading whitespace) of non-empty lines in text to size spaces/tabs.

vim.base64

vim.base64.decode({str})Decode a Base64 encoded string.
vim.base64.encode({str})Encode {str} using Base64.

vim.mpack

vim.mpack.decode({str})Decodes (or "unpacks") the msgpack-encoded {str} to a Lua object.
vim.mpack.encode({obj})Encodes (or "packs") Lua object {obj} as msgpack in a Lua string.

vim.glob

vim.glob.to_lpeg({pattern})Parses a raw glob into an lua-lpeg pattern.

vim.lpeg

Pattern:match({subject}, {init}, {...})Matches the given pattern against the subject string.
vim.lpeg.B({pattern})Returns a pattern that matches only if the input string at the current position is preceded by patt.
vim.lpeg.C({patt})Creates a simple capture, which captures the substring of the subject that matches patt.
vim.lpeg.Carg({n})Creates an argument capture.
vim.lpeg.Cb({name})Creates a back capture.
vim.lpeg.Cc({...})Creates a constant capture.
vim.lpeg.Cf({patt}, {func})Creates a fold capture.
vim.lpeg.Cg({patt}, {name})Creates a group capture.
vim.lpeg.Cmt({patt}, {fn})Creates a match-time capture.
vim.lpeg.Cp()Creates a position capture.
vim.lpeg.Cs({patt})Creates a substitution capture.
vim.lpeg.Ct({patt})Creates a table capture.
vim.lpeg.locale({tab})Returns a table with patterns for matching some character classes according to the current locale.
vim.lpeg.match({pattern}, {subject}, {init}, {...})Matches the given pattern against the subject string.
vim.lpeg.P({value})Converts the given value into a proper pattern.
vim.lpeg.R({...})Returns a pattern that matches any single character belonging to one of the given ranges.
vim.lpeg.S({string})Returns a pattern that matches any single character that appears in the given string (the S stands for Set).
vim.lpeg.setmaxstack({max})Sets a limit for the size of the backtrack stack used by LPeg to track calls and choices.
vim.lpeg.type({value})Returns the string "pattern" if the given value is a pattern, otherwise nil.
vim.lpeg.V({v})Creates a non-terminal (a variable) for a grammar.
vim.lpeg.version()Returns a string with the running version of LPeg.

vim.re

vim.re.compile({string}, {defs})Compiles the given {string} and returns an equivalent LPeg pattern.
vim.re.find({subject}, {pattern}, {init})Searches the given {pattern} in the given {subject}.
vim.re.gsub({subject}, {pattern}, {replacement})Does a global substitution, replacing all occurrences of {pattern} in the given {subject} by {replacement}.
vim.re.match({subject}, {pattern}, {init})Matches the given {pattern} against the given {subject}, returning all captures.
vim.re.updatelocale()Updates the pre-defined character classes to the current locale.

vim.regex

regex:match_line({buf}, {line_idx}, {start}, {end_})Matches line at line_idx (zero-based) in buffer buf.
regex:match_str({str})Matches string str against this regex.
vim.regex({re})Parses the Vim regex re and returns a regex object.

vim.version

vim.version()Returns the version of the current Nvim process.
VersionRange:has({version})Check if a version is in the range (inclusive from, exclusive to).
vim.version.cmp({v1}, {v2})Parses and compares two version objects (the result of vim.version.parse(), or specified literally as a {major, minor, patch} tuple, e.g. {1, 0, 3}).
vim.version.eq({v1}, {v2})Returns true if the given versions are equal.
vim.version.ge({v1}, {v2})Returns true if v1 >= v2.
vim.version.gt({v1}, {v2})Returns true if v1 > v2.
vim.version.intersect({r1}, {r2})Computes the common range shared by the given ranges.
vim.version.last({versions})TODO:
vim.version.le({v1}, {v2})Returns true if v1 <= v2.
vim.version.lt({v1}, {v2})Returns true if v1 < v2.
vim.version.parse({version}, {opts})Parses a semantic version string and returns a version object which can be used with other vim.version functions.
vim.version.range({spec})Parses a semver version-range "spec" and returns vim.VersionRange object:

vim.pos

vim.pos.cursor({buf}, {pos})Creates a new vim.Pos from cursor position (see api-indexing).
vim.pos.extmark({buf}, {row}, {col})Creates a new vim.Pos from extmark position (see api-indexing).
vim.pos.lsp({buf}, {pos}, {position_encoding})Creates a new vim.Pos from lsp.Position.
vim.pos.offset({buf}, {offset})Creates a new vim.Pos from buffer offset.
vim.pos.to_cursor({pos})Converts vim.Pos to cursor position (see api-indexing).
vim.pos.to_extmark({pos})Converts vim.Pos to extmark position (see api-indexing).
vim.pos.to_lsp({pos}, {position_encoding})Converts vim.Pos to lsp.Position.
vim.pos.to_offset({pos})Converts vim.Pos to buffer offset.

vim.range

vim.range.cursor({buf}, {start_pos}, {end_pos})Creates a new vim.Range from mark-like range (see api-indexing).
vim.range.extmark({buf}, {start_row}, {start_col}, {end_row}, {end_col})Creates a new vim.Range from extmark range (see api-indexing).
vim.range.has({outer}, {inner})Checks whether {outer} range contains {inner} range or position.
vim.range.intersect({r1}, {r2})Computes the common range shared by the given ranges.
vim.range.is_empty({range})Checks whether the given range is empty; i.e., start >= end.
vim.range.lsp({buf}, {range}, {position_encoding})Creates a new vim.Range from lsp.Range.
vim.range.to_cursor({range})Converts vim.Range to mark-like range (see api-indexing).
vim.range.to_extmark({range})Converts vim.Range to extmark range (see api-indexing).
vim.range.to_lsp({range}, {position_encoding})Converts vim.Range to lsp.Range.

vim.uri

vim.uri_decode({str})URI-decodes a string containing percent escapes.
vim.uri_encode({str}, {rfc})URI-encodes a string using percent escapes.
vim.uri_from_bufnr({buf})Gets a URI from a bufnr.
vim.uri_from_fname({path})Gets a URI from a file path.
vim.uri_to_bufnr({uri})Gets the buffer for a uri.
vim.uri_to_fname({uri})Gets a filename from a URI.

vim.lsp

112

vim.lsp

vim.lsp.buf_attach_client({bufnr}, {client_id})Implements the textDocument/did… notifications required to track a buffer for any language server.
vim.lsp.buf_detach_client({bufnr}, {client_id})Detaches client from the specified buffer.
vim.lsp.buf_is_attached({bufnr}, {client_id})Checks if a buffer is attached for a particular client.
vim.lsp.buf_notify({bufnr}, {method}, {params})Send a notification to a server
vim.lsp.buf_request_all({bufnr}, {method}, {params}, {handler})Sends an async request for all active clients attached to the buffer and executes the handler callback with the combined result.
vim.lsp.buf_request_sync({bufnr}, {method}, {params}, {timeout_ms})Sends a request to all server and waits for the response of all of them.
vim.lsp.config({name}, {cfg})Sets the default configuration for an LSP client (or all clients if the special name "*" is used).
vim.lsp.enable({name}, {enable})Auto-activates LSP in each buffer based on the lsp-config filetypes, root_markers, and root_dir.
vim.lsp.foldclose({kind}, {winid})Close all {kind} of folds in the the window with {winid}.
vim.lsp.foldexpr({lnum})Provides an interface between the built-in client and a foldexpr function.
vim.lsp.foldtext()Provides a foldtext function that shows the collapsedText retrieved, defaults to the first folded line if collapsedText is not provided.
vim.lsp.formatexpr({opts})Provides an interface between the built-in client and a formatexpr function.
vim.lsp.get_client_by_id({client_id})Gets a client by id, or nil if the id is invalid or the client was stopped.
vim.lsp.get_clients({filter})Gets active clients.
vim.lsp.get_configs({filter})Gets LSP configs.
vim.lsp.is_enabled({name})Checks if the given LSP config is enabled (globally, not per-buffer).
vim.lsp.omnifunc({findstart}, {base})Implements 'omnifunc' compatible LSP completion.
vim.lsp.start({config}, {opts})Create a new LSP client and start a language server or reuses an already running client if one is found matching name and root_dir.
vim.lsp.status()Consumes the latest progress messages from all clients and formats them as a string.
vim.lsp.tagfunc({pattern}, {flags})Provides an interface between the built-in client and 'tagfunc'.

vim.lsp.buf

vim.lsp.buf.add_workspace_folder({workspace_folder})Add the folder at path to the workspace folders.
vim.lsp.buf.clear_references()Removes document highlights from current buffer.
vim.lsp.buf.code_action({opts})Selects a code action (LSP:
vim.lsp.buf.declaration({opts})Jumps to the declaration of the symbol under the cursor.
vim.lsp.buf.definition({opts})Jumps to the definition of the symbol under the cursor.
vim.lsp.buf.document_highlight()Send request to the server to resolve document highlights for the current text document position.
vim.lsp.buf.document_symbol({opts})Lists all symbols in the current buffer in the location-list.
vim.lsp.buf.format({opts})Formats a buffer using the attached (and optionally filtered) language server clients.
vim.lsp.buf.hover({config})Displays hover information about the symbol under the cursor in a floating window.
vim.lsp.buf.implementation({opts})Lists all the implementations for the symbol under the cursor in the quickfix window.
vim.lsp.buf.incoming_calls()Lists all the call sites of the symbol under the cursor in the quickfix window.
vim.lsp.buf.list_workspace_folders()List workspace folders.
vim.lsp.buf.outgoing_calls()Lists all the items that are called by the symbol under the cursor in the quickfix window.
vim.lsp.buf.references({context}, {opts})Lists all the references to the symbol under the cursor in the quickfix window.
vim.lsp.buf.remove_workspace_folder({workspace_folder})Remove the folder at path from the workspace folders.
vim.lsp.buf.rename({new_name}, {opts})Renames all references to the symbol under the cursor.
vim.lsp.buf.selection_range({direction}, {timeout_ms})*lsp-incremental-selection*
vim.lsp.buf.signature_help({config})Displays signature information about the symbol under the cursor in a floating window.
vim.lsp.buf.type_definition({opts})Jumps to the definition of the type of the symbol under the cursor.
vim.lsp.buf.typehierarchy({kind})Lists all the subtypes or supertypes of the symbol under the cursor in the quickfix window.
vim.lsp.buf.workspace_diagnostics({opts})Request workspace-wide diagnostics.
vim.lsp.buf.workspace_symbol({query}, {opts})Lists all symbols in the current workspace in the quickfix window.

vim.lsp.client

Client:cancel_request({id})Cancels a request with a given request id.
Client:exec_cmd({cmd}, {context}, {handler})Execute a lsp command, either via client command function (if available) or via workspace/executeCommand (if supported by the server)
Client:is_stopped()Checks whether a client is stopped.
Client:notify({method}, {params})Sends a notification to an LSP server.
Client:on_attach({bufnr})Runs the on_attach function from the client's config if it was defined.
Client:request({method}, {params}, {handler}, {bufnr})Sends a request to the server.
Client:request_sync({method}, {params}, {timeout_ms}, {bufnr})Sends a request to the server and synchronously waits for the response.
Client:stop({force})Stops a client, optionally with force after a timeout.
Client:supports_method({method}, {bufnr})Checks if a client supports a given method.

vim.lsp.codelens

vim.lsp.codelens.enable({enable}, {filter})Enables or disables code lens for the {filter}ed scope.
vim.lsp.codelens.get({filter})Get all code lenses in the {filter}ed scope.
vim.lsp.codelens.is_enabled({filter})Query whether code lens is enabled in the {filter}ed scope
vim.lsp.codelens.run({opts})Run code lens at the current cursor position.

vim.lsp.completion

vim.lsp.completion.enable({enable}, {client_id}, {bufnr}, {opts})Enables or disables completions from the given language client in the given buffer.
vim.lsp.completion.get({opts})Triggers LSP completion once in the current buffer, if LSP completion is enabled (see lsp-attach lsp-completion).

vim.lsp.diagnostic

vim.lsp.diagnostic.from({diagnostics})Converts the input vim.Diagnostics to LSP diagnostics.
vim.lsp.diagnostic.get_namespace({client_id}, {is_pull}, {pull_id})Get the diagnostic namespace associated with an LSP client vim.diagnostic for diagnostics
vim.lsp.diagnostic.on_diagnostic({error}, {result}, {ctx})lsp-handler for the method "textDocument/diagnostic"
vim.lsp.diagnostic.on_publish_diagnostics({_}, {params}, {ctx})lsp-handler for the method "textDocument/publishDiagnostics"

vim.lsp.document_color

vim.lsp.document_color.color_presentation()Select from a list of presentations for the color under the cursor.
vim.lsp.document_color.enable({enable}, {filter}, {opts})Enables or disables document color highlighting for the {filter}ed scope.
vim.lsp.document_color.is_enabled({filter})Query whether document colors are enabled in the {filter}ed scope.

vim.lsp.inlay_hint

vim.lsp.inlay_hint.enable({enable}, {filter})Enables or disables inlay hints for the {filter}ed scope.
vim.lsp.inlay_hint.get({filter})Get the list of inlay hints, (optionally) restricted by buffer or range.
vim.lsp.inlay_hint.is_enabled({filter})Query whether inlay hint is enabled in the {filter}ed scope

vim.lsp.inline_completion

vim.lsp.inline_completion.enable({enable}, {filter})Enables or disables inline completion for the {filter}ed scope, inline completion will automatically be refreshed when you are in insert mode.
vim.lsp.inline_completion.get({opts})Accept the currently displayed completion candidate to the buffer.
vim.lsp.inline_completion.is_enabled({filter})Query whether inline completion is enabled in the {filter}ed scope
vim.lsp.inline_completion.select({opts})Switch between available inline completion candidates.

vim.lsp.linked_editing_range

vim.lsp.linked_editing_range.enable({enable}, {filter})Enable or disable a linked editing session globally or for a specific client.

vim.lsp.log

vim.lsp.log.get_filename()Returns the log filename.
vim.lsp.log.get_level()Gets the current log level.
vim.lsp.log.set_format_func({handle})Sets the formatting function used to format logs.
vim.lsp.log.set_level({level})Sets the current log level.

vim.lsp.on_type_formatting

vim.lsp.on_type_formatting.enable({enable}, {filter})Enables/disables on-type formatting globally or for the {filter}ed scope.

vim.lsp.rpc

vim.lsp.rpc.connect({host_or_path}, {port})Create a LSP RPC client factory that connects to either:
vim.lsp.rpc.format_rpc_error({err})Constructs an error message from an LSP error object.
vim.lsp.rpc.notify({method}, {params})Sends a notification to the LSP server.
vim.lsp.rpc.request({method}, {params}, {callback}, {notify_reply_callback})Sends a request to the LSP server and runs {callback} upon response.
vim.lsp.rpc.rpc_response_error({code}, {message}, {data})Creates an RPC response table error to be sent to the LSP response.
vim.lsp.rpc.start({cmd}, {dispatchers}, {extra_spawn_params})Starts an LSP server process and create an LSP RPC client object to interact with it.

vim.lsp.semantic_tokens

vim.lsp.semantic_tokens.enable({enable}, {filter})Enables or disables semantic tokens for the {filter}ed scope.
vim.lsp.semantic_tokens.force_refresh({bufnr})Force a refresh of all semantic tokens
vim.lsp.semantic_tokens.get_at_pos({bufnr}, {row}, {col})Return the semantic token(s) at the given position.
vim.lsp.semantic_tokens.highlight_token({token}, {bufnr}, {client_id}, {hl_group}, {opts})Highlight a semantic token.
vim.lsp.semantic_tokens.is_enabled({filter})Query whether semantic tokens is enabled in the {filter}ed scope

vim.lsp.util

vim.lsp.util.apply_text_document_edit({text_document_edit}, {index}, {position_encoding}, {change_annotations})Applies a TextDocumentEdit, which is a list of changes to a single document.
vim.lsp.util.apply_text_edits({text_edits}, {bufnr}, {position_encoding}, {change_annotations})Applies a list of text edits to a buffer.
vim.lsp.util.apply_workspace_edit({workspace_edit}, {position_encoding})Applies a WorkspaceEdit.
vim.lsp.util.buf_clear_references({bufnr})Removes document highlights from a buffer.
vim.lsp.util.buf_highlight_references({bufnr}, {references}, {position_encoding})Shows a list of document highlights for a certain buffer.
vim.lsp.util.character_offset({buf}, {row}, {col}, {offset_encoding})Returns the UTF-32 and UTF-16 offsets for a position in a certain buffer.
vim.lsp.util.convert_input_to_markdown_lines({input}, {contents})Converts any of MarkedString | MarkedString[] | MarkupContent into a list of lines containing valid markdown.
vim.lsp.util.convert_signature_help_to_markdown_lines({signature_help}, {ft}, {triggers})Converts textDocument/signatureHelp response to markdown lines.
vim.lsp.util.get_effective_tabstop({bufnr})Returns indentation size.
vim.lsp.util.locations_to_items({locations}, {position_encoding})Returns the items with the byte position calculated correctly and in sorted order, for display in quickfix and location lists.
vim.lsp.util.make_floating_popup_options({width}, {height}, {opts})Creates a table with sensible default options for a floating window.
vim.lsp.util.make_formatting_params({options})Creates a DocumentFormattingParams object for the current buffer and cursor position.
vim.lsp.util.make_given_range_params({start_pos}, {end_pos}, {bufnr}, {position_encoding})Using the given range in the current buffer, creates an object that is similar to vim.lsp.util.make_range_params().
vim.lsp.util.make_position_params({win}, {position_encoding})Creates a TextDocumentPositionParams object for the current buffer and cursor position.
vim.lsp.util.make_range_params({win}, {position_encoding})Using the current position in the current buffer, creates an object that can be used as a building block for several LSP requests, such as textDocument/codeAction, textDocument/colorPresentation, textDocument/rangeFormatting.
vim.lsp.util.make_text_document_params({bufnr})Creates a TextDocumentIdentifier object for the current buffer.
vim.lsp.util.make_workspace_params({added}, {removed})Create the workspace params
vim.lsp.util.open_floating_preview({contents}, {syntax}, {opts})Shows contents in a floating window.
vim.lsp.util.preview_location({location}, {opts})Previews a location in a floating window
vim.lsp.util.rename({old_fname}, {new_fname}, {opts})Rename old_fname to new_fname
vim.lsp.util.show_document({location}, {position_encoding}, {opts})Shows document and optionally jumps to the location.
vim.lsp.util.symbols_to_items({symbols}, {bufnr}, {position_encoding})Converts symbols to quickfix list items.

vim.lsp.protocol

vim.lsp.protocol.make_client_capabilities()Gets a new ClientCapabilities object describing the LSP client capabilities.
vim.lsp.protocol.resolve_capabilities({server_capabilities})Creates a normalized object describing LSP server capabilities.

vim.diagnostic

21

vim.diagnostic

vim.diagnostic.config({opts}, {namespace})Configure diagnostic options globally or for a specific diagnostic namespace.
vim.diagnostic.count({bufnr}, {opts})Get current diagnostics count.
vim.diagnostic.enable({enable}, {filter})Enables or disables diagnostics.
vim.diagnostic.fromqflist({list}, {opts})Convert a list of quickfix items to a list of diagnostics.
vim.diagnostic.get({bufnr}, {opts})Get current diagnostics.
vim.diagnostic.get_namespace({namespace})Get namespace metadata.
vim.diagnostic.get_namespaces()Get current diagnostic namespaces.
vim.diagnostic.get_next({opts})Get the next diagnostic closest to the cursor position.
vim.diagnostic.get_prev({opts})Get the previous diagnostic closest to the cursor position.
vim.diagnostic.hide({namespace}, {bufnr})Hide currently displayed diagnostics.
vim.diagnostic.is_enabled({filter})Check whether diagnostics are enabled.
vim.diagnostic.jump({opts})Move to a diagnostic.
vim.diagnostic.match({str}, {pat}, {groups}, {severity_map}, {defaults})Parse a diagnostic from a string.
vim.diagnostic.open_float({opts})Show diagnostics in a floating window.
vim.diagnostic.reset({namespace}, {bufnr})Remove all diagnostics from the given namespace.
vim.diagnostic.set({namespace}, {bufnr}, {diagnostics}, {opts})Set diagnostics for the given namespace and buffer.
vim.diagnostic.setloclist({opts})Add buffer diagnostics to the location list.
vim.diagnostic.setqflist({opts})Add all diagnostics to the quickfix list.
vim.diagnostic.show({namespace}, {bufnr}, {diagnostics}, {opts})Display diagnostics for the given namespace and buffer.
vim.diagnostic.status({bufnr})Returns formatted string with diagnostics for the current buffer.
vim.diagnostic.toqflist({diagnostics})Convert a list of diagnostics to a list of quickfix items that can be passed to setqflist() or setloclist().

vim.treesitter

85

TSTree methods

TSTree:copy()Returns a copy of the TSTree.
TSTree:root()Return the root node of this tree.

TSNode methods

TSNode:byte_length()Return the number of bytes spanned by this node.
TSNode:child({index})Get the node's child at the given {index}, where zero represents the first child.
TSNode:child_count()Get the node's number of children.
TSNode:child_with_descendant({descendant})Get the node's child that contains {descendant} (includes {descendant}).
TSNode:descendant_for_range({start_row}, {start_col}, {end_row}, {end_col})Get the smallest node within this node that spans the given range of (row, column) positions
TSNode:end_()Get the node's end position.
TSNode:equal({node})Check if {node} refers to the same node within the same tree.
TSNode:extra()Check if the node is extra.
TSNode:field({name})Returns a list of all the node's children that have the given field name.
TSNode:has_changes()Check if a syntax node has been edited.
TSNode:has_error()Check if the node is a syntax error or contains any syntax errors.
TSNode:id()Get a unique identifier for the node inside its own tree.
TSNode:iter_children()Iterates over all the direct children of {TSNode}, regardless of whether they are named or not.
TSNode:missing()Check if the node is missing.
TSNode:named()Check if the node is named.
TSNode:named_child({index})Get the node's named child at the given {index}, where zero represents the first named child.
TSNode:named_child_count()Get the node's number of named children.
TSNode:named_children()Returns a list of the node's named children.
TSNode:named_descendant_for_range({start_row}, {start_col}, {end_row}, {end_col})Get the smallest named node within this node that spans the given range of (row, column) positions
TSNode:next_named_sibling()Get the node's next named sibling.
TSNode:next_sibling()Get the node's next sibling.
TSNode:parent()Get the node's immediate parent.
TSNode:prev_named_sibling()Get the node's previous named sibling.
TSNode:prev_sibling()Get the node's previous sibling.
TSNode:range({include_bytes})Get the range of the node.
TSNode:sexpr()Get an S-expression representing the node as a string.
TSNode:start()Get the node's start position.
TSNode:symbol()Get the node's type as a numerical id.
TSNode:tree()Get the TSTree of the node.
TSNode:type()Get the node's type as a string.

vim.treesitter

vim.treesitter.foldexpr({lnum})Returns the fold level for {lnum} in the current buffer.
vim.treesitter.get_captures_at_cursor({win})Returns a list of highlight capture names under the cursor
vim.treesitter.get_captures_at_pos({buf}, {row}, {col})Returns a list of highlight captures at the given position
vim.treesitter.get_node({opts})Returns the smallest named node at the given position
vim.treesitter.get_node_range({node_or_range})Returns the node's range or an unpacked range table
vim.treesitter.get_node_text({node}, {source}, {opts})Gets the text corresponding to a given node
vim.treesitter.get_parser({buf}, {lang}, {opts})Returns the parser for a specific buffer and attaches it to the buffer
vim.treesitter.get_range({node}, {source}, {metadata})Get the range of a TSNode.
vim.treesitter.get_string_parser({str}, {lang}, {opts})Returns a string parser
vim.treesitter.inspect_tree({opts})Open a window that displays a textual representation of the nodes in the language tree.
vim.treesitter.is_ancestor({dest}, {source})Determines whether a node is the ancestor of another
vim.treesitter.is_in_node_range({node}, {line}, {col})Determines whether (line, col) position is in node range
vim.treesitter.node_contains({node}, {range})Determines if a node contains a range
vim.treesitter.select({target}, {count})Starts or adjusts a Visual selection at cursor, based on tree nodes.
vim.treesitter.start({buf}, {lang})Starts treesitter highlighting for a buffer
vim.treesitter.stop({buf})Stops treesitter highlighting for a buffer

vim.treesitter.language

vim.treesitter.language.add({lang}, {opts})Load parser with name {lang}
vim.treesitter.language.get_filetypes({lang})Returns the filetypes for which a parser named {lang} is used.
vim.treesitter.language.get_lang({filetype})Returns the language name to be used when loading a parser for {filetype}.
vim.treesitter.language.inspect({lang})Inspects the provided language.
vim.treesitter.language.register({lang}, {filetype})Register a parser named {lang} to be used for {filetype}(s).

vim.treesitter.languagetree

LanguageTree:children()Returns a map of language to child tree.
LanguageTree:contains({range})Determines whether {range} is contained in the LanguageTree.
LanguageTree:destroy()Destroys this LanguageTree and all its children.
LanguageTree:for_each_tree({fn})Invokes the callback for each LanguageTree recursively.
LanguageTree:included_regions()Gets the set of included regions managed by this LanguageTree.
LanguageTree:invalidate({reload})Invalidates this parser and its children.
LanguageTree:is_valid({exclude_children}, {range})Returns whether this LanguageTree is valid, i.e., LanguageTree:trees() reflects the latest state of the source.
LanguageTree:lang()Gets the language of this tree node.
LanguageTree:language_for_range({range})Gets the appropriate language that contains {range}.
LanguageTree:named_node_for_range({range}, {opts})Gets the smallest named node that contains {range}.
LanguageTree:node_for_range({range}, {opts})Gets the smallest node that contains {range}.
LanguageTree:parent()Returns the parent tree.
LanguageTree:parse({range}, {on_parse})Recursively parse all regions in the language tree using treesitter-parsers for the corresponding languages and run injection queries on the parsed trees to determine whether child trees should be created and parsed.
LanguageTree:register_cbs({cbs}, {recursive})Registers callbacks for the LanguageTree.
LanguageTree:source()Returns the source content of the language tree (bufnr or string).
LanguageTree:tree_for_range({range}, {opts})Gets the tree that contains {range}.
LanguageTree:trees()Returns all trees of the regions parsed by this parser.

vim.treesitter.query

vim.treesitter.query.add_directive({name}, {handler}, {opts})Adds a new directive to be used in queries
vim.treesitter.query.add_predicate({name}, {handler}, {opts})Adds a new predicate to be used in queries
vim.treesitter.query.edit({lang})Opens a live editor to query the buffer you started from.
vim.treesitter.query.get({lang}, {query_name})Returns the runtime query {query_name} for {lang}.
vim.treesitter.query.get_files({lang}, {query_name}, {is_included})Gets the list of files used to make up a query
vim.treesitter.query.lint({buf}, {opts})Lint treesitter queries using installed parser, or clear lint errors.
vim.treesitter.query.list_directives()Lists the currently available directives to use in queries.
vim.treesitter.query.list_predicates()Lists the currently available predicates to use in queries.
vim.treesitter.query.omnifunc({findstart}, {base})Omnifunc for completing node names and predicates in treesitter queries.
vim.treesitter.query.parse({lang}, {query})Parses a {query} string and returns a Query object (lua-treesitter-query), which can be used to search the tree for the query patterns (via Query:iter_captures(), Query:iter_matches()), or inspect/modify the query via these fields:
Query:iter_captures({node}, {source}, {start_row}, {end_row}, {opts})Iterates over all captures from all matches in {node}.
Query:iter_matches({node}, {source}, {start}, {stop}, {opts})Iterates the matches of self on a given range.
vim.treesitter.query.set({lang}, {query_name}, {text})Sets the runtime query named {query_name} for {lang}
TSQuery:disable_capture({capture_name})Disable a specific capture in this query; once disabled the capture cannot be re-enabled.
TSQuery:disable_pattern({pattern_index})Disable a specific pattern in this query; once disabled the pattern cannot be re-enabled.

The API: nvim_*

261

Global

nvim_ui_term_event(event, value)—
nvim_get_hl_id_by_name(name)Gets a highlight group by name
nvim_get_hl(ns_id, opts)Gets all or specific highlight groups in a namespace.
nvim_set_hl(ns_id, name, val)Sets a highlight group.
nvim_get_hl_ns(opts)Gets the active highlight namespace.
nvim_set_hl_ns(ns_id)Set active namespace for highlights defined with nvim_set_hl().
nvim_set_hl_ns_fast(ns_id)Set active namespace for highlights defined with nvim_set_hl() while redrawing.
nvim_feedkeys(keys, mode, escape_ks)Sends input-keys to Nvim, subject to various quirks controlled by mode flags.
nvim_input(keys)Queues raw user-input.
nvim_input_mouse(button, action, modifier, grid, row, col)Send mouse event from GUI.
nvim_replace_termcodes(str, from_part, do_lt, special)Replaces terminal codes and keycodes (<CR>, <Esc>, ...) in a string with the internal representation.
nvim_exec_lua(code, args)Executes Lua code.
nvim_strwidth(text)Calculates the number of display cells occupied by text.
nvim_list_runtime_paths()Gets the paths contained in runtime-search-path.
nvim_get_runtime_file(name, all)Finds files in runtime directories, in 'runtimepath' order.
nvim_set_current_dir(dir)Changes the global working directory.
nvim_get_current_line()Gets the current line.
nvim_set_current_line(line)Sets the text on the current line.
nvim_del_current_line()Deletes the current line.
nvim_get_var(name)Gets a global (g:) variable.
nvim_set_var(name, value)Sets a global (g:) variable.
nvim_del_var(name)Removes a global (g:) variable.
nvim_get_vvar(name)Gets a v:
nvim_set_vvar(name, value)Sets a v:
nvim_echo(chunks, history, opts)Prints a message given by a list of [text, hl_group] "chunks".
nvim_list_bufs()Gets the current list of buffers.
nvim_get_current_buf()Gets the current buffer.
nvim_set_current_buf(buf)Sets the current window's buffer to buf.
nvim_list_wins()Gets the current list of all window-IDs in all tabpages.
nvim_get_current_win()Gets the current window.
nvim_set_current_win(win)Navigates to the given window (and tabpage, implicitly).
nvim_create_buf(listed, scratch)Creates a new, empty, unnamed buffer.
nvim_open_term(buf, opts)Open a terminal instance in a buffer
nvim_chan_send(chan, data)Sends raw data to channel chan.
nvim_list_tabpages()Gets the current list of tab-IDs.
nvim_get_current_tabpage()Gets the current tabpage.
nvim_set_current_tabpage(tabpage)Sets the current tabpage.
nvim_paste(data, crlf, phase)Pastes at cursor (in any mode), and sets "redo" so dot (.) will repeat the input.
nvim_put(lines, type, after, follow)Puts text at cursor, in any mode.
nvim_get_color_by_name(name)Returns the 24-bit RGB value of a nvim_get_color_map() color name or "#rrggbb" hexadecimal string.
nvim_get_color_map()Returns a map of color names and RGB values.
nvim_get_context(opts)Gets a map of the current editor state.
nvim_load_context(dict)Sets the current editor state from the given context map.
nvim_get_mode()Gets the current mode.
nvim_get_keymap(mode)Gets a list of global (non-buffer-local) mapping definitions.
nvim_set_keymap(mode, lhs, rhs, opts)Sets a global mapping for the given mode.
nvim_del_keymap(mode, lhs)Unmaps a global mapping for the given mode.
nvim_get_api_info()Returns a 2-tuple (Array), where item 0 is the current channel id and item 1 is the api-metadata map (Dict).
nvim_set_client_info(name, version, type, methods, attributes)Self-identifies the client, and sets optional flags on the channel.
nvim_get_chan_info(chan)Gets information about a channel.
nvim_list_chans()Get information about all open channels.
nvim_list_uis()Gets a list of dictionaries representing attached UIs.
nvim_get_proc_children(pid)Gets the immediate children of process pid.
nvim_get_proc(pid)Gets info describing process pid.
nvim_select_popupmenu_item(item, insert, finish, opts)Selects an item in the completion popup menu.
nvim_del_mark(name)Deletes an uppercase/file named mark.
nvim_get_mark(name, opts)Returns a (row, col, buffer, buffername) tuple representing the position of the uppercase/file named mark.
nvim_eval_statusline(str, opts)Evaluates statusline string.

Buffer

nvim_buf_line_count(buf)Returns the number of lines in the given buffer.
nvim_buf_attach(buf, send_buffer, opts)Activates api-buffer-updates events on a channel, or as Lua callbacks.
nvim_buf_detach(buf)Deactivates buffer-update events on the channel.
nvim_buf_get_lines(buf, start, end, strict_indexing)Gets a line-range from the buffer.
nvim_buf_set_lines(buf, start, end, strict_indexing, replacement)Sets (replaces) a line-range in the buffer.
nvim_buf_set_text(buf, start_row, start_col, end_row, end_col, replacement)Sets (replaces) a range in the buffer
nvim_buf_get_text(buf, start_row, start_col, end_row, end_col, opts)Gets a range from the buffer (may be partial lines, unlike nvim_buf_get_lines()).
nvim_buf_get_offset(buf, index)Returns the byte offset of a line (0-indexed).
nvim_buf_get_var(buf, name)Gets a buffer-scoped (b:) variable.
nvim_buf_get_changedtick(buf)Gets a changed tick of a buffer
nvim_buf_get_keymap(buf, mode)Gets a list of buffer-local mapping definitions.
nvim_buf_set_keymap(buf, mode, lhs, rhs, opts)Sets a buffer-local mapping for the given mode.
nvim_buf_del_keymap(buf, mode, lhs)Unmaps a buffer-local mapping for the given mode.
nvim_buf_set_var(buf, name, value)Sets a buffer-scoped (b:) variable
nvim_buf_del_var(buf, name)Removes a buffer-scoped (b:) variable
nvim_buf_get_name(buf)Gets the full file name for the buffer
nvim_buf_set_name(buf, name)Sets the full file name for a buffer, like :file_f
nvim_buf_is_loaded(buf)Checks if a buffer is valid and loaded.
nvim_buf_delete(buf, opts)Deletes a buffer and its metadata (like :bwipeout).
nvim_buf_is_valid(buf)Checks if a buffer is valid.
nvim_buf_del_mark(buf, name)Deletes a named mark in the buffer.
nvim_buf_set_mark(buf, name, line, col, opts)Sets a named mark in the given buffer, all marks are allowed file/uppercase, visual, last change, etc. See mark-motions.
nvim_buf_get_mark(buf, name)Returns a (row,col) tuple representing the position of the named mark.
nvim_buf_call(buf, fun)Call a function with buffer as temporary current buffer.

Extmark

nvim_create_namespace(name)Creates a new namespace or gets an existing one.
nvim_get_namespaces()Gets existing, non-anonymous namespaces.
nvim_buf_get_extmark_by_id(buf, ns_id, id, opts)Gets the position (0-indexed) of an extmark.
nvim_buf_get_extmarks(buf, ns_id, start, end, opts)Gets extmarks in "traversal order" from a charwise region defined by buffer positions (inclusive, 0-indexed api-indexing).
nvim_buf_set_extmark(buf, ns_id, line, col, opts)Creates or updates an extmark.
nvim_buf_del_extmark(buf, ns_id, id)Removes an extmark.
nvim_buf_clear_namespace(buf, ns_id, line_start, line_end)Clears namespaced objects (highlights, extmarks, virtual text) from a region.
nvim_set_decoration_provider(ns_id, opts)Set or change decoration provider for a namespace

Window

nvim_win_get_buf(win)Gets the current buffer in a window
nvim_win_set_buf(win, buf)Sets the current buffer in a window.
nvim_win_get_cursor(win)Gets the (1,0)-indexed, buffer-relative cursor position for a given window (different windows showing the same buffer have independent cursor positions).
nvim_win_set_cursor(win, pos)Sets the (1,0)-indexed cursor position (byte offset) in the window.
nvim_win_get_height(win)Gets the window height
nvim_win_set_height(win, height)Sets the window height.
nvim_win_get_width(win)Gets the window width
nvim_win_set_width(win, width)Sets the window width.
nvim_win_get_var(win, name)Gets a window-scoped (w:) variable
nvim_win_set_var(win, name, value)Sets a window-scoped (w:) variable
nvim_win_del_var(win, name)Removes a window-scoped (w:) variable
nvim_win_get_position(win)Gets the window position in display cells.
nvim_win_get_tabpage(win)Gets the window tabpage
nvim_win_get_number(win)Gets the window number
nvim_win_is_valid(win)Checks if a window is valid
nvim_win_hide(win)Closes the window and hide the buffer it contains (like :hide with a window-ID).
nvim_win_close(win, force)Closes the window (like :close with a window-ID).
nvim_win_call(win, fun)Calls a function with window as temporary current window.
nvim_win_set_hl_ns(win, ns_id)Set highlight namespace for a window.
nvim_win_text_height(win, opts)Computes the number of screen lines occupied by a range of text in a given window.

Window config

nvim_open_win(buf, enter, config)Opens a new split window, floating window, or external window.
nvim_win_set_config(win, config)Reconfigures the layout and properties of a window.
nvim_win_get_config(win)Gets window configuration in the form of a dict which can be passed as the config parameter of nvim_open_win().

Tabpage

nvim_tabpage_list_wins(tabpage)Gets the windows in a tabpage
nvim_tabpage_get_var(tabpage, name)Gets a tab-scoped (t:) variable
nvim_tabpage_set_var(tabpage, name, value)Sets a tab-scoped (t:) variable
nvim_tabpage_del_var(tabpage, name)Removes a tab-scoped (t:) variable
nvim_tabpage_get_win(tabpage)Gets the current window in a tabpage
nvim_tabpage_set_win(tabpage, win)Sets the current window in a tabpage
nvim_tabpage_get_number(tabpage)Gets the tabpage number
nvim_tabpage_is_valid(tabpage)Checks if a tabpage is valid
nvim_open_tabpage(buf, enter, config)Opens a new tabpage.

Autocmd

nvim_get_autocmds(opts)Gets all autocommands matching ALL criteria in the {opts} query.
nvim_create_autocmd(event, opts)Creates an autocommand event handler, defined by callback (Lua function or Vimscript function name string) or command (Ex command string).
nvim_del_autocmd(id)Deletes an autocommand by id.
nvim_clear_autocmds(opts)Clears all autocommands matching the {opts} query.
nvim_create_augroup(name, opts)Create or get an autocommand group autocmd-groups.
nvim_del_augroup_by_id(id)Delete an autocommand group by id.
nvim_del_augroup_by_name(name)Delete an autocommand group by name.
nvim_exec_autocmds(event, opts)Executes handlers for {event} that match the corresponding {opts} query.

Command

nvim_parse_cmd(str, opts)Parse command line.
nvim_cmd(cmd, opts)Executes an Ex command cmd, specified as a Dict with the same structure as returned by nvim_parse_cmd().
nvim_create_user_command(name, cmd, opts)Creates a global user-commands command.
nvim_del_user_command(name)Delete a user-defined command.
nvim_buf_create_user_command(buf, name, cmd, opts)Creates a buffer-local command user-commands.
nvim_buf_del_user_command(buf, name)Delete a buffer-local user-defined command.
nvim_get_commands(opts)Gets a map of global (non-buffer-local) Ex commands.
nvim_buf_get_commands(buf, opts)Gets a map of buffer-local user-commands.

Options

nvim_get_option_value(name, opts)Gets the value of an option.
nvim_set_option_value(name, value, opts)Sets the value of an option.
nvim_get_all_options_info()Gets the option information for all options.
nvim_get_option_info2(name, opts)Gets the option information for one option from arbitrary buffer or window

Vimscript

nvim_exec2(src, opts)Executes Vimscript (multiline block of Ex commands), like anonymous :source.
nvim_command(cmd)Executes an Ex command.
nvim_eval(expr)Evaluates a Vimscript expression.
nvim_call_function(fn, args)Calls a Vimscript function with the given arguments.
nvim_call_dict_function(dict, fn, args)Calls a Vimscript Dictionary-function with the given arguments.
nvim_parse_expression(expr, flags, hl)Parse a Vimscript expression.

UI

nvim_ui_attach(width, height, options)Activates UI events on the channel.
nvim_ui_set_focus(gained)Tells the nvim server if focus was gained or lost by the GUI
nvim_ui_detach()Deactivates UI events on the channel.
nvim_ui_try_resize(width, height)—
nvim_ui_set_option(name, value)—
nvim_ui_try_resize_grid(grid, width, height)Tell Nvim to resize a grid.
nvim_ui_pum_set_height(height)Tells Nvim the number of elements displaying in the popupmenu, to decide
nvim_ui_pum_set_bounds(width, height, row, col)Tells Nvim the geometry of the popupmenu, to align floating windows with an external popup menu.
nvim_ui_send(content)Sends arbitrary data to a UI.

Deprecated — still callable

nvim_exec(src, output)deprecated at API level 11
nvim_command_output(command)deprecated at API level 7
nvim_execute_lua(code, args)deprecated at API level 7
nvim_buf_get_number(buffer)deprecated at API level 2
nvim_buf_clear_highlight(buffer, ns_id, line_start, line_end)deprecated at API level 7
nvim_buf_add_highlight(buffer, ns_id, hl_group, line, col_start, col_end)deprecated at API level 13
nvim_buf_set_virtual_text(buffer, src_id, line, chunks, opts)deprecated at API level 8
nvim_get_hl_by_id(hl_id, rgb)deprecated at API level 9
nvim_get_hl_by_name(name, rgb)deprecated at API level 9
buffer_insert(buffer, lnum, lines)deprecated at API level 1
buffer_get_line(buffer, index)deprecated at API level 1
buffer_set_line(buffer, index, line)deprecated at API level 1
buffer_del_line(buffer, index)deprecated at API level 1
buffer_get_line_slice(buffer, start, end, include_start, include_end)deprecated at API level 1
buffer_set_line_slice(buffer, start, end, include_start, include_end, replacement)deprecated at API level 1
buffer_set_var(buffer, name, value)deprecated at API level 1
buffer_del_var(buffer, name)deprecated at API level 1
window_set_var(window, name, value)deprecated at API level 1
window_del_var(window, name)deprecated at API level 1
tabpage_set_var(tabpage, name, value)deprecated at API level 1
tabpage_del_var(tabpage, name)deprecated at API level 1
vim_set_var(name, value)deprecated at API level 1
vim_del_var(name)deprecated at API level 1
nvim_get_option_info(name)deprecated at API level 11
nvim_set_option(name, value)deprecated at API level 11
nvim_get_option(name)deprecated at API level 11
nvim_buf_get_option(buffer, name)deprecated at API level 11
nvim_buf_set_option(buffer, name, value)deprecated at API level 11
nvim_win_get_option(window, name)deprecated at API level 11
nvim_win_set_option(window, name, value)deprecated at API level 11
nvim_call_atomic(calls)deprecated at API level 12
nvim_subscribe(event)deprecated at API level 13
nvim_unsubscribe(event)deprecated at API level 13
nvim_out_write(str)deprecated at API level 13
nvim_err_write(str)deprecated at API level 13
nvim_err_writeln(str)deprecated at API level 13
nvim_notify(msg, log_level, opts)deprecated at API level 13
ui_attach(width, height, enable_rgb)deprecated at API level 1
buffer_line_count(buf)deprecated at API level 1
buffer_get_lines(buf, start, end, strict_indexing)deprecated at API level 1
buffer_set_lines(buf, start, end, strict_indexing, replacement)deprecated at API level 1
buffer_get_var(buf, name)deprecated at API level 1
buffer_get_name(buf)deprecated at API level 1
buffer_set_name(buf, name)deprecated at API level 1
buffer_is_valid(buf)deprecated at API level 1
buffer_get_mark(buf, name)deprecated at API level 1
vim_command_output(command)deprecated at API level 1
buffer_get_number(buffer)deprecated at API level 1
buffer_clear_highlight(buffer, ns_id, line_start, line_end)deprecated at API level 1
buffer_add_highlight(buffer, ns_id, hl_group, line, col_start, col_end)deprecated at API level 1
vim_set_option(name, value)deprecated at API level 1
vim_get_option(name)deprecated at API level 1
buffer_get_option(buffer, name)deprecated at API level 1
buffer_set_option(buffer, name, value)deprecated at API level 1
window_get_option(window, name)deprecated at API level 1
window_set_option(window, name, value)deprecated at API level 1
vim_subscribe(event)deprecated at API level 1
vim_unsubscribe(event)deprecated at API level 1
vim_out_write(str)deprecated at API level 1
vim_err_write(str)deprecated at API level 1
vim_report_error(str)deprecated at API level 1
tabpage_get_windows(tabpage)deprecated at API level 1
tabpage_get_var(tabpage, name)deprecated at API level 1
tabpage_get_window(tabpage)deprecated at API level 1
tabpage_is_valid(tabpage)deprecated at API level 1
ui_detach()deprecated at API level 1
ui_try_resize(width, height)deprecated at API level 1
vim_feedkeys(keys, mode, escape_ks)deprecated at API level 1
vim_input(keys)deprecated at API level 1
vim_replace_termcodes(str, from_part, do_lt, special)deprecated at API level 1
vim_strwidth(text)deprecated at API level 1
vim_list_runtime_paths()deprecated at API level 1
vim_change_directory(dir)deprecated at API level 1
vim_get_current_line()deprecated at API level 1
vim_set_current_line(line)deprecated at API level 1
vim_del_current_line()deprecated at API level 1
vim_get_var(name)deprecated at API level 1
vim_get_vvar(name)deprecated at API level 1
vim_get_buffers()deprecated at API level 1
vim_get_current_buffer()deprecated at API level 1
vim_set_current_buffer(buf)deprecated at API level 1
vim_get_windows()deprecated at API level 1
vim_get_current_window()deprecated at API level 1
vim_set_current_window(win)deprecated at API level 1
vim_get_tabpages()deprecated at API level 1
vim_get_current_tabpage()deprecated at API level 1
vim_set_current_tabpage(tabpage)deprecated at API level 1
vim_name_to_color(name)deprecated at API level 1
vim_get_color_map()deprecated at API level 1
vim_get_api_info()deprecated at API level 1
vim_command(cmd)deprecated at API level 1
vim_eval(expr)deprecated at API level 1
vim_call_function(fn, args)deprecated at API level 1
window_get_buffer(win)deprecated at API level 1
window_get_cursor(win)deprecated at API level 1
window_set_cursor(win, pos)deprecated at API level 1
window_get_height(win)deprecated at API level 1
window_set_height(win, height)deprecated at API level 1
window_get_width(win)deprecated at API level 1
window_set_width(win, width)deprecated at API level 1
window_get_var(win, name)deprecated at API level 1
window_get_position(win)deprecated at API level 1
window_get_tabpage(win)deprecated at API level 1
window_is_valid(win)deprecated at API level 1

Deprecations

84

Deprecated in 0.12

nvim_set_decoration_provider on_lineUse on_range instead.
"float"in vim.diagnostic.JumpOpts. Use on_jump instead.
"float"in vim.diagnostic.Opts.Jump. Use on_jump instead.
:ownsyntaxUse 'winhighlight' instead.
vim.lsp.client_is_stopped()Use vim.lsp.get_client_by_id() instead.
vim.lsp.util.stylize_markdown()Use vim.treesitter.start() with vim.wo.conceallevel = 2.
vim.lsp.log.should_log()Use vim.lsp.log.set_format_func() instead and return nil to omit entries from the logfile.
vim.lsp.semantic_tokens.start()Use vim.lsp.semantic_tokens.enable(true) instead
vim.lsp.semantic_tokens.stop()Use vim.lsp.semantic_tokens.enable(false) instead
vim.lsp.set_log_level()Use vim.lsp.log.set_level() instead
vim.lsp.get_log_path()Use vim.lsp.log.get_filename() instead
vim.lsp.get_buffers_by_client_id()Use vim.lsp.get_client_by_id(id).attached_buffers instead
vim.lsp.stop_client()Use Client:stop() instead
vim.lsp.codelens.refresh()Use vim.lsp.codelens.enable(true) instead
vim.lsp.codelens.clear()Use vim.lsp.codelens.enable(false) instead
vim.lsp.codelens.display()deprecated
vim.lsp.codelens.save()deprecated
vim.lsp.codelens.on_codelens()deprecated
vim.diff()Renamed to vim.text.diff()
"buffer"in vim.keymap.set.Opts and vim.keymap.del.Opts Renamed to "buf"
hit-enterWith ui2, the legacy "Press ENTER" *press-enter prompt is never triggered.

Deprecated in 0.11

nvim_notify()Use nvim_echo() or nvim_exec_lua("vim.notify(...)", ...) instead.
nvim_subscribe()Plugins must maintain their own "multicast" channels list.
nvim_unsubscribe()Plugins must maintain their own "multicast" channels list.
nvim_out_write()Use nvim_echo().
nvim_err_write()Use nvim_echo() with {err=true}.
nvim_err_writeln()Use nvim_echo() with {err=true}.
nvim_buf_add_highlight()Use vim.hl.range() or nvim_buf_set_extmark()
vim.diagnostic.goto_next()Use vim.diagnostic.jump() with {count=1, float=true} instead.
vim.diagnostic.goto_prev()Use vim.diagnostic.jump() with {count=-1, float=true} instead.
vim.diagnostic.get_next_pos()Use the "lnum" and "col" fields from the return value of vim.diagnostic.get_next() instead.
vim.diagnostic.get_prev_pos()Use the "lnum" and "col" fields from the return value of vim.diagnostic.get_prev() instead.
The"win_id" parameter used by various functions is deprecated in favor of "winid" winid
vim.diagnostic.JumpOptsrenamed its "cursor_position" field to "pos".
TermCursorNCUnfocused terminal windows do not have a cursor.
vim.lsp.util.jump_to_locationUse vim.lsp.util.show_document() with {focus=true} instead.
vim.lsp.buf.execute_commandUse Client:exec_cmd() instead.
vim.lsp.buf.completionUse vim.lsp.completion.get() instead.
vim.lsp.buf_request_allThe error key has been renamed to err inside the result parameter of the handler.
vim.lsp.with()Pass configuration to equivalent functions in vim.lsp.buf.*.
vim.lsp.handlersDoes not support client-to-server response handlers. Only supports server-to-client requests/notification handlers.
vim.lsp.handlers.signature_help()Use vim.lsp.buf.signature_help() instead.
client.request()Use Client:request() instead.
client.request_sync()Use Client:request_sync() instead.
client.notify()Use Client:notify() instead.
client.cancel_request()Use Client:cancel_request() instead.
client.stop()Use Client:stop() instead.
client.is_stopped()Use Client:is_stopped() instead.
client.supports_method()Use Client:supports_method() instead.
client.on_attach()Use Client:on_attach() instead.
vim.lsp.start_client()Use vim.lsp.start() instead.
vim.region()Use getregionpos() instead.
vim.highlightRenamed to vim.hl.
vim.validate(opts:table) Use form 1. See vim.validate().
termopen()Use jobstart() with {term: v:true}.

Deprecated in 0.10

nvim_buf_get_option()Use nvim_get_option_value() instead.
nvim_buf_set_option()Use nvim_set_option_value() instead.
nvim_call_atomic()Use nvim_exec_lua() instead.
nvim_get_option()Use nvim_get_option_value() instead.
nvim_set_option()Use nvim_set_option_value() instead.
nvim_win_get_option()Use nvim_get_option_value() instead.
nvim_win_set_option()Use nvim_set_option_value() instead.
health#report_errorUse vim.health.error() instead.
health#report_infoUse vim.health.info() instead.
health#report_okUse vim.health.ok() instead.
health#report_startUse vim.health.start() instead.
health#report_warnUse vim.health.warn() instead.
Configuringdiagnostic-signs using :sign-define or sign_define(). Use the "signs" key of vim.diagnostic.config() instead.
vim.lsp.util.get_progress_messages()Use vim.lsp.status() instead.
vim.lsp.get_active_clients()Use vim.lsp.get_clients() instead.
vim.lsp.for_each_buffer_client()Use vim.lsp.get_clients() instead.
vim.lsp.util.trim_empty_lines()Use vim.split() with trimempty instead.
vim.lsp.util.try_trim_markdown_code_blocks()deprecated
vim.lsp.util.set_lines()deprecated
vim.lsp.util.extract_completion_items()deprecated
vim.lsp.util.parse_snippet()deprecated
vim.lsp.util.text_document_completion_list_to_complete_items()deprecated
vim.lsp.util.lookup_section()Use vim.tbl_get() instead: > local keys = vim.split(section, '.', { plain = true }) local vim.tbl_get(table, unpack(keys))
vim.loopUse vim.uv instead.
vim.tbl_add_reverse_lookup()deprecated
vim.tbl_flatten()Use Iter:flatten() instead.
vim.tbl_islist()Use vim.islist() instead.
The"term_background" UI option ui-ext-options is deprecated and no longer populated. Background color detection is now performed in Lua by the Nvim core, not the TUI.
LanguageTree:for_each_child()Use LanguageTree:children() (non-recursive) instead.

What Vim Has and Neovim Does Not

126

Vim9 script — the whole language

:abstractdeclare a Vim9 abstract class
:classstart of a class declaration
:defdefine a Vim9 user function
:defc[ompile]compile Vim9 user functions in current script
:disa[ssemble]disassemble Vim9 user function
:endclassend of a class declaration
:enddefend of a user function started with :def
:endenumend of an enum declaration
:endinterfaceend of an interface declaration
:enumstart of an enum declaration
:exp[ort]Vim9: export an item from a script
:finaldeclare an immutable variable in Vim9
:imp[ort]Vim9: import an item from another script
:interfacestart of an interface declaration
:leg[acy]make following command use legacy script syntax
:publicprefix for a class or object member
:staticprefix for a class member or function
:thisprefix for an object member during initialization (e.g. on |new()|)
:typecreate a type alias
:varvariable declaration in Vim9
:vim9[cmd]make following command use Vim9 script syntax
:vim9s[cript]indicates Vim9 script file

Ex commands

:P[rint]print lines
:Xask for encryption key
:be[have]set mouse and selection behavior
:clip[reset]reset 'clipmethod'
:cs[cope]execute cscope command
:cst[ag]use cscope to jump to a tag
:echoc[onsole]like :echomsg but write to stdout
:echow[indow]same as :echomsg, but use a popup window
:fix[del]set key code of <Del>
:ha[rdcopy]send text to the printer
:helpf[ind]dialog to open a help window
:lcs[cope]like ":cscope" but uses location list
:nbc[lose]close the current Netbeans session
:nb[key]pass a key to Netbeans
:nbs[tart]start a new Netbeans session
:o[pen]start open mode (not implemented)
:pro[mptfind]open GUI dialog for searching
:promptr[epl]open GUI dialog for search/replace
:scs[cope]split window and execute cscope command
:sh[ell]escape to a shell
:smi[le]make the user happy
:te[aroff]tear-off a menu
:wl[restore]restore the Wayland compositor connection
:xr[estore]restores the X server connection

Options

'autoshelldir'change directory to the shell's current directory
'clipmethod'specify order of what clipboard methods to use
'completepopup'options for the Insert mode completion info popup
'cryptmethod'type of encryption to use for file writing
'cscopepathcomp'how many components of the path to show
'cscopeprg'command to execute cscope
'cscopequickfix'use quickfix window for cscope results
'cscoperelative'Use cscope.out path basename as prefix
'cscopetag'use cscope for tag commands
'cscopetagorder'determines ":cstag" search order
'cscopeverbose'give messages when adding a cscope database
'esckeys'recognize function keys in Insert mode
'imactivatefunc'function to enable/disable the X input method
'imstatusfunc'function to obtain X input method status
'key'encryption key
'keyprotocol'what keyboard protocol to use for what terminal
'maxmem'maximum memory (in Kbyte) used for one buffer
'maxmemtot'maximum memory (in Kbyte) used for all buffers
'previewpopup'use popup window for preview
'printdevice'name of the printer to be used for :hardcopy
'printencoding'encoding to be used for printing
'printexpr'expression used to print PostScript for :hardcopy
'printfont'name of the font to be used for :hardcopy
'printheader'format of the header used for :hardcopy
'printmbcharset'CJK character set to be used for :hardcopy
'printmbfont'font names to be used for CJK output of :hardcopy
'printoptions'controls the format of :hardcopy output
'shortname'Filenames assumed to be 8.3 chars
'swapsync'how to sync the swap file
'term'name of the terminal
'termwinkey'key that precedes a Vim command in a terminal
'termwinscroll'max number of scrollback lines in a terminal window
'termwinsize'size of a terminal window
'textauto'obsolete, use 'fileformats'
'textmode'obsolete, use 'fileformat'
'ttybuiltin'use built-in termcap before external termcap
'ttymouse'type of mouse codes generated
'ttyscroll'maximum number of lines for a scroll
'ttytype'alias for 'term'
'viminfo'use .viminfo file upon startup and exiting
'viminfofile'file name used for the viminfo file
'weirdinvert'for terminals that have weird inversion method
'wincolor'window-local highlighting
'xtermcodes'request terminal codes from an xterm

Functions

autocmd_* ×3autocmd_add(), autocmd_delete(), autocmd_get()
ch_* ×18ch_canread(), ch_close(), ch_close_in(), ch_evalexpr(), ch_evalraw(), ch_getbufnr(), ch_getjob(), ch_info(), ch_log(), ch_logfile(), ch_open(), ch_read(), ch_readblob(), ch_readraw(), ch_sendexpr(), ch_sendraw(), ch_setoptions(), ch_status()
job_* ×6job_getchannel(), job_info(), job_setoptions(), job_start(), job_status(), job_stop()
js_* ×2js_decode(), js_encode()
listener_* ×3listener_add(), listener_flush(), listener_remove()
popup_* ×23popup_atcursor(), popup_beval(), popup_clear(), popup_close(), popup_create(), popup_dialog(), popup_filter_menu(), popup_filter_yesno(), popup_findecho(), popup_findinfo(), popup_findpreview(), popup_getoptions(), popup_getpos(), popup_hide(), popup_list(), popup_locate(), popup_menu(), popup_move(), popup_notification(), popup_setbuf(), popup_setoptions(), popup_settext(), popup_show()
prop_* ×11prop_add(), prop_add_list(), prop_clear(), prop_find(), prop_list(), prop_remove(), prop_type_add(), prop_type_change(), prop_type_delete(), prop_type_get(), prop_type_list()
remote_* ×6remote_expr(), remote_foreground(), remote_peek(), remote_read(), remote_send(), remote_startserver()
term_* ×24term_dumpdiff(), term_dumpload(), term_dumpwrite(), term_getaltscreen(), term_getansicolors(), term_getattr(), term_getcursor(), term_getjob(), term_getline(), term_getscrolled(), term_getsize(), term_getstatus(), term_gettitle(), term_gettty(), term_list(), term_scrape(), term_sendkeys(), term_setansicolors(), term_setapi(), term_setkill(), term_setrestore(), term_setsize(), term_start(), term_wait()
test_* ×25test_alloc_fail(), test_autochdir(), test_feedinput(), test_garbagecollect_soon(), test_getvalue(), test_gui_event(), test_ignore_error(), test_mswin_event(), test_null_blob(), test_null_channel(), test_null_dict(), test_null_function(), test_null_job(), test_null_list(), test_null_partial(), test_null_string(), test_null_tuple(), test_option_not_set(), test_override(), test_refcount(), test_setmouse(), test_settime(), test_srand_seed(), test_unknown(), test_void()
base64_decode()Vim 9.1 only
base64_encode()Vim 9.1 only
bindtextdomain()Vim 9.1 only
blob2str()Vim 9.1 only
complete_match()Vim 9.1 only
cscope_connection()Vim 9.1 only
diff()Vim 9.1 only
echoraw()Vim 9.1 only
err_teapot()Vim 9.1 only
exists_compiled()Vim 9.1 only
getcellpixels()Vim 9.1 only
getimstatus()Vim 9.1 only
getmouseshape()Vim 9.1 only
hlget()Vim 9.1 only
hlset()Vim 9.1 only
instanceof()Vim 9.1 only
list2tuple()Vim 9.1 only
ngettext()Vim 9.1 only
readdirex()Vim 9.1 only
server2client()Vim 9.1 only
str2blob()Vim 9.1 only
terminalprops()Vim 9.1 only
tuple2list()Vim 9.1 only
typename()Vim 9.1 only
uri_decode()Vim 9.1 only
uri_encode()Vim 9.1 only