<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Posts on jonathanchu.is</title>
    <link>https://jonathanchu.is/posts/</link>
    <description>Recent content in Posts on jonathanchu.is</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-us</language>
    <managingEditor>Jonathan Chu</managingEditor>
    <webMaster>Jonathan Chu</webMaster>
    <lastBuildDate>Sun, 08 Feb 2026 00:00:00 -0500</lastBuildDate>
    <atom:link href="https://jonathanchu.is/posts/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Introducing magit-gh</title>
      <link>https://jonathanchu.is/posts/introducing-magit-gh/</link>
      <pubDate>Sun, 08 Feb 2026 00:00:00 -0500</pubDate>
      <author>Jonathan Chu</author>
      <guid>https://jonathanchu.is/posts/introducing-magit-gh/</guid>
      <description>&lt;p&gt;After recently releasing &lt;a href=&#34;https://github.com/jonathanchu/magit-git-toolbelt&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;magit-git-toolbelt&lt;/a&gt;, a Transient interface for &lt;a href=&#34;https://github.com/nvie/git-toolbelt&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;git-toolbelt&lt;/a&gt; in &lt;a href=&#34;https://github.com/magit/magit&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;magit&lt;/a&gt;, I&amp;rsquo;m happy to share another Magit extension I&amp;rsquo;ve been working on &amp;ndash; &lt;a href=&#34;https://github.com/jonathanchu/magit-gh&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;magit-gh&lt;/a&gt;, an Emacs package that integrates the &lt;a href=&#34;https://cli.github.com&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;GitHub CLI&lt;/a&gt; (&lt;code&gt;gh&lt;/code&gt;) into &lt;a href=&#34;https://magit.vc/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Magit&lt;/a&gt;. Similar to my former package, it provides a Transient menu interface to list, checkout, and view pull requests directly from Emacs without leaving your workflow.&lt;/p&gt;
&lt;h2 id=&#34;why-i-wrote-this&#34;&gt;
  Why I wrote this
  &lt;a class=&#34;heading-link&#34; href=&#34;#why-i-wrote-this&#34;&gt;
    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;
    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;
  &lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;If you work with pull requests on GitHub every day, you know the git checkout dance: you&amp;rsquo;re deep in flow and in a Magit buffer, you need to check on a PR, so you switch to a browser, find the repo, navigate to the PR tab, and then maybe come back to checkout the branch in eshell or even your terminal. It&amp;rsquo;s a small context switch, but it adds up.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/magit/forge&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Forge&lt;/a&gt; has been the defacto and established solution for this and it&amp;rsquo;s a fantastic and comprehensive package for interacting with Git forges from within Magit &amp;ndash; it has all the bells and whistles for this workflow. If you need deep integration &amp;ndash; tracking issues, managing pull requests, reading and writing comments, all stored locally in a light database &amp;ndash; Forge is the right tool. &lt;strong&gt;I would highly recommend Forge over this package if that is your use case&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;magit-gh&lt;/code&gt; takes a different approach. It delegates to the &lt;a href=&#34;https://cli.github.com&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;GitHub CLI&lt;/a&gt; (&lt;code&gt;gh&lt;/code&gt;) for all GitHub interaction, which means:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;No local database&lt;/strong&gt; &amp;ndash; Forge maintains a local SQLite database via &lt;code&gt;emacsql&lt;/code&gt;, which can be tricky to set up (compiling native modules, resolving binary availability issues). &lt;code&gt;magit-gh&lt;/code&gt; stores nothing locally.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;No token management&lt;/strong&gt; &amp;ndash; Forge requires a GitHub personal access token stored in your &lt;code&gt;authinfo&lt;/code&gt; file (ideally encrypted with GPG). &lt;code&gt;magit-gh&lt;/code&gt; piggybacks on &lt;code&gt;gh auth login&lt;/code&gt;, which you have already configured from authenticating the first time.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Minimal dependencies&lt;/strong&gt; &amp;ndash; just Magit, Transient, and the &lt;code&gt;gh&lt;/code&gt; CLI.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The trade-off is that &lt;code&gt;magit-gh&lt;/code&gt; is far less featureful than Forge. It is intentionally a lightweight alternative for users who primarily want to list, checkout, and view pull requests without additional setup overhead.&lt;/p&gt;
&lt;h2 id=&#34;installation&#34;&gt;
  Installation
  &lt;a class=&#34;heading-link&#34; href=&#34;#installation&#34;&gt;
    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;
    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;
  &lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;You&amp;rsquo;ll need the &lt;a href=&#34;https://cli.github.com&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;GitHub CLI&lt;/a&gt; installed and authenticated first:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# macOS&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;brew install gh
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Linux (Fedora / RHEL / CentOS)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sudo dnf install gh
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Then authenticate&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;gh auth login
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Then install &lt;code&gt;magit-gh&lt;/code&gt; from MELPA:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;M-x package-install RET magit-gh RET&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Or with &lt;code&gt;use-package&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-emacs-lisp&#34; data-lang=&#34;emacs-lisp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;use-package&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;magit-gh&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nb&#34;&gt;:ensure&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;t&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nb&#34;&gt;:after&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;magit&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;usage&#34;&gt;
  Usage
  &lt;a class=&#34;heading-link&#34; href=&#34;#usage&#34;&gt;
    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;
    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;
  &lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;From any Magit status buffer, press &lt;code&gt;,&lt;/code&gt; to bring up the &lt;code&gt;magit-gh&lt;/code&gt; Transient menu. You can also invoke it directly with &lt;code&gt;M-x magit-gh&lt;/code&gt;. The menu is organized into Pull Request commands:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;magit-gh
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;└── Pull Requests
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    ├── l  List open PRs
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    ├── c  Checkout PR
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    └── v  View PR in browser
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;When you list open PRs (&lt;code&gt;l&lt;/code&gt;), a dedicated buffer opens showing PR number, title, author, and branch name. From that buffer you can checkout a PR with &lt;code&gt;RET&lt;/code&gt; or &lt;code&gt;c&lt;/code&gt;, open it in your browser with &lt;code&gt;v&lt;/code&gt;, refresh the list with &lt;code&gt;g&lt;/code&gt;, or close the buffer with &lt;code&gt;q&lt;/code&gt;.&lt;/p&gt;
&lt;figure&gt;&lt;img src=&#34;https://raw.githubusercontent.com/jonathanchu/magit-gh/refs/heads/main/screenshots/20260221_magit_gh_demo.gif&#34;&gt;
&lt;/figure&gt;

&lt;p&gt;If you don&amp;rsquo;t like the &lt;code&gt;,&lt;/code&gt; key binding, you can set a custom one. Note that the variable must be set &lt;strong&gt;before&lt;/strong&gt; the package loads so it needs to be in the init section:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-emacs-lisp&#34; data-lang=&#34;emacs-lisp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;use-package&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;magit-gh&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nb&#34;&gt;:ensure&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;t&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nb&#34;&gt;:after&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;magit&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nb&#34;&gt;:init&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;setq&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;magit-gh-key&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;; Example setting key to &amp;#34;;&amp;#34; instead of the default &amp;#34;,&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;To increase the number of PRs fetched (default 30):&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-emacs-lisp&#34; data-lang=&#34;emacs-lisp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;use-package&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;magit-gh&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nb&#34;&gt;:ensure&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;t&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nb&#34;&gt;:after&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;magit&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nb&#34;&gt;:custom&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;magit-gh-pr-limit&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;50&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;what-s-next&#34;&gt;
  What&amp;rsquo;s next
  &lt;a class=&#34;heading-link&#34; href=&#34;#what-s-next&#34;&gt;
    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;
    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;
  &lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Aside from bugs and visual improvements to the TUI, I would consider this package mostly feature complete. The current feature set is intentionally small, but I have plans to add support for listing closed/merged PRs, creating new PRs, viewing diffs and CI status, and eventually issue management &amp;ndash; all through the &lt;code&gt;gh&lt;/code&gt; CLI. You can track progress on the &lt;a href=&#34;https://github.com/jonathanchu/magit-gh&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;GitHub repo&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;If you use Magit and the GitHub CLI, give &lt;code&gt;magit-gh&lt;/code&gt; a try! It&amp;rsquo;s available on &lt;a href=&#34;https://melpa.org/#/magit-gh&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;MELPA&lt;/a&gt; and the source is on &lt;a href=&#34;https://github.com/jonathanchu/magit-gh&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;GitHub&lt;/a&gt;. Contributions and feedback are always welcome! Hope this is useful!&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Introducing magit-git-toolbelt</title>
      <link>https://jonathanchu.is/posts/introducing-magit-git-toolbelt/</link>
      <pubDate>Wed, 28 Jan 2026 00:00:00 -0500</pubDate>
      <author>Jonathan Chu</author>
      <guid>https://jonathanchu.is/posts/introducing-magit-git-toolbelt/</guid>
      <description>&lt;p&gt;I&amp;rsquo;ve been a long-time user of both Magit and &lt;a href=&#34;https://github.com/nvie/git-toolbelt&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;git-toolbelt&lt;/a&gt;, a suite of useful git helper commands by Vincent Driessen (&lt;a href=&#34;https://nvie.com/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;@nvie&lt;/a&gt;). Often times I find myself reaching for several commands constantly in my day-to-day workflow - things like cleaning up merged branches, listing recent branches, checking which local commits haven&amp;rsquo;t been pushed yet, and more. My two favorite ones are &lt;a href=&#34;https://github.com/nvie/git-toolbelt?tab=readme-ov-file#git-cleanup&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;git cleanup&lt;/a&gt; and &lt;a href=&#34;https://github.com/nvie/git-toolbelt?tab=readme-ov-file#git-delouse&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;git delouse&lt;/a&gt;. I won&amp;rsquo;t go into details of what these do, but check it out for yourself to learn how it can fit in your own git workflow! These tools were extremely helpful in simplifying my own personal workflow and allowed me to get back actually writing code instead of doing git surgery &amp;ndash; and sometimes unsuccessfully! The only friction was that I&amp;rsquo;d have to jump out of Magit and into a shell to run these commands&amp;hellip;so I wrote a package to fix that!&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/jonathanchu/magit-git-toolbelt&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;magit-git-toolbelt&lt;/a&gt; is an Emacs package that integrates git-toolbelt commands directly into Magit through a Transient menu interface. If you&amp;rsquo;re already comfortable in Magit&amp;rsquo;s workflow, this should feel right at home.&lt;/p&gt;
&lt;h2 id=&#34;what-it-does&#34;&gt;
  What it does
  &lt;a class=&#34;heading-link&#34; href=&#34;#what-it-does&#34;&gt;
    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;
    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;
  &lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;The package provides a Transient menu that organizes some select git-toolbelt commands into logical groups:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Commit Info&lt;/strong&gt; - Display the initial commit, current branch SHA, and local (unpushed) commits&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Branch Management&lt;/strong&gt; - Cleanup merged branches, list recent/local/remote branches&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Merge Status&lt;/strong&gt; - Check which branches have been merged or remain unmerged&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Diff &amp;amp; Inspection&lt;/strong&gt; - Show modified and untracked files&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Actions&lt;/strong&gt; - Undo and quickly reverse the last commit&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;screenshot&#34;&gt;
  Screenshot
  &lt;a class=&#34;heading-link&#34; href=&#34;#screenshot&#34;&gt;
    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;
    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;
  &lt;/a&gt;
&lt;/h2&gt;
&lt;figure&gt;&lt;img src=&#34;https://jonathanchu.is/images/magit-git-toolbelt-screenshot.png&#34;&gt;
&lt;/figure&gt;

&lt;h2 id=&#34;installation&#34;&gt;
  Installation
  &lt;a class=&#34;heading-link&#34; href=&#34;#installation&#34;&gt;
    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;
    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;
  &lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;You&amp;rsquo;ll need &lt;a href=&#34;https://github.com/nvie/git-toolbelt&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;git-toolbelt&lt;/a&gt; installed first, then you can install &lt;code&gt;magit-git-toolbelt&lt;/code&gt; from MELPA:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;M-x package-install RET magit-git-toolbelt RET&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Or with &lt;code&gt;use-package&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-emacs-lisp&#34; data-lang=&#34;emacs-lisp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;use-package&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;magit-git-toolbelt&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nb&#34;&gt;:ensure&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;t&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nb&#34;&gt;:after&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;magit&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;usage&#34;&gt;
  Usage
  &lt;a class=&#34;heading-link&#34; href=&#34;#usage&#34;&gt;
    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;
    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;
  &lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;From any Magit status buffer, press &lt;code&gt;\&lt;/code&gt; to bring up the git-toolbelt Transient menu. You can also invoke it directly with &lt;code&gt;M-x magit-git-toolbelt&lt;/code&gt;. From there, you get a submenu of all the available commands organized by category.&lt;/p&gt;
&lt;p&gt;If you prefer a different keybinding instead of &lt;code&gt;\&lt;/code&gt;, you can customize it before the package loads:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-emacs-lisp&#34; data-lang=&#34;emacs-lisp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;use-package&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;magit-git-toolbelt&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nb&#34;&gt;:ensure&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;t&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nb&#34;&gt;:after&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;magit&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nb&#34;&gt;:init&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;setq&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;magit-git-toolbelt-key&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;.&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;; Example setting key to &amp;#34;.o&amp;#34; instead of the default &amp;#34;\&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;why&#34;&gt;
  Why
  &lt;a class=&#34;heading-link&#34; href=&#34;#why&#34;&gt;
    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;
    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;
  &lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;The motivation for writing this wrapper package is simple - I wanted to stay in Magit. Every time I wanted to run a git-toolbelt helper command, I would have to break out of my Magit workflow and drop into eshell or terminal to run &lt;code&gt;git cleanup&lt;/code&gt;, as an example of one of my favorite git-toolbelt helpers. It was a small context switch and minor inconvenience that added up over the course of a day, but now those commands are just a keypress away from the Magit status buffer.&lt;/p&gt;
&lt;p&gt;I actually enjoyed writing this package &amp;ndash; it was good to get back into a fully functional language and get my brain working a bit more than usual. Fun fact - &lt;a href=&#34;https://github.com/nvie/git-toolbelt?tab=readme-ov-file#git-spinoff&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;git spinoff&lt;/a&gt; was directly inspired from Magit! My next goal for this package is to take better inventory of the tools in &lt;a href=&#34;https://github.com/nvie/git-toolbelt&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;git toolbelt&lt;/a&gt; and analyze what functionality is already covered in Magit&amp;rsquo;s extensive featureset, and see what git helper commands I could expose in magit-git-toolbelt that truly offers novel functionality to Magit users.&lt;/p&gt;
&lt;p&gt;If you use both Magit and git-toolbelt, give it a try and let me know what you think! The source is on &lt;a href=&#34;https://github.com/jonathanchu/magit-git-toolbelt&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;GitHub&lt;/a&gt; and it&amp;rsquo;s available on MELPA.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Code Forensics on init.el</title>
      <link>https://jonathanchu.is/posts/code-forensics-emacs/</link>
      <pubDate>Mon, 19 Jan 2026 18:40:09 -0500</pubDate>
      <author>Jonathan Chu</author>
      <guid>https://jonathanchu.is/posts/code-forensics-emacs/</guid>
      <description>&lt;p&gt;I&amp;rsquo;ve always been interested in developer experience and understanding the metrics often used to measure this unique type of productivity. It&amp;rsquo;s extremely enticing to think that If I could change my tooling, gain insight through telemetry and other metrics, I could potentially &amp;ldquo;game&amp;rdquo; a better and more fullfilling developer experience overall - and ultimately over-achieve when typically I would just coast through. The experience I&amp;rsquo;m talking about improving is not so much solely about the 9-5 day job work, but more about the overarching craft of engineering. Whether you&amp;rsquo;re coding away on pet projects on nights and weekends, tinkering with editors or Linux distros, or learning new technologies and programming languages for work, the underlying takeaways and insights one could gain from these developer experience metrics would carry over to all tangible coding activities that we do.&lt;/p&gt;
