<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="https://www.anand-iyer.com/feed.xml" rel="self" type="application/atom+xml" /><link href="https://www.anand-iyer.com/" rel="alternate" type="text/html" hreflang="en" /><updated>2026-02-19T02:36:09+00:00</updated><id>https://www.anand-iyer.com/feed.xml</id><title type="html">blank</title><entry><title type="html">Supercharge your cd command</title><link href="https://www.anand-iyer.com/blog/2018/supercharge-your-cd-command/" rel="alternate" type="text/html" title="Supercharge your cd command" /><published>2018-06-21T21:03:15+00:00</published><updated>2018-06-21T21:03:15+00:00</updated><id>https://www.anand-iyer.com/blog/2018/supercharge-your-cd-command</id><content type="html" xml:base="https://www.anand-iyer.com/blog/2018/supercharge-your-cd-command/"><![CDATA[<p>My primary use-case for command line is very simple. Most of the time, I just go
to a specific directory, and build/run something there. Rarely, I open up a
finder window, and even more rarely I might open a file in my editor.</p>

<p>The straight forward way to do such things is to first <code class="language-plaintext highlighter-rouge">cd</code> to the directory you want. Anyone who has
ever worked with Java/Scala projects knows how deeply nested the
sub directories could be, so naturally I was looking for a better solution. A
while back, I stumbled upon <a href="https://github.com/wting/autojump">autojump</a>, which is kind of a
Google’s /I’m feeling lucky/ feature for <code class="language-plaintext highlighter-rouge">cd</code>. It works great, as long as the
top ranked entry is what you want. However,
sometimes I wish I had more control over the result, specifically I wanted a
better way to interactively filter the ranked list.</p>

<p>Thankfully, I found <a href="https://github.com/junegunn/fzf">FZF</a>, a superb command
line fuzzy finder which helped me solve this problem (it is worthwhile installing FZF even if you don’t want to
read the rest of this post. It is that good.). What I did was to simply combine
FZF and <a href="https://github.com/clvv/fasd">FASD</a> (FASD is a bit
more flexible tool compared to autojump). The rest of this post assumes that you
have both of them installed. In OSX, you can use <code class="language-plaintext highlighter-rouge">brew</code> to achieve this:</p>

<figure class="highlight"><pre><code class="language-shell" data-lang="shell">brew <span class="nb">install </span>fasd fzf</code></pre></figure>

<p>Once installed, ensure that the necessary init commands are placed in your shell
rc. I use <code class="language-plaintext highlighter-rouge">zsh</code>, so I put them in my <code class="language-plaintext highlighter-rouge">.zshrc</code>. The next step is to create a
command that will combine these two and act as a replacement for the <code class="language-plaintext highlighter-rouge">cd</code>
command. For instance, if you use zsh, you can do:</p>

<figure class="highlight"><pre><code class="language-shell" data-lang="shell"><span class="nb">unalias </span>j 2&gt;/dev/null
j<span class="o">()</span> <span class="o">{</span>
    <span class="o">[</span> <span class="nv">$# </span><span class="nt">-gt</span> 0 <span class="o">]</span> <span class="o">&amp;&amp;</span> fasd_cd <span class="nt">-d</span> <span class="s2">"</span><span class="nv">$*</span><span class="s2">"</span> <span class="o">&amp;&amp;</span> <span class="k">return
    </span><span class="nb">local dir
    dir</span><span class="o">=</span><span class="s2">"</span><span class="si">$(</span>fasd <span class="nt">-Rdl</span> <span class="s2">"</span><span class="nv">$1</span><span class="s2">"</span> | fzf <span class="nt">-1</span> <span class="nt">-0</span> <span class="nt">--no-sort</span> +m<span class="si">)</span><span class="s2">"</span> <span class="o">&amp;&amp;</span> <span class="nb">cd</span> <span class="s2">"</span><span class="k">${</span><span class="nv">dir</span><span class="k">}</span><span class="s2">"</span> <span class="o">||</span> <span class="k">return </span>1
<span class="o">}</span></code></pre></figure>

<p>What this function does is to define the shell command <code class="language-plaintext highlighter-rouge">j</code>. When you use <code class="language-plaintext highlighter-rouge">j</code>
with an argument (e.g., <code class="language-plaintext highlighter-rouge">j e</code>), it simply passes the argument to <code class="language-plaintext highlighter-rouge">fasd</code> which
will take you to the first result based on the keyword (in my case, the top hit
for <code class="language-plaintext highlighter-rouge">e</code> is my <code class="language-plaintext highlighter-rouge">.emacs.d</code> directory). If I don’t use an argument to <code class="language-plaintext highlighter-rouge">j</code>, the
function takes the ranked list from <code class="language-plaintext highlighter-rouge">fasd</code> and feeds it to <code class="language-plaintext highlighter-rouge">fzf</code>, letting you
fuzzy search on the list!</p>

<p>Note that this is not limited to just the <code class="language-plaintext highlighter-rouge">cd</code> command. For example, I have defined command <code class="language-plaintext highlighter-rouge">e</code> that uses
<code class="language-plaintext highlighter-rouge">$EDITOR</code> to open a file:</p>

<figure class="highlight"><pre><code class="language-shell" data-lang="shell"><span class="nb">unalias </span>e 2&gt;/dev/null
e<span class="o">()</span> <span class="o">{</span>
    <span class="o">[</span> <span class="nv">$# </span><span class="nt">-gt</span> 0 <span class="o">]</span> <span class="o">&amp;&amp;</span> fasd <span class="nt">-f</span> <span class="nt">-e</span> <span class="k">${</span><span class="nv">EDITOR</span><span class="k">}</span> <span class="s2">"</span><span class="nv">$*</span><span class="s2">"</span> <span class="o">&amp;&amp;</span> <span class="k">return
    </span><span class="nb">local </span>file
    <span class="nv">file</span><span class="o">=</span><span class="s2">"</span><span class="si">$(</span>fasd <span class="nt">-Rfl</span> <span class="s2">"</span><span class="nv">$1</span><span class="s2">"</span> | fzf <span class="nt">-1</span> <span class="nt">-0</span> <span class="nt">--no-sort</span> +m<span class="si">)</span><span class="s2">"</span> <span class="o">&amp;&amp;</span> <span class="k">${</span><span class="nv">EDITOR</span><span class="k">}</span> <span class="s2">"</span><span class="k">${</span><span class="nv">file</span><span class="k">}</span><span class="s2">"</span> <span class="o">||</span> <span class="k">return </span>1
<span class="o">}</span></code></pre></figure>

<p>All these functions (and more) are defined in my <code class="language-plaintext highlighter-rouge">.zshrc</code>, which can be found
<a href="https://github.com/anandpiyer/.dotfiles/blob/master/.zshrc">here</a>.</p>]]></content><author><name></name></author><category term="Tips" /><summary type="html"><![CDATA[My primary use-case for command line is very simple. Most of the time, I just go to a specific directory, and build/run something there. Rarely, I open up a finder window, and even more rarely I might open a file in my editor.]]></summary></entry><entry><title type="html">A simpler way to manage your dotfiles</title><link href="https://www.anand-iyer.com/blog/2018/a-simpler-way-to-manage-your-dotfiles/" rel="alternate" type="text/html" title="A simpler way to manage your dotfiles" /><published>2018-05-05T01:01:12+00:00</published><updated>2018-05-05T01:01:12+00:00</updated><id>https://www.anand-iyer.com/blog/2018/a-simpler-way-to-manage-your-dotfiles</id><content type="html" xml:base="https://www.anand-iyer.com/blog/2018/a-simpler-way-to-manage-your-dotfiles/"><![CDATA[<p>Like most folks, I use git to manage my
<a href="https://github.com/anandpiyer/.dotfiles">dotfiles</a>. This lets me have a
versioned backup for my configurations, and if something breaks (and it does
often for me) I can revert to a working configuration fairly easily. For a long
time, I’ve followed the normal path of having a <code class="language-plaintext highlighter-rouge">dotfiles</code> folder and a script
that symlinks into the files in it from my <code class="language-plaintext highlighter-rouge">$HOME</code>. Recently, I came across
<a href="https://news.ycombinator.com/item?id=11070797">this thread in HackerNews</a> and
it literally blew my mind. In this post, I would like to share this very elegant
solution that avoids the need for any symlinking.</p>

