TextMate News

Anything vaguely related to TextMate and macOS.

Miscellaneous beta 15 notes

As you may have noticed, beta 15 was released today (though only as a PPC binary, since I haven’t updated my deployment script yet – I’ll put up a universal build shortly). I’m preparing for the official 1.1 release, so I’m holding back a little on new features and am instead cleaning up the existing stuff.

One simplification I’ve been wanting to do for some time is the clipboard history. The paste previous/next actions on ⇧⌘V and ⌥⌘V work very well, but when having to locate a clip from a while back, one uses the inspector (on ⌃⌥⌘V), and this was suboptimal. I’ve used it a few times as an example of what happens when you design GUI based on what your code can do, rather than what the user wants to do.

So gone are all the buttons, gone is the ability to edit the data, gone is the actual window – instead there’s just this popup:

clipboard history

It makes it feel more lightweight and makes it obvious that this is a one-shot for finding the old clip. A refinement would be to allow letters typed to filter the popup, but I’m satisfied with this for now.

Another part that needed simplification was the theme editor. It was always meant as a provisional solution to expose the new syntax and scope specific settings capabilities. The new approach is to split the theme editor into visual styles and scope/language specific preferences. The latter is edited in the bundle editor (currently still as plists) and the former is moved to Fonts & Colors in the Preferences window, it looks like this:

fonts and colors

And this is in fact the reason why I made this post, because it turns out that this is not how it looks on Panther. The segmented cells (font style column) are totally messed up, and I’ve been receiving bug reports all day about this – so just to let you know, I’m aware of the problem, and will figure out how to make a workaround.

On a brighter note, I did manage to make a workaround for the kernel panic which appear when you save files to AFP mounted volumes on Tiger, so if you had this problem and downgraded, 1.1b15 should be safe to use again!

But back to Fonts & Colors. As you can see from the grab, this is a nice simplification, but it has a trade-off: it’s no longer possible to create a new settings group which augment an existing theme. Instead language specific styles needs to be added to the theme itself.

Ideally there should be very few language specific styles, and long-term I intend to allow for each filetype to have its own theme (mostly for those languages which have very little in common with the general scopes used, so it should be the exception rather than the norm). Adding grouping to the Fonts & Colors preferences may also help in case the number of settings grow a lot. But for now you’re supposed to simply add whatever styles you desire to the theme you’re using.

The scope specific preferences (which are now in the bundle editor) still need an improved interface, especially so it’s possible to see what can actually be changed. I suggest opening the bundle editor and set the popup (which filters the item kinds) to “Preferences” and check some of the existing settings.

One preference which I am especially fond of is spellChecking. It allows to enable/disable spell checking for a scope, and by default it’s configured to disable it for keyword, constant, etc. and also for source, but enable it again for source string. With this setup it’s convenient to have “Check Spelling as You Type” enabled all the time, since it can easily be instructed to ignore that which is not prose. I even created a language grammar for the svn-commit.tmp files, so that the change set part of the file gets a scope for which I have spell checking disabled.

Speaking of scopes and language grammars, the basic HTML grammar now catches (some) empty tag pairs (e.g. <div></div>) and assigns a special scope to the caret position between the opening/closing tag. By using that scope for a snippet, and giving the snippet return as key equivalent, it’s possible to get a blank indented line between the tags when pressing return. Oh, and if you didn’t know, TextMate has a default macro on ctrl-shift space (previously it was ctrl space, but moved because of potential Spotlight/Quicksilver conflicts) which turns the word to the left of the caret into a tag pair. So try this: open an HTML file, type div and press ctrl-shift space, then press return. The end result should be the following, with the vertical bar indicating the caret position:


So this is first a macro (which is recorded, i.e. no programming skills required), then a snippet inserted on return (which is plain text, although a snippet can contain more), this snippet is restricted to a scope (so only between empty tags will return insert the snippet), and the scope is defined by a rule in the HTML language grammar (which is a regular expression, I encourage you to take a look at the various language grammars in the bundle editor, if you haven’t already).

And that wraps up the beta 15 notes, the latter example wasn’t really beta 15 specific, just me trying to inspire you to customize your environment to better suit your editing patterns. Another neat (and slightly related) trick is to change the smart typing characters based on context, for example after the template keyword in C++, there’s smart typing on < and >, Ruby has likewise smart typing on | when at the beginning of a block.

categories General


23 July 2005

by Andreas Wahlin

I don’t know if this request goes here … I really like the new easier way of assigning syntax coloring, however, I really miss different forms of tags (being a HTML editor). Dreamweaver has different syntax coloring for form tags, and I’d also like a special color for attributes within tags, even taking it so far as to have a unique color for the id attribute. Being able to color tables and lists would also be very nice.
I tried to dabble only slightly in editing the HTML language, but ended up with nothing. Is there a good tutorial somewhere?

