Vim: Как вставить команду в историю команд?

У меня есть отображение, где я могу выбрать текст и набрать (лидер) v для подтверждения моего визуального выбора с Ack.vim:

" Visual ack, used to ack for highlighted text
function! s:VAck()
    let old = @"
    norm! gvy
    let @z = substitute(escape(@", '\'), '\n', '\\n', 'g')
    let @" = old
endfunction


" Ack for visual selection
vnoremap <Leader>av :<C-u>call <SID>VAck()<CR>:exe "Ack! ".@z.""<CR>

Тем не менее, я часто захочу повторно подтвердить последнее, что я искал, поэтому я набираю : up, чтобы искать его в истории команд в обратном направлении. Проблема в том, что этот метод не заполняет историю!

Мой вопрос, как я могу сделать одно из следующего:

  • Вставьте запись в историю командной строки, используя Vimscript -или-
  • Сделайте так, чтобы создаваемая команда выполнялась как команда двоеточия, чтобы история заполнялась автоматически?

Я полностью осознаю :copen а также :colder Команды, чтобы открыть и перейти к старому списку быстрых исправлений (который заполняет Ack.vim), но я хотел бы знать, как решить мою вышеупомянутую проблему, потому что я хочу повторно подтвердить то же самое, когда я знаю, что части моего исходного кода имеют изменилось.

1 ответ

Когда они являются частью отображения, команды не добавляются в историю команд.

Добавление элемента в конкретную историю осуществляется с помощью histadd() функция:

call histadd("cmd", "e $MYVIMRC")

Увидеть :help histadd(),

Вы могли бы начать с того, чтобы заставить вашу функцию возвращать шаблон поиска вместо того, чтобы забивать ваши регистры:

function! VAck()
    let old = @"
    norm! gvy
    let pat = substitute(escape(@", '\'), '\n', '\\n', 'g')
    let @" = old
    return pat
endfunction

что позволит вам упростить ваше базовое отображение:

vnoremap <Leader>av :<C-u>exe "Ack! " . VAck()<CR>

что мы теперь можем изменить, чтобы добавить команду в историю:

vnoremap <Leader>av :<C-u>let cmd = "Ack! " . VAck() <bar> call histadd("cmd", cmd) <bar> execute cmd<CR>

где ты:

  1. построить свою команду, let cmd = "Ack! " . VAck()

  2. добавить эту команду в историю, call histadd("cmd", cmd)

  3. выполнить команду, execute cmd,

Конечный результат точно такой же, как если бы вы на самом деле набрали :Ack! foo,


Несколько комментариев...

  • Я думаю, что это хорошая идея, я изменю свой конфиг (у меня уже есть аналогичные функции и сопоставления) соответственно.

  • Вы должны использовать xnoremap вместо vnoremap чтобы ограничить ваше отображение в реальном визуальном режиме.

  • В VAck()Если вы откроете неназванный регистр, ваш системный буфер обмена будет перегружен, если у вас есть что-то вроде clipboard=unnamed в вашем конфиге. Вы должны использовать конкретный регистр вместо:

    function! VAck()
        let old = @z
        norm! gv"zy
        let pat = substitute(escape(@z, '\'), '\n', '\\n', 'g')
        let @z = old
        return pat
    endfunction
    
Другие вопросы по тегам