QCon 演讲火热征集中,快来分享技术实践与洞见! 了解详情
写点什么

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

  • 2014-03-26
  • 本文字数:3382 字

    阅读完需:约 11 分钟

如果只是想写几句试验代码,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 插件、自动化和机器人、游戏和规则引擎。

CS-Script 受到了 Python 的启发和影响。尽管它们面对的是完全不同的运行时范式,但 CS-Script 还是从 Python 借鉴了不少有用的想法,如多脚本执行、预编译等等。

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

Oleg:原因有很多。在 Windows 上开发的程序员很少有没听说过 Notepad++ 的。对很多人来说,它是“必备”的源代码编辑器。能够获此殊荣,Notepad++ 是当之无愧的,因为它具有优秀的架构和近乎完美的实现。但除了这些赞誉,它还有一定的上升空间。

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

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

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

当实现完成后,我又催生了其他一些想法。因此又发布了另一个 Notepad++ 插件(NppScript)。它使用 C#脚本对 Notepad++ 本身进行自动化。实际上每个这样的脚本自身,加上一些相关的插件特性(工具条图标、快捷键、菜单项),都可以看成是一个插件。下面的截图展示了这一想法。

(点击图像放大)

另一个原因是因为 CS-Script。尽管有了 Visual Studio 扩展和 Windows Explorer Shell 扩展,我还是觉得 CS-Script 不够圆满,没有一个专门的富编辑器。我当然知道 Visual Studio 提供了无与伦比的“编辑能力”,但它也不是“银弹”。我想让 C#和 CS-Script 用户拥有一个强大且轻量级的编辑器,不需要考虑任何部署和 license 的问题。

3 年前我甚至认真地尝试着开发这样一款编辑器。我花了大量时间对 SharpDevelop 做反向工程,并且几乎完成了一个为 C#量身定做的编辑器(代码名为 UltraSharp)。它是一个基于编辑器的自定义的 WinForm,包装了 NRefactory 5 预览版。但其性能和编辑功能都不能让人满意。因此我放弃了这个项目,转而专注于在 Visual Studio 中集成 CS-Script。我虽然取得了成功,但仍旧心仪永久免费、性能卓越、轻量级的 Notepad++。

对于这个插件,我还有一个不太明显但却强烈的动机。我们日常工作如此复杂。框架、工厂、模式、设计原则……我们几乎忘记了编程的乐趣。我不止一次地在文章中看到介绍批量重命名工具、下载器、目录同步工具或仅仅是又一个 MP3 文件标签组织工具。这些工具常常是为了引出全功能的应用程序开发(或部署方案),但在很多情况下,同样的工具可以仅用几行代码实现:

复制代码
foreach(string file in Directory.GetFiles(".", "*.mp3"))
{
var mp3 = TagLib.File.Create(file);
string dir = Path.GetDirectoryName(file);
string fileName = string.Format("{00}.{1}.mp3", mp3.Tag.Track, mp3.Tag.Title);
File.Move(file, Path.Combine(dir, fileName));
}

在 Notepad++ 中可以使用 CS-Script.Npp 插件来执行上述代码。它甚至可以准备一些脚本,能够在没有安装 Notepad++ 的 PC 上运行。

我认为 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 来说,一对儿开发者可以提高整个开发速度,他们可以同时开发相对独立的领域:插件基础、语法高亮、语法解析和用户体验。

关于受访者

Oleg Shilo生于乌克兰,并在那里获得了他的第一个资质:研究化学的硕士学位。18 年前移居澳大利亚,并获得了第二个资质:软件工程师。他在全澳洲机器人和自动化领域领先的工程公司工作。过去 4 年他就职于 Aqsacom Australia,任首席技术专家。

原文英文链接: Oleg Shilo on CS-Script and Notepad++

2014-03-26 07:324183
用户头像

发布了 59 篇内容, 共 23.9 次阅读, 收获喜欢 3 次。

关注

评论

发布
暂无评论
发现更多内容

建立数据地图,让数据资产“活”起来

数造万象

Spark RDD分区数与分区器源码解析

数新网络官方账号

spark

ArkUI开发趣味体验,快来抽取限量HarmonyOS专属头像!

HarmonyOS开发者

HarmonyOS

以Amazon Braket SDK和QuTrunk为例介绍量子编程框架

启科量子开发者官方号

量子计算

Renderbus瑞云渲染正式支持UE云渲染!离线渲染+实时渲染=渲染起飞!

Renderbus瑞云渲染农场

UE5 Renderbus瑞云渲染 3D制作软件

NGINX 开源社区捉虫征集令

NGINX开源社区

【精彩剧透】PyCon China 2022 邀您共赴技术Party!

PyChina

Python 开源 开发者 技术日

用一张图说一说 ChatGPT 内部技术工作流程

非喵鱼

Java 人工智能 AI 12 月 PK 榜 ChatGPT

已经看过这本书的“眼替”,带你探索广告投放的秘密!“照着操作,果然就能有效果!”

图灵社区

流量

2022年双碳背景下汽车行业发展洞察

易观分析

汽车 双碳

知识图谱与古希腊人物关系

数新网络官方账号

知识图谱

设计原则 — S 单一职责原则

Lemoon Can

面向对象设计原则 设计原则

StarRocks技术内幕 | 打造一款强大成熟的数据库有多难?

StarRocks

数据库·

WorkPlus SE专业版:政企值得托付即时通讯移动办公平台

BeeWorks

企业即时通讯软件哪个比较好用?

BeeWorks

【异常】window 10 安装node.js时遇到2502 2503错误解决方法

No8g攻城狮

nodejs Node node,js

精准管控 | AIRIOT数字油库智能化解决方案

AIRIOT

物联网 数字油库

谁能通俗的解释下,什么是云服务器?

Finovy Cloud

服务器 云服务器 云渲染 云渲染农场

数据治理:数据访问也需要治理!

用友BIP

架构实战 模块一:作业

Geek_6c89ef

BSN-DDC基础网络DDC SDK详细设计(八):示例

BSN研习社

BSN-DDC

SeaweedFS 高可用方案最佳实践

冰心的小屋

分布式文件系统 SeaweedFS

AWS AMAZON BRAKET与量子计算

启科量子开发者官方号

《媒体大数据分类分级指南》团体标准正式发布,易观分析参与编制

易观分析

大数据 媒体

一块钱能做什么?

白洞计划

Spring AOP在项目中的典型应用场景

江南一点雨

Java spring aop springboot

高效!启科量子线路模拟器QuSprout与AWS HPC集成,赋能量子计算

启科量子开发者官方号

量子计算

打造五层轻量监控体系

穿过生命散发芬芳

监控体系 12月月更

行话|入局「软件定义汽车」,你真的准备好了吗?

极狐GitLab

DevOps 汽车软件安全 软件定义汽车 极狐GitLab 汽车软件开发

开往春天的自动驾驶,从特斯拉和毫末智行的AI技术探索说起

脑极体

有奖征文 | 当我们谈操作系统时,我们在谈什么?

腾源会

开源 操作系统 opencloudOS

Oleg Shilo:基于CS-Script的Notepad++插件_C#_Jonathan Allen_InfoQ精选文章