Я однажды написал функцию, которая может делать это, не касаясь регистров или положения курсора:
function s:F.map.getvrange(start, end)
let [sline, scol]=a:start
let [eline, ecol]=a:end
let text=[]
let ellcol=col([eline, '$'])
let slinestr=getline(sline)
if sline==eline
if ecol>=ellcol
call extend(text, [slinestr[(scol-1):], ""])
else
call add(text, slinestr[(scol-1):(ecol-1)])
endif
else
call add(text, slinestr[(scol-1):])
let elinestr=getline(eline)
if (eline-sline)>1
call extend(text, getline(sline+1, eline-1))
endif
if ecol<ellcol
call add(text, elinestr[:(ecol-1)])
else
call extend(text, [elinestr, ""])
endif
endif
return text
endfunction
Это называется так:
let [sline, scol, soff]=getpos("'<")[1:]
let [eline, ecol, eoff]=getpos("'>")[1:]
if sline>eline || (sline==eline && scol>ecol)
let [sline, scol, eline, ecol]=[eline, ecol, sline, scol]
endif
let lchar=len(matchstr(getline(eline), '\%'.ecol.'c.'))
if lchar>1
let ecol+=lchar-1
endif
let text=s:F.map.getvrange([sline, scol], [eline, ecol])
Обратите внимание, что в этот момент у вас будет список строк в тексте: одна из причин, по которой я написал эту функцию, заключается в способности сохранять значения NULL в файле. Если вы придерживаетесь какого-либо решения, которое возвращает текст в регистр, все значения NULL будут заменены на новые строки, и все новые строки будут также представлены как новые строки. В выходных данных функции getvrange NULL представлены как новые строки, а новые строки представлены различными элементами: между каждым элементом списка есть NL, как и при выводе getline(start, end)
.
Эту функцию можно использовать только для получения строк для символьного выбора (так как для этого гораздо проще, а для блоков я перебираю строки и такая функция не нужна. Есть также функции для удаления заданного диапазона (без касания регистров) и вставка текста в заданную позицию (без касания регистров или курсора).