vim有类似于bash的'!$'的功能吗?

7

在开发过程中,我经常会做这样的事情:

:e <file>
:vsplit <the_same_file>  "reopen/re-edit with a vertical split

正如一些回答者所指出的那样,有一个更好的方法来实现这个目标::vs<CR>。假设暂时没有这种方法。

如果我在shell中打开文件,我会使用!$历史扩展来捕获上一个命令的最后一个参数,像这样:

$ echo "Hello" "stackoverflow"
Hello stackoverflow
$ echo "I'm posting on !$"
I'm posting on stackoverflow

这种扩展以及其他类似的扩展彻底重新定义了我使用命令行的方式。在vim中有类似的功能吗?我知道%代表当前文件,那么过去的命令参数呢?

我不知道有任何直接相当于bash的!$的东西。但是你可能会对使用q:感兴趣,它可以打开命令行窗口。命令行窗口显示您最后一些命令的历史记录,并允许用户使用普通的vim命令对命令进行编辑。有关更多信息,请参见:h cmdwin - Peter Rincker
我认为vim命令行没有与bash相同的功能集。在bash中,您的!$可以更短:<alt-.>。同时,如果您想在vim中实现问题开头的操作,在使用:e file打开文件后,可以按<c-w>v<c-w><c-v>,后者更容易按。 - Kent
你可以使用 :e %:e # 命令来重新编辑当前文件和上一个文件 — 这对你有帮助吗? - Jonathan Leffler
@Kent:这些方法可以帮我解决特定的问题,你提供的两个快捷方式也很有用。但是我更感兴趣的是扩展性。我已经相应地编辑了问题。 - Christopher
不,想象那些情况并不容易。因为你的例子非常琐碎且不准确(:vs<CR>),也许你能用实际例子帮助我们理解你所需要的。 - romainl
@romainl:经过一番思考,我删除了关于很容易想到例子的那行。我可以构建相当多的例子,但没有一个不具备其他实现同样功能的方法。最终,我并不是在试图声称vim 应该拥有这种能力。我只是想知道它是否有这种能力。 - Christopher
3个回答

3
据我所知,Vim没有历史扩展功能。因此,我们可以在命令行上使用Vim提供的工具,有多种选项可供选择:
- 使用“向上箭头”过滤。 - 命令行编辑命令:使用“CTRL-W”删除一个单词,使用“左箭头”和“右箭头”移动光标,使用“CTRL-B”和“CTRL-E”移动到行首/行尾。 - 使用命令行窗口“q:”(或者在命令行上按下“CTRL-F”)进行历史记录编辑。 - 找到与特定问题相适应的Vim风格的习惯用法解决方案,例如自动扩展的标记(如“%”和“#”)。
但是,如果您真的想要Bash风格的历史扩展,您可以使用命令行“<expr>”缩写轻松地实现一些简单的情况。我最常用的历史扩展项目(实际上并不经常使用)包括:
- “!!”,最近的命令行。 - “!-2”,倒数第二个命令行。 - “!*”,前一个命令行除了第一个参数之外的所有参数。 - “!$”,前一个命令行的最后一个参数。
以下是如何将它们实现为表达式缩写的方法:
cnoreabbr <expr> !!  getcmdtype() == ':' ? @: : '!*'
cnoreabbr <expr> !-2 getcmdtype() == ':' ? histget(':', -2) : '!-2'
cnoreabbr <expr> !*  getcmdtype() == ':' ? join(split(@:,'\s\+')[1:], ' ') : '!*'
cnoreabbr <expr> !$  getcmdtype() == ':' ? split(@:,'\s\+')[-1] : '!$'

以下是在Vim中如何使用您的示例:

:echo "Hello Stackoverflow"
Hello Stackoverflow
:echo "I'm posting on !$<Enter>
I'm posting on Stackoverflow

当然,如果你真的决定走这条路,对于更复杂的表达式,使用函数会更加合适。

我在想你可以像这样做一些事情。然而,我不想将其作为答案发布,主要是因为分隔符在处理字符串或函数时效果并不太好。 - FDinoff
在你的例子中,我本来期望 "Hello Stackoverflow" 被替换为最后一个参数。但显然这是不可能的,因为你正在按空格分割。 - FDinoff
它只在一些简单的情况下有效。这就是为什么我说“使用函数”的原因。但我认为提取@:并尝试解析命令行不合理(甚至不可行),最好坚持使用普通的命令行编辑。 - glts
可以做到。你只需要编写一个完整的下推自动机来进行解析。(或者找出Python实现的方法) - FDinoff
所以我再考虑了一下,这根本不合理。你需要在vim脚本中编写一个完整的解析器。这是不合理的,因为有太多需要考虑的特殊情况。你还需要考虑什么是最后一个参数?考虑使用字符串连接的:exec命令。参数是指exec之后的所有内容吗?还是仅限于最后一个被连接的字符串?我仍然认为这是可行的,但我不确定是否合理。 - FDinoff

1

使用没有参数的:vsp会将当前窗口分割。

虽然不完全符合您的要求,但我经常使用%代表当前文件名:

:e some_file
:vsp %

请看:help cmdline-special

这适用于我当前的情况,但这只是我想到的第一个重复先前参数或命令的情况。你知道任何扩展吗? - Christopher

0

杰出的VIM技巧中最佳 指出了一个历史重复起作用的特定领域,即在替换中:

" Summary of editing repeats [N]
.      last edit (magic dot)
:&     last substitute
:%&    last substitute every line
:%&gic last substitute every line confirm
g%     normal mode repeat last substitute
g&     last substitute on all lines
@@     last recording
@:     last command-mode command
:!!    last :! command
:~     last substitute
:help repeating

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接