&lt;p&gt;A while back, I watched one of Adam Tornhill&amp;rsquo;s talks on YouTube and the idea of &amp;ldquo;Your Code as a Crime Scene&amp;rdquo;. This was around the time that I started dabbling with Clojure and when I found out he wrote a book of the same title that followed a tool he released online, written in Clojure - it was a perfect match of interests and technology for me. Cloning the repo and following the README, code-maat &lt;a href=&#34;https://github.com/adamtornhill/code-maat&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;https://github.com/adamtornhill/code-maat&lt;/a&gt; was relatively easy to get up and running for baseline code analysis. The basic gist of this all is that you install the repo and run some jars over a git log that you save locally for static analysis. The GitHub page is well-documented but perhaps I will share my own notes (in the Notes section) for how I got it up and running at least.&lt;/p&gt;
&lt;p&gt;I decided to run this against a personal (what feels like a lifelong or lifetime) endeavor, my emacs config, and was curious to see what the output was. What follows was some insights, however obvious some may be, but also insightful findings from the code-maat output.&lt;/p&gt;
&lt;p&gt;Top-level numbers on my dotemacs &lt;a href=&#34;https://github.com/jonathanchu/dotemacs&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;https://github.com/jonathanchu/dotemacs&lt;/a&gt; repo. Over 11 years and 1,738 commits of config changes, visual UI and modeline tweaking, and transitions to org mode literate source blocks back to plain old elisp (and maybe a few more cycles of that dance over the years) ;)&lt;/p&gt;
&lt;figure&gt;&lt;img src=&#34;https://jonathanchu.is/images/code-forensics-overview.png&#34;&gt;
&lt;/figure&gt;

&lt;p&gt;Hotspots (Most Changed Files)&lt;/p&gt;
&lt;p&gt;This highlights files with the highest change frequency. These are potential hostpost where bugs tend to cluster and where refactoring may have the highest impact. Since these are screenshots, the large red dot in the first quadrant is my init.el file.&lt;/p&gt;
&lt;figure&gt;&lt;img src=&#34;https://jonathanchu.is/images/code-forensics-change-frequency.png&#34;&gt;
&lt;/figure&gt;

&lt;figure&gt;&lt;img src=&#34;https://jonathanchu.is/images/code-forensics-hotspot-bubble-chart.png&#34;&gt;
&lt;/figure&gt;

&lt;p&gt;Temporal Coupling is an interesting relationship insight into files and pairs of files.&lt;/p&gt;
&lt;p&gt;What this shows is files that frequently change together in the same commits. High coupling (60%+) between unrelated files may indicate hidden dependencies. Low coupling between related files (like .el and .org) is expected and healthy. There were no surprises here other than being impressed at how well this worked on first analysis. For example, when my emacs-init.org changed, so did my emacs-init.el in an expected and coupled manner.&lt;/p&gt;
&lt;figure&gt;&lt;img src=&#34;https://jonathanchu.is/images/code-forensics-temporal-coupling.png&#34;&gt;
&lt;/figure&gt;

&lt;p&gt;Code Complexity vs Change Frequency&lt;/p&gt;
&lt;p&gt;I think this was the most interesting and valuable metric and visualization. This is the &amp;ldquo;hotspot&amp;rdquo; visualization from the book and files in the upper-right quadrant (large file AND frequently changed) are the highest priority for refactoring.&lt;/p&gt;
&lt;figure&gt;&lt;img src=&#34;https://jonathanchu.is/images/code-forensics-hotspot.png&#34;&gt;
&lt;/figure&gt;

&lt;p&gt;I took it a step further and put an overlay over the hotspot chart to better show the risk and complexity.&lt;/p&gt;
&lt;figure&gt;&lt;img src=&#34;https://jonathanchu.is/images/code-forensics-hotspot-overlay.png&#34;&gt;
&lt;/figure&gt;

&lt;p&gt;This chart shows the files plotted by complexity (LOC in this case) vs change frequency, with quadrants indicating refactoring priority.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Top-Right (Red): High complexity + High churn = Refactor now — these are your biggest risks&lt;/li&gt;
&lt;li&gt;Top-Left (Orange): High complexity + Low churn = Consider refactoring — complex but stable&lt;/li&gt;
&lt;li&gt;Bottom-Right (Yellow): Low complexity + High churn = Monitor — lots of changes but manageable&lt;/li&gt;
&lt;li&gt;Bottom-Left (Green): Low complexity + Low churn = Leave alone — no action needed&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;All in all, this was a really neat and interesting tool to play around with, despite it being on a somewhat trivial, but active, repository. I am thinking of how I can leverage this in my day-to-day in a more automated way. In the meantime, if you want to try this out for yourself (go see code-maat) or just want to get your toes wet with static code analysis, I extracted the essential git commands for you to replicate this to a smaller degree. Give it a shot and see what insights you can gain!&lt;/p&gt;
&lt;p&gt;Git Commands Reference&lt;/p&gt;
&lt;p&gt;Hotspots - Most frequently changed files&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;git log --format&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;format: --name-only &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; grep -v &lt;span class=&#34;s1&#34;&gt;&amp;#39;^$&amp;#39;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; sort &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; uniq -c &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; sort -rn &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; head -20
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Code Churn - Total lines added/removed per file&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;git log --numstat --format&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; awk &lt;span class=&#34;s1&#34;&gt;&amp;#39;{add[$3]+=$1; del[$3]+=$2} END {for(f in add) if(f) printf &amp;#34;%d\t%d\t%d\t%s\n&amp;#34;, add[f]+del[f], add[f], del[f], f}&amp;#39;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; sort -rn &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; head -20
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Code Age - Last modification date per file&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;git ls-files &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;while&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;read&lt;/span&gt; f&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;do&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;git log -1 --format&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;%ai&amp;#39;&lt;/span&gt; -- &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;done&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; sort -r
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Temporal Coupling - Files that change together&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;git log --format&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;%H&amp;#39;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; head -200 &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;while&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;read&lt;/span&gt; commit&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;do&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nv&#34;&gt;files&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;git diff-tree --no-commit-id --name-only -r &lt;span class=&#34;nv&#34;&gt;$commit&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; sort&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$files&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;while&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;read&lt;/span&gt; f1&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;do&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$files&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;while&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;read&lt;/span&gt; f2&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;do&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;[[&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$f1&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt; &amp;lt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$f2&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;]]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;then&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$f1&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; &amp;lt;-&amp;gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$f2&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;done&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;done&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;done&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; sort &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; uniq -c &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; sort -rn &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; head -20
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Commit Frequency - Commits per day&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;git log --format&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;%as&amp;#39;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; sort &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; uniq -c
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Lines of Code - Current state&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;git ls-files &lt;span class=&#34;s1&#34;&gt;&amp;#39;*.el&amp;#39;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; xargs wc -l &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; sort -rn
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
    </item>
    <item>
      <title>Dark Mode Toggle for iTerm and Emacs</title>
      <link>https://jonathanchu.is/posts/dark-mode-toggle-emacs-iterm/</link>
      <pubDate>Sun, 12 Jul 2020 00:00:00 -0400</pubDate>
      <author>Jonathan Chu</author>
      <guid>https://jonathanchu.is/posts/dark-mode-toggle-emacs-iterm/</guid>
      <description>&lt;p&gt;For most of my life, I&amp;rsquo;ve always preferred a dark theme when it comes to coding whether I&amp;rsquo;m in Emacs or the terminal. Lately though, the past two years specifically, I&amp;rsquo;ve switched to a light theme for both Emacs and iTerm. I really don&amp;rsquo;t have a better rationale other than I feel like the lighter theme means it&amp;rsquo;s &amp;ldquo;work&amp;rdquo; time and helps me focus, whereas a dark theme would be more suitable if I was coding at night and wanted to save some eye strain from a full day of looking at a computer screen.&lt;/p&gt;
&lt;p&gt;With that said, I&amp;rsquo;ve definitely utilized Mac OS X&amp;rsquo;s dark mode toggle and the one thing that has bothered me was the white glare of my Emacs and terminal when I was coding at night.  I wrote up a series of scripts inspired by Anantha Kumaran&amp;rsquo;s excellent post on this exact issue called &lt;a href=&#34;https://ananthakumaran.in/2020/05/09/dark-mode-toggle.html&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Dark Mode Toggle&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Now, I can type a single command in terminal and it would change to a dark theme in both Emacs and iTerm.&lt;/p&gt;
&lt;figure&gt;&lt;img src=&#34;https://jonathanchu.is/images/emacs-iterm-light-dark-toggle.gif&#34;&gt;
&lt;/figure&gt;

&lt;p&gt;And here are the scripts that I wrangled together to achieve this:&lt;/p&gt;
&lt;p&gt;Toggle to a dark Emacs theme:&lt;/p&gt;
&lt;p&gt;Filename: emacs-dark-theme&lt;/p&gt;
&lt;p&gt;&lt;a id=&#34;code-snippet--emacs-dark-theme&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;#!/bin/sh
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;set&lt;/span&gt; -e
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; pgrep Emacs &amp;gt; /dev/null&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    emacsclient --eval &lt;span class=&#34;s2&#34;&gt;&amp;#34;(load-theme &amp;#39;doom-one t)&amp;#34;&lt;/span&gt; &amp;gt; /dev/null
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Toggle to a dark iTerm color scheme using AppleScript and iTerm&amp;rsquo;s Python API:&lt;/p&gt;
&lt;p&gt;Filename: iterm2_dark_theme.py&lt;/p&gt;
&lt;p&gt;&lt;a id=&#34;code-snippet--iterm2-dark-theme.py&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;ch&#34;&gt;#!/usr/bin/env python3&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# -*- coding: utf-8 -*-&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;iterm2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;async&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;main&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;connection&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;# Get the color preset we&amp;#39;d like&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;preset&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;iterm2&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ColorPreset&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;async_get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;connection&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;One Dark&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;profiles&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;iterm2&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PartialProfile&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;async_query&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;connection&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;partial&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;profiles&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;c1&#34;&gt;# Fetch the full profile and then set the color preset in it&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;profile&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;partial&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;async_get_full_profile&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;profile&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;async_set_color_preset&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;preset&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;iterm2&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;run_until_complete&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;main&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Call the iTerm Python script via AppleScript:&lt;/p&gt;
&lt;p&gt;Filename: iterm-dark-theme&lt;/p&gt;
&lt;p&gt;&lt;a id=&#34;code-snippet--iterm-dark-theme&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;tell application &lt;span class=&#34;s2&#34;&gt;&amp;#34;iTerm2&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    launch API script named &lt;span class=&#34;s2&#34;&gt;&amp;#34;iterm2_dark_theme.py&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;end tell
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I combine calling these scripts with one command like so:&lt;/p&gt;
&lt;p&gt;Filename: dark-mode&lt;/p&gt;
&lt;p&gt;&lt;a id=&#34;code-snippet--dark-mode&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;#!/bin/sh
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;set&lt;/span&gt; -e
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;/bin/bash /Users/jonathan/projects/dotfiles/bin/emacs-dark-theme
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;osascript /Users/jonathan/projects/dotfiles/bin/iterm-dark-theme
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And now this all can be ran with just:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$ dark-mode
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The same workflow can be done for switching back to a light theme by creating a new set of these scripts and modifying to the light theme you want!&lt;/p&gt;
&lt;p&gt;Thank you to &lt;a href=&#34;https://ananthakumaran.in/2020/05/09/dark-mode-toggle.html&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Anantha Kumaran&lt;/a&gt; for this first post and all credit goes to him!&lt;/p&gt;
&lt;p&gt;Happy (night) hacking!&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Emacs, Notmuch, isync, and msmtp Setup</title>
      <link>https://jonathanchu.is/posts/emacs-notmuch-isync-msmtp-setup/</link>
      <pubDate>Tue, 23 Jun 2020 00:00:00 -0400</pubDate>
      <author>Jonathan Chu</author>
      <guid>https://jonathanchu.is/posts/emacs-notmuch-isync-msmtp-setup/</guid>
      <description>&lt;p&gt;I&amp;rsquo;ve been meaning to move my email management to Emacs for the past year and finally made the jump after see &lt;a href=&#34;https://cestlaz.github.io/stories/emacs/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Mike Zamansky&amp;rsquo;s&lt;/a&gt; video on this (&lt;a href=&#34;https://www.youtube.com/watch?v=GlrsoIwJ-UM&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;YouTube&lt;/a&gt;). Here are my notes on how I got this all setup and configured.&lt;/p&gt;
&lt;p&gt;This is an opinionated setup based on Mac OS X and Fastmail. First, make sure you have &lt;a href=&#34;https://brew.sh/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Homebrew&lt;/a&gt; installed to install the packages needed.&lt;/p&gt;
&lt;h2 id=&#34;receiving-email&#34;&gt;
  Receiving email
  &lt;a class=&#34;heading-link&#34; href=&#34;#receiving-email&#34;&gt;
    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;
    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;
  &lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://notmuchmail.org/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Notmuch&lt;/a&gt; requires email to be stored on your local filesystem and one message per file. We&amp;rsquo;ll be using &lt;code&gt;isync&lt;/code&gt; for this.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$ brew install isync
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;a href=&#34;http://isync.sourceforge.net/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;http://isync.sourceforge.net/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;You&amp;rsquo;ll need to start out with an initial config which you can copy directly to your home directory.&lt;/p&gt;
&lt;p&gt;My &lt;code&gt;.mbsyncrc&lt;/code&gt; file looks like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;# First section: remote IMAP account
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;IMAPAccount fastmail
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Host imap.fastmail.com
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Port 993
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;User jonathanchu@fastmail.com
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;# For simplicity, this is how to read the password from another file.
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;# For better security you should use GPG https://gnupg.org/
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;PassCmd &amp;#34;cat ~/.mbsync-fastmail&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;SSLType IMAPS
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;SSLVersions TLSv1.2
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;IMAPStore fastmail-remote
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Account fastmail
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;# This section describes the local storage
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;MaildirStore fastmail-local
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Path ~/Maildir/
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Inbox ~/Maildir/INBOX
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;SubFolders Verbatim
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;# This section a &amp;#34;channel&amp;#34;, a connection between remote and local
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Channel fastmail
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Master :fastmail-remote:
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Slave :fastmail-local:
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Patterns *
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Expunge None
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;CopyArrivalDate yes
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Sync All
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Create Slave
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;SyncState *
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The contents of &lt;code&gt;.mbsync-fastmail&lt;/code&gt; contains my email password, which is probably not the best way to do store a password like this locally so I should fix this in the near future.&lt;/p&gt;
&lt;p&gt;Once this is configured and saved in your home directory, you can then run run &lt;code&gt;mbsync&lt;/code&gt; to pull your email down locally:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$ mbsync -a
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Note, you&amp;rsquo;ll have to run this each time to retrieve new mail. I know some folks might elect to have this as a running cron job every x minutes - this can be entirely based on your preference and email workflow.&lt;/p&gt;
&lt;p&gt;And finally, we just need to setup a search database for &lt;code&gt;notmuch&lt;/code&gt; to work by running:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$ notmuch new
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;viewing-and-writing-email&#34;&gt;
  Viewing and writing email
  &lt;a class=&#34;heading-link&#34; href=&#34;#viewing-and-writing-email&#34;&gt;
    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;
    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;
  &lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;We&amp;rsquo;re going to use &lt;code&gt;Notmuch&lt;/code&gt;, specifically in Emacs, to view our mail. First, you need to install &lt;code&gt;Notmuch&lt;/code&gt; on your OS:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$ brew install notmuch
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Once &lt;code&gt;notmuch&lt;/code&gt; is installed, run the following command to setup &lt;code&gt;notmuch&lt;/code&gt;. This will create a &lt;code&gt;.notmuch-config&lt;/code&gt; in your home directory.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$ notmuch setup
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;When you have entered your email information, in your Emacs configuration, you can install &lt;code&gt;notmuch-emacs&lt;/code&gt; by including the following:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-elisp&#34; data-lang=&#34;elisp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;use-package&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;notmuch&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nb&#34;&gt;:ensure&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;t&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nb&#34;&gt;:defer&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;t&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Then, you can run &lt;code&gt;m-x notmuch-hello&lt;/code&gt; and you will be greeted with the &lt;code&gt;notmuch&lt;/code&gt; starting screen.&lt;/p&gt;
&lt;p&gt;&lt;a id=&#34;orged7a5f4&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;figure&gt;&lt;img src=&#34;https://jonathanchu.is/images/notmuch-hello.png&#34;
    alt=&#34;Figure 1: m-x notmuch-hello&#34;&gt;&lt;figcaption&gt;
      &lt;p&gt;Figure 1: m-x notmuch-hello&lt;/p&gt;
    &lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;&lt;a id=&#34;orgd900945&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;figure&gt;&lt;img src=&#34;https://jonathanchu.is/images/notmuch-unread.png&#34;
    alt=&#34;Figure 2: notmuch unread&#34;&gt;&lt;figcaption&gt;
      &lt;p&gt;Figure 2: notmuch unread&lt;/p&gt;
    &lt;/figcaption&gt;
