Vim

支持分支的 undo

undo,编辑器世界中的后悔药,让你有机会撤销最近一步或多步操作,这是任何编辑器都具备的基础功能。比如,第一步输入 A,第二步输入 B,第三步输入 C,当前文本为 ABC,一次 undo 后变成 AB,再次 undo 后变成 A,显然,每次 undo 撤销的均是最后的一步操作,通常采用栈这种数据结构来实现 undo 功能,由于栈具有后进先出的特点,所以,功能实现起来非常自然且便捷,但同时,也引入了致命伤,无法支持分支上的 undo 操作。

还是前面的例子,分三步依次输入完 ABC 后,一次 undo 变成 AB,这时,输入 D,之后,无论你多少次 undo 都不可能再找回 C,究其原因,D 是彻底覆盖了 C,而不是与 C 形成两个分支,如下图所示:

不支持分支的 undo不支持分支的 undo

在我的使用场景中,非常需要在我输入 D 后还能找回 C 的 undo 功能,即,支持分支的 undo,gundo.vim (http://sjl.bitbucket.org/gundo.vim/ )降临。gundo.vim 采用树这种数据结构来实现 undo,每一次编辑操作均放在树的叶子上,每次 undo 后,先回到主干,新建分支继续后续操作,而不是直接覆盖,从而实现支持分支的 undo 功能。gundo.vim 要求 VIM 版本不低于 v7.3 且支持 python v2.4 及以上。

如下方式设置好调用 gundo.vim 的快捷方式:

" 调用 gundo 树
nnoremap <Leader>ud :GundoToggle<CR>

gundo.vim 非常贴心,调用它后,你会在左侧看到一个分割为上下两个区域的子窗口。上半区域以可视化方式显示了整颗 undo 树,同时,用 @ 标识最后一步编辑操作,用序号标识各步编辑操作的先后顺序,用时长显示每步操作距离当前消耗时间。下半区域展示了各个操作间的 diff 信息及其上下文,默认为选中那步操作与前一步操作间的 diff,键入 p 可以查看选中那步操作与最后一步操作(即有 @ 标识的那步)间的 diff,这对于找回多次编辑操作之前的环境非常有用。

支持分支的 undo支持分支的 undo

另外,我对持久保存 undo 历史也有需求,以便让我关闭 VIM 后重新启动也能找到先前的所有 undo 历史,这需要你在 .vimrc 中添加:

" 开启保存 undo 历史功能
set undofile
" undo 历史保存路径
set undodir=~/.undo_history/

你得先自行创建 .undo_history/。具体可参见 环境恢复 章节。

下一节:vim 有两类快速移动光标的方式:一类是以单词为单位的移动,比如,w 正向移动到相邻单词的首字符、b 逆向移动到相邻单词的首字符、e 正向移动到相邻单词的尾字符、 ge 逆向移动到相邻单词的尾字符;一类是配合查找字符的方式移动,比如,fa 正向移动到第一个字符 a 处、Fa 逆向移动到第一个字符 a 处。你要在非相邻的单词或字符间移动,你可以配合数字参数,比如,正向移动到相隔八个单词的首字符执行 8w、逆向移动到第四个 a 字符处执行 4Fa。