2013-07-18 3 views
0

Я пытаюсь написать плагин, который включает в себя перемещение вверх или вниз по переменному числу строк. Я хочу создать что-то, что можно использовать как пользовательское движение, для использования в нормальных, визуальных и операционных режимах.Что вызывает это странное поведение движения в визуальном режиме?

Вот небольшой фрагмент идеи: («3» здесь для примера Цель состоит в том, чтобы переместить переменное число строк, но это не имеет отношения к тому, что мой вопрос.).

function! MoveDownThreeLines(mode) 
    if a:mode == 'v' 
     normal! gv 
    endif 

    if a:mode == 'o' 
     normal! V3j 
    else 
     normal! 3j 
    endif 
endfunction 

nnoremap w :call MoveDownThreeLines('n')<CR> 
vnoremap w :call MoveDownThreeLines('v')<CR> 
onoremap w :call MoveDownThreeLines('o')<CR> 

Целью этого фрагмента является создание пользовательского движения, которое перемещается вниз по трем линиям. Я хочу, чтобы поведение w было таким же, как и у 3j. В нормальном режиме он перемещается на три строки, как ожидалось, и в режиме ожидания оператора оператор действует на четыре строки (текущий и три ниже), как и ожидалось. (Хотя мне пришлось вынудить движение быть linewise, используя V, что странно, потому что j уже движется по линуксу. Кто-нибудь знает, почему это так?)

Проблема в визуальном режиме. Если я вхожу в визуальный режим, то нажмите w, курсор перемещается вниз по трем линиям, как и ожидалось. Если я снова нажму w, он будет двигаться только по двум линиям.

Аналогичным образом, если я вхожу в визуальный режим и расширяю выделение вниз каким-либо другим способом, нажатие w перемещается только по двум линиям. Странная другая проблема заключается в том, что если я вхожу в визуальный режим и расширяю выделение вверх, w меняет мой выбор, чтобы быть от нижней части старого выделения до двух строк вниз. (Цель будет для w, чтобы переместить вершину выбора вниз три линии, так же, как если бы я использовал 3j.)

Как сделать w движения вниз три линии во всех случаях?

PS: Ingo Karkat, если вам посчастливилось прочитать это, спасибо за ваш довольно прокомментированный сценарий camelcasemotion - из этого вытекают некоторые идеи.

+2

Это хорошая практика добавить '', чтобы очистить визуальный диапазон '<,'> 'часть. 'vnoremap w: call MoveDownThreeLines ('v') ' –

+0

'gv' перемещает курсор вверх по строке при каждом выполнении, кроме первого. – FDinoff

+0

@PeterRincker Хорошо, я забыл об этом! Для тех, кто читает это позже, это не просто хорошая практика, она имеет значение в исполнении. И вот что здесь не так. Спасибо что подметил это! Если вы хотите опубликовать это как ответ, я пойду принять его. – pandubear

ответ

3

Вы должны префикс все (а не только визуальный режим один, так как заметил Питер Rincker) отображения с <C-u>, так как вы, вероятно, хотите поставить [count] с вашими отображений (вместо жесткого кодировкой 3).

В нормальном режиме подсчет (например, 3) преобразуется в :.,+2 при нажатии :. Аналогично, визуальный режим : prepends :'<,'>. Команда :call выполняет функцию один раз для каждой строки, что обычно не является тем, что вы хотите. (Вы можете изменить это путем добавления range ключевого слова к :function определению, но избежать, что счет переводится в диапазон позволяет использовать его даже более гибко, вы можете использовать его внутри вашей функции с v:count.)

+0

Правильно, спасибо. В этом есть смысл. Есть ли причина, по которой вы должны префиксные отложенные для оператора сопоставления с '', хотя? – pandubear

+0

Вам не нужно, поскольку немедленный счет не имеет режима нормального режима, но я не знаю, является ли это ошибкой или предполагается. Лучше быть последовательным, поскольку это, безусловно, не повредит. –

+0

+1 отличная информация о '' –

Смежные вопросы