我一直觉得VisualStudio是微软最了不起的产品之一,也是最智能和直观的语言开发工具之一,虽然它不是我日常主要的开发环境。在其中写程序总会给我轻松愉快的感觉。Intellisense是Visual Studio里的代码提示和完成功能,也是我见过的同类功能中最聪明的。关键字、类型名称、方法名称、类型和方法字段名称、对象初始化代码、注册事件处理程序的代码……输入代码的时时刻刻、各种场景,Visual Studio都会贴心地给出提示列表,默认选中它推测最可能的选项,并且在随后的回车、空格、句点、左圆括号等按键时自动输入选中的内容,使得原本像一篇文章的由众多单词和符号组成的代码只需少数按键和选择就能完成。Intellisense的聪明常常让我衷心赞叹,例如在长长的提示列表里它能记住最近一次类似的调用输入的是什么,从而选中该项目,这样的情形包括字段列表和对象的方法列表。
int iA, iB, pos; string text="abcba"; iB=text.IndexOf("b"); //再次键入i时,VS会显示提示列表,包括iA和iB, 但是会记住最近的输入,选中iB而不是按字母排序更前的iA。接下来只需键入后续的加号。 pos=iB+1; //类似地,键入text.后,VS在弹出的方法列表里,会选中最近输入的IndexOf,接下来只需键入左圆括号。 iA=text.IndexfOf("a");
程序员有时抱怨C#这类的静态强类型语言在声明和初始化变量时代码显得冗赘,例如MyClass obj=new MyClass();,MyClass作为类型名称要输入两次。有同感的计算机科学家因而研究出类型推断(Type Inference),使得在现在的C#里可以像在JavaScript里一样用var关键字声明变量,再根据后续的初始化代码推断出变量的类型,如var obj=new MyClass();。实际上如果是在VS里编程,类型名称也不需要输入两次,VS会代劳。
List<int> bPos=new List<int>();
下面这行代码的第二个List<int>就会被Intellisense提示和输入。所不同的是,类型推断增强的是语言本身的能力,Intellisense则提高的是编辑器的水平。
再来看看C#的竞争者Java语言最流行的开发环境Eclipse,这里的代码提示和完成功能叫做ContentAssist。在Edit菜单下的Content Assist子菜单下,就有Default、Java Type Proposals、Java Non-Type Proposals、Java Proposals、Template Proposals、Word Proposals、SWT Template Proposals、JPA Proposals、PDE API Tools Proposals、Java Proposals (Task-Focused)和Parameter Hints这么多细分的类型。默认状态下编辑时,只有输入类型或者对象变量后按句点,才会弹出方法列表,其他提示都需要调用菜单或按对应的Ctrl加空格键,并且选中方法后须按回车才能自动填上,如在Visual Studio里那样键入方法之后的左圆括号就不行。这样麻烦的操作让代码提示的功效大大降低,我于是想在偏好设置(Preferences)中看看此行为是否可修改。按照设置项的名称找到Preferences -> Java -> Editor -> Content Assist,果然有很多参数可配置。
顾名思义,Auto-Activation一节应该就是我想要的。默认的Enableauto activation是选中的,delay(延迟)设的是200,triggers for Java(对Java的触发键)为句点,triggers for Javadoc为@#。看来关键就是trrigers一项,目前只在键入句点后自动触发代码提示,我想要的则是像Visual Studio那样在输入代码的各种场景都弹出提示,要设置的触发键太多了,而且一时也想不全,要是能设置正则表达式就好了,但正则表达式里的特殊字符句点在这里没有转义就表明不能用。设置触发键的文本框不长,给了我只是为了输入单个键的错觉,以致我忽略了triggers用的是复数而且Javadoc的触发键就设置了两个。直觉上错过了在这里修改的可能性之后,我又看了Content Assist设置分类下的Advanced和Favorites两节,没有找到想要的设置。接着我Google了Eclipse和Visual Studio Intellisense这几个关键词,在第一条结果的Stack Overflow上找到了Tony给出的答案(http://stackoverflow.com/questions/2943131/eclipse-intellisense)。出奇地直接和简单,就是把输入代码时用到的各种字符都设置成触发键:ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz=.(!+-*/~,[{@#$%^&,为避免延迟,还可以把delay设置成零。如此一来,在Eclipse里编写代码的体验就迅速接近VisualStudio,但还是有一些细微的差异。Eclipse的提示划分成很多类别,总的覆盖的范围比VisualStudio广,但是在准确程度上略逊一筹。例如与编写一般Java代码最有关的Java Proposals(Task-Focused),会积极地在命名变量时给出参考名称,例如变量类型是MyEventPublisher,参考名称包括publisher、eventPublisher和myEventPublisher,很实用;但是在诸如键入左花括号的很多时候会给出无关的类型提示,更糟的是往往这时候只有一个提示项,Eclipse就自动插入了。由此我总结出的对Content Assist配置的修改如下:
在Advanced页里对默认提示包含哪些类别,就根据个人实际开发需要而定。此外在中文Windows下,Ctrl加空格键被Windows里的“文本服务和输入语言”设置为中文和英文输入法的切换热键,因此常常被各种IDE用作其他用途的这个组合键在中文Windows下就失效了。在Windows 7下我试着删除它作为中英文输入法切换的功能,但总是被自动恢复,于是将热键改为Ctrl加逗号,这样Ctrl加空格组合才被解放出来。
回过头我发现VS里聪明的代码提示和完成在偏好设置里也是可配置的,设置项没有那么繁多,但每一项都有正中下怀的感觉,并且这些默认设置都已恰到好处:
我给Visual Studio Intellisense带来的这种写程序体验起了个有些夸大的名称,理念式编程,或曰智能式、选择式。主要是它极大地减少了输入代码所需的击键次数,只要在脑子里构思出代码的逻辑,剩下每一行都只需敲寥寥数键,或是Intellisense已自动填上,或是选择一下即可,写程序在输入代码这部分工作上消耗的精力和时间都最小化了。有些人可能会反驳说写程序本来大部分时间就是花在想而不是敲键盘上,但至少对我这样有些粗心的人来说,在没有提示的情况下,键入成百上千的字符,严格符合程序的语法,本身也是一件耗神费力的事,特别是对Java这样类库越来越庞大,包和类型名称因为清晰必然冗长的语言来说。代码着色和编辑时错误提示减少了需要的注意力和出错的可能,代码自动完成则不但做到了这一点,还大大加速了输入的过程。与现代程序的编辑器相比,十多年前我上大学时输入Fortran和C的控制台风格的编辑器简直是噩梦。对于一个学习者而非熟练程序员来说,花在一个一个字符键入代码并保证不出错上付出的精力和时间与想出程序所花的不相上下。