Region Folding in Textmate
As a long time Microsoft developer who is in the progress of branching out and learning new things, I sometimes find it hard to give up certain features I’ve grown accustom to. When it comes to writing code, one feature of Visual Studio I have learned to rely on is folding sections of code using #region and #endregion. I find regions to be a great way to organize code around different subjects, activities, etc. For me it’s a way to reduce the visual clutter and immediately jump to the section of code I need to work on.
On the Mac, TextMate does a great job of code folding based on syntax. I’m doing a fair amount of work with Ruby these days and TextMate is an excellent tool. Unfortunately for me however all folding is based on the syntax of the code, and not extra non-code markers like #region. Luckily TextMate’s bundle system is completely extensible and customizable. Folding is based on regular expressions so with a fairly simple change I was able to get #region folding in TextMate.
The first step is to figure out the regular expression. The core regex for #region folding would be this:
^\s*\#region
^\s*\#endregion
Next open up TextMate’s Bundle editor, open the Ruby language, and locate the foldingStartMarker and foldingStopMarker sections. Below is the entire contents of my foldingStartMarker and foldingStopMarker sections.
foldingStartMarker = '(?x)^
(\s*+
(module|class|def
|unless|if
|case
|begin
|for|while|until
|( "(\\.|[^"])*+” # eat a double quoted string
| ”(\\.|[^''])*+” # eat a single quoted string
| [^#"''] # eat all but comments and strings
)*
( \s (do|begin|case)
| [-+=&|*/~%^<>~] \s*+ (if|unless)
)
)\b
(?! [^;]*+ ; .*? \bend\b )
|( “(\\.|[^"])*+” # eat a double quoted string
| ”(\\.|[^''])*+” # eat a single quoted string
| [^#"''] # eat all but comments and strings
)*
( \{ (?! [^}]*+ \} )
| \[ (?! [^\]]*+ \] )
)
).*$
| [#] .*? \(fold\) \s*+ $ # Sune’s special marker
| ^\s*\#region
‘;
foldingStopMarker = ‘(?x)
( (^|;) \s*+ end \s*+ ([#].*)? $
| ^ \s*+ [}\]] \s*+ ([#].*)? $
| [#] .*? \(end\) \s*+ $ # Sune’s special marker
| ^\s*\#endregion
)’;
You can see where my two regular expressions were added near the end of each section.
Once you do that, close the editor, reload your bundles, and you’re good to go.