<p>The key idea is really simple: make <code class="language-plaintext highlighter-rouge">$HOME</code> the git <code class="language-plaintext highlighter-rouge">work-tree</code>. The normal way
of doing this would be to do a <code class="language-plaintext highlighter-rouge">git init</code> in your <code class="language-plaintext highlighter-rouge">$HOME</code>, but that would
totally mess up git commands if you have other repositories in your <code class="language-plaintext highlighter-rouge">$HOME</code>
(also, you probably don’t want your entire <code class="language-plaintext highlighter-rouge">$HOME</code> in a git repo). So, instead,
we will create a dummy folder and initialize a <strong>bare</strong> repository (essentially
a git repo with <strong>no</strong> working directory) in there. All git commands will be run
with our dummy as the git directory, but <code class="language-plaintext highlighter-rouge">$HOME</code> as the work directory.</p>

<h2 id="first-time-setup">First Time Setup</h2>
<p>Setting this method up the first time is really easy. First, let’s create our
bare repository. I chose to name my placeholder <code class="language-plaintext highlighter-rouge">.dotfiles</code> (duh!)</p>

<figure class="highlight"><pre><code class="language-bash" data-lang="bash"><span class="nb">mkdir</span> <span class="nv">$HOME</span>/.dotfiles
git init <span class="nt">--bare</span> <span class="nv">$HOME</span>/.dotfiles</code></pre></figure>

<p>Now for the fun part. We will make an alias for running git commands in our
<code class="language-plaintext highlighter-rouge">.dotfiles</code> repository. I’m calling my alias <code class="language-plaintext highlighter-rouge">dotfiles</code>:</p>

<figure class="highlight"><pre><code class="language-shell" data-lang="shell"><span class="nb">alias </span><span class="nv">dotfiles</span><span class="o">=</span><span class="s1">'/usr/local/bin/git --git-dir=$HOME/.dotfiles/ --work-tree=$HOME'</span></code></pre></figure>

<p>Add this alias to your <code class="language-plaintext highlighter-rouge">.bashrc</code> or <code class="language-plaintext highlighter-rouge">.zshrc</code>. From now on, any git operation you
would like to do in the <code class="language-plaintext highlighter-rouge">.dotfiles</code> repository can be done by the <code class="language-plaintext highlighter-rouge">dotfiles</code>
alias. The cool thing is that you can run <code class="language-plaintext highlighter-rouge">dotfiles</code> from anywhere.</p>

<p>Let’s add a remote, and also set status not to show untracked files:</p>

<figure class="highlight"><pre><code class="language-shell" data-lang="shell">dotfiles config <span class="nt">--local</span> status.showUntrackedFiles no
dotfiles remote add origin git@github.com:anandpiyer/.dotfiles.git</code></pre></figure>

<p>You’ll need to change the remote URL to your git repo. Now, you can easily add the
config files you want to be in version control from where they are supposed to
be, commit and push. For example, to add <code class="language-plaintext highlighter-rouge">tmux</code> config files, I’ll do:</p>

<figure class="highlight"><pre><code class="language-shell" data-lang="shell"><span class="nb">cd</span> <span class="nv">$HOME</span>
dotfiles add .tmux.conf
dotfiles commit <span class="nt">-m</span> <span class="s2">"Add .tmux.conf"</span>
dotfiles push</code></pre></figure>

