BT

Facilitating the Spread of Knowledge and Innovation in Professional Software Development

Write for InfoQ

Topics

Choose your language

InfoQ Homepage Articles Oleg Shilo on CS-Script and Notepad++

Oleg Shilo on CS-Script and Notepad++

When you just want to try out some code, Visual Studio can feel like overkill. So some developers turn to lightweight editors such as Notepad++ for their scripting needs. Oleg Shilo talks about his project to add better CS-Script plugin for Notepad++.

InfoQ: What is CS-Script and how does it differ from normal C#?

Oleg: To put it simple, CS-Script is a CLR based runtime environment for executing scripts written in C#. It is important to note that CS-Script is not an interpreter but a shell that encapsulates either Microsoft or Mono C# compiler. And this is the reason why CS-Script is not different from normal C# at all. In fact the script engine targets the very same ECMA-compliant 'plain vanilla' C# that you compile into assembly with Visual Studio or MonoDevelop.

The simplest way to describe CS-Script is as follows: you can code your algorithm in C#, then compile it into assembly and then either execute this assembly directly or load and execute it from the host application. But CS-Script allows you to skip the compilation stage and load/execute the code immediately, effectively handling your C# code as a script. In other words C# script at runtime is nothing else but an assembly, which is compiled on-fly.

Of course it is more complicated under the hood and CS-Script offers a very appealing set of features: custom-JIT compilation, classless syntax, automatic namespace-to-assembly resolving, interface alignment etc.

CS-Script is 9 years old now and it has found its audience. When you are running MediaPortal or FlashDevelop you are using CS-Script. It has been used in AutoCAD plugins, automation and robotics, game and rules engines.

CS-Script was inspired and influenced by Python. While they follow completely different runtime paradigm CS-Script borrowed many usability ideas from Python: multi-script execution, pre-compilation....

InfoQ: Why did you decide to create a plugin for Notepad++?

Oleg: Well, there are a few reasons.

It is hard to find someone developing on Windows who hasn't heard about Notepad++. By many it is considered a "must have" source code editor. It's well deserved reputation is attributed to the clever architecture and close to flawless implementation. But despite all this "brilliance" it has certain room for the improvements.

Thus I think the "auto-completion" in Notepad++ is a bit clumsy. It is not really an intelligent code assistance. It is actually nothing else but a list of the "favourite words" grouped by the type of the document.

I do believe that such a bright editor as Notepad++ deserves something better. Thus I decided implement a real Notepad++ Intellisense solution for C#.

I wanted Notepad++ to have the same level if Intellisense support as Visual Studio offers. And this would also include "Go to definition", "Find references", "Show Method Info", "Add missing 'using'" and code formatting. This is how the plugin was born. The Intellisense related functionality is based on NRefactory but the heart of the plugin is CS-Script. And because the script engine is available within the plugin it was only logical to allow execution of C# code directly from Notepad++.

When the implementation has been practically completed a few other ideas have eventuated. Thus another Notepad++ plugin (NppScripts) just has been released. It allows automating Nopetad++ itself with C# scripts. In fact every such a script can be considered as a plugin on its own with all associated plugin attributes: toolbar icon, shortcut, menu item. This screenshot illustrates the idea.

             

              (Click on the image to enlarge it)

The second reason for the plugin is all about CS-Script. While it comes with Visual Studio extension and Windows Explorer Shell Extensions I always felt that CS-Script is kind of incomplete without a rich dedicated editor. I do realize that Visual Studio offers practically unbeatable "editing power" however it is still not a "silver bullet". I wanted C# and CS-Script users to have a powerful and light editor without any deployment or licensing pain.

About 3 years ago I even made a serious attempt to develop such an editor. I spend quite some time reverse engineering the SharpDevelop and have almost completed a C# dedicated editor (codename UltraSharp). It was a custom WinForm based editor wrapping the pre-version-5 NRefactory. However I was not satisfied with it's performance and not powerful enough editing capabilities. Thus I canned the project and concentrated on the integrating CS-Script with Visual Studio instead. I succeeded but still had some jealousy towards Notepad++ for it's ultimate availability, impressive performance and extremely light nature.

Also I had another less obvious but very strong motivation for developing this plugin. We are all caught in the complexity of our day job challenges. Frameworks, factories, patterns, design principles... We almost forgot that programming is fun. I have seen so many times articles describing some batch renaming utilities, downloaders, directory synchronizers or just another MP3 file tags organizer. These sort of utilities often attract the full scale application development (or even deployment solutions) but in many case the same can be actually done (and dusted) with just a few lines of code:

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));
}

