*map
and *noremap
. The first allows you to override its right side, the second is not. In additions, only the second should be used, since it is not known which bindings the user has. Classic example: noremap : ; noremap ; :
will break nmap <F4> :PluginToggle<CR>
, but not nnoremap <F4> :PluginToggle<CR>
. Other commands to keep in mind:*map
/ *noremap
, *abbrev
/ *noreabbrev
, *menu
/ *noremenu
normal
/ normal!
call feedkeys(string)
/ call feedkeys(string, 'n')
*map
to behave in the same way as their *noremap
equivalents. You will not be able to use nnoremap <Plug>PluginAction :DoAction<CR> if !hasmapto('<Plug>PluginAction') nmap <Leader>a <Plug>PluginAction endif
to allow users to redefine lhs and also support users who have enabled this setting, instead you have to bring all the definitions of the bindings to the form execute 'nnoremap '.get(g:, 'plugin_action_key', '<Leader>a').' :DoAction<CR>'
or more compatible with older versions of vim if !exists('g:plugin_action_key') let g:plugin_action_key='<Leader>a' endif execute 'nnoremap '.g:plugin_action_key.' :DoAction<CR>'
nmap <Esc> <Esc>
already suffering this. nnoremap <Plug>PluginAction :DoAction<CR> if !hasmapto('<Plug>PluginAction') nmap <Leader>a <Plug>PluginAction endif
or execute 'nnoremap '.get(g:, 'plugin_action_key', '<Leader>a').' :DoAction<CR>'
There is another reason why this method should not be used: for commands nnoremap <script> lhs rhs
and nnoremap lhs rhs
calling maparg('lhs', 'n', 0, 1)
will return the same dictionary. That is, if another developer wants, say, to temporarily make another binding with the same lhs
, and then restore the old one, then the file binding will not be correctly restored. if &compatible finish endif
The second most damaging effect on add-ons is to set up 'cpoptions' : with it, you can prevent the transfer of a part of a command to the next line , change the behavior of commands that create bindings, change the behavior of regular expressions, and do other bad things. This is usually partly handled by let s:saved_cpo=&cpo set cpo&vim <...> let &cpo=s:saved_cpo unlet s:saved_cpo
but with changing the behavior of regular expressions you can not do anything. It is also good that it does not affect functions (I mean built-in functions like match * () , substitute () , and not user-defined).#
(takes case into account) or ?
(accordingly, ignores it). Help/
and ?
, including when the search command is part of a range , you should explicitly specify \C
or \c
.:tag name
will have to turn into :tag /\V\C\^name\$
if you care about the register of tags.i
or I
*
and #
you can not do anything. Can use instead let @/='\V\C\<'.escape(expand('<cword>'), '\/').'\>' call histadd('/', @/) normal! n
, and you can just score and forget. Never seen the use of this action in additions.\M
, \m
, \v
or \V
when searching using /
and ?
, including when the search command is part of the range , and also use : sm or : sno instead of : s .g
flag to the exact opposite. The only way to handle it is to use let saved_gdefault=&gdefault set nogdefault " Do sm// commands here let &gdefault=saved_gdefault
./
) or the directory in which the current ( ../
) is located. execute 'normal! A'.text
to enter text, use setline () or append () instead. If you want to add it to the end of the line, you have to use let lines=split(text, "\n", 1) let lines[0]=getline('.').lines[0] call setline('.', remove(lines, 0)) if !empty(lines) call append('.', lines) endif
. Moving the cursor will also have to be considered manually. Inserting the text inside, as you can guess, will add a few more lines of code. An example, not jerking the cursor, can be found here .shell*
settings, and, according to the documentation, some settings do not change automatically with a change to 'shell' if they were changed explicitly earlier, so it’s better not to do this, since restoring everything “as it was "You will not succeed./
and ?
, including when the search command is part of a range . Use search () , which can be explicitly set the behavior or the standard "saved, changed, made, restored."glob('{*,.*}', 1, 1)
you will receive special directories in the load .
(current directory) and ..
(directory in which the current one is located), which in many cases you just need to ignore. execute "function Abc()\n DoSomething\nendfunction"
, here a new line always separates two commands. %s/\n\s*\\//
endfunction
on a separate line. The parser after the function
command just stupidly cheats all the lines belonging to the functions and saves them to an array until it encounters the endfunction
command found on the new line.fileencodings=utf8,cp1251
, in contrast to the compressed file encoded with CP1251. If you do not want this to happen with your supplement, there is v: cmdarg at your service. This variable always contains the data of the user ++ settings in a short form, so you will not have to support ++ enc and ++ encoding. An example can be found here (read, the next function is a write) (although 'fileformats' and 'fileencodings' are ignored here), but in some cases v: cmdarg can be simply combined with : read with : execute . Note that : read ignores ++ settings when reading shell command output. try echoerr 'Error' endtry
you write just echoerr 'Error' " some code here
get ready for the fact that you will have to debug strange problems related to the fact that “some code” is executed, then not - depending on whether you put the code inside the block :try
. Considering that inside the block :try
you cannot put only code that will never be executed, and the user may have more than one reason to put your code exactly there, having written :echoerr
you just in vain complicated your life. echohl ErrorMsg echomsg 'Error' echohl None
. If you need to interrupt the execution, there is : throw . And only if you are not at all satisfied with the error message issued by :throw
, there is try echoerr 'Error' endtry
. Simply :echoerr
no, you must forget it.shell
(or whether the user has an assembly that supports other programming languages).'b'
. It is recommended to use the shellredir setting value in order to have a better chance of making money on another computer. An example . enew call setline('.', "a\nb") yank put call setreg('"', getreg('"'), getregtype('"')) put
( look here to see why I took "\n"
). Here is what you see: a^@b a^@b a b
\r
before \n
.==
, ==?
, ==#
(inequality:! !=*
). Scalar types are compared as is, leading if necessary (if the arguments are of a different type) the string to the integer, and the integer to a floating point number. When comparing a string with a floating-point number, the string will first be converted to an integer, then an integer to a floating-point number. Therefore, "42"==42.0
, but "42.1"!=42.1
, and "42.1"==42.0
.:try
).is
, is?
, is#
(inequality: isnot*
). When comparing scalar types, it works the same way as type(a)==type(b) && a==b
(with the appropriate suffix, of course). When comparing non-scalar types (the reference to a function is also a scalar type), it first checks the type, then the identity (that is, whether the arguments refer to the same object in memory), similarly to the is
operator in Python. Never throws an error and never leads an argument to another type.is#
, is?
, isnot#
or isnot?
(the difference is described in the section “Settings / Ignoring the register”).==#
, ==?
!=#
or !=?
.==
, is
isnot
!=
And isnot
should be forgotten altogether.==
.is
.==#
for the lines I do not apply because I do not want to think whether I should (will) use the number as a “special argument” (like 0
instead of None
). let Func=function("tr")
, you probably also know that the variable name starts with a capital letter, because otherwise Vim will show an error. But there is another, less well-known, fact, because of which you should never assign a function reference to a variable: if someone somewhere defined the function “Func”, then Vim would also show an error. There are only two safe ways to use a function reference: pass it as an argument and use complex structures: a dictionary or a list: let d={} let d.func=function("tr")
, and function Apply(func, list) return call(a:func, a:list, {}) endfunction echo Apply(function("tr"), ["abc", "a", "d"])
completely safe, even despite the possibility of defining the function a:func()
. nnoremap <F4> :!python %<CR>
? This is another feature of Vim that could be comfortable ... if it worked normally. It is necessary to appear in the file name as a space / stroke / dollar (* sh) and instead of the file name the interpreter in this binding can get anything. Vim has many modifiers for the current file name like %:t
[ail] (leaves only the last part of the name), but the modifier %:E
[scape], which would run the file name through shellescape () , is not among them. Therefore, you have to screen everything yourself, while not forgetting the context of the call: when using system (), shellescape () should be called with one argument or zero instead of the second, and when used :! , : read! , : write! and other exclamation marks - with two arguments and one as the second. Examples: nnoremap <F4> :execute '!python' shellescape(@%, 1)<CR> nnoremap <F5> :call system('javac '.shellescape(expand('%')))<CR>
[^\na]
- familiar record? In VimL regular expressions, it means absolutely not what you think: this collection matches any character, as well as a new line . The fact is that this record means the same as the less discouraging \_[^a]
: that is, adding a new line to the collection, in this case consisting of all characters except a
.substitute(str, reg, '\=expr', flags)
can replace the regular expression with the result of the evaluation expr
, or maybe with =expr
. \=
, , ‐ , Vim . substitute() :s .^
« » , ( \(\)
, \%(\)
) ( \|
). $
, , .\n
, « », « ». : , . Vim « » — char*.-complete=dir
and -complete=file
, however, these arguments have little in common with auto-completion: command -complete=dir -nargs=1 -bar Echo :echo [<f-args>] command -nargs=1 EchoN :echo [<f-args>]
:Echo abc E172: :EchoN abc ['ab c'] :Echo * E77: :Echo $HOME ['/home/zyx'] :Echo `date` ['. . 28 17:17:47 MSK 2012']
.Agree, a bit is not what you expected, setting up auto-completion. Especially if the team must accept exactly the templates. Moreover, it is not described in the documentation. And does not happen with other options for auto-completion.Source: https://habr.com/ru/post/149919/
All Articles