&lt;/figure&gt;

&lt;h2 id=&#34;sending-email&#34;&gt;
  Sending email
  &lt;a class=&#34;heading-link&#34; href=&#34;#sending-email&#34;&gt;
    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;
    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;
  &lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Next, we&amp;rsquo;ll need to send our mail with something, so I chose &lt;code&gt;msmtp&lt;/code&gt; because of how easy it was to configure.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$ brew install msmtp
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The contents of my &lt;code&gt;.msmtprc&lt;/code&gt; file looks like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;defaults
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;auth on
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;protocol smtp
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;tls on
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;account fastmail
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;host smtp.fastmail.com
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;port 465
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;user jonathanchu@fastmail.com
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;passwordeval &amp;#34;cat ~/.mbsync-fastmail&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;tls_starttls off
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;from jonathanchu@fastmail.com
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;account default : fastmail
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Add this bit in your Emacs config:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-emacs-lisp&#34; data-lang=&#34;emacs-lisp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;setq&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;send-mail-function&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;sendmail-send-it&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nv&#34;&gt;sendmail-program&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;/usr/local/bin/msmtp&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nv&#34;&gt;mail-specify-envelope-from&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;t&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nv&#34;&gt;message-sendmail-envelope-from&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;header&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nv&#34;&gt;mail-envelope-from&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;header&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This article will be updated as I refine my email process and work out the bugs, but at this point you should have working email with Notmuch in Emacs!&lt;/p&gt;
</description>
    </item>
    <item>
      <title>EmacsConf 2019 Magit Deep Dive</title>
      <link>https://jonathanchu.is/posts/emacsconf2019-magit-deep-dive/</link>
      <pubDate>Tue, 07 Apr 2020 00:00:00 -0400</pubDate>
      <author>Jonathan Chu</author>
      <guid>https://jonathanchu.is/posts/emacsconf2019-magit-deep-dive/</guid>
      <description>&lt;p&gt;I was fortunate enough to get to present at EmacsConf 2019 in November of last year and I wanted to share the content from my presentation:&lt;/p&gt;
&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
      &lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube.com/embed/vS7YNdl64gY?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;YouTube video&#34;&gt;&lt;/iframe&gt;
    &lt;/div&gt;

&lt;p&gt;And here&amp;rsquo;s the source for my org slides on GitHub:&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/jonathanchu/emacsconf-2019-magit-deep-dive&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;https://github.com/jonathanchu/emacsconf-2019-magit-deep-dive&lt;/a&gt;&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Getting Started with Emacs and Clojure on OS X</title>
      <link>https://jonathanchu.is/posts/getting-started-emacs-clojure-mac-osx/</link>
      <pubDate>Sat, 13 Jun 2015 00:00:00 -0400</pubDate>
      <author>Jonathan Chu</author>
      <guid>https://jonathanchu.is/posts/getting-started-emacs-clojure-mac-osx/</guid>
      <description>&lt;p&gt;I&amp;rsquo;ve been learning Clojure in my spare time and coming from a
predominantly Python-focused career, I wanted to chronicle my
experiences with learning Clojure and integrating it within my Emacs
config.&lt;/p&gt;
&lt;p&gt;This article will be geared towards beginners, like me, looking to get
started with Clojure and Emacs on OS X.&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;
&lt;ol&gt;
&lt;li&gt;Install Homebrew - &lt;a href=&#34;http://brew.sh/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;http://brew.sh/&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I won&amp;rsquo;t go into too much detail here, aside from providing the
&lt;a href=&#34;http://brew.sh/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;link&lt;/a&gt; where you can find all the resources on
installing this. I highly recommend using Homebrew for your packaging
needs on OS X. The one liner to install looks like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;go&#34;&gt;ruby -e &amp;#34;$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We&amp;rsquo;ll be using Homebrew to install some of the necessary programs and
libraries.&lt;/p&gt;
&lt;ol start=&#34;2&#34;&gt;
&lt;li&gt;Install Homebrew Cask&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Next, we&amp;rsquo;ll need to install Java, as Clojure runs on the Java Virtual
Machine (JVM). You&amp;rsquo;ll need to install the Java Development Kit (JDK).&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://www.oracle.com/technetwork/java/index.html&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Java from Oracle&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;You can go to the Java website above to download it and install
manually, but I prefer to let package managers do that for me. It is
recommended to download at least version 6 of the JDK.&lt;/p&gt;
&lt;p&gt;For this, we can install the JDK through Homebrew Cask, which we will
need to install:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;go&#34;&gt;brew install caskroom/cask/brew-cask
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Homebrew Cask is really useful for managing application installs. No
more dragging to your &lt;code&gt;Applications&lt;/code&gt; folder anymore!&lt;/p&gt;
&lt;ol start=&#34;3&#34;&gt;
&lt;li&gt;Install Java&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Now that we have Homebrew Cask installed, we can install the JDK by
simply doing:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;go&#34;&gt;brew cask install java
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This will pull the latest version of the JDK according to Homebrew
Casks and install it on your machine. It should prompt you for your
password to proceed with the install.&lt;/p&gt;
&lt;ol start=&#34;4&#34;&gt;
&lt;li&gt;Install Leiningen&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;a href=&#34;http://leiningen.org/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Leiningen&lt;/a&gt; is a user interface to the Clojure
library that helps you automate projects and manage dependencies,
while fully setting up &lt;code&gt;lein&lt;/code&gt; and Clojure for you.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;go&#34;&gt;brew install leiningen
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;You now have Clojure installed!&lt;/p&gt;
&lt;ol start=&#34;5&#34;&gt;
&lt;li&gt;Configure Emacs&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This is mostly an optional step if you haven&amp;rsquo;t done this already. Make
sure you have something like this in your Emacs config:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-elisp&#34; data-lang=&#34;elisp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;add-to-list&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;exec-path&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;/usr/local/bin&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If your Homebrew install is standard, this is where your binaries
should be located. If not, adjust the path as necessary.&lt;/p&gt;
&lt;ol start=&#34;6&#34;&gt;
&lt;li&gt;Install Emacs packages &lt;code&gt;cider&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;kbd&gt;m-x&lt;/kbd&gt; &lt;code&gt;package-install&lt;/code&gt; &lt;kbd&gt;RET&lt;/kbd&gt; &lt;code&gt;cider&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Optionally, if you want to do &lt;a href=&#34;https://www.4clojure.com/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;4clojure&lt;/a&gt;
problems in Emacs, also install &lt;code&gt;4clojure.el&lt;/code&gt;:&lt;/p&gt;
&lt;p&gt;&lt;kbd&gt;m-x&lt;/kbd&gt; &lt;code&gt;package-install&lt;/code&gt; &lt;kbd&gt;RET&lt;/kbd&gt; &lt;code&gt;4clojure&lt;/code&gt;&lt;/p&gt;
&lt;ol start=&#34;7&#34;&gt;
&lt;li&gt;Add a &lt;code&gt;profiles.clj&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In your home directory, create a new &lt;code&gt;profiles.clj&lt;/code&gt; in &lt;code&gt;~/.lein/&lt;/code&gt; and
put this barebones config to start with:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;ss&#34;&gt;:user&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;ss&#34;&gt;:plugins&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[[&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;cider/cider-nrepl&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;0.9.0-SNAPSHOT&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;ss&#34;&gt;:dependencies&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[[&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;org.clojure/tools.nrepl&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;0.2.10&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]]}}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;*Note - modify the &lt;code&gt;cider-nrepl&lt;/code&gt; and &lt;code&gt;tools.nrepl&lt;/code&gt; versions if you
have issues. It should match the versions you have installed above.&lt;/p&gt;
&lt;p&gt;And there you have it! You should be able to fire up Emacs and start a
Clojure REPL through &lt;code&gt;cider&lt;/code&gt; and even answer a few
&lt;a href=&#34;https://www.4clojure.com/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;4clojure&lt;/a&gt; questions as you dive into
Clojure. Moving forward, I&amp;rsquo;m going to try and chronicle my adventures
learning Clojure.&lt;/p&gt;
&lt;p&gt;Happy hacking!&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Introducing Atom One Dark Theme for Emacs</title>
      <link>https://jonathanchu.is/posts/atom-one-dark-theme-for-emacs/</link>
      <pubDate>Tue, 09 Jun 2015 00:00:00 -0400</pubDate>
      <author>Jonathan Chu</author>
      <guid>https://jonathanchu.is/posts/atom-one-dark-theme-for-emacs/</guid>
      <description>&lt;p&gt;This past weekend I hacked together a new Emacs color theme that is
essentially a port of a &lt;a href=&#34;https://atom.io/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Atom.io&amp;rsquo;s&lt;/a&gt;
&lt;a href=&#34;https://atom.io/themes/one-dark-syntax&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;One Dark theme&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://jonathanchu.is/images/atom_one_dark_theme_emacs.png&#34; alt=&#34;Atom One Dark Theme for Emacs screenshot&#34;&gt;&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;
&lt;p&gt;Here&amp;rsquo;s the repo for this - &lt;a href=&#34;https://github.com/jonathanchu/atom-one-dark-theme&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;One Dark Theme for Emacs&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;It is based off of the official syntax and UI themes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://atom.io/themes/one-dark-ui&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;One Dark UI&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://atom.io/themes/one-dark-syntax&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;One Dark Syntax&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I use Emacs as my main text editor for any kind of real work, but I do
like to keep up the other editors out there just to keep my ear to the
ground. That&amp;rsquo;s pretty much how I discovered that they added a new core
theme called One Dark - when I opened up Atom the other day. :)&lt;/p&gt;
&lt;p&gt;And while many may joke around that the world needs &amp;ldquo;yet another text
editor&amp;rdquo;, I think Atom.io is doing some really great things. For
starters, I was really impressed by the active community they already
have. Their packaging system really isn&amp;rsquo;t anything new by standards
today, and it&amp;rsquo;s also arguable that being built by GitHub immediately
drew more interest and adoption simply because of the big name backing
it, but you can&amp;rsquo;t deny the sheer number of active participants
submitting new, quality packages each day.&lt;/p&gt;
&lt;p&gt;Back to the Emacs theme itself, it is a work in progress and pull
requests are greatly welcomed! I have not thoroughly covered some of
the commonly used modes yet (org-mode for starters), so those tweaks
will be forthcoming.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;In the screenshot, for those curious the font is Inconsolata and I
use &lt;code&gt;smart-mode-line&lt;/code&gt;. My whole emacs config can be found in
essentially one file &lt;a href=&#34;https://github.com/jonathanchu/dotemacs&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;here&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Upgrading to Jinja2 Templates in Django 1.8 With Admin</title>
      <link>https://jonathanchu.is/posts/upgrading-jinja2-templates-django-18-with-admin/</link>
      <pubDate>Sun, 26 Apr 2015 00:00:00 -0400</pubDate>
      <author>Jonathan Chu</author>
      <guid>https://jonathanchu.is/posts/upgrading-jinja2-templates-django-18-with-admin/</guid>
      <description>&lt;p&gt;In Django 1.8, a new template system was introduced along with the
ability to choose a templating engine, with Jinja2 having built-in
support. I tried this out on a newly created Django project and
getting setup with Jinja2 was trivial following the docs; however,
upon checking the &lt;code&gt;/admin&lt;/code&gt; page, I was greeted with this:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://jonathanchu.is/images/django_admin_error_screenshot.png&#34; alt=&#34;Django Admin error screenshot&#34;&gt;&lt;/p&gt;
&lt;p&gt;Ah, right! The contrib app Admin does not ship with Jinja2 templates.
I read through the docs and did not see any mention of using a
different template engine in combination with the Django Admin, so I
thought I&amp;rsquo;d share how I solved this to get Jinja2 and the Django Admin
templates to work together.&lt;/p&gt;
&lt;h2 id=&#34;jinja2--django-templates-for-admin&#34;&gt;
  Jinja2 + Django Templates for Admin
  &lt;a class=&#34;heading-link&#34; href=&#34;#jinja2--django-templates-for-admin&#34;&gt;
    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;
    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;
  &lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;First, here is a link for the upgrade path to use the new templating
system:
&lt;a href=&#34;https://docs.djangoproject.com/en/1.8/ref/templates/upgrading/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;https://docs.djangoproject.com/en/1.8/ref/templates/upgrading/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Take note of the section that tells you when you can remove things
like &lt;code&gt;TEMPLATE_DIRS&lt;/code&gt;, &lt;code&gt;TEMPLATE_CONTEXT_PROCESSORS&lt;/code&gt;, etc.&lt;/em&gt;&lt;/p&gt;
&lt;h5 id=&#34;install-jinja2&#34;&gt;
  Install Jinja2
  &lt;a class=&#34;heading-link&#34; href=&#34;#install-jinja2&#34;&gt;
    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;
    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;
  &lt;/a&gt;
&lt;/h5&gt;
&lt;p&gt;Make sure &lt;code&gt;Jinja2&lt;/code&gt; is installed:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ pip install jinja2
&lt;/code&gt;&lt;/pre&gt;
&lt;h5 id=&#34;in-settingspy&#34;&gt;
  In &lt;code&gt;settings.py&lt;/code&gt;
  &lt;a class=&#34;heading-link&#34; href=&#34;#in-settingspy&#34;&gt;
    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;
    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;
  &lt;/a&gt;
