Получить текущую строку в визуальном режиме из функции - PullRequest
3 голосов
/ 02 декабря 2010

У меня есть простой скрипт vim, который берет визуальный блок текста и сохраняет его в виде списка. Проблема с функцией VtoList() заключается в том, что она выполняется после , курсор возвращается к началу визуального блока, а не до него. Из-за этого у меня нет возможности получить строку, где заканчивается визуальный блок.

nn <F2> :call VtoList()<CR>

func! VtoList()
    firstline = line('v')  " Gets the line where the visual block begins
    lastline = line('.')   " Gets the current line, but not the one I want.
    mylist = getline(firstline, lastline)
    echo mylist
endfunc

Проблема с line('.'). Он должен вернуть текущую строку курсора, но перед вызовом функции курсор уже вернулся в начало визуального блока. Таким образом, я получаю только одну строку вместо диапазона строк.

Я собрал решение, которое устанавливает отметку каждый раз, когда пользователь нажимает V , и устанавливает другую отметку перед вызовом функции.

nnoremap V mV
nnoremap <F2> mZ:call VtoList()<CR>

Функция работает нормально, если я заменю line('v') и line('.') на line("'V") и line("'Z"), но я хочу избежать этого решения, если смогу, потому что оно может конфликтовать с отображениями пользователя.

Есть ли способ получить текущую строку визуального блока внутри функции до того, как курсор вернется в начало визуального блока?

1 Ответ

4 голосов
/ 02 декабря 2010

Не используйте :, используйте <expr>:

function! s:NumSort(a, b)
    return a:a>a:b ? 1 : a:a==a:b ? 0 : -1
endfunction
func! VtoList()
    let [firstline, lastline]=sort([line('v'), line('.')], 's:NumSort')
    let mylist = getline(firstline, lastline)
    echo mylist
    return ""
endfunc
vnoremap <expr> <F2> VtoList()

Обратите внимание на другие изменения: let (вы забыли это), sort (строка, где начинается выделение, может быть после строки, где заканчивается выделение), vnoremap (line("v") работает только в визуальном режиме), return (expr mappings возвращаемое значение выполнено, но оно вам не нужно, вам нужны только побочные эффекты). Вы можете заменить вторую строку на

    if mode()=~#"^[vV\<C-v>]"
        let [firstline, lastline]=sort([line('v'), line('.')], 's:NumSort')
    else
        let [firstline, lastline]=sort([line("'<"), line("'>")], 's:NumSort')
    endif

Причина, по которой ваше решение не работает, заключается в том, что когда в отображении появляется :, вы немедленно выходите из визуального режима и переходите в командный режим. line("v") работает только в визуальном режиме.

Другое примечание: vnoremap {lhs} : создаст командную строку, уже заполненную '<,'>. Возможно, вы добавили range к определению функции и используете let [firstline, lastline]=sort([a:firstline, a:lastline], 's:NumSort'). Но вы все равно выйдете из визуального режима с :.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...