如何在 Vim 中为命令创建别名?

Vim 是我编程时首选的文本编辑器,因此我总是遇到一个特别烦人的问题。

通常,当我需要快速保存缓冲区并继续执行其他杂项任务时,我会执行典型的

:w

然而,我总是ーー似乎有超过50% 的时间是这样ーー设法将 :w资本化。自然地,Vim 对我大喊大叫,因为 W是一个无效的命令:

E492: Not an editor command: W

我的问题是如何能一个 别名冒号-Vim 中的命令。特别是,你能举例说明如何别名 Ww

我知道的过程,以 地图钥匙的某些 命令,但这不是我要找的。

80838 次浏览

通过补充搜索,我发现有人问了几乎相同的 有个问题我。

:command <AliasName> <string of command to be aliased>

会有用的。

请注意,正如 理查指出的,用户命令必须以大写字母开头。

也许您想映射一个函数键(F1。.F12)至: w?然后把这个放进你的。Vimrc:

noremap  <f1> :w<return>
inoremap <f1> <c-o>:w<return>

(插入模式下的 ctrl-o 暂时切换到正常模式)。

若要保持完成不变,请尝试使用

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更安全。

最好的解决方案是使用 写一个自定义函数来处理只发生在命令栏开头的缩写。

为此,添加以下 vimrc 文件或其他任何文件。

" 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")

假设您想在 gvim 中为 tabnew 命令添加别名。您可以简单地在。Vimrc 文件(如果不在主文件夹中,则创建一个)

cabbrev t tabnew

我发现将 ;键映射到 :将是一个更好的解决方案,并且将使您更有效地输入其他命令。

nnoremap ; :
vnoremap ; :

最安全和最简单的是一个插件,如 Cmdalias.vim或我最近更新它的 Vim 化名考虑

  • 前面的空格或修饰符,如 :sil(ent)(!):redi(r),
  • 范围修饰符,例如用于当前视觉选择的 '<,'>,
  • 转义特殊字符,如引号,和
  • 检查所选别名是否是有效的命令行缩写。

我认为@ZyX 的回答很棒,但是如果您正在使用新版本的 nevim (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://")

N.b.如果从 .vim文件而不是 .lua文件使用它,则需要在函数调用前加上 lua(即 lua SetupCommandAlias("pg", "postgres://"))的前缀。