9 Environment Variables

Environment variables are used extensively in TextMate to provide scripts and commands with information.

Here is how to read the value of a variable (named VAR) in different scripting languages:

You can use them directly in Snippets, like in bash. Both bash and snippets support an extended form (${VAR}) where it is possible to do replacements in the variable, provide fallback values (if it is unset) etc.

Remember to double-quote variables used in shell scripts, otherwise bash will first expand the variable to its value and then split this according to the input-field-separator characters (read as the IFS variable, defaults to spaces, tabs and newlines). This means if TM_FILENAME is My Document.txt and we execute rm $TM_FILENAME then rm will actually get two arguments, first one being My and the second one being Document.txt.

For info about what can be done with environment variables in bash, see this blog post about the issue or check out the bash man file.

9.1 Dynamic Variables

The following variables reflect the users current configuration, which file he has open, where the caret is located in that file, the selection in the project drawer and so on.

A script can read these variables and make decisions accordingly.

Some of the variables are not always present. For example if the current file is untitled, or there is no selection, the corresponding variable will be unset. This is useful for example to make a command work with the selection, but fall back on the current line or word.

Bash has shorthand notation for providing a default value when a variable is not set, for example to fallback on the current word when there is no selection, we would use: "${TM_SELECTED_TEXT:-$TM_CURRENT_WORD}".

9.2 Static Variables

In addition to the dynamic variables, which TextMate provides automatically, it is sometimes useful to provide a list of static variables.

For example you may have templates or snippets that should insert your company name and prefer not to put the value directly in these, or there could be shared commands which need localized settings, for example the SQL bundle has a query command which use variables for username, password and database.

For this reason it is possible to set a default list of environment variables in Preferences → Advanced → Shell Variables.

Shell Variables

These variables are given to all shell commands started from TextMate and can also be used in snippets (as can the dynamic variables for that matter).

9.3 Context Dependent Variables

Some variables are a cross between dynamic and static. For example the Source bundle contains a Toggle Comment command which will toggle the comment for the current line or selection. This command uses three variables to decide what type of comment style the user wants.

A user who works with multiple languages will however need to specify this per language. This can be done by setting the shellVariables array in the bundle preferences and provide the proper scope selector to limit these variables.

Scoped Environment Variables

This has the advantage of actually being based on the carets location, which for the Toggle Comment command allows us to have it work differently for JavaScript, CSS, HTML and embedded PHP + Ruby, all in the same document.

An example of setting the 3 variables to comment the entire block (instead of line-by-line) with the HTML/SGML/XML comment markers is shown here:

shellVariables = (
   {  name = 'TM_COMMENT_START';
      value = '<!-- ';
   },
   {  name = 'TM_COMMENT_END';
      value = ' -->';
   },
   {  name = 'TM_COMMENT_MODE';
      value = 'block';
   },
);

9.4 Project Dependent Variables

Sometimes it is useful to have a command customized differently depending on the project. For this reason, it is possible to set variables for individual projects.

The way to do this is currently a little secret but if you deselect everything in the project drawer, then click the info (circled I) button, a panel will appear where you can set variables.

These variables are saved in the project file (*.tmproj) and will exist only for snippets and (shell) commands executed in the context of that project.