围绕选择创建virtualedit块

时间:2012-04-07 19:20:11

标签: virtual block vim

我正在尝试创建一个允许我选择几行并在其周围创建virtualedit块的脚本;最长一行后的一列。

这是我的代码

function! VirtualEdit()
  let EndLine = line("'>")

  set virtualedit = all

  let maxlength = max(map(range(line("'<"), line("'>")), "virtcol([v:val, '$'])"))-1
  call cursor(1,maxlength+1)  
  normal "^Q".EndLine."jc<space><ESC>"

  set virtualedit = ''
endfunction

它必须做的是什么 1)控制我选择的最长线(最大长度) 2)将光标放在最长行+1列列中选择的第一行 3)比激活视觉块选择(在我的Windows PC上命令为C-Q)
4)将视觉块扩展到选择的最后一行(我的电脑上的命令向下移动=“j”)。
5)使用“c”键插入“空格”字符,使用ESC退出插入模式,以便用空格填充虚拟块列。

但是我无法找到如何在正常命令中使用变量(Endline) 我还注意到以上示例中的键和不起作用。
我错了什么?

1 个答案:

答案 0 :(得分:3)

这里有很多错误:

  1. :set不允许您在=
  2. 周围留出空格
  3. :set不接受表达式,因此set ve=''let &ve="''",而let &ve='':set ve=
  4. :normal命令也不接受表达式,它接受刚刚执行的字符串。因此:normal "^试图使用寄存器^,失败(没有这样的寄存器)并停止处理该行的其余部分。使用:execute将表达式传递给:normal
  5. :normal命令不接受<Key>语法。它们也没有viml表达式,而是"\<Key>"代替(注意:只有双引号和反斜杠)。任何人都不接受^Q语法,并且在文本文件中使用原始控制代码(由vim显示为^Q)并不是最好的主意。
  6. 请勿在没有爆炸的情况下使用:normal。大多数时候你不需要它(在这种情况下你需要用^Q替换\<C-v>,因为它是一个映射。)
  7. 不要硬编码virtualedit值。而不是

    set ve=all
    <...>
    set ve=
    

    使用

    let savedve=&ve
    set ve=all
    try
        <...>
    finally
        let &ve=savedve
    endtry
    
  8. {N}j表示“N行向下”,而不是“转到第N行”。 “转到第N行”是{N}gg{N}G
  9. 您拥有let maxlen=<...>-1以及仅使用maxlen的{​​{1}}行maxlen+1。这很奇怪。
  10. 如果你解决了这个问题,你可以继续,但你不需要调整virtualedit并完全使用:normal

    function AddSpaces()
        let [lstart, lend]=[line("'<"), line("'>")]
        if lstart>lend
            let [lstart, lend]=[lend, lstart]
        endif
        let maxcol=max(map(range(lstart, lend), "virtcol([v:val, '$'])"))
        let newlines=map(range(lstart, lend), 'printf("%-'.maxcol.'s", getline(v:val))')
        call setline(lstart, newlines)
    endfunction