<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

  <title><![CDATA[endot]]></title>
  <link href="http://endot.org/atom.xml" rel="self"/>
  <link href="http://endot.org/"/>
  <updated>2012-02-13T13:14:40-08:00</updated>
  <id>http://endot.org/</id>
  <author>
    <name><![CDATA[Nate Jones]]></name>
    
  </author>
  <generator uri="http://octopress.org/">Octopress</generator>

  
  
  <entry>
    <title type="html"><![CDATA[git-walklog]]></title>
    <link href="http://endot.org/2012/02/13/git-walklog/"/>
    <updated>2012-02-13T12:22:00-08:00</updated>
    <id>http://endot.org/2012/02/13/git-walklog</id>
    <content type="html"><![CDATA[<p>Most of the time, when looking at history in a git repository, I am most interested in changes at a higher level than an individual commit.  From time to time, however, I really want to look at each commit on its own.  So, I created <a href="https://github.com/justone/dotfiles/blob/personal/bin/git-walklog">git-walklog</a>.  For each commit in the range specified, it:</p>

<ol>
  <li>Shows the standard log format: author, date, and commit message.  Then it waits for input.</li>
  <li>Hitting enter then runs <code>git difftool</code> on just that commit, showing you any differences in your configured difftool <sup id="fnref:1"><a href="#fn:1" rel="footnote">1</a></sup>.</li>
</ol>

<p>If you want to skip a commit, all you need to do is type ‘n’ or ‘no’.</p>

<p>I usually use <code>git log</code> with different options till I get it to just show the entries I’m interested in and then replace <code>log</code> with <code>walklog</code> to cruise through the commits.</p>

<h2 id="examples">Examples</h2>

<p>To see the last three commits:</p>

<div class="bogus-wrapper"><notextile><figure class="code"><figcaption><span /></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
</pre></td><td class="code"><pre><code class=""><span class="line">git walklog -3 --reverse</span></code></pre></td></tr></table></div></figure></notextile></div>

<p>To see the changes for a particular branch:</p>

<div class="bogus-wrapper"><notextile><figure class="code"><figcaption><span /></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
</pre></td><td class="code"><pre><code class=""><span class="line">git walklog master..branch --reverse</span></code></pre></td></tr></table></div></figure></notextile></div>

<p>To see what came in the last git pull:</p>

<div class="bogus-wrapper"><notextile><figure class="code"><figcaption><span /></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
</pre></td><td class="code"><pre><code class=""><span class="line">git walklog master@{1}.. --reverse</span></code></pre></td></tr></table></div></figure></notextile></div>

<p>I usually put <code>--reverse</code> in there, because I want to see the commits in the same order as they were created.</p>

<p>Enjoy.</p>

<div class="footnotes">
  <ol>
    <li id="fn:1">
      <p>You do have a difftool configured, don’t you?  Run <code>git config --global diff.tool vimdiff</code> and then use <code>git difftool</code> instead of <code>git diff</code> and all your diffs will show up in vimdiff.  Works for other diffing tools too, look for “Valid merge tools” in <a href="http://schacon.github.com/git/git-difftool.html">man difftool</a>.<a href="#fnref:1" rev="footnote">&#8617;</a></p>
    </li>
  </ol>
</div>
]]></content>
  </entry>
  
  
  
  <entry>
    <title type="html"><![CDATA[Git subtree tracking made easy]]></title>
    <link href="http://endot.org/2012/02/12/git-subtree-tracking-made-easy/"/>
    <updated>2012-02-12T16:33:00-08:00</updated>
    <id>http://endot.org/2012/02/12/git-subtree-tracking-made-easy</id>
    <content type="html"><![CDATA[<p>Last year, when I made my <a href="http://endot.org/2011/05/18/git-submodules-vs-subtrees-for-vim-plugins/">list of pros and cons comparing git subtrees with submodules</a>, one of the downsides listed for subtrees was that it’s hard to figure out where the code came from originally.</p>

<p>Well, it seems that the internet hasn’t been sitting on its hands.  While the main repository remained stable, a <a href="https://github.com/matthoffman/git-subtree">couple</a> <a href="https://github.com/bibendi/git-subtree">forks</a> took it upon themselves to teach git-subtree to keep a record of what it merges in a <code>.gittrees</code> file.  When a subtree is added, something like the following is added to the file:</p>

<div class="bogus-wrapper"><notextile><figure class="code"><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
<span class="line-number">2</span>
<span class="line-number">3</span>
<span class="line-number">4</span>
</pre></td><td class="code"><pre><code class=""><span class="line">[subtree "bin/remotecopy"]
</span><span class="line">    url = git@github.com:justone/remotecopy.git
</span><span class="line">    path = bin/remotecopy
</span><span class="line">    branch = master</span></code></pre></td></tr></table></div></figure></notextile></div>

<p>I created <a href="https://github.com/justone/git-subtree">my own fork</a> and merged in those ones as well as adding the <a href="https://github.com/justone/git-subtree/commit/84185583ccabc97da7627a5fd2e01c32ea4c0965">ability to prune stale entries</a>.</p>

<p>The next task was finding all the subtrees in my dotfiles repository and adding entries like the one above.  Here’s the shell script I used:</p>

<div class="bogus-wrapper"><notextile><figure class="code"><figcaption><span /></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
<span class="line-number">2</span>
<span class="line-number">3</span>
<span class="line-number">4</span>
<span class="line-number">5</span>
<span class="line-number">6</span>
<span class="line-number">7</span>
<span class="line-number">8</span>
<span class="line-number">9</span>
<span class="line-number">10</span>
<span class="line-number">11</span>
<span class="line-number">12</span>
<span class="line-number">13</span>
<span class="line-number">14</span>
<span class="line-number">15</span>
<span class="line-number">16</span>
<span class="line-number">17</span>
<span class="line-number">18</span>
<span class="line-number">19</span>
<span class="line-number">20</span>
<span class="line-number">21</span>
<span class="line-number">22</span>
<span class="line-number">23</span>
<span class="line-number">24</span>
<span class="line-number">25</span>
<span class="line-number">26</span>
<span class="line-number">27</span>
<span class="line-number">28</span>
<span class="line-number">29</span>
<span class="line-number">30</span>
<span class="line-number">31</span>
<span class="line-number">32</span>
<span class="line-number">33</span>
</pre></td><td class="code"><pre><code class="sh"><span class="line"><span class="c">#!/bin/sh</span>
</span><span class="line">
</span><span class="line"><span class="c"># for each path that was subtree merged</span>
</span><span class="line"><span class="k">for </span>path in <span class="sb">`</span>git log --grep Squashed --oneline | awk <span class="s1">&#39;{ print $3 }&#39;</span> | sort | uniq | sed <span class="s2">&quot;s/&#39;//g&quot;</span> | sed <span class="s2">&quot;s/\/$//g&quot;</span><span class="sb">`</span>; <span class="k">do</span>
</span><span class="line">
</span><span class="line">    <span class="c"># check to see if the subpath is already in .gittrees</span>
</span><span class="line">    git config -f .gittrees subtree.<span class="nv">$path</span>.url &amp;&gt; /dev/null
</span><span class="line">    <span class="k">if</span> <span class="o">[</span> <span class="nv">$?</span> -eq 0 <span class="o">]</span>; <span class="k">then</span>
</span><span class="line"><span class="k">        </span><span class="nb">echo</span> <span class="s2">&quot;$path already configured&quot;</span>
</span><span class="line">    <span class="k">else</span>
</span><span class="line">
</span><span class="line">        <span class="c"># look for the most recent commit</span>
</span><span class="line">        <span class="nv">commit</span><span class="o">=</span><span class="sb">`</span>git log --grep <span class="s2">&quot;Squashed &#39;$path/&#39;&quot;</span> --oneline | head -n 1 | awk <span class="s1">&#39;{ print $NF }&#39;</span><span class="sb">`</span>
</span><span class="line">        <span class="k">if</span> <span class="o">[[</span> <span class="nv">$commit</span> <span class="o">=</span>~ <span class="s1">&#39;..&#39;</span> <span class="o">]]</span>; <span class="k">then</span>
</span><span class="line"><span class="k">            </span><span class="nv">commit</span><span class="o">=</span><span class="sb">`</span><span class="nb">echo</span> <span class="nv">$commit</span> | cut -d . -f 3<span class="sb">`</span>
</span><span class="line">        <span class="k">fi</span>
</span><span class="line"><span class="k">        </span><span class="nb">echo</span> <span class="s2">&quot;last commit for $path is $commit&quot;</span>;
</span><span class="line">
</span><span class="line">        <span class="c"># ask for the git url</span>
</span><span class="line">        <span class="nb">echo</span> <span class="s2">&quot;Enter url: &quot;</span>
</span><span class="line">        <span class="nb">read </span>URL
</span><span class="line">
</span><span class="line">        <span class="c"># record the subtree info</span>
</span><span class="line">        git config -f .gittrees --unset subtree.<span class="nv">$path</span>.url
</span><span class="line">        git config -f .gittrees --add subtree.<span class="nv">$path</span>.url <span class="nv">$URL</span>
</span><span class="line">        git config -f .gittrees --unset subtree.<span class="nv">$path</span>.path
</span><span class="line">        git config -f .gittrees --add subtree.<span class="nv">$path</span>.path <span class="nv">$path</span>
</span><span class="line">        git config -f .gittrees --unset subtree.<span class="nv">$path</span>.branch
</span><span class="line">        git config -f .gittrees --add subtree.<span class="nv">$path</span>.branch master
</span><span class="line">    <span class="k">fi</span>
</span><span class="line">
</span><span class="line"><span class="k">    </span><span class="nb">echo</span> <span class="s2">&quot;------------------------------&quot;</span>
</span><span class="line"><span class="k">done</span>
</span></code></pre></td></tr></table></div></figure></notextile></div>

<p>When run, it finds any subtrees that have been squashed in and shows the path and the last short commit id.  For instance:</p>

<div class="bogus-wrapper"><notextile><figure class="code"><figcaption><span /></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
<span class="line-number">2</span>
<span class="line-number">3</span>
</pre></td><td class="code"><pre><code class=""><span class="line">$ sh ../subtree_commits.sh 
</span><span class="line">last commit for .vim/bundle/tabular is b7b4d87
</span><span class="line">Enter url: 
</span></code></pre></td></tr></table></div></figure></notextile></div>

<p>Then all I had to do was find the right git repository online and paste the url in.  I usually accomplished this by searching for <code>github [pluginname]</code> and then appending <code>/commit/[short sha1]</code> to the url to see if the commit existed.  For instance, looking for <code>github tabular</code> led me to <a href="https://github.com/godlygeek/tabular">https://github.com/godlygeek/tabular</a>, and appending <a href="https://github.com/godlygeek/tabular/commit/b7b4d87">/commit/b7b4d87</a> shows that the commit exists in that repository, so it’s likely the right one.  For the plugins that aren’t hosted by their authors on github or elsewhere, the <a href="https://github.com/vim-scripts">vim-scripts</a> mirror was usually where I ended up.  The script can be run multiple times, it skips any subtrees that already have entries in <code>.gittrees</code>.</p>

<p>After running the script for a while, and searching for all the home repositories for my subtrees, I ended up with <a href="https://github.com/justone/dotfiles/blob/personal/.gittrees">this .gittrees file</a>.</p>

<p>Now, if I want to list my subtrees:</p>

<div class="bogus-wrapper"><notextile><figure class="code"><figcaption><span /></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
<span class="line-number">2</span>
<span class="line-number">3</span>
<span class="line-number">4</span>
<span class="line-number">5</span>
<span class="line-number">6</span>
<span class="line-number">7</span>
<span class="line-number">8</span>
<span class="line-number">9</span>
<span class="line-number">10</span>
<span class="line-number">11</span>
<span class="line-number">12</span>
<span class="line-number">13</span>
<span class="line-number">14</span>
<span class="line-number">15</span>
<span class="line-number">16</span>
<span class="line-number">17</span>
<span class="line-number">18</span>
<span class="line-number">19</span>
<span class="line-number">20</span>
<span class="line-number">21</span>
<span class="line-number">22</span>
<span class="line-number">23</span>
<span class="line-number">24</span>
<span class="line-number">25</span>
<span class="line-number">26</span>
</pre></td><td class="code"><pre><code class=""><span class="line">$ dfm subtree list
</span><span class="line">    bin/git-subtree        (merged from https://github.com/justone/git-subtree.git branch master) 
</span><span class="line">    bin/remotecopy        (merged from git@github.com:justone/remotecopy.git branch master) 
</span><span class="line">    .bashrc.d/resty        (merged from https://github.com/micha/resty.git branch master) 
</span><span class="line">    .bashrc.d/z        (merged from https://github.com/rupa/z.git branch master) 
</span><span class="line">    .vim/bundle/AutoTag        (merged from https://github.com/vim-scripts/AutoTag.git branch master) 
</span><span class="line">    .vim/bundle/FuzzyFinder        (merged from https://github.com/vim-scripts/FuzzyFinder.git branch master) 
</span><span class="line">    .vim/bundle/L9        (merged from https://github.com/vim-scripts/L9.git branch master) 
</span><span class="line">    .vim/bundle/ack        (merged from https://github.com/mileszs/ack.vim.git branch master) 
</span><span class="line">    .vim/bundle/bufexplorer        (merged from https://github.com/vim-scripts/bufexplorer.zip.git branch master) 
</span><span class="line">    .vim/bundle/bufkill        (merged from https://github.com/vim-scripts/bufkill.vim.git branch master) 
</span><span class="line">    .vim/bundle/conque-shell        (merged from https://github.com/vim-scripts/Conque-Shell.git branch master) 
</span><span class="line">    .vim/bundle/gundo        (merged from https://github.com/sjl/gundo.vim.git branch master) 
</span><span class="line">    .vim/bundle/regbuf        (merged from https://github.com/tyru/regbuf.vim.git branch master) 
</span><span class="line">    .vim/bundle/syntastic        (merged from https://github.com/scrooloose/syntastic.git branch master) 
</span><span class="line">    .vim/bundle/tabular        (merged from https://github.com/godlygeek/tabular.git branch master) 
</span><span class="line">    .vim/bundle/taglist        (merged from https://github.com/vim-scripts/taglist.vim.git branch master) 
</span><span class="line">    .vim/bundle/ultisnips        (merged from https://github.com/SirVer/ultisnips.git branch master) 
</span><span class="line">    .vim/bundle/vcscommand        (merged from git://repo.or.cz/vcscommand.git branch master) 
</span><span class="line">    .vim/bundle/vim-colors-solarized        (merged from https://github.com/altercation/vim-colors-solarized.git branch master) 
</span><span class="line">    .vim/bundle/vim-fugitive        (merged from https://github.com/tpope/vim-fugitive.git branch master) 
</span><span class="line">    .vim/bundle/vim-markdown-preview        (merged from https://github.com/robgleeson/hammer.vim.git branch master) 
</span><span class="line">    .vim/bundle/vim-octopress        (merged from https://github.com/tangledhelix/vim-octopress.git branch master) 
</span><span class="line">    .vim/bundle/vim-r        (merged from https://github.com/jcfaria/Vim-R-plugin.git branch master) 
</span><span class="line">    .vim/bundle/vim-speeddating        (merged from https://github.com/tpope/vim-speeddating.git branch master) 
</span><span class="line">    .vim/bundle/vim-unimpaired        (merged from https://github.com/tpope/vim-unimpaired.git branch master) </span></code></pre></td></tr></table></div></figure></notextile></div>

<p>And to update a particular subtree:</p>

<div class="bogus-wrapper"><notextile><figure class="code"><figcaption><span /></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
<span class="line-number">2</span>
<span class="line-number">3</span>
<span class="line-number">4</span>
<span class="line-number">5</span>
<span class="line-number">6</span>
<span class="line-number">7</span>
</pre></td><td class="code"><pre><code class=""><span class="line">$ dfm subtree pull -P .bashrc.d/z --squash
</span><span class="line">From https://github.com/rupa/z
</span><span class="line"> * branch            master     -&gt; FETCH_HEAD
</span><span class="line">git fetch using:  https://github.com/rupa/z.git master
</span><span class="line">Merge made by recursive.
</span><span class="line"> .bashrc.d/z/z.sh |   49 +++++++++++++++++++++++++++++++++++++++++++------
</span><span class="line"> 1 files changed, 43 insertions(+), 6 deletions(-)</span></code></pre></td></tr></table></div></figure></notextile></div>

<p>Alright, that’s all I have time for today.  Enjoy.</p>
]]></content>
  </entry>
  
  
  
  <entry>
    <title type="html"><![CDATA[dfm tip: untracked binaries]]></title>
    <link href="http://endot.org/2012/01/22/dfm-tip-untracked-binaries/"/>
    <updated>2012-01-22T15:38:00-08:00</updated>
    <id>http://endot.org/2012/01/22/dfm-tip-untracked-binaries</id>
    <content type="html"><![CDATA[<h2 id="the-problem">The problem</h2>

<p>From time to time, I have scripts and binaries that I only really need on one system.  Since the base dotfiles repo includes a bin directory (for <code>dfm</code> itself), if I just drop files in there, git continually shows me that they are untracked.  For instance, if I have a script called <code>only_on_my_mac</code>, then running <code>dfm status</code> shows:</p>

<div class="bogus-wrapper"><notextile><figure class="code"><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
<span class="line-number">2</span>
<span class="line-number">3</span>
<span class="line-number">4</span>
<span class="line-number">5</span>
<span class="line-number">6</span>
</pre></td><td class="code"><pre><code class=""><span class="line"># On branch personal
</span><span class="line"># Untracked files:
</span><span class="line">#   (use "git add &lt;file&gt;..." to include in what will be committed)
</span><span class="line">#
</span><span class="line">#       bin/only_on_my_mac
</span><span class="line">nothing added to commit but untracked files present (use "git add" to track)</span></code></pre></td></tr></table></div></figure></notextile></div>

<p>At the very least, this is annoying.  Here, I offer three solutions to this problem.</p>

<h2 id="solution-1-gitignore">Solution 1: .gitignore</h2>

<p>The first solution is to just drop a .gitignore file in the bin directory and specify each file that needs to be ignored:</p>

<div class="bogus-wrapper"><notextile><figure class="code"><figcaption><span>$HOME/.dotfiles/bin/.gitignore</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
</pre></td><td class="code"><pre><code class=""><span class="line">only_on_my_mac</span></code></pre></td></tr></table></div></figure></notextile></div>

<p>If you only have a couple scripts, this may work.  However, after the third entry, this gets rather tedious.</p>

<h2 id="solution-2-create-an-excluded-directory">Solution 2: Create an excluded directory</h2>

<p>This solution is a slight modification of the previous one.  Instead of ignoring each individual file, create a directory for excluded scripts:</p>

<div class="bogus-wrapper"><notextile><figure class="code"><figcaption><span /></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
</pre></td><td class="code"><pre><code class=""><span class="line">mkdir .dotfiles/bin/excluded</span></code></pre></td></tr></table></div></figure></notextile></div>

<p>Then, ignore all the files inside that directory (except the .gitignore file itself):</p>

<div class="bogus-wrapper"><notextile><figure class="code"><figcaption><span>$HOME/.dotfiles/bin/excluded/.gitignore</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
<span class="line-number">2</span>
</pre></td><td class="code"><pre><code class=""><span class="line">*
</span><span class="line">!.gitignore</span></code></pre></td></tr></table></div></figure></notextile></div>

<p>Finally, update <code>.bashrc.load</code> to add the new directory to the path:</p>

<div class="bogus-wrapper"><notextile><figure class="code"><figcaption><span>$HOME/.dotfiles/.bashrc.load</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
</pre></td><td class="code"><pre><code class=""><span class="line">PATH=$HOME/bin/excluded:$PATH</span></code></pre></td></tr></table></div></figure></notextile></div>

<p>Now, any scripts that are only for one system can just be dropped into the bin/excluded directory and git/dfm won’t try to track them.</p>

<h2 id="solution-3-use-dfm-recursion">Solution 3: Use dfm recursion</h2>

<p>This solution involves modifying the <code>.dfminstall</code> file in the base of the dotfiles repository.  Add the following line:</p>

<div class="bogus-wrapper"><notextile><figure class="code"><figcaption><span>$HOME/.dotfiles/.dfminstall</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
</pre></td><td class="code"><pre><code class=""><span class="line">bin recurse</span></code></pre></td></tr></table></div></figure></notextile></div>

<p>Then, when <code>dfm</code> installs, it will symlink any scripts in the dotfiles’ bin directory instead of symlinking the entire directory.</p>

<div class="bogus-wrapper"><notextile><figure class="code"><figcaption><span>without recursion</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
<span class="line-number">2</span>
</pre></td><td class="code"><pre><code class=""><span class="line">$ ls -al bin
</span><span class="line">lrwxr-xr-x  1 jones  staff  13 Oct  4 20:20 bin -&gt; .dotfiles/bin</span></code></pre></td></tr></table></div></figure></notextile></div>

<div class="bogus-wrapper"><notextile><figure class="code"><figcaption><span>with recursion</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
<span class="line-number">2</span>
<span class="line-number">3</span>
<span class="line-number">4</span>
<span class="line-number">5</span>
<span class="line-number">6</span>
</pre></td><td class="code"><pre><code class=""><span class="line">$ ls -al bin
</span><span class="line">drwxr-xr-x 3 vagrant vagrant 4096 2012-01-23 01:31 .
</span><span class="line">drwxr-xr-x 5 vagrant vagrant 4096 2012-01-23 01:31 ..
</span><span class="line">-rw-r--r-- 1 vagrant vagrant   12 2012-01-23 01:31 only_on_my_mac
</span><span class="line">drwxr-xr-x 2 vagrant vagrant 4096 2012-01-23 01:31 .backup
</span><span class="line">lrwxrwxrwx 1 vagrant vagrant   20 2012-01-23 01:31 dfm -&gt; ../.dotfiles/bin/dfm</span></code></pre></td></tr></table></div></figure></notextile></div>

<p>This solution only started working today.  There was an bug in dfm that prevented the bin directory itself from being recurse-able.  If you want to use this solution, you’ll need to merge the <a href="https://github.com/justone/dotfiles">latest code</a>.</p>

<h2 id="conclusion">Conclusion</h2>

<p>I personally use Solution #2, mostly because I don’t want to keep a list of files to ignore (translation: lazy).</p>

<p>I hope these solutions are helpful.  Enjoy.</p>
]]></content>
  </entry>
  
  
  
  <entry>
    <title type="html"><![CDATA[My tmux configuration]]></title>
    <link href="http://endot.org/2011/12/06/my-tmux-configuration/"/>
    <updated>2011-12-06T20:58:00-08:00</updated>
    <id>http://endot.org/2011/12/06/my-tmux-configuration</id>
    <content type="html"><![CDATA[<p>For the longest time, I was a <a href="http://www.gnu.org/s/screen/">screen</a> user.  Then, a little while ago, I discovered <a href="http://tmux.sourceforge.net/">tmux</a>, the next generation terminal multiplexer.  Not only is it easier to search for on google, it has a rich and consistent configuration language.</p>

<p>I’ve figured out a rather unique tmux configuration and I wanted to share it.</p>

<h1 id="background">Background</h1>

<p>Originally, I just used tmux on remote servers to control several windows.  This made it easy to create new remote windows, but I had to keep multiple Terminal tabs open, one for each remote server.  I had long wanted to be able to reconnect with my tabs, much in the same way that I could reconnect with the windows on an individual server.  I contemplated just running tmux locally on my mac, but then each new window would have required a new connection, and they wouldn’t be logically grouped.</p>

<p>So I run tmux locally and remotely.</p>

<h1 id="nested-tmux">Nested tmux</h1>

<p>I manage my nested tmux sessions with three configuration files.</p>

<ol>
  <li><a href="https://github.com/justone/dotfiles/blob/personal/.tmux.shared">.tmux.shared</a> - contains configuration and bindings that are shared between my master and remote sessions</li>
  <li><a href="https://github.com/justone/dotfiles/blob/personal/.tmux.master">.tmux.master</a> - contains configuration unique to my local (master) session</li>
  <li><a href="https://github.com/justone/dotfiles/blob/personal/.tmux.conf">.tmux.conf</a> - contains configuration unique to the remote sessions</li>
</ol>

<h2 id="shared-configuration">Shared configuration</h2>

<p>Note: <code>bind -n</code> maps a key that works all the time, regular <code>bind</code> maps a key that has to be prefixed with the prefix key.</p>

<p>The shared configuration contains three basic sections:</p>

<ol>
  <li><a href="https://github.com/justone/dotfiles/blob/personal/.tmux.shared#L3">Vim-ish keybindings</a> - I set them whenever I can get them.  (-:</li>
  <li><a href="https://github.com/justone/dotfiles/blob/personal/.tmux.shared#L16">Misc. configuration</a> - One screen-compatible binding and one I’ll highlight later.</li>
  <li><a href="https://github.com/justone/dotfiles/blob/personal/.tmux.shared#L24">Status bar configuration</a> - This I mostly copied from someone else.</li>
</ol>

<h2 id="local-configuration">Local configuration</h2>

<p>The important setting here is updating the prefix to be <code>Ctrl-Alt-b</code>.  It took a few days to get used to hitting it, but my left ring finger now drops down to hit the alt key when I want to do local operations.</p>

<div class="bogus-wrapper"><notextile><figure class="code"><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
</pre></td><td class="code"><pre><code class=""><span class="line">set-option -g prefix M-C-b</span></code></pre></td></tr></table></div></figure></notextile></div>

<p>One convenience of using Terminal tabs is cruising between them with <code>Shift-Cmd-[</code> and <code>Shift-Cmd-]</code>.  To get a similar facility, I map <code>Ctrl-Alt-h</code> and <code>Ctrl-Alt-l</code> to previous and next:</p>

<div class="bogus-wrapper"><notextile><figure class="code"><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
<span class="line-number">2</span>
<span class="line-number">3</span>
</pre></td><td class="code"><pre><code class=""><span class="line"># window navigation
</span><span class="line">bind-key -n M-C-h prev
</span><span class="line">bind-key -n M-C-l next</span></code></pre></td></tr></table></div></figure></notextile></div>

<h2 id="remote-configuration">Remote configuration</h2>

<p>My remote configuration file doesn’t make any modifications with regard to nesting tmux sessions.  It uses the default <code>Ctrl-b</code> prefix and is named <code>.tmux.conf</code> so that it is the default when tmux is started.</p>

<p>It doesn’t specify next and previous window navigation like the master config because the corresponding choice for keys would be <code>Alt-h</code> and <code>Alt-l</code>, which confuses vim when I need to hit <code>Escape</code> followed by <code>h</code>, which happens rather frequently.  I fall back on the normal tmux navigation for next and previous window.</p>

<h1 id="other-nifty-settings">Other nifty settings</h1>

<h2 id="resizing-panes">Resizing panes</h2>

<p>I often split windows into multiple panes.  While tmux has some nice default layouts, it is sometimes easier to just move the divisions yourself.</p>

<p>Here’s the configuration section for resizing from my remote configuration:</p>

<div class="bogus-wrapper"><notextile><figure class="code"><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
<span class="line-number">2</span>
<span class="line-number">3</span>
<span class="line-number">4</span>
<span class="line-number">5</span>
</pre></td><td class="code"><pre><code class=""><span class="line"># keybindings to make resizing easier
</span><span class="line">bind -r C-h resize-pane -L
</span><span class="line">bind -r C-j resize-pane -D
</span><span class="line">bind -r C-k resize-pane -U
</span><span class="line">bind -r C-l resize-pane -R</span></code></pre></td></tr></table></div></figure></notextile></div>

<p>Hitting the sequence <code>Ctrl-b</code> <code>Ctrl-h</code> will make the division between the current pane and the one below it move one line.  What makes it usable is the <code>-r</code> flag, which means I can just keep hitting <code>Ctrl-h</code> as many times as I want until the panes look right.</p>

<h2 id="synchronizing-input">Synchronizing input</h2>

<p>Every so often, I want to send the same input to all panes in a particular window.  With this configuration, it’s easy to toggle the built in synchronization:</p>

<div class="bogus-wrapper"><notextile><figure class="code"><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
<span class="line-number">2</span>
<span class="line-number">3</span>
</pre></td><td class="code"><pre><code class=""><span class="line"># easily toggle synchronization (mnemonic: e is for echo)
</span><span class="line">bind e setw synchronize-panes on
</span><span class="line">bind E setw synchronize-panes off</span></code></pre></td></tr></table></div></figure></notextile></div>

<h1 id="conclusion">Conclusion</h1>

<p>Using these settings makes it a cinch to reconnect to my entire work environment from anywhere.  I have two status bar lines at the bottom of my screen; the lower one is analogous to Terminal tabs and the upper one shows my remote windows.</p>

<p>Enjoy.</p>
]]></content>
  </entry>
  
  
  
  <entry>
    <title type="html"><![CDATA[remotecopy - copy from remote terminals into your local clipboard]]></title>
    <link href="http://endot.org/2011/12/04/remotecopy-copy-from-remote-terminals-into-your-local-clipboard/"/>
    <updated>2011-12-04T14:56:00-08:00</updated>
    <id>http://endot.org/2011/12/04/remotecopy-copy-from-remote-terminals-into-your-local-clipboard</id>
    <content type="html"><![CDATA[<h1 id="problem">Problem</h1>

<p>I copy and paste all the time.  Most of the time, I copy short pieces of information that are too long to type (I’m lazy) but too short to setup anything more complex (wget, scp, etc.).  For a while, this was fine as most of my copy targets were either local to my system or in a terminal window on a remote server.  However, as I increased my use of splits in tmux and windows in vim, highlighting remote text with my mouse became horribly cumbersome.  I needed a way to copy remote text into my local clipboard.</p>

<h1 id="partial-solutions">Partial solutions</h1>

<p>Recent versions of Terminal let you select blocks of text when holding down the alt key, but when I copied and pasted, the resulting block of text had extra trailing whitespace.</p>

<p>Another solution I tried was <a href="https://bitheap.org/mouseterm/">MouseTerm</a>.  It’s a SIMBL plugin that sends your mouse events straight through to the remote terminal apps.  So, I could “set mouse=a” and then select text in any vim window without overlapping other windows.  The only problem was that once the text was selected, I couldn’t copy it back to my local computer.</p>

<p>Then, I found <a href="http://seancoates.com/blogs/remote-pbcopy">remote-pbcopy</a>.  It’s a setup where pbcopy is running in a daemon mode on your local laptop and listening on a specific port.  That port is then forwarded to the remote machine with SSH.  Finally, a little alias facilitates piping output into that port.  The result: remote data ends up in your local clipboard.</p>

<p>This is exactly what I wanted.  However, I didn’t like the caveat at the end: there is no security on the listening daemon.  This means that any if any malicious (or prank-minded) person can figure out what port you are using, they can smash your local copy buffer.</p>

<h1 id="remotecopy">Remotecopy</h1>

<p>My solution to this problem, <a href="https://github.com/justone/remotecopy">remotecopy</a>, is an evolution on remote-pbcopy.  It uses a secret value, like a password, to authenticate copy requests.  To do this, it replaces the client and server with perl equivalents so that a little extra logic can be added.</p>

<p>Here’s the sequence of events.</p>

<ol>
  <li>Start <code>remotecopyserver</code> on your local laptop.</li>
  <li>SSH to a remote host with the following argument: <code>-R 12345:localhost:12345</code></li>
  <li>On the remote host, run <code>remotecopy 'test string'</code></li>
  <li>Hit cmd-v and enter</li>
  <li>‘test string’ is now in your clipboard.</li>
</ol>

<p>Here’s how it works.</p>

<p>When remotecopy is run, it makes a connection to localhost:12345 (and therefore the remotecopyserver, via SSH).  Then, a short handshake is done, followed by the transfer of the copy data.</p>

<p>Before I describe the client side of the interaction, here is how the server operates:</p>

<ol>
  <li>On startup, generate a secret string.  Listen for connections.</li>
  <li>When a connection is made, the client will send it’s secret.</li>
  <li>If the secret matches the local secret, tell the client that it can send the copy data.  Read the data and push it into the local clipboard with pbcopy.</li>
  <li>If the secret is invalid or missing, tell the client so and close the connection.  Push the secret string into the local clipboard with pbcopy.</li>
</ol>

<p>It’s important not to miss the last part of step 4.  This makes the secret available later.</p>

<p>Now, back to remotecopy.  When remotecopy runs, it doesn’t know the secret from the server.  It does the following:</p>

<ol>
  <li>Connect to the server and send an empty secret. The server sends back a rejection.</li>
  <li>Prompt the user for the secret value.  (Because the server copied it into the paste buffer, all you need to do is paste (cmd-v) and hit enter)</li>
  <li>Reconnect to the server, sending the secret and then the copy data.</li>
</ol>

<p>It’s quite a long description, but the process is very quick.  If you already have the secret in your clipboard history, you can pass <code>-s &lt;secret&gt;</code> and remotecopy will only need to make one connection.</p>

<h1 id="example-runs">Example runs</h1>

<p>For each of these examples, after the secret is entered, the data is in the server’s copy buffer.</p>

<h2 id="copy-a-simple-string">Copy a simple string.</h2>

<div class="bogus-wrapper"><notextile><figure class="code"><figcaption><span /></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
<span class="line-number">2</span>
<span class="line-number">3</span>
</pre></td><td class="code"><pre><code class="sh"><span class="line"><span class="nv">$ </span>remotecopy foo
</span><span class="line">Input secret:
</span><span class="line">rc-b212f4522lle33a689edcca88d6845b8
</span></code></pre></td></tr></table></div></figure></notextile></div>

<h2 id="copy-output-of-another-program">Copy output of another program.</h2>

<div class="bogus-wrapper"><notextile><figure class="code"><figcaption><span /></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
<span class="line-number">2</span>
<span class="line-number">3</span>
</pre></td><td class="code"><pre><code class="sh"><span class="line"><span class="nv">$ </span>ls | remotecopy
</span><span class="line">Input secret:
</span><span class="line">rc-b212f4522lle33a689edcca88d6845b8
</span></code></pre></td></tr></table></div></figure></notextile></div>

<h2 id="specify-secret-on-command-line">Specify secret on command line</h2>

<p>Note: no prompt is needed.</p>

<div class="bogus-wrapper"><notextile><figure class="code"><figcaption><span /></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
</pre></td><td class="code"><pre><code class="sh"><span class="line"><span class="nv">$ </span>ls | remotecopy -s rc-b212f4520c3e33a689edcca88d6845b8
</span></code></pre></td></tr></table></div></figure></notextile></div>

<h1 id="using-remotecopy-with-vim">Using remotecopy with vim</h1>

<p>Since I use vim as much as possible, remotecopy includes a <a href="https://github.com/justone/remotecopy/tree/master/vim">vim plugin</a> that enables sending data from remote vim sessions.</p>

<p>To copy the entire file or visual selection, use <code>,y</code>.  To copy a particular buffer, use <code>,r</code>.  When the remotecopy is first attempted, there will be a prompt for the secret.  After that, the secret is cached so future copies are quick.</p>

<h1 id="using-remotecopy-with-dfm">Using remotecopy with dfm</h1>

<p>If you’re using <a href="http://endot.org/2010/10/16/dfm-a-utility-to-manage-dotfiles/">dfm</a> to manage your dotfiles, just copy it into your bin directory.  Both remotecopy and remotecopyserver are self contained perl scripts that don’t have external module dependencies.</p>

<p>You can also use git subtrees and symlink the vim plugin, like I do <a href="https://github.com/justone/dotfiles/commit/a8fdd27">here</a> and <a href="https://github.com/justone/dotfiles/commit/25bc70d">here</a>.</p>

<h1 id="more-information">More information</h1>

<p>Each script has full documentation.  Just run with the <code>--man</code> option to view it.</p>

<p>The code is available on <a href="https://github.com/justone/remotecopy">github</a>.</p>

<p>Enjoy.</p>
]]></content>
  </entry>
  
  
  
  <entry>
    <title type="html"><![CDATA[Octopress migration details]]></title>
    <link href="http://endot.org/2011/11/13/octopress-migration-details/"/>
    <updated>2011-11-13T20:16:00-08:00</updated>
    <id>http://endot.org/2011/11/13/octopress-migration-details</id>
    <content type="html"><![CDATA[<p>As is customary for those who’ve converted from WordPress to Octopress, here’s a quick post about my experience converting this blog.</p>

<p>Getting the blog up and running was a cinch, especially with a <a href="https://github.com/jbarratt/serialized.net-octopress">good example</a> to examine when I had questions.</p>

<h2 id="converting-old-entries">Converting old entries</h2>

<p>To convert my WordPress entries, I turned to <a href="https://github.com/thomasf/exitwp">exitwp</a>.  It worked pretty well, but I ran into two issues.</p>

<p>The first was that the YAML blob at the top of the converted posts wasn’t formatted correctly.</p>

<div class="bogus-wrapper"><notextile><figure class="code"><figcaption><span /></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
<span class="line-number">2</span>
<span class="line-number">3</span>
<span class="line-number">4</span>
<span class="line-number">5</span>
<span class="line-number">6</span>
<span class="line-number">7</span>
<span class="line-number">8</span>
<span class="line-number">9</span>
<span class="line-number">10</span>
<span class="line-number">11</span>
</pre></td><td class="code"><pre><code class="yaml"><span class="line"><span class="nn">---</span>
</span><span class="line"><span class="l-Scalar-Plain">author</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">nate</span>
</span><span class="line"><span class="l-Scalar-Plain">date</span><span class="p-Indicator">:</span> <span class="s">&#39;2011-10-29</span><span class="nv"> </span><span class="s">18:53:01&#39;</span>
</span><span class="line"><span class="l-Scalar-Plain">layout</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">post</span>
</span><span class="line"><span class="l-Scalar-Plain">slug</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">git-submodules-vs-subtrees-for-vim-plugins-part-2</span>
</span><span class="line"><span class="l-Scalar-Plain">status</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">publish</span>
</span><span class="line"><span class="l-Scalar-Plain">title</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">Git submodules vs. subtrees for vim plugins, part 2</span>
</span><span class="line"><span class="l-Scalar-Plain">wordpress_id</span><span class="p-Indicator">:</span> <span class="s">&#39;328&#39;</span>
</span><span class="line"><span class="p-Indicator">?</span> <span class="s">&#39;&#39;</span>
</span><span class="line"><span class="p-Indicator">:</span> <span class="p-Indicator">-</span> <span class="l-Scalar-Plain">Misc</span>
</span><span class="line"><span class="nn">---</span>
</span></code></pre></td></tr></table></div></figure></notextile></div>

<p>I solved this by switching to <a href="https://github.com/chitsaou/exitwp">chitsaou’s fork</a>.</p>

<p>The second problem was that html2text, which exitwp uses to do the actual conversion, was hard wrapping lines at 78 characters.  I fiddled with it for quite a while, hacking the backend code for html2text, but then I remembered that markdown parsers pass HTML straight through (and that I don’t care if old entries are regular HTML).  So I just modified the exitwp script to gut the html2fmt method:</p>

<div class="bogus-wrapper"><notextile><figure class="code"><figcaption><span /></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
<span class="line-number">2</span>
<span class="line-number">3</span>
<span class="line-number">4</span>
<span class="line-number">5</span>
<span class="line-number">6</span>
<span class="line-number">7</span>
<span class="line-number">8</span>
<span class="line-number">9</span>
<span class="line-number">10</span>
<span class="line-number">11</span>
<span class="line-number">12</span>
<span class="line-number">13</span>
<span class="line-number">14</span>
<span class="line-number">15</span>
<span class="line-number">16</span>
<span class="line-number">17</span>
<span class="line-number">18</span>
<span class="line-number">19</span>
</pre></td><td class="code"><pre><code class="diff"><span class="line">$ git di
</span><span class="line"><span class="gh">diff --git a/exitwp.py b/exitwp.py</span>
</span><span class="line"><span class="gh">index ae58d24..d21a8df 100755</span>
</span><span class="line"><span class="gd">--- a/exitwp.py</span>
</span><span class="line"><span class="gi">+++ b/exitwp.py</span>
</span><span class="line"><span class="gu">@@ -37,12 +37,7 @@ item_field_filter = config[&#39;item_field_filter&#39;]</span>
</span><span class="line"> date_fmt=config[&#39;date_format&#39;]
</span><span class="line">
</span><span class="line"> def html2fmt(html, target_format):
</span><span class="line"><span class="gd">-    html = html.replace(&quot;\n\n&quot;, &#39;&lt;br&gt;&#39;)</span>
</span><span class="line"><span class="gd">-    if target_format==&#39;html&#39;:</span>
</span><span class="line"><span class="gd">-        return html</span>
</span><span class="line"><span class="gd">-    else:</span>
</span><span class="line"><span class="gd">-        # This is like very stupid but I was having troubles with unicode encodings and process.POpen</span>
</span><span class="line"><span class="gd">-        return html2text(html, &#39;&#39;)</span>
</span><span class="line"><span class="gi">+    return html</span>
</span><span class="line">
</span><span class="line"> def parse_wp_xml(file):
</span><span class="line">     ns = {
</span></code></pre></td></tr></table></div></figure></notextile></div>

<h2 id="old-source-highlighting-plugin">Old source highlighting plugin</h2>

<p>I had used <a href="http://wordpress.org/extend/plugins/syntaxhighlighter/">SyntaxHighlighter Evolved</a> in WordPress to handle my syntax highlighting needs, so I needed to convert those to Octopress’ triple backtick format.</p>

<p>For this, I turned to some perl one liners:</p>

<div class="bogus-wrapper"><notextile><figure class="code"><figcaption><span /></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
<span class="line-number">2</span>
<span class="line-number">3</span>
<span class="line-number">4</span>
</pre></td><td class="code"><pre><code class="diff"><span class="line">perl -MHTML::Entities -p0777i -e &#39;s/(\[sourcecode[^]]*\])(.*)(\[\/(sourcecode)\])/$1.decode_entities($2).$3/mse&#39; *.markdown
</span><span class="line">perl -p -i -e &#39;s/\[sourcecode.*language=&quot;([^&quot;] )&quot;[^]]*\]/``` \1\n/&#39; *.markdown
</span><span class="line">perl -p -i -e &#39;s/\[sourcecode[^]]*\]/```\n/&#39; *.markdown
</span><span class="line">perl -p -i -e &#39;s/\[\/sourcecode\]/\n```/&#39; *.markdown
</span></code></pre></td></tr></table></div></figure></notextile></div>

<p>That first one uses a little trick to slurp in entire files (seen <a href="http://www.debian-administration.org/articles/298">here</a>) and decode HTML entities.</p>

<h2 id="finishing-touches">Finishing touches</h2>

<p>And, finally, many urls on my site included the hostname, making the Octopress preview less useful.  One more perl one liner:</p>

<div class="bogus-wrapper"><notextile><figure class="code"><figcaption><span /></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
</pre></td><td class="code"><pre><code class="diff"><span class="line">perl -p -i -e &#39;s{http://endot.org/}{/}g&#39; *.markdown
</span></code></pre></td></tr></table></div></figure></notextile></div>

<h2 id="final-verdict">Final verdict</h2>

<p>Octopress is awesome.</p>

<p>Enjoy.</p>
]]></content>
  </entry>
  
  
  
  <entry>
    <title type="html"><![CDATA[WordPress to Octopress]]></title>
    <link href="http://endot.org/2011/11/05/wordpress-to-octopress/"/>
    <updated>2011-11-05T22:08:00-07:00</updated>
    <id>http://endot.org/2011/11/05/wordpress-to-octopress</id>
    <content type="html"><![CDATA[<p><a href="http://wordpress.org/">WordPress</a> -&gt; <a href="http://octopress.org/">Octopress</a>.  Details later.</p>
]]></content>
  </entry>
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
</feed>

