<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://www.sanityinc.com/feed.xml" rel="self" type="application/atom+xml" /><link href="https://www.sanityinc.com/" rel="alternate" type="text/html" /><updated>2026-03-24T10:02:50+00:00</updated><id>https://www.sanityinc.com/feed.xml</id><title type="html">sanity, inc.</title><subtitle>Simple thinking for complex software.</subtitle><entry><title type="html">Package and deploy Python apps faster with Poetry and Nix</title><link href="https://www.sanityinc.com/articles/nix-tools-for-python-development/" rel="alternate" type="text/html" title="Package and deploy Python apps faster with Poetry and Nix" /><published>2020-09-02T00:00:00+00:00</published><updated>2020-09-02T00:00:00+00:00</updated><id>https://www.sanityinc.com/articles/nix-tools-for-python-development</id><content type="html" xml:base="https://www.sanityinc.com/articles/nix-tools-for-python-development/"><![CDATA[<p>I made a screencast for <a href="https://tweag.io">Tweag</a> to showcase how some
Nix-based tools can help with Python development, and of course there
are some Emacs tricks along the way.</p>

<!--more-->

<div style="position: relative; padding: 30px 0 56.25% 0; height: 0; overflow: hidden; margin-bottom:2em;">
<iframe style="position:absolute;top:0;left:0;width:100%;height:100%" src="//www.youtube.com/embed/TbIHRHy7_JM" frameborder="0" allowfullscreen=""></iframe>
</div>

<p>Check out <a href="https://www.tweag.io/blog/2020-08-12-poetry2nix/">this related
post</a> on the Tweag
blog, plus the <a href="https://github.com/pashky/restclient.el">restclient</a>
and <a href="https://github.com/akermu/emacs-libvterm">vterm</a> packages for
Emacs.</p>]]></content><author><name></name></author><category term="Nix" /><category term="Emacs" /><category term="Python" /><summary type="html"><![CDATA[I made a screencast for Tweag to showcase how some Nix-based tools can help with Python development, and of course there are some Emacs tricks along the way.]]></summary></entry><entry><title type="html">Our use of the Haskell and Elm programming languages</title><link href="https://www.sanityinc.com/articles/why-we-use-haskell-and-elm/" rel="alternate" type="text/html" title="Our use of the Haskell and Elm programming languages" /><published>2018-07-13T00:00:00+00:00</published><updated>2018-07-13T00:00:00+00:00</updated><id>https://www.sanityinc.com/articles/why-we-use-haskell-and-elm</id><content type="html" xml:base="https://www.sanityinc.com/articles/why-we-use-haskell-and-elm/"><![CDATA[<p>Over the last year, our team has built a beautiful and advanced Smart Cities system using functional languages. I wrote this document to explain our technology choices to stakeholders and partners.</p>

<!-- more -->

<h2 id="introduction">Introduction</h2>

<p>A number of programming languages - Haskell, Elm, Ruby, JavaScript/TypeScript, Rust, SQL - are being used in the construction of our systems. This variety is common in industry, since large software systems are increasingly being built of several smaller programs (including browser applications) which collaborate via HTTP and REST APIs, and therefore need not be written in the same language.</p>

<h2 id="industry-trends-in-programming-languages">Industry trends in programming languages</h2>

<p>Programming languages and environments have evolved continuously as computing power has increased. Java and C# used more memory and processor cycles than C/C++, but came with virtual machines that could run code compiled anywhere, so they became popular. Interpreted languages such as Python, PHP, JavaScript and Ruby can be interpreted fast enough that their programs can be run instantly so their behaviour can be observed immediately.</p>

<p>Those changes have largely resulted from being able to run programs faster, but importantly, programmers now have enough power on their desktop computers to use tools that can inspect their code before it runs, perform sophisticated analysis of its structure and implications, and use that analysis to provide feedback to the programmer. In this way, developers can <em>use</em> software to help them to <em>write</em> high quality code!</p>

<p>The fundamental design of most programming languages - including Java, C#, JavaScript, Python, C, C++ - is unfortunately such that this “static analysis” of code can only provide limited help and assurances to the programmer. It is therefore common in the software industry to deliver software that exhibits many bugs when it is run, or software that is expensive and risky to change because it is difficult to know whether changes have broken something.</p>

<p>A separate category of languages were built to allow static analysis of program correctness at development time. The most mature of these languages, <a href="https://en.wikipedia.org/wiki/Haskell_(programming_language)">Haskell</a>, has been continuously developed as an open standard since its first version in 1990, and is seeing industrial use by <a href="https://wiki.haskell.org/Haskell_in_industry">companies such as Facebook, Google, Microsoft, AT&amp;T, the New York Times and various investment banks</a>. In turn, features of those advanced languages have influenced newer hybrid languages such as Scala and Apple’s Swift. <a href="https://elm-lang.org/">Elm</a> is a Haskell-like language which offers the safety of Haskell but produces JavaScript code that can be run in a browser. Overall, these advanced languages are set to grow dramatically in use.</p>

<h2 id="choosing-the-best-tool-for-the-job">Choosing the best tool for the job</h2>

<p>Mainstream programming languages offer some advantages because they are in more widespread use: expertise is more available online and in the labour market, and a wide range of code libraries and vendors support those languages. In our technology group, we use a combination of more mainstream languages and Haskell and Elm, following the principle of choosing the best tool for the job.</p>

<p>Some functionality of our system, such as managing users and access control, is a commodity for which widely-used packaged code exists for the popular Ruby language, so we use that. In contrast, the novel functionality with which our system provides its unique value to our customers is the ability to process and query huge quantities of geographic data, and to explore it via a sophisticated browser-based visualisation engine. It is for these novel functions we have chosen Haskell and Elm.</p>

<h2 id="haskell-for-expressing-complex-behaviour">Haskell for expressing complex behaviour</h2>

<p>Haskell has excellent libraries for integrating with databases and web services, and for building API services. Our systems pass all of their geographic data through an API server written in Haskell, and not only must this server be reliable and fast, it must also be possible to evolve its design rapidly as we discover new requirements without breaking existing code.</p>

<p>Even when we make dramatic changes, Haskell’s language design and its development tools tell us if those changes are inconsistent with the existing design, and they require that we eliminate those inconsistencies. Those same tools help us to be confident that we are correctly handling all the possible inputs and outputs, which we model with Haskell’s advanced datatype system. The tools force us to consider every possible failure case, so that our programs will handle them appropriately.</p>

<p>The net result of this has been that we simply do not experience unexpected errors in our Haskell programs when they are deployed, so we can deploy new releases confidently and spend our time building valuable features rather than investigating run-time failures.</p>

<h2 id="building-beautiful-reliable-web-interfaces">Building beautiful, reliable web interfaces</h2>

<p>Elm has brought comparable benefits to the development of our web application interface: with a complex set of interrelated controls and information on the screen, it’s important to maintain consistency of display, particularly when new data is being loaded periodically from multiple servers. It is generally extremely hard to write such applications reliably in JavaScript, but Elm lets us program and analyse our web application interface code correctly, and then it produces JavaScript which runs absolutely reliably in the browser. Our users almost never experience programmer errors in the interface, since the Elm language and tools ensure that we specify the code’s behaviour correctly before it even runs in the user’s browser.</p>

<h2 id="language-choice-and-our-team">Language choice and our team</h2>

<p>Both the Haskell and Elm code-bases are worked upon by multiple developers simultaneously, and often experience significant change, but the associated language tools have consistently ensured that the team members have not accidentally broken each other’s work. Even as our code-bases have grown significantly, they have remained easy to work with.</p>

<p>The pool of developers available in the labour market with experience in these languages is relatively small, but very smart developers who value correctness of software have applied to us and been hired because we are using these interesting languages. Groups using Haskell in industry universally report that job applicants are plentiful, capable and motivated: the developers who are actively interested in learning progressive ideas and languages are exactly the ones who will succeed in a fast-moving environment building a complex product.</p>

<p>Some cross-training has been necessary for our team members with experience primarily in mainstream languages: it has taken the team a little time to learn the new languages and how to think about our code in the rigorous way they demand, which can be unfamiliar at first. Good software developers learn quickly, though, and our smart team of mixed industry experience levels has picked up and embraced both languages rapidly and enthusiastically. We are quickly becoming familiar with the tools, best practices and library ecosystem of each language, and our productivity is higher than we would have expected had we used only mainstream languages.</p>

<p>Industry support for the languages has increased significantly in the last decade, and is now very good. The Haskell and Elm software tools and libraries we rely on see regular releases and prompt bug-fixes, high-quality third party libraries are readily available for key parts of our applications, and online communities and reference information are readily available.</p>

<p>We are proud to be building complex software which consistently delights customers with its new features and reliability, and our language choices have contributed to our ability to do so.</p>]]></content><author><name></name></author><category term="Haskell" /><category term="Elm" /><summary type="html"><![CDATA[Over the last year, our team has built a beautiful and advanced Smart Cities system using functional languages. I wrote this document to explain our technology choices to stakeholders and partners.]]></summary></entry><entry><title type="html">An Emacs Chat with Sacha Chua</title><link href="https://www.sanityinc.com/articles/an-emacs-chat-with-sacha-chua/" rel="alternate" type="text/html" title="An Emacs Chat with Sacha Chua" /><published>2015-01-23T00:00:00+00:00</published><updated>2015-01-23T00:00:00+00:00</updated><id>https://www.sanityinc.com/articles/an-emacs-chat-with-sacha-chua</id><content type="html" xml:base="https://www.sanityinc.com/articles/an-emacs-chat-with-sacha-chua/"><![CDATA[<p>This week I was delighted to join Sacha Chua for the latest in her
popular series of “Emacs Chats”, in which she interviews notable Emacs
users.</p>

<!--more-->

<p>The discussion covered my background, history with Emacs, various tips
and tricks, and of course my involvement in <a href="https://melpa.org">MELPA</a>.</p>

<div style="position: relative; padding: 30px 0 56.25% 0; height: 0; overflow: hidden; margin-bottom:2em;">
<iframe style="position:absolute;top:0;left:0;width:100%;height:100%" src="//www.youtube.com/embed/Gq0hG_om9xY" frameborder="0" allowfullscreen=""></iframe>
</div>

<p>Sacha has a table of contents for the video
<a href="https://sachachua.com/blog/2015/01/emacs-chat-with-steve-purcell/?amp;shareadraft=baba27870_54bfd5841a433">over on her site</a>,
and if you like this video you should check out the
<a href="https://sachachua.com/emacs-chat/">other 17 she’s recorded to date</a>.</p>

<p>Thanks for having me, Sacha, and for all the work you do sharing
information so enthusiastically with your many readers!</p>]]></content><author><name></name></author><category term="Emacs" /><category term="MELPA" /><summary type="html"><![CDATA[This week I was delighted to join Sacha Chua for the latest in her popular series of “Emacs Chats”, in which she interviews notable Emacs users.]]></summary></entry><entry><title type="html">A Haskell Session With Ollie Charles For The Peer-To-Peer Video Series</title><link href="https://www.sanityinc.com/articles/haskell-peer-to-peer-session-with-ollie-charles/" rel="alternate" type="text/html" title="A Haskell Session With Ollie Charles For The Peer-To-Peer Video Series" /><published>2014-10-14T00:00:00+00:00</published><updated>2014-10-14T00:00:00+00:00</updated><id>https://www.sanityinc.com/articles/haskell-peer-to-peer-session-with-ollie-charles</id><content type="html" xml:base="https://www.sanityinc.com/articles/haskell-peer-to-peer-session-with-ollie-charles/"><![CDATA[<p>I recently sat down with local Haskell hero Ollie Charles to record a
video of him solving a fun programming problem.</p>

<!-- more -->

<p>Drew Neil’s
<a href="https://peertopeer.io/h/sp1/">Peer To Peer</a>
video series captures the working practices of experts in various
programming languages, providing viewers with tips, tricks and
insights.</p>

<p>Each video features a host, who brings along a task and acts as a
“customer”, and a guest, who has to solve the challenge in real time
using their tools of choice.</p>

<p>For this video, in which I was the host, I proposed that Ollie tackle
Dave Thomas’
<a href="https://codekata.com/kata/kata19-word-chains/">Word Chains Kata</a> – I
use this non-trivial problem myself whenever I learn a new programming
language, so I knew that it would keep Ollie on his toes.</p>

<p>Ollie’s <a href="https://ocharles.org.uk/">own site</a> is a treasure-trove of
carefully-explained Haskell tips and tricks, so I wasn’t surprised to
find myself enjoying his problem-solving approach and learning a lot.</p>

<p>To see what happened, check out the video:</p>

<p><a href="https://peertopeer.io/b/oc1/"><img src="/images/peertopeer-showreel.png" alt="" /></a></p>

<p>After the session, and having picked up a couple of new tricks from
Ollie, I even felt inspired to tackle the problem in Haskell
<a href="https://github.com/purcell/wordchainsrevenge">once more</a> myself.</p>

<p><em>Update: there’s also a great <a href="https://peertopeer.io/c/jw1">follow-up video</a>
featuring Ollie hosting John Wiegley</em></p>]]></content><author><name></name></author><category term="Haskell" /><summary type="html"><![CDATA[I recently sat down with local Haskell hero Ollie Charles to record a video of him solving a fun programming problem.]]></summary></entry><entry><title type="html">Swimming in code: recent hacks</title><link href="https://www.sanityinc.com/articles/swimming-in-code/" rel="alternate" type="text/html" title="Swimming in code: recent hacks" /><published>2010-09-05T00:00:00+00:00</published><updated>2010-09-05T00:00:00+00:00</updated><id>https://www.sanityinc.com/articles/swimming-in-code</id><content type="html" xml:base="https://www.sanityinc.com/articles/swimming-in-code/"><![CDATA[<p>Recently I’ve been on a hacking high, touching a lot of code, and in
touch with a lot of cool programmers. In retrospect I’m surprised at
the variety of stuff I’ve been doing, so I thought I’d write a short
list.</p>