&lt;/h5&gt;
&lt;p&gt;Here is how I defined my &lt;code&gt;TEMPLATES&lt;/code&gt; list:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;:::python
TEMPLATES = [
    {
        &#39;BACKEND&#39;: &#39;django.template.backends.jinja2.Jinja2&#39;,
        &#39;DIRS&#39;: [
            os.path.join(BASE_DIR, &#39;templates/jinja2&#39;),
        ],
        &#39;APP_DIRS&#39;: True,
        &#39;OPTIONS&#39;: {
            &#39;environment&#39;: &#39;myproject.jinja2.environment&#39;,
        },
    },
    {
        &#39;BACKEND&#39;: &#39;django.template.backends.django.DjangoTemplates&#39;,
        &#39;DIRS&#39;: [],
        &#39;APP_DIRS&#39;: True,
        &#39;OPTIONS&#39;: {
            &#39;context_processors&#39;: [
                &#39;django.contrib.auth.context_processors.auth&#39;,
                &#39;django.template.context_processors.debug&#39;,
                &#39;django.template.context_processors.i18n&#39;,
                &#39;django.template.context_processors.media&#39;,
                &#39;django.template.context_processors.static&#39;,
                &#39;django.template.context_processors.tz&#39;,
                &#39;django.contrib.messages.context_processors.messages&#39;,
            ],
        },
    },
]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You need to define both backends in the &lt;code&gt;TEMPLATES&lt;/code&gt; setting to be able
to use the Django Admin.&lt;/p&gt;
&lt;h5 id=&#34;create-directory-for-jinja2-templates&#34;&gt;
  Create directory for &lt;code&gt;jinja2&lt;/code&gt; templates
  &lt;a class=&#34;heading-link&#34; href=&#34;#create-directory-for-jinja2-templates&#34;&gt;
    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;
    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;
  &lt;/a&gt;
&lt;/h5&gt;
&lt;p&gt;Next, create a &lt;code&gt;jinja2&lt;/code&gt; directory in your project&amp;rsquo;s &lt;code&gt;templates&lt;/code&gt;
directory.  This is where we are going to put all of our Jinja2
templates.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ cd &amp;lt;path_to_project&amp;gt;/templates &amp;amp;&amp;amp; mkdir jinja2
&lt;/code&gt;&lt;/pre&gt;
&lt;h5 id=&#34;create-jinja2py&#34;&gt;
  Create &lt;code&gt;jinja2.py&lt;/code&gt;
  &lt;a class=&#34;heading-link&#34; href=&#34;#create-jinja2py&#34;&gt;
    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;
    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;
  &lt;/a&gt;
&lt;/h5&gt;
&lt;p&gt;Finally, create a file called &lt;code&gt;jinja2.py&lt;/code&gt; under your project directory
(should be at the same level as your &lt;code&gt;settings.py&lt;/code&gt;):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ cd myproject &amp;amp;&amp;amp; touch jinja2.py
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And put this in there:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;:::python
from django.contrib.staticfiles.storage import staticfiles_storage
from django.core.urlresolvers import reverse
from jinja2 import Environment


def environment(**options):
    env = Environment(**options)
    env.globals.update({
        &#39;static&#39;: staticfiles_storage.url,
        &#39;url&#39;: reverse,
    })
    return env
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This makes &lt;code&gt;static&lt;/code&gt; and &lt;code&gt;url&lt;/code&gt; available in your Jinja2 templates.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s a &lt;a href=&#34;http://mama.indstate.edu/users/ice/tree/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;tree&lt;/a&gt; of the final project structure:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ tree myproject
myproject
├── myproject
│   ├── __init__.py
│   ├── jinja2.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
├── manage.py
├── templates
│   └── jinja2
│       ├── base.html
│       ├── home.html
&lt;/code&gt;&lt;/pre&gt;
&lt;h5 id=&#34;pr0fit&#34;&gt;
  PR0FIT!
  &lt;a class=&#34;heading-link&#34; href=&#34;#pr0fit&#34;&gt;
    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;
    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;
  &lt;/a&gt;
&lt;/h5&gt;
&lt;p&gt;And that should do it!  If you go to &lt;code&gt;/admin/&lt;/code&gt; you should see a
working admin login.  Additionally, whatever templates you put in the
&lt;code&gt;templates/jinja2&lt;/code&gt; directory will be processed by the Jinja2 template
engine.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Keyboards</title>
      <link>https://jonathanchu.is/posts/keyboards/</link>
      <pubDate>Mon, 07 Apr 2014 00:00:00 -0400</pubDate>
      <author>Jonathan Chu</author>
      <guid>https://jonathanchu.is/posts/keyboards/</guid>
      <description>&lt;p&gt;I&amp;rsquo;ve tried out a number of keyboards in the past year in an attempt to
move away from my beloved, but aging, &lt;a href=&#34;http://www.amazon.com/Microsoft-Natural-Ergonomic-Keyboard-4000/dp/B000A6PPOK&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Microsoft Natural Ergonomic
Keyboard
4000&lt;/a&gt;
and wanted to put my reviews of them up for anyone looking for an
overview of the ones I tried. A few years back, I developed a small case
of carpal tunnel and knew I had to change some of my habits before it
got worse - these kind of problems don&amp;rsquo;t go away on their own! At the
time, I was using a second generation &lt;a href=&#34;https://www.apple.com/keyboard/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Apple wireless
keyboard&lt;/a&gt; with those chiclet-style
keys. I loved it and used it for a few years before the pain started up,
and then I had to give it up as it wasn&amp;rsquo;t the most ergonomic keyboard
out there. A &lt;a href=&#34;https://twitter.com/ryanquigley&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;friend of mine&lt;/a&gt;
recommended to try the Microsoft Natural Ergonomic Keyboard 4000 and
after reading a quick
&lt;a href=&#34;http://www.codinghorror.com/blog/2005/09/keyboarding-microsoft-natural-ergonomic-4000.html&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;review&lt;/a&gt;
online, I purchased one. It took a few hours of getting used to it, but
I quickly fell in love with it. The keyboard itself is not eye candy by
any means, but it got the job done and best yet, it helped ease the pain
in my wrists with the more &amp;ldquo;natural&amp;rdquo; positioning of the hands. With its
split keyboard layout, cushioned wrist rests built right into it, and a
nominal price tag, this easily become my main keyboard. Here&amp;rsquo;s my quick
breakdown of the MS Natural 4000:&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://www.amazon.com/Microsoft-Natural-Ergonomic-Keyboard-4000/dp/B000A6PPOK&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Microsoft Natural Ergonomic Keyboard
4000&lt;/a&gt;
(*stock photo)&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://jonathanchu.is/images/microsoft-natural-4000.jpg&#34; alt=&#34;Microsoft Natural Ergonomic Keyboard 4000&#34;&gt;&lt;/p&gt;
&lt;p&gt;Pros:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Comfortable wrist rests&lt;/li&gt;
&lt;li&gt;Generally sane layout, number pad, and function keys - although I don&amp;rsquo;t use many of them in daily use&lt;/li&gt;
&lt;li&gt;One of the lower priced keyboards out there&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Cons:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Lack of good key switches&lt;/li&gt;
&lt;li&gt;Not form factor - it&amp;rsquo;s a big keyboard and takes up more room than your standard keyboard with the wrist rests&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The next keyboard I tried out was a &lt;a href=&#34;http://www.daskeyboard.com/model-s-ultimate/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Das Ultimate
S&lt;/a&gt; and it was my first
experience with a keyboard that had &lt;em&gt;real&lt;/em&gt; switches. I got mine with MX
Blue switches and they lived up to the hype - man, were they loud! You
got a really satisfying feeling when hitting each key and the tactile
feel really made for a good combo. In the end, I ended up parting ways
with it as it was a bit too loud for my wife since we lived in a one
bedroom apartment together in NYC and the clickity-clack would interrupt
her shows.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://www.daskeyboard.com/model-s-ultimate/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Das Ultimate S&lt;/a&gt; (*stock
photo)&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://jonathanchu.is/images/das-ultimate-s.jpg&#34; alt=&#34;Das Ultimate S&#34;&gt;&lt;/p&gt;
&lt;p&gt;Pros:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;MX Blue switches, although I saw you can get in MX Brown now (a little quieter) from their website&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Cons:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Hard to keep clean with glossy polished surface. I found this
quite annoying actually, especially with two cats, it made the
keyboard look dirty and it smudged easily.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The next keyboard on my list was the &lt;a href=&#34;http://www.kinesis-ergo.com/shop/maxim-for-pc/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Kinesis
Maxim&lt;/a&gt;. I&amp;rsquo;ve heard good
things about Kinesis from other developers and decided to give them a
try. I opted for the Maxim as it was one that was closest to the
Microsoft 4000 I was used to using, with a split keyboard layout. I
ended up not liking it for one particular reason - the alt key on the
left side was smaller than a normal keyboard&amp;rsquo;s, which made hitting it
(Command key for you Mac guys) a bit difficult. As an Emacs user, I
found this even more annoying as this led to lots of simple errors.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://www.kinesis-ergo.com/shop/maxim-for-pc/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Kinesis Maxim&lt;/a&gt; (*stock
photo)&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://jonathanchu.is/images/kinesis-maxim.jpg&#34; alt=&#34;Kinesis Maxim&#34;&gt;&lt;/p&gt;
&lt;p&gt;Pros:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Adjustable split keyboard layout&lt;/li&gt;
&lt;li&gt;Comfortable wrist rests with sticker pads included - comparable to the Microsoft 4000 on comfort level&lt;/li&gt;
&lt;li&gt;Decent key switches&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Cons:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Adjustable split gears seemed a bit wonky&lt;/li&gt;
&lt;li&gt;Did not like the layout for the control and alt keys&lt;/li&gt;
&lt;li&gt;PGUP/PGDOWN, Windows key is in a new column on left side, wtf?!&lt;/li&gt;
&lt;li&gt;Alt key on left side is smaller than normal, the layout for command and option key was very
small compared to normal alt and Windows key&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Microsoft came out with a new ergonomic keyboard recently I was pretty
excited to give it a try, being how much I liked their previous
ergonomic keyboard. The &lt;a href=&#34;http://www.amazon.com/Microsoft-Sculpt-Ergonomic-Desktop-L5V-00001/dp/B00CYX54C0&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Microsoft Sculpt
Ergonomic&lt;/a&gt;
came out with a bit higher price tag than the MS 4000, a little more
than 2x the cost to be accurate, but I still gave it a shot. It felt
pretty natural to me for the split layout and they added a few other
things to make it more &amp;ldquo;up-to-date&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://www.amazon.com/Microsoft-Sculpt-Ergonomic-Desktop-L5V-00001/dp/B00CYX54C0&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Microsoft Sculpt
Ergonomic&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://jonathanchu.is/images/microsoft-sculpt-ergonomic.jpg&#34; alt=&#34;Microsoft Sculpt Ergonomic&#34;&gt;&lt;/p&gt;
&lt;p&gt;Pros:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Wireless&lt;/li&gt;
&lt;li&gt;Split keyboard layout&lt;/li&gt;
&lt;li&gt;Comfortable wrist rests&lt;/li&gt;
&lt;li&gt;Layout very similar to 4000 with small improvements&lt;/li&gt;
&lt;li&gt;Magnetic battery hinge, which was a nice little touch&lt;/li&gt;
&lt;li&gt;Separate number pad so you can use it or not, making the&lt;/li&gt;
&lt;li&gt;keyboard more form factor&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Cons:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Didn&amp;rsquo;t like the chiclet-style keys&lt;/li&gt;
&lt;li&gt;They don&amp;rsquo;t sell the keyboard separately (as of this writing), so
it comes with the mouse too, and the mouse isn&amp;rsquo;t that great&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I used the Sculpt for quite a few months, until I started to miss &lt;em&gt;real&lt;/em&gt;
switches, thus prompted my keyboard switch yet again. This time I went
back to a familiar brand, Kinesis, but tried the
&lt;a href=&#34;https://www.kinesis-ergo.com/shop/advantage-for-pc-mac/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Advantage&lt;/a&gt;
series at recommendation from one of my friends,
&lt;a href=&#34;https://twitter.com/Wraithan&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Wraithan&lt;/a&gt;. It was definitely a unique
keyboard with a hefty price tag. Unfortunately, it didn&amp;rsquo;t last more than
a week in my possession as I found the learning curve a bit too much to
overcome. I&amp;rsquo;m not a super fast typer, but my speeds range in the 70-80
WPM range with a regular layout keyboard. Using the Advantage, I was
down to 30-40 WPM with about 1-2 errors.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://www.kinesis-ergo.com/shop/advantage-for-pc-mac/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Kinesis
Advantage&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://jonathanchu.is/images/kinesis-advantage.jpg&#34; alt=&#34;Kinesis Advantage Full&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://jonathanchu.is/images/kinesis-advantage-left-side.jpg&#34; alt=&#34;Kinesis Advantage Left Side&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://jonathanchu.is/images/kinesis-advantage-right-side.jpg&#34; alt=&#34;Kinesis Advantage Right Side&#34;&gt;&lt;/p&gt;
&lt;p&gt;Pros:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Split keyboard&lt;/li&gt;
&lt;li&gt;All crucial and most used keys moved to thumb, your strongest
finger, to reduce fatigue&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Cons:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Big learning curve, the shape and slope of keys slowed me down
(show typing tests?)&lt;/li&gt;
&lt;li&gt;I found switching back to a regular keyboard layout (like your
laptop&amp;rsquo;s internal keyboard) was getting difficult. As mobile
worker, it&amp;rsquo;s important to work anywhere and having this become
an issue was a big one for me&lt;/li&gt;
&lt;li&gt;It&amp;rsquo;s a big and heavy keyboard, even for my tastes, so this is
not a good choice if you&amp;rsquo;re limited on desk space&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Finally, this brought me to try out the &lt;a href=&#34;https://elitekeyboards.com/products.php?sub=pfu_keyboards,hhkbpro2&amp;amp;pid=pdkb400w&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Happy Hacking Professional
2&lt;/a&gt;.
What I liked most about this was that the control key was already mapped
to the caps lock, which is something I always re-map on a keyboard I use
anyway.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://elitekeyboards.com/products.php?sub=pfu_keyboards,hhkbpro2&amp;amp;pid=pdkb400w&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Happy Hacking Professional
2&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://jonathanchu.is/images/happy-hacking-pro-2.jpg&#34; alt=&#34;Happy Hacking Professional 2&#34;&gt;&lt;/p&gt;
&lt;p&gt;Pros:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Topre key switches&lt;/li&gt;
&lt;li&gt;Small form factor&lt;/li&gt;
&lt;li&gt;Control key already where I would normally map it&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Cons:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Hated where the delete key is&lt;/li&gt;
&lt;li&gt;Also hated where the function key is, didn&amp;rsquo;t seem logical if you
had to press the function to use any function keys.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In the end, it&amp;rsquo;s a great keyboard all around, but the delete key
placement didn&amp;rsquo;t jive with me and is the only reason I am not using this
keyboard as my main. Overall, I think I will use this when I travel
because of it&amp;rsquo;s small, compact size, but not as my main keyboard. This
inevitably brought me to the &lt;a href=&#34;https://elitekeyboards.com/products.php?sub=topre_keyboards,rf104&amp;amp;pid=xf01t0&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Realforce
104U&lt;/a&gt;
keyboard. &lt;em&gt;This is the current one I&amp;rsquo;m using today&lt;/em&gt; and I am loving it.
The lack of a split keyboard layout is not something I&amp;rsquo;m looking for
anymore as I learned to help my wrist pains over the years (stretches
before day begins, once at lunchtime, and small breaks on the hour to
shake out hands.)&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://elitekeyboards.com/products.php?sub=topre_keyboards,rf104&amp;amp;pid=xf01t0&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Realforce
104U&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://jonathanchu.is/images/realforce-104u.jpg&#34; alt=&#34;Realforce 104U&#34;&gt;&lt;/p&gt;
&lt;p&gt;Pros:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Variable weighted keys is the biggest win for me. 45g for inner
keys, 35g on outside
&lt;a href=&#34;https://elitekeyboards.com/proddata/images/th/104u_ergochart_1000_th0x0.png&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;pic&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;It is a solid keyboard - makes me feel safe if I ever have to
fight off any bad guys with this keyboard&lt;/li&gt;
&lt;li&gt;Traditional look - almost like an old &lt;a href=&#34;http://en.wikipedia.org/wiki/Model_M_keyboard&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;IBM
keyboard&lt;/a&gt;, so
definitely no learing curve here&lt;/li&gt;
&lt;li&gt;Topre key switches, which are not as loud and tactile feeling as
cherry swtiches, but somewhere in-between which I&amp;rsquo;m starting to like&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Cons:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The lower weighted keys on the outside aaaaaare more prone to
typpppppppppos if you&amp;rsquo;re one that rests your fingers on the home
row like me sometimes ;)&lt;/li&gt;
&lt;li&gt;Price&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;After trying all these keyboards, and consequently going through the
return process for most of them, I can happily recommend the Realforce
104U to anyone looking for a professional keyboard with good switches.
The variable weighted keys helps me not fatigue as much since the weaker
fingers have 35g, stronger fingers have 45g. It&amp;rsquo;s the closest keyboard
to a traditional look-and-feel of an old-school IBM keyboard, with no
learning curve, but a higher price tag for what you would expect a
high-end keyboard. If you don&amp;rsquo;t have the space for a full-sized
keyboard, I would recommend a Happy Hacking Professional 2.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Django 1.5 Custom User Example</title>
      <link>https://jonathanchu.is/posts/django-15-custom-user-example/</link>
      <pubDate>Mon, 23 Sep 2013 00:00:00 -0400</pubDate>
      <author>Jonathan Chu</author>
      <guid>https://jonathanchu.is/posts/django-15-custom-user-example/</guid>
      <description>&lt;p&gt;With Django 1.5, one of the biggest changes introduced was the ability
