www.xbdev.net xbdev - software development
Friday December 14, 2018
home | about | contact | Donations

     
 

Visual Studio

Making our life easier..

 

Visual Studio Colour Syntax Python (.py) Plug-in

How to write one - by Ben Kenwright

 

 

One of the great things about Visual Studio, is that it lets you write all sorts of useful plug-ins to make your working day so much easier.  You can add buttons for this and that...and theres tons of free plugins you can also download.  But its so much cooler to write your own plug-in.

A great thing you can do, is do your own colour syntax highlighting for your different programming languages.  One such programming language I use a lot on a day to day basis is Python Scripting.  So I thought I'd site down and write my own colour coding plugin for it.


First things first, you have to download the visual studio SDK and install it, as you need this so you can write the plugin.  Now I've found a few different ways of writing the colour syntax plugins, but the easiest to get you going, is to use the Language Syntax Code that comes with the SDK called Babel.

 

After installing the new SDK, you can click on the visual studio project and select new language pack.  After this you enter in all the fields, such as the language extension, where you want to create the project etc, etc.  Then it creates a project and thats its!  It should run and compile.   Well almost.

 

The default project uses Lex for its syntax information.  To determine which words are which colour and when to stop and start colour coding, such as with comments or quotes you have to define all these in the lex file.

 

Screenshot of Visual Studio 2005 with Colour Python Syntax Plugin

 

The version of visual studio I use the most is Visual Studio 2005, so this tutorial/sample code will work with that.  Later versions of Visual Studio work similarly but might need investigating more.

 

One of the hardest parts of writing the Plug-in is making it work without the SDK on any Visual Studio.  As when you run your visual studio program from within visual studio, it launches another version of visual studio with is used for experimental testing.  Usually launching visual studio with the extension 'Exp8.0'  ...where the Exp is for Experimental.

And when you try and run it on the main version of visual studio, you'll have problems because it requires an authorisation key which you have to logon to the ms sdk website and register with to get.  And they email you this unique key back which you need to include in the registry so it can work on any visual studio that you include your plug-in with.

 

 

%{
%{ #include "service.h" #include "parser.cpp.h" %} White0 [ \t\r\f\v] White {White0}|\n ident {nmstart}{nmchar}* name {nmchar}+ nmstart [a-zA-Z]|{nonascii}|{escape} nonascii [^\0-\177] unicode \\[0-9a-f]{1,6}[ \n\r\t\f]? escape {unicode}|\\[ ~\200\4177777] nmchar [a-z0-9-]|{nonascii}|{escape} num [0-9]+|[0-9]*\.[0-9]+ thing \\\" string {string1}|{string2} string1 \"([\t !#$%&(-~]|\\{nl}|\'|{nonascii}|{escape}|{thing})*\" string2 \'([\t !#$%&(-~]|\\{nl}|\"|{nonascii}|{escape})*\' comment #([\t !#$%&(-~]|\\{nl}|\"|\'|{nonascii}|{escape})*\n nl \n|\r\n|\r|\f w [ \t\r\n\f]* %% {comment} { return LEX_COMMENT; } {string} { return STRING_QUOTE; } if { return KWIF; } else { return KWELSE; } while { return KWWHILE; } for { return KWFOR; } del { return KWDEL; } from { return KWFROM; } not { return KWNOT; } as { return KWAS; } elif { return KWELIF; } global { return KWGLOBAL; } with { return KWWITH; } assert { return KWASSERT; } pass { return KWPASS; } yield { return KWYIELD; } break { return KWBREAK; } except { return KWEXCEPT; } import { return KWIMPORT; } print { return KWPRINT; } class { return KWCLASS; } exec { return KWEXEC; } in { return KWIN; } raise { return KWRAISE; } continue { return KWCONTINUE; } finally { return KWFINALLY; } is { return KWIS; } return { return KWRETURN; } def { return KWDEF; } lambda { return KWLAMBDA; } try { return KWTRY; } and { return KWAND; } or { return KWOR; } False { return MFALSE; } True { return MTRUE; } [a-zA-Z_][a-zA-Z0-9_]* { return IDENTIFIER; } [0-9]+ { return NUMBER; } ; { return ';'; } , { return ','; } \( { return '('; } \) { return ')'; } \{ { return '{'; } \} { return '}'; } = { return '='; } \^ { return '^'; } \+ { return '+'; } \- { return '-'; } \* { return '*'; } \/ { return '/'; } \! { return '!'; } == { return EQ; } \!= { return NEQ; } \> { return GT; } \>= { return GTE; } \< { return LT; } \<= { return LTE; } \& { return '&'; } \&\& { return AMPAMP; } \| { return '|'; } \|\| { return BARBAR; } \. { return '.'; } \[ { return '['; } {White0}+ { return LEX_WHITE; } \n { return LEX_WHITE; } . { yyerror("illegal char"); return LEX_WHITE; } %% #include
Python Lex (.lex) Specification for Colour

 

The hardest part for me, was actually putting the lex together...as I'd never used the lex syntax before and to get it to work with all the cases was pretty tricky.  Best way to start is to just start simple, just highlight keywords, then try and add in comments then you add in any misc things you need like strings or special characters in different colours.

 

The colour syntax example includes all the source and a valid PLK hash so you can install it on any visual studio.  I also wrote an install bat which you can look at, which shows which parts of the registry the installed package dll needs to be linked in to for it to open with .py files.

 

Not that you also need to have the babel package dll for the custom package to work.  But you can install that when you install your package.

 

Hopefully this has given you some insight into how you can write your own plugins.  Its a little tricky at first but once you get it to run once, its all down hill from then onwards.

 

Happy coding.

Download Source Code & Executable (480k)

 

Compiled with Visual Studio 2005 and Babel & Lex

 

 

 

 

 

 

 

 

 

 

 


 

 

 

 

 

 

 

 

 
 Visitor: 9534626  { 209.237.238.175 } Copyright (c) 2002-2017 xbdev.net - All rights reserved.
Designated tutorial and software are the property of their respective owners.