Click here to Skip to main content
12,695,365 members (28,793 online)
Click here to Skip to main content
Add your own
alternative version

Stats

91.6K views
186 downloads
164 bookmarked
Posted

Sharpening Notepad++

, 29 Oct 2014 MIT
Rate this:
Please Sign up or sign in to vote.
This article describes the CS-Script C# Intellisense plugin for Notepad++ (CSScriptNpp).

This article describes the CS-Script C# Intellisense plugin for Notepad++ (CSScriptNpp). CSScriptNpp plugin turns Notepad++ into a light and yet fully functional IDE-like environment for developing and executing C# code.

https://www.codeproject.com/KB/Tools-IDE/694248/generic_view.png

Introduction

CSScriptNpp is an attempt to extend Notepad++ with the top-quality "code assistance" as well as to give users ability to exercise "free standing" C# code without any deployment or licensing pain usually associated with other IDEs.

While the plugin does not compete either directly or indirectly with any well know IDEs, it offers many core features commonly found in the well established IDEs like Visual Studio, Mono Develop or Eclipse.

The plugin delivers MS Visual Studio style User Experience but does not replicate it. CSScriptNpp will never match 100% the editing power of Visual Studio and Visual Studio will never match the simplicity and high availability of CSScriptNpp.

The high availability of CSScriptNpp is attributed to the Notepad++ plugin deployment model. The only step you need to perform in order to start using CSScriptNpp is to activate it in the Notepad++ Plugin Manager:
https://www.codeproject.com/KB/Tools-IDE/694248/plugin_manager.png

Note: after the installation you may want to check for the latest CSScriptNpp version from the About Box.

The plugin allows execution of the C# code (scripts) directly from Notepad++, without the need for any infrastructure (e.g. project file). It also offers convenient launching of the C# scripts with the system CLR Debugger (e.g. VS) attached.

The plugin can also be used to prepare simple deployment packages (or executables) for executing the scripts on the systems without any CSScriptNpp component (or even Notepad++) installed.

The following is a complete list of the all plugin features:

  • Intellisense related features:
    • CLR type members auto-complete
    • Add missing 'using'
    • Show CLR type quick info (when hovering mouse over the type member)
    • Show Method Overloads popup.
    • Go to definition (F12)
      • in the source code
      • in the reconstructed referenced assembly API interface (including XML documentation)
    • Smart Indentation
    • Formatting C# source code
    • CodeMap - panel with the class members of the current .cs document
  • Support for 'plain vanilla' ECMA-compliant C# syntax
  • Inclusion of the dependency scripts via CS-Script directives
  • Implicit assembly referencing via automatic resolving namesspaces into assemblies
  • Explicit assembly referencing via CS-Script directives
  • Intercepting Debug output
  • Intercepting Console output
  • Conventional build/execution error reporting
  • Preparing the script deployment package so it can be executed outside of Notepad++.

In this article I will only describe plugin's major features and the technical aspects (and challenges) of their implementation.

Acknowledgement

The CSScriptNpp plugin relies on a number of third-party solutions, of which two deserve special mentioning: CSharpCode.NRefactory and NppPlugin.NET. These two brilliant frameworks made CSScriptNpp possible. While other alternative solutions could be used, I wouldn't try to undertake such a challenging development without these two extraordinary solutions.

Overview

It is difficult to find someone developing on Windows who haven't heard about Notepad++. By many it is considered the best text editor and a "must have" source code editing tool. Its well deserved reputation is attributed to the clever architecture and close to flawless implementation.

Notepad++ is based on the text rendering engine Scintilla, which has been utilized by a number of source code editors. Apart from being very fast and rich in features, Scintilla has a very strong emphasis on the source code editing tasks. Notepad++ delivers all benefits of Scintilla and also extends them by allowing multi document editing as well as many other features. But arguably the most intriguing feature of Notepad++ its pluggable architecture. Thus the features, which are not available out of the box can be delivered via the third party plugins.

