Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
TextMate 2 .tm_properties

This is all based on the alpha release.


From the built-in help system:

For many settings TextMate will look for a .tm_properties file in the current folder and in any parent folders (up to the user’s home folder).

These are simple setting = value listings where the value is a format string in which other variables can be referenced.

If the setting name is uppercase it will be available as an environment variable (for commands and snippets).

For example to setup the basic stuff one could have ~/.tm_properties with these values:

# Settings
theme            = "71D40D9D-AE48-11D9-920A-000D93589AF6"
fontName         = "Menlo"
fontSize         = 13
fileBrowserGlob  = "{*,.tm_properties,.htaccess}"

# Variables
PATH             = "$PATH:$HOME/bin"
TM_GIT           = "/opt/local/bin/git"

It is possible to target only files matching a given glob, for example:

[ *.txt ]
softWrap         = true

softWrap         = true
spellChecking    = true
spellingLanguage = 'en'

[ "/usr/include/{**/,}*" ]
tabSize          = 8

A magic value of attr.untitled is used for untitled files. This allows setting the file type for these, e.g.:

[ attr.untitled ]
fileType         = 'source.c++'

The normal TM variables are available when expanding the format strings (values). In addition a CWD variable is available which represents the folder from which the .tm_properties file is read. This is necessary to set the project directory, for example I have ~/Source/Avian/.tm_properties with these settings:

projectDirectory = "$CWD"
windowTitle      = "$TM_DISPLAYNAME — Avian"
fileChooserGlob  = "{{src,Shared/include}/**/*.{cc,mm,h},target{,s},Makefile{,.*},.tm_properties}"

The first setting effectively sets TM_PROJECT_DIRECTORY to ~/Source/Avian. In ~/Source/Avian/Applications I have a (variable) setting like this:

TM_MAKE_TARGET   = '${TM_DIRECTORY/^.*\/Applications\/([^\/]+)(\/.*)?$/$1\/run/}'

What this does is set the make target based on the current directory. So if I am editing ~/Source/Avian/Applications/mate/src/ ⌘B will make mate/run whereas if I am in ~/Source/Avian/Applications/Avian/src/ it will make Avian/run. [Apple]: “Apple Inc.”

Load Order

From a pastie by Allan Odgaard. source

It will read from current folder and up until either it reaches ~ or /. If it reaches / then it will additionally read ~/.tm_properties. This means you can have “global” settings in that file and they work even when opening stuff not under your home folder.

In the file you can do sections with a glob against full path to restrict the following settings to just those which match the glob.

In the variable part you have a few variables, the usual $TM_FILEPATH and friends, but you also have $CWD, this is the folder containing the property file. This is useful if you put a .tm_properties file in the root of your project, for example I use this file with Avian:

# Settings
tabSize              = 3
projectDirectory     = "$CWD"
windowTitle          = "$TM_DISPLAYNAME — ${CWD/^.*\///}"
excludeInFileChooser = "{$exclude,*.xib}"

# Variables

TM_SYS_HEADER_PATH   = '${TM_SYS_HEADER_PATH:?$TM_SYS_HEADER_PATH:/usr/include/c++/4.0.0:/usr/include:/System/Library/Frameworks}:$CWD/Shared/include:${BUILD_DIR:-$CWD/build}/Avian/public'
TM_TODO_IGNORE       = '/(disabled(-src)?|onig-.*|build|cache|CxxTest|(FScript|BWToolkitFramework).framework)/'

TM_MAKE_FILE         = '${CWD}/Makefile'
TM_MAKE_TARGET       = 'Avian/run'

[ target ]
fileType             = ""

[ *.{h,pch} ]
fileType             = "source.objc++"

[ Makefile.* ]
fileType             = "source.makefile"

[ attr.untitled ]
fileType             = 'source.c++'

[ "tests/*.{cc,mm}" ]
scopeAttributes      = 'attr.test.cxxtest'
TM_MAKE_TARGET       = '${TM_FILEPATH/^.*?([^\/]*)\/tests\/.*$/$1/}/test'

[ "rmate/*" ]
TM_MAKE_TARGET       = rmate

As you can see I set the Makefile via CWD — here I can’t use TM_FILEPATH or similar, because those will be the “current file”, not the project root.

Some things of interest is how e.g. test files get the scope augmented, this is because I have unit test snippets I only want active in test files. Additionally I change the make target for test files.

While the .tm_properties can contain both settings and environment variables, while interpreting the file, Avian doesn’t distingish between the two, so it is possible to mix them in the value part and also reference already set variables, e.g. if we want to extend the default exclude setting we can do:

exclude = '{$exclude,*.o}'

The value is a glob so we use brace expansion to add the *.o extension.

Known Properties

