<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>TextMate Blog</title>
	<atom:link href="http://blog.macromates.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.macromates.com</link>
	<description>TextMate and OS X</description>
	<lastBuildDate>Mon, 27 Feb 2012 06:43:04 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>Leopards and Questions</title>
		<link>http://blog.macromates.com/2012/leopards-and-questions/</link>
		<comments>http://blog.macromates.com/2012/leopards-and-questions/#comments</comments>
		<pubDate>Mon, 27 Feb 2012 06:09:17 +0000</pubDate>
		<dc:creator>Michael Sheets</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://blog.macromates.com/?p=304</guid>
		<description><![CDATA[Today we are pushing out a new nightly build for the 2.0 alpha that changes the minimum OS requirement to start requiring Snow Leopard, this change was made after checking the current statistics for 2.0: 10.8 2.0% 10.7 86.7% 10.6 11.1% 10.5 0.2% With such a small percentage on 10.5 it makes sense to drop [...]]]></description>
			<content:encoded><![CDATA[<p>Today we are pushing out a new nightly build for the 2.0 alpha that changes the minimum OS requirement to start requiring Snow Leopard, this change was made after checking the current statistics for 2.0:</p>

<p><strong>10.8</strong> 2.0%<br />
<strong>10.7</strong> 86.7%<br />
<strong>10.6</strong> 11.1%<br />
<strong>10.5</strong> 0.2%</p>

<p>With such a small percentage on 10.5 it makes sense to drop its support. Moving forward we may decide that requiring Lion will be a reasonable tradeoff as it provides many underlying benefits we could take advantage of. The usage statistics will be monitored to determine the feasibility of this move.</p>

<p>Also to help answer many of the more commonly asked questions we&#039;ve put together <a href="http://wiki.macromates.com/FAQ/TextMate2" title="FAQ / TextMate2">a FAQ about 2.0</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.macromates.com/2012/leopards-and-questions/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Clever Completion</title>
		<link>http://blog.macromates.com/2012/clever-completion/</link>
		<comments>http://blog.macromates.com/2012/clever-completion/#comments</comments>
		<pubDate>Wed, 18 Jan 2012 01:19:45 +0000</pubDate>
		<dc:creator>James Gray</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://blog.macromates.com/?p=296</guid>
		<description><![CDATA[TextMate has always had completion and, as I&#039;ve said before, it remains the best reason to wear out your <abbr title="Escape">⎋</abbr> (esc) key. The idea is simple and I bet you are already familiar with it, but, just to recap, if I had this Ruby code: class BoundingBox def initialize(min_x, min_y, max_x, max_y) @min_x = min_x [...]]]></description>
			<content:encoded><![CDATA[<p>TextMate has always had completion and, as I&#039;ve said before, it remains the best reason to wear out your <abbr title="Escape">⎋</abbr> (esc) key.  The idea is simple and I bet you are already familiar with it, but, just to recap, if I had this Ruby code:</p>

<pre><code>class BoundingBox
  def initialize(min_x, min_y, max_x, max_y)
    @min_x = min_x
    @min_y = min_y

    @max_x = max_x
    @max_y = max_y
  end
end
</code></pre>

<p>I could later use completion to finish off this line:</p>

<pre>class BoundingBox
  def max_x=(x)
    fail "max_x must be &gt; min_x" unless @m‸
    # ...
  end
end</pre>

<p>If I push <abbr title="Escape">⎋</abbr> where my caret currently is (shown with <code>‸</code> above), TextMate will complete the variable reference to <code>@max_y</code>.  It starts with <code>@max_y</code>, because that&#039;s the closest instance variable reference to my caret (from the bottom of <code>initialize()</code>), meaning it had a high chance to be what I was referring to.  It&#039;s not really what I wanted though, so another press of <abbr title="Escape">⎋</abbr> cycles me to the second choice of <code>@max_x</code>.  That is what I want, so I add &gt; and another <code>@m</code>.  Then I can complete until I get <code>@min_x</code> (four presses of <abbr title="Escape">⎋</abbr> or just one press of <abbr title="Shift-Escape">⇧⎋</abbr> to go backwards, since it&#039;s the furthest reference from my caret).</p>

<p>In this article will discuss:</p>

<ul>
<li>Reasons to use completion</li>
<li>Suffix completion</li>
<li>Prefix completion</li>
<li>Mid-word completion</li>
<li>Intelligent scoped completion</li>
</ul>

<p><span id="more-296"></span></p>

<h2>Already Better</h2>

<p>The previous example pretty much worked in TextMate 1 and it&#039;s definitely still around in TextMate 2.  I say &#034;pretty much&#034; because this example is already showing off how much smarter TextMate 2 is when it comes to completion.</p>

<p>You see, TextMate 1 had a pretty fixed idea of what a &#034;word&#034; really is and, since completion works on words, it wasn&#039;t super clever.  By default, it would have ignored the leading <code>@</code> that identifies an instance variable and just started completing <code>m</code> words.  That means the first sequence would have gone <code>min_x</code>, <code>must</code>, and then <code>max_x</code> (since those are the closest to my caret).  Because TextMate 2 did use the <code>@</code> it got to the right answer in one less step.  In bigger examples it could save even more cycling.  This actually turns out to be a big change with some pretty sweeping implications for TextMate 2 and we&#039;ll get to those, but first let&#039;s take a few detours…</p>

<h2>Why use completion?</h2>

<p>I bet some of you are wondering if completion is really worth an article all by itself.  Frankly, it is.</p>

<p>Programming is hard enough all on its own, so anything that can make it easier is a win.  The fact is that completion reduces errors.  You&#039;re just less likely to typo a variable or method name while using it.  Since TextMate is often used for dynamic languages, like Ruby which silently uses <code>nil</code> for newly referenced instance variables, this becomes doubly important.</p>

<p>Make friends with your <abbr title="Escape">⎋</abbr> key.</p>

<h2>TextMate 2 is Now on the Right Side</h2>

<p>Completion in TextMate 1 only used content to the left of the cursor.  In other words, it finished typing words.  TextMate 2, now uses the left and right sides.  What does that give us?  Well, prefix completion for one thing.</p>

<p>Say I&#039;m still finishing off that method we looked at earlier and I make a mistake entering it:</p>

<pre>class BoundingBox
  def max_x=(x)
    fail "max_x must be &gt; min_x" unless @max_x &gt; @min_x
    ‸x = x
  end
end</pre>

<p>I meant to type <code>@max_x = x</code> there, instead of <code>x = x</code>.  I run my tests, they catch the bug, I come back and notice the problem.  Prefix completion makes the fix trivial.  I click in front of the first <code>x</code> and push <abbr title="Escape">⎋</abbr> until it fixes the variable reference (two times for this case).</p>

<h2>Selecting What You Don&#039;t Want</h2>

<p>Technically, TextMate 2 uses the content to both the left and right of the caret for completion.  This means you can also do a mid-word completion.  I can type an <code>@m_x</code>, stick my caret between the <code>m</code> and the <code>_</code>, and push <abbr title="Escape">⎋</abbr> to rotate between <code>@max_x</code> and <code>@min_x</code> (with the order determined by what&#039;s closest to my caret).</p>

<p>I know what you&#039;re thinking though.  It&#039;s kind of a contrived example, right?  When are you going to use that?</p>

<p>Well, it turns out that TextMate 2 has another trick up its sleeve that just might change your mind.  I said that it uses what&#039;s to the left and right of the caret, but I left out a detail.  It also removes any selection.</p>

<p>Knowing that, let&#039;s say you used <code>@min_x</code> somewhere when you meant to use <code>@max_x</code>.  Again, your tests catch the bug.  Good thing you have those tests!  So you go to fix it.  One possible solution is that you click behind the <code>n</code>, press <abbr title="Shift-⇠">⇧⇠</abbr> twice to select <code>in</code>, and push <abbr title="Escape">⎋</abbr> to make the correction.  It&#039;s guaranteed to be just one press of the <abbr title="Escape">⎋</abbr> key this time too, because, even thought TextMate 2 removes the selection to make the completion, it does use it to filter out the choice you didn&#039;t want.  Thus <code>@max_x</code> will be the only matching variable in our code with <code>@min_x</code> ruled out.</p>

<p>Are you keyboard jockeys scoffing at my use of the word &#034;click&#034; above?  Alright, let&#039;s get fancy.  If your caret is just after a <code>@min_x</code> you wish to change to a <code>@max_x</code>, try this:  press <abbr title="Control-⇠">⌃⇠</abbr> to jump over a sub-word chunk (the <code>x</code> in this case), then <abbr title="Control-Shift-⇠">⌃⇧⇠</abbr> to jump over the next sub-word chunk (<code>min_</code>) while selecting it, and finish the maneuver off with an <abbr title="Escape">⎋</abbr> to make the correction.  (Note:  if the OS swallows those sub-word bindings for Mission Control or Spaces, just add an <abbr title="Option">⌥</abbr> (option) to them:  <abbr title="Control-Option-⇠">⌃⌥⇠</abbr> and <abbr title="Control-Option-Shift-⇠">⌃⌥⇧⇠</abbr>.)  The <code>m</code> and the <code>_</code> don&#039;t change the result, so that&#039;s a three-keystroke correction that&#039;s guaranteed to be exactly what you want.</p>

<h2>It&#039;s All About Character and Class</h2>

<p>Let&#039;s go back to that concept of a word that I talked about earlier.  I said all of this works because TextMate 2 has an improved idea of what is in a word.  In truth, TextMate 2 can assign named grouping to any set of characters.  As is usually the case, this concept of character groups is managed by scope, allowing TextMate 2 to adapt to multiple languages.</p>

<p>Ruby considers <code>@max_x</code> to be a set of <code>variable</code> characters (with the <code>@</code>) because the Ruby bundle scopes it as <code>variable.other.readwrite.instance.ruby</code>.  That scope is inside of the scope <code>source.ruby</code> so it inherits this magic setting from the Source bundle:</p>

<pre><code>{ characterClass = 'variable'; }
</code></pre>

<p>That setting is scoped to <code>variable</code>, so it affects everything under that distinction.  In plain English it says, inside of source code files, treat variables as a group of related characters.  A Ruby instance variable includes the leading <code>@</code>, so it&#039;s in the same group of characters as letters that follow it.  Global variables and their leading <code>$</code> (in Ruby) would be treated the same.</p>

<p>But the real question is, what else does TextMate 2 consider to be related in code files?  Several things, including my personal favorite:</p>

<pre><code>{ characterClass = 'escape'; }
</code></pre>

<p>That&#039;s scoped to <code>constant.character.escape</code>, which means that escape sequences are now self contained chunks of characters separate from the content around them.</p>

<p>What can we do with that?  Well, say we have this simple Ruby statement:</p>

<pre><code>lines = "‸Just\nTesting"
</code></pre>

<p>That string contains three words as far as TextMate 2 is concerned.  That&#039;s not just for completion either.  If I place the caret at the beginning of the string and use <abbr title="Option-Right">⌥→</abbr> to jump forward by words, I&#039;ll skip to the end of <code>Just</code>, <code>\n</code>, and then <code>Testing</code>.  Compare that to TextMate 1, which considered <code>Just</code> and <code>nTesting</code> to be words with a little punctuation (<code>\</code>) between them.</p>

<p>But this article isn&#039;t about movement, as cool as it is.  It&#039;s about completion.  So let&#039;s add a little more code:</p>

<pre><code>lines = "Just\nTesting"
if lines =~ /\bTe‸/
  # ...
end
</code></pre>

<p>If we push <abbr title="Escape">⎋</abbr> with our caret after the <code>Te</code>, TextMate 2 will complete <code>Testing</code> from the string above.  Notice how much context it&#039;s using to make this decision.  We&#039;re inside a Regular Expression here, so TextMate 2 knows the word boundary escape (<code>\b</code>) isn&#039;t part of the word to complete (<code>Te</code>).  It also looks for possible completions inside of that Ruby string, where it knows the newline escape (<code>\n</code>) isn&#039;t part of the matching completion (<code>Testing</code>).</p>

<h2>Augmented Completion</h2>

<p>If that&#039;s not enough for your completion needs, <a href="http://manual.macromates.com/en/working_with_text#completion">you can augment the command yourself</a>.  TextMate 2 also takes this option one step further by passing the entire document to completion commands on stdin.</p>

<p>That&#039;s some clever completion, if you ask me!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.macromates.com/2012/clever-completion/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Format Strings</title>
		<link>http://blog.macromates.com/2011/format-strings/</link>
		<comments>http://blog.macromates.com/2011/format-strings/#comments</comments>
		<pubDate>Fri, 30 Dec 2011 17:05:27 +0000</pubDate>
		<dc:creator>James Gray</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://blog.macromates.com/?p=291</guid>
		<description><![CDATA[TextMate 1 allowed you to use variable references in Snippets and even to supply defaults or simple replacements for them. TextMate 2 expands a lot on what you can do with variable references and where you can use them. In this article we will discuss: The syntax of TextMate 2&#039;s Format Strings Where you can [...]]]></description>
			<content:encoded><![CDATA[<p>TextMate 1 allowed you to use variable references in Snippets and even to supply defaults or simple replacements for them.  TextMate 2 expands a lot on what you can do with variable references and where you can use them.</p>

<p>In this article we will discuss:</p>

<ul>
<li>The syntax of TextMate 2&#039;s Format Strings</li>
<li>Where you can use them</li>
<li>The kinds of tricks these tools can help you accomplish</li>
</ul>

<p><span id="more-291"></span></p>

<h2>Titling Your Work</h2>

<p>We&#039;ve already discussed <a href="http://blog.macromates.com/2011/git-style-configuration/"><code>.tm_properties</code> files</a> and how you can use them to customize TextMate 2&#039;s behavior.  What I didn&#039;t tell you before though is that those settings are Format Strings.</p>

<p>One option you can customize is the title used for the editing window.  By default, the window title shows the name and extension of the file you are editing.  Let&#039;s use some Format String magic to fancy that up.</p>

<p><img src="http://blog.macromates.com/wp-content/uploads/2011/12/the_default_window_title.png" alt="The default window title" /></p>

<p>First, I can just add this option to the <code>.tm_properties</code> in my home directory to also show the directory of the file being edited:</p>

<pre><code>windowTitle = "$TM_DISPLAYNAME – $TM_DIRECTORY"
</code></pre>

<p><img src="http://blog.macromates.com/wp-content/uploads/2011/12/a_window_title_with_a_directory.png" alt="A window title with a directory" /></p>

<p>This is useful to me if I am editing in a project where it&#039;s common for files to have the same name, but be located in different places.  Rails applications are like that.</p>

<p>However, the full paths can get pretty long.  If you want something shorter, we can edit the variable as it is used with a Regular Expression:</p>

<pre><code>windowTitle = "$TM_DISPLAYNAME – ${TM_DIRECTORY/([^\/])[^\/]+\//$1…\//g}"
</code></pre>

<p>That expression is a little difficult to read because it&#039;s matching directory separators, which are the same characters TextMate uses to delimit a Regular Expression.  The first chunk between the non-escaped <code>/</code> characters (<code>([^\/])[^\/]+\/</code>) is the expression which searches for two or more character directories with a trailing <code>/</code>.  The replacement string (<code>$1…\/</code>), before the next unescaped <code>/</code>, just truncates the directory down to the first character, an ellipsis, and the trailing separator.  The final <code>g</code> after the last <code>/</code> turns on the <strong>g</strong>lobal option for the replacement, so we trim all the directories but the last (because it won&#039;t have a trailing <code>/</code> to match).</p>

<p><img src="http://blog.macromates.com/wp-content/uploads/2011/12/a_window_title_with_a_truncated_directory.png" alt="A window title with a truncated directory" /></p>

<h2>Obsessive Compulsive Window Titles</h2>

<p><em>Note: the following example is real world and may get pretty complex.  Lighter example follows.</em></p>

<p>I like the trimmed paths, but I&#039;ll be honest and tell you that&#039;s not my actual <code>windowTitle</code> setting.  Here&#039;s what I really use:</p>

<pre><code>windowTitle = "$TM_DISPLAYNAME${TM_DIRECTORY/\A(?:\/Users\/james\/Documents\/(?:work\/)?(?!\b(?:communication|programming|reference)\b)\w+\/?(.*)|(.+))\z/${2:? – ${2/\/Users\/james/~/}:${1/\A(?=.)/ – /}}/}"
</code></pre>

<p>This leads us to two of the great features of Format Strings in TextMate 2:  the replacement of a variable reference is a nested Format String and you can branch based on whether or not a variable is set.  This allows your to run replacements on a replacement and choose between multiple replacements.  Let me explain how I use those in the pattern above.</p>

<p>I keep my current project directories just inside of <code>~/Documents</code>.  I also move older projects into a <code>~/Documents/work</code> subdirectory.  I want to see paths inside of those project directories, but I don&#039;t need to be reminded that they are in <code>~/Documents</code> or <code>~/Documents/work</code>.  I also don&#039;t need to see the project directory itself, since I&#039;m seeing that in the File Browser.  Other non-project directories should be handled normally.  There are also a few directories inside <code>~/Documents</code> that aren&#039;t project directories and those should be treated like any other directory.</p>

<p>For example, here are some path transformations:</p>

<ul>
<li><code>~/Documents/tm2_documentation/</code> is stripped</li>
<li><code>~/Documents/tm2_documentation/calendar/</code> becomes <code>calendar</code></li>
<li><code>~/Documents/work/scout/</code> is stripped</li>
<li><code>~/Documents/reference/documentation/</code> is not changed</li>
</ul>

<p>Given that, I just do a search for a leading (<code>\A</code>) followed by either (<code>(?:…|…)</code>) hardcoded path (<code>\/Users\/james\/Documents\/</code>), the optional work directory (<code>(?:work\/)?</code>), followed by a project directory name that isn&#039;t one of the exceptions (<code>(?!\b(?:communication|programming|reference)\b)\w+\/?</code>), and anything that happens to be trailing that (<code>(.*)</code>) or any other directory listing (<code>(.+)</code>) anchored to the end of the path (<code>\z</code>).  That&#039;s the easy part, but the replacement is where we get tricky.</p>

<p>To understand the replacement, you have to understand the desired result.  If I have a file open from just inside the root project directory, I only need to see that file&#039;s name.  For example, <code>Gemfile</code>.  However, if I have a file open deeper in the project, I want to see the name and the path from the project&#039;s root directory.  An example of that would be <code>show.html.erb – app/views/users</code>.  The gotcha is the separator (<code>–</code>).  I don&#039;t want the separator if it isn&#039;t going to be followed by a directory.  Non-project directories can just show the full directory path, but it would be nice to at least shorten <code>/Users/james</code> to <code>~</code> for them.</p>

<p>To accomplish that, I first check to see if I&#039;m in a project path or a normal (<code>${2:?…:…}</code>).  When it&#039;s a normal path, <code>$2</code> will be set because that&#039;s the part of the expression that matched them.  If it is set, I prepend a separator and run a replacement to alias my home directory as discussed above (<code>– ${2/\/Users\/james/~/}</code>).  If this is a project path, I run another regex replacement on <code>$1</code>.  If the beginning of it (<code>\A</code>) is followed by an unmatched non-newline character (<code>(?=.)</code>), I replace that beginning (no content, just an anchor) with a <code>–</code> to get my separator.</p>

<p>While the above was all about aesthetics, there are other variables, like <code>TM_MAKE_TARGET</code>, that can likewise benefit from a path-derived value.  There&#039;s an example of how this can be used in the article on <a href="http://blog.macromates.com/2011/git-style-configuration/"><code>.tm_properties</code> files</a>.</p>

<h2>Replacing a Replacement</h2>

<p>While the previous example is just a scary showing of how far I will go to keep my windows looking pretty, the features used have a lot of powerful and practical applications.</p>

<p>Nesting Format Strings allows for pretty clever uses of the Find and Replace dialog.  Want to convert a single-quoted Ruby string literal into the double-quoted variety while adding the proper escaping?  Just Find for the regex <code>'(.*?)'</code> and replace with <code>"${1/"|#\{/\\$0/g}"</code>.  Try that out on this chunk of Ruby:</p>

<pre><code>'a "simple" string with no #{interpolation}'
</code></pre>

<p>and it will be replaced with:</p>

<pre><code>"a \"simple\" string with no \#{interpolation}"
</code></pre>

<p>This works because the second search hunts inside of the original string content (<code>$1</code>) for things that need escaping (<code>"</code> and/or <code>#{</code>) and prepends the escape (<code>\\</code>) to them.</p>

<h2>This or That</h2>

<p>The other feature I made use of earlier was if/else variable replacements.  Again, this is a handy transformation tool.</p>

<p>Let&#039;s say we have some CSV content:</p>

<pre><code>Product,Price
iPhone 4S,$199.00
MacBook Pro,"$1,199.00"
"Mac OS X ""Lion""",$29.99
</code></pre>

<p>We could convert that to tab-separated content and strip the extra quoting (we&#039;re confident there are no tabs in the fields) as we go, with just one Find and Replace operation.  The Regular Expression used in the Find is <code>\G(?:"((?:""|[^"]*)*)"|([^,]*))([,\n])</code> and the replacement is <code>${1:?${1/""/"/g}:$2}${3/,/\t/}</code>.</p>

<p>Let&#039;s talk through how that works, because it&#039;s pretty instructive.</p>

<p>The idea with the regex is that we need to walk through the data one field at a time.  We do that by saying:  pick up where the last match ended or at the beginning for the first match (<code>\G</code>) and look for either (<code>(?:…|…)</code>) a quoted field <code>"(…)"</code>, which is zero or more escaped quotes and/or runs of non-quote characters (<code>(?:""|[^"]*)*</code>), or an unquoted field (<code>([^,]*)</code>) delimited by a comma or a newline (<code>([,\n])</code>).  Each time that pattern matches either <code>$1</code> will be set with the contents of an quoted field or <code>$2</code> will be set with the contents of and unquoted field.  No matter what <code>$3</code> will be set with a comma or a newline.  That sets us up for the replacement work.</p>

<p>The replacement string has two branches.  If <code>$1</code> is set (<code>${1:?…:…}</code>), then use the quoted content, but unescape all quotes first (<code>${1/""/"/g}</code>).  Otherwise, use the unquoted content (<code>$2</code>).  Either way, add the separator at the end, but switch commas to tabs (<code>${3/,/\t/}</code>).</p>

<h2>Bundled Ifs</h2>

<p>The <code>${VARIABLE:?…:…}</code> form is useful when you need an if clause and an else clause.  If you only need the if you can use <code>${VARIABLE:+…}</code> and you can use <code>${VARIABLE:-…}</code> for else-only insertions.</p>

<p>A good example where this shortcut style is used involves setting a shell variable inside the Themes bundle:</p>

<pre><code>shellVariables = (
  { name = 'TM_THEME_PATH';
    value = '${TM_THEME_PATH:+$TM_THEME_PATH:}$TM_BUNDLE_SUPPORT/web-themes';
  },
);
</code></pre>

<p>This prepends an existing path, if it already exists before it is set here.  This allows one command, like Web Preview in the Support folder, to read an environment variable (<code>TM_THEME_PATH</code>) and learn about the paths of third party bundles.</p>

<p>Bundle <code>completionCommand</code> settings are also Format Strings.</p>

<h2>The Case for Replacements</h2>

<p>Another form of Format Strings allows you to change the case of a variable reference.  If you combine that with the fact that scope <code>name</code> elements in TextMate 2&#039;s Language Grammars are now Format Strings, this allows for nice dynamic scoping tricks.</p>

<p>For example, say we rework Ruby&#039;s &#034;here-document&#034; (heredoc) syntax rule to look something like this (simplified) example:</p>

<pre>begin = '&lt;&lt;-?(\w+)';
name  = 'string.unquoted.${1:/downcase}.ruby';
…</pre>

<p>That would mean that a heredoc definition like this:</p>

<pre>&lt;&lt;-CSS
body {
  margin: 10px auto;
}
CSS</pre>

<p>would be scoped as <code>meta.here-doc.css.ruby</code>.  This allows the injection of the CSS Grammar and automations into the scope <code>meta.here-doc.css</code>.  That would mean that you get the proper syntax highlighting of these heredocs and you could trigger CSS Bundle commands while editing them.</p>

<p>As I write this, the ruby grammar still has a dozen rules with a dozen different tokens that include a dozen different languages, so the above is a planned simplification that would allow us to avoid having to upgrade the ruby grammar for new potential here-doc tokens.</p>

<p>The supported case transformations are <code>/upcase</code>, <code>/downcase</code>, and <code>/capitalize</code>.  There&#039;s also a special <code>/asciify</code> transformation that will transliterate things like &quot;æ&quot; and &quot;ø&quot; into &quot;ae&quot; and &quot;o&quot; respectively as well as remove any remaining non-ASCII characters.  The latter is particularly useful when deriving an identifier or label, that needs to be accepted by a language parser, from a heading or comment, which is free-form prose.  These transformations can be combined.</p>

<h2>A Tiny Snip of Snippets</h2>

<p>Format Strings also have some Snippet-only enhancements, like the new pop-up choice syntax.  We&#039;ll cover those in an upcoming article on what&#039;s new with Snippets.</p>

<p>In the meantime though, I will give you one fix TextMate 2 has over its predecessor.  If you need to place a literal number right after a numeric variable reference you can now use this form:  <code>${1}337</code>.  That works in Snippets and anywhere else Format Strings are used:  <code>.tm_properties</code> files, Find replacements, Language Grammar <code>name</code> fields, and Bundle Settings.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.macromates.com/2011/format-strings/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>mate and rmate</title>
		<link>http://blog.macromates.com/2011/mate-and-rmate/</link>
		<comments>http://blog.macromates.com/2011/mate-and-rmate/#comments</comments>
		<pubDate>Fri, 23 Dec 2011 12:17:12 +0000</pubDate>
		<dc:creator>James Gray</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://blog.macromates.com/?p=278</guid>
		<description><![CDATA[TextMate is and will always be a modern GUI application. However, developers are often forced to walk in two worlds using both GUI and command-line tools. TextMate has always bridged the gap between these environments with its trusty command-line sidekick: mate. In TextMate 2, mate has learned some new tricks. A new partner-in-crime has also [...]]]></description>
			<content:encoded><![CDATA[<p>TextMate is and will always be a modern GUI application.  However, developers are often forced to walk in two worlds using both GUI and command-line tools.  TextMate has always bridged the gap between these environments with its trusty command-line sidekick:  <code>mate</code>.</p>

<p>In TextMate 2, <code>mate</code> has learned some new tricks.  A new partner-in-crime has also been introduced:  <code>rmate</code>.</p>

<p>In this article will discuss:</p>

<ul>
<li>How to install the upgraded <code>mate</code></li>
<li><code>mate</code>&#039;s new features</li>
<li>What <code>rmate</code> is</li>
<li>The different ways to use <code>rmate</code></li>
</ul>

<p><span id="more-278"></span></p>

<h2>Upgrade Time</h2>

<p>Once you have TextMate 2, you need to make sure you refresh the command-line <code>mate</code> application.  This allows you to take advantage of its new features.</p>

<p>The installer of this command-line utility has moved in TextMate 2.  You can now find it in the <em>TextMate</em> menu under <em>Preferences…</em> in the <em>Terminal</em> pane.</p>

<p><img src="http://blog.macromates.com/wp-content/uploads/2011/12/terminal_preferences.png" style="width: 100%" alt="Terminal Preferences"></p>

<p>To install or upgrade <code>mate</code>, just select a Location and hit Install.  You may be prompted to Replace an old version, if present.</p>

<p>This pane can later be used to uninstall the command if you need to do that.</p>

<p>Users usually install <code>mate</code> into <code>~/bin</code> if they just need it for the current user and <code>/usr/local/bin</code> if they would rather make it accessible to all users (assuming they have <code>/usr/local/bin</code> in their <code>PATH</code>).  If you would like to find where your TextMate 1 version is before you upgrade, feed your Terminal this command:  <code>which mate</code>.</p>

<h2>Your New mate</h2>

<p>Let&#039;s get to the good stuff.  What&#039;s upgraded in <code>mate</code>?</p>

<p>First, it&#039;s a small tweak, but you will be happy to hear that <code>mate</code> now works with <code>sudo</code>.  You can use this to edit restricted access files in TextMate 2 without being bothered by an authorization dialog on save:</p>

<pre><code>sudo mate /etc/hosts
</code></pre>

<p>Next, <code>mate</code> has picked up some new command-line options.  One is <code>-t</code>, which allows you to set the type of an opened file.  Personally, I like this feature for README files, which I prefer to write in Markdown.  Since the name of standard files like this don&#039;t always include an extension, we can just tell TextMate 2 how to handle the file as we open it:</p>

<pre><code>mate -t text.html.markdown README
</code></pre>

<p>Another new option is <code>--name</code>.  This allows you to set <code>TM_DISPLAYNAME</code> which is typically shown in the title bar on TextMate&#039;s windows.  For a good use of that, let me share a line from my Bash configuration:</p>

<pre><code>export GIT_EDITOR="mate --name 'Git Commit Message' -w -l 1"
</code></pre>

<p>The <code>-w</code> and <code>-l</code> options have been around for a while.  <code>-w</code> just tells TextMate to <strong>w</strong>ait for the edit to finish.  That&#039;s what allows you to use the command as an external editor for tools like Git that are waiting for an answer.</p>

<p><code>-l</code> just tells TextMate to place the caret on the indicated <strong>l</strong>ine.  I force the first line here because Git has a habit of reusing commit message files and TextMate would otherwise try restore the caret to it&#039;s last location.  Since that last location was probably at the end of a message that&#039;s changed or no longer present, the caret would likely be left in the middle of Git&#039;s comments.  That&#039;s not too helpful for a quick edit, so <code>-l 1</code> forces the caret back to the beginning.</p>

<p>That leads us, finally, to the new option used above.  Since Git will just use some file like <code>.git/COMMIT_EDITMSG</code>, our window isn&#039;t going to have the best title by default.  This use of <code>--name</code> clears that up by telling me exactly what I&#039;m looking at.</p>

<h2>Selection Strings</h2>

<p>I mentioned before that TextMate 1&#039;s version of <code>mate</code> supported <code>-l</code>.  That&#039;s true, but <code>-l</code> is far more powerful in TextMate 2 and that new power has spread to other commands.</p>

<p>With the old version of <code>mate</code>, <code>-l</code> was super simple.  It just took a number and it took you to that line.  Easy enough.</p>

<p>In the new version, it now takes a Selection String.  These are a new tool in TextMate 2 for describing selections.  Here&#039;s the formal grammar for a Selection String:</p>

<pre><code>selection    = «range» ('&amp;' «range»)*
range        = «pos» | «normal_range» | «column_range»
pos          = «line» (':' «column»)?
normal_range = «pos» '-' «pos»
column_range = «pos» 'x' «pos»
line         = [1-9][0-9]*
column       = [1-9][0-9]*
</code></pre>

<p>OK, geeky, but what does it really mean?  Let&#039;s look at some examples.</p>

<p>If I save the above grammar to a <code>selection_string_syntax.txt</code> file, I can open it with the following command:</p>

<pre><code>mate -l 3 selection_string_syntax.txt
</code></pre>

<p>That would drop my caret (shown as ‸) at the beginning of the third line:</p>

<pre><code>‸pos          = «line» (':' «column»)?
</code></pre>

<p>If I prefer though, I can control where it is in the line:</p>

<pre><code>mate -l 3:16 selection_string_syntax.txt
</code></pre>

<p>That would place my caret here:</p>

<pre><code>pos          = ‸«line» (':' «column»)?
</code></pre>

<p>Of course, we can also make a selection:</p>

<pre><code>mate -l 3:32-3:38 selection_string_syntax.txt
</code></pre>

<p>That selects (shown between ‸ marks):</p>

<pre><code>pos          = «line» (':' «‸column‸»)?
</code></pre>

<p>But wait, is this TextMate 2 or what?  We have <a href="http://blog.macromates.com/2011/multiple-carets/">Multiple Carets</a> now, dang it!  How do we use more than one at once?  Like this:</p>

<pre><code>mate -l '3&amp;6' selection_string_syntax.txt
</code></pre>

<p>That places two carets:</p>

<pre><code>selection    = «range» ('&amp;' «range»)*
range        = «pos» | «normal_range» | «column_range»
‸pos          = «line» (':' «column»)?
normal_range = «pos» '-' «pos»
column_range = «pos» 'x' «pos»
‸line         = [1-9][0-9]*
column       = [1-9][0-9]*
</code></pre>

<p>You can also make column selections:</p>

<pre><code>mate -l '4:7x5:13' selection_string_syntax.txt
</code></pre>

<p>That gives us:</p>

<pre><code>normal‸_range‸ = «pos» '-' «pos»
column‸_range‸ = «pos» 'x' «pos»
</code></pre>

<p>Or you can make several unlinked selections using all of the above features:</p>

<pre><code>mate -l '2:18-2:21&amp;3:1-3:4&amp;4:18x5:21&amp;4:30x5:33' selection_string_syntax.txt
</code></pre>

<p>Which selects all occurrences of <code>pos</code> for replacement:</p>

<pre><code>selection    = «range» ('&amp;' «range»)*
range        = «‸pos‸» | «normal_range» | «column_range»
‸pos‸          = «line» (':' «column»)?
normal_range = «‸pos‸» '-' «‸pos‸»
column_range = «‸pos‸» 'x' «‸pos‸»
line         = [1-9][0-9]*
column       = [1-9][0-9]*
</code></pre>

<p>You get the idea.</p>

<p>The best news about these new Selection Strings is that they aren&#039;t just for <code>mate</code>.  You can also use them in the <em>Go to Line</em> (<abbr title="Command-L">⌘L</abbr>) and <em>Go to File</em> (<abbr title="Command-T">⌘T</abbr>) dialogs.  For that latter, you just tack a colon (<code>:</code>) onto the end of the name matching string then follow it up with a Selection String.</p>

<p>This means that you could respond to a warning message like the following:</p>

<pre><code>main.cc:32: warning: no return statement.
</code></pre>

<p>by selecting <code>main.cc:32</code>, copying that to the Find clipboard with <abbr title="Command-E">⌘E</abbr>, opening TextMate 2, calling up the <em>Go to File</em> dialog with (<abbr title="Command-T">⌘T</abbr>), and pushing <abbr title="Return">↩</abbr> to go straight there.  As this shows, <em>Go to File</em> honors the Find clipboard when it matches this format, just to make things like this easier.</p>

<h2>Remote mate</h2>

<p>In the past, TextMate has suffered with editing files on a server, but that&#039;s all changed now.  If you regularly find yourself SSHed into a remote box and wanting to edit a file using TextMate on your own box, your ship has come in.</p>

<p>TextMate 2 now ships with an <code>rmate</code> (Ruby) script that you can drop onto servers.  When you trigger <code>rmate</code> on a remote box, it will connect back to your box, allow you to edit, and update the file on the server with the changes.</p>

<p>Let me show you how to get <code>rmate</code> installed on a server you want edit from remotely.</p>

<h3>Installing rmate</h3>

<p>First, we need to copy <code>rmate</code> up to your server.  You can find a link to the script in the <em>Preferences…</em> dialog of the <em>TextMate</em> menu, under the <em>Terminal</em> pane.  Click that link to open the script, then finish the install with these steps:</p>

<ol>
<li>Open a Terminal and type <code>scp</code> followed by a space</li>
<li>Drag the <code>rmate</code> icon out of the window title bar and drop it into your Terminal to fill in the path to the script</li>
<li>Add another space and then the server you wish to install the script on followed by a colon (<code>:</code>) and the path to install the script into</li>
</ol>

<p>Your final command should look something like:</p>

<pre><code>scp /Applications/TextMate.app/Contents/Frameworks/Preferences.framework/Versions/A/Resources/rmate example.com:/usr/local/bin
</code></pre>

<p>If you don&#039;t have SSH setup to automatically log you into the server, you may also need to provide the proper authentication options.  If your user doesn&#039;t have permission to copy directly into a the directory you want to install into, you may need to upload the script to your user&#039;s home directory, SSH into the remote, and move it into place using <code>sudo</code>.  Alternately, you could place it in <code>~/bin</code> and ensure that directory is in your path.</p>

<p>Back on your own machine, you need to make sure TextMate 2 is ready for the incoming connections.  Be sure Accept <code>rmate</code> connections is checked in the <em>Terminal</em> pane of <em>Preferences…</em> in the <em>TextMate</em> menu.  You can leave &#034;Access for&#034; on &#034;local clients&#034; though, because I&#039;ll show you a secure trick for bridging the two computers.</p>

<p><img src="http://blog.macromates.com/wp-content/uploads/2011/12/terminal_preferences.png" style="width: 100%" alt="Terminal Preferences"></p>

<h3>The Magic of SSH Tunnels</h3>

<p>With the install out of the way, you should be ready to use <code>rmate</code>.</p>

<p>To do it&#039;s job, <code>rmate</code> needs a connection back to your computer so that it can talk to TextMate 2.  There are multiple ways you can accomplish this, but probably the best way is to use a reverse SSH tunnel.  With the proper setup, you can forward the port <code>rmate</code> likes back to your local machine where TextMate 2 can answer the call-to-duty.</p>

<p>The easiest way to do this is to connect to your server using a command like:</p>

<pre><code>ssh -R 52698:127.0.0.1:52698 example.com
</code></pre>

<p>The <code>-R</code> option sets up a reverse tunnel.  The first <code>52698</code> names a port on the remote.  It will be connected to <code>127.0.0.1:52698</code> or the same port on the connecting box.  That port number is the default for TextMate 2 and <code>rmate</code>, so you should now be able to edit away.</p>

<p>To test things out, just try a command like:</p>

<pre><code>rmate test_file.txt
</code></pre>

<p>That should contact TextMate 2 on your local box.  Note that TextMate 2 does need to be running for this to work.</p>

<p>Type some content using any TextMate editing features you just can&#039;t live without and save the file.  Then check it on your server with:</p>

<pre><code>cat test_file.txt
</code></pre>

<p>You should see the content you typed on the server.  Magic!</p>

<p>If you try to edit a file you don&#039;t have permission to change on the server, <code>rmate</code> will refuse the edit and warn you:</p>

<pre><code>$ rmate /etc/crontab 
File /etc/crontab is not writable! Use -f/--force to open anyway.
</code></pre>

<p>You can either use the <code>-f</code> option to force the open in read-only mode or use <code>sudo</code> to get the needed permissions.  Remember that <code>rmate</code> is a Ruby script, so RVM users will probably need to use <code>rvmsudo</code> to keep the same Ruby selected:</p>

<pre><code>rvmsudo rmate /etc/crontab
</code></pre>

<p>After you verify that things are working, feel free to update your SSH setting to automatically setup the tunnel without you needing to supply the <code>-R</code> arguments all the time.</p>

<p>For a single server just add an entry like the following to your <code>~/.ssh/config</code>:</p>

<pre><code>Host example.com
RemoteForward 52698 127.0.0.1:52698
</code></pre>

<p>If you want to make those settings the default for all of your servers, use the wildcard host:</p>

<pre><code>Host *
RemoteForward 52698 127.0.0.1:52698
</code></pre>

<p>With settings like those in place, a bare <code>ssh</code> command (without <code>-R</code>) should still establish the tunnel for you and allow you to use <code>rmate</code>.</p>

<h3>Port Forwarding</h3>

<p>SSH tunneling is probably the lowest configuration option for using <code>rmate</code>.  It&#039;s also the safest since the computers chat over an encrypted connection.  Go that way if you can.</p>

<p>However, if you can&#039;t, you do have other options.  One reason you might need these is if you use multiple machines to connect to the same account on one remote.  They wouldn&#039;t all be able to use the same port.</p>

<p>Of course, you can specify different ports when you setup TextMate 2 and/or your SSH tunnel.  <code>rmate</code> also supports <code>--host</code> and <code>--port</code> options, so you can use those to customize the connection.</p>

<p>One thing you may desire in complex connection scenarios is for <code>rmate</code> to just connect back to where the connection came from.  You can have it determine the IP address the SSH connection came from using <code>--host auto</code>.</p>

<p>You will probably need to setup port forwarding of the desired port in your router&#039;s settings to use a connection like this.</p>

<p>The real trick with these connections though is that it&#039;s really the client that knows how things should best be handled.  Using another feature of SSH, we can have the client set some variables to the proper details and forward those settings to the remote so <code>rmate</code> can honor them.</p>

<p>A server whitelists the variables it will accept from connecting clients, so you&#039;ll need to edit <code>/etc/ssh/sshd_config</code>.  It probably already have these lines in it:</p>

<pre><code># Allow client to pass locale environment variables
AcceptEnv LANG LC_*
</code></pre>

<p>You need to add allowances for <code>RMATE_HOST</code> and <code>RMATE_PORT</code>, so change that second line to read:</p>

<pre><code>AcceptEnv LANG LC_* RMATE_*
</code></pre>

<p>You also need a similar entry in your local <code>~/.ssh/config</code>:</p>

<pre><code>Host example.com
SendEnv RMATE_*
</code></pre>

<p>Again, you can put that setting under the host wildcard if you prefer.</p>

<p>Then you can add lines like the following to your local <code>~/.bashrc</code>:</p>

<pre><code>export RMATE_HOST=auto
export RMATE_PORT=12345
</code></pre>

<p>Those settings would be forwarded up to the server when you connect and <code>rmate</code> would use them to connect back to your computer for edits.</p>

<p>Either way, it&#039;s a little work to get <code>rmate</code> setup, but it sure expands TextMate 2 reach once you do.  Welcome to remote editing with TextMate.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.macromates.com/2011/mate-and-rmate/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Multiple Carets</title>
		<link>http://blog.macromates.com/2011/multiple-carets/</link>
		<comments>http://blog.macromates.com/2011/multiple-carets/#comments</comments>
		<pubDate>Mon, 19 Dec 2011 06:54:16 +0000</pubDate>
		<dc:creator>James Gray</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://blog.macromates.com/2011/multiple-carets/</guid>
		<description><![CDATA[One of the features user have continually requested for TextMate is the ability to insert multiple carets. Allan, TextMate&#039;s developer, was always a little resistant to the idea because it seemed to require the use of a mouse and he&#039;s not a mouse guy. Well, he caved. You can now use a mouse to throw [...]]]></description>
			<content:encoded><![CDATA[<p>One of the features user have continually requested for TextMate is the ability to insert multiple carets.  Allan, TextMate&#039;s developer, was always a little resistant to the idea because it seemed to require the use of a mouse and he&#039;s not a mouse guy.  Well, he caved.  You can now use a mouse to throw down multiple carets and then edit away.</p>

<p>In this article will discuss:</p>

<ul>
<li>Using multiple carets with the mouse</li>
<li>Changes to column selection</li>
<li>Using multiple carets with Find</li>
<li>Using multiple carets with Copy and Paste</li>
</ul>

<p><span id="more-272"></span></p>

<h2>Using the Mouse</h2>

<p>Let&#039;s look at an example.  Pretend we&#039;re building some sort of IO filter.  It allows you to wrap a file or some other stream and read data from it, but that data is modified on the way in.  In Ruby, you might have some code like:</p>

<pre><code>class IOFilter
  # ...

  def gets(*args)
    filter(@io.gets(*args))
  rescue IOError =&amp;gt; error
    handle_error(error)
  end

  def read(*args)
    filter(@io.read(*args))
  rescue IOError =&amp;gt; error
    handle_error(error)
  end

  # ...
end
</code></pre>

<p>Rescuing <code>IOError</code> covers some of the things that could go wrong.  For example, if the <code>@io</code> object we&#039;re wrapping was opened for writing but not reading, an <code>IOError</code> will be tossed.  There are other errors that can be raised for read operations though.  For example, a socket might raise an <code>EOFError</code> when the input is exhausted.  Let&#039;s say we received a bug report and need to add some handling for that error as well.  Assuming our <code>handle_error()</code> method is up to the task, we just need to add the new error in two places.  Here&#039;s where we would like to have our carets (shown with ‸):</p>

<pre><code>class IOFilter
  # ...

  def gets(*args)
    filter(@io.gets(*args))
  rescue IOError‸ =&amp;gt; error
    handle_error(error)
  end

  def read(*args)
    filter(@io.read(*args))
  rescue IOError‸ =&amp;gt; error
    handle_error(error)
  end

  # ...
end
</code></pre>

<p>TextMate 2 makes it trivial to do just that.  Click in either location to move the caret there, then <abbr title="Command">⌘</abbr>-click in the second location to add another caret.  You are now editing in both locations, so all we have to do is type <code>, EOFError</code> to add it to both lines.</p>

<p>We asked for the feature and we got it!</p>

<h2>Is it Really About the Mouse?</h2>

<p>If you have read this far and you are like me, you should have one burning question:  what made Allan give in?  You might like answer:  he realized that this feature wasn&#039;t just about the mouse.  That means we got more than we bargained for with our request.</p>

<p>Some features in TextMate 2 have been rethought in terms of multiple carets and new features have been added with multiple carets in mind.  These combine to create a powerful system which gives you many different ways to edit in multiple places at once, without needing to learn a ton of new tricks.</p>

<h2>Jagged Columns</h2>

<p>If you used TextMate 1 for any amount time, odds are good that you saw column selection in action.  It was my weapon of choice when I wanted to show off some quick editing tricks.</p>

<p>TextMate 2 still has column selection, of course.  It&#039;s really just a use of multiple carets now though and that dramatically increases the ways in which we can use it.</p>

<p>For example, let&#039;s say we have some lines of data that vary in length:</p>

<pre><code>one
two
three
four
five
six
seven
eight
nine
ten
</code></pre>

<p>Now I can put my cursor at the front on all of those lines the same way I did in TextMate 1:  move the caret before the <code>o</code> in <code>one</code> (<abbr title="Command-Up">⌘↑</abbr> if it&#039;s at the beginning of your document), press <abbr title="Shift-Option-Down">⇧⌥↓</abbr> to drag a selection down in front of the <code>t</code> in <code>ten</code> (this is a column movement command), and tap <abbr title="Option">⌥</abbr> to switch to column selection mode.</p>

<p>In TextMate 1, that gave you a special case selection that would always stay lined up vertically.  But it TextMate 2, you can just think of it as ten different carets.  That means we now have this:</p>

<pre><code>‸one
‸two
‸three
‸four
‸five
‸six
‸seven
‸eight
‸nine
‸ten
</code></pre>

<p>But those carets may not stay in a perfect line if our editing actions require otherwise.  To show that, let&#039;s move to the end of those lines (<abbr title="Command-Right">⌘→</abbr>):</p>

<pre><code>one‸
two‸
three‸
four‸
five‸
six‸
seven‸
eight‸
nine‸
ten‸
</code></pre>

<p>It&#039;s worth noting that getting a caret at the end of a group of selected lines was a separate feature in TextMate 1 called Edit Each Line in Selection (<abbr title="Option-Command-A">⌥⌘A</abbr>).  I loved that feature, but didn&#039;t need it often enough to remember the keyboard shortcut for it.  I always went hunting through the menu.  However, now that it&#039;s just another use of multiple carets and I can get to it using commands I am intimately familiar with, like column selection and the movement keys, I think it will be a lot more natural to pick up.  For this reason, Edit Each Line in Selection was removed from TextMate 2.</p>

<p>Again, you can use most normal editing commands with multiple carets.  Insert some text, delete text, move around, etc.  If you use variable width commands like Select Word (<abbr title="Control-W">⌃W</abbr>), Select Enclosing Typing Pairs (<abbr title="Shift-Command-B">⇧⌘B</abbr>), Select Current Scope (<abbr title="Control-Option-B">⌃⌥B</abbr>), any movement keys, forward delete (<abbr title="Forward Delete">⌦</abbr>) or backward delete (<abbr title="Delete">⌫</abbr>), Find Next (<abbr title="Command-G">⌘G</abbr>), or even something like Toggle Case of Character (<abbr title="Control-G">⌃G</abbr>), your carets may end up in different positions on different lines.  That&#039;s why these commands can be so powerful when combined with multiple carets since they allow you to edit in terms of concepts like &#034;words&#034; or &#034;scopes&#034; which could mean something a little different for each caret.</p>

<h2>An Aside, Literally</h2>

<p>TextMate 1, had a special editing mode called Freehand Editing (<abbr title="Option-Command-E">⌥⌘E</abbr>).  It allowed you to place the caret beyond the boundaries of the data.  If you edited in these margins, the gaps were filled in with spaces.</p>

<p>In TextMate 2, you don&#039;t really need to activate this mode due to some simple enhancements to caret placement.  Column selection is immune to data boundaries, for example.</p>

<p>Thus, if I write the following Ruby method call, notice I forgot the commas after the arguments, and have my caret positioned as shown:</p>

<pre><code>method( arg_one
        arg_forty_two‸
        arg_three )
</code></pre>

<p>the fastest fix is <abbr title="Shift-Up">⇧↑</abbr> to create a selection, <abbr title="Option">⌥</abbr> to switch it into column mode, and type a <code>,</code> to enter it on both lines.  This works because the top caret is in Freehand Mode.  (Technically, this exact example also works in TextMate 1, but in TextMate 2 you can move the carets with the top one staying in Freehand Mode as needed.)</p>

<p>In TextMate 2, you can also make this correction using the mouse.  An <abbr title="Option">⌥</abbr>-click allows you to place a caret beyond data boundaries (in Freehand Mode).  That works for multiple carets too, so you could just make an <abbr title="Option-Command">⌥⌘</abbr>-click above your first caret in the example above and type the <code>,</code>.</p>

<h2>Finding More Carets</h2>

<p>There&#039;s another way to get multiple carets without ever leaving the keyboard and that&#039;s the new Find All feature.</p>

<p>If you need to do some tricky replacement, you can always bring up the Find dialog, craft a regular expression, and turn it loose on your data.  That works, but it may require a few tries and a little use of Undo to get exactly what you need.</p>

<p>Find All is the other option.  It&#039;s basically a live edit Find and Replace feature using the normal TextMate 2 editing tools.  Oh, and you can totally skip the dialog if you like.</p>

<p>Ready for an example?  What if we had some code doing logging in various places?</p>

<pre><code>logger.info "Starting work..."
#...
if very_bad_stuff?
  logger.error "Uh guys, we should NEVER be here!"
end
#...
logger.debug "The current_user is:  #{current_user.id}."
#...
logger.info "Done."
</code></pre>

<p>Now let&#039;s say there is a decision to start using a different <code>logger</code> API.  It doesn&#039;t have as rich of an interface, replacing methods like <code>info()</code>, <code>error()</code>, and <code>debug()</code> with just <code>log()</code>, but it is going to aggregate the messages from all of your servers onto a centralized box.  It was decided that the tradeoff is worth it.</p>

<p>You can change the needed method calls with these steps.  First, just select any occurrence of <code>logger</code> and push <abbr title="Command-E">⌘E</abbr> to put it on the Find clipboard.  Then trigger Find All (in Selection) with <abbr title="Option-Command-F">⌥⌘F</abbr> (it automatically works on the whole document if the current selection matches the clipboard).  That should highlight all <code>logger</code> references in the document.  Those selections are just multiple carets with some preselected content.  Tap → twice to move over to the method calls and you should see this:</p>

<pre><code>logger.‸info "Starting work..."
#...
if very_bad_stuff?
  logger.‸error "Uh guys, we should NEVER be here!"
end
#...
logger.‸debug "The current_user is:  #{current_user.id}."
#...
logger.‸info "Done."
</code></pre>

<p>From here the replacement is trivial.  Select the methods with <abbr title="Control-W">⌃W</abbr> and type <code>log</code> to replace them.  Job done:</p>

<pre><code>logger.log "Starting work..."
#...
if very_bad_stuff?
  logger.log "Uh guys, we should NEVER be here!"
end
#...
logger.log "The current_user is:  #{current_user.id}."
#...
logger.log "Done."
</code></pre>

<p>As I showed, Find All will match whatever is inside of a selection when you have one.  If you don&#039;t though, it defaults to the entire document.</p>

<h2>Copy and Paste Meets Multiple Carets</h2>

<p>One question that&#039;s bound to arise is, can I Copy and Paste with multiple carets?  Sure you can.</p>

<p>Let&#039;s go back to our list of numbers as an example.  We will start with a many-to-many example.  Say we want to break this list into two columns:</p>

<pre><code>one
two
three
four
five
six
seven
eight
nine
ten
</code></pre>

<p>Do some <abbr title="Command">⌘</abbr>-clicking to get a caret on every other line:</p>

<pre><code>one
‸two
three
‸four
five
‸six
seven
‸eight
nine
‸ten
</code></pre>

<p>With that done, press <abbr title="Control-W">⌃W</abbr> to grab the words, <abbr title="Command-X">⌘X</abbr> for Cut, and <abbr title="Delete">⌫</abbr> to remove the extra lines.  That leaves us with:</p>

<pre><code>one‸
three‸
five‸
seven‸
nine‸
</code></pre>

<p>If we don&#039;t need even columns, we can just add a space and Paste (<abbr title="Command-V">⌘V</abbr>) right now.</p>

<p>For even columns, just <abbr title="Option">⌥</abbr>-click a space or two after the three or seven.  Then use that caret to line up four <abbr title="Option-Command">⌥⌘</abbr>-clicks.  You should end up with:</p>

<pre><code>one    ‸
three  ‸
five   ‸
seven  ‸
nine   ‸
</code></pre>

<p>A simple Paste (<abbr title="Command-V">⌘V</abbr>) finishes the job:</p>

<pre><code>one    two
three  four
five   six
seven  eight
nine   ten
</code></pre>

<p>The one-to-many case works as well, by just repeating the content.  Let&#039;s say we have some metric data:</p>

<pre><code>12
 5
27
 2
--
46 "bugs"
</code></pre>

<p>but perhaps your pointy haired boss would prefer to see the word <code>bugs</code> on every line.  Just double-click the word <code>bugs</code> and Copy (<abbr title="Command-C">⌘C</abbr>) it.  Press ↑ twice to end up behind the 2, then <abbr title="Shift-Up">⇧↑</abbr> three times to drag a selection behind the numbers, and <abbr title="Option">⌥</abbr> to switch into column mode.  Type a space and Paste (<abbr title="Command-V">⌘V</abbr>).  This pastes four copies of the clipboard contents, leaving you with:</p>

<pre><code>12 bugs‸
 5 bugs‸
27 bugs‸
 2 bugs‸
--
46 "bugs"
</code></pre>

<p>Notice that we get to keep our multiple carets with each one placed after the pasted text.  That&#039;s good, because I forgot to grab the quotes.  We can add them with <abbr title="Control-W">⌃W</abbr> to select the words and typing a single quote.</p>

<p>Finally, the many-to-one case collapses data as you would expect.  So if we had Ruby data like:</p>

<pre><code>name = { first: "James",
         middle: "Edward",
         last: "Gray",
         # leave the following out of dumb web forms
         suffix: "II" }
</code></pre>

<p>and we want to collapse that into one string, we could select the first colon, add it to the Find clipboard with <abbr title="Command-E">⌘E</abbr>, switch the selection to the entire hash with <abbr title="Shift-Command-B">⇧⌘B</abbr>, Find All with <abbr title="Option-Command-F">⌥⌘F</abbr>, then press → three times to move to the names.  Now we have:</p>

<pre><code>name = { first: "‸James",
         middle: "‸Edward",
         last: "‸Gray",
         # leave the following out of dumb web forms
         suffix: "‸II" }
</code></pre>

<p>From there select the names with <abbr title="Control-W">⌃W</abbr>, Copy (<abbr title="Command-C">⌘C</abbr>) them, switch the selection back to the hash with <abbr title="Shift-Command-B">⇧⌘B</abbr>, and replace it with the names using <abbr title="Command-V">⌘V</abbr>.  That gives us:</p>

<pre><code>name = James‸Edward‸Gray‸II‸
</code></pre>

<p>We can finish off the string by typing a space to add it after each word, pressing <abbr title="Command-Right">⌘→</abbr> to merge down to one caret at the end of the line, removing the extra space with <abbr title="Delete">⌫</abbr>, selecting the names by pushing <abbr title="Shift-Option-Left">⇧⌥←</abbr> four times, and typing a quote to enclose the string.  That leaves:</p>

<pre><code>name = "James Edward Gray II"
</code></pre>

<p>As you can see, all of these multiple caret features combine to create a powerful suite of editing tools.  Thanks Allan, for knowing what we wanted more than we did.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.macromates.com/2011/multiple-carets/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Whitespace Bundle</title>
		<link>http://blog.macromates.com/2011/whitespace-bundle/</link>
		<comments>http://blog.macromates.com/2011/whitespace-bundle/#comments</comments>
		<pubDate>Sun, 18 Dec 2011 11:29:17 +0000</pubDate>
		<dc:creator>Michael Sheets</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://blog.macromates.com/2011/whitespace-bundle/</guid>
		<description><![CDATA[Mads Hartmann Jensen has written a bundle which takes advantage of a new injection feature of language grammars to highlight what can be considered improper whitespace. Highlighting both trailing whitespace and mixed tab/space indentation it can also be limited to just one or the other. (This bundle will only work with the 2.0 alpha.)]]></description>
			<content:encoded><![CDATA[<p>Mads Hartmann Jensen has <a href="http://mads379.github.com/posts/whitespace-tmbundle">written a bundle</a> which takes advantage of a new injection feature of language grammars to highlight what can be considered improper whitespace. Highlighting both trailing whitespace and mixed tab/space indentation it can also be limited to just one or the other.</p>

<p>(This bundle will only work with the 2.0 alpha.)</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.macromates.com/2011/whitespace-bundle/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Git Style Configuration</title>
		<link>http://blog.macromates.com/2011/git-style-configuration/</link>
		<comments>http://blog.macromates.com/2011/git-style-configuration/#comments</comments>
		<pubDate>Fri, 16 Dec 2011 20:44:43 +0000</pubDate>
		<dc:creator>James Gray</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://blog.macromates.com/2011/git-style-configuration/</guid>
		<description><![CDATA[TextMate 2 isn&#039;t just about adding a ton of killer new features. It&#039;s also about throwing out what just plain didn&#039;t work. That means you can kiss the old project files goodbye. Of course, you throw out bad ideas so you can replace them with good ideas. Project files serve a couple of purposes in [...]]]></description>
			<content:encoded><![CDATA[<p>TextMate 2 isn&#039;t just about adding a ton of killer new features.  It&#039;s also about throwing out what just plain didn&#039;t work.  That means you can kiss the old project files goodbye.</p>

<p>Of course, you throw out bad ideas so you can replace them with good ideas.</p>

<p>Project files serve a couple of purposes in TextMate 1.  One was to give you access to folders you commonly work with.  That&#039;s now handled through TextMate 2&#039;s File Browser and we&#039;re going to talk a lot more about that in the future.  Another purpose though was to support project level configuration.  Configuration is a great idea, but the old interface was awkward and inflexible.</p>

<p>TextMate 2&#039;s new <code>.tm_properties</code> files address this need, similar to <code>.git</code> configuration files.</p>

<p>In this article we&#039;ll discuss:</p>

<ul>
<li>The various places TextMate 2 will look for configuration settings</li>
<li>Examples of some settings you may wish to tweak</li>
<li>Per file type configuration</li>
<li>Dynamic project based configuration</li>
</ul>

<p><span id="more-262"></span></p>

<h2>Project Settings</h2>

<p>Enough about the why, let&#039;s get to the how.</p>

<p>To start configuring project level options in TextMate 2, just dump a <code>.tm_properties</code> file in the root directory of the project and type your settings right in there.  If you already have the project open in TextMate 2, the easiest way to get to this file is to just select <em>Preferences…</em> from the File Browser&#039;s action menu.</p>

<p><img src="http://blog.macromates.com/wp-content/uploads/2011/12/preferences.png" alt="Selecting Preferences in the File Browser" /></p>

<p>By way of example, let&#039;s say you have a project of documentation files.  You could dump the following settings into a <code>.tm_properties</code> file at the root of that project:</p>

<pre><code>TM_GIT = "/usr/local/bin/git"

fontName = "DejaVu Sans Mono"
fontSize = 14

[ "*.{txt,md,mdown,markdown}" ]
softWrap = true
</code></pre>

<p>The above shows the three kinds of things you can configure.  First, you can set TextMate variables, as I did with <code>TM_GIT</code>.  The <em>Git</em> bundle helps me manage my commits while staying inside TextMate, but it needs to know where the <code>git</code> executable is installed to do that.  It assumes a <a href="http://www.macports.org/">MacPorts</a> install location by default, so I just redirected it to my <a href="http://mxcl.github.com/homebrew/">Homebrew</a> install here.</p>

<p>The second section shows how to set TextMate settings.  Here I&#039;ve entered the <code>fontName</code> and <code>fontSize</code> I prefer to work with.</p>

<p>The third section also configures a setting, but it shows how you can restrict settings to certain file types.  In this case I&#039;ve used a shell glob to specify that this setting be applied to files with a plain text or Markdown extension.  I want to wrap those files, but not any other code files that may be in the project.</p>

<p>TextMate 2 will apply these setting when working with any file under the project folder.  Different projects can have different settings per your tastes.</p>

<h2>From Folders to Global Defaults</h2>

<p>Now, as you probably already figured out, these files don&#039;t have to be project wide settings.  It&#039;s just a file in a folder as far as TextMate 2 is concerned and it will always affect every file below it.  Given that, you can adjust the settings for just part of a project, by adding a <code>.tm_properties</code> file to that folder.  You might apply some settings to the project as a whole, but then override them for the <code>doc</code> folder, for example.</p>

<p>This works because TextMate 2 walks up the current file path, looking for <code>.tm_properties</code> files.  All of those settings apply, with lower files overriding higher files as needed.</p>

<p>The search stops with the current user&#039;s home directory (<code>~</code>) or the root directory (<code>/</code>).  However, if the root directory is reached, the current user&#039;s home directory is added to the search above it.  This makes it possible to create a <code>~/.tm_properties</code> with global default settings that always apply, even if you edit files outside of your home directory.</p>

<h2>Smart Settings</h2>

<p>You can accomplish some pretty cool voodoo by playing with these configuration files.  For example, here&#039;s some of the project settings used to build TextMate 2:</p>

<pre><code>TM_MAKE_FILE = '${CWD}/Makefile'

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

<p>The first thing you should notice here is that we are allowed to use TextMate variables, as well as set them.  This allows us to configure the project&#039;s Makefile using <code>$CWD</code> (for current working directory).  This works because the <code>.tm_properties</code> file is in the root directory of the project and that will be the value of <code>$CWD</code>.</p>

<p>The Make target for the TextMate 2 project is set elsewhere (not shown), but we see another use of variables to override it for the tests on the last line here.  Note that it&#039;s possible to use regex replacements on these variables, just as we could in a snippet.</p>

<p>Finally, the powerful <code>scopeAttributes</code> setting is used here to add a scope to all content in the testing files.  This is also helpful for the activation of special snippets when working in these files.</p>

<p>As you can see, it&#039;s possible to show TextMate 2 how you want to work with each of your projects.  You could even set which language files should be spellchecked in, on a folder by folder and/or file type basis.</p>

<h2>The Settings</h2>

<p>A <a href="http://wiki.macromates.com/Reference/Settings">list of the available settings</a> is available as well as a <a href="http://wiki.macromates.com/Reference/FolderSpecificSettings">guide with more information</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.macromates.com/2011/git-style-configuration/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>TextMate 2 Tips</title>
		<link>http://blog.macromates.com/2011/textmate-2-tips/</link>
		<comments>http://blog.macromates.com/2011/textmate-2-tips/#comments</comments>
		<pubDate>Fri, 16 Dec 2011 20:02:06 +0000</pubDate>
		<dc:creator>Michael Sheets</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://blog.macromates.com/2011/textmate-2-tips/</guid>
		<description><![CDATA[A great site has sprung up to provide a lot of helpful tips and tricks about the TextMate 2 alpha release. You can also follow them on Twitter for updates.]]></description>
			<content:encoded><![CDATA[<p>A great site has sprung up to provide a lot of <a href="http://tm2tips.tumblr.com/" title="Textmate 2 Tips">helpful tips and tricks</a> about the TextMate 2 alpha release. You can also <a href="http://twitter.com/TM2Tips">follow them on Twitter</a> for updates.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.macromates.com/2011/textmate-2-tips/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Locating Bundles</title>
		<link>http://blog.macromates.com/2011/locating-bundles/</link>
		<comments>http://blog.macromates.com/2011/locating-bundles/#comments</comments>
		<pubDate>Thu, 15 Dec 2011 07:39:41 +0000</pubDate>
		<dc:creator>Michael Sheets</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://blog.macromates.com/2011/locating-bundles/</guid>
		<description><![CDATA[One of the new features in 2.0 is the ability to install new bundles directly from the app. You can see the list of available bundles by opening preferences and going to the Bundles tab. Bundles installed from here will be kept up-to-date automatically. In addition if you try to open a filetype without having [...]]]></description>
			<content:encoded><![CDATA[<p>One of the new features in 2.0 is the ability to install new bundles directly from the app. You can see the list of available bundles by opening preferences and going to the Bundles tab. Bundles installed from here will be kept up-to-date automatically. In addition if you try to open a filetype without having the currect bundle TextMate will offer to install it if available.</p>

<p>Also listed are a variety of theme bundles, you can filter list by clicking &#039;Themes&#039; in the top bar. The Themes bundle is installed by default and includes a collection of themes from 1.x.</p>

<p>For the duration of the alpha we have kept the support files separated so both versions can be run without affecting the other. This means you will have to manually move over your personal bundles and any bundles not available in the installer.</p>

<p><span id="more-243"></span></p>

<h2>Installing a Bundle</h2>

<p>You can install a bundle by placing it in this directory:</p>

<pre><code>~/Library/Application Support/Avian/Pristine Copy/Bundles/
</code></pre>

<p>When placed here TextMate will write any changes made in the bundle editor to a &#039;delta&#039; bundle allowing you to update this copy without removing your customizations.</p>

<p>If this is your own bundle or you want to submit changes back to the bundle you should instead use:</p>

<pre><code>~/Library/Application Support/Avian/Bundles/
</code></pre>

<p><strong>Note:</strong></p>

<ul>
<li>The <code>~</code> character in these paths refers to your home directory (<code>/Users/«yourname»/</code>).</li>
<li>The <code>Library</code> folder under Lion is hidden by default, you can access it from the Go menu in Finder while holding down option.</li>
<li>The directories under <code>Application Support</code> may not exist on your system, should they not you should create them.</li>
</ul>

<h2>Converting a Theme</h2>

<p>If you have a theme from 1.x you will need to move it into a bundle before using it with 2.0.</p>

<ol>
<li>Select <code>Edit Bundles…</code> from the Bundles menu and create a new bundle with <abbr title="Command-N">⌘N</abbr></li>
<li>Edit the bundle info in the drawer and add a description of the theme in the main text area.</li>
<li><p>Save your changes with <abbr title="Command-S">⌘S</abbr> and then in Finder go to:</p>

<pre><code>~/Library/Application Support/Avian/Bundles/
</code></pre>

<p>Right-click on the bundle and choose <code>Show Package Contents</code>.</p></li>
<li>Add a new folder named <code>Themes</code> and put the theme(s) inside it.</li>
<li>TextMate will automatically see your changes and the theme will be available under View → Theme.</li>
</ol>

<h3>Other Bundle Notes</h3>

<ul>
<li>Duplicate bundles installed at a higher level now completely eclipse the other bundle rather than being merged as in 1.x.</li>
<li>If you have a problem with a bundle please submit an issue at the appropriate bundle under the <a href="https://github.com/textmate/">textmate user on Github</a>.</li>
<li>If you would like to submit a change to a bundle most are available under the <a href="https://github.com/avian/">avian user on Github</a>. You can fork the bundle and then send us a pull request.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.macromates.com/2011/locating-bundles/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Alpha Tidbits</title>
		<link>http://blog.macromates.com/2011/alpha-tidbits/</link>
		<comments>http://blog.macromates.com/2011/alpha-tidbits/#comments</comments>
		<pubDate>Wed, 14 Dec 2011 14:11:04 +0000</pubDate>
		<dc:creator>Michael Sheets</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://blog.macromates.com/2011/alpha-tidbits/</guid>
		<description><![CDATA[To create a new file you can use the shortcut <abbr title="Option-Command-N">⌥⌘N</abbr> to create a new tab, when you save this tab it will default to the current or selected directory in the sidebar. Update: When providing the file name (in the save dialog) you can use brace expansion to create multiple files, e.g.: MyView.{mm,h}. The [...]]]></description>
			<content:encoded><![CDATA[<ul>
<li>To create a new file you can use the shortcut <abbr title="Option-Command-N">⌥⌘N</abbr> to create a new tab, when you save this tab it will default to the current or selected directory in the sidebar. <strong>Update:</strong> When providing the file name (in the save dialog) you can use brace expansion to create multiple files, e.g.: <code>MyView.{mm,h}</code>.</li>
<li>The current release will submit non-anonymous crash reports so we can pinpoint problem areas in the alpha. This can be disabled in preferences if needed but it is a great help if you can leave it on.</li>
</ul>

<h3>Around the Web</h3>

<ul>
<li>Ernie Miller give a good overview of <a href="http://erniemiller.org/2011/12/12/textmate-2-rmate-awesome/" title="TextMate 2 + rmate = Awesome  &#8211;  Ernie Miller">how to use rmate</a> to edit files on a remote server.</li>
<li>David Lanham shows a detailed shot of the <a href="http://dribbble.com/shots/351365-Textmate-2" title="Dribbble - Textmate 2 by David Lanham">new icon</a> he designed for us. <strong>Update:</strong> David has <a href="http://dribbble.com/shots/351365-Textmate-2?page=2" title="Dribbble - Textmate 2 by David Lanham">posted a comment</a> about the process of coming up with the icon.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.macromates.com/2011/alpha-tidbits/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

