Create virtualedit block around selection

♀尐吖头ヾ 提交于 2019-12-11 16:24:02

问题


I'm trying to create a script what permits me to select a few lines and create a virtualedit block around it; 1 column after the longest line.

This is my code

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

What it must do is
1) Control the longest line in my selection (maxlength).
2) Put the cursor on the first line in the selection at the column of the longest line +1 column.
3) Than Activate Visual Block selection (on my windows pc the command is C-Q)
4) Extend the visual block till the last line in the selection (the command on my pc for moving down = "j").
5) Than use the "c" key to insert a "space" character and ESC to exit the insert mode in order to fill the virtual block column with spaces.

However I can't find out how to use a variable (Endline) in a normal command.
I noted also that keys as and don't work in my above example.
What did I wrong?


回答1:


You have many errors here:

  1. :set does not let you have spaces around =
  2. :set does not accept expressions, thus set ve='' is let &ve="''", not let &ve='' which is :set ve=.
  3. :normal command also does not accept expressions, it accepts strings that are just executed. Thus :normal "^ is trying to use register ^, fails (no such register) and stops processing the rest of the line. Use :execute to pass expressions to :normal.
  4. :normal command does not accept <Key> syntax. Neither do viml expressions, they have "\<Key>" instead (note: only double quotes and with backslash). ^Q syntax is not accepted by anybody and having raw control codes (displayed by vim as ^Q) inside a text file is not the best idea.
  5. Don’t use :normal without a bang. Most of time you don’t need it (you need to replace ^Q with \<C-v> in this case though because it is a mapping).
  6. Don’t hardcode virtualedit value. Instead of

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

    use

    let savedve=&ve
    set ve=all
    try
        <...>
    finally
        let &ve=savedve
    endtry
    
  7. {N}j means “N lines down”, not “go to N’th line”. “Go to N’th line” is {N}gg or {N}G.
  8. You have let maxlen=<...>-1 and the on only line where maxlen is used you have maxlen+1. It is strange.

If you fix this you can proceed, but you don’t need adjusting virtualedit and using :normal at all:

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


来源:https://stackoverflow.com/questions/10057562/create-virtualedit-block-around-selection

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!