vim中的持久性撤消功能使用内部函数undofile()
来确定当前缓冲区的undofile的文件名。在我的一台机器上vim 8.0中有一个错误,其中undofile()
没有正确地逃脱路径分隔符。
:echo undofile(@%)
/home/bhawkins/.vim/undo/%home%bhawkins%some%path%to%code.c
那些裸%
字符在这台机器上不起作用(不知道为什么不)。该命令的正确结果应该是:
:echo undofile(@%)
/home/bhawkins/.vim/undo/\%home\%bhawkins\%some\%path\%to\%code.c
因此,即使正确保存历史记录,也无法加载撤消历史记录。例如,当我手动加载撤消文件时,持久撤消会神奇地开始工作(仅适用于那个缓冲区):
:rundo /home/bhawkins/.vim/undo/\%home\%bhawkins\%some\%path\%to\%code.c
通过将autocmd FileReadPost
的结果放入.vimrc
变量,我尝试将其设置为undofile()
中的let
- 但我无法弄清楚如何逃脱%
角色。
你可以试试这个:
1 redir => oldundo
2 echo undofile(@%)
3 redir end
4 let oldundo=oldundo[1:]
5 let newundo=substitute(oldundo,"%","\\\\%","g")
前三行捕获oldundo
变量中的撤消路径。第4行从^@
中删除第一个字符(oldundo
)。最后一行用%
替换\%
并将结果存储在newundo
中。最后要使用新路径,您可以输入:
:rundo <c-r>=newundo<cr>
这里<c-r>
表示Ctrl + r。而<cr>
代表Enter键。
事实证明在autocmd
中引用变量非常棘手:
autocmd BufReadPost * :let undofilename=substitute(undofile(@%), "%", "\\\\%", "g")
autocmd BufReadPost * :silent execute "rundo ".g:undofilename
在我看来,这是另一个原因,即vim应该使用像python这样组织良好的语言作为其命令行和脚本,而不是用这个被称为“vimscript”的这个庞大的本土杂乱来折磨人们。