to configure the user model. Anyone who has coded a Django app with a
business requirement of adding a birthday field, an arbitrary checkbox
to the user registration fields, or even making the signup process
email-only with no usernames, knows the awkward feeling of implementing
their own custom user and feeling a little less Django-esque when all is
said and done. This configurable user model change alone was enough for
me to 1) upgrade all my Django sites to 1.5 and to 2) swap out my
customer user code for the way it should be done now with the
configurable user model.&lt;/p&gt;
&lt;p&gt;The Django docs are &lt;em&gt;fantastic&lt;/em&gt;. It is one of the most comprehensive
and, most important, user-friendly documentations out there for
programmers of all skill levels. I highly encourage you to read through
the
&lt;a href=&#34;https://docs.djangoproject.com/en/dev/topics/auth/customizing/#custom-users-and-the-built-in-auth-forms&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;docs&lt;/a&gt;
first on customizing the user model, but isn&amp;rsquo;t required to understand
this walk-through.&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;re anything like me, you sometimes like to skim or even skip the
docs altogether, and turn to Google to try and find a solid example
online. I found a few, but none of them really seemed to show me a full
example of configuring the user model. As a result, I decided to write
my own and put it all together in an example Django project to show how
I handled the custom user model. Here is the &lt;a href=&#34;https://github.com/jonathanchu/django-custom-user-example&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;link to the repo on
Github&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This is going to be a brief walk-through in running this example
codebase. It is opinionated, but (hopefully!) easily understood - so
this would enable you to modify this example codebase slightly to fit
your business requirements.&lt;/p&gt;
&lt;p&gt;Also, this custom user example is inspired from &lt;a href=&#34;https://twitter.com/freakboy3742&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Dr. Russell
Keith-Magee&amp;rsquo;s&lt;/a&gt; great talk at DjangoCon
US 2013 titled &lt;a href=&#34;https://speakerdeck.com/freakboy3742/red-user-blue-user-myuser-auth-dot-user&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;&amp;ldquo;Red User, Blue User, MyUser,
auth.User&amp;rdquo;&lt;/a&gt;
and should serve as a good example for how you can change the core
fields of auth.User.&lt;/p&gt;
&lt;p&gt;Please note - this walk-through will assume you have pip and virtualenv
installed locally, as we&amp;rsquo;ll be using that to create the environment for
the example Django project.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://github.com/jonathanchu/django-custom-user-example&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;View the source on
Github&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;First, clone the example custom user project and change directory into
it:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ git clone https://github.com/jonathanchu/django-custom-user-example.git
$ cd django-custom-user-example
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then, create your virtual environment. We&amp;rsquo;ll only be installing Django
(v1.5.4):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ mkvirtualenv customuser(customuser)
$ pip install django
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After Django is installed, let&amp;rsquo;s run &lt;code&gt;syncdb&lt;/code&gt; to create our test DB and
first superuser. This is configured out-of-the-box to use SQLite3 for
simplicity, but feel free to change to whatever database backend you
feel more comfortable with. Create your superuser now and follow the
prompts:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(customuser) $ python manage.py syncdb...::Follow prompts to create a superuser::
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then we can run &lt;code&gt;runserver&lt;/code&gt; to checkout how the custom users in the
admin looks:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(customuser) $ python manage.py runserver
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And open up your browser to http://127.0.0.1:8000/admin and log in with
the superuser you just created. Under &amp;ldquo;Accounts&amp;rdquo;, you will see our
custom &amp;ldquo;Users&amp;rdquo; there. Try it out, take it for a spin, create additional
users from the admin, change passwords, etc. This all works nicely with
our custom user model!&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://i.imgur.com/uaG4qaH.png&#34; alt=&#34;Django Custom User Screenshot&#34;&gt;&lt;/p&gt;
&lt;p&gt;Hopefully this is helpful to some out there looking for a solid example
on customizing the User model. Any issues with the codebase, please use
the repo&amp;rsquo;s &lt;a href=&#34;https://github.com/jonathanchu/django-custom-user-example/issues&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;issues
tracker&lt;/a&gt;
on Github. Happy hacking!&lt;/p&gt;
&lt;p&gt;&amp;ndash; Sep 23, 2013&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Setting Up Deft Mode in Emacs with Org-Mode</title>
      <link>https://jonathanchu.is/posts/setting-up-deft-mode-in-emacs-with-org-mode/</link>
      <pubDate>Thu, 15 Aug 2013 00:00:00 -0400</pubDate>
      <author>Jonathan Chu</author>
      <guid>https://jonathanchu.is/posts/setting-up-deft-mode-in-emacs-with-org-mode/</guid>
      <description>&lt;p&gt;I&amp;rsquo;ve been a big fan of &lt;a href=&#34;http://notational.net/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Notational Velocity&lt;/a&gt; for
quite a few years now - and more recently,
&lt;a href=&#34;http://brettterpstra.com/projects/nvalt/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;nValt&lt;/a&gt; which is a popular
fork of Notational Velocity, but with a bit more features. Everyone has
their own process when it comes to taking notes, and to each his own,
but the one thing that really turned me on to Notational Velocity/nValt
is the simplicity and unstructured process of taking and searching for
notes. Coupled with Dropbox for seamless syncing, you have yourself a
great note taking process that was easy to use and even easier to
search. As for mobile, I used &lt;a href=&#34;http://simplenote.com/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Simplenote&lt;/a&gt; to
view my notes via Dropbox, and it made taking notes during programming
meetups or business meetings even easier. Life is good!&lt;/p&gt;
&lt;p&gt;However, over the past year, as I found myself coding more and more in
my text editor of choice, Emacs - the more I found myself wanting
something that didn&amp;rsquo;t seem so disconnected from where I do most of my
prose and coding. After a quick search, I found &lt;a href=&#34;http://jblevins.org/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Jason
Blevins&amp;rsquo;&lt;/a&gt; great little creation called
&lt;a href=&#34;http://jblevins.org/projects/deft/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Deft&lt;/a&gt;. To sum it up, Deft is an
open source mode for Emacs to view, record, and search for notes in
plain text, very much like Notational Velocity/nValt. I highly
encourage you to check out Jason&amp;rsquo;s &lt;a href=&#34;http://jblevins.org/projects/deft/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;project page for
Deft&lt;/a&gt;. After trying out Deft, it
made me want to switch 100% over to org-mode notes as I really only
used org-mode for sporadic notes. Now, I have the power of org-mode
with Emacs in a Notational Velocity-like buffer with Deft. The rest of
the article will be outlining how I set it up in my Emacs config.&lt;/p&gt;
&lt;h2 id=&#34;setting-up-deft&#34;&gt;
  Setting up Deft
  &lt;a class=&#34;heading-link&#34; href=&#34;#setting-up-deft&#34;&gt;
    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;
    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;
  &lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;First, go grab &lt;a href=&#34;http://jblevins.org/projects/deft/deft.el&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;deft.el&lt;/a&gt; and
make sure it is available in your Emacs config (i.e. -
~/.emacs/vendor/deft.el path). You can grab it
&lt;a href=&#34;http://jblevins.org/projects/deft/deft.el&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;here&lt;/a&gt; or get it directly
from my &lt;a href=&#34;https://github.com/jonathanchu/emacs/blob/master/vendor/deft.el&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Emacs config&lt;/a&gt;,
which is the original unmodified file.&lt;/p&gt;
&lt;p&gt;Once &lt;code&gt;deft.el&lt;/code&gt; is on your Emacs load path, you&amp;rsquo;ll need to tell Emacs to
use Deft. Put the following anywhere in your config (I like to keep
&lt;code&gt;modes&lt;/code&gt; separated in it&amp;rsquo;s own &lt;code&gt;modes.el&lt;/code&gt; file that gets loaded on
initialization):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(require &#39;deft)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Since I use Org-Mode, I want &lt;code&gt;*.org&lt;/code&gt; files to be recognized by the Deft
buffer, so let&amp;rsquo;s set the &lt;code&gt;deft-extension&lt;/code&gt; to &amp;ldquo;org&amp;rdquo;. I believe the
default file type that Deft will look for is &amp;ldquo;txt&amp;rdquo;, so omit this part or
add in &amp;ldquo;txt&amp;rdquo; if you want to use plain text files.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(setq deft-extension &amp;quot;org&amp;quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And again, since I&amp;rsquo;m using org-mode with Deft, let&amp;rsquo;s set the
&lt;code&gt;deft-text-mode&lt;/code&gt; appropriately to use org-mode:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(setq deft-text-mode &#39;org-mode)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, we need to tell Deft where to find all of my current org-mode
files. In my case, I like to keep all my org-mode files in Dropbox, so
that path would be &lt;code&gt;~/Dropbox/org&lt;/code&gt; for me. You should change this path
to wherever you keep your files.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(setq deft-directory &amp;quot;~/Dropbox/org&amp;quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Finally, the last bit of customization is to tell Deft to use the
filename as a title. By default, Deft will use the first line of the
file as the filename. In my note taking preference, I normally don&amp;rsquo;t
lead off a note with the title of the file (it&amp;rsquo;s usually a date like
&amp;ldquo;2013-08-15&amp;rdquo; if it&amp;rsquo;s a meeting), so I switched on the trigger for this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(setq deft-use-filename-as-title t)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Optionally, you can set &lt;code&gt;deft-auto-save-interval&lt;/code&gt; to &lt;code&gt;0&lt;/code&gt;. Its
default value is &lt;code&gt;1.0&lt;/code&gt;, which means it saves every second. This is
very useful to many, meaning you don&amp;rsquo;t ever have to manually save your
notes since Deft automatically does it for you; however, with my
custom emacs config, I prefer to turn this off completely and manually
save my notes file because I have a &lt;code&gt;before-save-hook&lt;/code&gt; that deletes
trailing whitespace. This made typing notes a bit annoying and would
often remove whitespace if I was in the middle of writing a sentence,
where I didn&amp;rsquo;t want it to do that yet.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(setq deft-auto-save-interval 0)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Putting it all together, and you have this in its entirety:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;;; deft
(require &#39;deft)
(setq deft-directory &amp;quot;~/Dropbox/org&amp;quot;)
(setq deft-extension &amp;quot;org&amp;quot;)
(setq deft-text-mode &#39;org-mode)
(setq deft-use-filename-as-title t)
(setq deft-auto-save-interval 0)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&#34;using-deft&#34;&gt;
  Using Deft
  &lt;a class=&#34;heading-link&#34; href=&#34;#using-deft&#34;&gt;
    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;
    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;
  &lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;To enter the Deft buffer, simply do:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;m-x deft ENTER
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And you should see the Deft buffer like so, with all of your org-files
(yes, I know - nothing is blurred out&amp;hellip;I got nothing to hide :P ):&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://cl.ly/image/3r06392e2r3B/Screen%20Shot%202013-08-15%20at%202.42.37%20AM.png&#34; alt=&#34;Deft buffer screenshot&#34;&gt;&lt;/p&gt;
&lt;p&gt;Start typing and you&amp;rsquo;ll see the list of notes filter out the results
that do not match, just like Notational Velocity. Hit ENTER to open the
note in a new buffer.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://cl.ly/image/1n1S41400T16/Screen%20Shot%202013-08-15%20at%202.43.03%20AM.png&#34; alt=&#34;Deft filter screenshot&#34;&gt;&lt;/p&gt;
&lt;p&gt;And there you have it! Much appreciation and thanks goes to &lt;a href=&#34;http://jblevins.org/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Jason
Blevins&lt;/a&gt; for this awesome mode that has
effectively streamlined my coding and note-taking all in Emacs!&lt;/p&gt;
&lt;p&gt;&amp;ndash; Aug 15, 2013&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Org-Mode and MobileOrg Installation and Config</title>
      <link>https://jonathanchu.is/posts/org-mode-and-mobileorg-installation-and-config/</link>
      <pubDate>Wed, 10 Jul 2013 00:00:00 -0400</pubDate>
      <author>Jonathan Chu</author>
      <guid>https://jonathanchu.is/posts/org-mode-and-mobileorg-installation-and-config/</guid>
      <description>&lt;p&gt;&lt;img src=&#34;https://jonathanchu.is/images/mobileorg_placeit.png&#34; alt=&#34;MobileOrg&#34;&gt;&lt;/p&gt;
&lt;h2 id=&#34;intro&#34;&gt;
  Intro
  &lt;a class=&#34;heading-link&#34; href=&#34;#intro&#34;&gt;
    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;
    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;
  &lt;/a&gt;
&lt;/h2&gt;
&lt;!-- PELICAN_BEGIN_SUMMARY --&gt;
&lt;p&gt;Throughout the years, I&amp;rsquo;ve flipped back and forth between Org-Mode and
applications such as &lt;a href=&#34;http://agiletortoise.com/drafts/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Drafts (iOS)&lt;/a&gt;,
&lt;a href=&#34;https://evernote.com/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Evernote&lt;/a&gt;, &lt;a href=&#34;http://simplenote.com/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Simplenote&lt;/a&gt;,
and even plain ol&amp;rsquo; &lt;a href=&#34;http://lifehacker.com/166299/geek-to-live--list-your-life-in-txt&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;text
files&lt;/a&gt;
(with the &lt;a href=&#34;http://notational.net/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Notational Velocity&lt;/a&gt; and
&lt;a href=&#34;http://brettterpstra.com/projects/nvalt/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;nValt&lt;/a&gt;) for my most basic
note-taking needs; however, I&amp;rsquo;ve always found myself coming back to
Org-Mode in the end for another spin around the block. The one positive
thing that kept me coming back to Org-Mode, and perhaps the same thing
that Emacs is often criticized for, is the fact that it has a lot of
functionality under the hood - almost &lt;em&gt;too&lt;/em&gt; much. Org-Mode is a very
feature-rich application. For my basic needs, I use Org-Mode primiarly
for three things:&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;
&lt;ul&gt;
&lt;li&gt;Basic note-taking and outlines&lt;/li&gt;
&lt;li&gt;TODO lists&lt;/li&gt;
&lt;li&gt;Tracking and clocking time&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;here-comes-mobileorg&#34;&gt;
  Here Comes MobileOrg
  &lt;a class=&#34;heading-link&#34; href=&#34;#here-comes-mobileorg&#34;&gt;
    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;
    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;
  &lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;When I first learned about &lt;a href=&#34;http://mobileorg.ncogni.to/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;MobileOrg&lt;/a&gt;, I
was really stoked that I would be able to record notes, update TODO
statuses, and even just view my org files on the go. Unfortunatley, I
found that the basic setup instructions on their website left a few
minor things out for someone new to MobileOrg, and this is my attempt to
supplement that to help others with the same issues I faced with setup.&lt;/p&gt;
&lt;h2 id=&#34;org-mode-configuration&#34;&gt;
  Org-Mode Configuration
  &lt;a class=&#34;heading-link&#34; href=&#34;#org-mode-configuration&#34;&gt;
    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;
    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;
  &lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;First off, it should be noted that I&amp;rsquo;m using Emacs 24 with Org-Mode
already baked in. If you&amp;rsquo;re using an earlier version of Emacs that
doesn&amp;rsquo;t have Org-Mode by default, please install it according to your
own preference (which we won&amp;rsquo;t get into here since there are a few
different ways to install Org-Mode).&lt;/p&gt;
&lt;p&gt;My root directory for all of my org files is kept in Dropbox in a
directory called &lt;code&gt;org&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;~/Dropbox/org
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I&amp;rsquo;ve found that this setup fits my workflow best since I also work off a
second laptop at times and would like all my org files to be synced
across all machines with as little effort as possible.&lt;/p&gt;
&lt;h2 id=&#34;mobileorg-setup&#34;&gt;
  MobileOrg Setup
  &lt;a class=&#34;heading-link&#34; href=&#34;#mobileorg-setup&#34;&gt;
    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;
    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;
  &lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Next, install MobileOrg from the &lt;a href=&#34;https://itunes.apple.com/us/app/mobileorg/id634225528?mt=8&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;App
Store&lt;/a&gt;. I
chose the path of least resistance and decided to use Dropbox as the
source for server config, so when you first open the application, click
on the Dropbox option, click to link account, and allow authentication
with Dropbox to proceed. It should have created a new directory for you
under:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;~/Dropbox/Apps/MobileOrg
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&#34;emacs-configuration-for-mobileorg&#34;&gt;
  Emacs Configuration for MobileOrg
  &lt;a class=&#34;heading-link&#34; href=&#34;#emacs-configuration-for-mobileorg&#34;&gt;
    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;
    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;
  &lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;You will need a few more lines of code to get this all working with your
local org files and MobileOrg. This is my basic config based on the two
main directories above that will need to go in your Emacs config:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;;; mobileorg settings
(setq org-directory &amp;quot;~/Dropbox/org&amp;quot;)
(setq org-mobile-inbox-for-pull &amp;quot;~/Dropbox/org/inbox.org&amp;quot;)
(setq org-mobile-directory &amp;quot;~/Dropbox/Apps/MobileOrg&amp;quot;)
(setq org-mobile-files &#39;(&amp;quot;~/Dropbox/org&amp;quot;))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Finally, from within Emacs - edit any org file located in
&lt;code&gt;~/Dropbox/org/&lt;/code&gt; and save those changes. Then send these changes to
MobileOrg to sync up:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;M-x org-mobile-push
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With any luck, you should be able to go back to MobileOrg on your mobile
device and click the refresh button to see your org file(s) all there.&lt;/p&gt;
&lt;p&gt;Happy hacking!&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Upgrading PostgreSQL 9.0 to 9.1 with pg_upgrade</title>
      <link>https://jonathanchu.is/posts/upgrading-postgresql-90-to-91-with-pg_upgrade/</link>
      <pubDate>Tue, 19 Jun 2012 00:00:00 -0400</pubDate>
      <author>Jonathan Chu</author>
      <guid>https://jonathanchu.is/posts/upgrading-postgresql-90-to-91-with-pg_upgrade/</guid>
      <description>&lt;p&gt;Recently, I updated all of the packages I have installed via
&lt;a href=&#34;https://github.com/mxcl/homebrew&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Homebrew&lt;/a&gt; and ran into some issues
with the PostgreSQL package. I was getting this error:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;The data directory was initialized by PostgreSQL version 9.0, which is not compatible with this version 9.1.4
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A quick search took me to this
&lt;a href=&#34;http://www.postgresql.org/docs/9.1/static/pgupgrade.html&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;page&lt;/a&gt;,
however the docs left a lot to be desired to say the least. Here&amp;rsquo;s a
step-by-step to how I eventually fixed it using pg_upgrade.&lt;/p&gt;
&lt;p&gt;First, change directories to your Postgres data directory.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ cd /usr/local/var
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, create a new directory for the new data directory.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ mkdir postgres9
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Use &lt;code&gt;initdb&lt;/code&gt; to initialize the new Postgres cluster in the new data
directory you created above.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ initdb /usr/local/var/postgres9
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Run &lt;code&gt;pg_upgrade&lt;/code&gt; with the following arguments:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ pg_upgrade -d /usr/local/var/postgres/ -D /usr/local/var/postgres9 -b /usr/local/Cellar/postgresql/9.0.4/bin/ -B /usr/local/Cellar/postgresql/9.1.4/bin/ -v
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If all goes without error, you can switch the data directories so
Postgres will point to the right source.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ mv postgres postgres9.0.1
$ mv postgres9 postgres
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can delete the script left behind by &lt;code&gt;pg_upgrade&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ rm delete_old_cluster.sh
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I actually had my old Postgres instance running, so I had to stop it
before restarting the new one:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ pg_ctl -D /usr/local/var/postgres9.0.1 stop -m fast
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then I restarted the new Postgres instance:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ launchctl unload -w homebrew.mxcl.postgresql.plist
$ launchctl load -w homebrew.mxcl.postgresql.plist
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And you&amp;rsquo;re done - this should fix the PostgreSQL incompatible data
directory issue.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Installing OpenTera on a TeraStation</title>
      <link>https://jonathanchu.is/posts/installing-opentera-on-a-terastation/</link>
      <pubDate>Sun, 27 May 2012 00:00:00 -0400</pubDate>
      <author>Jonathan Chu</author>
      <guid>https://jonathanchu.is/posts/installing-opentera-on-a-terastation/</guid>
      <description>&lt;p&gt;I have a Buffalo TeraStation that I bought in 2006 to store all my big
media files. Through the years it has served me well, although with Mac
OS X Lion, connectivity to the TeraStation stopped working altogether -
mainly due to Lion&amp;rsquo;s changed AFP connectivity. Usually with hardware of
this age, it would be simply replaced; however, I&amp;rsquo;ve always found
Buffalo&amp;rsquo;s hardware to be of great quality which is a testament to how
long it&amp;rsquo;s lasted. Sadly, installing OpenTera has been on my TODO list
for roughly a year now, so this fix is overdue. Buffalo officially
responded that there will be a firmware fix for this in the future, but
that was over a year ago. This is a quick walkthrough of how I got
read/write access back on the TeraStation through Mac OS X Lion. Note: I
did the download and firmware updates from my Windows PC, telnet from
Mac OS X Lion.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Find out the firmware version of your TeraStation. At the time of
writing, I have v2.14. Download the corresponding firmware version from
this &lt;a href=&#34;http://homepage.ntlworld.com/itimpi/telnet.htm&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;site&lt;/a&gt; and install
it. This is essentially the same firmware but with telnet enabled.
You&amp;rsquo;ll need telnet enabled to log into the TeraStation to install
OpenTera.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Download OpenTera Update v5 and Samba 3 from this
&lt;a href=&#34;http://homepage.ntlworld.com/itimpi/opentera.htm&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;site&lt;/a&gt;. Unzip and move
this on the TeraStation where you can later access it. I moved this into
my &amp;ldquo;Share&amp;rdquo; directory.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Telnet into the TeraStation. I believe the default user for the
firmware is &amp;ldquo;myroot&amp;rdquo;, which you should use to telnet in.&lt;/p&gt;
&lt;p&gt;$ telnet 192.168.0.108Trying 192.168.0.108&amp;hellip;
Connected to 192.168.0.108.
Escape character is &amp;lsquo;^]&amp;rsquo;.
Password:Login incorrect&lt;/p&gt;
&lt;p&gt;TERASTATION login: myroot
root@TERASTATION:~#&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Change directories into the OpenTera directory, the one you just
placed on the TeraStation, and run the &lt;code&gt;Update_OpenTera.sh&lt;/code&gt; script.&lt;/p&gt;
&lt;p&gt;root@TERASTATION:/# cd mnt/array1/share/OpenTera_v5/
root@TERASTATION:/mnt/array1/share/OpenTera_v5# ./Update_OpenTera.sh&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This script is an interactive install, so it will prompt you to say &amp;ldquo;y&amp;rdquo;
a few times. Go ahead and do so. If all is successful, you should see:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[OpenTera] ============ OpenTera Install Completed ===============
&lt;/code&gt;&lt;/pre&gt;
&lt;ol start=&#34;5&#34;&gt;
&lt;li&gt;
&lt;p&gt;Next, change directories into the Samba directory and run the
&lt;code&gt;Update_Samba.sh&lt;/code&gt; script.&lt;/p&gt;
&lt;p&gt;root@TERASTATION:/mnt/array1/share/OpenTera_v5# cd /mnt/array1/share/samba-3.0.37_ppc/
root@TERASTATION:/mnt/array1/share/samba-3.0.37_ppc# ./Update_Samba.sh&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;When all is completed, you should see:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;*********************************************************************
                Completed samba-3.0.37_ppc.tgz install
*********************************************************************
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And that&amp;rsquo;s it! I was able to access the TeraStation from Mac OS X Lion.
Hopefully this will be helpful to someone else out there, as I know I&amp;rsquo;m
not the only one with this problem. If I missed any steps, let me know -
good luck!&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://jonathanchu.is/images/terastation_finder_screenshot.png&#34; alt=&#34;TeraStation in
Finder&#34;&gt;&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Applications I Use</title>
      <link>https://jonathanchu.is/posts/applications-i-use/</link>
      <pubDate>Fri, 02 Mar 2012 00:00:00 -0400</pubDate>
      <author>Jonathan Chu</author>
      <guid>https://jonathanchu.is/posts/applications-i-use/</guid>
      <description>&lt;p&gt;About two years ago, I bought my dad a MacBook Pro as a gift and with
him being a long-time Windows user, the transition wasn&amp;rsquo;t seemless to
say the least. I wanted to write an article on the applications I use to
give him an idea of what&amp;rsquo;s out there. So here are some common and
not-so-common applications I use on a daily basis:&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;
&lt;h2 id=&#34;general&#34;&gt;
  General
  &lt;a class=&#34;heading-link&#34; href=&#34;#general&#34;&gt;
    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;
    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;
  &lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;http://www.alfredapp.com/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Alfred&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Alfred is a handy utility app that has a lot more functionality than
what I use it for. It lets you search and open applications quickly with
a few key strokes by simply typing the first few letters of the
application name.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://agilebits.com/onepassword&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;1Password&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;A password manager app. I don&amp;rsquo;t know any of my passwords anymore. You
keep one password that unlocks the &amp;ldquo;vault&amp;rdquo; and it gives you access to
all of your passwords. Mine are randomly generated. Save your encrypted
passwords file to Dropbox so you can have it on other devices (iPad,
iPhone, or any other machine that can run 1Password).&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://www.dropbox.com/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Dropbox&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;For effortless syncing between machines and helpful for sharing files,
pictures, etc.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://flexibits.com/fantastical&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Fantastical&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Quick entry of appointments in your calendar. Uses natural language and
parses it to extract the date, time, and title of meeting. You can type
in: &amp;ldquo;Lunch with Lydia tomorrow afternoon at 1pm&amp;rdquo; and it will create an
calendar event for you correctly.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://www.getcloudapp.com/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Cloud App&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;An easier way to share screenshots. You can set it up auto-upload every
time you take a screenshot and it automagically copies the sharable URL
to your clipboard.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://mattgemmell.com/2009/11/02/shady-for-tired-eyes/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Shady&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;For when working late at night, you can turn down the brightness of your
screen. It has presets, so once you activate it, it will dim to your
custom setting without having to fiddle with the System Preferences each
time you want to dim or turn back on your brightness.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://itunes.apple.com/us/app/caffeine/id411246225&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Caffeine&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Keeps your screen from dimming or shutting off. Useful when I&amp;rsquo;m
unplugged and on the go - if I don&amp;rsquo;t want the screen to dim after a few
minutes of inactivity, I simply turn this on. Helpful when others are
looking on at your laptop and you&amp;rsquo;re discussing something. You won&amp;rsquo;t
need to keep touching the touchpad every minute or two so it won&amp;rsquo;t dim.
Sure, you can change this in your System Preferences, but the idea is to
NOT have to keep modifying the presets so it&amp;rsquo;s not intrusive.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://www.eidac.de/?p=207&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;smcFan Control&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;A simple little app that sits in your top menu bar and tells you the
internal temperature. I like to keep an eye on this when I work - it
tells me if there&amp;rsquo;s an application that&amp;rsquo;s eating up a lot of CPU,
because the fans would turn on and the temperatures would rise. Also
lets you control the fan speed.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://fluidapp.com/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Fluid App&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I use this app to make web apps seem like a native application. For
example, instead of visiting my company&amp;rsquo;s Basecamp URL, I can make the
web application into a (fake) standalone application. Now, I can just
launch &amp;ldquo;basecamp&amp;rdquo; in Alfred and it will open up a dedicated browser for
Basecamp.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://mizage.com/divvy/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Divvy&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I use this for quick organization of my applications and windows. You
can have presets for sizes that you like to repeat, such as half-screen,
full-screen, etc. Useful when working with several applications, such as
a browser, terminal, and emacs, and keeping a visual on them all at
once.&lt;/p&gt;
&lt;h2 id=&#34;coding&#34;&gt;
  Coding
  &lt;a class=&#34;heading-link&#34; href=&#34;#coding&#34;&gt;
    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;
    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;
  &lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Emacs&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve been using Emacs for a few years now and the muscle memory is
definitely ingrained where I feel more productive in it than almost
anything else.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://macromates.com/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Textmate 2&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Another editor that I used heavily before diving (back) into emacs. Out
of habit, it&amp;rsquo;s more of a crutch than anything else. I still find myself
using it for viewing project tree structures and quick searching
throughout the project.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://www.iterm2.com/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;iTerm 2&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;An alternative to Terminal, much more feature-rich.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://www.charlesproxy.com/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Charles&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Made its way into my daily development arsenal as of recently. Has
become extremely useful in seeing all the responses the applications I&amp;rsquo;m
coding is making.&lt;/p&gt;
&lt;p&gt;Chrome and developer tools, Firefox, Safari&lt;/p&gt;
&lt;p&gt;My browsers of choice, in that order.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://gitx.frim.nl/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;GitX&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I use a
&lt;a href=&#34;http://brotherbard.com/blog/2010/03/experimental-gitx-fork/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;fork&lt;/a&gt; of
this and prefer it over some of the newer git GUIs out there.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://www.sourcetreeapp.com/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;SourceTree&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Another good one, only reason why it&amp;rsquo;s on here is because it&amp;rsquo;s free (for
now), so go ahead and grab a copy before they start charging! Great
product.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://www.versionsapp.com/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Versions&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I begrudgingly use this because I have one remaining project on SVN,
which will soon be no more. It makes working with SVN somewhat bearable.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://www.sequelpro.com/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Sequel Pro&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Great GUI for MySQL databases remote and local.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://pgadmin.org/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;pgAdmin3&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;GUI for PostgreSQL databases remote and local. I use this in conjunction
with pgphpmyadmin.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://www.panic.com/transmit/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Transmit&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;(S)FTP client.&lt;/p&gt;
&lt;h2 id=&#34;frontenddesign&#34;&gt;
  Frontend/Design
  &lt;a class=&#34;heading-link&#34; href=&#34;#frontenddesign&#34;&gt;
    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;
    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;
  &lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Photoshop CS5&lt;/p&gt;
&lt;p&gt;Need I say more?&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://iconfactory.com/software/xscope&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;xScope&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;For making sure everything is pixel perfect and colors match exactly in
the websites I code. Has been an indespensible tool throughout the
years.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://www.pixelmator.com/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Pixelmator&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Great alternative to Photoshop. I&amp;rsquo;m not a designer, but sometimes when
Photoshop chokes on opening a specific file, Pixelmator always seems to
come through in the end.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://www.balsamiq.com/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Balsamiq Mockups&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Great tool for quick wireframing and rapid prototyping.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://imageoptim.com/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;ImageOptim&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Use this to additionally compress your images and get them ready for
website use to ensure speed in loading the media assets.&lt;/p&gt;
&lt;h2 id=&#34;business&#34;&gt;
  Business
  &lt;a class=&#34;heading-link&#34; href=&#34;#business&#34;&gt;
    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;
    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;
  &lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;http://www.marketcircle.com/billings/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Billings&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This is a great app that I use daily to track my time and send invoices.
It also lets me see what payments are outstanding from each client. It
has a handy timer in the menu bar that lets you track time at any given
point with whatever you&amp;rsquo;re doing.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://www.omnigroup.com/products/omniplan/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;OmniPlan 2&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Great tool that I started using last year to create estimates for
clients. I mostly love any tool that Omni Group makes.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://notational.net/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Notational Velocity with Simplenote
integration&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Great for quick, free form note taking. Notational Velocity lets you
simply type in search terms in the top bar and it will search your notes
for it.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://www.iawriter.com/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;iA Writer&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Simple, fantastic tool for writing. Has Markdown support!&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://itunes.apple.com/us/app/soulver/id413965349?mt=12&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Soulver&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;A neat little calculator that uses some natural language to give you the
answer.&lt;/p&gt;
&lt;p&gt;ScanSnap Manager &lt;a href=&#34;http://www.amazon.com/Fujitsu-ScanSnap-Instant-Sheet-Fed-Macintosh/dp/B001XWCQO2/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Amazon
link&lt;/a&gt;,
since Fujitisu is more likely to change their URL than Amazon.&lt;/p&gt;
&lt;p&gt;I scan all my physical documents with the ScanSnap S1500M and use OCR
scanning to make the entire document searchable.&lt;/p&gt;
&lt;h2 id=&#34;socialfun&#34;&gt;
  Social/Fun
  &lt;a class=&#34;heading-link&#34; href=&#34;#socialfun&#34;&gt;
    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;
    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;
  &lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;http://www.adium.im/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Adium&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I use Adium for instant messaging as it allows you to sign in with
multiple types of accounts at once. I know iChat is getting better, but
I&amp;rsquo;ve been a long time user of Adium and feels like home to me.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://propaneapp.com/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Propane&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Great dedicated application for Campfire, so you don&amp;rsquo;t need to use the
browser to access it. Feels more like native IM now.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://codeux.com/textual/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Textual&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Great GUI for IRC. I used to just connect in my Emacs window, however it
proved to be too distracting when working.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://www.echofon.com/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Echofon&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;My Twitter client of choice.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://reederapp.com/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Reeder&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Great Google Reader application, now with Readability support.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://skitch.com/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Skitch&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Great to making those always funny memes&amp;hellip;and sending work stuff to
people.&lt;/p&gt;
&lt;h2 id=&#34;thats-it&#34;&gt;
  That&amp;rsquo;s it!
  &lt;a class=&#34;heading-link&#34; href=&#34;#thats-it&#34;&gt;
    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;
    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;
  &lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Like many people in my profession, I consider myself to be a bit of a
software junkie&amp;hellip;and with good reason! Just like with programming
languages - there&amp;rsquo;s always the right tool for the right job. This was a
fun little exercise to go over the tools I use on a daily basis and I
hope this is helpful for some out there. In one of next articles, I plan
to write more about my development workflow and the tools I use in
greater detail.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>2011 In Review</title>
      <link>https://jonathanchu.is/posts/2011-in-review/</link>
      <pubDate>Sat, 21 Jan 2012 00:00:00 -0400</pubDate>
      <author>Jonathan Chu</author>
      <guid>https://jonathanchu.is/posts/2011-in-review/</guid>
      <description>&lt;p&gt;Since it seems that everyone and their mother is doing a &amp;ldquo;year in
review&amp;rdquo; post, I find it fitting that I be no different and write one as
well - except it&amp;rsquo;s three weeks later than everyone else. 2011 was an
exciting year for me for a variety of reasons, as I went through some
big work and life changes, met some great new friends, and reunited with
a few long lost ones.&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;
&lt;h2 id=&#34;work&#34;&gt;
  Work
  &lt;a class=&#34;heading-link&#34; href=&#34;#work&#34;&gt;
    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;
    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;
  &lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;In February of 2011, I left my job at
&lt;a href=&#34;http://www.exhibit-e.com/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;exhibit-E&lt;/a&gt; where I was a web developer
making web sites for the art world. Over the past few years, I&amp;rsquo;ve always
done freelance work on the side whether it be small contract jobs or
building full social networking websites as a solo developer. My
decision to leave exhibit-E seemed to make sense now - I wanted to see
if I had what it took to survive as a full-time freelancer while working
under my own company name before I got too old and perhaps couldn&amp;rsquo;t take
on so much risk. I wasn&amp;rsquo;t too concerned with finding work, but more so
about being able to &lt;strong&gt;GROW&lt;/strong&gt; my own company; the latter obviously being
the hardest part. Within a week or two, I managed to land myself a great
gig as the lead developer for the RachaelRayShow.com&amp;hellip;and now it was
off to the races!&lt;/p&gt;
&lt;h2 id=&#34;conferences&#34;&gt;
  Conferences
  &lt;a class=&#34;heading-link&#34; href=&#34;#conferences&#34;&gt;
    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;
    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;
  &lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;In March, I went to &lt;a href=&#34;https://us.pycon.org&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;PyCon&lt;/a&gt; 2011 in Atlanta, GA.
This was my first programming conference and I met some fantastically
smart people there - some of which I&amp;rsquo;m fortunate to actually work with
right now on some of 3atmosphere&amp;rsquo;s current projects, and some that I
still keep in contact with via email. The talks were great and the
&amp;ldquo;networking&amp;rdquo; at night (aka exploring ATL&amp;rsquo;s nightlife) was the best part
of the trip. I&amp;rsquo;m really looking forward to returning to PyCon again this
year.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://jonathanchu.is/images/IMG_1116.jpg&#34; alt=&#34;Nick&amp;rsquo;s new laptop&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;a href=&#34;https://twitter.com/nficano&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Nick&lt;/a&gt; holding up his new laptop that
we bought at a mall in Atlanta during PyCon&amp;hellip;during iPad 2 (insanity)
launch day!&lt;/em&gt;&lt;/p&gt;
&lt;h2 id=&#34;more-work&#34;&gt;
  More Work!
  &lt;a class=&#34;heading-link&#34; href=&#34;#more-work&#34;&gt;
    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;
    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;
  &lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Over the next few months into the early summer, the project load at
3atmospheres really started to pick up. I take pride in the fact that I
never made one cold call or solicited ads for work - all the requests we
got in were from word-of-mouth and I couldn&amp;rsquo;t be more proud of our
humble beginning. It picked up so much that the once lonely one-man show
(me!) turned into (at the peak) six people working on several different
projects. I found myself quickly transitioning from coding to project
management, which I would say still is evenly split for me today. Out of
necessity for a meeting spot, we bought some seats at &lt;a href=&#34;https://generalassemb.ly/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;General
Assembly&lt;/a&gt; where we currently work.&lt;/p&gt;
&lt;p&gt;On a personal note, I got engaged at the end of the summer to my lovely
girlfriend of over four years,
&lt;a href=&#34;http://patriciaandjonathan.com/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Patricia&lt;/a&gt;, which easily made 2011 the
best year of my life thus far.&lt;/p&gt;
&lt;h2 id=&#34;more-conferences&#34;&gt;
  More Conferences!
  &lt;a class=&#34;heading-link&#34; href=&#34;#more-conferences&#34;&gt;
    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;
    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;
  &lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;In September, I was fortunate enough to get to go to three conferences:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;http://djangocon.us/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;DjangoCon&lt;/a&gt; (Portland)&lt;/li&gt;
&lt;li&gt;PyGotham (NYC)&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://strataconf.com/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Strata Conference&lt;/a&gt; (NYC)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And for the rest of the fall season into winter, it was just work, work,
and more work - literally every free hour I had was devoted to meeting
the deadlines that were set at the end of the year.&lt;/p&gt;
&lt;h2 id=&#34;lets-wrap-it-up&#34;&gt;
  Let&amp;rsquo;s Wrap It Up&amp;hellip;
  &lt;a class=&#34;heading-link&#34; href=&#34;#lets-wrap-it-up&#34;&gt;
    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;
    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;
  &lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;2011 was a great year and I&amp;rsquo;ve never worked harder, been more tired,
and, at the same time, had as much fun as I&amp;rsquo;ve ever had in my
professional career. I am so lucky to have gotten to meet and work with
such smart people, clients and coworkers alike, and I&amp;rsquo;m extremely proud
at how far we&amp;rsquo;ve come today. Admittedly, it wasn&amp;rsquo;t always rainbows and
butterflies with work, but for all the negative moments I&amp;rsquo;ve had this
year, I&amp;rsquo;ve used it as a learning experience and I wouldn&amp;rsquo;t trade it for
a second. I get to program in languages and frameworks of my choosing
(Python and Django!) and get to work with
&lt;a href=&#34;https://twitter.com/ryanquigley&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;people&lt;/a&gt;
&lt;a href=&#34;https://twitter.com/nficano&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;that&lt;/a&gt;
&lt;a href=&#34;https://twitter.com//bingimar&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;are&lt;/a&gt;
&lt;a href=&#34;https://twitter.com/arronhunt&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;smarter&lt;/a&gt;
&lt;a href=&#34;https://twitter.com/iancohen&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;than&lt;/a&gt;
&lt;a href=&#34;https://twitter.com/ginlane&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;me&lt;/a&gt;. Here&amp;rsquo;s to a great 2011 and an even
better 2012!&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Virtualenv and pip Basics</title>
      <link>https://jonathanchu.is/posts/virtualenv-and-pip-basics/</link>
      <pubDate>Wed, 09 Feb 2011 00:00:00 -0400</pubDate>
      <author>Jonathan Chu</author>
      <guid>https://jonathanchu.is/posts/virtualenv-and-pip-basics/</guid>
      <description>&lt;p&gt;When doing any kind of Python development, one tool I find indispensable
is &lt;a href=&#34;http://pypi.python.org/pypi/virtualenv&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;virtualenv&lt;/a&gt;. Virtualenv,
along with
&lt;a href=&#34;http://www.doughellmann.com/projects/virtualenvwrapper/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;virtualenvwrapper&lt;/a&gt;
and &lt;a href=&#34;http://pypi.python.org/pypi/pip&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;pip&lt;/a&gt;, make for a great way to
completely isolate your development environment.&lt;/p&gt;
&lt;p&gt;When I first started out developing Django sites, I used to use
&lt;a href=&#34;http://packages.python.org/distribute/easy_install.html&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;easy_install&lt;/a&gt;
to install all packages I needed to the system-wide &lt;code&gt;site-packages&lt;/code&gt;
directory. Even as a newbie to Django, I knew this wasn&amp;rsquo;t good practice,
but it ensured that commonly used libraries such as &lt;code&gt;MySQL-python&lt;/code&gt; was
available without any extra configuration with new projects. Regardless,
completely isolating your environment with virtualenv ensures that a)
you don&amp;rsquo;t install conflicting packages and b) any bugs introduced in
your project can be traced back directly to the packages you installed.
Also, a huge benefit is that it makes installing multiple versions of
Python super easy without having to create any symlinks.&lt;/p&gt;
&lt;h2 id=&#34;getting-started-with-virtualenv-and-pip&#34;&gt;
  Getting started with Virtualenv and pip
  &lt;a class=&#34;heading-link&#34; href=&#34;#getting-started-with-virtualenv-and-pip&#34;&gt;
    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;
    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;
  &lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;The first thing you will need to do is install pip. If you have
setuptools installed, which you most likely will with most modern
platforms, you can install pip through easy_install:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;easy_install pip
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, you&amp;rsquo;ll need to install virtualenv with pip:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;pip install virtualenv
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Finally, I would highly recommend installing virtualenvwrapper as it
makes it much easier to create and start virtual environments:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;pip install virtualenvwrapper
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As part of the install instructions for virtualenvwrapper, you need to
add this to your .bash_profile&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# virtualenv
export WORKON_HOME=$HOME/.virtualenvs
source /Library/Frameworks/Python.framework/Versions/2.7/bin/virtualenvwrapper.sh
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;Please note that this path may differ depending on what version of
Python you have. Also, I like to keep all my virtualenvs in a
directory called &lt;code&gt;.virtualenvs&lt;/code&gt; in my home directory, but this may
differ for you if you choose to keep your virtual environments in a
different directory.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Make sure you source your new &lt;code&gt;.bash_profile&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;source ~/.bash_profile
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;hellip;and that&amp;rsquo;s it! Now you&amp;rsquo;re all set to start using virtual
environments!&lt;/p&gt;
&lt;h2 id=&#34;creating-a-virtual-environment&#34;&gt;
  Creating a Virtual Environment
  &lt;a class=&#34;heading-link&#34; href=&#34;#creating-a-virtual-environment&#34;&gt;
    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;
    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;
  &lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;A few handy aliases I have in my &lt;code&gt;.bash_profile&lt;/code&gt; are found on &lt;a href=&#34;http://blog.doughellmann.com/2010/01/virtualenvwrapper-tips-and-tricks.html&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Doug
Hellmann&amp;rsquo;s
blog&lt;/a&gt;
and listed below:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# virtualenv aliases
# http://blog.doughellmann.com/2010/01/virtualenvwrapper-tips-and-tricks.html
alias v=&#39;workon&#39;
alias v.deactivate=&#39;deactivate&#39;
alias v.mk=&#39;mkvirtualenv --no-site-packages&#39;
alias v.mk_withsitepackages=&#39;mkvirtualenv&#39;
alias v.rm=&#39;rmvirtualenv&#39;
alias v.switch=&#39;workon&#39;
alias v.add2virtualenv=&#39;add2virtualenv&#39;
alias v.cdsitepackages=&#39;cdsitepackages&#39;
alias v.cd=&#39;cdvirtualenv&#39;
alias v.lssitepackages=&#39;lssitepackages&#39;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This saves some keystrokes, especially since I always create new virtual
environments with the &lt;code&gt;--no-site-packages&lt;/code&gt; switch to ensure a completely
clean environment.&lt;/p&gt;
&lt;p&gt;To create and start a new virtual environment with &lt;code&gt;--no-site-packages&lt;/code&gt;,
enter:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ v.mk myvirtualenv
New python executable in myvirtualenv/bin/pythonInstalling setuptools............done.
(myvirtualenv) $
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This creates and virtual environment and makes it active. To deactivate
it, you can simply type:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(myvirtualenv) $ deactivate
$
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So let&amp;rsquo;s go ahead and start our virtual environment once again and
install some packages to it.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ v myvirtualenv
(myvirtualenv) $
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We&amp;rsquo;re going to install Python package &lt;code&gt;Yolk&lt;/code&gt; as it is a useful command
line utility that lists the packages installed for the environment.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(myvirtualenv) $ pip install yolk
Downloading/unpacking yolk
  Downloading yolk-0.4.1.tar.gz (80Kb): 80Kb downloaded
  Running setup.py egg_info for package yolk

Requirement already satisfied (use --upgrade to upgrade): setuptools in /Users/jonathan/.virtualenvs/myvirtualenv/lib/python2.7/site-packages/setuptools-0.6c11-py2.7.egg (from yolk)
Installing collected packages: yolk
  Running setup.py install for yolk

    Installing yolk script to /Users/jonathan/.virtualenvs/myvirtualenv/bin

Successfully installed yolk
Cleaning up...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now you can use &lt;code&gt;yolk -l&lt;/code&gt; to list the packages installed for this
virtual environment:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(myvirtualenv) $ yolk -l
Python          - 2.7.1        - active development
(/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-dynload)
pip             - 0.8.1        - active
setuptools      - 0.6c11       - active
wsgiref         - 0.1.2        - active development
(/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7)
yolk            - 0.4.1        - active
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here is a brief one-line example showing how to create a virtualenv and
install Django, MySQL Python, South, Python Imaging Library (PIL), and
ImageKit using pip:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ v.mk newdjangoenv
(newdjangoenv) $ pip install django MySQL-python south pil django-imagekit
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When you have your requirements installed, it&amp;rsquo;s always good to take a
snapshot of the requirements and the current versions. You can do this
by typing &lt;code&gt;freeze&lt;/code&gt; and specifying an output file:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(newdjangoenv) $ pip freeze &amp;gt; requirements.txt
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And finally, you can use the &lt;code&gt;requirements.txt&lt;/code&gt; file so that your
environment is completely and easily replicable:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ pip install -r requirements.txt
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And there you have it &amp;ndash; you can now create and test your Python
applications in completely isolated environments!&lt;/p&gt;
&lt;p&gt;For more on pip and virtualenv, check out this great post by &lt;a href=&#34;http://www.saltycrane.com/blog/2009/05/notes-using-pip-and-virtualenv-django/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Salty
Crane&lt;/a&gt;
which got me started on all this.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>New Blog Platform</title>
      <link>https://jonathanchu.is/posts/new-blog-platform/</link>
      <pubDate>Tue, 18 Jan 2011 00:00:00 -0400</pubDate>
      <author>Jonathan Chu</author>
      <guid>https://jonathanchu.is/posts/new-blog-platform/</guid>
      <description>&lt;p&gt;After a long blogging hiatus, I recently decided to switch over my
custom Django blog to a static site generator, following the trend that
&lt;a href=&#34;https://github.com/mojombo/jekyll&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;many&lt;/a&gt;
&lt;a href=&#34;https://github.com/lakshmivyas/hyde&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;others&lt;/a&gt; have started. What made
the switch so appealing, going from a full-featured blogging engine to a
simple static site generator, was that I could write my blog entries in
a text editor of my choice and keep everything under version control
with Git. A simple push to the production server would serve my static
pages up via Nginx, which in the end would take up far less resources
and memory than a Django-powered blog application or even Wordpress. So
with that, I decided to search for a static site generator that would
suit me. I did some research and narrowed my choices down to three
static site generators:&lt;/p&gt;
&lt;!-- PELICAN_END_SUMMARY --&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/mojombo/jekyll&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Jekyll&lt;/a&gt; (Ruby-based)&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://ringce.com/hyde&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Hyde&lt;/a&gt; (Python-based)&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/xfire/growl&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Growl&lt;/a&gt; (Python-based)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Jekyll is the creation of &lt;a href=&#34;http://twitter.com/#!/mojombo&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;@mojombo&lt;/a&gt;, in
which he refers to it as &lt;a href=&#34;http://tom.preston-werner.com/2008/11/17/blogging-like-a-hacker.html&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;&amp;ldquo;Blogging Like a
Hacker&amp;rdquo;&lt;/a&gt;
as he so eloquently put it in his article. He pretty much hit the nail
on the head; blogging becomes a bit of a hassle when you use a
complicated blogging engine like Wordpress and the likes.
&lt;a href=&#34;https://github.com/mojombo/jekyll/wiki/sites&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Many&lt;/a&gt; are using Jekyll
and seem to be very happy with it.&lt;/p&gt;
&lt;p&gt;In the end, I decided to go with
&lt;a href=&#34;https://github.com/xfire/growl&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Growl&lt;/a&gt;. I chose Growl because it was
pure Python, had support for &lt;a href=&#34;http://jinja.pocoo.org/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Jinja2&lt;/a&gt;, and was
extremely lightweight with few dependencies. I decided not to go with
Jekyll, arguably the most popular static site generator currently out
there, because I wasn&amp;rsquo;t too fond of the templating language. Also, I
decided not to go with Hyde simply because I prefer Jinja2 over Django
templates, which is utilized in Hyde.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/xfire/growl&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Growl&lt;/a&gt; is written by &lt;a href=&#34;http://downgra.de/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Rico
Schiekel&lt;/a&gt; and &amp;ldquo;shamelessly stole some really cool
ideas from Jekyll&amp;rdquo;, which is absolutely awesome in my opinion. I think
it&amp;rsquo;s great that software can be created from borrowing the best parts of
other pieces of software, regardless of language.&lt;/p&gt;
&lt;p&gt;This blog is written and compiled with a slightly modified version of
&lt;a href=&#34;https://github.com/jonathanchu/growl&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Growl&lt;/a&gt;. So far, I&amp;rsquo;m loving the
writing process:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Write the article in Emacs&lt;/li&gt;
&lt;li&gt;Commit to Git repository&lt;/li&gt;
&lt;li&gt;Rsync the changes to my production server&lt;/li&gt;
&lt;li&gt;&amp;hellip;and that&amp;rsquo;s it!&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can find out more about
&lt;a href=&#34;https://github.com/jonathanchu/growl&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Growl&lt;/a&gt; by reading its
documentation. Here are some of the main features of Growl:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Pages and posts have a YAML header&lt;/li&gt;
&lt;li&gt;Pages and posts are written in Markdown&lt;/li&gt;
&lt;li&gt;Layouts are written in HTML and Jinja2&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The basic structure of my blog looks something like this:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://jonathanchu.is/images/jontourage_dir_structure.png&#34; alt=&#34;Jontourage Directory
Structure&#34;&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;_hooks&lt;/code&gt; contains Python scripts that extend Growl&lt;/li&gt;
&lt;li&gt;&lt;code&gt;_layout&lt;/code&gt; contains the basic layouts for your site&lt;/li&gt;
&lt;li&gt;&lt;code&gt;_libs&lt;/code&gt; contains any third party libraries you want to use&lt;/li&gt;
&lt;li&gt;&lt;code&gt;_posts&lt;/code&gt; contains all the posts&lt;/li&gt;
&lt;li&gt;&lt;code&gt;css&lt;/code&gt; and &lt;code&gt;img&lt;/code&gt; contain all the stylesheets and site media,
respectively&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;All files that end with an underscore, such as &lt;code&gt;index.html_&lt;/code&gt; for
example, get processed by Growl as a page. All processed pages and media
assets get dumped in the &lt;code&gt;deploy&lt;/code&gt; directory, which serves up your static
site.&lt;/p&gt;
&lt;p&gt;Posts need to be named in the following structure:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;2011-01-18-new-blog-platform.md2
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When the posts are processed by Growl, the date &lt;code&gt;2011-01-18&lt;/code&gt; gets parsed
and the directory structure is created -
&lt;a href=&#34;http://jontourage.com&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;http://jontourage.com&lt;/a&gt;**/2011/01/18/new-blog-platform/**&lt;/p&gt;
&lt;p&gt;As for the post content itself, it simply is a mix of YAML and Markdown.
Here&amp;rsquo;s an example of what a post header looks like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;---
layout: post
title: New Blog Platform
publish: false
---
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And the rest of the post is just Markdown! When I&amp;rsquo;m done writing the
article, I simply push to GitHub and sync up the production server using
a rsync hook:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ growl.py --deploy jontourage
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And that&amp;rsquo;s it! You can checkout my blog and the structure in more detail
&lt;a href=&#34;https://github.com/jonathanchu/jontourage&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;here&lt;/a&gt;.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Review: MacBook Air 13</title>
      <link>https://jonathanchu.is/posts/review-macbook-air-13/</link>
      <pubDate>Mon, 10 Jan 2011 00:00:00 -0400</pubDate>
      <author>Jonathan Chu</author>
      <guid>https://jonathanchu.is/posts/review-macbook-air-13/</guid>
      <description>&lt;p&gt;I recently decided to purchase a MacBook Air to use as my primary
computer, saying goodbye to my previous laptop - a 15&amp;quot; MacBook Pro with
a HiRes AntiGlare display, 2.66GHz i7, 8GB RAM, and 500GB HD @ 7200RPM,
NVIDIA GeForce GT 330M with 512MB memory. I went with the 13&amp;quot;, 2.13GHz
Core 2 Duo, 4GB RAM, 256GB flash storage configuration and could not be
happier with its performance. Portability was a very important factor to
me in making this decision, as I carry my laptop with me everyday. It&amp;rsquo;s
been serving as my primary computer for the past three weeks and the
transition has been absolutely seamless.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://jonathanchu.is/images/L1040591.jpg&#34; alt=&#34;MBA 1&#34;&gt;&lt;/p&gt;
&lt;h2 id=&#34;hardware&#34;&gt;
  Hardware
  &lt;a class=&#34;heading-link&#34; href=&#34;#hardware&#34;&gt;
    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;
    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;
  &lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;The Air weighs in at about 3 lbs and is surprisingly sturdy in terms of
build. Being a MacBook Pro user for most of my developer life, I was a
little wary that the build quality was going to be less sturdy from what
I&amp;rsquo;m used to, which was not the case at all. The glossy screen on the Air
was a concern of mine before purchasing, especially since I just came
from a matte display. The glossy screen on the stock MacBook Pro&amp;rsquo;s is
just too glossy for me to not be annoying. The Air is a good middle
ground - albeit not matte, it offers good enough contrast and isn&amp;rsquo;t as
glossy as the MacBook Pro line. One thing I am missing on the Air is a
backlit keyboard. The lack of ethernet port has never bothered me as I
have a wireless-N network at home which offer better speeds than your
average B/G network.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://jonathanchu.is/images/L1040583.jpg&#34; alt=&#34;MBA 2&#34;&gt;&lt;/p&gt;
&lt;p&gt;One thing that does annoy me is that the Air does not fit well on my
&lt;a href=&#34;http://www.amazon.com/gp/product/B000OOYECC?ie=UTF8&amp;amp;tag=jontourage-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=390957&amp;amp;creativeASIN=B000OOYECC&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Rain Design mStand&lt;/a&gt;.
As you can see in the picture below, aluminum does not rest on the pads
because of the thinness.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://jonathanchu.is/images/L1040585.jpg&#34; alt=&#34;MBA 3&#34;&gt;&lt;/p&gt;
&lt;h2 id=&#34;performance&#34;&gt;
  Performance
  &lt;a class=&#34;heading-link&#34; href=&#34;#performance&#34;&gt;
    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;
    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;
  &lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Despite the fact that the Air has a far inferior processor and only half
the amount of RAM as my previous laptop, I can honestly say that the Air
just feels faster. Most applications launch within one second, such as
the Microsoft Office apps, while the Adobe CS5 Suite launches within a
respectable two to three seconds. The flash storage is the obvious
difference maker here. As for configuration, I decided to start with a
new install and not restore from a Time Machine backup. The first thing
I did was install Xcode and
&lt;a href=&#34;http://mxcl.github.com/homebrew/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Homebrew&lt;/a&gt;, along with a bunch of apps
that I use daily for development. At the end of the whole config and
install process, the &lt;code&gt;Applications&lt;/code&gt; folder takes up about 15GB and my
iTunes library takes up about 47GB of disk space, leave roughly 135GB
remaining - which is more than enough space left. Considering what&amp;rsquo;s on
the flash storage, it takes ~15 seconds to boot up and ~25 seconds to
shut down.&lt;/p&gt;
&lt;p&gt;The resolution on the Air is 1440x900, which is the same as the 15&amp;quot;
MacBook Pro, but greater than the 13&amp;quot; MacBook Pro&amp;rsquo;s 1280x800. When I&amp;rsquo;m
at home, the Air is connected to my Apple LED Cinema Display 24&amp;quot; model
(discontinued) and supports 1920x1200. The connectors make for a perfect
fit being that the MiniDisplay Port is on the right side of the laptop,
while the power and USB are on the left.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://jonathanchu.is/images/L1040586.jpg&#34; alt=&#34;MBA 4&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://jonathanchu.is/images/L1040589.jpg&#34; alt=&#34;MBA 5&#34;&gt;&lt;/p&gt;
&lt;p&gt;As far as graphic intensive applications and games, I haven&amp;rsquo;t tried
playing any games or doing any video editing, but I can imagine there
will be some limitations. I&amp;rsquo;ve read in several places that games such as
World of Warcraft and StarCraft II run perfectly fine on the MacBook
Airs and may even start up faster, but the framerate is lower. This is a
limitation I can deal with given the hardware.&lt;/p&gt;
&lt;h3 id=&#34;likes&#34;&gt;
  Likes
  &lt;a class=&#34;heading-link&#34; href=&#34;#likes&#34;&gt;
    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;
    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;
  &lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Portability&lt;/li&gt;
&lt;li&gt;Boots up in about 15 seconds&lt;/li&gt;
&lt;li&gt;Almost all applications launch within 1-3 seconds&lt;/li&gt;
&lt;li&gt;Battery life upwards of 8 hours (50% screen brightness)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;dislikes&#34;&gt;
  Dislikes
  &lt;a class=&#34;heading-link&#34; href=&#34;#dislikes&#34;&gt;
    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;
    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;
  &lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Glossy screen&lt;/li&gt;
&lt;li&gt;No backlit keyboard&lt;/li&gt;
&lt;li&gt;Not (easily) upgradable&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;conclusion&#34;&gt;
  Conclusion
  &lt;a class=&#34;heading-link&#34; href=&#34;#conclusion&#34;&gt;
    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;
    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;
  &lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;I feel like the MBA is changing the way I work and I absoutely love
that. Now that I have a more portable laptop, I find myself working in
places that I normally wouldn&amp;rsquo;t (and didn&amp;rsquo;t with my 15&amp;quot; MacBook Pro,
i.e. - on the couch in front of the TV). If not having a DVD drive is a
dealbreaker, I would say this isn&amp;rsquo;t the laptop for you. All in all, I
could not be happier with the Air. It&amp;rsquo;s an excellent laptop and has been
able to handle all my tasks with ease.&lt;/p&gt;
</description>
    </item>
  </channel>
</rss>
