File Type Detection (RSpec & Rails)
To enable the functionality offered for a given file type, it is important that TextMate actually detects it.
In this post I will go through the 3 steps used to detect your file’s type and then answer the question of how to make TextMate automatically recognize rspec
files (for those who have bound .rb
to Ruby on Rails).
Finding the File Type
TextMate will go through 3 steps to figure out the type of your document, the first step that produce a result, will be used:
-
Check if you have a manual binding to the current file’s extension. Each time you use the language pop-up in the status bar to change the type of the current file, you make a manual binding. For example if you open
test.h
and change the language from C to Objective-C++ then you manually bind all.h
files to be of type Objective-C++. You can inspect your manual bindings by running the following line from Terminal:defaults read com.macromates.textmate OakLanguageFileBindings
For me that reveals my manual binding for
.h
files in the form of:{ fileTypes = ( h ); language = "FDAB1813-6B1C-11D9-BCAC-000D93589AF6"; name = "Objective-C++"; },
If you wish to get rid of all your manual bindings you can run the following line (while TextMate is not running):
defaults delete com.macromates.textmate OakLanguageFileBindings
-
Check if the first line of the file you open matches any of the first line patterns in the various language grammars.
For example if you select Bundles → Bundle Editor → Edit Languages… and locate the Ruby language grammar you will find that it has the following line:
firstLineMatch = '^#!/.*\bruby\b';
This is so that files starting e.g. with the following, will be recognized as Ruby files (despite extension):
#!/usr/bin/env ruby -wKU
-
Path (suffix) comparison. The last check, but most commonly used, is to compare the file types specified for each grammar, against the suffix of the file you open. Again if you open the Ruby grammar you will find this line in its language grammar:
fileTypes = ( rb, rbx, rjs, Rakefile, rake, cgi, fcgi, gemspec, irbrc, capfile );
So if you open
test.rb
it will see therb
extension and pick Ruby as the language grammar. This extension match is actually a broader suffix match, but it needs to be anchored either at a period, slash (path separator) or underscore. So this means that you can, as file type, give.ssh/config
orspec.rb
.
Changing the Defaults
Generally the way to change the default binding is to use the language pop-up in the status bar.
E.g. if you open test.rb
and the status bar shows Ruby, but you are working with Ruby on Rails, then you should select Ruby on Rails from the status bar to associate all .rb
files to Ruby on Rails. Presently there is no way to make the binding only for Rails projects, but as the Ruby on Rails grammar is a superset of the Ruby grammar, it shouldn’t be that big a problem.
Recently though, RSpec files have entered the scene, and these also use an .rb
extension. Though the entire name will have a _spec.rb
suffix, and the RSpec grammar does match that, so out-of-the-box if you open test_spec.rb
(and have the Ruby RSpec bundle installed) then you will see RSpec in the status bar.
The problem appears if you have manually bound .rb
to something, as we just did above in the example. Then when you open test_spec.rb
TextMate will treat the file according to your manual binding (which says it has an .rb
extension, and thus is Ruby on Rails).
So the trick to overcome this problem is to not do a manual binding for .rb
files (if you want _spec.rb
files identified as RSpec).
If you already did such manual binding you should be able to either:
-
Delete all your manual bindings with:
defaults delete com.macromates.textmate OakLanguageFileBindings
-
Open
/tmp/test.rb
and switch language back to Ruby. Since your manual binding is now the same as what TextMate would do by default, it records no binding at all. You can inspect the manual bindings recorded as shown at the start of this post.
When you have cleared the manual binding, then pick Bundles → Bundle Editor → Edit Languages… and add rb
to the Ruby on Rails grammar’s fileTypes
array so that it reads:
fileTypes = ( 'rxml', 'rb' );
Additionally remove rb
from the Ruby grammar’s fileTypes
array, so that there is no ambigiouty about which language owns the rb
extension.
After doing these two steps, try test the bindings by looking in the status bar of the document which opens when you run these two commands from the Terminal:
mate /tmp/test_spec.rb
mate /tmp/test.rb