From a pastie by Allan Odgaard. source


  • theme — UUID of theme, presently unused but will be back, and should allow name of theme as well (use View → Themes to change theme — remember to install the Themes bundle).
  • fontName, fontSize — Name and size of font, e.g. Menlo and 13. Presently these two keys are required to override font, but there will be a font option in the View menu, so this is only for special requirements.
  • showInvisibles — Sets the initial value. Can also be changed via View menu.
  • softTabs, tabSize — Presently can only be changed this way, but there should be some memory added to Avian.
  • spellChecking, spellingLanguage — Enable/disable spelling and set language. The language is defined by Apple, I can extract a list (but depends on installed spell checkers).


  • projectDirectory — the project directory, generally set to $CWD in a .tm_properties file at the root of the project. This affects TM_PROJECT_DIRECTORY and default folder for ⇧⌘F.
  • windowTitle — override the window title. The default is $TM_DISPLAYNAME but could e.g. be changed to $TM_FILEPATH. Should add a $TM_SCM_BRANCH.


  • binary — If set for a file, file browser will open it with external program when double clicked. Mainly makes sense when targetting specific globs.
  • encoding — Set to the file’s encoding. This will be used during save but is also fallback during load (when file is not UTF-8). Load encodinng heuristic is likely going to change.
  • fileType — The file type given as scope, e.g. text.plain.
  • useBOM — Used during save to add BOM (for those who insist on putting BOMs in their UTF-8 files).

File Filters

These are all globs and perhaps a bit arcane. (Note that the glob syntax is documented in the built-in help system.)

The file browser, if it has a file, checks that file against the first key with a value in this order: excludeFilesInBrowser, excludeInBrowser, excludeFiles, exclude. If neither match, it then does the same with include keys, and if one match, it is included.

The default include key is * (so no hidden files, although see the default .tm_properties which include .htaccess and .tm_properties). The default exclude key is the empty string (nothing matches).

  • exclude
  • excludeFiles
  • excludeDirectories
  • excludeInBrowser
  • excludeInFolderSearch
  • excludeInFileChooser
  • excludeFilesInBrowser
  • excludeDirectoriesInBrowser
  • include
  • includeFiles
  • includeDirectories
  • includeInBrowser
  • includeInFileChooser
  • includeFilesInBrowser
  • includeDirectoriesInBrowser
  • includeFilesInFileChooser

File Browsing

Purpose currently unknown.

  • fileBrowserGlob
  • fileChooserGlob


  • scopeAttributes — The value is added to the scope of the current file.

Default Properties

TextMate 2 defaults stored in

exclude = "{*.{o,pyc},Icon\r,CVS,_darcs,_MTN,\{arch\},blib,*~.nib}"
include = "{.tm_properties,.htaccess}"

TM_HG  = "/opt/local/bin/hg"
TM_GIT = "/opt/local/bin/git"

[ "/usr/include/{**/,}*" ]
tabSize          = 8

[ text ]
softWrap         = true

softWrap         = true
spellChecking    = true
spellingLanguage = 'en'

[ *.{icns,ico,jpg,jpeg,m4v,nib,pdf,png,psd,pyc,rtf,tif,tiff,xib} ]
binary           = true

[ source.ruby ]
softTabs         = true
tabSize          = 2

[ source.python ]
softTabs         = true
tabSize          = 4

[ "/System/Library/Frameworks/**/Headers/**/*" ]
encoding         = "MACROMAN"

fileType         = "text.plain"


  • Project files (*.tmproj) no longer exists. The .tm_property file will take its place and there are no plans to bring them back. source
  • Setting projectDirectory = "$CWD" affects how documents are opened. If a file is already opened then opening another file will be opended in the same window in a new tab. If they don't share the same .tm_property pointing to a directory, the opened file will open in a new window.
  • Settings environmental variables through preferences do not always work. Set it through the properties file to make them stick. The same goes for many menu items and other settings set from the preference window. When in doubt, use the properties file.
  • Properties set for a sub-directory will override whatever is set for its parents. It can carry over by accessing the parent property and using that for the sub-folder. To get the existing setting, prefix the name with a $ and combine with the new setting. Examples: exclude = "{$exclude, *.foo}", windowTitle = "Project Name – $windowTitle".
  • The color for ShowInvisibles property can be set through the theme. In the plist tree: settings > settings > invisibles. It uses a hex string with an optional alpha, e.g., #AAAAAA66 with 66 being the alpha. In version 1.x, it could be set through preferences.
  • Not related to any particular setting but the markdown language depends on a default theme to do scoped font changes. It's probably a good idea to leave the "Themes" bundle enabled even if none of the default themes are being used directly.

dvessel commented Dec 14, 2011

A few more resources:


dvessel commented Dec 15, 2011

Here’s an example of what I use:

Under ~/.tm_properties

# Display the name of the home directory.
windowTitle         = "$TM_DISPLAYNAME — ${CWD/^.*\///}"

# Omit .tm_properties so it doesn't show in the browser.
include             = ".htaccess"
# Exclude old *.tmproj files.
exclude             = "{$exclude,*.tmproj}"

# Variables.
TM_GIT              = "/usr/local/bin/git"
TM_SVN_DIFF_CMD     = "/usr/local/bin/ksdiff-svnwrapper"
PHP_MANUAL_LOCATION = "$HOME/Sites/localhost/reference/php_manual/"
TM_DRUPAL_API       = ""

# General settings.
showInvisibles      = true
spellChecking       = true

[ text ]
softWrap            = false
wrapColumn          = 80
softTabs            = true
tabSize             = 2

[ text.html.markdown ]
softWrap            = true
wrapColumn          = "Use Window Frame"
softTabs            = false
tabSize             = 4

[ text.plain ]
softWrap            = true
wrapColumn          = "Use Window Frame"
softTabs            = false
tabSize             = 4

[ source ]
softWrap            = false
wrapColumn          = 80
softTabs            = true
tabSize             = 2

[ source.plist ]
softTabs            = false
tabSize             = 4

[ ]
spellChecking       = false

For each project /.tm_properties

projectDirectory    = "$CWD"
windowTitle         = "$TM_DISPLAYNAME — Project Name"

For my Drupal projects

windowTitle           = "$TM_DISPLAYNAME — Project Name"
projectDirectory      = "$CWD"
excludeInFolderSearch = "{$excludeInFolderSearch,sites/*/files}"


Under Default Properties, I think you spelled the pathname wrong:

should be

AlekSi commented Dec 16, 2011

@dvessel Typo: $TM_FIEPATH instead of $TM_FILEPATH


dvessel commented Dec 16, 2011

Thanks guys. Fixed the typos.

Any setting for which side the project drawer shows on?

fk commented Dec 17, 2011

@dvessel Thanks!
@ryanfitzer You've probably already seen this in the release notes ("Help → Release Notes") from yesterdays update (8949):
File browser can be placed on the right side: defaults write com.macromates.TextMate.preview fileBrowserPlacement right.


Has anyone had any issues with settings not affecting the CWD? Specifically, fontName, and fontSize.

Ok, I created a .tm_properties file in the ~/ directory and the props worked. Not sure why they don't when in the project's directory.

I've noticed when specifying a property you need to have spaces around the equal sign.
So windowTitle="My Project" doesn't work but windowTitle = "My Project" does.


dvessel commented Dec 19, 2011

@ryanfitzer, still a problem in the latest release? I noticed that happened when I forced the .tm_defaults to not show in the file browser. It’s no longer a problem for me.

As far as CWD, I’m not sure why you would specifically target that. Just place the settings in the defaults file and it’s effectively the same as CWD.

Just saved a new .tm_properties file with a different fontName and fontSize in my project directory and saw no change.

spadin commented Jan 4, 2012

Thanks for this! I was about to give up on TextMate 2 for now until I found this gist and the info about tabSize and softTabs.

mmzoo commented Jan 13, 2012

