3

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

2 ответа2

4

Если я правильно понимаю, вы могли бы использовать

`<

а также

`>

Хитрость в том, что они идут в начало / конец предыдущей визуальной области, а не в текущую.

Итак, вы можете сделать что-то вроде этого:

: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
0

Заглавная буква H ("Дом") приведет вас к началу, а буква "L" ("Последний") - к концу.

Один из моментов поведения, который может вызвать у вас проблемы, состоит в том, что они помещают курсор на первый непустой символ строки, поэтому введите "0", чтобы перейти к абсолютному началу строки.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .