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

     2023-02-23     172

关键词:

【中文标题】如何在 Vim 中为命令创建别名?【英文标题】:How to create an alias for a command in Vim? 【发布时间】:2011-04-22 04:15:37 【问题描述】:

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

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

:w

但是,我总是——似乎超过 50% 的时间——设法利用:w。很自然,Vim 会对我大喊大叫,因为 W 是一个无效命令:

E492: Not an editor command: W

我的问题是如何在 Vim 中为冒号命令别名。特别是,您能否举例说明如何将W 别名为w

我知道将键映射到某些命令的过程,但这不是我想要的。

【问题讨论】:

Can I (re-) map commands in vim?的可能重复 为了避免:W,您可以映射一个键来执行保存。如果你习惯了一些使用 Ctrl-s 保存的程序,那么 $VIM/mswin.vim 中有这些映射:" Use CTRL-S for saving, also in Insert modenoremap <C-S> :update<CR>vnoremap <C-S> <C-C>:update<CR>inoremap <C-S> <C-O>:update<CR> 关于 Vi Stack 交换的类似问题:vi.stackexchange.com/q/2665/7244 【参考方案1】:

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

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

【讨论】:

这个答案对我来说是最安全最可靠的。 如果您使用推荐的解决方案,请注意以下两个命令都将作为较低的命令工作,根据实际缓冲区内容和 VIM 设置可能会出现意外结果::%s/W/foo/g&lt;CR&gt; :%s/w/foo/g&lt;CR&gt; 实际上,这意味着 W 将被替换 anywhere 在命令栏中,包括例如在搜索中,因此 s/W foo/bar/g 将被替换进入 s/w foo/bar/g。这会很快变得烦人。请参阅我的答案以获得全面的解决方案。 绝对的;这是一个可怕的想法。您应该永远永远永远这样做。 :cnoreabbrev &lt;expr&gt; W getcmdtype()==':'&amp;&amp;getcmdline()=~#'^W'?'w':'W'【参考方案2】:

通过补充搜索,我发现有人问的question和我几乎一样。

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

会成功的。

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

【讨论】:

使用 :command 是很好的解决方案。 :cnoreabbrev 不理解 cmd1|cmd2,:command 可以。 一个不那么容易混淆的写法是:command AliasName string of command to be aliased 这不会处理/转发任何command 参数,例如-nargs-complete 等。 :Q!:W! 怎么样? 直言不讳:将:command W w 放入.vimrc 文件中。【参考方案3】:

我发现将; 键映射到: 会是一个更好的解决方案,并且可以提高您键入其他命令的效率。

nnoremap ; :
vnoremap ; :

【讨论】:

这是 vim 的最佳技巧。我现在已经习惯了,每次遇到正常行为时,我都需要尝试几次才能重新训练自己的思想。 这不是问题的答案。 @Flimm 不,但它使 OP 的问题消失了。 当使用tf 时,通常可以使用; 转到下一个匹配项。即使您将分号映射到冒号,也可以安全地映射另一种方式。不会有别名循环。 nnoremap : ;【参考方案4】:

最好的解决方案是使用writing a custom function 处理仅出现在命令栏开头的缩写。

为此,请在您的 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')

一些useful abbreviations from the source material 我在哪里找到了这些东西:

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() 做同样的事情。【参考方案5】:

假设你想在 gvim 中为 tabnew 命令添加别名。您只需在 .vimrc 文件中键入以下命令(如果不在主文件夹中,则创建一个)

cabbrev t tabnew

【讨论】:

这将导致:saveas t example之类的命令被:saveas tabnew example替换【参考方案6】:

也许您想将您的一个功能键 (F1..F12) 映射到 :w ?然后把它放到你的 .vimrc 中:

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

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

【讨论】:

【参考方案7】:

最安全和最简单的是插件,例如cmdalias.vim 或我最近更新的vim-alias 考虑到

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

【讨论】:

【参考方案8】:

我认为@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://")

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

【讨论】:

在 Vim 编辑器中为 NERDTree 创建命令快捷方式

】在Vim编辑器中为NERDTree创建命令快捷方式【英文标题】:CreateacommandshortcutforNERDTreeinVimeditor【发布时间】:2011-09-2123:55:41【问题描述】:我想在命令行上为NERDTree创建一个缩写。我觉得每次我想启用它时都必须写:NERDTree很烦人。... 查看详情

在python中为打印设置命令别名?

...一个别名,如下所示:aliase=echosetaliase="echoblah"我想知道如何在Python中做同样的事情。我知道你可以给类别名,但是当我尝试给命令(例如print语句)一个别名时,我得到一个错误:>>&g 查看详情

如何在css或sass中为类名起别名

】如何在css或sass中为类名起别名【英文标题】:howtoaliasclassnameincssorsass【发布时间】:2012-10-3109:28:02【问题描述】:我可以为css类创建别名吗?我正在使用这种很棒的字体,并且我正在尝试为某些图标类创建别名。这样.icon-globe... 查看详情

在 Windows 7 中为 composer 创建一个工作别名

...:19:09【问题描述】:我不确定这是路径别名,但我不确定如何在Windows7中执行此操作。当我运行PHP作曲家时,它会按预期显示所有作曲家选项。但是,如果我尝试像一样运行C:\\>phpcomposer.pharcomposerglobalu 查看详情

如何在c中为函数提供别名[重复]