<h2 id="setting-up-a-new-machine">Setting Up a New Machine</h2>
<p>To set up a new machine to use your version controlled config files, all you
need to do is to clone the repository on your new machine telling git that it is
a bare repository:</p>

<figure class="highlight"><pre><code class="language-shell" data-lang="shell">git clone <span class="nt">--separate-git-dir</span><span class="o">=</span><span class="nv">$HOME</span>/.dotfiles https://github.com/anandpiyer/.dotfiles.git ~</code></pre></figure>

<p>However, some programs create default config files, so this might fail if git
finds an existing config file in your <code class="language-plaintext highlighter-rouge">$HOME</code>. In that case, a simple solution
is to clone to a temporary directory, and then delete it once you are done:</p>

<figure class="highlight"><pre><code class="language-shell" data-lang="shell">git clone <span class="nt">--separate-git-dir</span><span class="o">=</span><span class="nv">$HOME</span>/.dotfiles https://github.com/anandpiyer/.dotfiles.git tmpdotfiles
rsync <span class="nt">--recursive</span> <span class="nt">--verbose</span> <span class="nt">--exclude</span> <span class="s1">'.git'</span> tmpdotfiles/ <span class="nv">$HOME</span>/
<span class="nb">rm</span> <span class="nt">-r</span> tmpdotfiles</code></pre></figure>

<p>There you go. No symlink mess.</p>

<p>My dotfiles are <a href="https://github.com/anandpiyer/.dotfiles">here</a> for reference.</p>]]></content><author><name></name></author><category term="Tips" /><summary type="html"><![CDATA[Like most folks, I use git to manage my dotfiles. This lets me have a versioned backup for my configurations, and if something breaks (and it does often for me) I can revert to a working configuration fairly easily. For a long time, I’ve followed the normal path of having a dotfiles folder and a script that symlinks into the files in it from my $HOME. Recently, I came across this thread in HackerNews and it literally blew my mind. In this post, I would like to share this very elegant solution that avoids the need for any symlinking.]]></summary></entry><entry><title type="html">Fixing Google Voice in OBi100 with FreePBX</title><link href="https://www.anand-iyer.com/blog/2017/fixing-google-voice-in-obi100-with-freepbx/" rel="alternate" type="text/html" title="Fixing Google Voice in OBi100 with FreePBX" /><published>2017-12-15T17:26:12+00:00</published><updated>2017-12-15T17:26:12+00:00</updated><id>https://www.anand-iyer.com/blog/2017/fixing-google-voice-in-obi100-with-freepbx</id><content type="html" xml:base="https://www.anand-iyer.com/blog/2017/fixing-google-voice-in-obi100-with-freepbx/"><![CDATA[<p>OBIHAI recently <a href="http://blog.obihai.com/2017/11/end-of-line-for-google-voice-on-obi100.html">announced</a> the end of support for their 100/110 product line. This means no more firmware updates for this device. Unfortunately, this translates to loss of Google Voice functionality for many users, since the device will fail when trying to connect to Google Voice with an error “<em>Backing Off : TCP connection to XXX.XXX.XXX.XXX failed</em>”. In this post, I’ll discuss a simple solution to recover Google Voice functionality. All you need is an old laptop or a desktop that is connected to your router via ethernet. Let’s get started!</p>

<h3 id="step-1-install-freepbx--asterix">Step 1: Install FreePBX &amp; Asterix</h3>

<p>The first thing we are going to do is to wipe the old system and install FreePBX and Asterisk. To do so:</p>

<ul>
  <li><a href="https://www.freepbx.org/downloads/">Download the FreePBX distribution</a>. I used version SNG7-PBX-64bit-1710-1 which bundles FreePBX 14 along with Asterisk 13, 14 or 15.</li>
  <li>Use <a href="https://unetbootin.github.io/">UNetbootin</a> or <a href="http://etcher.io/">Etcher</a> to create a bootable USB from the ISO image you downloaded and install it. During installation, you will be asked to choose the version of Asterisk. I chose the recommended combination (FreePBX 14 with Asterisk 13).</li>
  <li>You will need to create root password, remember this password.</li>
  <li>After the installation is completed, reboot the system and login using username <code class="language-plaintext highlighter-rouge">root</code> and the password you set earlier. You will then be presented with the web address of the FreePBX GUI.</li>
</ul>

<h3 id="step-2-configuring-freepbx">Step 2: Configuring FreePBX</h3>

<p>We now need to configure our FreePBX installation for use with Google Voice. In a different laptop/desktop, open the FreePBX GUI in a browser window. You will be asked to create an admin user the first time. Once logged in:</p>

<ul>
  <li>It is recommended that you activate your FreePBX (free to do so). Once activated, you can access <code class="language-plaintext highlighter-rouge">Admin -&gt; System Admin</code> where you will be able to do many things, including setting a static IP for your FreePBX installation.</li>
  <li>Go to <code class="language-plaintext highlighter-rouge">Admin -&gt; Updates</code> and click <code class="language-plaintext highlighter-rouge">Module Updates</code>. Select <code class="language-plaintext highlighter-rouge">Standard</code>, <code class="language-plaintext highlighter-rouge">Unsupported</code> and <code class="language-plaintext highlighter-rouge">Extended</code> in repositories, and click on <code class="language-plaintext highlighter-rouge">Check Online</code>. The page will reload with your selection. Scroll down to <strong>Connectivity</strong> where you will be able to see <code class="language-plaintext highlighter-rouge">Google Voice/Chan Motif</code>. Click on it, select <code class="language-plaintext highlighter-rouge">Download and Install</code>. Scroll back up to the top of the page, and click on <code class="language-plaintext highlighter-rouge">Process</code>. The system will download and install the Google Voice motif. If an <code class="language-plaintext highlighter-rouge">Apply Settings</code> button appears at the top in red, click on it (do this every time this button appears).</li>
  <li>Go to <code class="language-plaintext highlighter-rouge">Application -&gt; Extensions</code> and add a new PJSIP extension. Fill in name (e.g., <strong>100</strong>), and a secret. Leave everything else to their default values and submit followed by apply settings.</li>
  <li>Go to <code class="language-plaintext highlighter-rouge">Connectivity -&gt; Google Voice</code> and fill in your Google Voice username, password and number. Check <code class="language-plaintext highlighter-rouge">Add Trunk</code>, <code class="language-plaintext highlighter-rouge">Add Outbound Routes</code> and <code class="language-plaintext highlighter-rouge">Send Unanswered to Google Voicemail</code>. Once you submit and apply, check back the entry (the top right of the page will list your newly created entry). You should see the status as <strong>Connected</strong>. If you don’t, try enabling access to less secure apps in your Google account and retry.</li>
  <li>Go to <code class="language-plaintext highlighter-rouge">Connectivity -&gt; Inbound Routes</code>. Add a new inbound route. In the <strong>DID</strong> field, put in your Google Voice number (10 digits only, e.g. 1234567890). In the <strong>Set Destination</strong> field, choose <strong>Extension</strong> and select the PJSIP extension we created earlier.</li>
  <li>At this point, you are ready to check if all this works. Install an SIP client (e.g., Zoiper SIP Softphone) on your phone, add your FreePBX IP as the SIP server. User will be the extension you created (e.g., 100), and the password will be the secret you set on this extension. Try making a call, it should go through Google Voice. If you call your Google Voice number, the SIP client should get the call. If both work, you are set.</li>
</ul>

<h3 id="step-3-configuring-obi100110">Step 3: Configuring OBi100/110</h3>

<p>Finally, let us point  the OBi device to your FreePBX server.</p>

<ul>
  <li>Login to OBITalk, and remove the (defunct) Google Voice entry.</li>
  <li>Recreate SP1 as a <strong>Generic Service Provider</strong>. Check <code class="language-plaintext highlighter-rouge">Primary Line for Outgoing Calls</code>. Use the FreePBX IP address as the proxy server, and 5060 as the port. Username and password would be from the extension you created in FreePBX (e.g. 100). Save it, and go to your dashboard. You should see <strong>Registered</strong> in the status.</li>
  <li>Now you should be able to make and receive calls via Google Voice through your OBi!</li>
</ul>]]></content><author><name></name></author><category term="Tips" /><summary type="html"><![CDATA[OBIHAI recently announced the end of support for their 100/110 product line. This means no more firmware updates for this device. Unfortunately, this translates to loss of Google Voice functionality for many users, since the device will fail when trying to connect to Google Voice with an error “Backing Off : TCP connection to XXX.XXX.XXX.XXX failed”. In this post, I’ll discuss a simple solution to recover Google Voice functionality. All you need is an old laptop or a desktop that is connected to your router via ethernet. Let’s get started!]]></summary></entry><entry><title type="html">Research Literature Management with Emacs</title><link href="https://www.anand-iyer.com/blog/2017/research-literature-management-with-emacs/" rel="alternate" type="text/html" title="Research Literature Management with Emacs" /><published>2017-07-12T21:26:12+00:00</published><updated>2017-07-12T21:26:12+00:00</updated><id>https://www.anand-iyer.com/blog/2017/research-literature-management-with-emacs</id><content type="html" xml:base="https://www.anand-iyer.com/blog/2017/research-literature-management-with-emacs/"><![CDATA[<p>A major activity in the daily routine of a graduate student is reading a lot of
literature. Obviously, this results in a huge pile of papers to manage over time
and hence it is unsurprising that we seek out a literature management solution
atleast once during our graduate life. Fortunately, there
are
<a href="http://www.mendeley.com">several</a> <a href="http://www.readcube.com">excellent</a> <a href="http://www.zotero.org">solutions</a> today
that addresses this problem. I’ve tried many of them, but finally settled
on something that works for me. This post describes my current workflow;
hopefully it will be useful for someone else too.</p>

<p>At a high-level, my literature management system is really simple. I keep a
bibliography file to which I add papers that I find interesting. For each entry
in this file, I link two things: the PDF of the paper, and notes on the paper.
With this setting, I can quickly search for an entry, find the PDF and/or notes
for the matching entry. All this is made possible by Emacs, with the help of a
few packages. Let me explain this in a bit of details.</p>

<h3 id="basic-setup">Basic Setup</h3>
<p>The first thing to do is to set up a few basic things. As I mentioned, I have
one bibliography file where I want new entries to go. I also need a folder to
store all the PDFs and a way to store notes on each of these entries. For this
task, I leverage the <a href="https://github.com/jkitchin/org-ref"><strong>org-ref</strong></a> package.
Here’s my org-ref setup:</p>

<figure class="highlight"><pre><code class="language-lisp" data-lang="lisp"><span class="p">(</span><span class="k">setq</span> <span class="nv">org-ref-bibliography-notes</span> <span class="s">"~/org/ref/notes.org"</span>
      <span class="nv">org-ref-default-bibliography</span> <span class="o">'</span><span class="p">(</span><span class="s">"~/org/ref/master.bib"</span><span class="p">)</span>
      <span class="nv">org-ref-pdf-directory</span> <span class="s">"~/org/ref/pdfs/"</span><span class="p">)</span></code></pre></figure>

<p>The code should be self-explanatory: bibliography entries are stored in a file
named <code class="language-plaintext highlighter-rouge">master.bib</code>, while PDF files corresponding to the entries go in the
<code class="language-plaintext highlighter-rouge">pdfs</code> folder. I chose to store my notes in a single org file <code class="language-plaintext highlighter-rouge">notes.org</code>. Note
that it is entirely possible to have separate note files for every entry in your
bibliography file. My <code class="language-plaintext highlighter-rouge">org</code> folder is synced with a cloud storage service.</p>