While Notepad++ is packed with features, there are still some gaps to be filled. Thus the auto-completion is entirely context ignorant. It is nothing else but a list of the "favourite words" grouped by the type of the source code documents. This may be OK for the interpreted languages it is not so for the compiled languages like C#. The comfort level of editing C# code with Notepad++ is not even comparable with that offered by Visual Studio. And this is exactly what the presented plugin CSScriptNpp is trying to resolve.

Not only it delivers the true context specific code auto-completion (like VS Intellisense) but is also allows convenient code execution, as well as many other features commonly found in the full scale IDEs.

I do believe that despite the fact that Visual Studio offers practically unbeatable code editing power, there is a strong need for an alternative tools with a smaller footprint, lighter runtime and more liberal licencing.

I was sincerely impressed by the unconventional motivation of Rob Eisenberg for his Caliburn.Micro. He said: "My vision was to take 90% of Caliburn’s features and squash them into 10% of the code". It is exactly how I feel about CSScriptNpp. Though in my case I was "squashing" Visual Studio features. I do not think that the plugin delivers 90% of them. May by just 70% of the most commonly used ones. And the effort and the codebase size is probably <1%.

The Intellisese related features implemented with the help of NRefactory but the heart of the plugin is the CS-Script execution engine - my another pet-project.

I always felt that CS-Script is kind of incomplete without a rich dedicated editor. I even made a serious attempt to develop one. I spend quite some time reverse engineering the SharpDevelop and have almost completed a C# dedicated editor - custom WinForm based editor wrapping the pre-version-5 NRefactory.

However I was not satisfied with its performance and not generic enough nature. Thus I canned the project and instead concentrated on the integrating CS-Script with Visual Studio (CS-Script VS Tools). But I always felt jealousy towards Notepad++ for its ultimate availability, impressive performance and extremely light nature. This was my another strong motivation for developing this plugin .

The CSScriptNpp is one of two CS-Script plugins for Notepad++. The second one is NppScripts - the plugin for automating Notepad++ with scripts written in C#. Its development is completed (it will be published in a few weeks) but it is a subject for another article.

Plugin Architecture Highlights

Hosting
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 container is a rather 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 native exporting symbols. Thus it makes possible for unmanaged host applications like Notepad++ to host an ordinary assembly directly, without any need for wrappers. The project template also provides an interface (structs, constants etc.) for the all Notepad++ functionality normally available within any other plugins.

Intellisense All code analysis features (e.g. Intellisense) are based on ICSharpCode.NRefactory (part of SharpDevelop IDE). Arguably it is the most mature Open-Source solution available today for parsing C# code and building SynatxTree. It even has code auto-completion already implemented out of the box. However the reality is a bit more complicated. NRefactory has very little (if any) documentation. 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 some time and effort, to reverse engineer the API but eventually I managed to integrate NRefactory with the Notepad++ plugin.

This, however wasn't the only challenge. When I made my first attempt for the C# editor (about 4 years ago) I wrapped ICSharpCode.NRefactory.dll into a more manageable generic adapter. In 2013 I tried to reuse that wrapper and to my disappointment I released that I had to start it all over again because the NRefactory API had changed completely. Now it is called NRefactory5.

Today NRefactory5 still has some features not finalized but it suits CSScriptNpp purpose quite well. Thus, it was possible to implement auto-completion (like MS Intellisense), "Go To Definition", "Find All References", "Add Missing Usings" and all cases of "Show Member Info".

CS-Script integration
The script execution and dependencies management is implemented with CS-Script execution engine. You can find the full details about this in my CodeProject article "C# Script: The Missing Puzzle Piece". But to put it simple, CS-Script allows execution of the plain-vanilla (ECMA-compliant) C# code without building the executable or maintaining any infrastructure (like VS project). With CS-Script it is also possible to express dependencies (referenced assemblies and other scripts) directly from the script code. Note that you do not need to have CS-Script installed as the plugin contains the minimal set of CS-Script assemblies required for the script execution.

