SublimeText2 Plugin: RunBuild

I was talking to my coworker, Todd Anderson, today about running build systems in Sublime Text 2. It’s a great editor, very powerful and configurable. But somewhat of a lack of documentation on all those features. One problem we both had was setting up multiple build systems on a project, say one for running unit tests, one for running JSLint, one for deployment, etc. You can specify build systems right in a project file as per this reference: http://www.sublimetext.com/docs/2/projects.html. For a drop dead simple example, you could have one that launches your index.html file in chrome, and another that launches your unit tests in tests.html. This would look something like this:

[php lang=”JavaScript”]”build_systems”:
[
{
“name”: “preview”,
“cmd”: [“/usr/bin/google-chrome”, “$project_path/index.html”]
},
{
“name”: “test”,
“cmd”: [“/usr/bin/google-chrome”, “$project_path/tests.html”]
}
][/php]

Now, in your “Tools/Build System” menu you should have two entries: preview and build. You can choose one, and the next time you build it will do what you specified in that system. The problem is switching between them. Grab the mouse and go to Menu / Tools / Build System / test (or preview). Then, F7 or Ctrl-B to build. Or maybe you forgot which one you were on, so when you build it builds the wrong thing and you have to cancel and go back and check and redo it. Minor pain, but it gets annoying.

Ideally, you could assign a specific keyboard command to each build system. So I started digging in to see how to do this.

First Part of the Solution: set_build_system

After some digging around, I found that there’s an internal command called “set_build_system”. You pass it a single argument called “file”. The value is one of two things:

1. The path to a sublime-build file, such as “Packages/Java/Ant.sublime-build”

or

2. The name of a custom build path in your project file (like what we just created as “test” and “preview”.

You can use this command in a keyboard shortcut. Go to the Preferences menu, Key Bindings – User. This will open up a Default sublime-keymap file, which should contain an empty JSON array like this: [], unless you have already added some shortcuts. You can create shortcuts that will change your build system like so:

[php lang=”JavaScript”][
{ “keys”: [“ctrl+shift+p”], “command”: “set_build_system”, “args”: { “file”: “preview”} },
{ “keys”: [“ctrl+shift+t”], “command”: “set_build_system”, “args”: { “file”: “test”} }
][/php]

With this, Control-Shift-P will set your build system to your custom preview build system, and test likewise. But it’s still a two step process: set the system, then build. And again, there’s no visual indication of which system is currently set, and no visual indication of when it changes, so you’ll still find yourself checking manually in the menu to see which is checked.

Ideal scene again, would be one shortcut that chooses the system and then builds.

Second Part of the Solution: plugins

A keyboard shortcut can only run a single command. But we need to run two commands: choose the build system and then build. To do this, you can create a sublime text 2 plugin. This is far easier than it sounds. In fact, Todd and I were both pretty shocked at how easy it turned out to be and how quickly we got it working.

A plugin is a Python class that creates a custom command. It extends one of three plugin classes: WindowCommand, TextCommand, or ApplicationCommand. This post was very helpful in getting me started:

http://net.tutsplus.com/tutorials/python-tutorials/how-to-create-a-sublime-text-2-plugin/

Here’s the command that Todd and I came up with virtually at the same time:

[php lang=”Python”]import sublime, sublime_plugin

class RunBuildCommand(sublime_plugin.WindowCommand):
def run(self, build_system):
self.window.run_command( “set_build_system”, {“file”: build_system } )
self.window.run_command( “build” )[/php]

Running through it, this imports a couple of sublime packages, defines a class that extends WindowCommand, and a single method called run.

The run method takes a single parameter (besides “self” that all python methods get) which will be the name of the build system to run.

It then does the two things we need to do by making calls to self.window.run_command, passing in the command to run and any arguments.

First we call “set_build_system” like we did in the first keymap example. This passes through the build_system argument.

Then we call build, with no args.

So we’ve accomplished our two actions in a single stroke: set the build system, then build.

You can save this file as “RunBuild.py” anywhere in your Packages folder in Sublime’s config folder (check documentation to see where that is on your OS). I suggest you give it its own folder so it becomes /Packages/RunBuild/RunBuild.py.

Now we just need to change the keymap to call this custom command instead of set_build_system. The name of the class, RunBuildCommand, will be mapped to a command called “run_build”. CamelCase becomes camel_case in this setup. So we do this:

[php lang=”JavaScript”][
{ “keys”: [“ctrl+shift+p”], “command”: “run_build”, “args”: { “build_system”: “preview” } },
{ “keys”: [“ctrl+shift+t”], “command”: “run_build”, “args”: { “build_system”: “test” } }
]
[/php]

And we are done! Control-Shift-P launches index.html in the browser, and Control-Shift-T launches test.html. Of course, your build system(s) could be far more complex than the simple one I showed here, there you go.

This entry was posted in General, Technology. Bookmark the permalink.

4 Responses to SublimeText2 Plugin: RunBuild

  1. DannyT says:

    Been playing with Sublime for a short while and wanted to achieve the same. First result on google was Bit-101. Good to still find you’re still useful for my post-flash learning too! 😛

  2. Arthur Alvim says:

    Hey guys, That’s exactly what I was looking for.
    I am really grateful.

    I used it for changing the build system in LaTeX files.
    https://gist.github.com/2852859

    Thanks!
    ST2. Simply great. =)

  3. James T says:

    Thanks, very helpful. On Windows, RunBuild needed some help finding the build system files, here’s a variant of RunBuild that worked for me.

    https://gist.github.com/jamietre/5859816

Leave a Reply