Creating a plugin that actually does something

From Code::Blocks

NOTE: this article is a work in progress.

In this article we are going to create a "real" plugin. That is a plugin that actually does something more elaborate than just greeting the world ;).

Interpreted languages support plugin

We are going to create a plugin that will add support for interpreted languages in Code::Blocks. "Interpreted" are considered the languages that do not generate native machine code but rather generate an intermediate code that an interpreter understands and converts to native machine code at runtime.

Planning stage

While we 're in the early development stage (a.k.a. planning), let's decide what this plugin will be able to do and what it won't. This plugin should allow the user to:

  • define as many interpreters as needed
  • associate specific file extensions with each interpreter
  • run any interpreter's shell
  • run any interpreter with the appropriate arguments to operate on or accept as input a source file (more on that below)

As you see, while we 're not over-complicating things, we should hopefully end up with a really useful plugin :).

Data structures

Let's decide now what structures we will need (code-wise) to store the above requirements and their relationships.

Requirement: define as many interpreters as needed.

Since we don't want to impose any limits, we need a dynamic container of some sort. I guess std::vector will suite us just fine :).

Requirement: associate specific file extensions with each interpreter.

A simple semicolon-separated string will suffice. E.g. "*.py;*.pyc".

Requirement: run any interpreter's shell.

A string is enough. E.g. "C:\Python\Python24\pythonw.exe".

Requirement: run any interpreter with the appropriate arguments to operate on or accept as input a source file.

So we need a dynamic array holding somekind of struct defining the available actions. Because nothing beats a good example, here is the most common (and important action): "Run". This action would cause the interpreter to be launched with the source file as argument and run it.

struct InterpreterAction
   wxString name; // the action's name, e.g. "Run"
   wxString command; // the command, e.g. "$interpreter --run $file"

The final struct that glues all of the above together is this:

struct Interpreter
   wxString name; // a friendly name for the interpreter
   wxString executable; // the full path to the interpreter's executable
   wxString extensions; // a semicolon-separated list of extension wildcards (e.g. "*.py;*.pyc")
   std::vector<InterpreterAction> actions; // an array of possible actions with this interpreter

Implementation stage

Let's roll our sleeves up and start working on this plugin :).

First thing we need is to create a new project for this plugin. Thankfully, the Code::Blocks Team has already provided us with a nice and easy wizard that will generate all the boilerplate code for us. Let's get going.

Click on "File->New->Project" and a dialog with the available project wizards will appear. Select the "Code::Blocks plugin" and click "Go". Intlng 1.png

This will start the Code::Blocks plugin wizard. The first page of this wizard displays some important info which you should read. When you 're done reading, click "Next".

Now enter the plugin's title, e.g. "Interpreted languages support". If you don't need to edit anything else in this page (like the destination directory), click "Next".

Intlng 2.png

In this page, we must decide what type of plugin we want to make as well as its name. For the name enter "InterpretedLangs". Also, set the plugin's type to "Generic". For more info on the various plugin types and their differences, see the Code::Blocks SDK documentation. Finally, make sure you check the options as seen in the picture above. This will allow our plugin to add a configuration page in the Code::Blocks settings dialogs and generally integrate nicer. Click "Next".

In the next page, fill in any info you deem appropriate for this plugin. Click "Next".

In the compiler page, select (if not already selected) the "GCC" compiler because that's what Code::Blocks is built with.

Finally click "Finish".

You should find yourself in Code::Blocks again with the new plugin project open and ready for editing :). But first let's see if this compiles. If it doesn't, don't bother reading more. This article assumes a valid development setup from your side...

Note that the Code::Blocks plugin wizard was kind enough to add some post-build commands that will copy the plugin and its resources where Code::Blocks expects to find them. It even set Code::Blocks as a "host" application for our plugin (which is a dynamic library and can't run on its own). This means that after you build the plugin, you can "run" it too :).

Go on, build and run it. Does it work? OK, let's move on :)

To be continued...

Mandrav 06:51, 22 September 2006 (EDT)