Developers who are already familiar with CS-Script and particularly with the Visual Studio extension "CS-Script tools for VS2012-13" will most likely find themselves comfortable with CSScriptNpp as well. The user experience is very similar. In fact CSScriptNpp allows loading the script in Visual Studio with just a single click of the toolbar button. This can be useful when your script needs the full power of Visual Studio (e.g. integrated debugger):

https://www.codeproject.com/KB/Tools-IDE/694248/vs_integration1.png

 

Usage Many plugin features are straight forward and self explanatory. You can find all details about how to use any
specific feature here. But the simplest use-case is as follows:

  • Make Project panel visible by clicking on the toolbar button or selecting menu item Plugins->CS-Script->Project Panel

    https://www.codeproject.com/KB/Tools-IDE/694248/project_panel.png

  • Create and load new script
    https://www.codeproject.com/KB/Tools-IDE/694248/create_new.png
     
  • Modify the script and validate it with F7 or Ctrl+Shift+B or just click the validate button:
    This step is optional.
    https://www.codeproject.com/KB/Tools-IDE/694248/validate.png
     
  • Now you can execute the script with F5

Execution/Tracing/Debugging When executing the script you have an option to do this as a completely separate external process (Shift+F5) or you can allow CSScriptNpp to listen to the Debut Output messages (F5). This interesting feature is based on the already existing DbMon.Net solution and all credit should go to its creator Christian Birkl. DbMon.Net intercepts all Debug.Write* and Trace.Write* messages and prints them in the Output Panel. You can also use this feature to listen to all Debug messages on the system (similar to SysInternals Dbgview.exe).

https://www.codeproject.com/KB/Tools-IDE/694248/debug_simple.png
CSScriptNpp also allows intercepting Console Output messages.

https://www.codeproject.com/KB/Tools-IDE/694248/console_out.png

Though if your console also expects some user input then intercepting StdOut is not very practical as it hides the actual console window.

A part from capturing the debug output later versions of plugin feature the integration with MDbg (by Microsoft). 

 https://www.codeproject.com/KB/Tools-IDE/694248/debugger_full.png

Code Navigation The code navigation functionality consist of the following features:

  • Advanced text search functionality provided by Notepad++.
  • Conventional "Find All References" and "Go To Definition", which work very similar to the same functionality in Visual Studio. This also includes reconstruction (decompilation) of the referenced assembly interface with its XML documentation.
  • CodeMap - current document class members list. No equivalent feature is available in Visual Studio and it can only be achieved via VS extensions.
    This feature is particularly useful when working with the large size source code, e.g. with reconstructed (decompiled) referenced assemblies:

    https://www.codeproject.com/KB/Tools-IDE/694248/code_tree.png

Formatting
Code auto-formatting is an essential part of any modern IDE. And I considered it as a must-have feature for CSScriptNpp.

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

It is not a real full scale C# parser either by its reliability or by its functionality (or by the elegancy for that matter). But it does the work. This simple brackets matching engine allows achieving the plugin functionality otherwise impossible without fixing/extending ICSharpCode.NRefactory.

Limitations

It is important to be aware of the plugin limitations. The most obvious one is that the quality of Intellissense is as good as its engine (ICSharpCode.NRefactory). I have identified quite a few NRefactory limitations in the areas relevant to CSScriptNpp. While awaiting NRefactory updates with improvements I have implemented some work around. However, the latest NRefactory update did not bring any improvement but instead broke what already worked. So I had to ignore the update. Unfortunately NRefactory is in the permanent "move" and its API is quite "fluid", thus, I do not plan migrating to the new version of NRefactory unless there is a very strong case for it.

CSScriptNpp is intended for the small to medium scale of scripted applications. It is unlikely it can be as effective for the large products, particularly those based on the heterogeneous source content (Resources, XAML, T4 etc.).

