2009/02/13

VoodooPad and TextMate

VoodooPad's new HTML-savvy application-specific URLs are a great way to retrace your steps in TextMate.

I keep my worklog in VoodooPad. I do most of my code editing in TextMate. When I'm trying to understand a new chunk of code, I often need to jump around through the code base.

It's hard to keep track of where I've been, so I can back out of a code path once I understand what it does. Until now I've just jotted down pathnames and line numbers in my worklog, so I could manually retrace my steps.

Puzzle Pieces


  • VoodooPad URLs. They let you inject HTML content — including hyperlinks — into an open VoodooPad document.
  • TextMate URLs of the form txmt://open?url=file://pathname&line=lineNum;column=colNum. Open one of these URLs and TextMate will open a window showing the specified line (and column, if specified) of the specified file.
  • Textmate commands and key equivalents.
    TextMate lets you define custom commands and trigger them with keyboard shortcuts that you specify.


Put these all together and what do you get?

Scenario
  • Select some code of interest in TextMate
  • Type your keyboard shortcut
  • A hyperlink pointing to the selected code is inserted into your VoodooPad document

Later, when you want to get back to that chunk of code, just click on the hyperlink in VoodooPad. TextMate will open the document and jump to the line of code referenced by the hyperlink.

Granted, you're probably going to edit that code someday; and then your bookmarks will break. But this is a handy way to leave a trail of breadcrumbs while you're trying to decipher a new body of code.

Code

Here's a Python script which implements this "Bookmark in VoodooPad" capability in TextMate. You can use it by opening TextMate's Bundle Editor (Bundles -> Bundle Editor -> Show Bundle Editor), creating a New Command using the tool menu at the bottom left of the Bundle Editor window, and pasting it into the resulting Command(s) text area:

#!/usr/bin/env python2.6
import os, datetime, urllib, subprocess

escape = urllib.quote

# What Textmate location are we bookmarking?
path = os.environ["TM_FILEPATH"]
lineNum = os.environ["TM_LINE_NUMBER"]
_tmURLTemplate = """txmt://open?url=file://{path}&line={lineNum}"""
tmURL = _tmURLTemplate.format(path=path, lineNum=lineNum)

# Which VoodooPad worklog page should we add it to?
vpPageName = escape(datetime.date.today().strftime("%Y-%m-%d"))

# What text should Voodoopad show for the link?
currLine = os.environ.get("TM_SELECTED_TEXT", os.environ["TM_CURRENT_LINE"])

# How should the HTML be formatted?
_vpHTMLTemplate = '''<a style="font:12px helvetica" href="{tmURL}">{currLine}</a>'''
vpMarkup = _vpHTMLTemplate.format(tmURL=tmURL, currLine=currLine)

# What URL do we open to inject the HTML into VoodooPad?
_vpURLTemplate = """voodoopad:html={vpMarkup}&page={vpPageName}"""
vpURL = _vpURLTemplate.format(vpMarkup=escape(vpMarkup), vpPageName=escape(vpPageName))

subprocess.check_call(["open", vpURL])


Specify a key equivalent such as ⌘-T (Command-T) and you're off to the races.

2 comments:

Uwe Kitzmann said...

I like this idea. Maybe something like

currLine = cgi.escape(currLine)

is necessary to allow bookmarks of html code.

Regards, Uwe

Mitch said...

I thought so, too. I actually tried escaping currLine on my first attempt, and found that it wasn't necessary. In fact, doing so caused the HTML to render incorrectly in VoodooPad -- with '%20' where spaces should be, and so on.