Could someone give me a hint how I can make TextMate interpret an application bundle (i.e. as a regular directory instead of a package? I can't quite figure it out...

noelboss commented Feb 1, 2012

@dvessel Had the same issue as ryanfitzer. Saving the file in my User Dir worked – project folder didn't.
Version 2.0 (8971)

csuhta commented Feb 4, 2012

I found I was assuming that some things would work, but they actually fail silently. This may not be 100% correct, but my rules are now all working after following these tips:

You have to put spaces inside the braces for a scope rule

# this
[ source.php ]
# not this

You can't combine scopes. You have to do each scope rule separately.

[ text.html.erb,source.ruby ]
softTabs = true
softWrap = false
tabSize = 2

# This also DOES NOT work
[ source.ruby ]
[ text.html.erb ]
softTabs = true
softWrap = false
tabSize = 2

Expanded blob syntax seems to choke on dots inside the expandable pattern

# This works
[ "*.{erb}" ]

# This doesn't seem to work
[ "*.{html.erb}" ]

I'm having trouble with excluding Subversion directories. I have tried these variations of the same line all to no avail:

excludeDirectories = ".svn"
excludeDirectories = "{.svn}"

Would appreciate help from anyone who's successfully done this.

Also tried the following, also with no better success:

excludeInFileChooser = "{$excludeInFileChooser,log,vendor,tmp,META-INF,.svn}"
excludeInBrowser = "{$excludeInBrowser,log,vendor,tmp,META-INF,.svn}"
excludeInFolderSearch = "{$excludeInFolderSearch,log,vendor,tmp,META-INF,.svn}"

Anyone found an option for making the Symbol list alpha-sorted yet? Is there even an option for this in the current build?

csuhta commented Feb 24, 2012

@syn4k I see that even themes included with TM2 have a lineHighlight color set, but TM2 seems to be ignoring it.

fleep commented Mar 14, 2012

Is there any way to keep the filebrowser open even after you close the last file?

When I open a "project" directory from my terminal:

mate ~/myproject

It opens up my project with an "untitled" file open. Sometimes I just want the file browser there without an active, editable file (or rather, I've opened up a bunch of files, and I've CMD+W them all away). In TextMate 1, the project window remained open with the project pane. In TextMate 2, once you close that last file, the file browser goes away with it.

Is there a setting to change this behavior? It's probably the last thing keeping me from using this over TM1.

csuhta commented Mar 15, 2012

@fleep, the Macromates site says:

When I close the final tab in a window the entire window closes, is there a way to change/stop this?
This is a common request and is likely to change in a future build.

rk commented Jun 28, 2012

Is there a way to get configuration values from the .tm_properties file from within a command?

fleep commented Jun 28, 2012

@rk: do you mean from a particular scripting language? Or from the command line? Or from within Textmate itself?

rk commented Jun 28, 2012

@fleep: I mean that from within a command, say written in Ruby, is there a way to get options from the nearest .tm_properties file? I've been using the JSLint module with a command, and instead of globally configuring it with settings I want to put them into a JSLint section of the .tm_properties file and get them from it. So far I'm not finding it, if it exists.

fleep commented Jun 28, 2012

@rk: It's a relatively easy-to-parse text file, and most languages provide easy-to-use directory-traversal tools. It's trivial in PHP, for example, to crawl up a directory tree from the current directory until you find a .tm_properties file, and then pass the filename to parse_init_file() to get an array of the properties.

rk commented Jun 29, 2012

@fleep: Yeah, it is. I've done stuff like that before. However, I wanted to know if the TextMate environment had something already built to do this. After looking at the bundle resources I don't think there is one yet.

Any way to treat symlinks as expandable directories (ie with the clickable triangle next to it) in the file browser?

this doesn't work on cython files (I'm using the old school Cython bundle for syntax highlighting, this may be the problem? any tips on how I can edit it to fix?)

[ source.python ]
disableIndentCorrections = true
indentOnPaste = "simple"

# I've also tried [ source.cython ] here, to no avail...
[ *.pyx ]
disableIndentCorrections = true
indentOnPaste = "simple"

(this does nothing - it still aggressively and wrongly corrects my indentation in pyx files.)

bobrocke commented Feb 2, 2013

+1 for manewitz. Symlinks as expandable directories would solve some of my project management problems.

estum commented Feb 13, 2013

How to add multiple source scope? For example, *.css.scss files scopes either to source.css or to source.scss.

How can I have "Show Invisibles" for files always on? I tried the showInvisibles settings but it seems to only apply to invisible characters in the text.

Zearin commented Jun 4, 2014

@dvssel Thanks for this! I have a fork with some minor improvements to formatting, grammar, and phrasing. Please feel free to use my edits if you want!

is the theme setting implemented yet? I am doing this:

    [ *.{yaml,yml,YAML} ]
    theme            = '6b98072a-62a3-4cd4-b597-35c38bff8016'

and I'm not sure if it is not working because it is not implemented yet or some other reason.

Wolfr commented Dec 2, 2015

Here is mine, I wrote a blog post a long time ago with some tips:

include = "{$include,.gitignore,,.htpasswd,.htaccess,jshintrc,.editorconfig,.tmp,.prettifyrc,node_modules/bootstrap-sass}"
excludeInFolderSearch = "{$excludeInFolderSearch,dist,node_modules}"
excludeInFileChooser = "{$exclude,$excludeInFolderSearch}"

So what this does is add some more files to the tree that aren't visible by default (in include). What it also does is exclude both node_modules and dist (output of a static site generator).

Now, I have a question. What I am looking to do is to exclude node_modules but include node_modules/bootstrap-sass in my searches. Does anyone know how to do that?

tm_properties is whitespace sensitive, especially with excludeInFolderSearch.

Is there a key similar to windowTitle for tabs? e.g. tabTitle

(any idea what happened to textmate/textmate issue tracker?)

Thank you for providing information.It opens up my project with an "untitled" file open. Sometimes I just want the file browser there without an active, editable file (or rather, I've opened up a bunch of files, and I've CMD+W them all away). I have used in the In TextMate 1, the project window remained open with the project pane. In TextMate 2, once you close that last file, the file browser goes away with it.

Is there a setting to change this behavior? It's probably the last thing keeping me from using this over TM1.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment