Я хочу сделать несколько хитрых сопоставлений, которые обертывают выбранную визуальную область некоторым кодом. Для этого мне нужно убедиться, что я нахожусь в начале текущей визуальной области. Есть ли горячая клавиша для этого в визуальном режиме?
2 ответа
Если я правильно понимаю, вы могли бы использовать
`<
а также
`>
Хитрость в том, что они идут в начало / конец предыдущей визуальной области, а не в текущую.
Итак, вы можете сделать что-то вроде этого:
:vmap __ <Esc>`>aEND<Esc>`<iSTART<Esc>l
В моей версии Vim после использования этой последовательности последняя визуальная область немного шаткая (при повторном выборе ее с помощью gv
выделяется область, которая не совсем правильная).
Для перемещения по текущей визуальной области пользователь может интерактивно использовать o
(и, возможно, O
если используется область блока), но они не являются детерминированными, если вы хотите использовать их на карте.
Итак, я написал функцию ниже, чтобы сделать детерминистическую версию o
(определенную как _^
и _$
ниже). Пример команды _*
использует их для выполнения «обтекания», аналогичного описанному выше __
, но также подделывает, оставляя визуальную область выбранной, повторно выбирая область (1v
) после выполнения обтекания:
:function! MoveToVisualAreaExtrema(wantEnd) range
: normal gv
: let l:mode = mode()
: " only character (v) and line mode (V) work with this implementation
: if !(l:mode == 'v' || l:mode == 'V')
: throw 'must be in character- or line-visual mode'
: endif
: " get original posision
: let l:iLn = line('.')
: let l:iCl = col('.')
: " move to other end of visual selection
: normal o
: " get current position
: let l:cLn = line('.')
: let l:cCl = col('.')
: let l:atEnd = (l:cLn > l:iLn) || (l:cLn == l:iLn) && (l:cCl > l:iCl)
: if a:wantEnd != l:atEnd
: normal o
: endif
: if l:mode == 'V'
: execute 'normal ' . (a:wantEnd ? '$' : '0')
: endif
:endfunction
:vmap _^ :call MoveToVisualAreaExtrema(0)<CR>
:vmap _$ :call MoveToVisualAreaExtrema(1)<CR>
:" Example: wrap ";print q();" around the visual region
:vmap _* _$<Esc>a);<Esc>gv_^<Esc>i;print q(<Esc>l1v
Заглавная буква H ("Дом") приведет вас к началу, а буква "L" ("Последний") - к концу.
Один из моментов поведения, который может вызвать у вас проблемы, состоит в том, что они помещают курсор на первый непустой символ строки, поэтому введите "0", чтобы перейти к абсолютному началу строки.