<!-- more -->

<h3 id="open-source">Open source</h3>

<h4 id="javascript">Javascript</h4>

<ul>
  <li>I added support for Twitter’s “lists” to
  <a href="https://tweet.seaofclouds.com/">seaofclouds’ tweet.js widget</a>: see
  my <a href="https://github.com/purcell/tweet">clone on github</a>. You can see
  it in action at the bottom of
  <a href="https://www.looktothestars.org/">this page</a>.</li>
</ul>

<h4 id="clojure">Clojure</h4>

<ul>
  <li>Congomongo - Clojure’s de-facto standard library for accessing
  <a href="https://www.mongodb.org/">MongoDB</a> - had no support for MongoDB’s
  file
  <a href="https://www.mongodb.org/display/DOCS/GridFS+Specification">GridFS</a>
  file storage scheme, so I
  <a href="https://github.com/purcell/congomongo">added it</a>.</li>
  <li>When I’ve only had a few spare minutes, I’ve been
  <a href="https://github.com/purcell/rosettacode-clojure">filling in a few missing Clojure examples on Rosettacode</a>. It’s
  a great way to share knowledge, learn new libraries and
  algorithms, and solve puzzles.</li>
  <li>I’ve contributed minor patches to
  <a href="https://github.com/technomancy/leiningen">Leiningen</a>, the Clojure
  build tool.</li>
</ul>

<h4 id="ruby">Ruby</h4>

<ul>
  <li>Accepted some patches for my
  <a href="https://github.com/purcell/darcs-to-git">darcs-to-git</a> repository
  conversion script. (See
  <a href="/articles/converting-darcs-repositories-to-git">my original article about this</a>.)</li>
</ul>

<h4 id="python">Python</h4>

<ul>
  <li>I’ve agreed to review (but not write) the unit-testing chapter of
  the PSF’s planned Python book. Although I
  <a href="https://pyunit.sf.net">wrote the unittest module</a>, I’m no longer
  an active Python user or member of the community.</li>
</ul>

<h4 id="emacs-lisp">Emacs lisp</h4>

<ul>
  <li>My haml-mode patch for colorizing “filter:” blocks in haml files has
  been
  <a href="https://github.com/nex3/haml/commit/94a8228e">committed upstream</a>,
  so now textile, markdown, javascript and ruby portions of these
  files are font-locked correctly.</li>
  <li>Naturally, while I’ve been doing all this diverse hacking, I’ve been
  <a href="https://github.com/purcell/emacs.d/commits/master">tweaking my emacs config quite heavily</a>.</li>
</ul>

<h4 id="misc">Misc</h4>

<ul>
  <li>As I recently blogged, I
  <a href="/articles/open-txmt-urls-from-rails-in-emacs-on-osx">customised emacs-handler</a>
  and have played with
  <a href="/articles/full-screen-support-for-cocoa-emacs-on-osx">full-screen support for Cocoa Emacs</a>.</li>
</ul>

<h3 id="closed-source">Closed-source</h3>

<p>I have two main closed-source projects on my plate. The first, our
<a href="https://www.looktothestars.org">site about celebrities and the charities they support</a>,
has seen me doing a bunch of Twitter API hacking recently. The second
project, currently Top Secret, is a Clojure data-oriented website,
using MongoDB and fun stuff like geocoding and data mining.</p>

<h3 id="thoughts">Thoughts</h3>

<p>The programming ecosphere is more diverse than ever, and there are more
powerful tools available to programmers than ever before. It’s thrilling
to be involved with this, and to aid in the cross-pollination of tricks,
skills and idioms between unrelated projects. As a work-from-home
entrepreneur, collaborating remotely on open (and closed) source
projects with interesting people is a surprisingly good proxy for having
real officemates.</p>]]></content><author><name></name></author><category term="Emacs" /><category term="github" /><category term="javascript" /><category term="lisp" /><category term="python" /><category term="Ruby" /><summary type="html"><![CDATA[Recently I’ve been on a hacking high, touching a lot of code, and in touch with a lot of cool programmers. In retrospect I’m surprised at the variety of stuff I’ve been doing, so I thought I’d write a short list.]]></summary></entry><entry><title type="html">Save hours by reading mailing lists in Emacs over IMAP</title><link href="https://www.sanityinc.com/articles/read-mailing-lists-in-emacs-over-imap/" rel="alternate" type="text/html" title="Save hours by reading mailing lists in Emacs over IMAP" /><published>2010-09-05T00:00:00+00:00</published><updated>2010-09-05T00:00:00+00:00</updated><id>https://www.sanityinc.com/articles/read-mailing-lists-in-emacs-over-imap</id><content type="html" xml:base="https://www.sanityinc.com/articles/read-mailing-lists-in-emacs-over-imap/"><![CDATA[<p>Emacs’ built-in newsreader Gnus is made for efficiently keeping up
with high-volume lists; I show how to hook it into your IMAP account.</p>