<h3 id="adding-entries">Adding Entries</h3>
<p>When I come across a paper that I’m interested in reading, I add it to
<code class="language-plaintext highlighter-rouge">master.bib</code>. Most of the time, I can <em>simply drag-and-drop the paper link or
DOI</em> to the bibliography file and let org-ref take care of creating the entry
and downloading the PDF. Otherwise, I simply copy the bibtex entry and then run
<code class="language-plaintext highlighter-rouge">doi-utils-get-bibtex-entry-pdf</code> to get the PDF.</p>

<p>Once I decide to read (and make notes on) a paper that is in my bibliography
file, I then proceed to make an entry for it in my <code class="language-plaintext highlighter-rouge">notes.org</code> file. I do this in
either of two ways: if I have the <code class="language-plaintext highlighter-rouge">master.bib</code> file open, I can simply go to the
entry I want to read, and then use the <code class="language-plaintext highlighter-rouge">org-ref-open-bibtex-notes</code> command. As
the name suggests, this command opens the corresponding notes entry in the
<code class="language-plaintext highlighter-rouge">org-ref-bibliography-notes</code> file, creating a new entry if it can’t find one. If
I don’t have the <code class="language-plaintext highlighter-rouge">master.bib</code> file open, I use the excellent <code class="language-plaintext highlighter-rouge">helm-bibtex</code>
package to search through my bibliography files. When I find the entry I’m
looking for, I open notes (or create it) with helm’s available
actions on the selected entry. For this to work, we
need to let <code class="language-plaintext highlighter-rouge">helm-bibtex</code> know where the notes and PDF files are:</p>

<figure class="highlight"><pre><code class="language-lisp" data-lang="lisp"><span class="p">(</span><span class="k">setq</span> <span class="nv">bibtex-completion-bibliography</span> <span class="s">"~/org/ref/master.bib"</span><span class="p">)</span>
      <span class="nv">bibtex-completion-library-path</span> <span class="s">"~/org/ref/pdfs"</span>
      <span class="nv">bibtex-completion-notes-path</span> <span class="s">"~/org/ref/notes.org"</span><span class="err">)</span> </code></pre></figure>

<p>You can customize the fields in the entry created in <code class="language-plaintext highlighter-rouge">notes.org</code> by both
<code class="language-plaintext highlighter-rouge">org-ref</code> and <code class="language-plaintext highlighter-rouge">helm-bibtex</code> to your liking.</p>

<h3 id="taking-notes">Taking Notes</h3>
<p>Now that I have an entry in my <code class="language-plaintext highlighter-rouge">notes.org</code> file for the paper that I want to
read, the next step is to take notes as I read. You can simply type down your
thoughts below the entry in <code class="language-plaintext highlighter-rouge">notes.org</code>, but I like seeing the notes
side-by-side with the page on which it was made. For this purpose, I use
the <a href="https://github.com/rudolfochrist/interleave"><strong>interleave</strong></a> package. To
use the <code class="language-plaintext highlighter-rouge">interleave</code> package, all I need to do is to add the <code class="language-plaintext highlighter-rouge">INTERLEAVE_PDF</code>
property to the <code class="language-plaintext highlighter-rouge">PROPERTIES</code> section of the entry in my <code class="language-plaintext highlighter-rouge">notes.org</code> file. Then,
to open the PDF, I place the cursor on the title, and invoke <code class="language-plaintext highlighter-rouge">interleave-mode</code>
command. This will display the PDF side-by-side with my notes, where I can
navigate, see or add notes on any page.</p>

<h3 id="searching">Searching</h3>
<p>The combination of <code class="language-plaintext highlighter-rouge">org-ref</code>, <code class="language-plaintext highlighter-rouge">helm-bibtex</code> and <code class="language-plaintext highlighter-rouge">interleave</code> gives me great
flexibility. I can easily search for entries in my bibliography files using
<code class="language-plaintext highlighter-rouge">helm-bibtex</code>. From there, I can open the paper and/or its notes. Since I use
Emacs to write papers, <code class="language-plaintext highlighter-rouge">org-ref</code> makes it easy to insert citations, look up
notes and download papers as I write. Having the notes in plain text lets me
search through them easily. Finally, as a bonus, <code class="language-plaintext highlighter-rouge">org</code> mode lets me easily
export my notes in several formats.</p>

<p>To summarize, having the literature management system tightly coupled with my paper
writing environment (Emacs with AUCTeX) worked quite well for me.</p>]]></content><author><name></name></author><category term="Tips" /><summary type="html"><![CDATA[A major activity in the daily routine of a graduate student is reading a lot of literature. Obviously, this results in a huge pile of papers to manage over time and hence it is unsurprising that we seek out a literature management solution atleast once during our graduate life. Fortunately, there are several excellent solutions today that addresses this problem. I’ve tried many of them, but finally settled on something that works for me. This post describes my current workflow; hopefully it will be useful for someone else too.]]></summary></entry><entry><title type="html">Managing Finances in Grad School</title><link href="https://www.anand-iyer.com/blog/2014/managing-finances-in-gradschool/" rel="alternate" type="text/html" title="Managing Finances in Grad School" /><published>2014-12-20T08:25:00+00:00</published><updated>2014-12-20T08:25:00+00:00</updated><id>https://www.anand-iyer.com/blog/2014/managing-finances-in-gradschool</id><content type="html" xml:base="https://www.anand-iyer.com/blog/2014/managing-finances-in-gradschool/"><![CDATA[<p>Managing finances is one of the biggest challenges for a graduate student. This is especially true in the case of students with a family. This post is an attempt to summarize a few things that worked for me in getting my finances under control. Although this post is written with married graduate students in mind, I believe it is as useful, if not more, for others as well.</p>

