#vim #mapping
#vim #сопоставление
Вопрос:
Я знаю, что в режиме визуального блока с помощью <S-i>
( I
) можно вставлять несколько выбранных строк, однако я хочу добиться того же эффекта с помощью функции, допустим, у меня есть функции, которые могут определять три суб-визуальных режима ( visual-character
, visual-line
visual-block
) следующим образом,
function! VisualMappingSpace()
let m = visualmode()
if m ==# 'v'
echo 'character-wise visual'
elseif m == 'V'
echo 'line-wise visual'
elseif m == "<C-V>"
echo 'block-wise visual'
endif
endfunction
Я пробовал следующим образом, но это не работает. Я хочу вставить что-нибудь в строки, которые я выбираю, когда нажимаю <space>
в visual-block
режиме.
function! VisualMappingSpace()
let m = visualmode()
if m ==# 'v'
exec "normal y"
elseif m == 'V'
exec "normal y"
elseif m == "<C-V>"
let g:block_insert_content = input("")
exec "normal I ".g:block_insert_content
endif
endfunction
vnoremap <silent> <Space> :call VisualMappingSpace()<CR>
Комментарии:
1.
exec "normal y"
должно бытьnormal y
. В любом случае, чего вы ожидаете? Что вы получаете вместо этого?2. На самом деле, чего я ожидал, так это того, что в режиме
visual-character
иvisual-line
, когда я нажимаю<space>
, я могу скопировать выбранные строки в регистр по умолчанию, а вvisual-block
режиме, когда я нажимаю<space>
, я могу вставить что-то в выбранные строки, точно так же, как то, что я нажимаюI
вvisual-block
режиме.
Ответ №1:
Сопоставление в визуальном режиме, которое переходит в режим командной строки через :
, автоматически вставит визуальный диапазон ( '<,'>
). С :call
это означает, что ваша функция вызывается один раз для каждой выбранной строки. Вы должны были заметить через повторяющиеся запросы.
Чтобы избежать этого, вставьте <C-u>
в свое сопоставление; это очищает диапазон.
Вторая проблема: когда вы вставляете запрошенный текст, вам нужно заново создать выделение (ваше сопоставление перешло из визуального режима в режим командной строки, помните?) через gv
; затем I
будет работать:
function! VisualMappingSpace()
let m = visualmode()
if m ==# 'v'
exec "normal y"
elseif m == 'V'
exec "normal y"
elseif m == "<C-V>"
let g:block_insert_content = input("")
exec "normal gvI ".g:block_insert_content
endif
endfunction
vnoremap <silent> <Space> :<C-u>call VisualMappingSpace()<CR>
Также обратите внимание, что перед вашим запрашиваемым текстом стоит дополнительный пробел; Я не уверен, что вы этого хотите: gvI ".