Vim:内部和外部的Columnvise增量?

时间:2012-03-24 00:28:27

标签: vim editor

通过外部,我想要的解决方案不使用Vim的脚本黑客但尝试重用某些基本的* ix工具。 Vim内部的东西要求提供解决方案,以获得内部填充(如脚本)的列增量。

1           1 
1           2 
1           3 
1   --->    4
1           5
1           6
.           .
.           .

Vim有一个脚本可以进行列加法,VisIncr。它已经聚集了大约50/50的起伏,也许品尝了一点重新发明的轮子。如何在不使用此类脚本的情况下对Vim中的内容进行列增量?那么另一个问题是,如何在没有/在Vim之外的情况下对列进行增量?

最优雅,可重复使用,最好是小赢得比赛!

3 个答案:

答案 0 :(得分:3)

我认为不需要脚本,只需要一个简单的宏

 "a   yyp^Ayy

然后播放,或映射播放。

当然,我总是有可能完全误解这个问题......

答案 1 :(得分:3)

技术的最佳选择在很大程度上取决于实际情况 转型。影响至少有两点变化 实现:

  1. 要操作的行是否是文件中唯一的行?如果不, 是由上下文定义的行的范围(即它由空格分隔 线条,如段落)或是任意的,应该由 用户?

  2. 这些行是否已包含应更改的号码 是否有必要插入新文本,将文字留在线上?

  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