今天同事遇到了一个vim上的小问题, 在选定的ID上键入Ctrl-],如果有多个跟这个ID名称匹配的Tag话,

在同事的机器上会直接跳转到第一个匹配项,切换到后续匹配项需要通过显式地输入:tnext来完成,很不方

便。

而在我的机器上,键入了Ctrl-]以后,如果有多个匹配项,vim会给出一个列表,提示用户选择想要跳转到的

Tag位置。(为便于描述,后面称vim的这种行为是预期行为)

我们的系统都是Ubuntu,用的也都是vim,当时他的系统还是我帮着作的,看起来环境的差异性不大,那为

什么一个相同的操作,在我们两个人的机器上会有不同的行为表现呢? 于是开始了一系列的定位过程:

1。怀疑是同事机器上的vim的设置有问题。

1). 正向分析

:help Ctrl-], :help tags,读了一下相关文档,却没有找到直接有用的信息。

2). 粗暴作法

:set all

把vim里所有可以通过set命令进行设置的options都打出来,试图在里面搜索跟tagsCtrl-]相关的选项,

vim的选项委实太多,在vim的options列表里也就看到几个从名字看起来跟tags关系比较密切的选项, 针对

这几个选项分别查了一下相关的manual,却没有看到有实质性帮助的信息。

基于字面内容相似性进行的搜索也就无功而返。

3). 逆向分析

会不会在我本地的.vimrc里有某个选项影响到vim的行为了呢?

把我本地的.vimrc文件清空,打开vim,测试Ctrl-]的行为,仍然会出现预期行为。

这样看来似乎跟vim的配置也无关。

而且,在这个尝试之后,自己似乎不知不觉地形成了这样一种认知---"vim的标准默认行为应该就是跟我机

器上vim的表现是一样的"


登录到公司服务器上,把.vimrc清空,试了一下vim,发现Ctrl-]的行为也是预期行为,于是,坚定了上面

刚形成的认知。

继而,怀疑在同事的.vimrc里打开了某个选项,而该选项会影响Ctrl-]的默认行为,于是跑到同事的机器

上,把他的.vimrc里的内容清空,结果他的vim的行为还跟以前一样-_-。

看起来,之前形成的结论似乎有些问题,于是启动了第二个思考方向。

2。怀疑同事机器上的vim的版本有问题。

1).跑到同事的机器上,看了看他的vim的版本,发现跟自己机器上vim的版本一样。

2) .想起vim在build的时候,可以定制不同的feature,于是怀疑同事机器上的vim的feature状态跟自己机

器上的vim不一样。

分别在自己和同事的机器上执行vim --version,输出结果文件,diff了一下,发现在build feature上没有

差异。

这条路又走不下去了,脑子里继续琢磨,启动了第三个思考方向。

3。vim通常会带有一些plugin,会不会是这些plugin影响到了vim的行为呢?

1). 在自己机器上,把vim的plugin目录清空,然后再试Ctrl-]这个时候发现跟同事机器上的行为是一样

的了!


于是,基本确定了是plugin目录里的某个插件在我的机器上安装了,在同事的机器上没有安装,造成了我们

两台机器上vim的行为差异。

问题是,在我的plugin目录下,安装了的插件非常之多,可能是哪个插件的问题呢?

同事建议说,也许是cscope相关的插件,因为cscope和ctags都是用于协助对文件进行navigate的工

具,本质上来看相似度较大。


我follow了同事的提议, 在自己机器上,把cscope相关的插件还原回plugin目录,再试vim的行为,果然出

现了预期的Ctrl-]行为。

2). 为了确认就是cscope 插件的影响,自己又校验了一次,把除cscope插件以外的其他插件还原回plugin

录,测试vim下Ctrl-]的行为, 这次Ctrl-]又不正常了。这就完全确定了在其他vim选项相同的情形下,

cscope插件的存在与否对vim Ctrl-]预期行为的影响构成了充分必要条件


3). 具体来说,cscope插件是怎样影响到vim Ctrl-]的行为呢?自己猜测了一下,觉得有可能是cscope插件里

把Ctrl-]这个按键序列定制了,或是设置了某个选项,该选项会影响到Ctrl-]的行为。

打开cscope的插件,检查其源码,没有看到Ctrl-]的定制项,于是开始集中检查源码里面的set命令,倒是看

到了几个set命令,但是从这几条set命令的选项名字来看,都不像是可能影响到Ctrl-]的行为的。不过,自己

还是基于客观事实,把这几个set命令一一试了一下。试到set cscopetag的时候,发现这个set命令对

Ctrl-]的行为会产生影响。于是:help cscopetag,看到了相关描述,原来set cscopetag之后,Ctrl-]

的行为就由原来的调用 :tag命令改为调用 :cstag命令了。而:cstag命令会对应到:tjump命令上,:tjump

命令在vim manual里的描述如下:

:tj[ump][!] [ident]    Like ":tselect", but jump to the tag directly when there is only one match. 

{not in Vi}


可以看出,:tjump提供的正是我们所期待的行为。

问题的根源算是找到了。然后自己继续验证了一下自己对问题根源的理解,把plugin目录下的插件清空,在

.vimrc里加入set cscoptag,然后启动vim,键入Ctrl-],这次vim的行为如预期,会在出现多个同名

tag的时候,给出一个备选列表了。

经过一番尝试,自己也终于成功找到问题根源了:)。

-------------------------------------我是分隔线----------------------------------------------------------------------------------

另外对思考过程中走的几个弯路作了一下总结回顾:

1.   对这个问题的分析,其实不需要跑到同事的机器上也能完成,只要自己能透过表象层面,想到影响vim

行为的在本质上并非是.vimrc,而是set, map这样会对vim行为产生影响的命令的话,那么所有包括

通过set, map等命令,并且会在vim启动过程中被加载的脚本文件都应该被考虑到,而非仅.vimrc


而从这个角度来看,.vimrc文件本质上跟plugin不是一样的么?可是自己在初始的思考过程中却忽略了

plugin对vim行为的影响,形成了一种假设“能影响vim的行为就是.vimrc”。这个假设似乎是在潜意识下引

入的,因为通常我们正是通过配制.vimrc来定制vim的行为,这个表面现象出现的频率如此之高,稍有

不慎,就会让我们形成潜意识的假设,把表面因果误认为本质因果。
也正是这个假设让自己走了一些弯路



2. vim的manual作得不够好,既然cscopetag这个option会影响到Ctrl-]的行为,我觉得,vim manual

里应该以某种方式对这种命令之间的相互联系提供双向链接描述,也就是说:通过vim manual,看到

cscope的描述,我们能了解到它对Ctrl-]会有影响;而看到Ctrl-]的描述,我们也能知道cscope会对

它有影响
,这样,我们就更容易从现象层面易观测的Ctrl-]出发,找到所需的信息,避免走弯路了。如果我

是vim manual的作者,我想,我会考虑把这样的信息加入vim的manual里,来提高vim用户的使用效率。

(实际上,最后自己能定位出问题的根源,在相当大程度上还是因为自己的机器上凑巧装了cscope插件,影响

到了vim的行为,误打误撞地建立了一个带预期行为的环境,可以作为分析过程中试错实验的参考范本。如

果自己机器上没有这样一个参考环境,只是从正向分析的角度,来定位这个问题的话,我想会多付出数倍的

时间才可能定位到问题根源,由此可见一个编写良好的manual可能对用户生产率带来的影响。)

3. 自己在分析问题的过程中,多次因为思路走得过快,几乎是在下意识,就形成了有问题的认识而不自知。

比如说,在把本地的.vimrc清空以后,发现我本地的vim的行为是预期的,就形成一个结论,认为vim的默

认行为就是预期行为
。这个结论的形成是不严谨的,它依赖于一个隐晦的假设:"影响到vim行为的只有

.vimrc,plugin目录下的东西是不会影响到vim行为的
"。这个隐晦假设之所以会形成,既跟自己之前有

太多通过.vimrc定制vim行为的经历有关系,还可能跟自己用:set all列出vim的所有选项,没有看到字面上

跟tags明显相关并且会影响到Ctrl-]相关行为的选项,基于这个表面现象,自己偷了个懒,放弃了深入的思考

考,形成了一个无意识的假设。

而实际上,如果自己当时能仔细审视一下已形成的认识,会发现,vim的选项那样多,自己甚至连完整过一

遍都没作到,就基于字面的相似度形成了一个假设,这是多么脆弱的,站不住脚的假设,但这个假设就那样

在不经意间形成了。

在形成这个假设的思考环节中自己的思路走得不够细致,过于求快了一点。而正是这个思考环节的问题直接

影响到了后续的问题分析过程,让自己多走了一点弯路。

如果自己在分析这个问题的过程中,对每一步思考环节,都能有意识地稍作省视,也许很快就发现其中一些

推导环节里站不住脚的地方,继而通过更少的实际尝试就能定位出问题根源了呢。

转自:http://hi.baidu.com/yjpro/blog/ite/d4c913250c296a6c34a80f38.html