如何映射d [count] d?


18

注意:这不是“ d3fg”命令如何工作的重复项请在投票关闭前阅读它!

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

d3j很简单:将d操作员应用于3j运动,

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

d3d 看起来应该很简单,它将d运算符应用于...,但是什么是3d?这不是一个议案。如果您3d自己输入,Vim会将其视为一个运算符,然后是一个运算符,并耐心等待进一步的输入。

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

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

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

编辑:这是一个文本对象吗?:h text-objects不包括在“文本对象选择命令”列表中,但随后它确实包含DD在“从小分组,以大物”删除列表。并d2aw确实删除了光标下的单词和随后的单词。另一方面,c2d什么也不做。

*我确定必须提到它们,但是我找不到。我已经阅读了:help deleting:help motion.txt并尝试:helpgrep dNd了从1到9的所有N值


2
我认为最后d的确认。因此与相同d3<CR>y3y并且c3c也能以相同的方式工作...尽管在Vim:help,vi(1),nvi(1)或POSIX规范中,我都找不到关于此的任何文档...它在vinvibtw 中的行为相同。
马丁·图尔诺伊

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

Answers:


28

操作员待定模式

键入操作者(等之间dcgU)以及运动(如wi}/foo<CR>),Vim的是在操作符等待模式。您可以使用:omap和创建映射:onoremap

在我的示例中,我将映射待处理的操作符dw。这是一个随机选择,因为我不知道您实际想要使用它什么。

创建一个omap

让我们为d操作员挂起模式创建一个映射。我假设我们在这里(例如您的.vimrc)中编写VimScript ,所以我将省略前导:s。

onoremap d w

这使dd行为像dw。这也使d[count]d行为像d[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串联运算符来构建字符串.


您的实际用例可能会与我在此处概述的用例有所不同,但是希望这可以帮助您顺利进行。

Vimming!


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

1
实际上,出于第二种想法,我现在接受这一点。您已经解释了如何创建这样的映射以及它如何在后台运行,这是我要求的两件事。
Rich
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.