The initial positions of the docked windows in the first release is not handled accurately. This results in the CSScriptNpp panels needing to be docked manually on the first ever loading. After that their proper docking will be persisted and maintained by Notepad++ correctly.

Points of Interest

As part of the plugin development I also completed a few micro-projects with their own distinctive functionality:

Reflector - assembly decompiling solution that reconstructs the assembly interface as C# code. Visual Studio does this as well but I think that CSScriptNpp does this slightly better.

Code Formatting - despite not being ideal it possesses a good balance of functionality and practicality.

Debug Monitor - inexpensive but very functional and reusable solution.

Keyboard Interception - simple reusable solution for the application-wide key stroke monitoring. It allowed Notepad++ and CSScriptNpp overlapping shortcuts (e.g. F5) to be handled without any collisions.

Auto Updates - The Notepad++ Plugin Manager is a fantastic vehicle for delivering a product to the user. However its release schedule (every one or two month) does not favor a responsive product support. Thus, I have develop checking and applying updates from the AboutBox. Updates are sourced from the CS-Script server and implemented as MSI. Interestingly enough, the MSI updates authored with Wix# (my yet another pat project).

Classless scripts - CS-Script always supported classless scripts - free standing C# code without the class definition. But no editing tools (including VS) can fully support such a code. And only Notepad++ offers the same level of support for both normal and classless C#. In fact when I started using CSScriptNpp the classless format became my default choice.
Note classless format allows optional substitution of 'Main' with 'main':

//css_args /ac 
using System; 

void main(string[] args) 
{ 
   Console.WriteLine("Hello World!"); 
} 

Conclusion

There were a few reasons for CSScriptNpp development. I wanted Notepad++ to be equipped with the first class auto-completion (equal to MS Intellisense). I wanted CS-Script to have a first class dedicated editor capable of utilizing the script engine potential.

But I also had another less obvious but very strong motivation...

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 CodeProject solutions for batch renaming utilities, downloaders, directory synchronizers or yet another MP3 file tags organizer. This sort of utilities often attracts full scale application development (and even deployment solutions) though in many cases the same result can be achieved with just a few lines of high level language code (see Samples section). And the CSScriptNpp plugin allows executing such a code within Notepad++. It also allows preparing the scripts for running them on PC where Notepad++ is not even installed.

I think Notepad++ with CS-Script give us a good opportunity to jump behind our desks 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 just for the sheer fun of it.


Samples

The samples below are not to describe C# scripting as such. They are just to give you an idea about what the type of C# code can now be executed directly from Notepad++:

This tiny script allows embedding the track and name tags of the MP3 file into the file name for all files in the current directory:

//css_args /ac 
//css_ref lib\taglib-sharp.dll 
using System.IO; 
using System; 

void main() 
{ 
    foreach(string file in Directory.GetFiles(".", "*.mp3")) 
    { 
        var mp3 = TagLib.File.Create(file); 

        string fileName = string.Format("{00}.{1}.mp3", mp3.Tag.Track, mp3.Tag.Title); 
        string dir = Path.GetDirectoryName(file); 
        File.Move(file, Path.Combine(dir, fileName)); 
    } 

   Console.WriteLine("Done..."); 
} 

This script demonstrates the use of Async feature of .NET 4.5:

//css_args /ac 
using System.Threading; 
using System.Threading.Tasks; 
using System; 

void main(string[] args) 
{ 
    Execute(); 
    Console.ReadLine(); 
} 

async void Execute() 
{ 
    await Task.Run(()=> 
    { 
        Thread.Sleep(1000); 
        Console.WriteLine("Continue"); 
    }); 
    Console.WriteLine("Done"); 
}  

License

This article, along with any associated source code and files, is licensed under The MIT License

Share

About the Author