<ul>
  <li>
    <p><strong>Track your cash flow</strong>. You should know where your money is going. I use <a href="https://www.mint.com" target="_blank">Mint</a> and <a href="https://www.talkable.com/x/NXVL0R" target="_blank">Personal Capital</a> for this purpose.</p>
  </li>
  <li>
    <p>Once you understand your spending patterns, <strong>create a budget</strong>. Have a goal in mind when creating the budget. For instance, my goal is to save a particular amount of money from every pay check. The good folks at YNAB is giving away their highly acclaimed software, You Need A Budget (YNAB), for <a href="http://www.youneedabudget.com/blog/2014/ynab-is-now-free-for-college-students/" target="_blank">free for students</a>.</p>
  </li>
  <li>
    <p>It is hard, but make efforts to <strong>stick with your budget</strong>. <a href="https://levelmoney.com" target="_blank">Level</a> app helps me with this, it shows me how much I can spend without going over my budget.</p>
  </li>
  <li>
    <p>Bank with an institution that does not ridicule you with miniscule rates and outrageous maintenance fee. I use <a href="http://www.ally.com/bank/online-savings-account/" target="_blank">Ally</a> bank.</p>
  </li>
  <li>
    <p>If you manage to save money, <strong>invest your savings</strong>. With long-term
inflation rate <a href="https://ycharts.com/indicators/us_inflation_rate" target="_blank">above 3%</a>, a savings account is a bad investment choice.
<a href="https://wisebanyan.com/r/yPHVSiMvT" target="_blank">WiseBanyan</a> lets you invest as low as $10 a month in a
combination of stock and bond ETFs for free. <a href="http://share.robinhood.com/anandp" target="_blank">Robinhood</a> lets you trade stocks for free. The stock market has returned an
average of <a href="http://pages.stern.nyu.edu/~adamodar/New_Home_Page/datafile/histretSP.html" target="_blank">over 7%</a> historically. Assuming this holds in the future,
investing $500 every month will make your net worth exceed the <a href="http://money.cnn.com/2014/06/11/news/economy/middle-class-wealth/" target="_blank">median American middle class</a> by the time you graduate!</p>
  </li>
  <li>
    <p>Sign up for good cashback credit cards such as the Chase Freedom card. If you have more than one credit card, an interesting app to use is <a href="https://www.walla.by" target="_blank">Wallaby</a>, which tells you the best card to use when you shop.</p>
  </li>
  <li>
    <p>Cellphone service is a basic necessity, but gone are those days when you had to spend a fortune on a decent plan. For the frugal folks, <a href="https://www.freedompop.com" target="_blank">FreedomPop</a> offers <strong>FREE</strong> service.</p>
  </li>
  <li>
    <p>While it is convenient to order things from Amazon and have it delivered to your home, many everyday essentials such as toothpaste, mouthwash, soap, body wash etc can be obtained absolutely <em>free</em> if you are willing to <strong>do a little bit of couponing</strong> along with some help from store specific blogs such as <a href="http://www.iheartcvs.com" target="_blank">IHeartCVS</a> and <a href="http://www.iheartwags.com" target="_blank">IHeartWags</a>. However, I must warn you that couponing is very additctive.</p>
  </li>
</ul>]]></content><author><name></name></author><category term="Finance" /><summary type="html"><![CDATA[Managing finances is one of the biggest challenges for a graduate student. This is especially true in the case of students with a family. This post is an attempt to summarize a few things that worked for me in getting my finances under control. Although this post is written with married graduate students in mind, I believe it is as useful, if not more, for others as well.]]></summary></entry><entry><title type="html">Fixing missing bootcamp partition in OSX</title><link href="https://www.anand-iyer.com/blog/2014/fixing-missing-bootcamp-partition-in-osx/" rel="alternate" type="text/html" title="Fixing missing bootcamp partition in OSX" /><published>2014-05-28T08:25:00+00:00</published><updated>2014-05-28T08:25:00+00:00</updated><id>https://www.anand-iyer.com/blog/2014/fixing-missing-bootcamp-partition-in-osx</id><content type="html" xml:base="https://www.anand-iyer.com/blog/2014/fixing-missing-bootcamp-partition-in-osx/"><![CDATA[<p><strong>Symptom:</strong> You use Bootcamp to dual-boot OSX and Windows. After installing Windows, you are not able to see the BOOTCAMP partition in OSX. If you try viewing the disk using disk utility, the BOOTCAMP partition is greyed out, and shows up as FAT formatted although it is NTFS formatted.</p>

<p>Turns out the issue occurs because of a modification during Windows installation. Once Bootcamp Assistant (BCA) created the BOOTCAMP partition and restarted the system, I noticed that there was an additional small-sized partition created (~600MB) just before the BOOTCAMP partition. Instead of ignoring it, I deleted and recreated the bootcamp partition from Windows setup hoping the wasted space would be reclaimed. That was a bad idea.</p>

<p>When you do this, it confuses the hybrid GPT/MBR partitioning scheme used by BCA. Essentially, when you remove/resize/add partitions via Windows setup, that information gets updated in the MBR record, but is not synced to the GPT record. Thus, Windows will see the OSX partition, but not vice-versa.</p>

<p>The easy way to fix this without going through the pain of removing and reinstalling Windows from scratch is to sync the MBR info back to the GPT record. Here’s how to do it:</p>

<p>First, we need detailed information on the MBR record—where the partition starts, where it ends etc. For this purpose, use the <code class="language-plaintext highlighter-rouge">gptsync</code> tool. Homebrew has the gptsync package, but if you try to use it, you’ll end up with the following error:</p>

<figure class="highlight"><pre><code class="language-bash" data-lang="bash">    Warning: Unknown GPT spec revision 0x00010000 </code></pre></figure>

<p>This is because of 64-bit incompatability. A fixed version of gptsync aimed at OSX, extracted from rEFIt is available <a href="https://github.com/JrCs/gptsync">here</a>. Just compile it using Xcode, and you’re good to go.</p>