<!-- more -->

<p>With features like configurable message threading, kill-files and
per-thread and per-poster scoring, Gnus has the potential to save a
lot of the time you would normally spend wading through high-volume
mailing lists.</p>

<p>Nowadays most people read mailing lists via IMAP-enabled mail
accounts, e.g. Gmail. Gnus supports IMAP directly, but it doesn’t work
well when the remote folders have thousands of messages, as is the
case with many mailing lists. As a workaround, we can use <a href="https://wiki.github.com/jgoerzen/offlineimap/">offlineimap</a>
to maintain a local copy of our folders. As a side benefit, we can
then read mail off-line.</p>

<p><em>(Update: since this article was written, Gnus IMAP support has
 improved, so the following steps may or may not be strictly
 necessary.)</em></p>

<p>We can use the excellent <a href="https://www.dovecot.org/">Dovecot</a> to provide an IMAP interface to that
local copy so that Gnus can access it; and we can do this without
configuring Dovecot as a full IMAP server, which would need to run
constantly and be configured for authentication etc.</p>

<p>On a Mac, you can install dovecot and offlineimap with <a href="https://github.com/mxcl/homebrew">Homebrew</a>,
MacPorts or, presumably, Fink.</p>

<p>In <code class="language-plaintext highlighter-rouge">~/.dovecotrc</code>:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>protocols = imap
mail_location = maildir:~/Library/Caches/OfflineImap
auth default {
}
</code></pre></div></div>

<p>And in <code class="language-plaintext highlighter-rouge">~/.offlineimaprc</code>:</p>

<div class="language-ini highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nn">[general]</span>
<span class="py">accounts</span> <span class="p">=</span> <span class="s">Mail</span>
<span class="py">maxsyncaccounts</span> <span class="p">=</span> <span class="s">1</span>
<span class="py">ui</span> <span class="p">=</span> <span class="s">TTY.TTYUI</span>
<span class="nn">[Account Mail]</span>
<span class="py">localrepository</span> <span class="p">=</span> <span class="s">Local</span>
<span class="py">remoterepository</span> <span class="p">=</span> <span class="s">Remote</span>
<span class="nn">[Repository Local]</span>
<span class="py">type</span> <span class="p">=</span> <span class="s">IMAP</span>
<span class="py">preauthtunnel</span> <span class="p">=</span> <span class="s">dovecot -c ~/.dovecotrc --exec-mail imap</span>
<span class="nn">[Repository Remote]</span>
<span class="py">type</span> <span class="p">=</span> <span class="s">IMAP</span>
<span class="c"># or "type = Gmail", if applicable
</span><span class="py">remotehost</span> <span class="p">=</span> <span class="s">my.mail.server</span>
<span class="py">remoteuser</span> <span class="p">=</span> <span class="s">myuser</span>
<span class="py">remotepass</span> <span class="p">=</span> <span class="s">mypassword</span>
<span class="py">ssl</span> <span class="p">=</span> <span class="s">yes</span>
<span class="py">maxconnections</span> <span class="p">=</span> <span class="s">1</span>
<span class="py">realdelete</span> <span class="p">=</span> <span class="s">no</span>
<span class="py">folderfilter</span> <span class="p">=</span> <span class="s">lambda foldername: re.search("^Lists</span><span class="se">\.</span><span class="s">", foldername)
</span></code></pre></div></div>

<p>Now, simply running “offlineimap” should sync your mailing lists into
<code class="language-plaintext highlighter-rouge">~/Library/Caches/OfflineImap</code>. (You’ll need to do this regularly,
e.g. before and after reading your lists. Julien Danjou recently wrote
<a href="https://julien.danjou.info/offlineimap-el.html">a nice elisp wrapper for offlineimap</a>.)</p>

<p>All that remains is to tell Gnus how to access your local mail cache.</p>

<p>In .gnus:</p>

<div class="language-scheme highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="nf">setq</span> <span class="nv">imap-shell-program</span> <span class="s">"dovecot -c ~/.dovecotrc --exec-mail imap"</span><span class="p">)</span>
<span class="p">(</span><span class="nf">setq</span> <span class="nv">gnus-select-method</span> <span class="o">'</span><span class="p">(</span><span class="nf">nnimap</span> <span class="s">"Mail"</span>
                                  <span class="p">(</span><span class="nf">nnimap-stream</span> <span class="nv">shell</span><span class="p">)))</span>