And CS-Script.Npp plugin allows executing the code as above within Notepad++. It even allows preparing the script for running it on PC where Notepad++ is not even installed.

I think Notepad++ with CS-Script give us a good opportunity to jump at the desk and just code. Code without worrying about any code infrastructure. Code without thinking about where to save the project file or where to find the executable you just compiled. Code for fun.

InfoQ: What’s involved in creating a Notepad++ plugin?

Oleg: The conventional Notepad++ plugin development requires coding in C++. While I am fully comfortable with C++ I do prefer C#. Thus I used NppPlugin.NET as a plugin container. This plugin hosting solution deserves a special mentioning as it is rather an extremely elegant approach to the Interop challenges. It is nothing else but a special VS project template with a very clever post-build action, which injects special exporting symbols. Thus it makes possible for unmanaged host applications like Notepad++ to host an ordinary assembly directly without any need for wrappers of any sort. The project template also provides an interface (structs, constants) for the all Notepad++ functionality normally available within any other plugins.

Another third-party solution that I used is ICSharpCode.NRefactory (part of SharpDevelop IDE). It is the most mature Open-Source solution for parsing C# code and building SynatxTree. Even more, it already has code auto-completion implemented. However in reality it is a bit more complicated.

NRefactory has practically no documentation. Though its author(s) provided a comprehensive set of code samples, which seems to be even a better option. However all samples are too SharpDevelop specific and do not help with using the library outside of the SharpDevelop UI controls suite. It took me quite some time and effort, to reverse engineer the API but eventually I managed to integrate NRefactory with Notepad++ plugin.

Another challenge was to implement code formatting. I had to make a difficult decision to implement my own solution instead of using NRefactory built-in formatting. Unfortunately NRefactory formatting is not fully completed (at least the version I used) and not flexible enough to handle non-standard syntax (e.g. classless C# scripts).

And when it comes to the interaction with the user I tried to replicate all major user experiences of Visual Studio: Solution Explorer, Output Panel, CodeMap....

InfoQ: Let’s say a company has created a small DSL for internal use. Do you think it would be feasible for them to have a developer create their own plugin for Notepad++? Or is this something that needs a team effort?

Oleg: Of course it will all depend on the scale of the development. The solution will consist of the following logical parts: plugin infrastructure, syntax highlighter, syntax parser and user interaction support.

Plugin infrastructure is arguably the easiest part. NppPlugin.NET can do the heavy lifting. This part definitely can be handled by a single developer. If deployment requirements are not heavy you can even use NppScripts (Notepad++ automation plugin). Thus the whole infrastructure can probably be done in a single script ~100 lines of code. The NppScripts release comes with a script sample for implementing a custom auto-complete. Auto-complete that allows context-specific completion suggestions.

Syntax highlighting in most of the cases can be accomplished with the built-in Notepad++ style customization. Some highlighting tasks cannot be done with customization and then you will need to develop a full scale custom Lexar (usually in C++). But still it is rather a single developer effort.

Syntax parser will attract the affort proportional to the complexity of the syntax. Thus something as simple as DOS commands syntax will need a single person effort. But for something as complex as a custom flavour of C# you will definitely need a team effort. Well, in case of CS-Script.Npp it was a single person effort but I had a luxury of not having the due day.

And the support of the user interaction for the DSL scenarios would be fairly simple. In most of the cases the auto-complete popup and some sort of a config console. Again a single-developer effort. Unless of course the DSL complexity will require an intensive user interaction at runtime.

The bottom line is that in most of the cases the DSL plugin can be developed by a single developer. If the complexity of the DSL is moderate to high then the team needs to be involved. However even in case of a simple DSL a couple developers can speed up the development by working simultaneously on the relatively independent development domains: plugin infrastructure, syntax highlighter and syntax parser and UX.

About the Interviewee

Oleg Shilo was born in Ukraine, where he got his original qualification - Master's Degree in Research Chemistry. After moving to Australia 18 years ago he obtained his second qualification as a Software Engineer and worked in Australian leading engineering companies in the Robotics and Automation domain. For the last 4 years he worked as a Lead Technical Expert at Aqsacom Australia (Lawful Interception).

Rate this Article

Adoption
Style

BT