<p>Running <code class="language-plaintext highlighter-rouge">gptsync</code> on my machine resulted in the following:</p>

<figure class="highlight"><pre><code class="language-bash" data-lang="bash">    <span class="o">&gt;</span> ./gptsync /dev/disk0
    
    Current GPT partition table:
     <span class="c">#      Start LBA      End LBA  Type</span>
     1             40       409639  EFI System <span class="o">(</span>FAT<span class="o">)</span>
     2         409640    250801735  Mac OS X HFS+
     3      250801736    252071271  Mac OS X Boot
     4      252071936    500117503  Basic Data

    Current MBR partition table:
     <span class="c"># A    Start LBA      End LBA  Type</span>
     1              1       409639  ee  EFI Protective
     2         409640    250801735  af  Mac OS X HFS+
     3 <span class="k">*</span>    250802176    251518975  07  NTFS/HPFS
     4      251518976    500115455  07  NTFS/HPFS   </code></pre></figure>

<p>In the scenario above, the solution was to modify the GPT table to match the MBR table. Essentially, delete partitions 3 and 4, and then recreate it as per MBR. For this purpose, I used the gdisk tool available <a href="http://www.rodsbooks.com/gdisk/">here</a>. Once installed, run the tool (usage instructions are similar to fdisk, tutorial is available on the tool’s website). I used <code class="language-plaintext highlighter-rouge">d</code> command to delete partitions 3 and 4, <code class="language-plaintext highlighter-rouge">n</code> command to recreate them with first sector and last sector noted from MBR and type 0700. Once done, check the changes using command <code class="language-plaintext highlighter-rouge">p</code>, and verify for errors using <code class="language-plaintext highlighter-rouge">v</code>. If there are no errors, confirm the changes by writing them with command <code class="language-plaintext highlighter-rouge">w</code>, reboot and enjoy!</p>]]></content><author><name></name></author><category term="Tips" /><summary type="html"><![CDATA[Symptom: You use Bootcamp to dual-boot OSX and Windows. After installing Windows, you are not able to see the BOOTCAMP partition in OSX. If you try viewing the disk using disk utility, the BOOTCAMP partition is greyed out, and shows up as FAT formatted although it is NTFS formatted.]]></summary></entry><entry><title type="html">Re-signing IPA files</title><link href="https://www.anand-iyer.com/blog/2013/re-signing-ipa-files/" rel="alternate" type="text/html" title="Re-signing IPA files" /><published>2013-03-28T23:49:00+00:00</published><updated>2013-03-28T23:49:00+00:00</updated><id>https://www.anand-iyer.com/blog/2013/re-signing-ipa-files</id><content type="html" xml:base="https://www.anand-iyer.com/blog/2013/re-signing-ipa-files/"><![CDATA[<p>Scenario: You have an IPA that you want to test on a device, but the IPA was generated using a provisioning profile that does not include the device, and was signed with a certificate that is not yours. You drag this IPA to XCode’s organizer window hoping it would be installed on the connected device, but this results in an <code class="language-plaintext highlighter-rouge">Unknown error</code>.</p>

<p>Turns out that this is easy to fix. Here’s how to make it work.</p>

<p>First, unpack the IPA (<code class="language-plaintext highlighter-rouge">unzip -q &lt;IPA&gt;</code>). This would create a directory named <code class="language-plaintext highlighter-rouge">Payload</code> and a few other files. Delete the existing signature in the extracted package:</p>

<figure class="highlight"><pre><code class="language-bash" data-lang="bash">    <span class="nb">rm</span> <span class="nt">-rf</span> <span class="s2">"Payload/*.app/_CodeSignature"</span> <span class="s2">"Payload/*.app/CodeResources"</span></code></pre></figure>

<p>For the next step, you need two things: a valid provisioning profile and a valid certificate. Both can be obtained via the iOS developer portal.</p>

<p>Replace the provisioning profile first</p>

<figure class="highlight"><pre><code class="language-bash" data-lang="bash">    <span class="nb">cp</span> &lt;PROVISIONING_PROFILE&gt; <span class="s2">"Payload/*.app/embedded.mobileprovision"</span></code></pre></figure>

<p>Then resign using your certificate (the certificate must be present in your keychain)</p>

<figure class="highlight"><pre><code class="language-bash" data-lang="bash">    /usr/bin/codesign <span class="nt">-f</span> <span class="nt">-s</span> <span class="s2">"&lt;CERTIFICATE&gt;"</span> <span class="nt">--resource-rules</span> <span class="s2">"Payload/*.app/ResourceRules.plist"</span> <span class="s2">"Payload/*.app"</span></code></pre></figure>

<p>Now you can recreate the IPA and then drag &amp; drop it in the XCode organizer to install it on the device!</p>

<figure class="highlight"><pre><code class="language-bash" data-lang="bash">    zip <span class="nt">-qr</span> &lt;IPA_resigned&gt; Payload</code></pre></figure>

<p><strong>Edit:</strong> If you are looking for user friendly options, check out the <a href="http://floatlearning.com/2011/11/re-signing-an-ios-app-without-xcode/" target="_blank">script by Daniel</a> or the <a href="http://www.gorbster.net/blog/archives/273" target="_blank">app by Brian</a>.</p>]]></content><author><name></name></author><category term="Tips" /><summary type="html"><![CDATA[Scenario: You have an IPA that you want to test on a device, but the IPA was generated using a provisioning profile that does not include the device, and was signed with a certificate that is not yours. You drag this IPA to XCode’s organizer window hoping it would be installed on the connected device, but this results in an Unknown error.]]></summary></entry><entry><title type="html">Gnuplot cairo terminal errors in Mountain Lion</title><link href="https://www.anand-iyer.com/blog/2013/gnuplot-cairo-terminal-errors-in-mountain-lion/" rel="alternate" type="text/html" title="Gnuplot cairo terminal errors in Mountain Lion" /><published>2013-03-17T20:31:00+00:00</published><updated>2013-03-17T20:31:00+00:00</updated><id>https://www.anand-iyer.com/blog/2013/gnuplot-cairo-terminal-errors-in-mountain-lion</id><content type="html" xml:base="https://www.anand-iyer.com/blog/2013/gnuplot-cairo-terminal-errors-in-mountain-lion/"><![CDATA[<p>I love the cairo terminal in gnuplot, it creates amazing plots. My recent upgrade to Mountain Lion broke my homebrew based gnuplot installation, throwing a bunch of glib errors when I set the terminal to pdfcairo or pngcairo (normal terminals work fine):</p>

