Vim:如何将命令插入到命令历史记录中?

3

我有一个映射,可以选择文本并键入(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生成),但我想知道如何解决我的上述问题,因为当我知道源代码的某些部分已更改时,我想要重新搜索相同的内容。
1个回答

10

当命令成为映射的一部分时,它们不会被添加到命令历史记录中。

使用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
    

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接