I’m not completely clear on what you said about language-specific styles. I think they’re absolutely essential to TextMate – one of its main selling points.

For example, the important symbols and syntax in an Objective-C program are different than the important symbols in a PHP program, which are more different still than the important symbols in a CSS file. TextMate is the only text editor I’ve found that realizes this is how things work in the real world.

I’ve been using b12 for a while since it was the last one to color PHP files correctly. Unfortunately, I haven’t really had time to go in and monkey with the settings files to get it working on b14. It looks like I’ll have to stay with b12 even longer – until all of this gets worked out.

Andreas: There’s currently no tutorial. I’ll keep in mind that I should write one :)

As for coloring the value of the id attribute, this can be done by making a new entry (in Fonts & Colors) and giving it scope: meta.toc-list.id. You can check the scope of the stuff you want to style by placing the caret on the item and pressing ⌃⇧T.

It has been proposed (by some of those who contribute to the HTML language grammar) that we markup inline and block tags differently, so that these can be styled differently and also to markup incorrectly placed tags as invalid etc. I don’t think this change is around the corner though.

As for marking up different tags, the current language grammar has this rule:

{ name = "declaration.tag.html";
    begin = "</?([a-zA-Z0-9:]+)";
    end = ">";
    captures = { 1 = { name = "entity.name.tag.html"; }; };
    patterns = …

The [a-zA-Z0-9:]+ part of the begin value is the regular expression which matches any tag. And the entity.name.tag.html in the captures array is the name given to that part of the match.

So if e.g. you want to style form tags differently, you should make a copy of the entire rule, and change it so it says:

{ name = "declaration.tag.html";
    begin = "</?((?i:form)\\b)";
    end = ">";
    captures = { 1 = { name = "entity.name.tag.form.html"; }; };
    patterns = …

The reason why form is enclosed in (?i:…) is to make the match case-insensitive, and the \\b escape sequence matches a word-boundary, this is so that we don’t match <formula> or other words derived from form.

You should btw keep your changed copy above the general rule (since the latter is a catch-all).

This change only markup form tags differently, to also style them differently you should go to Fonts & Colors and add a setting with scope set to: entity.name.tag.form (otherwise it’ll just inherit the setting for entity.name.tag).

This can then repeated for all the tags you want styled specially. You can handle multiple tags with one rule, if you want them styled the same, e.g.:

{ name = "declaration.tag.html";
    begin = "</?((?i:ol|ul|dl)\\b)";
    end = ">";
    captures = { 1 = { name = "entity.name.tag.list.html"; }; };
    patterns = …

24 July 2005

by Andreas Wahlin

I think I’m beginning to understand how this works :) However, I can’t get it to work, I put this text directly above the general tag-capture rule

{ name = "declaration.tag.html";
    match = "<(?i:(form|select|input))\\b[^>]*(>)</(\\1)>";
    captures = 
    { 1 = { name = "entity.name.tag.form.html"; };
        2 = { name = "meta.scope.between-tag-pair.html"; };
        3 = { name = "entity.name.tag.html"; };

Yet it does not work, I’ve hit both format button (which says it’s correct) and test button, and I’ve also relaunched the program. Obviously I’ve put up a form declaration with entity.name.tag.form.html, and I’ve also used shift+control+t (which was wonderful and helped me to realize the naming convention of the capturing stuff) but the form stays adamantly unchanged. I test it on a form tag.

Btw, is it possible to contribute bits and things on a more regular/respected basis? This would probably be down the lines of lots of well (and sometimes not so well) motivated bitching :)

I like color, structure and I’m a heavy JavaScripter (for instance, it bugs me that the folders don’t detect this.NewFunction = function() { … }; )

I’ve also been thinking that one should do a BBedit styled color scheme for HTML, for “switchers”.

Andreas: your rule is correct! :)

The culprit is that if you look at the top of the HTML grammar, you’ll find a very similar rule which I made to catch empty tag pairs (as in <form></form>), because I wanted to change the behavior of return when inside such a pair (there’s a snippet which use the scope) — so the problem is that this rule has higher precedence (because it’s higher up in the language definition), and thus eats your test text.

So if either you a) move your rule to the top of the grammar, or b) add disabled = 1; to my rule (or remove it), it will work!

As for contributing, all bundles are kept in a subversion repository to which selected developers have commit access. There’s a mailing list (textmate at lists dot macromates dot com) which you’re welcome to send suggested changes to (and subscribe to as well), there’s also the #textmate IRC channel (for general talk, also related to bundles).

I’ve heard the BBEdit switcher-theme a few times, so that’d probably be nice, but I don’t own BBEdit myself, so I have no idea which colors it use ;)

