Sublime, urxvt, and nose-progressive
For many of my projects I use the excellent nose-progressive for running tests. Among other features, it prints out lines that are intended to be helpful to jump straight to the code that caused the error. This works well for some workflows, but not mine.
Here is an example of nose-progressive's output:
Reusing old database "test_kitsune". Set env var FORCE_DB=1 if you need fresh DBs. Generating sample data from wiki... Done! FAIL: kitsune.apps.wiki.tests.test_models:DocumentTests.test_document_is_template vim +44 apps/wiki/tests/test_models.py # test_document_is_template assert 0 AssertionError 1438 tests, 1 failure, 0 errors, 5 skips in 115.0s
In particular, note the line that begins
vim +44 apps/wiki.... It is
indicating the file and line number where the error occurred, and if I
were to copy that line and execute it in my shell, it would launch vim
with the right file and location. Not bad! It chose vim because that is
what I have
$EDITOR set to.
Unfortunately, even though my
$EDITOR is set to vim, I use Sublime in
my day to day editing tasks. I like to keep
$EDITOR set to vim,
because it tends to be used in places where I don't want to escalate to
Sublime, but in this case I really do want the GUI editor.. This feature
of nose-progressive doesn't help me much.
So how can I get nose-progressive to be helpful? In the recent 1.5 release of nose-progressive, a feature to customize this line was added. Promising. Additionally, I use urxvt as my terminal, and with some configuring, it can open links when they are clicked on. A plan is beginning to form.
First, I made nose-progressive output a line that will indicate that
Sublime should be used to open the file, not vim. A quick trip to the
documentation taught me that I can set the environment variable
$NOSE_PROGRESSIVE_EDITOR_SHORTCUT_TEMPLATE to a template string to
Quite a mouthful, but it gets the job done. This format string will print something visually resembling the old line, but with a custom format. In action, it looks like this:
Reusing old database "test_kitsune". Set env var FORCE_DB=1 if you need fresh DBs. FAIL: kitsune.apps.wiki.tests.test_models:DocumentTests.test_document_is_template subl:///home/mythmon/src/kitsune/apps/wiki/tests/test_models.py:44 # test_document_is_template assert 0 AssertionError 1 test, 1 failure, 0 errors in 0.0s
Awesome! Now to get the terminal to respond.
I use a package called urxvt-perls to add features like clickable links
to my terminal. I tweaked it's config to look like this to make it
recognize my custom Sublime links from above, as well as normal web
links. This is the relevant snippet of my
URxvt.perl-ext-common: default,url-select URxvt.url-select.launcher: urxvt_launcher URxvt.url-select.underline: true URxvt.url-select.button: 3 URxvt.matcher.pattern.1: \\b(subl://[^ ]+)\\b
Line by line:
url-selectadd-on is loaded.
- Set the launcher script to
urxvt_launcher. More on this in a second.
- Underline links when they are detected.
- Use the right mouse button to open links.
- Add an additional pattern to search for to make clickable.
Now when normal web links (like http://www.grinchcentral.com/) are
found, or my custom
subl:// links are clicked,
be executed with the underlined text as
Bash is not my native language, but it seemed the appropriate tool for this job. I hacked together this script:
#!/bin/bash if [[ $1 == 'subl://'* ]]; then path=$(echo $1 | sed -e 's|^subl://([^ :]+)(:(\d+))?|\1 :\2|') exec subl $path else exec browser $1 fi
This seems to do the trick. If the "url" starts with the string
subl://, then it extracts a url and a line number from the argument,
execs sublime with that information. Otherwise, it runs
browser, which is simply a symlink for whatever
browser I'm using at the moment.
All of this combined together make nice, clickable links to exactly what line of code is breaking my tests. Time will tell if this is useful but if nothing else, it is quite neat.