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

  <title><![CDATA[Arthur Loder (artloder)]]></title>
  <link href="http://artloder.com/atom.xml" rel="self"/>
  <link href="http://artloder.com/"/>
  <updated>2015-01-18T07:43:49-05:00</updated>
  <id>http://artloder.com/</id>
  <author>
    <name><![CDATA[Arthur Loder]]></name>
    
  </author>
  <generator uri="http://octopress.org/">Octopress</generator>

  
  <entry>
    <title type="html"><![CDATA[My PS1: Confessions of a Bash Illiterate]]></title>
    <link href="http://artloder.com/blog/2014/08/17/my-ps1-confessions-of-a-bash-illiterate/"/>
    <updated>2014-08-17T00:00:00-04:00</updated>
    <id>http://artloder.com/blog/2014/08/17/my-ps1-confessions-of-a-bash-illiterate</id>
    <content type="html"><![CDATA[<p>Full-disclosure: I&#8217;ll never win a <em>Bash Script of the Year Award</em>. I
occasionally write them, but my skills are pretty basic, so apologies if my
attempt to build out a meaningful bash prompt offends your bash sensibilities.
Comments are semi-welcomed.</p>

<blockquote><p>&#8220;To truly know a man, first you must know his prompt.&#8221;<br/>~Sage.</p></blockquote>


<p>I&#8217;m always intrigued when I see a fellow developer&#8217;s terminal prompt, as if
I&#8217;m peering into his or her nerd soul. If you spend a lot of time in front of a
terminal, it&#8217;s worthwhile to customize your prompt. Yet I often see people who
stick with the system default.</p>

<!-- more -->


<p>Below is the default on my MacBook, and I honestly can&#8217;t imagine using it:</p>

<figure class='code'><figcaption><span>bash </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'>macbook:~ aloder$ cd ~/checkout/projects/some/project/
</span><span class='line'>macbook:project aloder$</span></code></pre></td></tr></table></div></figure>


<p>I don&#8217;t have many prompt requirements, but the following are non-negotiable
must-haves:</p>

<ul>
<li><strong><em>I can see the full pathname of the current working directory</em></strong>. I have
lots of directories named <em>target</em>, <em>bin</em>, <em>webapp</em>, etc., so seeing the full
path gives me a better chance of catching myself before doing something stupid
due to an incorrect assumption about the current directory. Additionally, when
scanning your previous commands, you know the working directory in which each
was executed.</li>
<li><strong><em>My cursor is left-justified</em></strong>. Given that I want to see the full-path, if
the cursor is on the same line, this shifts the cursor to the right as the path
gets longer. Even the default prompt above shifted the cursor to the right
because &#8216;aloder&#8217; is longer than &#8216;~&#8217;. When I look back in my terminal window, I
like having each command start in the same place. I also want to give my
verbose commands the best chance of fitting on a single line.</li>
<li><strong><em>There&#8217;s a blank line before the prompt</em></strong>. This makes it easier to
differentiate commands and their output when browsing the scrollback buffer.</li>
</ul>


<p>Below is a PS1 environment variable that meets the above requirements. This
lived in my <em>.bashrc</em> for quite some time.</p>

<figure class='code'><figcaption><span>emacs .bashrc  </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='bash'><span class='line'><span class="nv">PS1</span><span class="o">=</span><span class="s2">&quot;\n\u@\h: \w\n$ &quot;</span>
</span></code></pre></td></tr></table></div></figure>


<p>This is the prompt it creates:</p>

<figure class='code'><figcaption><span>bash </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'>aloder@macbook: ~/checkout/projects/some/project
</span><span class='line'>$</span></code></pre></td></tr></table></div></figure>


<p>This prompt did the trick for a while, but in order to include the git branch
as additional context, I later added in a <em>parse_git_branch</em> function and
updated my PS1:</p>

<figure class='code'><figcaption><span>emacs .bashrc  </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='bash'><span class='line'>parse_git_branch<span class="o">()</span> <span class="o">{</span>
</span><span class='line'>    git branch 2&gt; /dev/null | sed -e <span class="s1">&#39;/^[^*]/d&#39;</span> -e <span class="s1">&#39;s/* \(.*\)/ [\1]/&#39;</span>
</span><span class='line'><span class="o">}</span>
</span><span class='line'><span class="nv">PS1</span><span class="o">=</span><span class="s2">&quot;\n\u@\h\$(parse_git_branch): \w\n$ &quot;</span>
</span></code></pre></td></tr></table></div></figure>


<p>This is how it looks after <em>cd</em>-ing into a git working directory in which I&#8217;ve
checked out the &#8216;master&#8217; branch:</p>

<figure class='code'><figcaption><span>bash </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'>aloder@macbook [master]: ~/checkout/projects/some/project
</span><span class='line'>$</span></code></pre></td></tr></table></div></figure>


<p>I was satisfied with this until I started using <a href="http://virtualenv.readthedocs.org">virtualenv</a>
and <a href="http://virtualenvwrapper.readthedocs.org/">virtualenvwrapper</a> for my
Python development. I wanted to add the current active virtualenv to my prompt
context, but I was not a fan of the PS1 update performed by virtualenv&#8217;s
<em>bin/activate</em> script. I made my own changes but my prompt wouldn&#8217;t update the
git or virtualenv context after changing directories due to virtualenv&#8217;s own
PS1 mangling. Rather than figure out what was causing this, I did the
following:</p>

<ol>
<li>Moved all PS1 properties/code into a separate <em>~/.bashrc_ps1</em> file.</li>
<li>Updated the virtualenvwrapper <em>$WORKON_HOME/postactivate</em> script to source
the new file, which ensures the PS1 is unaffected by virtualenv.</li>
</ol>


<figure class='code'><figcaption><span>emacs postactivate  </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='bash'><span class='line'><span class="c">#!/bin/bash</span>
</span><span class='line'><span class="c"># This hook is run after every virtualenv is activated.</span>
</span><span class='line'>
</span><span class='line'><span class="nb">source</span> ~/.bashrc_ps1
</span></code></pre></td></tr></table></div></figure>


<p>As for the prompt context itself, I wanted it to be terse. I&#8217;ve seen some crazy
prompts that put way too much info on the screen. Assuming <em>webpy</em> is my active
virtualenv and that I&#8217;m on the <em>master</em> git branch, I want the context portion
of my prompt to look like this:</p>

<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'>[webpy|master]</span></code></pre></td></tr></table></div></figure>


<p>If I don&#8217;t have a virtualenv activated or am not in a git directory, it should
degrade and display only one:</p>

<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>
</pre></td><td class='code'><pre><code class=''><span class='line'>[webpy]
</span><span class='line'>[master]</span></code></pre></td></tr></table></div></figure>


<p>For instance, here&#8217;s what it looks like when I have a &#8216;webpy&#8217; virtualenv
activated but am not in a git project:</p>

<figure class='code'><figcaption><span>bash </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'>aloder@macbook [webpy]: ~/checkout/home
</span><span class='line'>$</span></code></pre></td></tr></table></div></figure>


<p>I also decided that I wanted to display the virtualenv or git branch in a
different color if either is non-default; this way, only the non-default
values will stand out. For instance, my default virtualenv is named &#8216;default&#8217;,
and my typical git branch name is &#8216;master&#8217;.</p>

<p>Below is the full contents of my <em>~/.bashrc_ps1</em> file to
achieve this:</p>

<figure class='code'><figcaption><span>emacs .bashrc_ps1  </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>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
<span class='line-number'>41</span>
<span class='line-number'>42</span>
<span class='line-number'>43</span>
<span class='line-number'>44</span>
<span class='line-number'>45</span>
<span class='line-number'>46</span>
<span class='line-number'>47</span>
<span class='line-number'>48</span>
<span class='line-number'>49</span>
<span class='line-number'>50</span>
<span class='line-number'>51</span>
<span class='line-number'>52</span>
<span class='line-number'>53</span>
<span class='line-number'>54</span>
<span class='line-number'>55</span>
<span class='line-number'>56</span>
<span class='line-number'>57</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="c"># .bashrc_ps1</span>
</span><span class='line'>
</span><span class='line'><span class="nb">export </span><span class="nv">GITBRANCH_DEFAULT</span><span class="o">=</span>master
</span><span class='line'><span class="nb">export </span><span class="nv">VIRTUALENV_DEFAULT</span><span class="o">=</span>default
</span><span class='line'>
</span><span class='line'>get_gitbranch<span class="o">()</span> <span class="o">{</span>
</span><span class='line'>    git branch 2&gt; /dev/null | sed -e <span class="s1">&#39;/^[^*]/d&#39;</span> -e <span class="s1">&#39;s/* \(.*\)/\1/&#39;</span>
</span><span class='line'><span class="o">}</span>
</span><span class='line'>
</span><span class='line'>get_virtualenv<span class="o">()</span> <span class="o">{</span>
</span><span class='line'>    <span class="k">if</span> <span class="o">[</span> -n <span class="s2">&quot;$VIRTUAL_ENV&quot;</span> <span class="o">]</span>;
</span><span class='line'>    <span class="k">then</span>
</span><span class='line'><span class="k">        </span>basename <span class="nv">$VIRTUAL_ENV</span>
</span><span class='line'>    <span class="k">fi</span>
</span><span class='line'><span class="o">}</span>
</span><span class='line'>
</span><span class='line'>get_ps1_context<span class="o">()</span> <span class="o">{</span>
</span><span class='line'>    <span class="nv">virtualenv</span><span class="o">=</span><span class="k">$(</span>get_virtualenv<span class="k">)</span>
</span><span class='line'>    <span class="nv">gitbranch</span><span class="o">=</span><span class="k">$(</span>get_gitbranch<span class="k">)</span>
</span><span class='line'>    <span class="k">if</span> <span class="o">[</span> -n <span class="s2">&quot;$virtualenv&quot;</span> <span class="o">]</span> <span class="o">||</span> <span class="o">[</span> -n <span class="s2">&quot;$gitbranch&quot;</span> <span class="o">]</span>;
</span><span class='line'>    <span class="k">then</span>
</span><span class='line'><span class="k">        </span><span class="nv">ps1</span><span class="o">=</span><span class="s2">&quot;${ps1}[&quot;</span>
</span><span class='line'>        <span class="k">if</span> <span class="o">[</span> -n <span class="s2">&quot;$virtualenv&quot;</span> <span class="o">]</span>;
</span><span class='line'>        <span class="k">then</span>
</span><span class='line'><span class="k">            </span><span class="nv">ps1</span><span class="o">=</span><span class="s2">&quot;${ps1}&quot;</span>
</span><span class='line'>            <span class="k">if</span> <span class="o">[</span> <span class="s2">&quot;$virtualenv&quot;</span> !<span class="o">=</span> <span class="nv">$VIRTUALENV_DEFAULT</span> <span class="o">]</span>;
</span><span class='line'>            <span class="k">then</span>
</span><span class='line'><span class="k">                </span><span class="nv">ps1</span><span class="o">=</span><span class="s2">&quot;${ps1}\e[0;32m&quot;</span>
</span><span class='line'>            <span class="k">fi</span>
</span><span class='line'><span class="k">            </span><span class="nv">ps1</span><span class="o">=</span><span class="s2">&quot;${ps1}${virtualenv}&quot;</span>
</span><span class='line'>            <span class="k">if</span> <span class="o">[</span> <span class="s2">&quot;$virtualenv&quot;</span> !<span class="o">=</span> <span class="nv">$VIRTUALENV_DEFAULT</span> <span class="o">]</span>;
</span><span class='line'>            <span class="k">then</span>
</span><span class='line'><span class="k">                </span><span class="nv">ps1</span><span class="o">=</span><span class="s2">&quot;${ps1}\033[0m&quot;</span>
</span><span class='line'>            <span class="k">fi</span>
</span><span class='line'><span class="k">        fi</span>
</span><span class='line'><span class="k">        if</span> <span class="o">[</span> -n <span class="s2">&quot;$virtualenv&quot;</span> <span class="o">]</span> <span class="o">&amp;&amp;</span> <span class="o">[</span> -n <span class="s2">&quot;$gitbranch&quot;</span> <span class="o">]</span>;
</span><span class='line'>        <span class="k">then</span>
</span><span class='line'><span class="k">            </span><span class="nv">ps1</span><span class="o">=</span><span class="s2">&quot;${ps1}|&quot;</span>
</span><span class='line'>        <span class="k">fi</span>
</span><span class='line'><span class="k">        if</span> <span class="o">[</span> -n <span class="s2">&quot;$gitbranch&quot;</span> <span class="o">]</span>;
</span><span class='line'>        <span class="k">then</span>
</span><span class='line'><span class="k">            if</span> <span class="o">[</span> <span class="s2">&quot;$gitbranch&quot;</span> !<span class="o">=</span> <span class="nv">$GITBRANCH_DEFAULT</span> <span class="o">]</span>;
</span><span class='line'>            <span class="k">then</span>
</span><span class='line'><span class="k">                </span><span class="nv">ps1</span><span class="o">=</span><span class="s2">&quot;${ps1}\e[0;91m&quot;</span>
</span><span class='line'>            <span class="k">fi</span>
</span><span class='line'><span class="k">            </span><span class="nv">ps1</span><span class="o">=</span><span class="s2">&quot;${ps1}${gitbranch}&quot;</span>
</span><span class='line'>            <span class="k">if</span> <span class="o">[</span> <span class="s2">&quot;$gitbranch&quot;</span> !<span class="o">=</span> <span class="nv">$GITBRANCH_DEFAULT</span> <span class="o">]</span>;
</span><span class='line'>            <span class="k">then</span>
</span><span class='line'><span class="k">                </span><span class="nv">ps1</span><span class="o">=</span><span class="s2">&quot;${ps1}\033[0m&quot;</span>
</span><span class='line'>            <span class="k">fi</span>
</span><span class='line'><span class="k">        fi</span>
</span><span class='line'><span class="k">        </span><span class="nv">ps1</span><span class="o">=</span><span class="s2">&quot;${ps1}]&quot;</span>
</span><span class='line'>        <span class="nb">printf</span> <span class="nv">$ps1</span>
</span><span class='line'>    <span class="k">fi</span>
</span><span class='line'><span class="o">}</span>
</span><span class='line'>
</span><span class='line'><span class="nv">PS1</span><span class="o">=</span><span class="s2">&quot;\n\u@\h \$(get_ps1_context): \w\n$ &quot;</span>
</span></code></pre></td></tr></table></div></figure>



]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Hello, World &#060;eom&#062;]]></title>
    <link href="http://artloder.com/blog/2014/05/17/hello-world/"/>
    <updated>2014-05-17T00:00:00-04:00</updated>
    <id>http://artloder.com/blog/2014/05/17/hello-world</id>
    <content type="html"><![CDATA[
]]></content>
  </entry>
  
</feed>
