N.B.这不是“ d3fg”命令如何工作的重复项?请在投票关闭之前阅读它!

我为使像大型删除之类的小型删除工作而陷入僵局。我遇到的问题是我不知道如何重新映射d3d之类的命令。实际上,我什至无法理解它们的工作原理,也无法在Vim的帮助下找到它们。*

d运算符应用于3j运动,

3dd也很简单:它以3的“ count”运行dd命令。

d运算符应用于…但是3d是什么?这不是一个议案。如果单独输入3d,Vim会将其视为一个运算符,然后再耐心等待进一步的输入。

您不能将运算符应用于其他运算符。 dd在帮助中并未描述为两个运算符的序列。这是一个单独的两键命令。 (比照dc,它什么也不做。)

对于需要两次击键的命令,计数的位置也不太灵活:2gj将光标向下移动两个屏幕-line,但是g2j会完全放弃前两个按键,并将光标向下移动一行。

它如何工作?这只是Vim内部代码中的一种特殊情况吗?有什么方法可以创建d[count]d映射?

编辑:它是文本对象吗? :h text-objects不在“文本对象选择命令”列表中包括它,但随后在“从小到大对象分组”的删除列表中确实包括了dd。 d2aw确实删除了光标和后面的单词。另一方面,c2d却不执行任何操作。

*我敢肯定它们的某些提及必须存在,但我找不到。我已经读过:help deleting:help motion.txt,并尝试过:helpgrep dNd来获取1–9中所有N的值。

评论

我认为最后一个d可以作为确认。因此与d3 相同。 y3y和c3c的工作原理相同……尽管在Vim:help,vi(1),nvi(1)或POSIX规范中,我都找不到关于此的任何文档。 vi和nvi btw。

在某种程度上,dd与d_相同。 _将光标移到第([count] -1)行的第一个非空白行,但是它是行方向的,因此与运算符配对时,它会在整行上进行操作。因此,可以在两个ds之间出现一个计数。

#1 楼

在输入运算符(例如dcgU)和动作(例如wi}/foo<CR>)之间,Vim处于运算符待定模式。您可以使用:omap:onoremap为此创建映射。在我的示例中,我将映射待处理的d映射到w。这是一个随机选择,因为我不知道您实际上想将其用于什么。

创建omap

让我们在操作员待定模式下为d创建映射。我假设我们在这里编写VimScript(例如在您的.vimrc中),因此我将省略前导: s。

onoremap d w


这使dd的行为类似于dw。这也使d[count]dd[count]w一样起作用。但是我敢打赌,您不想影响dd的行为(即,不提供[count])。

表达式映射

表达式映射使您可以评估要生成的VimScript表达式映射的右侧。该表达式应计算为字符串。表达式映射用<expr>关键字表示。Vim还具有一些内置变量,这些变量在不同的时间填充,通常在映射期间很有用。其中之一是v:count,它是提供给操作员或动作的[count]

将它们放在一起。如果未提供[count],则v:count将为0。我们可以告诉映射在这种情况下只使用d

onoremap <expr> d v:count == 0 ? 'd' : 'w'


现在dd的行为类似于默认值(删除一行),但是d[count]d的行为类似于d[count]w。太酷了!

限制它在d运算符之后使用。

您可能会注意到一些问题。现在,cd的行为也类似于cw。这可能不是问题,但是出于完整性考虑,让我们对其加以限制,使其仅在d运算符之后起作用。

Vim还有另一个变量v:operator,其中包含最近使用的运算符。在做任何特殊操作之前,还要检查一下。

onoremap <expr> d (v:count == 0 \|\| v:operator != 'd') ? 'd' : 'w'


注意:由于:map命令可以与|链接在一起,因此我们必须在此处的表达式中对其进行转义。因此,逻辑OR运算符||变为\|\|

很酷,因此cdc[count]d像以前一样无所事事。这样很好,以便其他插件可以定义cd

我不想只删除一些其他动作

如果要将d[count]d映射到完全不同的对象,则没有

当您在“普通”模式下键入命令时,如果您错误地开始键入命令,可以按<Esc>取消该命令。这同样适用于您的映射。

d[count]d将当前行更改为[count]是什么。

onoremap <expr> d (v:count == 0 \|\| v:operator != 'd') ? 'd' : '<Esc>cc' . v:count . '<Esc>'


映射的最后一部分是VimScript表达式:<Esc>cc' . v:count . '<Esc>'。用<Esc>取消挂起的d命令,然后用cc更改当前行,用v:count键入[count]的值(在“插入”模式下),然后用<Esc>返回“普通”模式。请注意,我们在这里使用VimScript串联运算符.构建字符串。


您的实际用例可能与我在此处概述的用例有所不同,但是希望帮助您使球滚动。

祝您玩得开心!

评论


好答案!已投票。我在问题开始时确实链接了我的用例(也在vi.SE上),但我想您一定错过了它。我基本上需要执行:omap d d(!),但是不幸的是,由于我对d的映射设置了自定义操作符功能,因此实际上未达到操作符待定模式。希望有可能进行调整以使d3d正常工作。 (如果您有任何想法,请告诉我,或者如果愿意,可以随时为其他问题提供完整的解决方案。)如果我无法很快解决,我将接受并提出另一个更具体的问题。谢谢!

–丰富
15年3月14日在8:22



实际上,出于第二种想法,我现在接受这一点。您已经解释了如何创建这样的映射以及它如何在后台运行,这是我问的两件事。

–丰富
15年3月14日在8:51