123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669 |
- *usr_40.txt* Nvim
- VIM USER MANUAL - by Bram Moolenaar
- Make new commands
- Vim is an extensible editor. You can take a sequence of commands you use
- often and turn it into a new command. Or redefine an existing command.
- Autocommands make it possible to execute commands automatically.
- |40.1| Key mapping
- |40.2| Defining command-line commands
- |40.3| Autocommands
- Next chapter: |usr_41.txt| Write a Vim script
- Previous chapter: |usr_32.txt| The undo tree
- Table of contents: |usr_toc.txt|
- ==============================================================================
- *40.1* Key mapping
- A simple mapping was explained in section |05.3|. The principle is that one
- sequence of key strokes is translated into another sequence of key strokes.
- This is a simple, yet powerful mechanism.
- The simplest form is that one key is mapped to a sequence of keys. Since
- the function keys, except <F1>, have no predefined meaning in Vim, these are
- good choices to map. Example: >
- :map <F2> GoDate: <Esc>:read !date<CR>kJ
- This shows how three modes are used. After going to the last line with "G",
- the "o" command opens a new line and starts Insert mode. The text "Date: " is
- inserted and <Esc> takes you out of insert mode.
- Notice the use of special keys inside <>. This is called angle bracket
- notation. You type these as separate characters, not by pressing the key
- itself. This makes the mappings better readable and you can copy and paste
- the text without problems.
- The ":" character takes Vim to the command line. The ":read !date" command
- reads the output from the "date" command and appends it below the current
- line. The <CR> is required to execute the ":read" command.
- At this point of execution the text looks like this:
- Date: ~
- Fri Jun 15 12:54:34 CEST 2001 ~
- Now "kJ" moves the cursor up and joins the lines together.
- To decide which key or keys you use for mapping, see |map-which-keys|.
- MAPPING AND MODES
- The ":map" command defines remapping for keys in Normal mode. You can also
- define mappings for other modes. For example, ":imap" applies to Insert mode.
- You can use it to insert a date below the cursor: >
- :imap <F2> <CR>Date: <Esc>:read !date<CR>kJ
- It looks a lot like the mapping for <F2> in Normal mode, only the start is
- different. The <F2> mapping for Normal mode is still there. Thus you can map
- the same key differently for each mode.
- Notice that, although this mapping starts in Insert mode, it ends in Normal
- mode. If you want it to continue in Insert mode, append an "a" to the
- mapping.
- Here is an overview of map commands and in which mode they work:
- :map Normal, Visual and Operator-pending
- :vmap Visual
- :nmap Normal
- :omap Operator-pending
- :map! Insert and Command-line
- :imap Insert
- :cmap Command-line
- Operator-pending mode is when you typed an operator character, such as "d" or
- "y", and you are expected to type the motion command or a text object. Thus
- when you type "dw", the "w" is entered in operator-pending mode.
- Suppose that you want to define <F7> so that the command d<F7> deletes a C
- program block (text enclosed in curly braces, {}). Similarly y<F7> would yank
- the program block into the unnamed register. Therefore, what you need to do
- is to define <F7> to select the current program block. You can do this with
- the following command: >
- :omap <F7> a{
- This causes <F7> to perform a select block "a{" in operator-pending mode, just
- like you typed it. This mapping is useful if typing a { on your keyboard is a
- bit difficult.
- LISTING MAPPINGS
- To see the currently defined mappings, use ":map" without arguments. Or one
- of the variants that include the mode in which they work. The output could
- look like this:
- _g :call MyGrep(1)<CR> ~
- v <F2> :s/^/> /<CR>:noh<CR>`` ~
- n <F2> :.,$s/^/> /<CR>:noh<CR>`` ~
- <xHome> <Home>
- <xEnd> <End>
- The first column of the list shows in which mode the mapping is effective.
- This is "n" for Normal mode, "i" for Insert mode, etc. A blank is used for a
- mapping defined with ":map", thus effective in both Normal and Visual mode.
- One useful purpose of listing the mapping is to check if special keys in <>
- form have been recognized (this only works when color is supported). For
- example, when <Esc> is displayed in color, it stands for the escape character.
- When it has the same color as the other text, it is five characters.
- REMAPPING
- The result of a mapping is inspected for other mappings in it. For example,
- the mappings for <F2> above could be shortened to: >
- :map <F2> G<F3>
- :imap <F2> <Esc><F3>
- :map <F3> oDate: <Esc>:read !date<CR>kJ
- For Normal mode <F2> is mapped to go to the last line, and then behave like
- <F3> was pressed. In Insert mode <F2> stops Insert mode with <Esc> and then
- also uses <F3>. Then <F3> is mapped to do the actual work.
- Suppose you hardly ever use Ex mode, and want to use the "Q" command to format
- text (this was so in old versions of Vim). This mapping will do it: >
- :map Q gq
- But, in rare cases you need to use Ex mode anyway. Let's map "gQ" to Q, so
- that you can still go to Ex mode: >
- :map gQ Q
- What happens now is that when you type "gQ" it is mapped to "Q". So far so
- good. But then "Q" is mapped to "gq", thus typing "gQ" results in "gq", and
- you don't get to Ex mode at all.
- To avoid keys to be mapped again, use the ":noremap" command: >
- :noremap gQ Q
- Now Vim knows that the "Q" is not to be inspected for mappings that apply to
- it. There is a similar command for every mode:
- :noremap Normal, Visual and Operator-pending
- :vnoremap Visual
- :nnoremap Normal
- :onoremap Operator-pending
- :noremap! Insert and Command-line
- :inoremap Insert
- :cnoremap Command-line
- RECURSIVE MAPPING
- When a mapping triggers itself, it will run forever. This can be used to
- repeat an action an unlimited number of times.
- For example, you have a list of files that contain a version number in the
- first line. You edit these files with "vim *.txt". You are now editing the
- first file. Define this mapping: >
- :map ,, :s/5.1/5.2/<CR>:wnext<CR>,,
- Now you type ",,". This triggers the mapping. It replaces "5.1" with "5.2"
- in the first line. Then it does a ":wnext" to write the file and edit the
- next one. The mapping ends in ",,". This triggers the same mapping again,
- thus doing the substitution, etc.
- This continues until there is an error. In this case it could be a file
- where the substitute command doesn't find a match for "5.1". You can then
- make a change to insert "5.1" and continue by typing ",," again. Or the
- ":wnext" fails, because you are in the last file in the list.
- When a mapping runs into an error halfway, the rest of the mapping is
- discarded. CTRL-C interrupts the mapping (CTRL-Break on MS-Windows).
- DELETE A MAPPING
- To remove a mapping use the ":unmap" command. Again, the mode the unmapping
- applies to depends on the command used:
- :unmap Normal, Visual and Operator-pending
- :vunmap Visual
- :nunmap Normal
- :ounmap Operator-pending
- :unmap! Insert and Command-line
- :iunmap Insert
- :cunmap Command-line
- There is a trick to define a mapping that works in Normal and Operator-pending
- mode, but not in Visual mode. First define it for all three modes, then
- delete it for Visual mode: >
- :map <C-A> /---><CR>
- :vunmap <C-A>
- Notice that the five characters "<C-A>" stand for the single key CTRL-A.
- To remove all mappings use the |:mapclear| command. You can guess the
- variations for different modes by now. Be careful with this command, it can't
- be undone.
- SPECIAL CHARACTERS
- The ":map" command can be followed by another command. A | character
- separates the two commands. This also means that a | character can't be used
- inside a map command. To include one, use <Bar> (five characters). Example:
- >
- :map <F8> :write <Bar> !checkin %:S<CR>
- The same problem applies to the ":unmap" command, with the addition that you
- have to watch out for trailing white space. These two commands are different:
- >
- :unmap a | unmap b
- :unmap a| unmap b
- The first command tries to unmap "a ", with a trailing space.
- When using a space inside a mapping, use <Space> (seven characters): >
- :map <Space> W
- This makes the spacebar move a blank-separated word forward.
- It is not possible to put a comment directly after a mapping, because the "
- character is considered to be part of the mapping. You can use |", this
- starts a new, empty command with a comment. Example: >
- :map <Space> W| " Use spacebar to move forward a word
- MAPPINGS AND ABBREVIATIONS
- Abbreviations are a lot like Insert mode mappings. The arguments are handled
- in the same way. The main difference is the way they are triggered. An
- abbreviation is triggered by typing a non-word character after the word. A
- mapping is triggered when typing the last character.
- Another difference is that the characters you type for an abbreviation are
- inserted in the text while you type them. When the abbreviation is triggered
- these characters are deleted and replaced by what the abbreviation produces.
- When typing the characters for a mapping, nothing is inserted until you type
- the last character that triggers it. If the 'showcmd' option is set, the
- typed characters are displayed in the last line of the Vim window.
- An exception is when a mapping is ambiguous. Suppose you have done two
- mappings: >
- :imap aa foo
- :imap aaa bar
- Now, when you type "aa", Vim doesn't know if it should apply the first or the
- second mapping. It waits for another character to be typed. If it is an "a",
- the second mapping is applied and results in "bar". If it is a space, for
- example, the first mapping is applied, resulting in "foo", and then the space
- is inserted.
- ADDITIONALLY...
- The <script> keyword can be used to make a mapping local to a script. See
- |:map-<script>|.
- The <buffer> keyword can be used to make a mapping local to a specific buffer.
- See |:map-<buffer>|
- The <unique> keyword can be used to make defining a new mapping fail when it
- already exists. Otherwise a new mapping simply overwrites the old one. See
- |:map-<unique>|.
- To make a key do nothing, map it to <Nop> (five characters). This will make
- the <F7> key do nothing at all: >
- :map <F7> <Nop>| map! <F7> <Nop>
- There must be no space after <Nop>.
- ==============================================================================
- *40.2* Defining command-line commands
- The Vim editor enables you to define your own commands. You execute these
- commands just like any other Command-line mode command.
- To define a command, use the ":command" command, as follows: >
- :command DeleteFirst 1delete
- Now when you execute the command ":DeleteFirst" Vim executes ":1delete", which
- deletes the first line.
- Note:
- User-defined commands must start with a capital letter. You cannot
- use ":Next". The underscore cannot be used! You can use digits, but
- this is discouraged.
- To list the user-defined commands, execute the following command: >
- :command
- Just like with the builtin commands, the user defined commands can be
- abbreviated. You need to type just enough to distinguish the command from
- another. Command line completion can be used to get the full name.
- NUMBER OF ARGUMENTS
- User-defined commands can take a series of arguments. The number of arguments
- must be specified by the -nargs option. For instance, the example
- :DeleteFirst command takes no arguments, so you could have defined it as
- follows: >
- :command -nargs=0 DeleteFirst 1delete
- However, because zero arguments is the default, you do not need to add
- "-nargs=0". The other values of -nargs are as follows:
- -nargs=0 No arguments
- -nargs=1 One argument
- -nargs=* Any number of arguments
- -nargs=? Zero or one argument
- -nargs=+ One or more arguments
- USING THE ARGUMENTS
- Inside the command definition, the arguments are represented by the
- <args> keyword. For example: >
- :command -nargs=+ Say :echo "<args>"
- Now when you type >
- :Say Hello World
- Vim echoes "Hello World". However, if you add a double quote, it won't work.
- For example: >
- :Say he said "hello"
- To get special characters turned into a string, properly escaped to use as an
- expression, use "<q-args>": >
- :command -nargs=+ Say :echo <q-args>
- Now the above ":Say" command will result in this to be executed: >
- :echo "he said \"hello\""
- The <f-args> keyword contains the same information as the <args> keyword,
- except in a format suitable for use as function call arguments. For example:
- >
- :command -nargs=* DoIt :call AFunction(<f-args>)
- :DoIt a b c
- Executes the following command: >
- :call AFunction("a", "b", "c")
- LINE RANGE
- Some commands take a range as their argument. To tell Vim that you are
- defining such a command, you need to specify a -range option. The values for
- this option are as follows:
- -range Range is allowed; default is the current line.
- -range=% Range is allowed; default is the whole file.
- -range={count} Range is allowed; the last number in it is used as a
- single number whose default is {count}.
- When a range is specified, the keywords <line1> and <line2> get the values of
- the first and last line in the range. For example, the following command
- defines the SaveIt command, which writes out the specified range to the file
- "save_file": >
- :command -range=% SaveIt :<line1>,<line2>write! save_file
- OTHER OPTIONS
- Some of the other options and keywords are as follows:
- -count={number} The command can take a count whose default is
- {number}. The resulting count can be used
- through the <count> keyword.
- -bang You can use a !. If present, using <bang> will
- result in a !.
- -register You can specify a register. (The default is
- the unnamed register.)
- The register specification is available as
- <reg> (a.k.a. <register>).
- -complete={type} Type of command-line completion used. See
- |:command-completion| for the list of possible
- values.
- -bar The command can be followed by | and another
- command, or " and a comment.
- -buffer The command is only available for the current
- buffer.
- Finally, you have the <lt> keyword. It stands for the character <. Use this
- to escape the special meaning of the <> items mentioned.
- REDEFINING AND DELETING
- To redefine the same command use the ! argument: >
- :command -nargs=+ Say :echo "<args>"
- :command! -nargs=+ Say :echo <q-args>
- To delete a user command use ":delcommand". It takes a single argument, which
- is the name of the command. Example: >
- :delcommand SaveIt
- To delete all the user commands: >
- :comclear
- Careful, this can't be undone!
- More details about all this in the reference manual: |user-commands|.
- ==============================================================================
- *40.3* Autocommands
- An autocommand is a command that is executed automatically in response to some
- event, such as a file being read or written or a buffer change. Through the
- use of autocommands you can train Vim to edit compressed files, for example.
- That is used in the |gzip| plugin.
- Autocommands are very powerful. Use them with care and they will help you
- avoid typing many commands. Use them carelessly and they will cause a lot of
- trouble.
- Suppose you want to replace a datestamp on the end of a file every time it is
- written. First you define a function: >
- :function DateInsert()
- : $delete
- : read !date
- :endfunction
- You want this function to be called each time, just before a buffer is written
- to a file. This will make that happen: >
- :autocmd BufWritePre * call DateInsert()
- "BufWritePre" is the event for which this autocommand is triggered: Just
- before (pre) writing a buffer to a file. The "*" is a pattern to match with
- the file name. In this case it matches all files.
- With this command enabled, when you do a ":write", Vim checks for any
- matching BufWritePre autocommands and executes them, and then it
- performs the ":write".
- The general form of the :autocmd command is as follows: >
- :autocmd [group] {events} {file-pattern} [++nested] {command}
- The [group] name is optional. It is used in managing and calling the commands
- (more on this later). The {events} parameter is a list of events (comma
- separated) that trigger the command.
- {file-pattern} is a filename, usually with wildcards. For example, using
- "*.txt" makes the autocommand be used for all files whose name end in ".txt".
- The optional [++nested] flag allows for nesting of autocommands (see below),
- and finally, {command} is the command to be executed.
- When adding an autocommand the already existing ones remain. To avoid adding
- the autocommand several times you should use this form: >
- :augroup updateDate
- : autocmd!
- : autocmd BufWritePre * call DateInsert()
- :augroup END
- This will delete any previously defined autocommand with `:autocmd!` before
- defining the new one. Groups are explained later.
- EVENTS
- One of the most useful events is BufReadPost. It is triggered after a new
- file is being edited. It is commonly used to set option values. For example,
- you know that "*.gsm" files are GNU assembly language. To get the syntax file
- right, define this autocommand: >
- :autocmd BufReadPost *.gsm set filetype=asm
- If Vim is able to detect the type of file, it will set the 'filetype' option
- for you. This triggers the Filetype event. Use this to do something when a
- certain type of file is edited. For example, to load a list of abbreviations
- for text files: >
- :autocmd Filetype text source ~/.config/nvim/abbrevs.vim
- When starting to edit a new file, you could make Vim insert a skeleton: >
- :autocmd BufNewFile *.[ch] 0read ~/skeletons/skel.c
- See |autocmd-events| for a complete list of events.
- PATTERNS
- The {file-pattern} argument can actually be a comma-separated list of file
- patterns. For example: "*.c,*.h" matches files ending in ".c" and ".h".
- The usual file wildcards can be used. Here is a summary of the most often
- used ones:
- * Match any character any number of times
- ? Match any character once
- [abc] Match the character a, b or c
- . Matches a dot
- a{b,c} Matches "ab" and "ac"
- When the pattern includes a slash (/) Vim will compare directory names.
- Without the slash only the last part of a file name is used. For example,
- "*.txt" matches "/home/biep/readme.txt". The pattern "/home/biep/*" would
- also match it. But "home/foo/*.txt" wouldn't.
- When including a slash, Vim matches the pattern against both the full path
- of the file ("/home/biep/readme.txt") and the relative path (e.g.,
- "biep/readme.txt").
- Note:
- When working on a system that uses a backslash as file separator, such
- as MS-Windows, you still use forward slashes in autocommands. This
- makes it easier to write the pattern, since a backslash has a special
- meaning. It also makes the autocommands portable.
- DELETING
- To delete an autocommand, use the same command as what it was defined with,
- but leave out the {command} at the end and use a !. Example: >
- :autocmd! FileWritePre *
- This will delete all autocommands for the "FileWritePre" event that use the
- "*" pattern.
- LISTING
- To list all the currently defined autocommands, use this: >
- :autocmd
- The list can be very long, especially when filetype detection is used. To
- list only part of the commands, specify the group, event and/or pattern. For
- example, to list all BufNewFile autocommands: >
- :autocmd BufNewFile
- To list all autocommands for the pattern "*.c": >
- :autocmd * *.c
- Using "*" for the event will list all the events. To list all autocommands
- for the cprograms group: >
- :autocmd cprograms
- GROUPS
- The {group} item, used when defining an autocommand, groups related autocommands
- together. This can be used to delete all the autocommands in a certain group,
- for example.
- When defining several autocommands for a certain group, use the ":augroup"
- command. For example, let's define autocommands for C programs: >
- :augroup cprograms
- : autocmd BufReadPost *.c,*.h :set sw=4 sts=4
- : autocmd BufReadPost *.cpp :set sw=3 sts=3
- :augroup END
- This will do the same as: >
- :autocmd cprograms BufReadPost *.c,*.h :set sw=4 sts=4
- :autocmd cprograms BufReadPost *.cpp :set sw=3 sts=3
- To delete all autocommands in the "cprograms" group: >
- :autocmd! cprograms
- NESTING
- Generally, commands executed as the result of an autocommand event will not
- trigger any new events. If you read a file in response to a FileChangedShell
- event, it will not trigger the autocommands that would set the syntax, for
- example. To make the events triggered, add the "++nested" flag: >
- :autocmd FileChangedShell * ++nested edit
- EXECUTING AUTOCOMMANDS
- It is possible to trigger an autocommand by pretending an event has occurred.
- This is useful to have one autocommand trigger another one. Example: >
- :autocmd BufReadPost *.new execute "doautocmd BufReadPost " . expand("<afile>:r")
- This defines an autocommand that is triggered when a new file has been edited.
- The file name must end in ".new". The ":execute" command uses expression
- evaluation to form a new command and execute it. When editing the file
- "tryout.c.new" the executed command will be: >
- :doautocmd BufReadPost tryout.c
- The expand() function takes the "<afile>" argument, which stands for the file
- name the autocommand was executed for, and takes the root of the file name
- with ":r".
- ":doautocmd" executes on the current buffer. The ":doautoall" command works
- like "doautocmd" except it executes on all the buffers.
- USING NORMAL MODE COMMANDS
- The commands executed by an autocommand are Command-line commands. If you
- want to use a Normal mode command, the ":normal" command can be used.
- Example: >
- :autocmd BufReadPost *.log normal G
- This will make the cursor jump to the last line of *.log files when you start
- to edit it.
- Using the ":normal" command is a bit tricky. First of all, make sure its
- argument is a complete command, including all the arguments. When you use "i"
- to go to Insert mode, there must also be a <Esc> to leave Insert mode again.
- If you use a "/" to start a search pattern, there must be a <CR> to execute
- it.
- The ":normal" command uses all the text after it as commands. Thus there
- can be no | and another command following. To work around this, put the
- ":normal" command inside an ":execute" command. This also makes it possible
- to pass unprintable characters in a convenient way. Example: >
- :autocmd BufReadPost *.chg execute "normal ONew entry:\<Esc>" |
- \ 1read !date
- This also shows the use of a backslash to break a long command into more
- lines. This can be used in Vim scripts (not at the command line).
- When you want the autocommand do something complicated, which involves jumping
- around in the file and then returning to the original position, you may want
- to restore the view on the file. See |restore-position| for an example.
- IGNORING EVENTS
- At times, you will not want to trigger an autocommand. The 'eventignore'
- option contains a list of events that will be totally ignored. For example,
- the following causes events for entering and leaving a window to be ignored: >
- :set eventignore=WinEnter,WinLeave
- To ignore all events, use the following command: >
- :set eventignore=all
- To set it back to the normal behavior, make 'eventignore' empty: >
- :set eventignore=
- ==============================================================================
- Next chapter: |usr_41.txt| Write a Vim script
- Copyright: see |manual-copyright| vim:tw=78:ts=8:noet:ft=help:norl:
|