问题
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:
:set
does not let you have spaces around=
:set
does not accept expressions, thusset ve=''
islet &ve="''"
, notlet &ve=''
which is:set ve=
.: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
.: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.- 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). Don’t hardcode
virtualedit
value. Instead ofset ve=all <...> set ve=
use
let savedve=&ve set ve=all try <...> finally let &ve=savedve endtry
{N}j
means “N lines down”, not “go to N’th line”. “Go to N’th line” is{N}gg
or{N}G
.- You have
let maxlen=<...>-1
and the on only line wheremaxlen
is used you havemaxlen+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