<figure class="highlight"><pre><code class="language-bash" data-lang="bash">    Error: GLib-GObject-CRITICAL <span class="k">**</span>: gtype.c:2720: You forgot to call g_type_init<span class="o">()</span> </code></pre></figure>

<p>This is essentially an issue with the latest version of Pango package. There are two ways to fix this:</p>

<ul>
  <li>Force homebrew to go back to a lower version of Pango; this error seems to appear in versions 1.32.6 or later.</li>
  <li>Patch the gnuplot installation’s Cairo terminal as suggested <a href="https://github.com/mxcl/homebrew/pull/18528" target="_blank">here</a>.</li>
</ul>

<p><strong>Note:</strong> If you are not getting cairo terminals in your gnuplot installation, reinstall it with cairo option enabled: <code class="language-plaintext highlighter-rouge">brew install gnuplot --cairo</code></p>]]></content><author><name></name></author><category term="Tips" /><summary type="html"><![CDATA[I love the cairo terminal in gnuplot, it creates amazing plots. My recent upgrade to Mountain Lion broke my homebrew based gnuplot installation, throwing a bunch of glib errors when I set the terminal to pdfcairo or pngcairo (normal terminals work fine):]]></summary></entry><entry><title type="html">Latex Tips Collection</title><link href="https://www.anand-iyer.com/blog/2013/latex-tips-collection/" rel="alternate" type="text/html" title="Latex Tips Collection" /><published>2013-01-13T15:56:30+00:00</published><updated>2013-01-13T15:56:30+00:00</updated><id>https://www.anand-iyer.com/blog/2013/latex-tips-collection</id><content type="html" xml:base="https://www.anand-iyer.com/blog/2013/latex-tips-collection/"><![CDATA[<p>Over time, I’ve come across many useful Latex tips and tricks scattered across the internet. Here’s an attempt to collect some of those:</p>

<ul>
  <li>
    <p><strong><a href="http://gurmeet.net/computer-science/latex-tips-n-tricks-for-conference-papers/">Tips for Conference Papers</a> by Gurmeet Singh</strong></p>

    <p>A nice set of tricks that saves your life at the last minute during deadlines.</p>
  </li>
  <li>
    <p><strong><a href="http://www.read.seas.harvard.edu/~kohler/latex.html">Latex Usage Notes</a> by Eddie Kohler</strong></p>

    <p>Solutions for common Latex problems, tips on proper formatting, etc.</p>
  </li>
  <li>
    <p><strong><a href="http://www.tablesgenerator.com">Table Generator</a></strong></p>

    <p>Easy way to generate latex source code for tables, supports booktabs style too!</p>
  </li>
  <li>
    <p><strong><a href="http://detexify.kirelabs.org/classify.html">Detexify</a></strong></p>

    <p>Find latex symbols by simply drawing them. Huge time saver when you are working on a deadline.</p>
  </li>
</ul>]]></content><author><name></name></author><category term="Tips" /><category term="latex" /><summary type="html"><![CDATA[Over time, I’ve come across many useful Latex tips and tricks scattered across the internet. Here’s an attempt to collect some of those: Tips for Conference Papers by Gurmeet Singh A nice set of tricks that saves your life at the last minute during deadlines.]]></summary></entry><entry><title type="html">Syncing folders outside Dropbox folder</title><link href="https://www.anand-iyer.com/blog/2012/syncing-folders-outside-dropbox-folder/" rel="alternate" type="text/html" title="Syncing folders outside Dropbox folder" /><published>2012-10-16T06:25:03+00:00</published><updated>2012-10-16T06:25:03+00:00</updated><id>https://www.anand-iyer.com/blog/2012/syncing-folders-outside-dropbox-folder</id><content type="html" xml:base="https://www.anand-iyer.com/blog/2012/syncing-folders-outside-dropbox-folder/"><![CDATA[<p>A big complaint I have about <a href="http://db.tt/VZd1Zsgp">Dropbox</a> is that unlike <a href="https://www.sugarsync.com/referral?rf=fevam6f0oyxab&amp;utm_source=website&amp;utm_medium=web&amp;utm_campaign=referral&amp;shareEvent=2630716">SugarSync</a>, it doesn’t allow me to sync any folder in my computer (essentially, I need to place the folders I want to be synced inside the “Dropbox” folder).</p>

<p>Recently, I found a workaround for this problem. Here’s the trick to syncing any folder in your computer: softlink the folder to your Dropbox folder!</p>

<p>If you’re using a Mac (or Linux), just use the following command:</p>

<figure class="highlight"><pre><code class="language-bash" data-lang="bash">    <span class="nb">ln</span> -s /full-path-to-folder/file-to-sync ~/Dropbox/desired-folder-name</code></pre></figure>

<p>That’s it, from now on, all file(s) in the actual path would now sync with Dropbox.</p>]]></content><author><name></name></author><category term="Tips" /><category term="any folder" /><category term="dropbox" /><category term="sugarsync" /><summary type="html"><![CDATA[A big complaint I have about Dropbox is that unlike SugarSync, it doesn’t allow me to sync any folder in my computer (essentially, I need to place the folders I want to be synced inside the “Dropbox” folder).]]></summary></entry></feed>