Creating your first Programmer's Notepad extension

PyPN provides a great way to add functionality to Programmer’s Notepad by writing simple Python code, but you might want to do something more advanced. For this there’s the Programmer’s Notepad Extension SDK.

The SDK lets you extend PN using C++, allowing you to react to editor events and provide new commands in the menu. PyPN is itself implemented as an extension using this same SDK, and you can use the SDK to provide support for other scripting languages too.


What You’ll Need

You need a Windows C++ compiler and the Boost C++ library. Note that you don’t need to compile any of boost, we use the header-only bits.

I suggest using the free Microsoft Visual C++ Express if you don’t already have Visual Studio, this should guarantee compatibility.

Getting Started

Download the SDK and copy the template project, this is a good base for your extension. Note that the SDK also contains a demo extension showing use of various parts of the SDK. Change the name and version of your extension and you’re ready to add it to Programmer’s Notepad for the first time:

[sourcecode language=’cpp’]void __declspec(dllexport) __stdcall pn_get_extension_info(PN::BaseString& name, PN::BaseString& version) { name = “My First Plugin”; version = “1.0”; }[/sourcecode]

Compile the extension and place the .dll file in your PN directory. Now run “pn –findexts” and your plugin will be discovered and loaded the next time you start PN. Go to Tools->Options->Extensions and see your extension listed.

Everything else you want to do flows from the instance of IPN that’s passed to your init function. This interface gives you access to the open documents, lets you sign up to handle document events and gives you access to app-level services like script registration, find in files and options management.

Working with Documents

Everything you want to do with an open document is done through the IDocument interface. You get a pointer to one of these from your IPN instance by calling GetCurrentDocument, NewDocument or equivalent.

[sourcecode language=’cpp’] // Make a new document IDocumentPtr doc = pn->NewDocument(NULL);

// Send scintilla messages (see documentation)
doc->SendEditorMessage(SCI_APPENDTEXT, 6, (LPARAM)"Hello!");

// Save changes
doc->Save("c:\\temp\\test.txt", true);

// Done with the document

This is the first in a series of posts that will become the introductory documentation for extensions. Next time we’ll look at how to add menu commands for your plugin. The series will be added to the docs site as we go: Writing your First Extension