】如何在c中为函数提供别名[重复]【英文标题】:Howtogivealiasforafunctioninc[duplicate]【发布时间】:2016-12-0507:00:21【问题描述】:问题是这样的:我有一个名为ADD_TWO(int,int);的函数,现在在程序中,我想创建它的别名,保持之前的函... 查看详情

如何在 C# 中为类名起别名,而不必向使用该类的每个文件添加一行代码?

】如何在C#中为类名起别名,而不必向使用该类的每个文件添加一行代码?【英文标题】:HowdoIaliasaclassnameinC#,withouthavingtoaddalineofcodetoeveryfilethatusestheclass?【发布时间】:2010-09-1915:27:42【问题描述】:我想为类名创建一个别名。... 查看详情

在 Spring Data 中为同一 QueryDSL 路径创建多个别名

】在SpringData中为同一QueryDSL路径创建多个别名【英文标题】:CreatingmultiplealiasesforthesameQueryDSLpathinSpringData【发布时间】:2017-05-3018:08:45【问题描述】:我有一个扩展QuerydslBinderCustomizer的通用SpringData存储库接口,允许我自定义查... 查看详情

如何在查询中为 eloquent 模型起别名

】如何在查询中为eloquent模型起别名【英文标题】:Howtoaliaseloquentmodelsinaquery【发布时间】:2016-05-2418:16:11【问题描述】:你如何给一个雄辩的模型起别名?例如,如果我有如下SQL查询:SELECTone.name,one.id,one.nameASsortkey1,CAST(NULLASUNSI... 查看详情

我可以在 Python 中为继承的方法创建别名吗?

】我可以在Python中为继承的方法创建别名吗?【英文标题】:CanIcreateanaliastoaninheritedmethodinPython?【发布时间】:2017-03-3002:21:03【问题描述】:我的Python程序中有一个非常复杂的类层次结构。该程序有许多工具,要么是模拟器,要... 查看详情

如何分别创建多个 Flutter 版本别名以在 Windows PC 的命令提示符中使用 [关闭]

】如何分别创建多个Flutter版本别名以在WindowsPC的命令提示符中使用[关闭]【英文标题】:HowtocreateMultipleFlutterversionAliasestouseincommandpromptinWindowsPCseparately[closed]【发布时间】:2021-02-1405:33:09【问题描述】:我有2个版本的颤振1是最... 查看详情

为啥 hibernate 在不同的 JVM 实例中为相同的查询创建不同的列别名?

】为啥hibernate在不同的JVM实例中为相同的查询创建不同的列别名?【英文标题】:WhydoeshibernatecreatedifferentcolumnaliasesforsamequeryindifferentJVMinstances?为什么hibernate在不同的JVM实例中为相同的查询创建不同的列别名?【发布时间】:2016... 查看详情

如何在 Python 中为类型定义别名以进行类型提示

】如何在Python中为类型定义别名以进行类型提示【英文标题】:HowtodefineanaliasforatypeinPythonfortypehinting【发布时间】:2018-03-2310:01:45【问题描述】:如何为类型定义别名以使用类型提示:importtypingtypeTickerstr#Howtodothis?Iusedgolangnotation... 查看详情

如何在 MySQL 中为数据库起别名?

】如何在MySQL中为数据库起别名?【英文标题】:HowdoIaliasadatabaseinMySQL?【发布时间】:2010-11-2103:25:58【问题描述】:我正在寻找一种在MySQL中为数据库设置别名的方法。原因是能够在不关闭系统的情况下重命名实时生产数据库。... 查看详情

如何在 Python 中为不和谐的机器人创建重新加载命令?

】如何在Python中为不和谐的机器人创建重新加载命令?【英文标题】:HowwouldImakeareloadcommandinPythonforadiscordbot?【发布时间】:2017-04-0117:39:37【问题描述】:我正在尝试弄清楚如何创建一个命令来“重新加载”DiscordBot的命令,并允... 查看详情

如何在 angular-cli 中为长路径制作“别名”?

】如何在angular-cli中为长路径制作“别名”?【英文标题】:Howtomakean“alias”foralongpathinangular-cli?【发布时间】:2017-05-2106:48:48【问题描述】:我正在使用AngularCLI。如何转换路径:importAppConfig,AppConfigInterfacefrom\'../../../app.config\';... 查看详情

linux别名,yum源,vim使用技巧(代码片段)

本篇主要讲述:1 命令的别名2 软件包管理3 配置永久主机名 4 使用vim创建/修改文件 1、命令的别名alias简化复杂命令的输入[root@A/]#aliasmyls=‘ls-lh‘#定义别名等号两边不能有空格[root@A/]#myls/root/[root@A/]#alias#... 查看详情

如何在 java 中为 Servlet 上下文添加别名?

】如何在java中为Servlet上下文添加别名?【英文标题】:HowdoIaddaliasestoaServletContextinjava?【发布时间】:2012-09-2418:49:56【问题描述】:我有一个在Tomcat下运行的servlet。我需要提供一些文件,我想我们可以从外部(到WEB-APP)目录中... 查看详情

如何在 Perl/CGI 中为 Web 应用程序创建持久的 shell 命令会话?

】如何在Perl/CGI中为Web应用程序创建持久的shell命令会话?【英文标题】:HowtocreateapersistantshellcommandsessioninPerl/CGIforawebapp?【发布时间】:2013-09-0317:31:56【问题描述】:我正在使用前端终端模拟器(http://terminal.jcubic.pl/)。我在后端... 查看详情