Remove Trailing Whitespace in TextMate 2 Code Files

I still use TextMate for some things: editing documents quickly, scripting in Ruby, navigating project folders of foreign code bases (especially when they’re not using my main language so I could use Xcode, e.g. Java projects), and finding and replacing text.

But it always bugged me that when I move around code and indent and outdent and whatnot, that sometime lines with nothing but whitespaces would be saved. Or I’d combine stuff and have 10 trailing spaced all of a sudden. I do show invisible characters, but I don’t want to pay attention to that kind of stuff when I’m coding.

Xcode can be setup to remove trailing whitespace while you edit. I want that.

Turns out TextMate has a “Text” bundle with the “Remove Trailing Spaces in Document / Selection” command. You can launch it from the Bundles menu, but then you still have to do it manually.

Turns out TextMate also has callbacks! You can hook any command to callback.document.will-save and it’ll be executed before saving the file.

To set this up:

  • Open the bundle editor (from the main menu, select “Bundles > Edit bundles …”, or hit ⌃⌥⌘B)
  • Select “Text” from the leftmost pane (that’s the pane listing all installed bundles)
  • Select “Menu Actions” from the 2nd pane
  • Select “Converting / Stripping” submenu from the 3rd pane
  • Select “Remove Trailing Spaces in Document / Selection” from the 4th pane
  • In the item drawer to the right of the bundle editor, you’ll see a swath of settings; in there …
  • set the Semantic Class attribute to callback.document.will-save, and then
  • set the Scope Selector attribute to source.

I included the last setting because I do not want to trim trailing whitespace from Markdown documents: sometimes, empty lines with indentation do have meaning. And every time, 2 trailing spaces signify a line break. I don’t want to lose these. You can leave the limitation out if you want.

Here’s a depiction of the settings:

TextMate 2 Bundle Editor settings to trim whitespace in code

For the curious: text instead of source would apply the command to non-source code files like plain text or Markdown or Pandoc – or HTML. You can combine selectors to apply to specific types, like source, text.html. Be aware that Markdown documents report their base scope as text.html.markdown, though, so you’d end up removing trailing whitespace from Markdown again. So you might instead want to use text.html.basic if you use the plain HTML language from the bundle, or text.html.erb if you use the “HTML (Ruby - ERB)” language setting. You can put as many language scopes in the list as you like, as far as I know, so source.ruby, text.html.basic, source.swift would work, too. You can go crazy and restrict this down to the scope of individual blocks, like meta.tag.inline.span.start.html to only remove trailing whitespace inside the <span> tag itself, before the closing >.

If you don’t know which scope the language you’re using reports to the bundle engine, invoke the “Show Scope” command from the command palette (“Bundles > Select Bundle Item …”, or ⌃⌘T).

Works beautifully and reduced my git diff noise a ton already. Have fun hacking away!