</code></pre></div></div>

<p>Now you can start Gnus with <code class="language-plaintext highlighter-rouge">M-x gnus</code>, and then press <code class="language-plaintext highlighter-rouge">^</code> to enter
the server buffer. Drill down into the “nnimap+Mail” server and use
<code class="language-plaintext highlighter-rouge">u</code> to subscribe to each of the mailing lists. They should then appear
in Gnus’ main <code class="language-plaintext highlighter-rouge">*Group*</code> buffer.</p>

<p>That’s enough to get started reading mail more efficiently, and as
with all things Emacs, there’s great potential for customising Gnus to
suit your own preferences.</p>

<p>Further reading</p>

<ul>
  <li><a href="https://bc.tech.coop/blog/070813.html">GNUS and Gmail setup for dummies - covers configuring Gnus to send mail over SMTP</a></li>
  <li><a href="https://sachachua.com/blog/2008/05/geek-how-to-use-offlineimap-and-the-dovecot-mail-server-to-read-your-gmail-in-emacs-efficiently/">Sacha Chua’s guide to Gnus + Offlineimap + Gmail - the source for much of this article</a></li>
  <li><a href="https://www.gnus.org/">Gnus homepage</a></li>
</ul>]]></content><author><name></name></author><category term="Emacs" /><summary type="html"><![CDATA[Emacs’ built-in newsreader Gnus is made for efficiently keeping up with high-volume lists; I show how to hook it into your IMAP account.]]></summary></entry><entry><title type="html">Full-screen support for Cocoa Emacs on OS X</title><link href="https://www.sanityinc.com/articles/full-screen-support-for-cocoa-emacs-on-osx/" rel="alternate" type="text/html" title="Full-screen support for Cocoa Emacs on OS X" /><published>2010-01-31T00:00:00+00:00</published><updated>2010-01-31T00:00:00+00:00</updated><id>https://www.sanityinc.com/articles/full-screen-support-for-cocoa-emacs-on-osx</id><content type="html" xml:base="https://www.sanityinc.com/articles/full-screen-support-for-cocoa-emacs-on-osx/"><![CDATA[<p>Prolific Japanese hacker Daisuke Murase (a.k.a. <a href="https://github.com/typester">typester</a>) has recently patched Cocoa Emacs to add a full-screen display mode. Here’s how to add this must-have feature into your own local Emacs tree while you wait for it to get integrated into the official Emacs sources.</p>

<!-- more -->

<p>Let’s start with the assumptions that using the latest dev version of Emacs is a Good Thing, and that full-screen display is a feature so wonderful (particularly on laptops) that it’s worth some small effort to obtain.</p>

<p>I build my Emacs from a local copy of the official <a href="https://repo.or.cz/r/emacs.git">Emacs git repo</a>, which is automatically updated from the master bzr tree. Just a “git pull”, and I’m up to date.</p>

<p>I don’t want to build from typester’s repo because it hasn’t been updated from upstream since December.</p>

<p>So I add typester’s repo as an additional remote:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ git remote add typester git://github.com/typester/emacs.git
$ git fetch typester
</code></pre></div></div>

<p>However, I find that his feature branch doesn’t merge cleanly with the official clone, perhaps because he started with a different git clone of the emacs sources.</p>

<p>Looking at the history of typester’s branch, the last upstream change was a3585f6c2a. So, to apply the changes he made on my current branch:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ git diff a3585f6c2a typester/feature/fullscreen | patch -p1
</code></pre></div></div>

<p>And I see it applies without any conflicts! Great! (Here’s <a href="https://gist.github.com/291150">a copy of the patch as it looks today</a>.)</p>

<p>Now I can build as usual:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ ./configure --with-ns
$ make &amp;&amp; make install
$ mv nextstep/Emacs.app /Applications/
</code></pre></div></div>

<p>To toggle full-screen mode inside emacs:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>M-x ns-toggle-fullscreen
</code></pre></div></div>]]></content><author><name></name></author><category term="Emacs" /><category term="Mac" /><category term="OSX" /><summary type="html"><![CDATA[Prolific Japanese hacker Daisuke Murase (a.k.a. typester) has recently patched Cocoa Emacs to add a full-screen display mode. Here’s how to add this must-have feature into your own local Emacs tree while you wait for it to get integrated into the official Emacs sources.]]></summary></entry><entry><title type="html">Open “txmt:” URLs from Rails backtraces using Emacs on OS X</title><link href="https://www.sanityinc.com/articles/open-txmt-urls-from-rails-in-emacs-on-osx/" rel="alternate" type="text/html" title="Open “txmt:” URLs from Rails backtraces using Emacs on OS X" /><published>2010-01-31T00:00:00+00:00</published><updated>2010-01-31T00:00:00+00:00</updated><id>https://www.sanityinc.com/articles/open-txmt-urls-from-rails-in-emacs-on-osx</id><content type="html" xml:base="https://www.sanityinc.com/articles/open-txmt-urls-from-rails-in-emacs-on-osx/"><![CDATA[<p>When Rails prints a backtrace in HTML, it’s helpfully rendered as a
“txmt:” link so that users can click open the corresponding location
in TextMate on OS X. If you’re an Emacs user, here’s how to make those
URLs open in Emacs instead.</p>

