Scratching My Own Itch: Create Github Gists from within BBEdit


I type a lot. Sometimes it’s source code and sometimes it’s English, but I spend a good amount of my time moving the cursor to the right in one way or another.

Because I type so much, it’s important to me that I have the best tools for the job I’m currently doing. Not too long ago, I changed my primary text editor from the venerable vim to the (relatively) new kid on the block, Sublime Text 2. ST2 was far more Mac-like than vim (yes, even the MacVim variant), but it really lacked polish. So, I hopped over to the App Store and dropped more than a little cheddar on what has become my new text editing home: the grand poobah of them all, BBEdit.

It’s been great. BBEdit has its quirks and I’ve had to learn new ways to perform common tasks, but I’m really happy.

The Problem

Much of my daytime work for Evernote involves explaining how a given chunk of source code works. I routinely utilize Github’s gist facility to quickly publish some code and easily embed it in the web page I’m writing (here’s an example).

One feature I really loved about Sublime Text 2 (which isn’t a native feature, but was provided by an add-on package) was the ability to quickly create gists without leaving the app: highlight a few lines of code or whatever, strike a key chord and fill in a couple of fields (filename and description). A few seconds after hitting Return, the gist would be created and the URL would be in my pasteboard.

Sadly, BBEdit has no such capability, either out of the box or with a third-party add-on.

So, I built it.

The Thing

(Warning: lots and lots of nerdy programming talk ahead)

The solution is comprised of two parts: a Python program, makeGist.py, that creates gists and a small AppleScript program that provides the interface between BBEdit and the Python program. Let’s quickly discuss each, shall we?

makeGist.py

As previously mentioned, this program lets you create gists from the command line. It can actually be used on its own if you feel so inclined. Running it looks like this:

python makeGist.py -f filename.txt -d "gist description" -c "contents of the gist"

Running that exact command will produce this result:

$ python makeGist.py -f filename.txt -d "gist description" -c "contents of the gist"
https://gist.github.com/14bf8c1e27bf15a6ed14 

(I’m also leaving the gist up if anybody wants to see that I’m not lying).

There’s also an optional -p parameter, which will create a public gist (the default behavior is to create private gists).

In a nut, each of these parameter values is shoehorned into a simple value object, then converted to JSON and sent to the Github gist API. Since, chances are, most of you reading this don’t really care about what all that means, I’ll let those who are interested peruse the source code.

Once it’s done doing its business, it prints out the HTTP URL of the gist to the console.

Now, the part that ties it to BBEdit…

Make BBEdit Gist.scpt

This monstrosity merely provides the user interface to makeGist.py. Specifically, it does the following:

  1. Grabs the current directory (so it knows where to find makeGist.py).
  2. Defines an absurdly long shell command (which is how makeGist.py is run).
  3. Prompts the user for a gist description and lets them choose a public or private gist.

When the script is run, the user is greeted with this awful dialog:

Yep, pretty awful, but it gets the job done and I couldn’t design my way out of a wet paper sack and I’m fine with all of it.

Once the user completes the single field and clicks one of the buttons (assuming it’s not the Cancel button which, like it says on the tin, aborts the app), it asks BBEdit for the selected text in the front-most buffer. If no text is selected, it takes all of the text in the front-most buffer. That text, combined with the options chosen by the user, are used to construct the parameters to makeGist.py. The script is run and the output—the URL of the newly-minted gist, if all went well—is shoved into the system pasteboard.

Using the Thing

First, download the source files from Github. You need both the Python script and the AppleScript file. Drop them both into ~/Library/Application Support/BBEdit/Scripts/.

Next, open makeGist.py and update github_user and github_pass to your Github username and password.

Finally, restart BBEdit and you should see “Make BBEdit Gist” in the Scripts menu. Highlight some text (or don’t), then click that menu item. Assuming the bailing wire and chewing gum didn’t give way, you’ll have a gist URL in your clipboard in a couple of seconds. Spiffy!

What’s Wrong with The Thing

Because I’m not actually a real programmer, I’m shipping this thing with some known issues. Like you do.

Let’s start with authentication.

As it stands right now and like I mentioned a second ago, you’ll need to populate the github_user and github_pass variables at the top of makeGist.py before you can use it. These credentials are used to procure an auth token from Github which is then used to create gists. I’m not sure how long these auth tokens are valid and I wanted to avoid having to build in a UI for the user to enter their Github login, so this is where I landed. I understand there’s some awesome gitcredentials madness available, but I’m not that smart and I haven’t had oodles of free time to investigate it.

Next, user interface.

There are currently no alerts or notifications when a) the process is finished or b) there was a problem. These can be chalked up to my inexperience with AppleScript and, frankly, a bit of laziness. I wanted the workflow to be optimized for minimal user input and, as such, I felt that popping up a “We’re Done!” dialog at the end of the process would be inelegant.

Finally, we come to real, not-crappy error handling.

makeGist.py does check for various exception types during execution and, near as I can tell, won’t loudly unwind the call stack if things go south. That said, it also doesn’t do any fancy stuff like retrying in the event of a timeout, etc.

Oh, I almost forgot: this software is provided without warranty and if it turns your Mac into a smoldering heap of unicorn entrails, don’t come crying to me.

Takeaway: if any of this makes you squeamish or angry, please don’t use The Thing (or, if you’re up for it, fork the project and fix the bug/add the feature!)

In Conclusion

I had an itch and I scratched it — it’s that simple. As with most of the goofy, one-off software bits I publish here, I have no clue if this will be useful to anybody but me.

If you do end up using it:

  1. Awesome!
  2. Let me know (either using Github’s issues feature or via Twitter) if you have any problems with it.
  3. If you have any Python and/or AppleScript chops and feel like making the thing better, do feel free to fork the project and send me a pull request with any features/fixes you add.

Either way, I hope you guys dig this thing.