微信号:infoqchina

介绍:有内容的技术社区媒体

Oleg Shilo:基于CS-Script的Notepad++的插件

2014-03-28 17:26 InfoQ

如果只是想写几句试验代码,Visual Studio显得有点大材小用。因此一些开发者会选择轻量级的编辑器,如Notepad++,来满足编写脚本的需要。Oleg Shilo向我们介绍了他的项目,一个优秀的基于CS-Script的Notepad++的插件。

 

InfoQ:CS-Script是什么?它与普通的C#有什么区别?

Oleg:简单来说,CS-Script是一个基于CLR的运行时环境,可以执行用C#编写的脚本。值得注意的是,CS-Script并不是一个解释器,而是封装了微软或Mono C#编译器的shell。因此它与普通的C#没有什么不同。实际上,它的脚本引擎面向的也是ECMA兼容的“单纯功能”的C#,与用Visual Studio或MonoDevelop编译成程序集的C#没有什么区别。

 

描述CS-Script最简单的方式是:我们可以用C#编写算法,编译成程序集,然后直接执行该程序集,或在宿主应用程序中加载并执行。但CS-Script可以跳过编译阶段,而立即加载并执行代码,将C#代码当做脚本来处理。换句话说,运行时的C#脚本就是一个动态编译的程序集。

 

当然,实际情况要比这复杂得多,而且CS-Script提供了众多吸引眼球的特性:自定义JIT编译、省略类的语法、自动命名空间到程序集的映射、接口对齐等。

CS-Script现在已经9岁了,并且有一批用户。MediaPortal或FlashDevelop就是基于CS-Script构建的。它还被用于AutoCAD插件、自动化和机器人、游戏和规则引擎。

 

InfoQ:为什么会为Notepad++创建一个插件?

Oleg:原因有很多。我认为Notepad++的“自动补全”功能还有点简陋,还不足以成为智能的代码辅助工具。它只是按文件类型分组的一些“高频词”而已。

 

我坚信这样一个很牛的编辑器应该变得更好。因此我决定为Notepad++实现一个C#的智能感知解决方案。

 

我想让Notepad++能拥有与Visual Studio同种级别的智能感知。同时还包括“转到定义”、“查找引用”、“显示方法信息”、“添加缺少的‘using’”和代码格式化。这就是这个插件诞生的缘由。智能感知相关的功能基于NRefactory,但插件的核心是CS-Script。并且由于插件使用了脚本引擎,因此可以在Notepad++中直接执行C#代码。

 

另一个原因是因为CS-Script。尽管有了Visual Studio扩展和Windows Explorer Shell扩展,我还是觉得CS-Script不够圆满,没有一个专门的富编辑器。我想让C#和CS-Script用户拥有一个强大且轻量级的编辑器,不需要考虑任何部署和license的问题。

 

对于这个插件,我还有一个不太明显但却强烈的动机。我们日常工作如此复杂。框架、工厂、模式、设计原则……我们几乎忘记了编程的乐趣。我认为Notepad++和CS_Script让我们有机会只关注代码,而不用担心代码的基础结构,不用考虑在哪里保存项目文件或寻找刚刚编译的可执行文件。乐在码中。

 

InfoQ:创建一个Notepad++插件都包含哪些内容?

Oleg:传统的Notepad++插件开发要求用C++编写代码。尽管我用C++没问题,但我还是更喜欢C#。因此我用NppPlugin.NET作为插件容器。需要特别指出的是,这个插件宿主方案可以优雅地应对互操作的挑战。它只是一个特殊的VS项目模板,包含一些聪明的预编译行为,可以注入特殊的导出符号。因此,非托管的宿主应用程序(如Notepad++)可以在不借助任何包装器的情况下,直接承载一个普通的程序集。该项目模板还提供了一个接口(结构、常量),提供在其他插件中存在的所有Notepad++功能。

 

