Использование команды Vim для вставки текста в несколько строк

#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 ".