我要插入一个以“ 01”开头的数字。为简单起见,让我们为数字加上前缀。
方法1:手动选择所有具有相同Level的行。调用魔法,我很快就会学到。
方法2:编写一个搜索并替换,该替换将匹配具有给定级别的所有行,并且在每个匹配项中包括替换文本中的一个数字,该数字在每个匹配项中增加一个。
我在StackOverflow或其他Vim站点上也发现了类似的问题,但每个问题似乎都具有以下一个或多个问题:
插入当前行号,而不是插入一个任意的但递增的数字。
不对数字进行零补。 (这些都会导致错误
E481: No range allowed
。) /> #1 楼
与https://vi.stackexchange.com/a/818/227上的答案类似,您可以使用全局命令。它可以指示vim搜索与模式匹配的行,然后在其上执行命令。
您希望将文本添加到以“ Level N:”开头的行之前,因此我们的全局命令可能是
:g/^Level \d:/{COMMANDS}
将替换命令(正则表达式替换)用于命令
命令更有趣。我通常喜欢用正则表达式替换类似的东西,因为它很容易使用变量。 >它的工作方式
在替换命令的替换部分可以是一个表达式。
我们要做的第一件事是将变量
i
设置为起始编号。我选择了1,但任何数字都可以。 let i = 1
然后运行全局命令,该命令将我们设置为在匹配的行上执行操作。
g/^Level \d:/
使用替换命令和let命令,让全局命令插入值并增加计数器。
s/^/\=printf("%02d ", i)/ | let i = i+1
替换命令的正则表达式查找
^
行的开头,并将其替换为表达式,我们的表达式将是格式化打印的结果。像C语言一样,vim的printf带有格式设置参数。 %02d
意味着将参数转换为十进制数字d
,至少占用2个空格2
并填充0 0
。有关详细信息和其他转换选项(包括浮点格式),请参见:help printf
。我们给printf我们的计数变量i
,第一次给我们01
,第二次给我们02
,以此类推。替换命令使用它来替换行的开头,从而有效地将printf的结果插入开头。 br /> 请注意,我在d之后放置了一个空格:
"%02d "
。您没有在问题中提出要求(并且我没有看到示例输出),但我怀疑您想将数字与单词“ Level”分开。从给printf的字符串中删除空格,使插入的数字紧靠Level中的L。最后,每次替换后
let i = i + 1
都会增加我们的计数器。通常可用于用任意功能数据替换与其他条件匹配的行的部分。与替换类似,我们将使用global进行匹配,但是将代替用户使用正则表达式替换正则表达式,而是执行一系列操作。问题示例
:let i = 1 | g/^Level \d:/s/^/\=printf("%02d ", i)/ | let i = i+1
如何工作
使用的值与替代项非常相似(我们仍在使用printf格式化我们的数字以使其填充0 2位数字),但操作不同。我们构造了一个字符串,该字符串将“ normal!I”与我们的数据结合在一起,第一次将是“ normal!I01”,第二次将是“ normal!I02”,等等。操作就像在普通模式下一样。在此示例中,我们的常规命令是
:help :exe
,它将插入到行的开头。如果我们使用了normal
,它将删除该行,而I
将在匹配的行之后打开一个新行。就像您在正常模式下自己键入dd
(或其他任何操作)一样。我们在o
之后使用I
来确保没有映射妨碍我们。请参阅!
。然后插入的是我们的printf的值,如第一个使用替代的示例中一样。该方法比正则表达式更奇特,因为您可以执行
normal
之类的操作,该操作将转到文本:help :normal
的开头,向前移动2个单词execute "normal! ^2wy" . i . "th$p"
,拉动直到第i个“ h”字符^
,然后移至行尾2w
,然后粘贴y" . i . "th
。这几乎就像运行宏一样,但是实际上并没有用完寄存器,而是可以合并任何表达式中的字符串。我发现这非常强大。每个级别都有自己的计数器的方法
您可能希望每个级别都有自己的计数器。如果您提前知道最大级别数,则可以执行以下操作(添加额外的代码以查找最大级别可能并不难,但是会使此答案变得太长。这会变得很长)。 br />
首先,让我们释放i,以防万一我们已经将其用作整数。我们无法将i转换为列表,我们必须以这种方式创建它。您在问题中显示了2,但假设其中有10个是有趣的。由于列表索引是基于0的,并且我不想像您的列表那样更正基于1的索引,因此我们将只创建足够的元素(11),并且永远不要使用0索引。 br />
接下来,我们需要一种获取级别编号的方法。幸运的是,替代函数也可以使用,因此我们将其命名为行并提取级别号
$
因为我现在是11个
p
的列表(每个索引都是我们的级别),我们现在可以调整以上任一示例以使用此替换的结果:通过替换命令:
:let i = 1 | g/^Level \d:/execute "normal! I" . printf("%02d ", i) | let i = i+1
通过常规命令:
:unlet! i
示例输入:
:let j = 0
:let i = []
:while j < 11 | let i += [1] | let j += 1 | endwhile
示例输出:
:unlet! i | unlet! j | let j = 0 | let i = [] | while j < 11 | let i += [1] | let j += 1 | endwhile
:g/^Level \d:/let ind=str2nr(substitute(getline("."), "^Level \(\d\):.*", "\=submatch(1)", "")) | s/^/\=printf("%02d ", i[ind])/ | let i[ind] += 1
评论
哇,非常百科。我只阅读了第一部分,感觉比过去几年我从中学到了更多关于Vim的知识。这种答案使Stack Exchange优于一般的问答站点,并且显示了具有Vim特定SE的好处。
–hippietrail
2015年4月30日,下午3:48
#2 楼
您可以通过录制宏来处理它。从原始文件开始,在第一个实例前添加数字。现在您要记录从这一点开始的动作。01
yiw
在寄存器q中启动宏/> qq/^Level 1<CR>P<C-A>A<space><esc>0yiwq
搜索以“ Level 1”开头的行qq
在光标之前粘贴(包含您的数字)/^Level 1<CR>
递增数字P
在数字后面插入空格<C-A>
移至开头A<space><esc>
取消当前数字0
结束宏,然后使用
yiw
重复此宏。评论
是
–hippietrail
2015年4月29日在2:43
它是Control + a。在vim中,它应该增加一个数字。如果您已将键绑定更改为执行Windows操作而不是执行Vim操作,则您将无法执行人们在此处发布的大多数操作。
–jecxjo
2015年4月29日在2:45
由于有人的无限智慧,Windows的Vim版本没有附带不同的绑定。我只是使用香草的现成绑定。我回想起(-:
–hippietrail
2015年4月29日在2:47
并非如此,我的Windows安装具有正常的vim绑定。您是否可能安装了其他人的vim版本?还是可以在“简易”模式下运行vim?我相信Windows会以普通和简易模式选项安装桌面图标。
–jecxjo
15年4月29日在2:50
不,这是因为Windows中的默认安装会加载mswin.vim。如果您创建自己的vimrc而不加载mswin.vim,则将获得正常的vim绑定。我为所有安装(Linux,Mac和Windows)保留一个vimrc,从不处理mswin.vim。有关此问题的更多信息,请参见stackoverflow.com/questions/289681/…
–jecxjo
2015年4月29日在2:53
#3 楼
您可以从https://stackoverflow.com/a/4224454/15934进行构建,以零填充您的数字。 ,我将使用一对函数和一个命令:" A reminder: how to start numbers at the first line
:'<,'>s/^\s*\zs/\=(line('.') - line("'<")+1).'. '
然后,选择您的行并键入
:PrependNumber
(您将看到:'<,'>PrependNumber
。命令采用可选参数:将在其之前插入数字的模式] 评论
但是line(“。”)的意思不是“使用当前行号”吗?那是我的问题1.我可以找到以前的答案。
–hippietrail
2015年4月29日在8:19
是的。这就是为什么我减去范围中第一行的行号。
–卢克·赫米特(Luc Hermitte)
15年4月29日在8:20
啊,好的,我还没有测试过,因为我什至不记得如何在Vim中输入脚本...必须首先阅读(-
–hippietrail
2015年4月29日在8:23
在Windows下,将代码复制粘贴到$ HOME / vimfiles / plugin / whatevernameyouwish.vim中。或者,如果您愿意(甚至是第一次),甚至是$ HOME / _vimrc(Windows文件名)。如果不确定计算机上的$ HOME是什么,请询问vim它认为它是什么->:echo $ HOME
–卢克·赫米特(Luc Hermitte)
2015年4月29日在8:27
如果vim脚本已正确安装在正确的目录({rtp} / plugin,或{rtp} / ftplugin / {filetype} / ftplugin(针对特定于文件类型的插件)中,则甚至不需要:source。 :source是我们十年半前不得不玩的东西。
–卢克·赫米特(Luc Hermitte)
2015年4月29日在8:35
评论
我能想到的最佳标签不存在:选择和范围,因此可以随时重新标签或创建这些标签之一。这个插件不是解决您问题的完整解决方案,但是对于添加数字列非常有用:VisIncr。文档在这里。 FWIW。