Skip to content

vimrc ​

Settings › Vim › vimrc holds the lines that run every time Vim mode starts in an editor — the same idea as vim's own ~/.vimrc, kept in the app's settings. The pencil beside the card opens it in the editor, which checks every line as you type and underlines what it refuses; Save is available only when nothing is refused, and leaving without saving discards the changes.

This vim is a small, deliberate subset of vim. A vimrc here is a list of what to map, set and name, not a script — four kinds of line, and nothing else. Everything below is what those four kinds can do, then the common vimrc lines that will not work and what happens to each.

Mappings ​

The map family, with the mode each one binds in:

CommandNon-recursive formMode
mapnoremapnormal, visual and operator-pending
nmapnnoremapnormal
vmapvnoremapvisual
imapinoremapinsert
omaponoremapoperator-pending (after d, c, y…)

Short forms work as at the command line: nn is nnoremap, no is noremap. Prefer the noremap forms, as in vim: the right-hand side then means the keys' original bindings, whatever else is mapped.

A mapping fires however its keys arrive: typed, replayed by a macro (@q), run by :normal, or from the right-hand side of a recursive mapping (nmap). A noremap right-hand side and :normal! use no mappings, as in vim — but a macro they replay does, so nnoremap Q @q runs the mappings inside the macro. The app's own keys — gC, gr, cs, cr and the rest of the extras — count as built in, not as mappings, so nnoremap <leader>c gCC works as nnoremap <leader>c gcc does.

A mapping may use its own key: in nmap n nzz or imap ( ()<Left> the key keeps its original meaning inside the mapping. Unlike vim, that holds anywhere in the right-hand side, not only at its start: nmap w ww moves two words.

The left-hand side is a key or a sequence of keys. A sequence whose first key is a vim command of its own — , repeats the last f/t search — waits a second for the next key before doing its own job, as vim does after timeoutlen; Esc cancels a pending sequence unless it continues one (<Esc><Esc> is a mapping of its own).

The right-hand side is one of:

  • keys — nnoremap Y y$, vnoremap < <gv, inoremap jk <Esc>;
  • an ex command — : … <CR>: nnoremap <leader>w :w<CR>, nnoremap <leader>f :find<CR>. Any command the command line accepts, including :action for an app action: nnoremap <leader>p :action workspace.commandPalette<CR>. The Vim mode page lists them. Several commands go between one : and <CR> with <Bar> between them, vim's way: nnoremap <leader>x :w<Bar>action workspace.closeTab<CR> saves, then closes the tab only if the save succeeded. A bare | does the same.

Key notation the mappings understand: letters and symbols as typed; <CR>, <Esc>, <Space>, <Tab>, <BS>, <Del>, <Ins>, <Home>, <End>, <PageUp>, <PageDown>, <Up>, <Down>, <Left>, <Right>; <C-x> for a Ctrl key; <S-Tab>, <S-CR> for Shift with a special key (a shifted letter is just the capital); <leader>; <lt> for a literal <; <Bar> for |. Key names can be written in any case, as in vim: <space>, <c-x> and <cr> are <Space>, <C-x> and <CR>; <Return> and <Enter> are <CR>.

<Nop> unbinds a key: nnoremap Q <Nop> makes Q do nothing in normal mode, inoremap <C-x> <Nop> the same in insert mode. It must be the whole right-hand side. After an operator (onoremap p <Nop>), the key is ignored and the operator stays pending, as in vim: dp deletes nothing, and the next key is still d's motion.

Not available on the left- or right-hand side:

  • <A-x>, <M-x> — Alt and Option are the app's (Alt keys are reserved for the app).
  • <expr> and <script> mappings — there is no expression language to evaluate; the line is refused.
  • <Plug>, <SID>, <Cmd>…<CR> — no plugins, no script functions; a <Cmd> sequence is not recognised.
  • <silent>, <nowait>, <buffer>, <unique>, <special> are accepted and ignored: mappings are silent already, never wait, and there is one buffer.

Settings ​

set with the options this editor has, in vim's spellings:

OptionShortValuesWhat it is here
numbernuset nu, set nonuline numbers
relativenumberrnuset rnu, set nornurelative line numbers
wrapset wrap, set nowrapline wrapping
tabstoptsset ts=4tab width
shiftwidthswset sw=2indent width
expandtabetset et, set noetspaces for tabs
listset list, set nolistshow whitespace

timeoutlen (tm) is how long a mapping of several keys waits for its next key, in milliseconds: set timeoutlen=300, from 100 to 5000, a second when unset. As in vim it covers insert mode too — inoremap jk <Esc> waits that long for the k; unset, insert mode keeps its own quicker wait (200 ms). It is never saved to your settings: the vimrc sets it each time, and a :set timeoutlen=… at the command line lasts until the editor is reloaded, in that editor only — a diff or blame view keeps its own. :set timeoutlen& drops the command line's value, so the vimrc's applies again. While timeoutlen is set it also replaces an insertModeEscKeysTimeout set at the command line; to give insert mode a wait of its own, set that in the vimrc, after timeoutlen.

clipboard (cb): set clipboard=unnamed makes the unnamed register the system clipboard, as in vim — yanks go to it and p pastes from it; see The clipboard. unnamedplus means the same, set clipboard= turns the mirror off, and a desktop vimrc's set clipboard^=unnamed,unnamedplus, += and -= are read as written. Never saved to your settings: without the line, the Mirror unnamed register switch decides.

And the vim engine's own: textwidth (tw, for gq), pcre (search with JavaScript regexps rather than vim's), filetype (ft), langmap (lmap), insertModeEscKeysTimeout. Several options on one line work as on a desktop: set ts=4 sw=4 et. An unknown one is refused by name and the rest still apply. tabstop and shiftwidth are one tab size here, so a line giving them two values (set ts=8 sw=4) keeps the last and says so. The forms are set nu, set nonu, set ts=4, set et!; a query (set list?) has no use at startup, and vim's set invnu, set nu& and set sw:4 are not the engine's — all are refused. setlocal and setglobal mean set here — there is one settings store. Any other option name — hlsearch, ignorecase, smartcase, incsearch, autoindent, smartindent, mouse, scrolloff … — is refused as Unknown option; the app's own settings cover several of these (search is incremental and highlighted already).

