This guide goes through the various style issues related to creating a bundle.

If you are going to contribute the bundle to the shared repository of bundles, please read through this entire style guide.

Comments are welcomed!

Naming the Bundle

If the bundle is intended to add support for a specific programming language, it should be named after this language.

If it provides support for a framework or similar used with a specific programming language, the bundle should use the name of the programming language first, and then the name of the framework.

For example the bundle adding support for Yahoo’s UI library is named ‘JavaScript YUI’, since the framework is named YUI and is for JavaScript.

By prefixing the bundle with the name of the language for which the framework is for, the bundle will be close to the language in the Bundles menu, and users who are not familiar with the language or framework, will have a better idea about what it is.

Naming Bundle Items

A bundle item which will prompt the user for input or confirmation (normally by opening a dialog) must end with an ellipsis (…). This character is typed using ⌥; (on a US keymap).

A bundle item (command) which works on the selection or a fallback unit should indicate this by using “«unit» / Selection” in the title, for example: “Paste Line / Selection Online…”. When the user is browsing the menu, TextMate will remove the part that does not apply.

Bundle item titles should be title cased as described in Apple’s human interface guidelines:

> Title style means that you capitalize every word
> except:
>   * Articles (a, an, the)
>   * Coordinating conjunctions (and, or)
>   * Prepositions of three or fewer letters, except
>     when the preposition is part of a verb phrase,
>     as in “Starting Up the Computer.”
> In title style, always capitalize the first and last
> word, even if it is an article, a conjunction, or a
> preposition of three or fewer letters.

Keep bundle item titles short but do not sacrifice understandability. We prefer a long title where the user understands what selecting the item will lead to, over something short which requires reading the help file for the bundle.

Key Equivalents

When finding a key for an action be sure to adhere to the conventions established in other bundles, some of these are listed below.

  • ⌘R — run current document / typeset document
  • ⌘B — build current document
  • ⌘I — insert markup for italic around selection or caret
  • ⌘B — insert markup for bold around selection or caret
  • ⌘U — insert markup for underline around selection or caret
  • ⌘K — insert markup for color / monospace or similar fourth style around selection or caret
  • ⌃H — lookup documentation (for current word)
  • ⌃⇧H — convert / tidy / pretty print document
  • ⌃⇧L — wrap selection as a link
  • ⌃⇧V — validate document (e.g. W3C or lint)
  • ⌃⇧W — wrap selection in something
  • ⇧↩ — create a function using the current word as its name
  • ⌅ — insert newline starting with markup resembling that of the current line (e.g. insert line comment marker, list item bullet, etc.)

When you are introducing functionality unparalleled by other bundle’s items, then you may need to find a new key equivalent. Use ⌃⇧ as modifiers, though be aware that the following key equivalents are globally unavailable:

  • ⌃⇧A — Subversion menu
  • ⌃⇧B — Insert comment header (banner)
  • ⌃⇧C — Math menu (various calculations)
  • ⌃⇧D — Duplicate line
  • ⌃⇧E — Execute line as ruby
  • ⌃⇧F — Hypersearch (find)
  • ⌃⇧J — Merge line with next (join)
  • ⌃⇧K — Delete line (kill)
  • ⌃⇧N — Document Statistics (word count)
  • ⌃⇧O — Open terminal
  • ⌃⇧P — Show current scope
  • ⌃⇧Q — Run line / selection as an SQL query
  • ⌃⇧T — Show TODO list
  • ⌃⇧X — Convert character to hexadecimal
  • ⌃⇧Z — CVS menu

If there is no key available with ⌃⇧ then use ⌃⇧⌘.

Tab Triggers

Tab triggers should be easy for the user to guess, that means either use the first word of what is inserted (which would often be a language keyword like for, while, or similar) or devise a consistent convention, for example just the first 3 letters of what is inserted, if many of the language keywords are too long.

Not having an easy to guess or consistent scheme means that users will generally not be able to use the tab triggers.

Scope Selectors

All items in a bundle MUST be scoped so that they are only available for the language the bundle caters for.

Even items without a key equivalent or tab trigger should generally be scoped to the language the bundle represents, as the items will otherwise clutter the Select Bundle Item… menu (brought up on ⌃⌘T).

Language Grammar

The language grammar should use the first letter of the bundle name with ⌃⌥⇧ as modifiers for its key equivalent. For example Java is ⌃⌥⇧J.

Scope Names

The scope names used in the language grammar MUST conform to the naming conventions mentioned in the manual.

Some historical info is available.

To make it a bit easier, there is a validate_bundle.rb script in Support/bin. This is called with a bundle as argument, and will tell you if any of the scope names are not conforming, for example:

cd ~/Library/Application\ Support/TextMate/Bundles
../Support/bin/validate_bundle.rb Java.tmbundle

Environment Variable Prefix

Any environment variables should be prefixed by TM_«bundle_name». This is to prevent collisions with other applications or bundles. bundle_name should be the name of the bundle lowercased with spaces replaced by underscores (_). If the bundle name is exceptionally long a shorter token may be used, but should be used for the entire bundle.

Menu Structure

Be sure to edit the menu structure of the bundle. This is done by opening the bundle editor and selecting the bundle itself.

See the Designing the Elements of Menus section of AHIG for tips about how to design menus.

Some general rules of thumb:

  • don’t be afraid to use separators in the menu to group items, grouping makes the menu look more distinctive, which is generally good — of course grouping should make sense
  • place the most important / used items near the top of the menu
  • the root menu should preferably not have more than 15-20 items, and with that many items, there should on average be only 3-5 items per group

Help File

Bundles that require setup or where features are not clear from the item titles should contain a help file. Make a command in the bundle called Help without a key equivalent or tab trigger, but still give it a scope selector so that ⌃⌘T + entering help will show just that item, in the Select Bundle Item… window.

Generally we use Markdown for help files and have them converted on-the-fly using the HTML output option.

If your help is divided into sections, you can use the $TM_SUPPORT_PATH/lib/markdown_to_help.rb script to have a table of contents generated and sections enumerated. See e.g. LaTeX → Help for an example.


If there is an item for setting the preferences for the bundle it should be named "Preferences…" with a key equivalent of ⌥⌘, (Option-Command-,).

Test Files

If you have various files that act to test the grammar/etc they should be located in a directory named "Tests" in the top level of the bundle.

Contact / Description

Each bundle needs to contain a contact name / address and a short description.

Currently there is no way to edit (nor view) this from inside TextMate. The info is kept in the bundle’s info.plist using the following keys:

  • contactName — The full name of the contact for this bundle.

  • contactEmailRot13 — A ROT13 encoded email address for the bundle contact (we obfuscate it to avoid spammers from picking up the files, seeing how bundles will often be available via anonymous svn over http). Hint: TextMate has a ROT13 encryption function in the Mail bundle.

  • description — A short description for the bundle. Do link to more info about the language (or whatever) the bundle is about. The format is HTML, but do not style the content, only use it for links. The description will generally be placed inside a <p>…</p> or it will be shown as plain text, with all tags stripped.


This is from Vectorscript.tmbundle/info.plist:

<string>Ryan McCuaig</string>
<string><a href="">VectorScript</a> is the scripting language used by the <a href="">VectorWorks</a> CAD software.</string>