Friday 5 December 2014

PowerShell and Notepad++ - Adding custom keyword highlighting

I've been playing around with using Notepad++ as my PowerShell script editor of choice.  I like ISE, I just fancied a change.  Sure, ISE has some really nice intellisense and syntax highlighting features but Notepad++ just feels quicker.

Notepad++ includes native support for PowerShell syntax highlighting (yay!) but this didn't include all the cmdlets I have available on my system.  This isn't surprising, there's a huge amount available through various modules, but it's a little bit annoying to have some highlighted and others not.

There is support for adding custom keywords through the style configurator (see here for an example) but I didn't like this.  I had far too many to add for a start.  And it messed up my stylers.xml file.  I'm a bit anal about this but when I added a keyword through the style configurator my stylers.xml changed from:

<WordsStyle name="CMDLET" styleID="9" fgColor="804000" bgColor="293134" fontName="" fontStyle="0" fontSize="" keywordClass="instre2">

to:

<WordsStyle name="CMDLET" styleID="9" fgColor="804000" bgColor="293134" fontName="" fontStyle="0" fontSize="" keywordClass="instre2">new-keyword</WordsStyle>

Yeah, that annoyed me.  It just looked kinda messy.  Especially when there's a really nice list of keywords already in langs.xml.

<Keywords name="instre2">add-content add-history add-member add-pssnapin clear-content clear-item clear-itemproperty...etc...</Keywords>

I really don't think editing langs.xml directly is supported.  I think you run the risk of losing your changes on the next version of Notepad++.  It's much prettier though.  So all I need to do is add the missing keywords into that xml tag and job's a good 'un.  So where do I get them from?  From PowerShell.

Using the Get-Command cmdlet after loading all the modules I use will show me all cmdlets (yay!).  With a bit of tinkering this can be formatted to suit the xml format of the tags.  That being, space between each tag and everything in lower case.  Lower case seems to be important, it wouldn't work without that.  That gave me this:

[string]$commands = (get-command).name; foreach ($c in $commands) {$c.ToLower() + " " >> commands.txt}

Long story short, this pulls all the cmdlets from my PowerShell session and leaves them in commands.txt in a format that's ready to cut and paste into langs.xml.  There's probably a nicer way to do this but, hey, I'm just learning PowerShell.

Copy and paste the contents of commands.txt into langs.xml in the <Keywords name="instre2">  tag and you get syntax highlighting for them all.  Very nice!

One other thing to point out, you will find some extra entries in your keywords you weren't expecting, such as all your drive letters.  That's because they are technically a command in PowerShell.  You can either tidy these up manually, regex them out or improve on the initial command above so they don't appear in the first place.  I haven't quite gotten around to that yet.


No comments: