tag:www.rhnh.net,2008:/vim Vim - Xavier Shay's Blog 2011-08-20T22:35:06Z Enki Xavier Shay notreal@rhnh.net tag:www.rhnh.net,2008:Post/854 2011-08-20T10:35:00Z 2011-08-20T22:35:06Z Vim and tmux on OSX <p>I recently switched from MacVim to vim inside tmux, using iTerm in full screen mode (<code>Command+Enter</code>). It&#8217;s pretty rad. I tried screen first, but even after a lot of screwing around there was still a lot of brokeness, and I don&#8217;t like how it does split panes anyways. Follows are some notes about what is required for tmux.</p> <h3>Get the latest vim and tmux</h3> <p>Latest vim required for proper clipboard sharing, if you don&#8217;t want to install it you can use the <code>pbcopy</code> plugin mentioned below. A formula won&#8217;t ever be in the main homebrew repository because they have a policy of not including packages already provided by the system, but homebrew-alt is pretty legit.</p><table class="CodeRay"><tr> <td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"><pre>1<tt> </tt>2<tt> </tt></pre></td> <td class="code"><pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }">brew install --HEAD https://raw.github.com/adamv/homebrew-alt/master/duplicates/vim.rb<tt> </tt>brew install tmux<tt> </tt></pre></td> </tr></table> <h3>Set up pretty colors</h3> <p><a href="https://img.skitch.com/20110821-gfp7b3g8xrk25bfdxgrxdnghnr.jpg"><img src="https://img.skitch.com/20110821-gfp7b3g8xrk25bfdxgrxdnghnr.jpg" width='640' alt='my vim/tmux setup' /></a></p> <p>I use the <a href="http://ethanschoonover.com/solarized">solarized</a> color scheme. To make this work, ensure you are not overriding the <code>TERM</code> variable in your <code>.{bash|zsh}rc</code>, then create an alias for tmux:</p><table class="CodeRay"><tr> <td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"><pre>1<tt> </tt>2<tt> </tt></pre></td> <td class="code"><pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"># .zshrc<tt> </tt>alias tmux=&quot;TERM=screen-256color-bce tmux&quot;<tt> </tt></pre></td> </tr></table> <p>I also have a tmux config:</p><table class="CodeRay"><tr> <td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"><pre>1<tt> </tt>2<tt> </tt></pre></td> <td class="code"><pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"># .tmux.conf<tt> </tt>set -g default-terminal &quot;screen-256color&quot;<tt> </tt></pre></td> </tr></table> <h3>Clipboard sharing</h3> <p>Up until I wrote this blog post, I had been using the <a href="https://github.com/mortice/pbcopy.vim">pbcopy plugin</a> to share clipboard using a cute hack involving ssh&#8217;ing back into your machine to run <code>pbcopy</code>/<code>pbpaste</code>. In researching some more details on this though I found an <strong>excellent</strong> write up of the problem and a <a href="https://github.com/ChrisJohnsen/tmux-MacOSX-pasteboard">far better solution by Chris Johnsen</a> that enables proper sharing without ssh&#8217;ing, and therefore also the <code>*</code> register (use <code>"*y</code> to copy, <code>"*p</code> to paste &#8211; note this does <strong>not</strong> work with the vim that ships with <span class="caps">OSX</span>).</p> <h3>Mouse integration</h3> <p>The mouse is good for two things: scrolling, and selecting text from your scrollback.</p> <p>For the first, put the following config:</p><table class="CodeRay"><tr> <td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"><pre>1<tt> </tt>2<tt> </tt></pre></td> <td class="code"><pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"># ~/.tmux.conf<tt> </tt>set -g mode-mouse on<tt> </tt></pre></td> </tr></table> <p>For the second, hold the option key while you select.</p> <h3>Workflow</h3> <p>Find another reference for basic keys, this here are notes on top of that. <code>Ctrl-B</code> sucks as an escape sequence, rebind it to <code>Ctrl-A</code> to match screen. Most online references don&#8217;t mention it, but the default binding for horizontal split is <code>prefix "</code> (it&#8217;s in the man page). I tend to have a main pane for editing and a smaller pane for a <code>REPL</code> or log. If I need to investigate the smaller pane, I press <code>Ctrl-A Ctrl-O</code>, which switches the two panes to give me the log in the larger one.</p> <p>I use the <a href="https://github.com/xaviershay/tslime.vim" title="I had to patch it">tslime.vim plugin</a> to send text directly from vim to the supplementary pane. This is a killer feature. As well as the built in <code>Ctrl-C</code> shortcut, I also use a trick I learned from <a href="http://blog.extracheese.org/">Gary Bernhardt</a> and remap <code>&lt;leader&gt;t</code> on the fly to send whatever command I am currently testing to the other pane. Some examples:</p><table class="CodeRay"><tr> <td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"><pre>1<tt> </tt>2<tt> </tt>3<tt> </tt>4<tt> </tt></pre></td> <td class="code"><pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }">; Load a file into a clojure repl<tt> </tt>:map ;t :w\|:call Send_to_Tmux(&quot;\n\n\n(load-file \&quot;./myfile.clj\&quot;)\n&quot;)&lt;CR&gt;<tt> </tt>; Run rspec in zsh<tt> </tt>:map ;t :w\|:call Send_to_Tmux(&quot;rspec spec/my_spec.rb\n&quot;)&lt;CR&gt;<tt> </tt></pre></td> </tr></table> <p>If I need to interact with a shell I&#8217;ll usually <code>Ctrl-Z</code> vim, do what I need to do, then <code>fg</code> back again. If it&#8217;s a context switch, I&#8217;ll start a new tmux window then exit it after I&#8217;m done with the distraction.</p> <p>I don&#8217;t use sessions. I prefer setting up from scratch each time since it takes no time at all, and eases my brain into the problem. Clean desk and all that.</p> <p>That&#8217;s it. Nothing too fancy, but I&#8217;ve been meaning to make the switch from MacVim for a while and with this set up I can&#8217;t ever see myself going back.</p> tag:www.rhnh.net,2008:Post/303 2007-12-13T12:19:00Z 2007-12-17T04:11:19Z Formatting ruby hashes in VIM <p>I&#8217;ve been meaning to write this script for a while. If you&#8217;re anal about your whitespace (like I), you&#8217;ll often pretty up your ruby hashes to make them easy to read by adding a bit of whitespace to the keys before the =&gt;. I wrote a ruby script to do this automatically!</p><table class="CodeRay"><tr> <td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"><pre>1<tt> </tt>2<tt> </tt>3<tt> </tt>4<tt> </tt>5<tt> </tt>6<tt> </tt>7<tt> </tt>8<tt> </tt>9<tt> </tt><strong>10</strong><tt> </tt>11<tt> </tt>12<tt> </tt>13<tt> </tt>14<tt> </tt>15<tt> </tt>16<tt> </tt>17<tt> </tt>18<tt> </tt>19<tt> </tt><strong>20</strong><tt> </tt>21<tt> </tt>22<tt> </tt>23<tt> </tt>24<tt> </tt>25<tt> </tt>26<tt> </tt>27<tt> </tt>28<tt> </tt>29<tt> </tt><strong>30</strong><tt> </tt>31<tt> </tt>32<tt> </tt>33<tt> </tt>34<tt> </tt>35<tt> </tt>36<tt> </tt>37<tt> </tt>38<tt> </tt>39<tt> </tt></pre></td> <td class="code"><pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><span class="c">#!/usr/bin/env ruby</span><tt> </tt><tt> </tt><span class="c"># format_hash.rb</span><tt> </tt><span class="c">#</span><tt> </tt><span class="c"># Formats ruby hashes</span><tt> </tt><span class="c"># a =&gt; 1</span><tt> </tt><span class="c"># ab =&gt; 2</span><tt> </tt><span class="c"># abc =&gt; 3</span><tt> </tt><span class="c">#</span><tt> </tt><span class="c"># becomes</span><tt> </tt><span class="c"># a =&gt; 1</span><tt> </tt><span class="c"># ab =&gt; 2</span><tt> </tt><span class="c"># abc =&gt; 3</span><tt> </tt><span class="c">#</span><tt> </tt><span class="c"># http://rhnh.net</span><tt> </tt><tt> </tt>lines = []<tt> </tt><span class="r">while</span> line = gets<tt> </tt> lines &amp;lt;&amp;lt; line<tt> </tt><span class="r">end</span><tt> </tt><tt> </tt>indent = lines.first.index(<span class="rx"><span class="dl">/</span><span class="k">[^</span><span class="ch">\s</span><span class="k">]</span><span class="dl">/</span></span>)<tt> </tt><tt> </tt><span class="c"># Massage into an array of [key, value]</span><tt> </tt>lines.collect! {|line| <tt> </tt> line.split(<span class="s"><span class="dl">'</span><span class="k">=&gt;</span><span class="dl">'</span></span>).collect {|line| <tt> </tt> line.gsub(<span class="rx"><span class="dl">/</span><span class="k">^</span><span class="ch">\s</span><span class="k">*</span><span class="dl">/</span></span>, <span class="s"><span class="dl">'</span><span class="dl">'</span></span>).gsub(<span class="rx"><span class="dl">/</span><span class="ch">\s</span><span class="k">*$</span><span class="dl">/</span></span>, <span class="s"><span class="dl">'</span><span class="dl">'</span></span>) <tt> </tt> }<tt> </tt>}<tt> </tt><tt> </tt>max_key_length = lines.collect {|line| line[<span class="i">0</span>].length}.max<tt> </tt><tt> </tt><span class="c"># Pad each key with whitespace to match length of longest key</span><tt> </tt>lines.collect! {|line|<tt> </tt> line[<span class="i">0</span>] = <span class="s"><span class="dl">&quot;</span><span class="k">%</span><span class="il"><span class="idl">#{</span>indent<span class="idl">}</span></span><span class="k">s%-</span><span class="il"><span class="idl">#{</span>max_key_length<span class="idl">}</span></span><span class="k">s</span><span class="dl">&quot;</span></span> % [<span class="s"><span class="dl">'</span><span class="dl">'</span></span>, line[<span class="i">0</span>]]<tt> </tt> line.join(<span class="s"><span class="dl">'</span><span class="k"> =&gt; </span><span class="dl">'</span></span>)<tt> </tt>}<tt> </tt><tt> </tt>print lines.join(<span class="s"><span class="dl">&quot;</span><span class="ch">\n</span><span class="dl">&quot;</span></span>)<tt> </tt></pre></td> </tr></table> <p>Put that in your path, then in <span class="caps">VIM</span> you can run the following command to format the current selection:</p> <macro:code> :&#8217;&lt;,&#8217;&gt;!format_hash.rb # Or map F2 to do it for you&#8230; :vmap &lt;F2&gt; !format_hash.rb&lt;CR&gt; &#8212;- tag:www.rhnh.net,2008:Post/128 2007-07-08T07:26:00Z 2007-08-15T07:28:06Z The Switch to VIM <p>I&#8217;m been meaning to try out Vim for a while, especially since I now use two different platforms/editors for development (mac/textmate at work, linux/jedit at home). Finally got some time to try it out this weekend, and initial reports are positive! The thing that strikes me the most is how quickly you can navigate/select things without using the mouse. Vim&#8217;s navigation shortcuts are like <span class="caps">CTRL</span>-(LEFT|RIGHT) on crack. Regex search forward and back, move by multiple lines, seek to next/prev char. I haven&#8217;t internalized this navigation yet and already I&#8217;m loving it. Give me some experience and I&#8217;ll become an absolute machine. It&#8217;s a bit weird because I&#8217;m using colemak, so the &#8220;stick to the home row&#8221; mantra doesn&#8217;t really apply, but overall it&#8217;s still quite bearable. I need to figure out how to replicate the Apple-T shortcut in textmate (quick swith to file) and I think I&#8217;ll be sold. I&#8217;ll use it at work for the week and see how things go. For reference, I found the <a href="http://www.vi-improved.org/tutorial.php">tutorial on the vi-improved site</a> to be quite helpful.</p>