P.S. Just FYI: I ran your post through Markdown to get proper escaping (unfortunately I haven’t figured out how to make WordPress respect the <pre> used around code blocks).

Scott: I’m not sure what changed from b12 to b13 since you lost (PHP targeted) coloring. Which theme are you using? If you’re using Pastels on Dark then it just received an update which added extra styling for CSS, PHP, and JavaScript.

As for language specific coloring, my goal is to keep it at a minimum (in the default themes), not remove the ability.

My struggles with it is on how to present the Fonts & Colors preferences without overloading the user with 200 items to customize… but I think adding the ability to group items in the preferences will take out some of that complexity.

24 July 2005

by Andreas Wahlin

I really can’t seem to find the rule you mention there Allan, but it doesen’t matter that much, I merely wanted to see if I could do it ;)
As you see I’ve now joined said mailinglist in order to contribute a bit (read; get things where I want them hehe) and was thinking about that BBedit theme, perhaps I could do it. I have BBedit right here and I actually like that syntax colouring scheme … for html that is, it sucks in php and javascript. Possibly a dreamweaver scheme as well, I suppose it’s mainly lots of copy/paste :( and the correct scopes to support it.
I’m not making promises here, just elaborating …

b15: Soft Wrap.

I can’t seem to turn off software. I click it off in the menu, but when I return to that file/tab it’s turned back on.

How do I keep it off?

Phil: Go to the bundle editor (window menu) and open the Text bundle. There’s a preference here which enables soft wrap (for text). Delete this item.

I have removed these default mode-specific soft wrap settings for 1.1b16 and will re-introduce the automatic remembering based on file-type :)

01 August 2005

by Dan Kelley

Allan, you mention an official 1.1 release. That will be great to see. These betas (or alphas, as others have correctly called them) have been quite amazing to watch, like a building being constructed before our eyes. At every stage of the work, whether an advance or a retreat, the TM community has felt confident that the building will be not just strong, but also elegant. Well done.

Having said that, it certainly seems to be the right time to slow up on the feature addition and to work on documentation. New users will not have been reading this wiki, and so they need to be presented with something that makes sense. They will need to learn how to do simple tasks that are not obvious from the menus. Column editing, or edit-lines-in-region (whatever it’s called) is a case in point; the menus and the action are not clear, and the docs could benefit from some examples.

PS. this post was /supposed/ to be a thanks for your decision to stop adding features, but now I must note one feature I’d like to see. I am sorry to harp on this… Please make control-F move forward one character, as it does in other osx applications. You’re in the middle of an alpha series, so it’s OK to make the change. Sure, you may annoy a few dozen present users, but think of the benefit from the hundreds of users who should start enjoying the official 1.1. soon? Honestly, this single thing is enough to make me not recommend TM to my friends. Many users (those from a unix background and those who simply type a lot) have come to rely on the standard control-F action. I’ve probably typed control-F ten times in typing into this web form. So, it is a familiar thing for control-F to move in the text without altering it. So, every minute or so, when I’m using TM on a document, I wreck it by typing control-F. Sure, there is undo, but there is also a lot of swearing involved, followed by a TM quit and an emacs launch. That’s not the right thing, is it? Maybe, Allan, I’m a lone voice on this. If so, that’s fine. I don’t need TM, since I’ve used emacs for decades and can get things done in it, but I would like to help in the polishing of TM, so that I can recommend it to friends and students.


Dan: I’ll revise the key bindings for 1.1, however, making ctrl-F (or any other key) move forward (or any other action(s)) can be done simply by recording a macro:

  1. Automation / Start Macro Recording (⌥⌘M)
  2. Press arrow right
  3. Automation / Stop Macro Recording (⌥⌘M)
  4. Automation / Save Scratch Macro… (⌃⌘M)

Name the macro “Move Forward” and give it ctrl-F as key equivalent.

Thanks Allan.

I just changed it to 0 and that worked great.

Window -> Show Bundle Editor -> Text Utilities -> Miscellaneous -> softWrap = “0”;

05 August 2005

by Jay Soffian

Re: softwrap.

It would be really nice if softwrap would respect the indentation of the line above it. e.g.

def some_function():
<tab>this is a really long line that needs to wrap

It would be nice if “here” lined up with “this” on the line above.

Also, still waiting for a split-buffer feature. :-)

The editor is coming along nicely, but it hasn’t 100% replaced emacs for me quite yet… :-)

05 August 2005

by Jay Soffian

Ugh, looks like the weblog swallowed some of my text. Let me try again:

def some_function():
TAB”some really long text that needs to
be soft-wrapped”

I’d like for “be” to line up with the quote in the line above it.

Jay: something like that (indented soft wrap) is scheduled for 1.3. Split-buffer may appear in 1.2 – but no promises :)