<!-- more -->

<p>First, get a copy of Daisuke Murase’s
<a href="https://github.com/typester/emacs-handler">emacs-handler</a> project
using git or by downloading a tarball.</p>

<p>Then apply the following patch:</p>

<div class="language-diff highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gh">diff --git a/Info.plist b/Info.plist
index 1880412..deb1fa4 100644
</span><span class="gd">--- a/Info.plist
</span><span class="gi">+++ b/Info.plist
</span><span class="p">@@ -8,6 +8,7 @@</span>
                        &lt;key&gt;CFBundleURLSchemes&lt;/key&gt;
                        &lt;array&gt;
                                &lt;string&gt;emacs&lt;/string&gt;
<span class="gi">+                               &lt;string&gt;txmt&lt;/string&gt;
</span>                        &lt;/array&gt;
                        &lt;key&gt;CFBundleURLName&lt;/key&gt;
                        &lt;string&gt;org.unknownplace.emacshandler&lt;/string&gt;
</code></pre></div></div>

<p>Alternatively, you can just check out
<a href="https://github.com/purcell/emacs-handler">my clone of emacs-handler</a>,
which has the above patch built-in.</p>

<p>Finally, open the project in Xcode, and build it. Fire up the
resulting <code class="language-plaintext highlighter-rouge">EmacsHandler.app</code>, and edit the app’s preferences to point to
your Emacs.</p>

<p>That should be all you need to do – just keep <code class="language-plaintext highlighter-rouge">EmacsHandler.app</code> around
somewhere on your Mac.</p>]]></content><author><name></name></author><category term="Emacs" /><category term="Mac" /><category term="OSX" /><category term="Rails" /><category term="Textmate" /><category term="Ruby" /><summary type="html"><![CDATA[When Rails prints a backtrace in HTML, it’s helpfully rendered as a “txmt:” link so that users can click open the corresponding location in TextMate on OS X. If you’re an Emacs user, here’s how to make those URLs open in Emacs instead.]]></summary></entry><entry><title type="html">So you think you found a bug in a library?</title><link href="https://www.sanityinc.com/articles/so-you-think-you-found-a-bug/" rel="alternate" type="text/html" title="So you think you found a bug in a library?" /><published>2009-06-29T00:00:00+00:00</published><updated>2009-06-29T00:00:00+00:00</updated><id>https://www.sanityinc.com/articles/so-you-think-you-found-a-bug</id><content type="html" xml:base="https://www.sanityinc.com/articles/so-you-think-you-found-a-bug/"><![CDATA[<p>From time to time I receive bug reports for the libraries I’ve
written. Some reports describe genuine bugs (and I’ll be the first to
admit I’m not perfect), but far too many others demonstrate a missed
step in the submitter’s “bug assessment” mental process.</p>

<!-- more -->

<p>Specifically, ten years ago I wrote the unit testing module included
in Python’s standard library. The module was a fairly direct copy of
JUnit’s proven design at that time, and has since been used as the
basis of (I’m sure) millions of unit tests in projects around the
globe, including Python itself. It’s fairly safe to say that the major
bugs have been ironed out by this stage.</p>

<p>But still, from time to time, I receive emails smugly pointing out a
glaring bug in the module, with indignant comments such as “I am
trying to teach more people in my company to use unit testing, but
after the[y] discover bugs like these they come to me discouraged.”</p>

<p>Many such bug reports come complete with a short “demonstration” code
snippet that shows a fundamental misunderstanding of how the library
is to be used. I send polite responses, but I’d rather have simply
been asked for a link to a good tutorial instead.</p>

<p>So here’s a question I’d like to request that programmers
(whatever his opinion of his own ability) ask themselves before reporting
a bug in a library they are using:</p>

<blockquote>
  <p>“Given the number of people using this library, is it at all possible
