0

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

这是我的代码

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) 控制我的选择中最长的线 (maxlength)。
2)将光标放在选择中的第一行最长行+1列的列。
3)比激活可视块选择(在我的windows pc上,命令是CQ)
4)将可视块扩展到选择的最后一行(我的pc上用于向下移动的命令=“j”)。
5)然后使用“c”键插入一个“空格”字符并使用ESC退出插入模式,以便用空格填充虚拟块列。

但是我不知道如何在普通命令中使用变量(Endline)。
我还注意到,在我上面的示例中,密钥作为并且不起作用。
我做错了什么?

4

1 回答 1

3

你这里有很多错误:

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

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

    采用

    let savedve=&ve
    set ve=all
    try
        <...>
    finally
        let &ve=savedve
    endtry
    
  7. {N}j表示“向下 N 行”,而不是“转到第 N 行”。“转到第 N 行”是{N}gg{N}G
  8. 您拥有let maxlen=<...>-1并且唯一maxlen使用您的线路maxlen+1。它很奇怪。

如果你解决了这个问题,你可以继续,但你根本不需要调整 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
于 2012-04-07T19:49:26.440 回答