Vim是我编程时首选的文本编辑器,因此我经常遇到一个非常烦人的问题。
经常情况下,当我需要快速保存缓冲区并继续进行其他杂项任务时,我会执行典型的
:w
然而,我总是——似乎超过50%的时间——将:w
大写。自然地,Vim会报错因为W
是无效的命令:
E492: Not an editor command: W
我的问题是如何在Vim中创建别名Colon命令。特别是,你能否举例说明如何将W
别名为w
。
我知道可以通过映射键来执行某些命令,但这不是我想要的。
要保持自动完成不变,请尝试使用
cnoreabbrev W w
这将会在命令行中用w
替换W
,但只有在它前后都不是单词字符的情况下才会进行替换。因此:W<CR>
将被替换为:w<CR>
,但:Write
则不会受影响。(请注意,这会影响与之匹配的所有命令,包括您可能意想不到的命令。例如,命令:saveas W Z
将被替换为:saveas w Z
,因此请小心使用。)
以下是我现在会如何写:
cnoreabbrev <expr> W ((getcmdtype() is# ':' && getcmdline() is# 'W')?('w'):('W'))
作为一个函数:
fun! SetupCommandAlias(from, to)
exec 'cnoreabbrev <expr> '.a:from
\ .' ((getcmdtype() is# ":" && getcmdline() is# "'.a:from.'")'
\ .'? ("'.a:to.'") : ("'.a:from.'"))'
endfun
call SetupCommandAlias("W","w")
通过检查命令类型是否为:
以及命令是否为W
,因此它比仅使用cnoreabbrev W w
更安全。
:%s/W/foo/g<CR>
:%s/w/foo/g<CR>
。 - cprn:cnoreabbrev <expr> W getcmdtype()==':'&&getcmdline()=~#'^W'?'w':'W'
- kev:command AliasName 要被别名的命令字符串
。 - Alec Jacobson:Q!
或:W!
怎么样? - Jacklynn:command W w
放入 .vimrc
文件中。 - isomorphismes我发现将;
键映射为:
会是一个更好的解决方案,而且可以让你在输入其他命令时更高效。
nnoremap ; :
vnoremap ; :
t
或f
时,通常可以使用;
跳转到下一个出现位置。即使将分号映射为冒号,也可以安全地将其反向映射。不会出现别名循环。nnoremap : ;
- Luc" cabs - less stupidity {{{
fu! Single_quote(str)
return "'" . substitute(copy(a:str), "'", "''", 'g') . "'"
endfu
fu! Cabbrev(key, value)
exe printf('cabbrev <expr> %s (getcmdtype() == ":" && getcmdpos() <= %d) ? %s : %s',
\ a:key, 1+len(a:key), Single_quote(a:value), Single_quote(a:key))
endfu
"}}}
" use this custom function for cabbrevations. This makes sure that they only
" apply in the beginning of a command. Else we might end up with stuff like
" :%s/\vfoo/\v/\vbar/
" if we happen to move backwards in the pattern.
" For example:
call Cabbrev('W', 'w')
以下是我从源材料中找到的一些有用的缩写:
call Cabbrev('/', '/\v')
call Cabbrev('?', '?\v')
call Cabbrev('s/', 's/\v')
call Cabbrev('%s/', '%s/\v')
call Cabbrev('s#', 's#\v')
call Cabbrev('%s#', '%s#\v')
call Cabbrev('s@', 's@\v')
call Cabbrev('%s@', '%s@\v')
call Cabbrev('s!', 's!\v')
call Cabbrev('%s!', '%s!\v')
call Cabbrev('s%', 's%\v')
call Cabbrev('%s%', '%s%\v')
call Cabbrev("'<,'>s/", "'<,'>s/\v")
call Cabbrev("'<,'>s#", "'<,'>s#\v")
call Cabbrev("'<,'>s@", "'<,'>s@\v")
call Cabbrev("'<,'>s!", "'<,'>s!\v")
string()
,它与你的 Single_quote()
做的事情是一样的。 - ZyX假设您想在gvim中为tabnew命令添加别名。您只需在.vimrc文件中键入以下命令(如果不在主文件夹中,则创建一个):
cabbrev t tabnew
:saveas t example
的命令被替换为 :saveas tabnew example
。 - Flimmnoremap <f1> :w<return>
inoremap <f1> <c-o>:w<return>
(在插入模式下按ctrl-o可以暂时切换到正常模式)。
最安全和最简单的方法是使用像cmdalias.vim这样的插件,或者像我最近更新的vim-alias一样的插件,它们考虑了以下因素:
:sil(ent)(!)
或:redi(r)
,'<,'>
表示当前可视选择区域,我认为 @ZyX 的回答很好,但如果你正在使用更新版本的 Neovim(0.5+),你可能想要使用 Lua 定义这个函数。以下是一种可能的方法:
function _G.abbreviate_or_noop(input, output)
local cmdtype = vim.fn.getcmdtype()
local cmdline = vim.fn.getcmdline()
if (cmdtype == ":" and cmdline == input) then
return output
else
return input
end
end
function SetupCommandAlias(input, output)
vim.api.nvim_command("cabbrev <expr> " .. input .. " " .. "v:lua.abbreviate_or_noop('" .. input .. "', '" .. output .. "')")
end
call SetupCommandAlias("pg", "postgres://")
中删除call
,并像这样使用函数:SetupCommandAlias("pg", "postgres://")
。.vim
文件而不是.lua
文件中使用它,则需要在函数调用前加上lua
前缀,即lua SetupCommandAlias("pg", "postgres://")
。
:W
,您可以映射一个键来执行保存操作。如果您习惯于使用 Ctrl-s 进行保存,则可以使用 $VIM/mswin.vim 中的以下映射:" Use CTRL-S for saving, also in Insert mode
noremap <C-S> :update<CR>
vnoremap <C-S> <C-C>:update<CR>
inoremap <C-S> <C-O>:update<CR>
- mMontu