A vimrc's settings apply while Vim is active, over your saved settings, and never change them: set relativenumber shows relative numbers only while Vim runs, and Settings › Editor still shows what you chose there. Settings › Vim lists which ones are in force.

The leader ​

let mapleader = "," (or let g:mapleader = "\<Space>") sets what <leader> means in every line after it, as in vim; unset, the leader is a backslash. A space works either way: let mapleader = " " and "\<Space>" both make the leader the Space key. A | cannot be a leader here and is refused. Only let mapleader is supported: any other let is refused.

A mapping typed at the command line can use <leader> too: :nnoremap <leader>d dd takes the leader your vimrc ends on, as it stands when you type it.

Commands of your own ​

command names a line of commands, as in vim:

command! Ship w | action workspace.closeTab
command! Open action project.quickOpen <args>

:Ship then saves and closes the tab, and :Open main.go opens the file picker on main.go. The name starts with a capital letter. The body is any line the command line accepts, | and all; <args> is what follows the name when it is run, and <q-args> the same in double quotes. A command is defined when Vim mode starts and runs only when you type it. Every command its body names must exist, so define a command before another that uses it. delcommand Ship removes one defined above it. Vim's -bar and -nargs=… are accepted and ignored; -range, -complete=… and the other attributes are refused. A script is a command of its own already — :Join runs the script named Join — so a command Join … line is refused as Join is a stored script; a command's body may run one, as in command J Join.

Comments and lines ​

Lines starting with a quote are comments; blank lines are skipped; a line starting with \ continues the line above it. A " inside a mapping is a key, not a comment; only the let line takes a trailing comment. | divides a line as it does at the command line: set nu | set rnu is two settings, each checked on its own. A mapping and a command keep their bars.

What will not work ​

Every line not covered above is refused, with its reason under the editor's error count. The ones people bring from a real vimrc:

LineWhat happens
syntax on, filetype plugin indent on, set nocompatibleNot an editor command / Unknown option — the editor highlights, indents and behaves without them
colorscheme …refused: the theme is a setting (Settings › Editor)
autocmd …, augroup …Not an editor command — no events to hook
function, if, for, call, execute, sourceNot an editor command — a vimrc here is not a script
Plug '…', call plug#begin(), Plugin '…'Not an editor command — no plugins
normal …, %s/…/…/, g/…/d, sortnot allowed at startup; put it in a mapping — nothing to act on yet
unmap, nunmap…refused — a line you don't want is a line you delete
mapclearrefused — it would clear the app's own mappings
let g:anything = …refused — only let mapleader
set hlsearch, set ignorecase, …Unknown option — see the table above
nnoremap <A-j> …Alt keys are reserved for the app
nnoremap <expr> …refused — no expressions
nnoremap x dd<Nop>refused — <Nop> must be the whole right-hand side

A refused line costs only itself: the rest of the file still runs.

Importing a vimrc ​

The editor's toolbar has Import beside Share: pick a file — your desktop ~/.vimrc from Files or iCloud — and its text replaces what is in the editor, nothing saved yet. Every line this app refuses is commented out, with a note above it saying why, so the file lands valid and keeps all your lines; a refused line that opens a block (if … endif, function … endfunction, augroup … augroup END, and try, for and while with their enders) takes the whole block, with one note. A summary says how many lines were commented out and in how many places, and how many still need your attention if any remain; the Problems count lists those. Read the notes, uncomment what you want back, and Save. Windows line endings are converted; a file over 256 KB, or not UTF-8 text, is refused.

The example ​

A vimrc is never empty: until you change it, it is a template that documents itself; clearing it, or the toolbar's ↻ button (Reset to the example), brings the template back. It holds every feature above, each followed by examples that are commented out — a leader, jj to leave insert mode, <leader>w to save, Y, screen-line j/k, >gv, a mapping to :action, the settings. Delete the leading quote of an example to turn it on, and change it to taste; as written, the template runs nothing.

Last updated: