Vim中能否让编号寄存器保存复制(yank)历史(无需插件)
好问题!默认情况下Vim的编号寄存器(1-9)确实只记录删除、更改这类操作的历史,而最近一次的复制(yank)只会存在@0寄存器里。不过不用插件也能实现让复制操作也加入到编号寄存器的历史队列中,核心是利用Vim的自动命令来捕获复制事件,手动模拟删除操作的历史更新逻辑。
具体实现步骤
你只需要把下面这段代码添加到你的.vimrc(Windows下是_vimrc)文件里:
augroup YankToNumberedRegisters autocmd! autocmd TextYankPost * if v:event.operator is 'y' && v:event.regname is '' \| let old_reg1 = @1 \| let @1 = @" \| let i = 2 \| while i <=9 && old_reg1 != '' \| let temp = @i \| let @i = old_reg1 \| let old_reg1 = temp \| let i +=1 \| endwhile \| endif augroup END
代码解释
augroup和autocmd!:把相关的自动命令分组,避免重复加载时出现冲突,是Vim脚本里的常规操作。TextYankPost *:监听所有缓冲区的复制完成事件,这个事件在你用y系列命令完成复制后触发。- 条件判断
v:event.operator is 'y' && v:event.regname is '':只处理普通复制操作(比如yw、yy这种没指定自定义寄存器的复制),避免干扰你指定寄存器的复制(比如"ay)。 - 后面的循环逻辑:完全模拟Vim处理删除历史的方式——把原来的
@1内容往后挤到@2,@2到@3,以此类推,最多保留9条历史,然后把这次复制的内容(存在默认寄存器@"里)放到@1的位置。
使用效果
设置完成后,你每次用普通复制命令复制内容,都会像删除操作一样,被加入到@1-@9的历史序列里:
- 复制一段文字后,用
"1p就能粘贴这段内容; - 再复制另一段,
"1p会粘贴新的内容,原来的那段可以用"2p粘贴; - 同时
@0寄存器依然保留最近一次的复制内容,你还是可以用"0p快速粘贴最近复制的内容,不影响原有习惯。
注意事项
- 这个方法依赖
TextYankPost事件,Vim 7.4及以上版本才支持,现在大部分主流Vim版本都满足这个条件; - 如果是指定寄存器的复制(比如
"ay),这段代码不会处理,这样能避免自定义寄存器的操作干扰编号寄存器的历史。
内容的提问来源于stack exchange,提问作者nbl7
相关产品推荐
相关产品推荐