我使用了另一个第三方解决方案是ICSharpCode.NRefactory(属于SharpDevelop IDE)。它是最成熟的解析C#代码和构建语法树的开源解决方案。此外,它还实现了代码自动补全。但实际上它多少还是有点复杂。

 

NRefactory没有文档。尽管作者提供了充分的代码示例,这貌似是一个更好的选择。但所有示例都是SharpDevelp特有的,如果不使用SharpDevelop UI控件套件的话,它们无法提供任何帮助。我花了大量时间和精力对API进行反向工程,并最终成功将其集成到Notepad++插件中。

 

还有一个挑战是实现代码格式化。我做出了一个艰难的决定,实现自己的格式化解决方案,而不是使用NRefactory内置的格式化。这是因为NRefactory的格式化并不完备(至少我使用的版本是这样),而且对于非标准的语法(如没有类的C#脚本)不够灵活。

 

在涉及到用户交互时,我复制了Visual Studio的所有主要用户体验:解决方案浏览器、输出面板,CodeMap等等。

 

InfoQ:假设某公司创建了一个小型的DSL供内部使用。您认为让一个开发者创建他们自己的Notepad++插件是否可行?这是否需要整个团队的努力?

Oleg:这当然取决于开发的规模。解决方案由以下几个逻辑部分组成:插件基础、语法高亮、语法解析和用户交互支持。

 

插件基础可以说是最简单的部分。NppPlugin.NET能承担大部分工作。因此完全可以由单个开发者搞定。如果开发需求不重,甚至可以使用NppScripts(Notepad++自动化插件)。整个基础结构不到100行代码。NppScripts发布时自带了一个脚本示例,可以实现自定义的自动补全——允许特定上下文补全建议的自动补全功能。

 

语法高亮在大多数情况下可以通过定制内嵌的Notepad++样式来实现。某些高亮任务无法由定制完成,那么就需要自己开发完整的Lexar(通常用C++开发)。但也只需要一个开发者即可。

 

语法解析器的工作量与语法的复杂度成正比。因此像DOS指令这样简单的语法只需要一个人。但像C#这样复杂的语法就肯定需要一个团队了。尽管CS-SCript.Npp是一个人完成的,不过好在我没有任何期限。

 

为DSL支持用户交互也十分简单。大多数情况下只需要自动补全的弹出框和一些配置控制台。同样也是一个人的工作量。当然,除非DSL的复杂性要求在运行时进行密集的用户交互。

 

在大多数情况下,DSL插件都可以由一个开发者完成。如果DSL的复杂性是中到高级的,就需要一个团队参与了。不过,即使对于一个简单的DSL来说,一对儿开发者可以提高整个开发速度,他们可以同时开发相对独立的领域:插件基础、语法高亮、语法解析和用户体验。

 

更多精彩内容,请点击阅读原文。

 

***********************************

本文来自InfoQ微信公众账号:infoqchina

1、回复“今日新闻”,查看今天更新的新闻;

2、回复“今日英文”,查看今天英文站的更新;

3、回复“文章 +关键词”,搜索关键词相关内容;

4、回复“QCon”,了解QCon大会相关信息;

5、回复“活动”,了解最近InfoQ组织的线下沙龙;

6、回复“架构师”,获取《架构师》下载地址;

7、回复“投稿”,了解投稿和加入编辑团队的流程。

***********************************

 
InfoQ 更多文章 Facebook如何实现PB级别数据库自动化备份 学术派Google软件工程师Matt Welsh谈移动开发趋势 Spotify为什么要使用一些“无聊”的技术? 妹纸们放假了,汉纸们做啥? 大多数重构可以避免
猜您喜欢 解决问题的智慧:望、闻、问、切 一个90后清纯美女程序员的故事(程序员必看) 使用OpenResty搭建WAF应用 安卓单元测试(九):使用Mockito Annotation快速创建Mock PHP7今天要正式发布了