TextMate



TextMate also has 'completion' functions that you can make use of. The simplest of these is the automatic insertion of closing characters, meaning that if you type (or it will automatically. TextMate is a simple yet robust text editor that supports a vast array of languages from simple plain text to HTML to ObjectiveC. An application that supports the SVN and Git repositories and supports bundling so you can add your own or other support for other languages or modified languages. Text Inmate allows friends and family on the outside to send and receive text messages to/from ANY U.S.A. Based cell phone to an inmate without needing Corrlinks or an app installed.

Although TextMate has been around for a long time (in computer years) and many language bundles exist, it is startling to find that the process of writing a language grammar remains poorly documented. Having recently managed to write a grammar of my own for the first time, here are some things I learned along the way.

Time Involved

Writing a grammar can be a slow business. It took me some weeks just to prepare, collecting information and locating and studying the existing instructions and documentation.

It then took me about three weeks of extremely frustrating, difficult work before I got my first two scopes working in the grammar. (This was mostly because of undocumented things you mustn’t do and things that TextMate can’t do, both of which I tell you about later on this page.) After that, though, it was remarkably smooth sailing, and I was able to finish the entire grammar in a week. Here are some git log excerpts:

A snippet is a piece of text that you would like to insert in your document. It can include code to run at insertion time, variables (like selected text), tab stops/placeholders for missing information (which you can tab through after insertion) and perform transformations on the data which you enter in the placeholders. Used N(Textmate)2or more person sharing, exchanging & forwaring SMS on a continues spand of time.Used as ADJ.2or more persons sharing, exchanging and forwarding Intimate SMS on.

How Scopes Are Styled

One of the chief reasons for writing a grammar is syntax coloring — which, like so much else about a grammar, depends on scopes. The rules for how a scope should be colored and styled, however, are to be found, not in the grammar itself, but in themes and also in settings.

In particular:

  • In TextMate 2, the standard themes are all in the Themes bundle. The user will probably have selected one of these themes. You have no control over which it is; yet upon this choice depends how your grammar will affect the look of a document.

  • Themes can also be hidden away in other bundles. (Fortunately, at the moment, no standard bundle that I use, other than the Themes bundle, contains any themes.)

  • Settings can color and style scopes, like miniature one-rule themes.

Since themes and settings are going to have an effect on how your scopes are displayed, you should take some time to examine the existing themes, as well as looking through all settings of all bundles, to get some notion of what this effect might be. To save you some time, I will now summarize the information that I gathered in this regard.

Standard Themes

Unfortunately, different standard themes affect different scopes; ideally you should note down every scope listed in every theme, but this would take too long. Here are some of the main general scopes that are styled by the standard themes; these are scopes that you generally want to use, because you can rely on the user to have selected a standard theme that will style them for you:

Settings

I was stunned to discover that, in addition to themes, a bundle’s settings can style scopes. It turns out that this fact is extremely important. For example, I scratched my head for about two weeks, trying to figure out why my italic text was shown as italic. I couldn’t find any theme that was doing this. Then one day I stumbled on the Text bundle, which contains the responsible setting.

Here are the chief bundle settings to be aware of:

  • Text bundle: markup.bold, markup.italic, markup.underline. (The underlining imposed by markup.underline is also how the Hyperlink Helper bundle injects underlining onto your URLs.) There are some other settings here, but they affect things like soft wrapping (also something to watch out for).

  • Themes bundle: markup.heading.n, markup.quote, markup.raw.block. These settings affect both the font and size of these scopes. In my opinion, they are among the most horrible side effects of using TextMate 2. (If I wanted font and size to vary through my document, I’d be using Microsoft Word, for heaven’s sake. I’m here for the text. It’s called TextMate, after all.) To avoid having your text affected by these settings, avoid these scopes. I have also disabled these settings in my copy of TextMate, but you can’t rely on every user to do that.

  • TextMate bundle: meta.separator.

If you use or enable other bundles, keep your eyes peeled for settings that may perform scope styling. For example:

  • Diff bundle: markup.changed, markup.deleted, markup.inserted; meta.diff.header, meta.diff.index, meta.diff.range.

The Source bundle doesn’t contain any style settings, but it does have some settings that determine what counts as a word character for purposes of code completion (as explained in this article) as well as word selection and navigation, so you might want to be careful with the distinctions being made here.

Standard Scopes

The official list of scopes that are considered standard or conventional is not quite the same as the list of scopes that are commonly styled by themes. It’s good to have this list on hand. The list as given in the documentation is as follows. I have starred once the entries that are present also in the list of commonly styled scopes (though note that for some reason there are commonly styled scopes that are not present in this list); I have double-starred the entries that are styled by settings:

The Bundle Development bundle will also assist you as you edit your grammar by marking unusual scope names.

Note that although the documentation claims that meta scope is not styled, nevertheless some meta subscopes are in the list of scopes styled by themes and settings above.

Regular Expressions

Grammar match rules are written as Ruby regular expressions. You need to be conversant with these! Download a copy of the Oniguruma regular expression syntax (used by Ruby) and keep it handy. Things to note:

  • Greedy, reluctant, and possessive matches

  • Lookbehind and lookahead — your match rules are likely to make extensive use of these

  • Shy groups, named groups, named group references, and “variables” (the “Tanaka Akira Special”, allowing you to refer forward to a group by number or name) — I found named groups, in particular, extremely helpful for clarifying complicated expressions

  • G — This is a way of anchoring an attempted match in exactly the place where the previous match ended (useful when a grammar works by carving up a document completely into contiguous scopes)

It will also be a good idea to keep Rubular open in your browser. It allows you to test regular expressions, indicating matched groups.

Bear in mind, however, that because of the way the TextMate parser surveys your document, all regular expressions used in grammar match rules must apply to a single line at a time. A single expression cannot embrace multiple lines. Thus it is possible to write a regular expression that appears to work in Rubular (or TextMate’s regex Find) but will fail as part of a grammar.

Another pitfall is that TextMate will not complain if you write a bad regular expression; the expression will just fail silently. That’s probably a good thing in general, but it can drive you mad while trying to understand why your regular expression isn’t working. This is another reason why Rubular is useful; it will show a descriptive error message if the expression itself is syntactically faulty.

Regular expressions will be surrounded by single quotes in the grammar. To express a single quote within a regular expression in a grammar, use two single quotes in succession.

Textmate download

Grammar Structure

Textmate

We now come to the actual apparent structure of a language grammar. I say “apparent” because I’m just guessing, based on my experience. The documentation is shockingly uninformative about this. There is no formal complete definitive specification, so far as I have discovered, of the structure of a grammar. Moreover, many aspects of a grammar are described in separate and scattered documents that can be difficult to discover. You should certainly keep on hand a copy of the grammar page in the manual, as well as James Edward Gray II’s book. But I will attempt to do a better job here of assembling and summarizing the facts.

Property List Syntax

The grammar is portrayed by the bundle editor as an old-style property list. Under the hood, however, it is a new-style property list, i.e. XML. This means that every time you save, the grammar is “compiled” into a new-style property list, with an error dialog if you’ve made a mistake such that this can’t be done; and every time you abandon the grammar window, when you return to it, the window is repopulated by “decompiling” the saved XML into an old-style property list. Therefore:

  • The grammar contents may not look the same when you return to it as when you left it; for example, things whose order does not matter (dictionary elements) may appear in a different order.

  • If you leave the grammar window after seeing the error dialog and without correcting the error, you will lose your recent work, because your recent work wasn’t saved, and now it has been wiped out by reading and decompiling the previously saved XML from disk.

    (This is more of a problem than you might expect, because the bundle editor window is responsive to clicks when it is not frontmost. Thus, you might switch to another window to study something about why your property list might be invalid, then click on the bundle editor window to switch back, and discover that, because of where you clicked, you’ve accidentally left your grammar window and have lost all your recent work. I know this from experience, obviously! My solution is: before switching away from the bundle editor with unsaved changes, copy its contents and paste them into BBEdit for safekeeping.)

An old style property list has two kinds of collection: arrays and dictionaries.

  • An array, bounded by parentheses (), is an ordered list of elements separated by comma. It does no harm to follow the last element with a comma as well, and I recommend that you do so.

  • A dictionary, bounded by curly braces {}, is an unordered list of name–value pairs separated by and ending with semicolon. A name–value pair is joined by an equal sign. The name does not have to be quoted, and usually will not be, unless it contains spaces or numbers. String values will be single quoted.

    NOTE: In the grammar structure, any dictionary can contain a comment entry. This can be extremely useful and I recommend liberal use of this feature.

Top Level Structure

Before I can describe the top level of a language grammar, I need to tell you that a match rule (also called a pattern) is a dictionary. But I’m not going to tell you what’s in a match rule until later.

The top level, in the TextMate 2 bundle editor window, is a dictionary — that is, it’s a pair of curly braces {}. Some of the entries in the real underlying dictionary are now edited through fields in the bundle editor drawer. Of these, the most important is the grammar’s scope, listed in the drawer’s Grammar field. This is the main scope that will be assigned to the entire document. It is typically a specialization of some existing scope, in order to acquire related bundle-based features, though not usually in such a way that an existing grammar will be injected automatically on top of yours.

For example, text.html.markdown is not magically imposed upon by the Text bundle’s grammar (which is scoped to text.plain) or by the HTML bundle’s grammar (which is scoped to text.html.basic). But because it is a specialization of text.html, it does magically acquire any features scoped to text.html, such as the Command-Ampersand keyboard shortcut from the HTML bundle.

On the other hand, in the Bundle Development bundle, the Language Grammar grammar is scoped as source.plist.textmate.grammar exactly so that the Property List bundle’s Property List (Old-Style) grammar (source.plist) can be magically imposed upon it; the former is a pure specialization of the latter.

From here on, let’s confine ourselves to what’s shown in the bundle editor window itself. The top-level dictionary can contain (aside from a comment) a patterns array and (optionally) a repository dictionary, and that’s all.

  • A patterns array is an array of match rules. The fact that it’s an array is important, because order matters. Matches are performed in the order listed. TextMate considers lines of a document one at a time, looking within each one for matches. When we make a match, that’s the end for everything in that line up to that point. Thus, you can effectively make conditional rules by judicious ordering of a patterns array.

  • A repository is a dictionary, and it may contain two kinds of thing:

    • A repository may contain named match rules. The fact that the rules are named is important, because this means that a match rule can refer to another match rule by name, provided the latter is in a repository.

    • A repository may contain named top levels. That is, a repository entry might be a name paired with a dictionary containing a patterns array and (optionally) a repository dictionary.

      The patterns array inside a named dictionary inside a repository provides a way of naming (and thus referring to) a whole bunch of match rules simultaneously.

      The repository inside a named dictionary inside a repository has no structural significance — it is not special merely because it is at a deeper level — but it is certainly an organizational convenience, especially because the bundle editor gives you structural code folding.

To illustrate and explain, here’s the structure of the Markdown grammar:

With that structure, the name block can be used to refer to all of the block > patterns match rules simultaneously. The blockquote match rule, despite its depth (a repository within a repository), can be referred to from anywhere.

Match Rules

A match rule, also known as a pattern, is where the power lies in a language grammar. It is the part of the grammar that actually instructs TextMate’s parser what to do: “as you walk through the text, look for this pattern and assign this scope.”

A match rule, as I’ve already said, is a dictionary. In describing the overall structure of the language grammar, I’ve already told you the two main places where match rules can go:

  • A match rule can be one entry in a patterns array.

  • A match rule can be a named dictionary in a repository.

I have not, however, said anything yet about what is inside a match rule dictionary. Now it’s time to do that. There are actually three possible structures for the contents of a match rule:

  • An include.

  • A match pattern.

  • A begin/end (or begin/while) pattern.

We will consider each in turn. But first, I’ll mention two things that any match rule can contain:

  • A comment. This is a name–value pair named comment.

  • An off switch. This is a name–value pair named disabled, with value 1. This is a convenient way to experiment or develop, leaving a rule in place while effectively commenting it out.

An Include Match Rule

An include match rule is a way of saying: “Substitute for me the named match rule(s) I hereby specify.” Such a match rule contains, I believe, just one name–value pair. The name of that pair is include. The value is usually the name of something in the repository at any level, preceded by a hash-sign. (But it cannot, I believe, be #repository, even though that might be the name of something in the repository.)

To see include rules in action, let’s return to and fill out a little further the structure of the Markdown grammar:

Consider how, by means of include rules, the blockquote match rule is actually brought into play. There is only one top-level match rule — the include rule specifying #block. This rule effectively substitutes for itself the entire array of patterns listed under block in the repository. These patterns are themselves all include rules. The result is exactly as if the top level patterns array were the include rule for #separator, then the include rule for #heading, then the include rule for #blockquote, and so on.

Those include rules, in turn, are virtually replaced by the rules that their values name — the actualseparator rule from the repository, the actualheading rule from the respository, the actualblockquote rule from the repository, and so forth. Those actual rules are all defined in the second-level repository.

(Note that the order of the include rules in the patterns array is significant; an array is ordered. The order of the actual rules in the second-level repository, on the other hand, is undefined and unimportant; it happens to be shown as alphabetical, and that’s convenient, but it’s just a detail of the display implementation.)

The value of an include rule can alternatively be a scope name. This is a good way to inject an entire grammar inside yours. For example, in my AsciiDoc bundle, I assume that the contents of a passthrough block (never mind what that is) will be XML. Therefore, inside my match rule for a passthrough block, I have an include rule specifying text.xml. This causes the whole grammar from the XML bundle to come into play in this region of my document. In addition, TextMate 2 permits a single named item to be plucked from a foreign repository using the syntax scopeName#itemName.

The value of an include rule can also be $self, meaning the whole current grammar, or $base, the grammar inside which we are embedded. They are used by several prominent grammars (such as the Objective-C grammar), but I have never used them and I don’t quite understand the details.

As I mentioned at the outset, as far as I can tell, if a match rule contains an include key, that is its only key (except possibly for comment and disabled).

A One-Pattern Rule

A one-pattern rule must contain at least this key–value pair:

  • The match key. Its value is a regular expression that the TextMate parser is to look for.

    This is, I am at pains to stress, a single-line regular expression. The TextMate parser will not examine more than one line of text at a time; thus, a regular expression that includes a newline (n) anywhere other than as the last matched character will never match. By the same token, though, it can be quite useful (especially in a “prose” language grammar such as the Markdown grammar) to end a regular expression with $n? as a way of snarfing up the newline at the end of the line if there is one.

A one-pattern rule may also contain this key–value pair:

  • The name key. Its value is a scope, or an expression that evaluates to a scope. This is the scope that will be applied to the matched text. This scope assignment, in turn, has far-reaching implications for how the matched text will be styled by themes and settings, as I’ve already described above.

For example, here’s the rule from the Markdown grammar repository that picks out certain characters preceded by backslash:

This means that any matches we find using the escape rule will be assigned the constant.character.escape.markdown scope. A theme or setting may then come along and style any constant.character.escape text.

The scope name can be, as I mentioned earlier, “an expression that evaluates to a scope”. What do I mean by that? Well, the scope name is actually what TextMate calls a format string. For more about these, see this article. The syntax here is derived from shell programming syntax. With a format string, you can do things such as:

  • Use a matched group as a term: Refer to it as $0, $1, and so forth.

  • Use the value of a global variable as a term.

  • Perform a transform, such as downcasing, on the value of a term.

  • Do a find/replace on the value of a term.

  • Supply a different result depending on whether a term (such as a matched group) is defined or not.

A one-pattern rule may also contain this key–value pair:

  • The captures key. Its value is a dictionary. In this dictionary, each key is a number or name corresponding to a matched group from the match expression, and the corresponding value is a dictionary. This dictionary may contain one or both of these entries:

    • A name. This is the scope that will be assigned to the matched group text.

    • A patterns array. This is a list of match rules to be sought within the matched group text — thus permitting the search for matches to continue inside the matched text.

This use of the captures > patterns structure is extremely important. Without it, a stretch of text matched by a match rule is considered finished, and TextMate’s search proceeds to the rest of the line after the matched text. With it, the stretch of matched text itself becomes a candidate for further matches.

Here’s a simple minimal example. Imagine a toy markup language in which bold is delimited by asterisks and italic is delimited by underlines:

This works, but only for bold and italic stretches of text that are separate, like this: The five dysfunctions of a team free audio download torrent.

An italic stretch cannot occur inside a bold stretch, because once a stretch of text has been matched as bold, it is discarded from further consideration. If we want italic inside bold, and vice versa, to be possible, we can use the captures > patterns structure to duplicate the italic pattern inside the bold pattern and the bold pattern inside the italic pattern:

That sort of thing is perfectly legal — the patterns array is a list of match rules, and we are providing match rules. And it works, correctly marking up text such as this:

In this case, though, a neater approach would be to move the match rules into the repository so that they can be referred to by name, and use the captures > patterns structure with the patterns match rules being include rules, to continue the search for italic inside a matched bold stretch of text, and vice versa:

WARNING: Do not put a patterns array at the top level of a one-pattern match rule. It doesn’t generate any explicit error, but it doesn’t work correctly either. So, for example, this is wrong:

You are getting the benefit of my hard-fought experience here; it took me about a week of wrestling (and some direct help from Allan Odgaard) to learn the right way to do an include inside a one-pattern match rule.

A Two-Pattern Rule

A two-pattern rule must contain two regular expressions: either begin and end, or (new in TextMate 2) begin and while. These are still single-line regular expressions (the TextMate parser does not consider more than one line at a time), but there are two of them, so together they may delimit a stretch of text that embraces multiple lines.

  • The begin key is a regular expression that will be sought initially.

  • If the begin regular expression generates a match, TextMate will start looking immediately after it (starting in the same line, if the begin match did not snarf up the entire line) for the end or while expression.

    • If you provided an end expression, TextMate will keep walking the document until it matches the end expression, and will stop.

    • If you provided a while expression, TextMate will keep walking the document until it comes to a line where the while expression fails.

Neither of these pairs works quite the way I would have intuitively expected, so I’m going to say some more about them.

With begin/end, if the end pattern is not found, the overall match does not fail: rather, once the begin pattern is matched, the overall match runs to the end pattern or to the end of the document, whichever comes first. The underlying architectural reason is that the TextMate parser does not backtrack; once the begin pattern is matched, it is matched successfully and that’s that — TextMate can’t change its mind and decide that it shouldn’t have matched the begin pattern after all.

This is a major limitation in the degree of intelligence a language grammar can exhibit; it is said to be due to the need for speed, and perhaps for simplicity. In any case, it is intentional, and some grammars actually take deliberate advantage of this behavior. For example, the Property List Old-Style grammar starts like this:

The expression (?=not)possible is, uh, not possible; the next character can’t be “n” if the next character is “p”. This end pattern is designed to fail. The whole pair thus means: Once you have encountered a left parenthesis or a left curly brace, immediately snarf it up along with the entire remainder of the document (and just about everything else in the grammar then works through include rules inside that snarfed-up material).

With begin/while, things are even stranger. It’s rather difficult for me to deduce what the rules are; they are not yet documented, and I know of only one grammar that uses begin/while, namely the Markdown grammar, so my available examples are quite limited. Here’s what I’ve been able to guess:

  1. Unlike begin/end, the text matched by begin/while stops at the end of the current line. Thus, if the begin is encountered and the while is never encountered, only the rest of the line containing the begin text is subsumed into the matched text.

  2. After encountering a begin match, the TextMate parser looks in the next line to see if it can match the while pattern. If it can, it incorporates the matched text and the entire rest of that line, and looks in the next line to see if it can match the while pattern. This continues until a line is encountered in which the while pattern cannot be matched.

Again, there is no backtracking; failure to find the while pattern at all is not a reason for rejecting the begin match that was already found. Notice also that nothing about these rules says that the resulting matched stretches of text have to be contiguous. That’s because they don’t have to be contiguous! So, for example, let’s say that the begin pattern matches an asterisk (*) and the while pattern matches a plus sign (+). Then (matching stretches are shown in caps):

Well, I told you it was strange! However, it seems likely that I’m abusing the begin/while rule with this example. This curious “from here to the end of the line” match behavior is probably intended for patterns that mark an entire line in terms of how it begins. You’ll notice that all the Markdown grammar uses of the begin/while work that way. For example, the blockquote rule is written like this:

That means, in essence: match an entire line that begins with one (begin) or more (while) greater-than signs (and perhaps one space after the greater-than sign), and keep matching entire successive lines (while) that begin that way.

Now let’s talk about other key–value pairs that can appear in a two-pattern rule.

  • The name key. This is the scope (or an expression evaluating to a scope) to be applied to the entire matched stretch(es) of text starting at the start of the begin match.

  • The contentName key. This is the scope to be applied to what’s between the begin match and the end match (or the end of the document). (With begin/while, this isn’t illegal, but it’s pointless, as it covers exactly the same stretch(es) as the name scope.)

  • The beginCaptures and endCaptures (or whileCaptures) keys. These work like the captures key in the one-pattern rule: the value is a dictionary each of whose entries refers to a match group in the begin, end, or while pattern respectively, and is itself a dictionary containing name or patterns (or both). Thus you can apply a scope to, and/or continue searching inside, a matched stretch of text. If the name or number of the matched group happens to be the same for both the begin pattern and the other pattern, you can (if appropriate) use captures as a shorthand to avoid saying the same thing twice.

  • The patterns key. This is like the patterns key inside the captures and beginCaptures (and so forth) dictionaries, but it applies to the region between the begin and end matches. Again, this is so that you can continue searching inside this stretch of text, which otherwise would be marked down as completed (and TextMate would start matching after the end match).

A surprise arises if a match specified in the patterns array can be satisfied by continuing beyond the end match. What happens is that the match does continue beyond the end, and causes the end to shift with it. For example, suppose we have this rule:

If we start out like this, then things behave as we expect:

The words “a bold” are in bold, and that’s the end of that. But now:

I would have expected that since the italic rule can’t be satisfied inside the matched bold stretch, it wouldn’t be matched. However, TextMate has loaded the entire second line for examination, and thus succeeds in matching the words “bold stretch” as italic. Moreover, we have now “punched through” the original end of the bold stretch, and the entire rest of the line becomes bold, along with the entire rest of the document until and unless we come to another bold end match (a plus sign). I find this both surprising and disappointing, as it greatly limits the kinds of natural logical structure you can successfully express.

(In addition, we are told that, in case both a subpattern (from the patterns array) and the main end pattern would end exactly on the same character, the end pattern wins unless you set the applyEndPatternLast key to 1. I don’t understand what this means and I won’t try to explain it.)

Developing Your Grammar

In conclusion, some pearls of advice about the process of actual development of your grammar.

Collect all the documentation I’ve mentioned (including, I dare to suggest, this article) and leave everything open on your computer screen so that you can consult it as you work.

Now create your initial language grammar and start writing rules. Your first and constant question will be, at all times: “Is this working as I intend?” Thus you will need to have open, at all times, a TextMate document whose type is set to correspond to the grammar you are developing. As you create rules, add test text to the document so that you can see how it is affected.

The big issue, of course, is whether a given stretch of text is being assigned the scope you think it should be. Unfortunately, TextMate gives you no simple way to discover this. You cannot, for example, say “Show me all the scope runs of this document.” Nor can you search for a scope within a document. So you need some other way to examine the scope(s) in force at a point of the document.

One important technique is to select some text and then press Control-Shift-P or Control-Shift-Command-P. These are commands from the Bundle Development bundle that display the current scopes(s) in a tooltip (which, unfortunately, vanishes if you so much as twitch the mouse).

Another clever device is to impose your own theme containing a special artificial scope (such as text.testing) that it styles in a very prominent way; you can then temporarily use that special scope as the name or contentName value in a rule to see just where that rule is applied in your test document. A newly created theme is empty, so you’ll probably want to paste into your theme the contents of an existing theme. For example, copy the whole contents of the Mac Classic theme; make a new theme in your bundle; select the new theme’s contents and paste the Mac Classic theme contents in its place; and now add a scope such as this:

Now bring your test document to the front and choose View > Theme > YourTheme to apply your special theme to it.

The bad news here is that if you make a change to your theme, it is not registered immediately in your test document; you have to choose View > Theme > YourTheme again in order to make any changes take effect. (Like themes, certain other changes are applied only lazily. For example, if your bundle is to have Folding settings or Table of Contents settings, you’ll find that it can be quite difficult to nudge TextMate to reflect any changes you make in those settings.)

On the other hand, the good news — the really good news — is that any change you make in your grammar takes effect as soon as you save. Thus it is very easy to work simultaneously on the test document and the grammar. You can make a change in your grammar, save, and then immediately examine your test document to see how it is styled. If you’re using the special theme trick that I just suggested, you can create or modify a rule and set its scope to text.testing to see that it carves up the document the way you expect, before changing its scope to the real value you ultimately want it to have.

Finally, be prepared to crash. This happens, presumably, because the combination of the grammar and the test document has driven TextMate temporarily insane. However, that’s not bad; it’s good, because it’s better that you should crash TextMate now, while developing your grammar, than that TextMate should crash later and cause someone (maybe you) editing a document under the influence of your grammar to lose work on that document. Moreover, you probably will not lose any work on your grammar, because the evil change that you made in the grammar didn’t go into effect until you saved; so, ipso facto, you did save. (You might lose work on your test document, but that’s far less important. Still, you should be saving that test document often as well.)

To recover from such a crash, do not be a ninny (like me) and open the test document again in TextMate. That might merely cause TextMate to crash again! It is the combination of your grammar and this test document that is the source of the trouble. Instead, open TextMate without any document, get back to the bundle editor, and try to undo whatever bad thing you did that is causing the crash. It will not always be clear what this is, but I suspect that it is usually some sort of infinite recursion caused by a match rule containing an include rule containing itself.

TextMate
Developer(s)Allan Odgaard (MacroMates), Ciarán Walsh
Initial release5 October 2004; 16 years ago
Stable release
2.0.19[1] / 25 February 2021; 48 days ago
Repository
Operating systemmacOS
TypeSource code editor
License
  • 2.0: GNU General Public License
  • 1.0: Proprietary
Websitemacromates.com

TextMate is a general-purpose GUItext editor for macOS created by Allan Odgaard. TextMate features declarative customizations, tabs for open documents, recordable macros, folding sections, snippets, shell integration, and an extensible bundle system.

History[edit]

TextMate 1.0 was released on 5 October 2004, after 5 months of development, followed by version 1.0.1 on 21 October 2004.[2][3][4] The release focused on implementing a small feature set well, and did not have a preference window or a toolbar, didn't integrate FTP, and had no options for printing.[5][6] At first only a small number of programming languages were supported, as only a few “language bundles” had been created. Even so, some developers found this early and incomplete version of TextMate a welcome change to a market that was considered stagnated by the decade-long dominance of BBEdit.[7]

TextMate 1.0.2 came out on 10 December 2004. In the series of TextMate 1.1 betas, TextMate gained features: a preferences window with a GUI for creating and editing themes; a status bar with a symbol list; menus for choosing language and tab settings, and a “bundle editor” for editing language-specific customizations. On 6 January 2006, Odgaard released TextMate 1.5, the first “stable release” since 1.0.2.[8] Reviews were positive, in contrast to earlier versions that had been criticised.[9]

TextMate continued to develop through mid-2006. On 8 August 2006, TextMate was awarded the Apple Design Award for Best Developer Tool, at Apple's Worldwide Developers Conference in San Francisco, California, to “raucous applause.”[10] In February 2006, the TextMate blog expressed intentions for future directions, including improved project management, with a plug-in system to support remote file systems such as FTP, and revision control systems such as Subversion.[11] Throughout 2007, the core application changed only minimally, though its “language bundles” continued to advance.

In June 2009, TextMate 2 was announced as being about 90 percent complete, but with an undisclosed final-feature list.[12] A public alpha was made available for download on the TextMate blog in December 2011, followed by a release candidate at the end of 2016. In September 2019, a final version was released.[13]

In August 2012, TextMate 2's source code was published on GitHub under the terms of version 3 of the GNU General Public License,[14] an attempt by the developer to counteract restrictions Apple placed on software distributed through the Mac App Store.[15] TextMate licenses continue to be sold on macromates.com, however.[16] Odgaard stated he prefers receiving patches as public domain as this preserves his ability to release a future version under a more permissive license, or to make a version available on the Mac App Store. Odgaard also stated he has a friend who uses some of TextMate's frameworks in a closed-source project, and they could not incorporate patches released under GPL.[17][18]

Features[edit]

Hierarchal scopes[edit]

TextMate allows users to create their own arbitrarily complex syntax highlighting modes by using a modified version of the Apple ASCII property list format to define language grammars. These grammars allow nesting rules to be defined using the Onigurumaregular expression library, and then assigned specific “scopes”: compound labels which identify them for coloration.

Therefore, each point of a document is assigned one or more scopes, which define where in the document the point is, how it should be colored, and what the behavior of TextMate should be at that point. For instance, the title of one of the links in the “External links” section has the scope:

This scope tells us that we are looking at a link title within a link within a list within a MediaWiki document.

TextMate themes can mark up any scope, at varying levels of precision. For instance, one theme may decide to color every constant (constant.*) identically, while another may decide that numerical constants (constant.numeric.*) should be colored differently than escaped characters (constant.character.escape.*). The hierarchal scope syntax allows language authors and theme authors various levels of coverage, so that each one can choose to opt for simplicity or comprehensiveness, as desired.

Commands[edit]

TextMate supports user-defined and user-editable commands that are interpreted by bash or the interpreter specified with a shebang. Commands can be sent many kinds of input by TextMate (the current document, selected text, the current word, etc.) in addition to environment variables and their output can be similarly be handled by TextMate in a variety of ways. At its most simple, a command might receive the selected text, transform it, and re-insert it into the document replacing the selection. Other commands might simply show a tool tip, create a new document for their output, or display it as a web page using TextMate's built-in HTML renderer.

Many language-specific bundles such as bash, PHP or Ruby contain commands for compiling and/or running the current document or project. In many cases the STDOUT and STDERR of the code's process will be displayed in a window in TextMate.

Snippets[edit]

At their simplest, TextMate “snippets” are pieces of text which can be inserted into the document at the current location via a context-sensitive key stroke or tab completion. Snippets are 'intelligent', supporting 'tab stops' dynamic updating, access to environment variables, and the ability to run inline scripts. This allows complicated behaviors. Tab stops can be cycled through using the “tab” key and support default text, drop-downs, to complete elements of the snippet. The results of these tab stops can be dynamically changed in another portion of the snippet, as the user fills in a stop. TextMate environment variables can be used, supporting information about the current scope, line number, or author name, etc. Snippets also have the ability to run inline shell scripts.

Textmate for windows

Bundles[edit]

TextMate language grammars, snippets, macros, commands, and templates can be grouped into “bundles” of functionality. Any snippet, macro, or command can be executed by pressing a keyboard shortcut, by typing a particular word and then pressing the “tab” key (so-called “tab triggers”), or by selecting the command from a menu. Alive address book serialfree software and shareware. Tab triggers are particularly useful; the combination of tab triggers and snippets greatly eases coding in verbose languages, or languages with commonly typed patterns.

Snippets, macros, and commands can be limited to a particular scope, so that for instance the “close html tag” command does not work in a python script, freeing up that keyboard shortcut to be used for something else. This allows individual languages, and even individual scopes, to override built-in commands such as “Reformat Paragraph” with more specialized versions. Even special keys such as the return key and spacebar can be overridden.

A Subversion repository is available containing many more bundles than are shipped with the editor package, for everything from Markdown to blogging to MIPS assembly language.[19]

Project management[edit]

Several documents or folders can be opened at once in a TextMate project window, which provides a drawer along its side listing file and folder names, and a series of tabs across the top. In TextMate 1.5, this drawer provides a means for users to organize files and folders from across the file system, as well as the ability to create virtual folders for further organization. This feature was removed from TextMate 2 and replaced with an ordinary file browser. Search and replace can be undertaken across an entire project, and commands can interact with the selected files or folders in the drawer. Bundles for CVS, Subversion, darcs, and other revision control systems allow TextMate to manage versioned code.

Other features[edit]

TextMate has many features common to programming editors:

  • Folding code sections can be used to hide areas of a document not currently being edited, for a more compact view of code structure or to avoid distraction. The sections to be folded can be selected by hand, or the structure of the document itself can be used to determine foldings.
  • Regular-expression–based search and replace speeds complicated text manipulations. TextMate uses the Oniguruma regular expression library developed by K. Kosako.[20]
  • A function pop-up provides a list of sections or functions in the current document.
  • Clipboard history allows users to cut many sections of text at once, and then paste them.
  • Column editing mode allows adding the same text to several rows of text, and is very useful for manipulating tabular data.
  • 'rmate' support for launching textmate as editor for files from remote servers - much improved over work-arounds needed in version 1 [21]

In addition, TextMate supports features to integrate well with the OS X graphical environment:

  • Clipboard graphical history supports pasting from previous copies, including prior launches.
  • Find and replace support an analogous graphical history.
  • Editing is further enhanced by multiple cursors (insertion points), and the ability to extend the current selection to additional instances creating multiple cursors.
  • A WebKit-based HTML view window shows live updates as an HTML document is edited.
  • VoiceOver and Zoom users can use TextMate thanks to its accessibility support.[22]

Limitations[edit]

TextMate does have a few limitations when compared to other editors in its class:

  • Because TextMate is not tightly coupled to a scripting language, as Emacs is to Emacs Lisp, it is impossible for users to have complete control over the program's configuration and behavior. Allan Odgaard explained his thoughts on the subject in an email to the TextMate mailing list, advocating for 'platform-recommended' solutions.[23]
  • No built-in HTML validator — because TextMate uses the W3C validator for HTML validation, users must have an active network connection to validate HTML using the standard functionality.
  • Despite its substantial support for macros, commands, and snippets, TextMate has no built-in support for code-hinting or guided code-completion, so text editors that support these features may prove to be a better choice when learning the syntax of a new language or coding in verbose languages.
  • TextMate is not binary safe. It is explicitly text only, and does not guarantee that arbitrary binary data in a file will be preserved through a load/save cycle, regardless of whether that data is edited.[citation needed]

Community[edit]

TextMate has a community of users, who contribute to the git repository of open-source TextMate bundles.[24] The TextMate wiki has hints and tips, feature suggestions, and links to external resources. A ticket system exists for filing bug reports and feature requests, and an IRC channel (#textmateconnect) is usually active.

TextMate bundles exist to support code written in many dozens of programming languages. The Ruby and Ruby on Rails bundles are supported by David Heinemeier Hansson, Ruby on Rails’ creator.

Awards[edit]

TextMate 1.5 won the Apple Design Award for best developer tool in 2006.

See also[edit]

References[edit]

  1. ^'Release 2.0.19'. 25 February 2021. Retrieved 20 March 2021.
  2. ^David Hansson. “TextMate 1.0 is finally here!”, TextMate Blog, 5 October 2004.
  3. ^Allan Odgaard. “Profiles/Allan Odgaard” on the TextMate wiki, 20 November 2005.
  4. ^David Hansson. “TextMate 1.0.1 emerges after nine betas”, TextMate Blog, 21 October 2005.
  5. ^Matt Willmore. “TextMate 1.0.1 Review: A Checkmate for TextMate?Archived 2006-08-20 at the Wayback Machine”, Maczealots.com, 8 October 2004.
  6. ^Michael “drunkenbatman” Bell. “TextMate: The Missing Editor for OS XArchived 2006-05-14 at the Wayback Machine”, Drunkenblog, 4 November 2004.
  7. ^Kimbro Staken. “A cool new text editor - TextMate - Mac OS XArchived 2004-12-04 at Archive.today”, Inspirational Technology, 6 October 2004.
  8. ^Allan Odgaard. “TextMate 1.5”, TextMate Blog, 6 January 2006.
  9. ^Rui Carmo. “Third Time’s The Charm”, Tao of Mac, 8 January 2006.
  10. ^John Gruber. “ADA: TextMate 1.5.2”, Daring Fireball Linked List, 8 August 2006.
  11. ^Allan Odgaard. “Future Directions”, TextMate Blog, 15 February 2006.
  12. ^TextMate Blog: Working on It, 14 June 2009
  13. ^TextMate Github: [1], Sep 16, 2019
  14. ^GitHub, [2], Aug 9, 2012
  15. ^'TextMate 2.0 goes open source in response to OS X restrictions'. TextMate developer MacroMates announced on Thursday that the code for TextMate 2.0, currently in alpha, is now available via the online GitHub repository. The code is being open sourced in order to counteract what some developers see as Apple's increasingly limiting user and developer freedom on the Mac platform.
  16. ^'License Policy'. Retrieved June 17, 2018.
  17. ^Odgaard, (2009). CONTRIBUTING.md.
  18. ^'Odgaard: 'I will continue working on TextMate as long as I am a Mac user''. Many open source proponents and would-be code contributors were vociferous in their opposition to Odgaard's choice of version 3 of the GNU General Public License, while asking upstream code patches to carry a public domain license. The problem, unfortunately, is the tug-of-war between FOSS principles and the desires of commercial ventures.
  19. ^For information on getting more bundles, see the relevant section in the TextMate manual.
  20. ^'20 Regular Expressions'. TextMate. Retrieved 2009-04-28.
  21. ^How to edit files from my FTP Server as a TextMate project. TextMate Wiki - FAQ: Projects
  22. ^Support accessibility in text view - VoiceOver and Zoom. GitHub pull request
  23. ^Allan Odgaard. “Re: Changing cursor position from command”. TextMate mailing list. 14 February 2007.
  24. ^Manual.macromates.com

Further reading[edit]

Textmate 3

  • Gray, James Edward II (January 2007). Textmate: Power Editing for the Mac. Pragmatic Bookshelf. ISBN0-9787392-3-X.

Textmate For Windows

External links[edit]

Textmate Themes

Retrieved from 'https://en.wikipedia.org/w/index.php?title=TextMate&oldid=1008465121'