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

У меня есть сопоставление, в котором я могу выбрать текст и ввести (leader)av, чтобы подтвердить мой визуальный выбор с помощью 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 заполняется), но я хотел бы знать, как решить описанную выше проблему, потому что я хочу повторно подтвердить ту же самую вещь, когда я знаю, что части моего исходного кода изменились.


person Andy Ray    schedule 17.10.2014    source источник


Ответы (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
    
person romainl    schedule 18.10.2014