Tips and tricks

I was asked on IRC today if TextMate could show the changes from last time the document was saved, and was also informed that smart-typing of quotes conflicts with Pythons triple-quoted strings.

Both things turns out to be surprisingly simple to fix for the user, and since this isn't the first time I've been asked for features where the solution expose TextMate's ease of customization, I figured it was time to start a Tips and Tricks category on this blog.

As for showing the differences between the current document and the version on disk: OS X ships with the standard diff command, and TextMate already has syntax highlight for diff files, so what we need is to create a new command that runs diff on the current buffer and the file on disk.

By using - as filename for diff, we instruct it to use the standard input (a unix convention), so the command needs to have standard input set to “Entire document”, output to “Open as new window”, and the actual command should then be: diff -u "$TM_FILEPATH" -. The $TM_FILEPATH is a shell variable containing the full path of current file.

In the GUI this looks like this (click for full size):

diff against saved

It opens the result from diff in a new window. TextMate will pick up that the result is a diff file and show it like this:

diff with saved

The other problem was the smart-typing. When you type a quote-character, TextMate will auto-insert an extra (closing) quote to the right of the caret (with a few exceptions). If you type a second quote-character, it will overwrite the auto-inserted character (so that when you instinctually e.g. type () you won't get ())).

In Python there are triple-quoted strings ("""like this""") and while there is a snippet which allows you to type tr followed by tab (to get """|""", | marking the caret) and even press tab again (after typing the string content) to skip the last 3 quotes), many will probably reach for the " key when they want to start a string.

One can of course disable smart-typing, disable it for Python, or exclude the quote-character from the smart-typing pairs (for Python), but we choose neither.

What we really want is to get rid of the overwrite feature of smart-typing, and we can do that by making a snippet which is set to "$0" and have " as key equivalent ($0 is where the caret ends, after inserting the snippet).

But since it's only inside strings (in Python) that we want to change the behavior of the " key, we set the scope to: source.python string. And it ends up looking like this:

quote pair in python

Amazingly simple if you ask me :) We could make it more advanced by letting the Python grammar assign a name to various forms of empty/non-empty double/triple-quoted strings, and overload the meaning of " depending (even more) on context. So if the string was already triple-quoted, it probably should overwrite when at the end of the string (in front of the threee quotes). Generally though, you can use ⌘↩ (command return) to go to the end of the line and insert a newline, so if you have typed this (again, with | marking the caret):

str = """Hello world|"""

Pressing ⌘↩ results in:

str = """Hello world"""
|

And while on the topic of Python, Domenico Carbotta asked for a running environment for Python which would catch exceptions and show these with links to the source. I pointed him toward how pdflatex and xcodebuild uses the HTML output capability of commands to present a glorified build report with potential errors shown using hyperlinks, and it didn't take him long to create something even nicer for Python (called PyMate).

It runs your Python script in an environment and catches potential exceptions, showing them nicely with links to the erroneous source and line number, this is how it looks (script in the top window, result in the bottom window):

pymate

Brad Miller did a few enhancements (like requesting input) and have added the command to the Python bundle in the bundle repository (it will be included with 1.1b17).

This script has inspired another user to work on something similar for Ruby :)

One last tip, devised while writing this blog-entry: I have a few screen grabs in this post. All of them are scaled down to one third of their original size. Rather than scale them on disk, I put one third of the size in the width/height fields of the <img> tag. This requires that I know the original size, and that I do the math for the 8 values.

To get the original size, I drag the images into TextMate, which triggers the PNG drag command (setup for the text.html scope).

Now to scale the value, what I do is add /3 to the original value, select the expression and press ⌃⇧E, which executes the selection as a Ruby expression (and inserts the result). However, since I do that for all my blog-posts (scale the images down to one third), I have automated this by selecting Start Macro Recording before adding /3, pressing ⌃⇧E, and removing the original value, that way I just need to fire a macro, to scale down the value. As a bonus I've made the macro end with a regexp search for (?=\d), which moves the caret in front of the next digit in the buffer, meaning that usually after firing the macro, I'll be at the next value that needs scaling, and can just fire the macro again.

And just for the records, both ⌘↩ and ⌃⇧E are plain bundle items which you can edit, duplicate or remove (in the Source and Ruby bundle respectively).

10 Comments

  1. 11 Aug 2005 | # Andreas Wahlin wrote…

    That's it! I'm registering right now! I've put it off long enough. Btw, Allan, I very very rarely (if ever) pay for shareware; but TextMate is so great especially since you give so much back to the community and isn't just an anonymous developer! Thank you for this great editor, I'm no longer jelous of the KDE dudes who can run Quanta :)

    (as a tip Alan, if you just delete the textmate setting plist thingy in application support, the registration period resets to 30 days, of course you loose all the settings in the process)

  2. 11 Aug 2005 | # Martin wrote…

    Great tips! I would like some kind of keyboard shortcut viewer to see how/where all keys are binded to. It would be a lot easier than having to dig through all macros/commands etc in the Bundle Editor

    Thanks for a great editor!

  3. 11 Aug 2005 | # Martin wrote…

    (continued from above)..Or some kinf of floating Automation-palette. Now I tend to miss a lot of great commands just for the sake they live 3 menu levels down.

    ciao

  4. 11 Aug 2005 | # Allan Odgaard wrote…

    Martin: You can try ⌃⌥⌘K. I'm aware that the deeply buried menu items is a bit of a problem (when you don't know the tab-triggers and/or key equivalents) and do intend to introduce something better (eventually).

    Andreas: Thanks for the support – as for the preferences file, I'm a fan of transparency and simply cannot get myself to store hidden files on the users system.

  5. 12 Aug 2005 | # Martin wrote…

    Hum, nothing happens when I press ⌃⌥⌘K, what should it trigger? I'm using the latest beta, 1.1b16

  6. 12 Aug 2005 | # Allan Odgaard wrote…

    Martin: It should trigger: Run Command… → Language Definitions → Show Keyboard Shortcuts.

    Maybe you have the Language Definitions bundle disabled (Show Bundle Editor → Change Filtering…)

  7. 13 Aug 2005 | # Martin wrote…

    Ah, that was what I was looking for, thanks!

  8. 25 Aug 2005 | # Ivan wrote…

    Like Martin, I rarely buy software and just registered for TextMate today. I love to demo applications, simplely because I love to try new things. One of things that turns me off is the nagware and spyware (shareware that installs hidden files). They are not necessarily bad software; the nagging reminder certainly kills the user experience. Kudos to Allan for not making TextMate one of them.

    It didn't take long to convince me to buy TextMate, but one thing that puts itself to the top is the reminder. The reminder screen only comes when you start the app and it won't appear until you restart the app. I rarely quit TextMate nor do I shutdown my Mac ever. I have really enjoyed using TextMate without any interruption.

  9. 02 Sep 2005 | # Jim M wrote…

    I just updated to b17 and noticed PyMate. However, there are soem quirks:

    1. If I hit Command-R, which used to run my python script and output to a text window, a menu pops up giving me the choice of running it in Python – the older text output – or Python (HTML Output) – which produces PyMates highlighted HTML output. It is annoying that instead of hitting Command-R for each run, I have to also choose from a menu option. Can my choice be bound somewhere to shortcut the menu?

    2. The PyMate output says you can still get the older Python (text only) output by hitting Shift-Command-R. but when I do this, TextMate crashes!

  10. 02 Sep 2005 | # Jim M wrote…

    Forget my last comment – my svn bundles were not up to date, the menu is now gone and Command-Shift-R works…

Comments closed, you can use the mailing list for discussion.