that I could be the first person to discover this bug, or is it more
likely that I’ve misunderstood how to use the library?”</p>
</blockquote>]]></content><author><name></name></author><summary type="html"><![CDATA[From time to time I receive bug reports for the libraries I’ve written. Some reports describe genuine bugs (and I’ll be the first to admit I’m not perfect), but far too many others demonstrate a missed step in the submitter’s “bug assessment” mental process.]]></summary></entry><entry><title type="html">Adding Array#to_proc to Ruby</title><link href="https://www.sanityinc.com/articles/adding-array-to-proc-to-ruby/" rel="alternate" type="text/html" title="Adding Array#to_proc to Ruby" /><published>2009-04-14T00:00:00+00:00</published><updated>2009-04-14T00:00:00+00:00</updated><id>https://www.sanityinc.com/articles/adding-array-to-proc-to-ruby</id><content type="html" xml:base="https://www.sanityinc.com/articles/adding-array-to-proc-to-ruby/"><![CDATA[<p>Here’s a neat Ruby trick for fans of <code class="language-plaintext highlighter-rouge">Symbol#to_proc</code>.</p>

<!-- more -->

<p>This magical method, introduced by both Rails and Ruby 1.9, lets you do things like this:</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">&gt;</span> <span class="sx">%w(1 2 3 4 5)</span><span class="p">.</span><span class="nf">map</span> <span class="o">&amp;</span><span class="ss">:to_i</span>
<span class="o">=&gt;</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">]</span>
</code></pre></div></div>

<p>And that proc can, of course, take multiple parameters:</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">[</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">3</span><span class="p">,</span><span class="mi">4</span><span class="p">].</span><span class="nf">zip</span><span class="p">([</span><span class="mi">2</span><span class="p">,</span><span class="mi">3</span><span class="p">,</span><span class="mi">4</span><span class="p">,</span><span class="mi">5</span><span class="p">])</span>
<span class="o">=&gt;</span> <span class="p">[[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">],</span> <span class="p">[</span><span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">],</span> <span class="p">[</span><span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">],</span> <span class="p">[</span><span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">]]</span><span class="o">&gt;</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">3</span><span class="p">,</span><span class="mi">4</span><span class="p">].</span><span class="nf">zip</span><span class="p">([</span><span class="mi">2</span><span class="p">,</span><span class="mi">3</span><span class="p">,</span><span class="mi">4</span><span class="p">,</span><span class="mi">5</span><span class="p">]).</span><span class="nf">map</span> <span class="o">&amp;</span><span class="ss">:sum</span>
<span class="o">=&gt;</span> <span class="p">[</span><span class="mi">3</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">9</span><span class="p">]</span>
</code></pre></div></div>

<p>However, if you want to “close” a value into the proc, you’re out of
luck, so you have to define a block old-school-style:</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">&gt;</span> <span class="sx">%w(kung ruby bar)</span><span class="p">.</span><span class="nf">map</span> <span class="p">{</span> <span class="o">|</span><span class="n">e</span><span class="o">|</span> <span class="n">e</span> <span class="o">+</span> <span class="s2">"-fu"</span> <span class="p">}</span>
<span class="o">=&gt;</span> <span class="p">[</span><span class="s2">"kung-fu"</span><span class="p">,</span> <span class="s2">"ruby-fu"</span><span class="p">,</span> <span class="s2">"bar-fu"</span><span class="p">]</span>
</code></pre></div></div>

<p>But check out the following little hack:</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">class</span> <span class="nc">Array</span>
  <span class="k">def</span> <span class="nf">to_proc</span>
    <span class="nb">lambda</span> <span class="p">{</span> <span class="o">|</span><span class="n">target</span><span class="o">|</span> <span class="n">target</span><span class="p">.</span><span class="nf">send</span><span class="p">(</span><span class="o">*</span><span class="nb">self</span><span class="p">)</span> <span class="p">}</span>
  <span class="k">end</span>
<span class="k">end</span>
</code></pre></div></div>

<p>Now look what you can do:</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">&gt;</span> <span class="sx">%w(kung ruby bar)</span><span class="p">.</span><span class="nf">map</span> <span class="o">&amp;</span><span class="p">[:</span><span class="o">+</span><span class="p">,</span> <span class="s2">"-fu"</span><span class="p">]</span>
<span class="o">=&gt;</span> <span class="p">[</span><span class="s2">"kung-fu"</span><span class="p">,</span> <span class="s2">"ruby-fu"</span><span class="p">,</span> <span class="s2">"bar-fu"</span><span class="p">]</span>
</code></pre></div></div>

<p>What do you think? Handy? Disgusting? Leave a comment to let me know!</p>

<p><em>Update: apparently others have had
<a href="https://rails.lighthouseapp.com/projects/8994/tickets/1253-arrayto_proc">similar</a>
<a href="https://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/199820">ideas</a>,
but with different semantics. So perhaps this trick is a little too
opaque…</em></p>]]></content><author><name></name></author><category term="Ruby" /><summary type="html"><![CDATA[Here’s a neat Ruby trick for fans of Symbol#to_proc.]]></summary></entry></feed>