Oleg Shilo
Technical Lead
Australia Australia
I was born in Ukraine. After completing the university degree worked there as a Research Chemist. Last 18 years I live in Australia where I've got my second qualification as a Software Engineer.

"I am the lucky one: I do enjoy what I am doing!"

You may also be interested in...

Comments and Discussions

 
GeneralMy vote of 1 Pin
Member 1241033818-Apr-16 15:00
memberMember 1241033818-Apr-16 15:00 
GeneralRe: My vote of 1 Pin
Oleg Shilo18-Apr-16 15:20
memberOleg Shilo18-Apr-16 15:20 
QuestionInstall Fail Pin
Member 1241033818-Apr-16 14:59
memberMember 1241033818-Apr-16 14:59 
AnswerRe: Install Fail Pin
Oleg Shilo18-Apr-16 17:10
memberOleg Shilo18-Apr-16 17:10 
QuestionNot compatible with Notepad++ v6.8.3 Pin
atoi_powered5-Oct-15 5:53
memberatoi_powered5-Oct-15 5:53 
AnswerRe: Not compatible with Notepad++ v6.8.3 Pin
Oleg Shilo5-Oct-15 16:00
memberOleg Shilo5-Oct-15 16:00 
QuestionExcellent piece of software Pin
Member 836678023-Jul-15 12:02
memberMember 836678023-Jul-15 12:02 
AnswerRe: Excellent piece of software Pin
Oleg Shilo23-Jul-15 17:31
memberOleg Shilo23-Jul-15 17:31 
GeneralThank you very much. Pin
EncodeTheCode!5-Mar-15 6:05
memberEncodeTheCode!5-Mar-15 6:05 
GeneralMy vote of 5 Pin
Shemeer NS1-Nov-14 5:44
mvpShemeer NS1-Nov-14 5:44 
GeneralMy vote of 5 Pin
_Noctis_31-Oct-14 16:51
professional_Noctis_31-Oct-14 16:51 
GeneralRe: My vote of 5 Pin
Oleg Shilo4-Nov-14 2:14
memberOleg Shilo4-Nov-14 2:14 
GeneralMy vote of 5 Pin
S. K. Tripathi30-Oct-14 20:10
professionalS. K. Tripathi30-Oct-14 20:10 
QuestionHigh Five Pin
netizenk30-Oct-14 10:55
membernetizenk30-Oct-14 10:55 
GeneralMy vote of 5 Pin
djklord30-Oct-14 8:39
memberdjklord30-Oct-14 8:39 
GeneralRe: My vote of 5 Pin
Oleg Shilo4-Nov-14 2:16
memberOleg Shilo4-Nov-14 2:16 
GeneralRe: My vote of 5 Pin
djklord5-Nov-14 3:54
memberdjklord5-Nov-14 3:54 
GeneralThumbs Up Pin
Bilal Haider30-Oct-14 1:07
memberBilal Haider30-Oct-14 1:07 
GeneralRe: Thumbs Up Pin
Oleg Shilo30-Oct-14 3:27
memberOleg Shilo30-Oct-14 3:27 
Questiongood one :) Pin
sunny122929-Oct-14 21:45
membersunny122929-Oct-14 21:45 
AnswerRe: good one :) Pin
Oleg Shilo30-Oct-14 3:30
memberOleg Shilo30-Oct-14 3:30 
GeneralMy vote of 5 Pin
peteSJ29-Oct-14 14:28
memberpeteSJ29-Oct-14 14:28 
GeneralRe: My vote of 5 Pin
Oleg Shilo29-Oct-14 14:32
memberOleg Shilo29-Oct-14 14:32 
GeneralMy vote of 5 Pin
majid torfi29-Oct-14 2:46
membermajid torfi29-Oct-14 2:46 
GeneralMy vote of 5 Pin
majid torfi27-Oct-14 23:44
membermajid torfi27-Oct-14 23:44 
GeneralRe: My vote of 5 Pin
Oleg Shilo30-Oct-14 3:31
memberOleg Shilo30-Oct-14 3:31 
QuestionArguments for the debugger Pin
Michael Betser13-Jun-14 17:25
memberMichael Betser13-Jun-14 17:25 
AnswerRe: Arguments for the debugger Pin
Oleg Shilo13-Jun-14 17:40
memberOleg Shilo13-Jun-14 17:40 
GeneralRe: Arguments for the debugger Pin
Michael Betser12-Aug-14 14:20
memberMichael Betser12-Aug-14 14:20 
GeneralRe: Arguments for the debugger Pin
Oleg Shilo12-Aug-14 22:34
memberOleg Shilo12-Aug-14 22:34 
GeneralRe: Arguments for the debugger Pin
Oleg Shilo13-Aug-14 19:54
memberOleg Shilo13-Aug-14 19:54 
SuggestionIssue with the strings Pin
Trần Hùng Cường6-Jun-14 0:54
memberTrần Hùng Cường6-Jun-14 0:54 
GeneralRe: Issue with the strings Pin
Oleg Shilo6-Jun-14 3:27
memberOleg Shilo6-Jun-14 3:27 
QuestionMy function is too long, so i cannot see all function hint Pin
Trần Hùng Cường23-Apr-14 19:38
memberTrần Hùng Cường23-Apr-14 19:38 
AnswerRe: My function is too long, so i cannot see all function hint Pin
Oleg Shilo25-Apr-14 5:37
memberOleg Shilo25-Apr-14 5:37 
GeneralRe: My function is too long, so i cannot see all function hint Pin
Trần Hùng Cường25-Apr-14 19:08
memberTrần Hùng Cường25-Apr-14 19:08 
GeneralRe: My function is too long, so i cannot see all function hint Pin
Oleg Shilo25-Apr-14 23:10
memberOleg Shilo25-Apr-14 23:10 
GeneralRe: My function is too long, so i cannot see all function hint Pin
Oleg Shilo11-May-14 1:03
memberOleg Shilo11-May-14 1:03 
GeneralRe: My function is too long, so i cannot see all function hint Pin
Trần Hùng Cường11-May-14 18:05
memberTrần Hùng Cường11-May-14 18:05 
GeneralMy vote of 4 Pin
Trần Hùng Cường23-Apr-14 19:15
memberTrần Hùng Cường23-Apr-14 19:15 
GeneralThanks Pin
MCavallaro28-Mar-14 1:14
memberMCavallaro28-Mar-14 1:14 
GeneralRe: Thanks Pin
Oleg Shilo30-Mar-14 3:17
memberOleg Shilo30-Mar-14 3:17 
Question. This look great Pin
irneb24-Mar-14 0:14
memberirneb24-Mar-14 0:14 
AnswerRe: . This look great Pin
Oleg Shilo24-Mar-14 0:32
memberOleg Shilo24-Mar-14 0:32 
GeneralMy vote of 5 Pin
Alfred Loeffler18-Mar-14 11:51
memberAlfred Loeffler18-Mar-14 11:51 
GeneralRe: My vote of 5 Pin
Oleg Shilo18-Mar-14 16:34
memberOleg Shilo18-Mar-14 16:34 
GeneralMy vote of 5 Pin
mrmike18-Mar-14 4:05
membermrmike18-Mar-14 4:05 
GeneralRe: My vote of 5 Pin
Oleg Shilo18-Mar-14 12:44
memberOleg Shilo18-Mar-14 12:44 
BugA typo Pin
alex2001_ts17-Mar-14 8:57
memberalex2001_ts17-Mar-14 8:57 
GeneralRe: A typo Pin
Oleg Shilo17-Mar-14 14:58
memberOleg Shilo17-Mar-14 14:58 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.170118.1 | Last Updated 29 Oct 2014
Article Copyright 2013 by Oleg Shilo
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid