codekingpro/portable-devtools
114k
1*map.txt* For Vim version 9.2. Last change: 2026 Feb 142 3 4 VIM REFERENCE MANUAL by Bram Moolenaar5 6 7Key mapping, abbreviations and user-defined commands.8 9This subject is introduced in sections |05.4|, |24.7| and |40.1| of the user10manual.11 121. Key mapping |key-mapping|13 1.1 MAP COMMANDS |:map-commands|14 1.2 Special arguments |:map-arguments|15 1.3 Mapping and modes |:map-modes|16 1.4 Listing mappings |map-listing|17 1.5 Mapping special keys |:map-special-keys|18 1.6 Special characters |:map-special-chars|19 1.7 What keys to map |map-which-keys|20 1.8 Examples |map-examples|21 1.9 Using mappings |map-typing|22 1.10 Mapping alt-keys |:map-alt-keys|23 1.11 Mapping meta-keys |:map-meta-keys|24 1.12 Mapping super-keys or command keys |:map-super-keys|25 1.13 Mapping in modifyOtherKeys mode |modifyOtherKeys|26 1.14 Mapping with Kitty keyboard protocol |kitty-keyboard-protocol|27 1.15 Mapping an operator |:map-operator|282. Abbreviations |abbreviations|293. Local mappings and functions |script-local|304. User-defined commands |user-commands|31 32==============================================================================331. Key mapping *key-mapping* *mapping* *macro*34 35Key mapping is used to change the meaning of typed keys. The most common use36is to define a sequence of commands for a function key. Example: >37 38 :map <F2> a<C-R>=strftime("%c")<CR><Esc>39 40This appends the current date and time after the cursor (in <> notation |<>|).41 42 431.1 MAP COMMANDS *:map-commands*44 45There are commands to enter new mappings, remove mappings and list mappings.46See |map-overview| for the various forms of "map" and their relationships with47modes.48 49{lhs} means left-hand-side *{lhs}*50{rhs} means right-hand-side *{rhs}*51 52:map {lhs} {rhs} |mapmode-nvo| *:map*53:nm[ap] {lhs} {rhs} |mapmode-n| *:nm* *:nmap*54:vm[ap] {lhs} {rhs} |mapmode-v| *:vm* *:vmap*55:xm[ap] {lhs} {rhs} |mapmode-x| *:xm* *:xmap*56:smap {lhs} {rhs} |mapmode-s| *:smap*57:om[ap] {lhs} {rhs} |mapmode-o| *:om* *:omap*58:map! {lhs} {rhs} |mapmode-ic| *:map!*59:im[ap] {lhs} {rhs} |mapmode-i| *:im* *:imap*60:lm[ap] {lhs} {rhs} |mapmode-l| *:lm* *:lma* *:lmap*61:cm[ap] {lhs} {rhs} |mapmode-c| *:cm* *:cmap*62:tma[p] {lhs} {rhs} |mapmode-t| *:tma* *:tmap*63 Map the key sequence {lhs} to {rhs} for the modes64 where the map command applies. The result, including65 {rhs}, is then further scanned for mappings. This66 allows for nested and recursive use of mappings.67 Note: Trailing spaces are included in the {rhs},68 because space is a valid Normal mode command.69 See |map-trailing-white|.70 71 *:nore* *:norem*72:no[remap] {lhs} {rhs} |mapmode-nvo| *:no* *:noremap* *:nor*73:nn[oremap] {lhs} {rhs} |mapmode-n| *:nn* *:nnoremap*74:vn[oremap] {lhs} {rhs} |mapmode-v| *:vn* *:vnoremap*75:xn[oremap] {lhs} {rhs} |mapmode-x| *:xn* *:xnoremap*76:snor[emap] {lhs} {rhs} |mapmode-s| *:snor* *:snore* *:snoremap*77:ono[remap] {lhs} {rhs} |mapmode-o| *:ono* *:onoremap*78:no[remap]! {lhs} {rhs} |mapmode-ic| *:no!* *:noremap!*79:ino[remap] {lhs} {rhs} |mapmode-i| *:ino* *:inor* *:inoremap*80:ln[oremap] {lhs} {rhs} |mapmode-l| *:ln* *:lnoremap*81:cno[remap] {lhs} {rhs} |mapmode-c| *:cno* *:cnor* *:cnoremap*82:tno[remap] {lhs} {rhs} |mapmode-t| *:tno* *:tnoremap*83 Map the key sequence {lhs} to {rhs} for the modes84 where the map command applies. Disallow mapping of85 {rhs}, to avoid nested and recursive mappings. Often86 used to redefine a command.87 Note: Keys in {rhs} also won't trigger abbreviation,88 with the exception of |i_CTRL-]| and |c_CTRL-]|.89 Note: When <Plug> appears in the {rhs} this part is90 always applied even if remapping is disallowed.91 92 93:unm[ap] {lhs} |mapmode-nvo| *:unm* *:unmap*94:nun[map] {lhs} |mapmode-n| *:nun* *:nunmap*95:vu[nmap] {lhs} |mapmode-v| *:vu* *:vunmap*96:xu[nmap] {lhs} |mapmode-x| *:xu* *:xunmap*97:sunm[ap] {lhs} |mapmode-s| *:sunm* *:sunmap*98:ou[nmap] {lhs} |mapmode-o| *:ou* *:ounmap*99:unm[ap]! {lhs} |mapmode-ic| *:unm!* *:unmap!*100:iu[nmap] {lhs} |mapmode-i| *:iu* *:iunmap*101:lu[nmap] {lhs} |mapmode-l| *:lu* *:lunmap*102:cu[nmap] {lhs} |mapmode-c| *:cu* *:cun* *:cunmap*103:tunma[p] {lhs} |mapmode-t| *:tunma* *:tunmap*104 Remove the mapping of {lhs} for the modes where the105 map command applies. The mapping may remain defined106 for other modes where it applies.107 It also works when {lhs} matches the {rhs} of a108 mapping. This is for when an abbreviation applied.109 Note: Trailing spaces are included in the {lhs}.110 See |map-trailing-white|.111 112:mapc[lear] |mapmode-nvo| *:mapc* *:mapclear*113:nmapc[lear] |mapmode-n| *:nmapc* *:nmapclear*114:vmapc[lear] |mapmode-v| *:vmapc* *:vmapclear*115:xmapc[lear] |mapmode-x| *:xmapc* *:xmapclear*116:smapc[lear] |mapmode-s| *:smapc* *:smapclear*117:omapc[lear] |mapmode-o| *:omapc* *:omapclear*118:mapc[lear]! |mapmode-ic| *:mapc!* *:mapclear!*119:imapc[lear] |mapmode-i| *:imapc* *:imapclear*120:lmapc[lear] |mapmode-l| *:lmapc* *:lmapclear*121:cmapc[lear] |mapmode-c| *:cmapc* *:cmapclear*122:tmapc[lear] |mapmode-t| *:tmapc* *:tmapclear*123 Remove ALL mappings for the modes where the map124 command applies.125 Use the <buffer> argument to remove buffer-local126 mappings |:map-<buffer>|127 Warning: This also removes the |mac-standard-mappings|128 and the |dos-standard-mappings|.129 130:map |mapmode-nvo|131:nm[ap] |mapmode-n|132:vm[ap] |mapmode-v|133:xm[ap] |mapmode-x|134:sm[ap] |mapmode-s|135:om[ap] |mapmode-o|136:map! |mapmode-ic|137:im[ap] |mapmode-i|138:lm[ap] |mapmode-l|139:cm[ap] |mapmode-c|140:tma[p] |mapmode-t|141 List all key mappings for the modes where the map142 command applies. Note that ":map" and ":map!" are143 used most often, because they include the other modes.144 145:map {lhs} |mapmode-nvo| *:map_l*146:nm[ap] {lhs} |mapmode-n| *:nmap_l*147:vm[ap] {lhs} |mapmode-v| *:vmap_l*148:xm[ap] {lhs} |mapmode-x| *:xmap_l*149:sm[ap] {lhs} |mapmode-s| *:smap_l*150:om[ap] {lhs} |mapmode-o| *:omap_l*151:map! {lhs} |mapmode-ic| *:map_l!*152:im[ap] {lhs} |mapmode-i| *:imap_l*153:lm[ap] {lhs} |mapmode-l| *:lmap_l*154:cm[ap] {lhs} |mapmode-c| *:cmap_l*155:tma[p] {lhs} |mapmode-t| *:tmap_l*156 List the key mappings for the key sequences starting157 with {lhs} in the modes where the map command applies.158 159These commands are used to map a key or key sequence to a string of160characters. You can use this to put command sequences under function keys,161translate one key into another, etc. See |:mkexrc| for how to save and162restore the current mappings.163 164 *map-ambiguous*165When two mappings start with the same sequence of characters, they are166ambiguous. Example: >167 :imap aa foo168 :imap aaa bar169When Vim has read "aa", it will need to get another character to be able to170decide if "aa" or "aaa" should be mapped. This means that after typing "aa"171that mapping won't get expanded yet, Vim is waiting for another character.172If you type a space, then "foo" will get inserted, plus the space. If you173type "a", then "bar" will get inserted.174 175Trailing white space ~176 *map-trailing-white*177This unmap command does NOT work: >178 :map @@ foo179 :unmap @@ | print180 181Because it tries to unmap "@@ ", including the white space before the command182separator "|". Other examples with trailing white space: >183 unmap @@ 184 unmap @@ # Vim9 script comment185 unmap @@ " legacy script comment186 187An error will be issued, which is very hard to identify, because the ending188whitespace character in `unmap @@ ` is not visible.189 190A generic solution is to put the command separator "|" right after the mapped191keys. After that white space and a comment may follow: >192 193 unmap @@| # Vim9 script comment194 unmap @@| " legacy script comment195 196 1971.2 SPECIAL ARGUMENTS *:map-arguments*198 199"<buffer>", "<nowait>", "<silent>", "<special>", "<script>", "<expr>" and200"<unique>" can be used in any order. They must appear right after the201command, before any other arguments.202 203 *:map-local* *:map-<buffer>* *:map-buffer*204 *E224* *E225*205If the first argument to one of these commands is "<buffer>" the mapping will206be effective in the current buffer only. Example: >207 :map <buffer> ,w /[.,;]<CR>208Then you can map ",w" to something else in another buffer: >209 :map <buffer> ,w /[#&!]<CR>210The local buffer mappings are used before the global ones. See <nowait> below211to make a short local mapping not taking effect when a longer global one212exists.213The "<buffer>" argument can also be used to clear mappings: >214 :unmap <buffer> ,w215 :mapclear <buffer>216Local mappings are also cleared when a buffer is deleted, but not when it is217unloaded. Just like local option values.218Also see |map-precedence|.219 220 *:map-<nowait>* *:map-nowait*221When defining a buffer-local mapping for "," there may be a global mapping222that starts with ",". Then you need to type another character for Vim to know223whether to use the "," mapping or the longer one. To avoid this add the224<nowait> argument. Then the mapping will be used when it matches, Vim does225not wait for more characters to be typed. However, if the characters were226already typed they are used.227Note that this works when the <nowait> mapping fully matches and is found228before any partial matches. This works when:229- There is only one matching buffer-local mapping, since these are always230 found before global mappings.231- There is another buffer-local mapping that partly matches, but it is232 defined earlier (last defined mapping is found first).233 234 *:map-<silent>* *:map-silent*235To define a mapping which will not be echoed on the command line, add236"<silent>" as the first argument. Example: >237 :map <silent> ,h /Header<CR>238The search string will not be echoed when using this mapping. Messages from239the executed command are still given though. To shut them up too, add a240":silent" in the executed command: >241 :map <silent> ,h :exe ":silent normal /Header\r"<CR>242Note that the effect of a command might also be silenced, e.g., when the243mapping selects another entry for command line completion it won't be244displayed.245Prompts will still be given, e.g., for inputdialog().246Using "<silent>" for an abbreviation is possible, but will cause redrawing of247the command line to fail.248 249 *:map-<special>* *:map-special*250Define a mapping with <> notation for special keys, even though the "<" flag251may appear in 'cpoptions'. This is useful if the side effect of setting252'cpoptions' is not desired. Example: >253 :map <special> <F12> /Header<CR>254<255 *:map-<script>* *:map-script*256If the first argument to one of these commands is "<script>" and it is used to257define a new mapping or abbreviation, the mapping will only remap characters258in the {rhs} using mappings that were defined local to a script, starting with259"<SID>". This can be used to avoid that mappings from outside a script260interfere (e.g., when CTRL-V is remapped in mswin.vim), but do use other261mappings defined in the script.262Note: ":map <script>" and ":noremap <script>" do the same thing. The263"<script>" overrules the command name. Using ":noremap <script>" is264preferred, because it's clearer that remapping is (mostly) disabled.265 266 *:map-<unique>* *:map-unique* *E226* *E227*267If the first argument to one of these commands is "<unique>" and it is used to268define a new mapping or abbreviation, the command will fail if the mapping or269abbreviation already exists. Example: >270 :map <unique> ,w /[#&!]<CR>271When defining a local mapping, there will also be a check if a global map272already exists which is equal.273Example of what will fail: >274 :map ,w /[#&!]<CR>275 :map <buffer> <unique> ,w /[.,;]<CR>276If you want to map a key and then have it do what it was originally mapped to,277have a look at |maparg()|.278 279 *:map-<expr>* *:map-expression*280If the first argument to one of these commands is "<expr>" and it is used to281define a new mapping or abbreviation, the argument is an expression. The282expression is evaluated to obtain the {rhs} that is used. Example: >283 :inoremap <expr> . <SID>InsertDot()284The result of the s:InsertDot() function will be inserted. It could check the285text before the cursor and start omni completion when some condition is met.286Using a script-local function is preferred, to avoid polluting the global287namespace. Use <SID> in the RHS so that the script that the mapping was288defined in can be found.289 290For abbreviations |v:char| is set to the character that was typed to trigger291the abbreviation. You can use this to decide how to expand the {lhs}. You292should not either insert or change the v:char.293 294In case you want the mapping to not do anything, you can have the expression295evaluate to an empty string. If something changed that requires Vim to296go through the main loop (e.g. to update the display), return "\<Ignore>".297This is similar to "nothing" but makes Vim return from the loop that waits for298input. Example: >299 func s:OpenPopup()300 call popup_create(... arguments ...)301 return "\<Ignore>"302 endfunc303 nnoremap <expr> <F3> <SID>OpenPopup()304 305Keep in mind that the expression may be evaluated when looking for306typeahead, before the previous command has been executed. For example: >307 func StoreColumn()308 let g:column = col('.')309 return 'x'310 endfunc311 nnoremap <expr> x StoreColumn()312 nmap ! f!x313You will notice that g:column has the value from before executing "f!",314because "x" is evaluated before "f!" is executed.315This can be solved by inserting <Ignore> before the character that is316expression-mapped: >317 nmap ! f!<Ignore>x318 319When defining a mapping in a |Vim9| script, the expression will be evaluated320in the context of that script. This means that script-local items can be321accessed in the expression.322 323Be very careful about side effects! The expression is evaluated while324obtaining characters, you may very well make the command dysfunctional.325For this reason the following is blocked:326- Changing the buffer text |textlock|.327- Editing another buffer.328- The |:normal| command.329- Moving the cursor is allowed, but it is restored afterwards.330If you want the mapping to do any of these let the returned characters do331that, or use a |<Cmd>| mapping instead.332 333You can use getchar(), it consumes typeahead if there is any. E.g., if you334have these mappings: >335 inoremap <expr> <C-L> nr2char(getchar())336 inoremap <expr> <C-L>x "foo"337If you now type CTRL-L nothing happens yet, Vim needs the next character to338decide what mapping to use. If you type 'x' the second mapping is used and339"foo" is inserted. If you type any other key the first mapping is used,340getchar() gets the typed key and returns it.341 342Here is an example that inserts a list number that increases: >343 let counter = 0344 inoremap <expr> <C-L> ListItem()345 inoremap <expr> <C-R> ListReset()346 347 func ListItem()348 let g:counter += 1349 return g:counter .. '. '350 endfunc351 352 func ListReset()353 let g:counter = 0354 return ''355 endfunc356 357CTRL-L inserts the next number, CTRL-R resets the count. CTRL-R returns an358empty string, so that nothing is inserted.359 360Note that using 0x80 as a single byte before other text does not work, it will361be seen as a special key.362 363 *<Cmd>* *:map-cmd*364The special text <Cmd> begins a "command mapping", it executes the command365directly without changing modes. Where you might use ":...<CR>" in the366{rhs} of a mapping, you can instead use "<Cmd>...<CR>".367Example: >368 noremap x <Cmd>echo mode(1)<CR>369<370This is more flexible than `:<C-U>` in Visual and Operator-pending mode, or371`<C-O>:` in Insert mode, because the commands are executed directly in the372current mode, instead of always going to Normal mode. Visual mode is373preserved, so tricks with |gv| are not needed. Commands can be invoked374directly in Command-line mode (which would otherwise require timer hacks).375Example of using <Cmd> halfway Insert mode: >376 nnoremap <F3> aText <Cmd>echo mode(1)<CR> Added<Esc>377 378Unlike <expr> mappings, there are no special restrictions on the <Cmd>379command: it is executed as if an (unrestricted) |autocommand| was invoked.380 381 *<ScriptCmd>*382<ScriptCmd> is like <Cmd> but sets the context to the script the mapping was383defined in, for the duration of the command execution. This is especially384useful for |Vim9| script. It also works to access an import, which is useful385in a plugin using a, possibly autoloaded, script: >386 vim9script387 import autoload 'implementation.vim' as impl388 nnoremap <F4> <ScriptCmd>impl.DoTheWork()<CR>389<390No matter where <F4> is typed, the "impl" import will be found in the script391context of where the mapping was defined. When it's an autoload import, as in392the example, the "implementation.vim" script will only be loaded once <F4> is393typed, not when the mapping is defined.394 395Without <ScriptCmd> using "s:impl" would result in "E121: Undefined variable".396 397Note:398- Because <Cmd> and <ScriptCmd> avoid mode-changes it does not trigger399 |CmdlineEnter| and |CmdlineLeave| events, because no user interaction is400 expected.401- For the same reason, |keycodes| like <C-R><C-W> are interpreted as plain,402 unmapped keys.403- The command is not echo'ed, no need for <silent>.404- The {rhs} is not subject to abbreviations nor to other mappings, even if the405 mapping is recursive.406- In Visual mode you can use `line('v')` and `col('v')` to get one end of the407 Visual area, the cursor is at the other end.408 409 *E1255* *E1136*410<Cmd> and <ScriptCmd> commands must terminate, that is, they must be followed411by <CR> in the {rhs} of the mapping definition. |Command-line| mode is never412entered. To use a literal <CR> in the {rhs}, use |<lt>|.413 414 4151.3 MAPPING AND MODES *:map-modes*416 *mapmode-nvo* *mapmode-n* *mapmode-v* *mapmode-o*417 418There are seven sets of mappings419- For Normal mode: When typing commands.420- For Visual mode: When typing commands while the Visual area is highlighted.421- For Select mode: like Visual mode but typing text replaces the selection.422- For Operator-pending mode: When an operator is pending (after "d", "y", "c",423 etc.). See below: |omap-info|.424- For Insert mode. These are also used in Replace mode.425- For Command-line mode: When entering a ":" or "/" command.426- For Terminal mode: When typing in a |:terminal| buffer.427 428Special case: While typing a count for a command in Normal mode, mapping zero429is disabled. This makes it possible to map zero without making it impossible430to type a count with a zero.431 432 *map-overview* *map-modes*433Overview of which map command works in which mode. More details below.434 COMMANDS MODES ~435:map :noremap :unmap Normal, Visual, Select, Operator-pending436:nmap :nnoremap :nunmap Normal437:vmap :vnoremap :vunmap Visual and Select438:smap :snoremap :sunmap Select439:xmap :xnoremap :xunmap Visual440:omap :onoremap :ounmap Operator-pending441:map! :noremap! :unmap! Insert and Command-line442:imap :inoremap :iunmap Insert443:lmap :lnoremap :lunmap Insert, Command-line, Lang-Arg444:cmap :cnoremap :cunmap Command-line445:tmap :tnoremap :tunmap Terminal-Job446 447Same information in a table:448 *map-table*449 Mode | Norm | Ins | Cmd | Vis | Sel | Opr | Term | Lang | ~450Command +------+-----+-----+-----+-----+-----+------+------+ ~451[nore]map | yes | - | - | yes | yes | yes | - | - |452n[nore]map | yes | - | - | - | - | - | - | - |453[nore]map! | - | yes | yes | - | - | - | - | - |454i[nore]map | - | yes | - | - | - | - | - | - |455c[nore]map | - | - | yes | - | - | - | - | - |456v[nore]map | - | - | - | yes | yes | - | - | - |457x[nore]map | - | - | - | yes | - | - | - | - |458s[nore]map | - | - | - | - | yes | - | - | - |459o[nore]map | - | - | - | - | - | yes | - | - |460t[nore]map | - | - | - | - | - | - | yes | - |461l[nore]map | - | yes | yes | - | - | - | - | yes |462 463 464 COMMANDS MODES ~465 Normal Visual+Select Operator-pending ~466:map :noremap :unmap :mapclear yes yes yes467:nmap :nnoremap :nunmap :nmapclear yes - -468:vmap :vnoremap :vunmap :vmapclear - yes -469:omap :onoremap :ounmap :omapclear - - yes470 471:nunmap can also be used outside of a monastery.472 *mapmode-x* *mapmode-s*473Some commands work both in Visual and Select mode, some in only one. Note474that quite often "Visual" is mentioned where both Visual and Select mode475apply. |Select-mode-mapping|476NOTE: Mapping a printable character in Select mode may confuse the user. It's477better to explicitly use :xmap and :smap for printable characters. Or use478:sunmap after defining the mapping.479 480 COMMANDS MODES ~481 Visual Select ~482:vmap :vnoremap :vunmap :vmapclear yes yes483:xmap :xnoremap :xunmap :xmapclear yes -484:smap :snoremap :sunmap :smapclear - yes485 486 *mapmode-ic* *mapmode-i* *mapmode-c* *mapmode-l*487Some commands work both in Insert mode and Command-line mode, some not:488 489 COMMANDS MODES ~490 Insert Command-line Lang-Arg ~491:map! :noremap! :unmap! :mapclear! yes yes -492:imap :inoremap :iunmap :imapclear yes - -493:cmap :cnoremap :cunmap :cmapclear - yes -494:lmap :lnoremap :lunmap :lmapclear yes* yes* yes*495 496* If 'iminsert' is 1, see |language-mapping| below.497 498The original Vi did not have separate mappings for499Normal/Visual/Operator-pending mode and for Insert/Command-line mode.500Therefore the ":map" and ":map!" commands enter and display mappings for501several modes. In Vim you can use the ":nmap", ":vmap", ":omap", ":cmap" and502":imap" commands to enter mappings for each mode separately.503 504 *mapmode-t*505The terminal mappings are used in a terminal window, when typing keys for the506job running in the terminal. See |terminal-typing|.507 508 *omap-info*509Operator-pending mappings can be used to define a movement command that can be510used with any operator. Simple example: >511 :omap { w512makes "y{" work like "yw" and "d{" like "dw".513 514To ignore the starting cursor position and select different text, you can have515the omap start Visual mode to select the text to be operated upon. Example516that operates on a function name in the current line: >517 onoremap <silent> F :<C-U>normal! 0f(hviw<CR>518The CTRL-U (<C-U>) is used to remove the range that Vim may insert. The519Normal mode commands find the first '(' character and select the first word520before it. That usually is the function name.521 522To enter a mapping for Normal and Visual mode, but not Operator-pending mode,523first define it for all three modes, then unmap it for524Operator-pending mode: >525 :map xx something-difficult526 :ounmap xx527 528Likewise for a mapping for Visual and Operator-pending mode or Normal and529Operator-pending mode.530 531 *language-mapping*532":lmap" defines a mapping that applies to:533- Insert mode534- Command-line mode535- when entering a search pattern536- the argument of the commands that accept a text character, such as "r" and537 "f"538- for the input() line539Generally: Whenever a character is to be typed that is part of the text in the540buffer, not a Vim command character. "Lang-Arg" isn't really another mode,541it's just used here for this situation.542 The simplest way to load a set of related language mappings is by using the543'keymap' option. See |45.5|.544 In Insert mode and in Command-line mode the mappings can be disabled with545the CTRL-^ command |i_CTRL-^| |c_CTRL-^|. These commands change the value of546the 'iminsert' option. When starting to enter a normal command line (not a547search pattern) the mappings are disabled until a CTRL-^ is typed. The state548last used is remembered for Insert mode and Search patterns separately. The549state for Insert mode is also used when typing a character as an argument to550command like "f" or "t".551 Language mappings will never be applied to already mapped characters. They552are only used for typed characters. This assumes that the language mapping553was already done when typing the mapping.554 555 5561.4 LISTING MAPPINGS *map-listing*557 558When listing mappings the characters in the first two columns are:559 560 CHAR MODE ~561 <Space> Normal, Visual, Select and Operator-pending562 n Normal563 v Visual and Select564 s Select565 x Visual566 o Operator-pending567 ! Insert and Command-line568 i Insert569 l ":lmap" mappings for Insert, Command-line and Lang-Arg570 c Command-line571 t Terminal-Job572 573Just before the {rhs} a special character can appear:574 * indicates that it is not remappable575 & indicates that only script-local mappings are remappable576 @ indicates a buffer-local mapping577 578Everything from the first non-blank after {lhs} up to the end of the line579(or '|') is considered to be part of {rhs}. This allows the {rhs} to end580with a space.581 582Note: When using mappings for Visual mode, you can use the "'<" mark, which583is the start of the last selected Visual area in the current buffer |'<|.584 585The |:filter| command can be used to select what mappings to list. The586pattern is matched against the {lhs} and {rhs} in the raw form.587 588While mappings are being listed, it is not possible to add or clear mappings,589e.g. from a timer callback. *E1309*590 591 *:map-verbose*592When 'verbose' is non-zero, the detected and used 'keyprotocol' value will be593displayed in the first line. Also a key map will also display where it was594last defined. Example: >595 596 :verbose map <C-W>*597 Kitty keyboard protocol: Cleared598 n <C-W>* * <C-W><C-S>*599 Last set from /home/abcd/.vimrc600 601See |:verbose-cmd| for more information.602 603 6041.5 MAPPING SPECIAL KEYS *:map-special-keys*605 606There are three ways to map a special key:6071. The Vi-compatible method: Map the key code. Often this is a sequence that608 starts with <Esc>. To enter a mapping like this you type ":map " and then609 you have to type CTRL-V before hitting the function key. Note that when610 the key code for the key is in the termcap (the t_ options), it will611 automatically be translated into the internal code and become the second612 way of mapping (unless the 'k' flag is included in 'cpoptions').6132. The second method is to use the internal code for the function key. To614 enter such a mapping type CTRL-K and then hit the function key, or use615 the form "#1", "#2", .. "#9", "#0", "<Up>", "<S-Down>", "<S-F7>", etc.616 (see table of keys |key-notation|, all keys from <Up> can be used). The617 first ten function keys can be defined in two ways: Just the number, like618 "#2", and with "<F>", like "<F2>". Both stand for function key 2. "#0"619 refers to function key 10, defined with option 't_f10', which may be620 function key zero on some keyboards. The <> form cannot be used when621 'cpoptions' includes the '<' flag.6223. Use the termcap entry, with the form <t_xx>, where "xx" is the name of the623 termcap entry. Any string entry can be used. For example: >624 :map <t_F3> G625< Maps function key 13 to "G". This does not work if 'cpoptions' includes626 the '<' flag.627 628The advantage of the second and third method is that the mapping will work on629different terminals without modification (the function key will be630translated into the same internal code or the actual key code, no matter what631terminal you are using. The termcap must be correct for this to work, and you632must use the same mappings).633 634DETAIL: Vim first checks if a sequence from the keyboard is mapped. If it635isn't the terminal key codes are tried (see |terminal-options|). If a636terminal code is found it is replaced with the internal code. Then the check637for a mapping is done again (so you can map an internal code to something638else). What is written into the script file depends on what is recognized.639If the terminal key code was recognized as a mapping the key code itself is640written to the script file. If it was recognized as a terminal code the641internal code is written to the script file.642 643 6441.6 SPECIAL CHARACTERS *:map-special-chars*645 *map_backslash* *map-backslash*646Note that only CTRL-V is mentioned here as a special character for mappings647and abbreviations. When 'cpoptions' does not contain 'B', a backslash can648also be used like CTRL-V. The <> notation can be fully used then |<>|. But649you cannot use "<C-V>" like CTRL-V to escape the special meaning of what650follows.651 652To map a backslash, or use a backslash literally in the {rhs}, the special653sequence "<Bslash>" can be used. This avoids the need to double backslashes654when using nested mappings.655 656 *map_CTRL-C* *map-CTRL-C*657Using CTRL-C in the {lhs} is possible, but it will only work when Vim is658waiting for a key, not when Vim is busy with something. When Vim is busy659CTRL-C interrupts/breaks the command.660When using the GUI version on MS-Windows CTRL-C can be mapped to allow a Copy661command to the clipboard. Use CTRL-Break to interrupt Vim.662 663 *map_space_in_lhs* *map-space_in_lhs*664To include a space in {lhs} precede it with a CTRL-V (type two CTRL-Vs for665each space).666 *map_space_in_rhs* *map-space_in_rhs*667If you want a {rhs} that starts with a space, use "<Space>". To be fully Vi668compatible (but unreadable) don't use the |<>| notation, precede {rhs} with a669single CTRL-V (you have to type CTRL-V two times).670 *map_empty_rhs* *map-empty-rhs*671You can create an empty {rhs} by typing nothing after a single CTRL-V (you672have to type CTRL-V two times). Unfortunately, you cannot do this in a vimrc673file.674 *<Nop>*675An easier way to get a mapping that doesn't produce anything, is to use676"<Nop>" for the {rhs}. This only works when the |<>| notation is enabled.677For example, to make sure that function key 8 does nothing at all: >678 :map <F8> <Nop>679 :map! <F8> <Nop>680<681 *map-multibyte*682It is possible to map multibyte characters, but only the whole character. You683cannot map the first byte only. This was done to prevent problems in this684scenario: >685 :set encoding=latin1686 :imap <M-C> foo687 :set encoding=utf-8688The mapping for <M-C> is defined with the latin1 encoding, resulting in a 0xc3689byte. If you type the character á (0xe1 <M-a>) in UTF-8 encoding this is the690two bytes 0xc3 0xa1. You don't want the 0xc3 byte to be mapped then or691otherwise it would be impossible to type the á character.692 693 *<Leader>* *mapleader*694To define a mapping which uses the "g:mapleader" variable, the special string695"<Leader>" can be used. It is replaced with the string value of696"g:mapleader". If "g:mapleader" is not set or empty, a backslash is used697instead. Example: >698 map <Leader>A oanother line<Esc>699Works like: >700 map \A oanother line<Esc>701But after (legacy script): >702 let mapleader = ","703Or (Vim9 script): >704 g:mapleader = ","705It works like: >706 map ,A oanother line<Esc>707 708Note that the value of "g:mapleader" is used at the moment the mapping is709defined. Changing "g:mapleader" after that has no effect for already defined710mappings.711 712 *<LocalLeader>* *maplocalleader*713<LocalLeader> is just like <Leader>, except that it uses "maplocalleader"714instead of "mapleader". <LocalLeader> is to be used for mappings which are715local to a buffer. Example: >716 :map <buffer> <LocalLeader>A oanother line<Esc>717<718In a global plugin <Leader> should be used and in a filetype plugin719<LocalLeader>. "mapleader" and "maplocalleader" can be equal. Although, if720you make them different, there is a smaller chance of mappings from global721plugins to clash with mappings for filetype plugins. For example, you could722keep "mapleader" at the default backslash, and set "maplocalleader" to an723underscore.724 725 *map-<SID>*726In a script the special key name "<SID>" can be used to define a mapping727that's local to the script. See |<SID>| for details.728 729 *<Plug>*730The special key name "<Plug>" can be used for an internal mapping, which is731not to be matched with any key sequence. This is useful in plugins732|using-<Plug>|.733 734 *<MouseMove>*735The special key name "<MouseMove>" can be used to handle mouse movement. It736needs to be enabled with 'mousemoveevent'. Currently only works in the GUI.737The |getmousepos()| function can be used to obtain the mouse position.738 739 *<Char>* *<Char->*740To map a character by its decimal, octal or hexadecimal number the <Char>741construct can be used:742 <Char-123> character 123743 <Char-033> character 27744 <Char-0x7f> character 127745 <S-Char-114> character 114 ('r') shifted ('R')746This is useful to specify a (multibyte) character in a 'keymap' file.747Upper and lowercase differences are ignored.748 749 *map-comments*750It is not possible to put a comment after these commands, because the '"'751character is considered to be part of the {lhs} or {rhs}. However, one can752use |", since this starts a new, empty command with a comment.753 754 *map_bar* *map-bar*755Since the '|' character is used to separate a map command from the next756command, you will have to do something special to include a '|' in {rhs}.757There are three methods:758 use works when example ~759 <Bar> '<' is not in 'cpoptions' :map _l :!ls <Bar> more^M760 \| 'b' is not in 'cpoptions' :map _l :!ls \| more^M761 ^V| always, in Vim and Vi :map _l :!ls ^V| more^M762 763(here ^V stands for CTRL-V; to get one CTRL-V you have to type it twice; you764cannot use the <> notation "<C-V>" here).765 766All three work when you use the default setting for 'cpoptions'.767 768When 'b' is present in 'cpoptions', "\|" will be recognized as a mapping769ending in a '\' and then another command. This is Vi compatible, but770illogical when compared to other commands.771 772 *map_return* *map-return*773When you have a mapping that contains an Ex command, you need to put a line774terminator after it to have it executed. The use of <CR> is recommended for775this (see |<>|). Example: >776 :map _ls :!ls -l %:S<CR>:echo "the end"<CR>777 778To avoid mapping of the characters you type in insert or Command-line mode,779type a CTRL-V first. The mapping in Insert mode is disabled if the 'paste'780option is on.781 *map-error*782Note that when an error is encountered (that causes an error message or might783cause a beep) the rest of the mapping is not executed. This is Vi-compatible.784 785Note that the second character (argument) of the commands @zZtTfF[]rm'`"v786and CTRL-X is not mapped. This was done to be able to use all the named787registers and marks, even when the command with the same name has been788mapped.789 790 7911.7 WHAT KEYS TO MAP *map-which-keys*792 793If you are going to map something, you will need to choose which key(s) to use794for the {lhs}. You will have to avoid keys that are used for Vim commands,795otherwise you would not be able to use those commands anymore. Here are a few796suggestions:797- Function keys <F2>, <F3>, etc.. Also the shifted function keys <S-F1>,798 <S-F2>, etc. Note that <F1> is already used for the help command.799- Any key with the Alt or Meta key pressed. Depending on your keyboard800 accented characters may be used as well. |:map-alt-keys|801- Use the '_' or ',' character and then any other character. The "_" and ","802 commands do exist in Vim (see |_| and |,|), but you probably never use them.803- Use a key that is a synonym for another command. For example: CTRL-P and804 CTRL-N. Use an extra character to allow more mappings.805- The key defined by <Leader> and one or more other keys. This is especially806 useful in scripts. |mapleader|807 808See the file "index" for keys that are not used and thus can be mapped without809losing any builtin function. You can also use ":help {key}^D" to find out if810a key is used for some command. ({key} is the specific key you want to find811out about, ^D is CTRL-D).812 813 8141.8 EXAMPLES *map-examples*815 816A few examples (given as you type them, for "<CR>" you type four characters;817the '<' flag must not be present in 'cpoptions' for this to work). >818 819 :map <F3> o#include820 :map <M-g> /foo<CR>cwbar<Esc>821 :map _x d/END/e<CR>822 :map! qq quadrillion questions823 824 825Multiplying a count826 827When you type a count before triggering a mapping, it's like the count was828typed before the {lhs}. For example, with this mapping: >829 :map <F4> 3w830Typing 2<F4> will result in "23w". Thus not moving 2 * 3 words but 23 words.831If you want to multiply counts use the expression register: >832 :map <F4> @='3w'<CR>833The part between quotes is the expression being executed. |@=|834 835 8361.9 USING MAPPINGS *map-typing*837 838Vim will compare what you type with the start of a mapped sequence. If there839is an incomplete match, it will get more characters until there either is a840complete match or until there is no match at all. Example: If you map! "qq",841the first 'q' will not appear on the screen until you type another842character. This is because Vim cannot know if the next character will be a843'q' or not. If the 'timeout' option is on (which is the default) Vim will844only wait for one second (or as long as specified with the 'timeoutlen'845option). After that it assumes that the 'q' is to be interpreted as such. If846you type slowly, or your system is slow, reset the 'timeout' option. Then you847might want to set the 'ttimeout' option.848 849 *map-precedence*850Buffer-local mappings (defined using |:map-<buffer>|) take precedence over851global mappings. When a buffer-local mapping is the same as a global mapping,852Vim will use the buffer-local mapping. In addition, Vim will use a complete853mapping immediately if it was defined with <nowait>, even if a longer mapping854has the same prefix. For example, given the following two mappings: >855 :map <buffer> <nowait> \a :echo "Local \a"<CR>856 :map \abc :echo "Global \abc"<CR>857When typing \a the buffer-local mapping will be used immediately. Vim will858not wait for more characters to see if the user might be typing \abc.859 860 *map-keys-fails*861There are situations where key codes might not be recognized:862- Vim can only read part of the key code. Mostly this is only the first863 character. This happens on some Unix versions in an xterm.864- The key code is after character(s) that are mapped. E.g., "<F1><F1>" or865 "g<F1>".866 867The result is that the key code is not recognized in this situation, and the868mapping fails. There are two actions needed to avoid this problem:869 870- Remove the 'K' flag from 'cpoptions'. This will make Vim wait for the rest871 of the characters of the function key.872- When using <F1> to <F4> the actual key code generated may correspond to873 <xF1> to <xF4>. There are mappings from <xF1> to <F1>, <xF2> to <F2>, etc.,874 but these are not recognized after another half a mapping. Make sure the875 key codes for <F1> to <F4> are correct: >876 :set <F1>=<type CTRL-V><type F1>877< Type the <F1> as four characters. The part after the "=" must be done with878 the actual keys, not the literal text.879Another solution is to use the actual key code in the mapping for the second880special key: >881 :map <F1><Esc>OP :echo "yes"<CR>882Don't type a real <Esc>, Vim will recognize the key code and replace it with883<F1> anyway.884 885Another problem may be that when keeping ALT or Meta pressed the terminal886prepends ESC instead of setting the 8th bit. See |:map-alt-keys|.887 888 *recursive_mapping*889If you include the {lhs} in the {rhs} you have a recursive mapping. When890{lhs} is typed, it will be replaced with {rhs}. When the {lhs} which is891included in {rhs} is encountered it will be replaced with {rhs}, and so on.892This makes it possible to repeat a command an infinite number of times. The893only problem is that the only way to stop this is by causing an error. The894macros to solve a maze uses this, look there for an example. There is one895exception: If the {rhs} starts with {lhs}, the first character is not mapped896again (this is Vi compatible).897For example: >898 :map ab abcd899will execute the "a" command and insert "bcd" in the text. The "ab" in the900{rhs} will not be mapped again.901 902If you want to exchange the meaning of two keys you should use the :noremap903command. For example: >904 :noremap k j905 :noremap j k906This will exchange the cursor up and down commands.907 908With the normal :map command, when the 'remap' option is on, mapping takes909place until the text is found not to be a part of a {lhs}. For example, if910you use: >911 :map x y912 :map y x913Vim will replace x with y, and then y with x, etc. When this has happened914'maxmapdepth' times (default 1000), Vim will give the error message915"recursive mapping".916 917 *:map-undo*918If you include an undo command inside a mapped sequence, this will bring the919text back in the state before executing the macro. This is compatible with920the original Vi, as long as there is only one undo command in the mapped921sequence (having two undo commands in a mapped sequence did not make sense922in the original Vi, you would get back the text before the first undo).923 924 9251.10 MAPPING ALT-KEYS *:map-alt-keys*926 927For a readable mapping command the <A-k> form can be used. Note that <A-k>928and <A-K> are different, the latter will use an upper case letter. Actually,929<A-K> and <A-S-K> are the same. Instead of "A" you can use "M". If you have930an actual Meta modifier key, please see |:map-meta-keys|.931 932In the GUI Vim handles the Alt key itself, thus mapping keys with ALT should933always work. But in a terminal Vim gets a sequence of bytes and has to figure934out whether ALT was pressed or not.935 936If the terminal supports the modifyOtherKeys mode and it has been enabled,937then Vim can recognize more key combinations, see |modifyOtherKeys| below.938The Kitty keyboard protocol works in a similar way, see939|kitty-keyboard-protocol|.940 941By default Vim assumes that pressing the ALT key sets the 8th bit of a typed942character. Most decent terminals can work that way, such as xterm, aterm and943rxvt. If your <A-k> mappings don't work it might be that the terminal is944prefixing the character with an ESC character. But you can just as well type945ESC before a character, thus Vim doesn't know what happened (except for946checking the delay between characters, which is not reliable).947 948As of this writing, some mainstream terminals like gnome-terminal and konsole949use the ESC prefix. There doesn't appear a way to have them use the 8th bit950instead. Xterm should work well by default. Aterm and rxvt should work well951when started with the "--meta8" argument. You can also tweak resources like952"metaSendsEscape", "eightBitInput" and "eightBitOutput".953 954On the Linux console, this behavior can be toggled with the "setmetamode"955command. Bear in mind that not using an ESC prefix could get you in trouble956with other programs. You should make sure that bash has the "convert-meta"957option set to "on" in order for your Meta keybindings to still work on it958(it's the default readline behavior, unless changed by specific system959configuration). For that, you can add the line: >960 961 set convert-meta on962 963to your ~/.inputrc file. If you're creating the file, you might want to use: >964 965 $include /etc/inputrc966 967as the first line, if that file exists on your system, to keep global options.968This may cause a problem for entering special characters, such as the umlaut.969Then you should use CTRL-V before that character.970 971Bear in mind that convert-meta has been reported to have troubles when used in972UTF-8 locales. On terminals like xterm, the "metaSendsEscape" resource can be973toggled on the fly through the "Main Options" menu, by pressing Ctrl-LeftClick974on the terminal; that's a good last resource in case you want to send ESC when975using other applications but not when inside Vim.976 977 9781.11 MAPPING META-KEYS *:map-meta-keys*979 980Mapping keys with the Meta modifier works very similar to using the Alt key.981What key on your keyboard produces the Meta modifier depends on your keyboard982and configuration.983 984Note that mapping <M-a> actually is for using the Alt key. That can be985confusing! It cannot be changed, it would not be backwards compatible.986 987For the Meta modifier the "T" character is used. For example, to map Meta-b988in Insert mode: >989 :imap <T-b> terrible990 9911.12 MAPPING SUPER-KEYS or COMMAND-KEYS *:map-super-keys* *:map-cmd-key*992 993The Super modifier is available in GUI mode (when |gui_running| is 1) for gVim994on Linux and MacVim on Mac OS. If you're on a Mac, this represents the995Command key, on Linux with the GTK GUI it represents the Super key.996The character "D" is used for the Super / Command modifier.997 998For example, to map Command-b in Insert mode: >999 :imap <D-b> barritone1000 10011.13 MAPPING IN modifyOtherKeys mode *modifyOtherKeys*1002 1003Xterm and a few other terminals can be put in a mode where keys with modifiers1004are sent with a special escape code. Vim recognizes these codes and can then1005make a difference between CTRL-H and Backspace, even when Backspace sends the1006character 8. And many more special keys, such as Tab and CTRL-I, which cannot1007be mapped separately otherwise.1008 1009For xterm modifyOtherKeys is enabled in the builtin termcap entry. If this is1010not used you can enable modifyOtherKeys with these lines in your vimrc: >1011 let &t_TI = "\<Esc>[>4;2m"1012 let &t_TE = "\<Esc>[>4;m"1013 1014This sets modifyOtherKeys to level 2. Note that modifyOtherKeys level 1 does1015not work. Some terminals do not support level 2 and then send key codes that1016Vim will not be able to correctly recognize.1017 1018In case the modifyOtherKeys mode causes problems you can disable it: >1019 let &t_TI = ""1020 let &t_TE = ""1021It does not take effect immediately. To have this work without restarting Vim1022execute a shell command, e.g.: `!ls` Or put the lines in your |vimrc|.1023 1024When modifyOtherKeys is enabled you can map <C-[> and <C-S-{>: >1025 imap <C-[> [[[1026 imap <C-{> {{{1027Without modifyOtherKeys <C-[> and <C-{> are indistinguishable from Esc.1028Note that <C-{> is used and not <C-S-[> or <C-S-{>. This works on most1029keyboards. Similarly, <C-}> is used instead of <C-S-]> or <C-S-}> and1030<C-|> instead of <C-S-\> or <C-S-|>. Note that '|' has a special meaning in a1031mapping, see |map-bar|.1032 1033WARNING: if you map <C-[> you may very well break any key codes that start1034with Esc. Make sure it comes AFTER other mappings.1035 1036Starting with xterm version 377 Vim can detect the modifyOtherKeys state by1037requesting it. For this the 't_RK' termcap entry is used. When the response1038is found then Vim will know whether modifyOtherKeys level 2 is enabled, and1039handle mappings accordingly.1040 1041Before version 377 Vim automatically detects if the modifyOtherKeys mode was1042enabled when it spots an escape sequence that must have been created by it.1043To see if Vim detected such an escape sequence use `:verbose map`, the first1044line will then show "Seen modifyOtherKeys: true" (possibly translated).1045 1046This automatic detection depends on receiving an escape code starting with1047"<1b>[27;". This is the normal way xterm sends these key codes. However, if1048the *formatOtherKeys* resource is set another form is used that is not1049recognized, therefore you must not set formatOtherKeys.1050 1051A known side effect is that in Insert mode the raw escape sequence is inserted1052after the CTRL-V key. This can be used to check whether modifyOtherKeys is1053enabled: In Insert mode type CTRL-SHIFT-V CTRL-V, if you get one byte then1054modifyOtherKeys is off, if you get <1b>[27;5;118~ then it is on.1055 1056Note that xterm up to version 376 has a bug that makes Shift-Esc send a1057regular Esc code, the Shift modifier is dropped.1058 1059When the 'esckeys' option is off, then modifyOtherKeys will be disabled in1060Insert mode to avoid every key with a modifier causing Insert mode to end.1061 1062 10631.14 MAPPING WITH KITTY KEYBOARD PROTOCOL *kitty-keyboard-protocol*1064 1065If the value of 'term' contains "kitty" then Vim will send out an escape1066sequence to enable the Kitty keyboard protocol. This can be changed with the1067'keyprotocol' option.1068 1069Like modifyOtherKeys, this will make it possible to distinguish between more1070keys with modifiers. Also, this protocol sends an escape sequence for the Esc1071key, so that Vim does not need to use a timeout to know whether receiving an1072Esc character means the Esc key was pressed or it's the start of an escape1073sequence.1074 1075Vim automatically detects if the Kitty keyboard protocol was enabled when it1076spots the response to the status request (this should be part of the |t_TI|1077termcap entry). To see if Vim detected such an escape sequence use: >1078 :verbose map1079The first line will then show "Kitty keyboard protocol: {value}" (possibly1080translated). The meaning of {value}:1081 Unknown no status received yet1082 Off protocol is not used1083 On protocol is used1084 Disabled protocol was used but expected to have been disabled1085 by 't_TE'1086 Cleared protocol expected to have been disabled by 't_TE',1087 previous state is unknown1088 1089 10901.15 MAPPING AN OPERATOR *:map-operator*1091 1092An operator is used before a {motion} command. To define your own operator1093you must create a mapping that first sets the 'operatorfunc' option and then1094invoke the |g@| operator. After the user types the {motion} command the1095specified function will be called.1096 1097 *g@* *E774* *E775*1098g@{motion} Call the function set by the 'operatorfunc' option.1099 The '[ mark is positioned at the start of the text1100 moved over by {motion}, the '] mark on the last1101 character of the text.1102 The function is called with one String argument:1103 "line" {motion} was |linewise|1104 "char" {motion} was |characterwise|1105 "block" {motion} was |blockwise-visual|1106 The type can be forced, see |forced-motion|.1107 {not available when compiled without the |+eval|1108 feature}1109 1110Here is an example that counts the number of spaces with <F4>: >1111 1112 nnoremap <expr> <F4> CountSpaces()1113 xnoremap <expr> <F4> CountSpaces()1114 " doubling <F4> works on a line1115 nnoremap <expr> <F4><F4> CountSpaces() .. '_'1116 1117 function CountSpaces(context = {}, type = '') abort1118 if a:type == ''1119 let context = #{1120 \ dot_command: v:false,1121 \ extend_block: '',1122 \ virtualedit: [&l:virtualedit, &g:virtualedit],1123 \ }1124 let &operatorfunc = function('CountSpaces', [context])1125 set virtualedit=block1126 return 'g@'1127 endif1128 1129 let save = #{1130 \ clipboard: &clipboard,1131 \ selection: &selection,1132 \ virtualedit: [&l:virtualedit, &g:virtualedit],1133 \ register: getreginfo('"'),1134 \ visual_marks: [getpos("'<"), getpos("'>")],1135 \ }1136 1137 try1138 set clipboard= selection=inclusive virtualedit=1139 let commands = #{1140 \ line: "'[V']",1141 \ char: "`[v`]",1142 \ block: "`[\<C-V>`]",1143 \ }[a:type]1144 let [_, _, col, off] = getpos("']")1145 if off != 01146 let vcol = getline("'[")->strpart(0, col + off)->strdisplaywidth()1147 if vcol >= [line("'["), '$']->virtcol() - 11148 let a:context.extend_block = '$'1149 else1150 let a:context.extend_block = vcol .. '|'1151 endif1152 endif1153 if a:context.extend_block != ''1154 let commands ..= 'oO' .. a:context.extend_block1155 endif1156 let commands ..= 'y'1157 execute 'silent noautocmd keepjumps normal! ' .. commands1158 echomsg getreg('"')->count(' ')1159 finally1160 call setreg('"', save.register)1161 call setpos("'<", save.visual_marks[0])1162 call setpos("'>", save.visual_marks[1])1163 let &clipboard = save.clipboard1164 let &selection = save.selection1165 let [&l:virtualedit, &g:virtualedit] = get(a:context.dot_command ? save : a:context, 'virtualedit')1166 let a:context.dot_command = v:true1167 endtry1168 endfunction1169 1170An <expr> mapping is used to be able to fetch any prefixed count and register.1171This also avoids using a command line, which would trigger CmdlineEnter and1172CmdlineLeave autocommands.1173 1174Note that the 'selection' option is temporarily set to "inclusive" to be able1175to yank exactly the right text by using Visual mode from the '[ to the ']1176mark.1177 1178Also note that the 'clipboard' option is temporarily emptied to avoid1179clobbering the `"*` or `"+` registers, if its value contains the item `unnamed`1180or `unnamedplus`.1181 1182The `mode()` function will return the state as it will be after applying the1183operator.1184 1185Here is an example for using a lambda function to create a normal-mode1186operator to add quotes around text in the current line: >1187 1188 nnoremap <F4> <Cmd>let &opfunc='{t ->1189 \ getline(".")1190 \ ->split("\\zs")1191 \ ->insert("\"", col("'']"))1192 \ ->insert("\"", col("''[") - 1)1193 \ ->join("")1194 \ ->setline(".")}'<CR>g@1195 1196==============================================================================11972. Abbreviations *abbreviations* *Abbreviations*1198 1199Abbreviations are used in Insert mode, Replace mode and Command-line mode.1200If you enter a word that is an abbreviation, it is replaced with the word it