通过外部,我想要的解决方案不使用Vim的脚本黑客但尝试重用某些基本的* ix工具。 Vim内部的东西要求提供解决方案,以获得内部填充(如脚本)的列增量。
1 1
1 2
1 3
1 ---> 4
1 5
1 6
. .
. .
Vim有一个脚本可以进行列加法,VisIncr。它已经聚集了大约50/50的起伏,也许品尝了一点重新发明的轮子。如何在不使用此类脚本的情况下对Vim中的内容进行列增量?那么另一个问题是,如何在没有/在Vim之外的情况下对列进行增量?
最优雅,可重复使用,最好是小赢得比赛!
答案 0 :(得分:3)
我认为不需要脚本,只需要一个简单的宏
"a yyp^Ayy
然后播放,或映射播放。
当然,我总是有可能完全误解这个问题......
答案 1 :(得分:3)
技术的最佳选择在很大程度上取决于实际情况 转型。影响至少有两点变化 实现:
要操作的行是否是文件中唯一的行?如果不, 是由上下文定义的行的范围(即它由空格分隔 线条,如段落)或是任意的,应该由 用户?
这些行是否已包含应更改的号码 是否有必要插入新文本,将文字留在线上?
由于没有信息可以回答这些问题,我们将在下面尝试 构建灵活的解决方案。
一般解决方案是在行的开头操作替换 在用户指定的范围内。视觉模式可能是最简单的方式 选择任意范围的线,所以我们在这里假设边界 范围由视觉选择定义。
:'<,'>s/^\d\+/\=line(".")-line("''")+1/
如果需要对缓冲区中的每一行进行编号,则命令可以是 简化如下。
:%s/^\d\+/\=line('.')/
在任何情况下,如果数字应该仅插入到数字的开头
线条(没有修改已经存在的线条),人们可以改变
模式从^\d\+
到^
,并可选择添加分隔符:
:'<,'>s/^\d\+/\=(line(".")-line("''")+1).' '/
或
:%s/^/\=line('.').' '/
分别
对于基于命令行工具的解决方案,可以考虑使用流 Sed等编辑或AWK等文字提取和报告工具。
要使用Sed为文件中的每一行编号,请运行命令
$ sed = filename | sed 'N;s/\n/ /'
要在AWK中执行相同操作,请使用命令
$ awk '{print NR " " $0}' filename
可以很容易地修改以限制特定行范围的编号 满足某种条件。例如,以下命令编号 第2到第8行。
$ awk '{print (2<=NR && NR<=8 ? ++n " " : "") $0}' filename
感兴趣的是如何将命令与链接的脚本中的命令相似 问题陈述已实施,可以使用以下命令作为 参考。
vnoremap <leader>i :call EnumVisualBlock()<cr>
function! EnumVisualBlock() range
if visualmode() != "\<c-v>"
return
endif
let [l, r] = [virtcol("'<"), virtcol("'>")]
let [l, r] = [min([l, r]), max([l, r])]
let start = matchstr(getline("'<"), '^\d\+', col("'<")-1)
let off = start - line("'<")
let w = max(map([start, line("'>") + off], 'len("".v:val)'))
exe "'<,'>" 's/\%'.l.'v.*\%<'.(r+1).'v./'.
\ '\=printf("%'.w.'d",line(".")+off).repeat(" ",r-l+1-w)'
endfunction
答案 2 :(得分:1)
如果您希望将1 1 1 1 ...
更改为1 2 3 4 ...
。 (这些数字应该在不同的行上。)
:let i=1 | g/1/s//\=i/g | let i+=1
如果某些1 1 1 1 ...
位于同一行:
:let g:i = 0
:func! Inc()
: let g:i+=1
: return g:i
:endfun
:%s/1/\=Inc()/g