<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="../feed.xsl" type="text/xsl"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">

<channel>
<title>Susam's How-To Pages</title>
<link>https://susam.net/tag/how-to.html</link>
<atom:link rel="self" type="application/rss+xml" href="https://susam.net/tag/how-to-full.xml"/>
<description>Feed for Susam's How-To Pages</description>

<item>
<title>Git Checkout, Reset and Restore</title>
<link>https://susam.net/git-checkout-reset-restore.html</link>
<guid isPermaLink="false">gcrrp</guid>
<pubDate>Thu, 12 Mar 2026 00:00:00 +0000</pubDate>
<description>
<![CDATA[
<p>
  I have always used the <code>git checkout</code> and <code>git
  reset</code> commands to reset my working tree or index but since
  Git 2.23 there has been a <code>git restore</code> command available
  for these purposes.  In this post, I record how some of the 'older'
  commands I use map to the new ones.  Well, the new commands aren't
  exactly new since Git 2.23 was released in 2019, so this post is
  perhaps six years too late.  Even so, I want to write this down for
  future reference.  It is worth noting that the old and new commands
  are not always equivalent.  I'll talk more about this briefly as we
  discuss the commands.  However, they can be used to perform similar
  tasks.  Some of these tasks are discussed below.
</p>
<h2 id="contents">Contents<a href="#contents"></a></h2>
<ul>
  <li><a href="#experimental-setup">Experimental Setup</a></li>
  <li><a href="#reset-working-directory">Reset the Working Tree</a></li>
  <li><a href="#reset-index">Reset the Index</a></li>
  <li><a href="#reset-working-directory-and-index">Reset the Working Tree and Index</a></li>
  <li><a href="#summary">Summary</a></li>
</ul>
<h2 id="experimental-setup">Experimental Setup<a href="#experimental-setup"></a></h2>
<p>
  To experiment quickly, we first create an example Git repository.
</p>
<pre><code>mkdir foo/; cd foo/; touch a b c
git init; git add a b c; git commit -m hello</code></pre>
<p>
  Now we make changes to the files and stage some of the changes.  We
  then add more unstaged changes to one of the staged files.
</p>
<pre><code>date | tee a b c d; git add a b d; echo &gt; b</code></pre>
<p>
  At this point, the working tree and index look like this:
</p>
<pre><samp>$ <kbd>git status</kbd>
On branch main
Changes to be committed:
  (use "git restore --staged &lt;file&gt;..." to unstage)
        <span class="c2">modified:   a
        modified:   b
        new file:   d</span>

Changes not staged for commit:
  (use "git add &lt;file&gt;..." to update what will be committed)
  (use "git restore &lt;file&gt;..." to discard changes in working directory)
        <span class="c4">modified:   b
        modified:   c</span></samp></pre>
<p>
  File <code>a</code> has staged changes.  File <code>b</code> has
  both staged and unstaged changes.  File <code>c</code> has only
  unstaged changes.  File <code>d</code> is a new staged file.  In
  each experiment below, we will work with this setup.
</p>
<p>
  All results discussed in this post were obtained using Git 2.47.3 on
  Debian 13.2 (Trixie).
</p>
<h2 id="reset-working-directory">Reset the Working Tree<a href="#reset-working-directory"></a></h2>
<p>
  As a reminder, we will always use the following command between
  experiments to ensure that we restore the experimental setup each
  time:
</p>
<pre><code>date | tee a b c d; git add a b d; echo &gt; b</code></pre>
<p>
  To discard the changes in the working tree and reset the files in
  the working tree from the index, I typically run:
</p>
<pre><code>git checkout .</code></pre>
<p>
  However, the modern way to do this is to use the following command:
</p>
<pre><code>git restore .</code></pre>
<p>
  Both commands leave the working tree and the index in the following
  state:
</p>
<pre><samp>$ <kbd>git status</kbd>
On branch main
Changes to be committed:
  (use "git restore --staged &lt;file&gt;..." to unstage)
        <span class="c2">modified:   a
        modified:   b
        new file:   d</span></samp></pre>
<p>
  Both commands operate only on the working tree.  They do not alter
  the index.  Therefore the staged changes remain intact in the index.
</p>
<h2 id="reset-index">Reset the Index<a href="#reset-index"></a></h2>
<p>
  Another common situation is when we have staged some changes but
  want to unstage them.  First, we restore the experimental setup:
</p>
<pre><code>date | tee a b c d; git add a b d; echo &gt; b</code></pre>
<p>
  I normally run the following command to do so:
</p>
<pre><code>git reset</code></pre>
<p>
  The modern way to do this is:
</p>
<pre><code>git restore -S .</code></pre>
<p>
  Both commands leave the working tree and the index in the following
  state:
</p>
<pre><samp>$ <kbd>git status</kbd>
On branch main
Changes not staged for commit:
  (use "git add &lt;file&gt;..." to update what will be committed)
  (use "git restore &lt;file&gt;..." to discard changes in working directory)
        <span class="c4">modified:   a
        modified:   b
        modified:   c</span>

Untracked files:
  (use "git add &lt;file&gt;..." to include in what will be committed)
        <span class="c4">d</span>

no changes added to commit (use "git add" and/or "git commit -a")</samp></pre>
<p>
  The <code>-S</code> (<code>--staged</code>) option tells <code>git
  restore</code> to operate on the index (not the working tree) and
  reset the index entries for the specified files to match the
  version in <code>HEAD</code>.  The unstaged changes remain intact as
  modified files in the working tree.  With the <code>-S</code>
  option, no changes are made to the working tree.
</p>
<p>
  From the arguments we can see that the old and new commands are not
  exactly equivalent.  Without any arguments, the <code>git
  reset</code> command resets the entire index to <code>HEAD</code>,
  so all staged changes become unstaged.  Similarly, when we run
  <code>git restore -S</code> without specifying a commit, branch or
  tag using the <code>-s</code> (<code>--source</code>) option, it
  defaults to resetting the index from <code>HEAD</code>.
  The <code>.</code> at the end ensures that all paths under the
  current directory are affected.  When we run the command at the
  top-level directory of the repository, all paths are affected and
  the entire index gets reset.  As a result, both the old and the new
  commands accomplish the same result.
</p>
<h2 id="reset-working-directory-and-index">Reset the Working Tree and Index<a href="#reset-working-directory-and-index"></a></h2>
<p>
  Once again, we restore the experimental setup.
</p>
<pre><code>date | tee a b c d; git add a b d; echo &gt; b</code></pre>
<p>
  This time we not only want to unstage the changes but also discard
  the changes in the working tree.  In other words, we want to reset
  both the working tree and the index from <code>HEAD</code>.  This is
  a dangerous operation because any uncommitted changes discarded in
  this manner cannot be restored using Git.
</p>
<pre><code>git reset --hard</code></pre>
<p>
  The modern way to do this is:
</p>
<pre><code>git restore -WS .</code></pre>
<p>
  The working tree is now clean:
</p>
<pre><samp>$ <kbd>git status</kbd>
On branch main
nothing to commit, working tree clean</samp></pre>
<p>
  The <code>-W</code> (<code>--worktree</code>) option makes the
  command operate on the working tree.  The <code>-S</code>
  (<code>--staged</code>) option resets the index as described in the
  previous section.  As a result, this command unstages any changes
  and discards any modifications in the working tree.
</p>
<p>
  Note that when neither of these options is specified,
  <code>-W</code> is implied by default.  That's why the
  bare <code>git restore .</code> command in the previous section
  discards the changes in the working tree.
</p>
<h2 id="summary">Summary<a href="#summary"></a></h2>
<p>
  The following table summarises how the three pairs of commands
  discussed above affect the working tree and the index, assuming the
  commands are run at the top-level directory of a repository.
</p>
<div style="overflow: auto">
  <table class="grid" style="margin: 0">
    <thead>
      <tr>
        <th>Old</th>
        <th>New</th>
        <th>Working Tree</th>
        <th>Index</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td class="pre"><code>git checkout .</code></td>
        <td class="pre"><code>git restore .</code></td>
        <td>Reset to match the index.</td>
        <td>No change.</td>
      </tr>
      <tr>
        <td class="pre"><code>git reset</code></td>
        <td class="pre"><code>git restore -S .</code></td>
        <td>No change.</td>
        <td>Reset to match <code>HEAD</code>.</td>
      </tr>
      <tr>
        <td class="pre"><code>git reset --hard</code></td>
        <td class="pre"><code>git restore -SW .</code></td>
        <td>Reset to match <code>HEAD</code>.</td>
        <td>Reset to match <code>HEAD</code>.</td>
      </tr>
    </tbody>
  </table>
</div>
<p>
  The <code>git restore</code> command is meant to provide a clearer
  interface for resetting the working tree and the index.  I still use
  the older commands out of habit.  Perhaps I will adopt the new ones
  in another six years, but at least I have the mapping written down
  now.
</p>
<!-- ### -->
<p>
  <a href="https://susam.net/git-checkout-reset-restore.html">Read on website</a> |
  <a href="https://susam.net/tag/technology.html">#technology</a> |
  <a href="https://susam.net/tag/how-to.html">#how-to</a>
</p>
]]>
</description>
</item>
<item>
<title>Soju User Delete Hash</title>
<link>https://susam.net/soju-user-delete-hash.html</link>
<guid isPermaLink="false">sudhs</guid>
<pubDate>Sat, 14 Feb 2026 00:00:00 +0000</pubDate>
<description>
<![CDATA[
<p>
  In <a href="from-znc-to-soju.html">my last post</a>, I talked about
  switching from ZNC to Soju as my IRC bouncer.  One thing that caught
  my attention while creating and deleting Soju users was that the
  delete command asks for a confirmation, like so:
</p>
<pre><samp>$ <kbd>sudo sojuctl user delete soju</kbd>
To confirm user deletion, send "user delete soju 4664cd"
$ <kbd>sudo sojuctl user delete soju 4664cd</kbd>
deleted user "soju"</samp></pre>
<p>
  That confirmation token for a specific user never changes, no matter
  how many times we create or delete it.  The confirmation token is
  not saved in the Soju database, as can be confirmed here:
</p>
<pre><samp>$ <kbd>sudo sqlite3 -table /var/lib/soju/main.db 'SELECT * FROM User'</kbd>
+----+----------+--------------------------------------------------------------+-------+----------+------+--------------------------+---------+--------------------------+--------------+
| id | username |                           password                           | admin | realname | nick |        created_at        | enabled | downstream_interacted_at | max_networks |
+----+----------+--------------------------------------------------------------+-------+----------+------+--------------------------+---------+--------------------------+--------------+
| 1  | soju     | $2a$10$yRj/oYlR2Zwd8YQxZPuAQuNo2j7FVJWeNdIAHF2MinYkKLmBjtf0y | 0     |          |      | 2026-02-16T13:49:46.119Z | 1       |                          | -1           |
+----+----------+--------------------------------------------------------------+-------+----------+------+--------------------------+---------+--------------------------+--------------+</samp></pre>
<p>
  Surely, then, the confirmation token is derived from the user
  definition?  Yes, indeed it is.  This can be confirmed at the
  <a href="https://codeberg.org/emersion/soju/src/commit/v0.10.1/service.go#L1185-L1203">source
  code here</a>.  Quoting the most relevant part from the source code:
</p>
<pre><code>hashBytes := sha1.Sum([]byte(username))
hash := fmt.Sprintf("%x", hashBytes[0:3])</code></pre>
<p>
  Indeed if we compute the same hash ourselves, we get the same token:
</p>
<pre><samp>$ <kbd>printf soju | sha1sum | head -c6</kbd>
4664cd</samp></pre>
<p>
  This allows us to automate the two step Soju user deletion process
  in a single command:
</p>
<pre><code>sudo sojuctl user delete soju "$(printf soju | sha1sum | head -c6)"</code></pre>
<p>
  But of course, the implementation of the confirmation token may
  change in future and Soju helpfully outputs the deletion command
  with the confirmation token when we first invoke it without the
  token, so it is perhaps more prudent to just take that output and
  feed it back to Soju, like so:
</p>
<pre><code>sudo sojuctl $(sudo sojuctl user delete soju | sed 's/.*"\(.*\)"/\1/')</code></pre>
<!-- ### -->
<p>
  <a href="https://susam.net/soju-user-delete-hash.html">Read on website</a> |
  <a href="https://susam.net/tag/shell.html">#shell</a> |
  <a href="https://susam.net/tag/irc.html">#irc</a> |
  <a href="https://susam.net/tag/technology.html">#technology</a> |
  <a href="https://susam.net/tag/how-to.html">#how-to</a>
</p>
]]>
</description>
</item>
<item>
<title>From ZNC to Soju</title>
<link>https://susam.net/from-znc-to-soju.html</link>
<guid isPermaLink="false">fztsj</guid>
<pubDate>Thu, 12 Feb 2026 00:00:00 +0000</pubDate>
<description>
<![CDATA[
<p>
  I have recently switched from ZNC to Soju as my IRC bouncer and I am
  already quite pleased with it.  I usually run my bouncer on a Debian
  machine, where Soju is well packaged and runs smoothly right after
  installation.  By contrast, the ZNC package included with Debian 13
  (Trixie) and earlier fails to start after installation because of a
  missing configuration file.  As a result, I was forced to maintain
  my own configuration file along with a necessary PEM bundle, copy
  them to the Debian system and carefully set the correct file
  permissions before I could run ZNC successfully.  None of this is
  necessary with Soju, since installing it from the Debian package
  repository automatically sets up the configuration and certificate
  files.  I no longer have to manage any configuration or certificate
  files myself.
</p>
<h2 id="setup">Setup<a href="#setup"></a></h2>
<p>
  It is quite straightforward to install and set up Soju on Debian.
  The following two commands install Soju:
</p>
<pre><code>sudo apt-get update
sudo apt-get -y install soju</code></pre>
<p>
  Then setting up an IRC connection involves another two commands:
</p>
<pre><code>sudo sojuctl user create -username soju -password YOUR_SOJU_PASSWORD
sudo sojuctl user run soju network create -name bnc1 -addr irc.libera.chat -nick YOUR_NICK -pass YOUR_NICK_PASSWORD</code></pre>
<p>
  Here, <code>YOUR_SOJU_PASSWORD</code> is a placeholder for a new
  password you must choose for your Soju user.  Finally, we restart
  Soju as follows:
</p>
<pre><code>sudo systemctl restart soju</code></pre>
<h2 id="database">Database<a href="#database"></a></h2>
<p>
  What previously involved maintaining several files that had to be
  installed and configured on each machine running ZNC is now reduced
  to the two <code>sojuctl</code> commands above.  Still, the
  configuration needs to live somewhere.  In fact, the
  two <code>sojuctl</code> commands introduce earlier store the
  configuration in a SQLite database.  Here is a glimpse of what the
  database looks like:
</p>
<pre><samp>$ <kbd>sudo sqlite3 /var/lib/soju/main.db '.tables'</kbd>
Channel              MessageFTS_data      ReadReceipt
DeliveryReceipt      MessageFTS_docsize   User
Message              MessageFTS_idx       WebPushConfig
MessageFTS           MessageTarget        WebPushSubscription
MessageFTS_config    Network
$ <kbd>sudo sqlite3 /var/lib/soju/main.db 'SELECT * from User'</kbd>
1|soju|$2a$10$mM5Qcz8.OPMi9lyWDxPRh.bNxzq7jtLdxcoPl09AYTnqcmLmEqzSO|0|||2026-02-17T23:24:24.926Z|1||-1
$ <kbd>sudo sqlite3 /var/lib/soju/main.db 'SELECT * from Network'</kbd>
1|bnc1|1|irc.libera.chat|YOUR_NICK||||YOUR_NICK_PASSWORD|||||||1|1</samp></pre>
<h2 id="client">Client Configuration<a href="#client"></a></h2>
<p>
  Finally, the IRC client can be configured to connect to port 6697 on
  the system running Soju.  Here is an example of how this can be done
  in Irssi:
</p>
<pre><code>/network add -nick YOUR_NICK -user soju/bnc1 net1
/server add -tls -network bnc1 YOUR_SOJU_HOST 6697 YOUR_SOJU_PASSWORD
/connect net1
</code></pre>
<p>
  You can also set up multiple connections to IRC networks through the
  same Soju instance.  All you need to do is repeat
  the <code>sojuctl</code> commands to create additional networks such
  as <code>bnc2</code>, <code>bnc3</code> and so on, then repeat the
  configuration in your IRC client using new network names such as
  <code>net2</code>, <code>net3</code>, etc.  These network names are
  entirely user defined, so you can choose any names you like.  The
  names <code>bnc2</code>, <code>net2</code> and so on are only
  examples.
</p>
<!-- ### -->
<p>
  <a href="https://susam.net/from-znc-to-soju.html">Read on website</a> |
  <a href="https://susam.net/tag/irc.html">#irc</a> |
  <a href="https://susam.net/tag/technology.html">#technology</a> |
  <a href="https://susam.net/tag/how-to.html">#how-to</a>
</p>
]]>
</description>
</item>
<item>
<title>Search User Comment on Jira</title>
<link>https://susam.net/search-user-comment-on-jira.html</link>
<guid isPermaLink="false">xrnzg</guid>
<pubDate>Tue, 20 Feb 2024 00:00:00 +0000</pubDate>
<description>
<![CDATA[
<p>
  I have been using Jira for a very long time now.  I first came
  across it while contributing to Apache projects in 2006.  I find the
  search features of Jira to be remarkably clumsy and inadequate.
  Nevertheless, very recently I learnt to solve a common problem of
  mine.  Let us say, I know a user named <code>jdoe</code> has
  commented about a specific topic in some Jira ticket.  How do I find
  that ticket?  Here is the search filter for it:
</p>
<pre><code>issueFunction in commented("by jdoe") and comment ~ "hello"</code></pre>
<p>
  The above example would search all comments by
  user <code>jdoe</code> that contains the
  string <code>"hello"</code>.  However one limitation of this
  solution is that the <code>issueFunction</code> field is provided by
  ScriptRunner for Jira, so you need this app to be available on your
  Jira for this solution to work.
</p>
<!-- ### -->
<p>
  <a href="https://susam.net/search-user-comment-on-jira.html">Read on website</a> |
  <a href="https://susam.net/tag/technology.html">#technology</a> |
  <a href="https://susam.net/tag/how-to.html">#how-to</a>
</p>
]]>
</description>
</item>
<item>
<title>Sorting in Emacs</title>
<link>https://susam.net/sorting-in-emacs.html</link>
<guid isPermaLink="false">umnyp</guid>
<pubDate>Wed, 09 Aug 2023 00:00:00 +0000</pubDate>
<description>
<![CDATA[
<p>
  In this article, we will perform a series of hands-on experiments
  that demonstrate the various Emacs commands that can be used to sort
  text in different ways.  There is sufficient documentation available
  for these commands in the Emacs and Elisp manuals.  In this article,
  however, we will take a look at some concrete examples to illustrate
  how they work.
</p>
<h2 id="sorting-lines">Sorting Lines<a href="#sorting-lines"></a></h2>
<p>
  Our first set of experiments demonstrates different ways to sort
  lines.  Follow the steps below to perform these experiments.
</p>
<ol>
  <li> <!-- 1. Create buffer -->
    <p>
      First create a buffer that has the following text:
    </p>
<pre><code>Carol  200  London  LHR-&gt;SFO
Dan    20   Tokyo   HND-&gt;LHR
Bob    100  London  LCY-&gt;CDG
Alice  10   Paris   CDG-&gt;LHR
Bob    30   Paris   ORY-&gt;HND</code></pre>
    <p>
      Let us pretend that each line is a record that represents some
      details about different persons.  From left to right, we have
      each person's name, some sort of numerical ID, their current
      location and their upcoming travel plan.  For example, the first
      line says that Carol from London is planning to travel from
      London Heathrow (LHR) to San Francisco (SFO).
    </p>
  </li>
  <li> <!-- 2. sort-lines -->
    <p>
      Type <code>C-x h</code> to mark the whole buffer and
      type <code>M-x sort-lines RET</code> to sort lines
      alphabetically.  The buffer looks like this now:
    </p>
<pre><code>Alice  10   Paris   CDG-&gt;LHR
Bob    100  London  LCY-&gt;CDG
Bob    30   Paris   ORY-&gt;HND
Carol  200  London  LHR-&gt;SFO
Dan    20   Tokyo   HND-&gt;LHR</code></pre>
  </li>
  <li> <!-- 3. sort-lines (reverse) -->
    <p>
      Type <code>C-x h</code> followed by <code>C-u M-x sort-lines
      RET</code> to reverse sort lines alphabetically.  The key
      sequence <code>C-u</code> specifies a prefix argument that
      indicates that a reverse sort must be performed.  The buffer
      looks like this now:
    </p>
<pre><code>Dan    20   Tokyo   HND-&gt;LHR
Carol  200  London  LHR-&gt;SFO
Bob    30   Paris   ORY-&gt;HND
Bob    100  London  LCY-&gt;CDG
Alice  10   Paris   CDG-&gt;LHR</code></pre>
  </li>
  <li> <!-- 4. sort-fields (first) -->
    <p>
      Type <code>C-x h</code> followed by <code>M-x sort-fields
      RET</code> to sort the lines by the first field only.  Fields
      are separated by whitespace.  Note that the result now is
      slightly different from the result of <code>M-x sort-lines
      RET</code> presented in point 2 earlier.  Here Bob from Paris
      comes before Bob from London because the sorting was performed
      by the first field only.  The sorting algorithm ignored the rest
      of each line.  However in point 2 earlier, Bob from London came
      before Bob from Paris because the sorting was performed by
      entire lines.
    </p>
<pre><code>Alice  10   Paris   CDG-&gt;LHR
Bob    30   Paris   ORY-&gt;HND
Bob    100  London  LCY-&gt;CDG
Carol  200  London  LHR-&gt;SFO
Dan    20   Tokyo   HND-&gt;LHR</code></pre>
  </li>
  <li> <!-- 5. sort-fields (second) -->
    <p>
      Type <code>C-x h</code> followed by <code>M-2 M-x sort-fields
      RET</code> to sort the lines alphabetically by the second field.
      The key sequence <code>M-2</code> here specifies a numeric
      argument that identifies the field we want to sort by.  Note
      that <code>100</code> comes before <code>20</code> because we
      performed an alphabetical sort, not numerical sort.  The result
      looks like this:
    </p>
<pre><code>Alice  10   Paris   CDG-&gt;LHR
Bob    100  London  LCY-&gt;CDG
Dan    20   Tokyo   HND-&gt;LHR
Carol  200  London  LHR-&gt;SFO
Bob    30   Paris   ORY-&gt;HND</code></pre>
  </li>
  <li> <!-- 6. sort-numeric-fields -->
    <p>
      Type <code>C-x h</code> followed by <code>M-2 M-x
      sort-numeric-fields RET</code> to sort the lines numerically by
      the second field.  The result looks like this:
    </p>
<pre><code>Alice  10   Paris   CDG-&gt;LHR
Dan    20   Tokyo   HND-&gt;LHR
Bob    30   Paris   ORY-&gt;HND
Bob    100  London  LCY-&gt;CDG
Carol  200  London  LHR-&gt;SFO</code></pre>
  </li>
  <li> <!-- 7. sort-fields (third) -->
    <p>
      Type <code>C-x h</code> followed by <code>M-3 M-x sort-fields
      RET</code> to sort the lines alphabetically by the third field
      containing city names.  The result looks like this:
    </p>
<pre><code>Bob    100  London  LCY-&gt;CDG
Carol  200  London  LHR-&gt;SFO
Alice  10   Paris   CDG-&gt;LHR
Bob    30   Paris   ORY-&gt;HND
Dan    20   Tokyo   HND-&gt;LHR</code></pre>
    <p>
      Note that we cannot supply the prefix argument <code>C-u</code>
      to this command to perform a reverse sort by a specific field
      because the prefix argument here is used to identify the field
      we need to sort by.  If we do specify the prefix
      argument <code>C-u</code>, it would be treated as the numeric
      argument <code>4</code> which would sort the lines by the fourth
      field.  However, there is a little trick to reverse sort lines
      by a specific field.  The next point shows this.
    </p>
  </li>
  <li> <!-- 8. reverse-region -->
    <p>
      Type <code>C-x h</code> followed by <code>M-x reverse-region
      RET</code>.  This reverses the order of lines in the region.
      Combined with the previous command, this effectively
      reverse sorts the lines by city names.  The result looks like
      this:
    </p>
<pre><code>Dan    20   Tokyo   HND-&gt;LHR
Bob    30   Paris   ORY-&gt;HND
Alice  10   Paris   CDG-&gt;LHR
Carol  200  London  LHR-&gt;SFO
Bob    100  London  LCY-&gt;CDG</code></pre>
  </li>
  <li> <!-- 9. sort-fields (negative) -->
    <p>
      Type <code>C-x h</code> followed by <code>M-- M-2 M-x
      sort-fields RET</code> to sort the lines alphabetically by the
      second field from the right (third from the left).  Note that
      the first two key combinations are <kbd>meta</kbd>+<kbd>-</kbd>
      and <kbd>meta</kbd>+<kbd>2</kbd>.  They specify the negative
      argument <code>-2</code> to sort the lines by the second field
      from the right.  The result looks like this:
    </p>
<pre><code>Carol  200  London  LHR-&gt;SFO
Bob    100  London  LCY-&gt;CDG
Bob    30   Paris   ORY-&gt;HND
Alice  10   Paris   CDG-&gt;LHR
Dan    20   Tokyo   HND-&gt;LHR</code></pre>
  </li>
  <li> <!-- 10. sort-columns -->
    <p>
      Type <code>M-&lt;</code> to move the point to the beginning of
      the buffer.  Then type <code>C-s London RET</code> followed
      by <code>M-b</code> to move the point to the beginning of the
      word <code>London</code> on the first line.  Now
      type <code>C-SPC</code> to set a mark there.
    </p>
    <p>
      Then type <code>C-4 C-n C-e</code> to move the point to the end
      of the last line.  An active region should be visible in the
      buffer now.
    </p>
    <p>
      Finally type <code>M-x sort-columns RET</code> to sort the
      columns bounded by the column positions of mark and point (i.e.
      the last two columns).  The result looks like this:
    </p>
<pre><code>Bob    100  London  LCY-&gt;CDG
Carol  200  London  LHR-&gt;SFO
Alice  10   Paris   CDG-&gt;LHR
Bob    30   Paris   ORY-&gt;HND
Dan    20   Tokyo   HND-&gt;LHR</code></pre>
  </li>
  <li> <!-- 11. sort-columns (reverse) -->
    <p>
      Like before, type <code>M-&lt;</code> to move the point to the
      beginning of the buffer.  Then type <code>C-s London RET</code>
      followed by <code>M-b</code> to move the point to the beginning
      of the word <code>London</code> on the first line.  Now
      type <code>C-SPC</code> to set a mark there.
    </p>
    <p>
      Again, like before, type <code>C-4 C-n C-e</code> to move the
      point to the end of the last line.  An active region should be
      visible in the buffer now.
    </p>
    <p>
      Now type <code>C-u M-x sort-columns RET</code> to reverse sort
      the last two columns.
    </p>
<pre><code>Dan    20   Tokyo   HND-&gt;LHR
Bob    30   Paris   ORY-&gt;HND
Alice  10   Paris   CDG-&gt;LHR
Carol  200  London  LHR-&gt;SFO
Bob    100  London  LCY-&gt;CDG</code></pre>
  </li>
  <li> <!-- 12. sort-regexp-fields (warning) -->
    <p>
      Warning: This step shows how <em>not to</em> use
      the <code>sort-regexp-fields</code> command.  In most cases you
      probably do not want to do this.  The next point shows a typical
      usage of this command that is correct in most cases.
    </p>
    <p>
      Type <code>C-x h</code> followed by <code>M-x sort-regexp-fields
      RET [A-Z]*-&gt;\(.*\) RET \1 RET</code> to sort by the
      destination airport.  This command first matches the destination
      aiport in each line in a regular expression capturing group
      (<code>\(.*\)</code>).  Then we ask this command to sort the
      lines by the field matched by this capturing group
      (<code>\1</code>).  The result looks like this:
    </p>
<pre><code>Dan    20   Tokyo   LCY-&gt;CDG
Bob    30   Paris   ORY-&gt;HND
Alice  10   Paris   HND-&gt;LHR
Carol  200  London  CDG-&gt;LHR
Bob    100  London  LHR-&gt;SFO</code></pre>
    <p>
      Observe how all our travel records are messed up in this result.
      Now Dan from Tokyo is travelling from LCY to CDG instead of
      travelling from HND to LHR.  Compare the results in this point
      with that of the previous point.  This command has sorted the
      destination fields fine and it has maintained the association
      between the source airport and destination airport fine too.
      But the association between the other fields (first three
      columns) and the last field (source and destination airports) is
      broken.  This happened because the regular expression matches
      only the last column and we sorted by only the destination field
      of the last column, so the association of the fields in the last
      column is kept intact but the rest of the association is broken.
      Only the part of each line that is matched by the regular
      expression moves around while the sorting is performed;
      everything else remains unchanged.  This behaviour may be useful
      in some limited situations but in most cases, we want to keep
      the association between all the fields intact.  The next point
      shows how to do this.
    </p>
    <p>
      Now type <code>C-/</code> (or <code>C-x u</code>) to undo this
      change and revert the buffer to the previous good state.  After
      doing this, the buffer should look like the result presented in
      the previous point.
    </p>
  </li>
  <li> <!-- 13. sort-regexp-fields (correct) -->
    <p>
      Assuming the state of the buffer is same as that of the result
      in point 11, we will now see how to alter the previous step such
      that when we sort the lines by the destination field, entire
      lines move along with the destination fields.  The trick is to
      ensure that the regular expression matches entire lines.  To do
      so, we make a minor change in the regular expression.
      Type <code>C-x h</code> followed by <code>M-x sort-regexp-fields
      RET .*-&gt;\(.*\) RET \1 RET</code>.
    </p>
<pre><code>Bob    100  London  LCY-&gt;CDG
Bob    30   Paris   ORY-&gt;HND
Dan    20   Tokyo   HND-&gt;LHR
Alice  10   Paris   CDG-&gt;LHR
Carol  200  London  LHR-&gt;SFO</code></pre>
    <p>
      Now the lines are sorted by the destination field and Dan from
      Tokyo is travelling from HND to LHR.
    </p>
  </li>
  <li> <!-- 14. sort-regexp-fields (reverse) -->
    <p>
      Type <code>C-x h</code> followed by <code>M-- M-x
      sort-regexp-fields RET .*-&gt;\(.*\) RET \1 RET</code> to
      reverse sort the lines by the destination airport.  Note that
      the first key combination is <kbd>meta</kbd>+<kbd>-</kbd> here.
      This key combination specifies a negative argument that results
      in a reverse sort.  The result looks like this:
    </p>
<pre><code>Carol  200  London  LHR-&gt;SFO
Dan    20   Tokyo   HND-&gt;LHR
Alice  10   Paris   CDG-&gt;LHR
Bob    30   Paris   ORY-&gt;HND
Bob    100  London  LCY-&gt;CDG</code></pre>
  </li>
  <li> <!-- 15. shell-command-on-region -->
    <p>
      Finally, note that we can always invoke shell commands on a
      region and replace the region with the output of the shell
      command.  To see this in action, first prepare the buffer by
      typing <code>M-&lt;</code> followed by <code>C-k C-k C-y
      C-y</code> to duplicate the first line of the buffer.
    </p>
    <p>
      Then type <code>C-x h</code> followed by <code>C-u M-| sort -u
      RET</code> to sort the lines but remove duplicate lines during
      the sort operation.  The <code>M-|</code> key sequence invokes
      the command <code>shell-command-on-region</code> which prompts
      for a shell command, executes it and usually displays the output
      in the echo area.  If the output cannot fit in the echo area,
      then it displays the output in a separate buffer.  However, if a
      prefix argument is supplied, say with <code>C-u</code>, then it
      replaces the region with the output.  As a result, the buffer
      now looks like this:
    </p>
    <pre><code>Alice  10   Paris   CDG-&gt;LHR
Bob    100  London  LCY-&gt;CDG
Bob    30   Paris   ORY-&gt;HND
Carol  200  London  LHR-&gt;SFO
Dan    20   Tokyo   HND-&gt;LHR</code></pre>
    <p>
      This particular problem of removing duplicates while sorting can
      be also be accomplished by typing <code>C-x h</code> followed
      by <code>M-x sort-lines RET</code> and then <code>C-x h</code>
      followed by <code>M-x delete-duplicate-lines</code>.
      Nevertheless, it is useful to know that we can execute arbitrary
      shell commands on a region.
    </p>
  </li>
</ol>
<h2 id="sorting-paragraphs-and-pages">Sorting Paragraphs and Pages<a href="#sorting-paragraphs-and-pages"></a></h2>
<p>
  We have covered most of the sorting commands mentioned in the Emacs
  manual in the previous section.  Now we will switch gears and
  discuss a few more of the remaining ones.  We will no longer sort
  individual lines but paragraphs and pages instead.
</p>
<ol>
  <li> <!-- 1. Create buffer -->
    <p>
      First create a buffer with the content provided below.  Note
      that the text below contains three form feed characters.  In
      Emacs, they are displayed as <code class="hl">^L</code>.  Many
      web browsers generally do not display them.
      The <code class="hl">^L</code> symbols that we see in the text
      below have been overlayed with CSS.  But there are actual form
      feed characters next to those overlays.  If you are viewing this
      post with any decent web browser, you can copy the text below
      into your Emacs and you should be able to see the form feed
      characters in Emacs.  In case you do not, insert them yourself
      by typing <code>C-q C-l</code>.
    </p>
<pre><code>Emacs is an advanced, extensible, customisable,
self-documenting editor.

Emacs editing commands operate in terms of
characters, words, lines, sentences, paragraphs,
pages, expressions, comments, etc.
<span class="ctrl-l hl">&#12;</span>
We will use the term frame to mean a graphical
window or terminal screen occupied by Emacs.

At the very bottom of the frame is an echo area.
The main area of the frame, above the echo area,
is called the window.
<span class="ctrl-l hl">&#12;</span>
The cursor in the selected window shows the
location where most editing commands take effect,
which is called point.

If you are editing several files in Emacs, each in
its own buffer, each buffer has its own value of
point.
<span class="ctrl-l hl">&#12;</span></code></pre>
  </li>
  <li> <!-- 2. sort-pages -->
    <p>
      Our text has six paragraphs spread across three pages.  Each
      form feed character represents a page break.  Type <code>C-x
      h</code> followed by <code>M-x sort-pages RET</code> to sort the
      pages alphabetically.  Note how the second page moves to the
      bottom because it begins with the letter "W".  The buffer now
      looks like this now:
    </p>
<pre><code>Emacs is an advanced, extensible, customisable,
self-documenting editor.

Emacs editing commands operate in terms of
characters, words, lines, sentences, paragraphs,
pages, expressions, comments, etc.
<span class="ctrl-l hl">&#12;</span>
The cursor in the selected window shows the
location where most editing commands take effect,
which is called point.

If you are editing several files in Emacs, each in
its own buffer, each buffer has its own value of
point.
<span class="ctrl-l hl">&#12;</span>
We will use the term frame to mean a graphical
window or terminal screen occupied by Emacs.

At the very bottom of the frame is an echo area.
The main area of the frame, above the echo area,
is called the window.
<span class="ctrl-l hl">&#12;</span></code></pre>
  </li>
  <li> <!-- 3. sort-paragraphs -->
    <p>
      Finally, type <code>C-x h</code> followed by <code>M-x
      sort-paragraphs</code> to sort the paragraphs alphabetically.
      The buffer looks like this now:
    </p>
<pre><code>At the very bottom of the frame is an echo area.
The main area of the frame, above the echo area,
is called the window.

Emacs editing commands operate in terms of
characters, words, lines, sentences, paragraphs,
pages, expressions, comments, etc.
<span class="ctrl-l hl">&#12;</span>
Emacs is an advanced, extensible, customisable,
self-documenting editor.

If you are editing several files in Emacs, each in
its own buffer, each buffer has its own value of
point.
<span class="ctrl-l hl">&#12;</span>
The cursor in the selected window shows the
location where most editing commands take effect,
which is called point.

We will use the term frame to mean a graphical
window or terminal screen occupied by Emacs.
<span class="ctrl-l hl">&#12;</span></code></pre>
  </li>
</ol>
<h2 id="references">References<a href="#references"></a></h2>
<p>
  To read and learn more about the sorting commands described above
  refer to the following resources:
</p>
<ul>
  <li><a href="https://www.gnu.org/software/emacs/manual/html_node/emacs/Sorting.html">Emacs Manual: Sorting Text</a></li>
  <li><a href="https://www.gnu.org/software/emacs/manual/html_node/elisp/Sorting.html">Elisp Manual: Sorting Text</a></li>
</ul>
<p>
  Within Emacs, type the following commands to read these manuals:
</p>
<ul>
  <li><code>M-: (info "(emacs) Sorting") RET</code></li>
  <li><code>M-: (info "(elisp) Sorting") RET</code></li>
</ul>
<p>
  Further, the documentation strings for these commands have useful
  information too.  Use the key sequence <code>C-h f</code> to look up
  the documentation strings.  For example, type <code>C-h f
  sort-regexp-fields RET</code> to look up the documentation string
  for the <code>sort-regexp-fields</code> command.
</p>
<!-- ### -->
<p>
  <a href="https://susam.net/sorting-in-emacs.html">Read on website</a> |
  <a href="https://susam.net/tag/emacs.html">#emacs</a> |
  <a href="https://susam.net/tag/technology.html">#technology</a> |
  <a href="https://susam.net/tag/how-to.html">#how-to</a>
</p>
]]>
</description>
</item>
<item>
<title>Good Quality DOSBox Video Capture</title>
<link>https://susam.net/good-quality-dosbox-video-capture.html</link>
<guid isPermaLink="false">dyzhs</guid>
<pubDate>Tue, 01 Sep 2020 00:00:00 +0000</pubDate>
<description>
<![CDATA[
<h2 id="vintage-dos-programs">Vintage DOS Programs<a href="#vintage-dos-programs"></a></h2>
<p>
  Once in a while, I fire up one of the vintage DOS games or language
  interpreters in DOSBox for nostalgia's sake.  DOSBox is an emulator
  program that emulates IBM PC compatible computers running DOS.
  Trying my hands on these antiquated DOS programs now evokes old
  memories from my childhood days days when I first came across
  computers as part of our primary school curriculum.
</p>
<p>
  Computers were much simpler in those days.  The ones in our school
  were IBM PC compatible computers with mostly monochrome displays.  A
  couple of them had support for a very limited number of colours
  provided by CGA or EGA graphics cards.  The ability to boot a
  computer using a 5&frac14;-inch floppy disk containing MS-DOS, load
  a Logo or BASIC interpreter or a computer game from another floppy
  disk and then write some programs or play a few games without any
  distraction had its own charm that I find missing from modern day
  computing.
</p>
<p>
  Often while using old DOS programs with DOSBox in this day and age,
  I want to take screenshot captures or video captures of the DOSBox
  sessions and share them with my friends.  In this article, I will
  explain how I create good quality screenshot captures and video
  captures of DOSBox sessions in formats that I can share with others.
</p>
<h2 id="contents">Contents<a href="#contents"></a></h2>
<ul>
  <li><a href="#vintage-dos-programs">Vintage DOS Programs</a></li>
  <li><a href="#software-versions">Software Versions</a></li>
  <li><a href="#ibm-pc-logo-in-dosbox">IBM PC Logo in DOSBox</a></li>
  <li><a href="#digger-in-dosbox">Digger in DOSBox</a></li>
  <li><a href="#dosbox-screenshot-capture">DOSBox Screenshot Capture</a></li>
  <li><a href="#dosbox-video-capture">DOSBox Video Capture</a></li>
  <li><a href="#dosbox-audio-video-capture">DOSBox Audio/Video Capture</a></li>
  <li><a href="#dosbox-gif-animation">DOSBox GIF Animation</a></li>
  <li><a href="#references">References</a></li>
</ul>
<h2 id="software-versions">Software Versions<a href="#software-versions"></a></h2>
<p>
  Since this article involves several pieces of software, some of what
  is written here may not hold good in future if the behaviour of any
  of these software tools change in future.  The list below contains
  the versions of all software tools that were used to test the
  commands provided in this article:
</p>
<ol>
  <li>macOS High Sierra 10.13.6</li>
  <li>DOSBox 0.74-3</li>
  <li>FFmpeg 4.3.1</li>
  <li>ImageMagick 7.0.10-28</li>
  <li>IBM Personal Computer Logo Version 1.00</li>
  <li>Digger (Original PC booter version by Windmill Software)</li>
</ol>
<p>
  Note that both Logo and Digger programs in the list above are DOS
  programs that were released in 1983.  They cannot be run directly on
  modern computers but they can be run with DOSBox since it emulates
  old IBM PC compatible computers.
</p>
<h2 id="ibm-pc-logo-in-dosbox">IBM PC Logo in DOSBox<a href="#ibm-pc-logo-in-dosbox"></a></h2>
<p>
  IBM Personal Computer Logo developed by Logo Computer Systems Inc.
  (LCSI) in 1983 was the first piece of software I got introduced to
  while learning computers as a kid.  I came across it at the age of 8
  when I was in Class 4 and our school had a 5&frac14;-inch floppy
  disk with IBM PC Logo on it.  As a result, Logo was the first
  programming language I learnt in my life.  About 20 years later, I
  would realise that the first programming language I learnt is a
  dialect of Lisp.  How wonderful!
</p>
<figure id="logo-welcome-screenshot">
  <a href="files/blog/dosbox-logo-0.png"><img
     src="files/blog/dosbox-logo-0.png"
     alt="A screenshot of IBM Personal Computer Logo with copyright notices of IBM and LCSI, welcome message and question mark prompt"></a>
  <figcaption>
    Welcome screen of IBM Personal Computer Logo
  </figcaption>
</figure>
<p>
  If the Logo interpreter program <code>LOGO.COM</code> exists in the
  current directory, it can be run with DOSBox using the following
  command:
</p>
<pre><code>dosbox LOGO.COM</code></pre>
<p>
  One of the things I enjoyed drawing with Logo was a grid of
  overlapping circles like this:
</p>
<figure id="logo-program-screenshot">
  <a href="files/blog/dosbox-logo-1.png"><img
     src="files/blog/dosbox-logo-1.png"
     alt="A grid made with 20 circles along with Logo source code for it"></a>
  <figcaption>
    Grid of circles drawn with IBM Personal Computer Logo
  </figcaption>
</figure>
<p>
  Here is the Logo source code for the above output:
</p>
<pre><code>REPEAT 20 [REPEAT 180 [FD 1 RT 2] RT 18]</code></pre>
<h2 id="digger-in-dosbox">Digger in DOSBox<a href="#digger-in-dosbox"></a></h2>
<p>
  At around the same time I learnt Logo, I also came across Digger, a
  computer game for IBM PC developed by Windmill Software in 1983.
</p>
<figure id="digger-welcome-screenshot">
  <a href="files/blog/dosbox-digger-0.png"><img
     src="files/blog/dosbox-digger-0.png"
     alt="A screenshot of Digger welcome screen with the names and pictures of various game characters with a copyright notice of Windmill Software"></a>
  <figcaption>
    Welcome screen of Digger
  </figcaption>
</figure>
<p>
  If the Digger program <code>DIGGER.COM</code> exists in the
  directory, it can be run using DOSBox with the following command:
</p>
<pre><code>dosbox DIGGER.COM -c "config -set cpu cycles=500" -machine cga</code></pre>
<p>
  The <code>-machine cga</code> option emulates a machine with Colour
  Graphics Adapter (CGA) because Digger requires a machine of this
  type to run correctly.  The <code>cycles=500</code> configuration
  option slows down the speed at which DOSBox emulates instructions in
  order to emulate the slow machines of olden days.  Without this
  option, Digger runs too fast to be able to be conveniently playable.
</p>
<figure id="digger-game-screenshot">
  <a href="files/blog/dosbox-digger-1.png"><img
     src="files/blog/dosbox-digger-1.png"
     alt="A screenshot of underground maze in the game of Digger"></a>
  <figcaption>
    A game of Digger that has just begun
  </figcaption>
</figure>
<p>
  Digger has an excellent gameplay where the player digs through
  underground tunnels to pick up emeralds, drop gold bags to release
  the gold or squash nobbins and hobbins, collect the released gold to
  earn more points and so on.  It uses bright and attractive colours.
  The music is great.  When Digger was released in 1983, it was quite
  advanced for its time.
</p>
<h2 id="dosbox-screenshot-capture">DOSBox Screenshot Capture<a href="#dosbox-screenshot-capture"></a></h2>
<p>
  The screenshots above were obtained by running IBM PC Logo and the
  original 1983 PC booter version of Digger on DOSBox and then
  resizing the screenshots such that their aspect ratio matches the
  aspect ratio of old CRT computer monitors.
</p>
<p>
  To obtain the screenshots, we first press
  <kbd>ctrl</kbd>+<kbd>f5</kbd> while DOSBox is running.  The paths of
  the screenshots appear in the console output at the terminal where
  DOSBox was launched.  For example:
</p>
<pre><samp>Capturing Screenshot to /Users/susam/Library/Preferences/capture/logo_000.png
Capturing Screenshot to /Users/susam/Library/Preferences/capture/logo_001.png</samp></pre>
<pre><samp>Capturing Screenshot to /Users/susam/Library/Preferences/capture/digger_000.png
Capturing Screenshot to /Users/susam/Library/Preferences/capture/digger_001.png</samp></pre>
<p>
  The screenshots obtained in this manner have an aspect ratio of 8:5
  which makes the output look stretched horizontally.  The old CRT
  computer monitors for which these old DOS programs were written had
  an aspect ratio of 4:3 instead.  This stretched look can be fixed by
  resizing the images to an aspect ratio of 4:3.  Here are the
  commands used to fix the aspect ratio and produce the images:
</p>
<pre><code>convert logo_000.png -sample '1920x1440!' dosbox-logo-0.png
convert logo_001.png -sample '1920x1440!' dosbox-logo-1.png</code></pre>
<pre><code>convert digger_000.png -sample '1920x1440!' dosbox-digger-0.png
convert digger_001.png -sample '1920x1440!' dosbox-digger-1.png</code></pre>
<!--
According to Screen Resolution Statistics for January 2020 by
w3schools.com, here are the statistics of browser resolutions:

Resolution   %age  Cumulative

Lower         9.0    9.0
1280 x  720   3.9   12.9
1024 x  768   1.4   14.3
1360 x  768   1.0   15.3
1366 x  768  27.6   42.9
1280 x  800   1.8   44.7
1536 x  864   9.8   54.5
1440 x  900   5.6   60.1
1600 x  900   4.1   64.2
1280 x 1024   2.4   66.6
1680 x 1050   2.6   69.2
1920 x 1080  20.3   89.5
1920 x 1200   1.5   91.0
2560 x 1440   1.7   92.7
Other High    7.3  100.0

1440 x 1080 is strictly larger than 54.5% displays.
1600 x 1200 is strictly larger than 66.6% displays.
1920 x 1440 is strictly larger than 91.0% displays.
x 1080 is larger than 89.5% displays
x 1200 is larger than 91.0% displays.
x 1440 is larger than 92.7% displays
-->
<p>
  The <code>convert</code> program comes with ImageMagick.  There are
  a few things worth noting here:
</p>
<ul>
  <li>
    We use the <code>-sample</code> option here to resize the image as
    opposed to using <code>-resize</code> or <code>-scale</code>.  The
    <code>-resize</code> or <code>-scale</code> option would smooth
    the jagged edges in the text and graphics by introducing
    additional colours.  The <code>-resize</code> option is great for
    real world images where we do want the edges to be smooth while
    scaling up or down but in these screenshots we want to retain the
    crisp and jagged edges that is typical of DOSBox and the old CRT
    monitors.  Therefore we use the <code>-sample</code> option that
    does not introduce any new colours.  Instead it uses
    nearest-neighbour interpolation (point sampling) to decide the
    colours of the scaled image.
  </li>
  <li>
    The <code>!</code> flag is used to ignore the aspect ratio of the
    original image.  Without this flag, the output files would be
    1920x1200 in size, that is, the largest size with an aspect ratio
    of 8:5 that fits in a 1920x1440 box.  With this flag, the original
    aspect ratio of 8:5 is ignored and the output is exactly 1920x1440
    in size.
  </li>
</ul>
<h2 id="dosbox-video-capture">DOSBox Video Capture<a href="#dosbox-video-capture"></a></h2>
<p>
  To start capturing video of DOSBox, we
  press <kbd>ctrl</kbd>+<kbd>alt</kbd>+<kbd>f5</kbd>.  The same key
  combination stops capturing video.  The following output appears in
  the console output to show where the video file is saved:
</p>
<pre><samp>Capturing Video to /Users/susam/Library/Preferences/capture/logo_000.avi
Stopped capturing video.</samp></pre>
<p>
  Say, I want to share a video capture of DOSBox with Logo running on
  it with my friends who might be on devices that do not support
  playing AVI files.  The following FFmpeg command converts the video
  to a format that can be distributed widely and played on a wide
  range of devices and players:
</p>
<pre><code>ffmpeg -i logo_000.avi -an -c:v libx264 -preset veryslow \
       -crf 17 -vf format=yuv420p,scale=1920:1440:flags=neighbor,fps=30 \
       dosbox-logo.mp4</code></pre>
<p>
  Here is what the output looks like:
</p>
<figure id="logo-video">
  <video controls>
    <source src="files/blog/dosbox-logo.mp4" type="video/mp4">
  </video>
  <figcaption>
    Video capture of IBM Personal Computer Logo
    [<a href="files/blog/dosbox-logo.mp4">MP4</a>]
  </figcaption>
</figure>
<p>
  Let us briefly discuss the various FFmpeg options used here:
</p>
<ul>
  <li>
    <p>
      <code>-i logo_000.avi</code>
    </p>
    <p>
      This, of course, specifies the input file.
    </p>
  </li>
  <li>
    <p>
      <code>-an</code>
    </p>
    <p>
      The audio is silent in this video, so we reduce the file size a
      little by disabling the audio stream with this option.  For
      example, without this option the output file size was 317 KB but
      with this option it turned out to be 282 KB.
    </p>
    <p>
      This option should not be specified if the audio stream needs to
      preserved, for example, with DOS games that have audio.  We will
      see an example of this in the next section.
    </p>
  </li>
  <li>
    <p>
      <code>-c:v libx264</code>
    </p>
    <p>
      This option selects the x264 encoder to encode the video stream
      into H.264 format.  H.264 is also known as MPEG-4 Part 10,
      Advanced Video Coding (MPEG-4 AVC).  Currently, it is the most
      popular format for recording, compression and distribution of
      video content.
    </p>
  </li>
  <li>
    <p>
      <code>-crf 17</code>
    </p>
    <p>
      This option provides visually lossless output, that is, high
      quality output without any loss in quality that can be perceived
      by human eyes.  For completely lossless output, we need to use
      the <code>-crf 0</code> option.  However, this option sets the
      video profile to <code>High 4:4:4 Predictive</code> which
      prevents the video from playing in some video players.  This
      issue is discussed in more detail in the point
      about <code>yuv420p</code> pixel format that comes later in this
      list.  Since <code>-crf 0</code> cannot be used due to this
      issue, the next best option is
      <code>-crf 1</code> which while not completely lossless is much
      better than visually lossless.  Since it trades quality for
      output size, the output file turns out to be 319 KB in size.  The
      <code>-crf 51</code> option produces the most lossy output, that
      is, the worst quality output with a file size of 159 KB.
    </p>
  </li>
  <li>
    <p>
      <code>-preset veryslow</code>
    </p>
    <p>
      This option provides better compression at the cost of encoding
      speed.  For example, without this option it produces an output
      of size 355 KB in about 16 seconds on my system but with this
      option it produces an output of size 282 KB in about 31 seconds
      on the same system.
    </p>
  </li>
  <li>
    <p>
      <code>-vf format=yuv420p</code>
    </p>
    <p>
      This video filter option ensures that the output video file can
      be run in a wide range of devices and players.
    </p>
    <p>
      For example, without this video filter option, we get the output
      in the YUV 4:4:4 planar format.  I found that QuickTime Player
      version 10.4 on macOS High Sierra as well as Android 9.0.0 was
      unable to play this format.
    </p>
<pre><samp>$ <kbd>ffmpeg -v quiet -i logo_000.avi -an -c:v libx264 dosbox-logo.mp4</kbd>
$ <kbd>ffprobe -v error -show_entries stream=codec_name,profile,pix_fmt dosbox-logo.mp4</kbd>
[STREAM]
codec_name=h264
profile=High 4:4:4 Predictive
pix_fmt=yuv444p
[/STREAM]</samp></pre>
    <p>
      With this video filter option, we get the output in the YUV
      4:2:0 planar format.  Now both QuickTime Player version 10.4 as
      well as Android 9.0.0 could play this format.
    </p>
<pre><samp>$ <kbd>ffmpeg -v quiet -i logo_000.avi -an -c:v libx264 -vf format=yuv420p dosbox-logo.mp4</kbd>
$ <kbd>ffprobe -v error -show_entries stream=codec_name,profile,pix_fmt dosbox-logo.mp4</kbd>
[STREAM]
codec_name=h264
profile=High
pix_fmt=yuv420p
[/STREAM]</samp></pre>
    <p>
      For maximum compatibility with very old or obsolete devices, we
      could add the <code>-profile:v baseline</code> option that setst
      the video profile to <code>Constrained Baseline</code>.  This
      option is not recommended unless we really need to support old
      or obsolete devices.  We also need to keep in mind that the
      baseline profile does not support lossless encoding with
      the <code>-crf 0</code> option.  The least lossy encoding option
      we can specify with this profile is <code>-crf 1</code> which
      while not technically lossless is much better than visually
      lossless.
    </p>
<pre><samp>$ <kbd>ffmpeg -v quiet -i logo_000.avi -an -c:v libx264 -vf format=yuv420p -profile:v baseline dosbox-logo.mp4</kbd>
$ <kbd>ffprobe -v error -show_entries stream=codec_name,profile,pix_fmt dosbox-logo.mp4</kbd>
[STREAM]
codec_name=h264
profile=Constrained Baseline
pix_fmt=yuv420p
[/STREAM]</samp></pre>
  </li>
  <li>
    <p>
      <code>scale=1920:1440:flags=neighbor</code>
    </p>
    <p>
      With this video filter option, we resize the video to maintain
      an aspect ratio of 4:3, that is, the aspect ratio of the old CRT
      computer monitors, so that the output looks similar to how it
      used to look on those monitors.
    </p>
    <p>
      The <code>neighbor</code> flag ensures that the nearest-neighbor
      interpolation (point sampling) is used to decide the colours of
      the scaled image.  Without this option, the default bicubic
      interpolation algorithm is used.  It has the effect of smoothing
      the edges by introducing new colours such as new shades of grey
      for this example video.  While such smoothing of edges is good
      for scaling pictures of the real world, in this case, it spoils
      the crisp and jagged edges that is typical of output visible in
      DOSBox or the old CRT monitors.  With the <code>neighbor</code>
      option, we retain the crisp and jagged edges visible in the
      original video capture.
    </p>
  </li>
  <li>
    <p>
      <code>fps=30</code>
    </p>
    <p>
      This video filter option sets the frame rate to 30 frames per
      second (FPS).  Without this option, the output video has a frame
      rate of 70.09 FPS and file size of 558 KB.  With this option the
      output frame rate is 30 FPS and the file size is 282 KB.
    </p>
    <p>
      The default value of <code>machine</code> configuration variable
      of DOSBox v0.74-3 is <code>svga_s3</code>, so by default it
      emulates a machine with SVGA card.  While emulating a machine
      with SVGA card, DOSBox creates video capture files with frame
      rate of 70.09 FPS.  When it emulates a machine with CGA card,
      such as when the its <code>machine</code> configuration variable
      is set to <code>cga</code> or when DOSBox is run with
      the <code>-machine cga</code> option, it creates video captures
      files with frame rate of 59.92 FPS.
    </p>
    <p>
      For the <a href="#logo-video">Logo video capture</a>, there is
      no high-speed motion going on in the video, so we don't need a
      high frame rate.  A lower frame rate of 30 FPS looks just as
      good.
    </p>
  </li>
</ul>
<h2 id="dosbox-audio-video-capture">DOSBox Audio/Video Capture<a href="#dosbox-audio-video-capture"></a></h2>
<p>
  The video capture of Digger game is processed similarly, however,
  there are a few additional things we need to take care of.  We want
  to include the game audio in the output file.  We also want a higher
  frame rate because games may sometimes have high-speed motion.
</p>
<p>
  Like before, we use <kbd>ctrl</kbd>+<kbd>alt</kbd>+<kbd>f5</kbd> to
  start capturing the video.  The same key combination stops capturing
  video.  The following output appears in the console output to show
  where the video file is saved:
</p>
<pre><samp>Capturing Video to /Users/susam/Library/Preferences/capture/digger_000.avi
Stopped capturing video.</samp></pre>
<p>
  Here is the command to convert the video capture of Digger to a
  distributable format:
</p>
<pre><code>ffmpeg -i digger_000.avi -c:a aac -b:a 256k -c:v libx264 -preset veryslow \
       -crf 17 -vf format=yuv420p,scale=1920:1440:flags=neighbor,fps=50 \
       dosbox-digger.mp4</code></pre>
<p>
  Here is the output:
</p>
<figure id="digger-video">
  <video controls>
    <source src="files/blog/dosbox-digger.mp4" type="video/mp4">
  </video>
  <figcaption>
    Video capture of Digger
    [<a href="files/blog/dosbox-digger.mp4">MP4</a>]
  </figcaption>
</figure>
<p>
  Most of the FFmpeg options used in the command above have been
  discussed in the previous section.  Let us discuss the new options
  used here that have not been discussed earlier:
</p>
<ul>
  <li>
    <p>
      <code>-c:a aac</code>
    </p>
    <p>
      This option selects the native FFmpeg AAC encoder to encode the
      audio stream to Advanced Audio Coding (AAC) format.  It is a
      very popular format for audio streams in MP4 files.
    </p>
  </li>
  <li>
    <p>
      <code>-b:a 256k</code>
    </p>
    <p>
      This sets the audio bitrate high enough to ensure that we get
      good quality audio in the output.  We don't need to worry about
      our specified bitrate being too high.  If the audio can be
      encoded with a lower bitrate without compromising on quality,
      the output audio stream is encoded at a lower bitrate.  For
      example, for this specific video, the actual audio bitrate in
      the output file turns out to be 245k because that is enough to
      encode the audio stream in the input file.
    </p>
<pre><samp>$ <kbd>ffprobe -v error -select_streams a -show_entries stream=bit_rate dosbox-digger.mp4</kbd>
[STREAM]
bit_rate=245184
[/STREAM]</samp></pre>
  </li>
  <li>
    <p>
      <code>fps=50</code>
    </p>
    <p>
      If we set the frame rate to a lower value like 30 FPS like we
      did in the previous section, we still get pretty good output,
      however, certain parts of the output video look slightly choppy.
      For example, at 7 seconds into the video when the player is the
      pushing up against the gold bag, the video becomes slightly
      choppy if we generate the output with a frame rate of 30 FPS.  A
      higher frame rate such as 50 FPS prevents this problem.
    </p>
    <p>
      If we omit this option entirely, we get an output video that has
      the same frame rate as that of the input video, that is, 59.92
      FPS, with an output file size of 4.6 MB.  With this option, we
      get an output video that has a frame rate of 50 FPS and a file
      size of 4.2 MB.
    </p>
  </li>
</ul>
<p>
  If we look at the output video above closely enough, we see that the
  colours don't look as crisp as they do in
  the <a href="#digger-game-screenshot">Digger game screenshot</a>.
  The <code>neighbor</code> flag was very effective at maintaining the
  crisp and jagged edges in the <a href="#logo-video">Logo video
  capture</a> but it does not produce perfect results for
  the <a href="#digger-video">Digger video capture</a> in this
  section.  Despite the imperfection, it is still necessary to specify
  the <code>neighbor</code> option because without this option, the
  output video looks even worse.  We can use a different pixel format
  like <code>yuv444p</code> instead of <code>yuv420p</code> to work
  around this issue.  Using the <code>yuv444p</code> format indeed
  results in perfect nearest-neighbour interpolation which helps in
  retaining the crisp and jagged edges in the video accurately but as
  explained in the previous section, many media players currently
  cannot play this pixel format, so we stick to using
  the <code>yuv420p</code> format in this article.
</p>
<h2 id="dosbox-gif-animation">DOSBox GIF Animation<a href="#dosbox-gif-animation"></a></h2>
<p>
  Now just for fun, let us see if we can convert the video captures
  into GIF animations.  This can be done quite easily with FFmpeg.
  Here are the commands to convert the Logo video capture to GIF
  animation:
</p>
<pre><samp>ffmpeg -i logo_000.avi -vf palettegen palette.png
ffmpeg -i logo_000.avi -i palette.png \
       -lavfi 'scale=1920:1440:flags=neighbor,paletteuse,fps=30' \
       dosbox-logo.gif</samp></pre>
<p>
  The first command generates a colour palette from the video capture.
  The second command uses this colour palette to generate a GIF
  animation.  Like before, we use the <code>neighbor</code> flag to
  retain the crisp and jagged edges.  Here is the output:
</p>
<figure id="logo-gif">
  <a href="files/blog/dosbox-logo.gif"><img
      src="files/blog/dosbox-logo.gif"
       alt="An animated image of programming in Logo"></a>
  <figcaption>
    GIF animation of IBM Personal Computer Logo
  </figcaption>
</figure>
<p>
  Here are the commands to convert the Digger video capture to GIF
  animation:
</p>
<pre><samp>ffmpeg -i digger_000.avi -vf palettegen palette.png
ffmpeg -i digger_000.avi -i palette.png \
       -lavfi 'scale=1920:1440:flags=neighbor,paletteuse,fps=50' \
       dosbox-digger.gif</samp></pre>
<figure id="digger-gif">
  <a href="files/blog/dosbox-digger.gif"><img
      src="files/blog/dosbox-digger.gif"
       alt="An animated image of a game of Digger"></a>
  <figcaption>
    GIF animation of a game of Digger
  </figcaption>
</figure>
<h2 id="references">References<a href="#references"></a></h2>
<p>
  Here is a bunch of references that contains more details about the
  commands used in this article:
</p>
<ul>
  <li><a href="https://www.dosbox.com/wiki/Special_Keys">DOSBox Special Keys</a></li>
  <li><a href="https://www.imagemagick.org/Usage/resize/">ImageMagick Examples: Resize or Scaling</a></li>
  <li><a href="https://www.imagemagick.org/Usage/filter/">ImageMagick Examples: Resampling Filters</a></li>
  <li><a href="https://trac.ffmpeg.org/wiki/Encode/H.264">FFmpeg H.264 Video Encoding Guide</a></li>
  <li><a href="https://trac.ffmpeg.org/wiki/Scaling">FFmpeg Scaling Guide</a></li>
  <li><a href="https://www.ffmpeg.org/ffmpeg-scaler.html">FFmpeg Scaler Documentation</a></li>
  <li><a href="https://ffmpeg.org/ffmpeg-filters.html">FFmpeg Filters Documentation</a></li>
</ul>
<!-- ### -->
<p>
  <a href="https://susam.net/good-quality-dosbox-video-capture.html">Read on website</a> |
  <a href="https://susam.net/tag/dos.html">#dos</a> |
  <a href="https://susam.net/tag/technology.html">#technology</a> |
  <a href="https://susam.net/tag/how-to.html">#how-to</a>
</p>
]]>
</description>
</item>
<item>
<title>Lisp in Vim</title>
<link>https://susam.net/lisp-in-vim.html</link>
<guid isPermaLink="false">bgxhz</guid>
<pubDate>Sat, 07 Dec 2019 00:00:00 +0000</pubDate>
<description>
<![CDATA[
<h2 id="introduction">Introduction<a href="#introduction"></a></h2>
<p>
  Fifteen years ago, writing Lisp code in Vim was an odd adventure.
  There were no good plugins for Vim that assisted in structured
  editing of Lisp s-expressions or allowed interactive programming by
  embedding a Lisp Read-Eval-Print-Loop (REPL) or a debugger within
  the editor.  The situation has improved a lot since then.  In the
  last ten years, we have seen active development of two Vim plugins
  named <a href="https://github.com/kovisoft/slimv">Slimv</a> and
  <a href="https://github.com/l04m33/vlime">Vlime</a>.  Slimv is over
  10 years old now.  Vlime is more recent and less than 3 years old
  right now.  Both support interactive programming in Lisp.
</p>
<p>
  I am going to discuss and compare both Slimv and Vlime in this
  article.  I will show how to get started with both plugins and
  introduce some of their basic features.  I will not cover everything
  though.  This is not a tutorial.  For tutorials, see
  the <a href="#references"><em>References</em></a> section.
</p>
<p>
  If you are looking only for a comparison of the two plugins or a
  quick recommendation, jump directly to the
  <a href="#comparison-of-slimv-and-vlime"><em>Comparison of Slimv and Vlime</em></a>
  section or the
  <a href="#quick-recommendation"><em>Quick Recommendation</em></a>
  section.
</p>
<h2 id="contents">Contents<a href="#contents"></a></h2>
<ul>
  <li><a href="#introduction">Introduction</a></li>
  <li><a href="#background">Background</a>
    <ul>
      <li><a href="#lisp">Lisp</a></li>
      <li><a href="#emacs-slime">Emacs: SLIME</a></li>
      <li><a href="#vim-slimv-vlime">Vim: Slimv/Vlime</a></li>
    </ul>
  </li>
  <li><a href="#vim-plugin-management">Vim Plugin Management</a></li>
  <li><a href="#software-versions">Software Versions</a></li>
  <li><a href="#get-started">Get Started</a>
    <ul>
      <li><a href="#get-started-with-slimv-and-sbcl">Get Started with Slimv and SBCL</a></li>
      <li><a href="#get-started-with-vlime-and-sbcl">Get Started with Vlime and SBCL</a></li>
      <li><a href="#get-started-with-paredit">Get Started with Paredit</a></li>
    </ul>
  </li>
  <li><a href="#use-debugger-and-inspector">Use Debugger and Inspector</a>
    <ul>
      <li><a href="#use-debugger-and-inspector-with-slimv">Use Debugger and Inspector with Slimv</a></li>
      <li><a href="#use-debugger-and-inspector-with-vlime">Use Debugger and Inspector with Vlime</a></li>
    </ul>
  </li>
  <li><a href="#trace-function">Trace Function</a>
    <ul>
      <li><a href="#trace-function-in-slimv">Trace Function in Slimv</a></li>
      <li><a href="#trace-function-in-vlime">Trace Function in Vlime</a></li>
    </ul>
  </li>
  <li><a href="#nifty-features">Nifty Features</a>
    <ul>
      <li><a href="#evaluate-top-level-form">Evaluate Top-Level Form</a></li>
      <li><a href="#rainbow-parentheses">Rainbow Parentheses</a></li>
      <li><a href="#argument-list">Argument List</a></li>
      <li><a href="#omni-completion">Omni-Completion</a></li>
      <li><a href="#describe-symbol">Describe Symbol</a></li>
      <li><a href="#expand-macro">Expand Macro</a></li>
      <li><a href="#cross-reference">Cross Reference</a></li>
    </ul>
  </li>
  <li><a href="#other-common-lisp-implementations">Other Common Lisp Implementations</a>
    <ul>
      <li><a href="#use-slimv-with-clisp">Use Slimv with CLISP</a></li>
      <li><a href="#use-slimv-with-ecl">Use Slimv with ECL</a></li>
      <li><a href="#use-vlime-with-clisp">Use Vlime with CLISP</a></li>
      <li><a href="#use-vlime-with-ecl">Use Vlime with ECL</a></li>
    </ul>
  </li>
  <li><a href="#other-lisp-dialects">Other Lisp Dialects</a>
    <ul>
      <li><a href="#use-slimv-with-mit-gnu-scheme">Use Slimv with MIT/GNU Scheme</a></li>
      <li><a href="#use-slimv-with-clojure">Use Slimv with Clojure</a></li>
    </ul>
  </li>
  <li><a href="#comparison-of-slimv-and-vlime">Comparison of Slimv and Vlime</a></li>
  <li><a href="#quick-recommendation">Quick Recommendation</a></li>
  <li><a href="#disclosure">Disclosure</a></li>
  <li><a href="#references">References</a></li>
</ul>
<h2 id="background">Background<a href="#background"></a></h2>
<p>
  Before we get started with Slimv and Vlime, it would be nice to take
  a brief look at the heritage behind these plugins.  These plugins
  provide Lisp development environments for Vim, so their story begins
  with Lisp.
</p>
<h3 id="lisp">Lisp<a href="#lisp"></a></h3>
<p>
  Lisp is a family of programming languages with a distinctive, fully
  parenthesised prefix notation.  It is quite unlike most of the other
  popular programming languages today like C, Python, Ruby, etc.  Its
  homoiconic nature and its powerful macro system that can transform
  arbitrary Lisp expressions make it such a flexible, versatile,
  extensible and introspective language that articles describing Lisp
  often have the word "enlightenment" in them.  For example, see the
  following articles:
</p>
<ul>
  <li>
    <a href="http://www.paulgraham.com/avg.html"><em>Beating the
    Averages</em></a> (by Paul Graham)
  </li>
  <li>
    <a href="https://www.defmacro.org/ramblings/lisp.html"><em>The
    Nature of Lisp</em></a> (by Slava Akhmechet)
  </li>
  <li>
    <a href="https://twobithistory.org/2018/10/14/lisp.html"><em>How
    Lisp Became God's Own Programming Language</em></a> (by Sinclair
    Target)
  </li>
</ul>
<p>
  Lisp has been described in various ways by various eminent
  personalities in the history of computing.  Alan Kay has famously
  described Lisp as:
</p>
<blockquote>
  The greatest single programming language ever designed.
</blockquote>
<p>
  John Foderaro has written this about Lisp:
</p>
<blockquote>
  Lisp is a programmable programming language.
</blockquote>
<p>
  Eric S. Raymond has expressed the enlightenment one experiences by
  learning Lisp in his famous article titled
  <a href="http://www.catb.org/~esr/faqs/hacker-howto.html"><em>How To Become A Hacker</em></a>:
</p>
<blockquote>
  Lisp is worth learning for the profound enlightenment experience you
  will have when you finally get it.  That experience will make you a
  better programmer for the rest of your days, even if you never
  actually use Lisp itself a lot.
</blockquote>
<p>
  Randall Munroe, the creator of the
  <a href="https://xkcd.com/">XKCD</a> webcomic has dedicated two
  comic strips to Lisp:
</p>
<figure class="soft">
  <img src="files/blog/xkcd-224-lisp.jpg" alt="XKCD comic on Lisp"
       title="Original title text: We lost the documentation on quantum mechanics.  You'll have to decode the regexes yourself.">
  <figcaption>
    <em>Lisp</em> by Randall Munroe
    (Source: <a href="https://xkcd.com/224/">https://xkcd.com/224/</a>)
  </figcaption>
</figure>
<figure class="soft">
  <img src="files/blog/xkcd-297-lisp-cycles.png" alt="XKCD comic on Lisp Cycles"
       title="Original title text: I've just received word that the Emperor has dissolved the MIT computer science program permanently.">
  <figcaption>
    <em>Lisp Cycles</em> by Randall Munroe
    (Source: <a href="https://xkcd.com/297/">https://xkcd.com/297/</a>)
  </figcaption>
</figure>
<p>
  Developed in 1958 by John McCarthy, Lisp is the second oldest
  programming language in use today.  Only Fortran is older, by one
  year.  Some of the popular Lisp dialects today include Common Lisp,
  Scheme and Clojure.  Most of this article would focus on Common
  Lisp.  Scheme and Clojure would be discussed briefly towards the end
  of this article.
</p>
<h3 id="emacs-slime">Emacs: SLIME<a href="#emacs-slime"></a></h3>
<p>
  Many Lisp programmers immediately think of Emacs when they think of
  writing Lisp code.  Emacs is a family of text editors.  An Emacs
  editor itself is typically implemented in a dialect of Lisp.  There
  is an Emacs mode named SLIME that provides excellent support for
  programming in Lisp.  SLIME stands for Superior Lisp Interaction
  Mode for Emacs.  First released in August 2003, SLIME was created by
  Eric Marsden and then later developed further by Luke Gorrie and
  Helmut Eller.  It offers a Read-Eval-Print-Loop (REPL), integrated
  debugging and interactive evaluation of expressions, all available
  right within the editor.  There are several nifty key bindings
  available to compile and evaluate parts or whole of the code in the
  current buffer.
</p>
<p>
  SLIME works by launching a Swank TCP server.  Swank is a backend
  server program written in Common Lisp that listens on a socket to
  receive SLIME commands from Emacs and execute them.  SLIME is so
  useful that it is considered to be indispensible by many Lisp
  programmers who write Lisp code in Emacs.
</p>
<h3 id="vim-slimv-vlime">Vim: Slimv/Vlime<a href="#vim-slimv-vlime"></a></h3>
<p>
  Is there anything similar to SLIME for Vim?  Yes, there are two
  popular options:
</p>
<ul>
  <li>
    <p>
      <strong>Slimv:</strong> It stands for Superior Lisp Interaction
      Mode for Vim.  It is a Vim plugin created by Tamas Kovacs that
      was first released in January 2009.
    </p>
  </li>
  <li>
    <p>
      <strong>Vlime:</strong> It is a Vim plugin created by Kay Z that
      was first released in May 2017.  It is much more recent than
      Slimv.  Vlime is younger than Slimv by eight years.
    </p>
  </li>
</ul>
<p>
  Both plugins use a client-server architecture like SLIME does in
  Emacs.  Both plugins rely on Swank server to be started.  In fact,
  Slimv bundles a slightly modified version of Swank with it, so that
  it can launch it and connect to it to send expressions to be
  evaluated.  Vlime does not bundle Swank server with itself but it
  provides a wrapper that automatically downloads Swank server when
  needed.
</p>
<h2 id="vim-plugin-management">Vim Plugin Management<a href="#vim-plugin-management"></a></h2>
<p>
  When I started using Vim fifteen years ago, we used to just download
  a Vim plugin and copy/extract it to <code>~/.vim</code> directory.
  These days, there are a few plugin management tools for Vim such
  as <a href="https://github.com/tpope/vim-pathogen">Pathogen</a>,
  <a href="https://github.com/VundleVim/Vundle.Vim">Vundle</a>,
  <a href="https://github.com/junegunn/vim-plug">vim-plug</a>, etc.  I
  am not going to use any of them because I don't know which one of
  them you use and I don't want to write down steps for each one of
  them.
</p>
<p>
  In fact, I have never used any Vim plugin manager myself.  Until Vim
  7, I used to create a <code>~/.vim/bundle</code> directory, then
  copy each plugin to its own directory within it and add the plugin's
  directory path to Vim's <code>runtimepath</code> option.
</p>
<p>
  Vim 8 has native support for packages which makes installing plugins
  and loading them simpler.  With Vim 8, we can copy each plugin to
  its own directory within <code>~/.vim/pack/plugins/start</code> and
  they are loaded automatically when Vim starts.  The directory name
  <code>plugins</code> in this path is only an example.  It could be
  any arbitrary name and Vim would still load the plugins fine.
</p>
<p>
  In this article, I will use Vim 8's native support for packages to
  set up Vim plugins.  The only exception to this would be installing
  Vlime.  The top-level directory of Vlime is not the plugin
  directory.  The plugin directory is contained in a subdirectory
  named <code>vim</code>.  This does not conform to the directory
  structure of plugins in a Vim package.  Therefore, in this article,
  I will set up Vlime in the old fashioned way by copying it
  to <code>~/.vim/bundle</code> and then adding the path to its plugin
  directory to Vim's <code>runtimepath</code> option.
</p>
<h2 id="software-versions">Software Versions<a href="#software-versions"></a></h2>
<p>
  Since this article involves several layers of software, some of what
  is written here may not hold good in future as these various pieces
  of software change and evolve over time.  Therefore, in this
  section, I will note down the versions of various software tools I
  used while writing this article.  Here they are:
</p>
<ul>
  <li>Debian GNU/Linux 10.1 (buster)</li>
  <li>Vim 8.1</li>
  <li>
    Slimv (Git repo last updated on 30 Nov 2019 with commit
    <a href="https://github.com/kovisoft/slimv/commits/47a0070">47a0070</a>)
  </li>
  <li>
    Vlime (Git repo last updated on 16 Oct 2017 with commit
    <a href="https://github.com/l04m33/vlime/commits/065b95f">065b95f</a>)
  </li>
  <li>
    Paredit (Git repo last updated on 30 Nov 2019 with commit
    <a href="https://github.com/kovisoft/paredit/commits/d99905a">d99905a</a>)
  </li>
  <li>
    Rainbow Parentheses (Git repo last updated on 29 Oct 2015 with commit
    <a href="https://github.com/junegunn/rainbow_parentheses.vim/commits/27e7cd7">27e7cd7</a>)
  </li>
  <li>SBCL 1.4.16.debian</li>
  <li>GNU CLISP 2.49.92</li>
  <li>ECL 16.1.3</li>
  <li>MIT/GNU Scheme 9.1.1 on Debian GNU/Linux 9.11 (stretch)</li>
  <li>Clojure 1.10.1</li>
  <li>Quicklisp beta (libraries last updated on 30 Nov 2019)</li>
  <li>tmux 2.8</li>
</ul>
<p>
  You will probably need only a tiny subset of the tools above
  depending on which sections in this article you would follow.  Just
  pick the sections you want to try out and follow the steps written
  in them.  They will walk you through the procedure to install the
  tools applicable to the sections you have picked.  Regardless of
  which sections you pick, I recommend that you definitely go through
  the three "Get Started" subsections below.  These subsections go
  into detail about some of the prerequisites such as support for
  tmux, Paredit, support for Python interface in Vim, etc. that are
  not covered in the other sections.
</p>
<p>
  The choice of Debian may look like an odd one.  I want the commands
  and steps discussed in this article to be easily reproducible in a
  free and open source operating system.  Debian happens to be my
  favourite.  What works on Debian is easily reproducible on Ubuntu
  and other derivatives, often without any changes to the steps.  I
  believe, it will not be too difficult to translate the steps
  provided for Debian to the steps that would work on another
  operating system.
</p>
<p>
  Note that Quicklisp (a prerequisite for Vlime) is still beta
  software at the time of writing this article.  The actual steps to
  install Quicklisp may change in future.  Check
  <a href="https://www.quicklisp.org/">https://www.quicklisp.org/</a>
  for the most up-to-date instructions to install Quicklisp.
</p>
<h2 id="get-started">Get Started<a href="#get-started"></a></h2>
<h3 id="get-started-with-slimv-and-sbcl">Get Started with Slimv and SBCL<a href="#get-started-with-slimv-and-sbcl"></a></h3>
<p>
  Here are the steps to set up Slimv and use it:
</p>
<ol>
  <li>
    <p>
      Install the tools required to set up a Common Lisp development
      environment with Slimv with this command:
    </p>
    <pre><code>sudo apt-get install vim-nox sbcl tmux git</code></pre>
    <p>
      The default Vim in Debian is <code>vim.basic</code> provided by
      the <code>vim</code> package which does not have support for
      Python interface.  Slimv is written in Vim script, Lisp and
      Python 3, so it does need a Vim package that has support for
      Python interface.  One such package is <code>vim-nox</code> that
      provides the <code>vim.nox</code> command.  Installing it
      automatically updates the <code>vim</code> command to
      run <code>vim.nox</code>.  Another such package
      is <code>vim-gtk</code> which additionally provides GUI support.
      The graphical Vim known as GVim can be launched with
      the <code>gvim</code> command.  It runs in the desktop
      environment.  For the purpose of this article, I will stick
      to <code>vim-nox</code> because it is lightweight.  All steps
      meant for Slimv would run equally well on <code>vim-gtk</code>,
      MacVim and GVim.
    </p>
    <p>
      Installing tmux is optional.  Slimv can launch Swank server
      automatically if Vim is running within tmux, GNU Screen or a
      desktop environment, so if you are using GNU Screen already, you
      don't need to install tmux.  Also, if you are running Slimv in a
      desktop environment, you don't really need to install either
      tmux or GNU Screen, although you could if you would like to see
      Swank running in a separate tmux or GNU Screen window rather
      than a separate terminal window.  In this article, I am going to
      assume that Vim is running within tmux.
    </p>
    <p>
      If you are going to run Slimv in a terminal without a desktop
      environment, tmux or GNU Screen, Swank server has to be run
      manually.  Point 4 below explains how to do it.
    </p>
  </li>
  <li>
    <p>
      Installing Slimv is pretty simple.  Here is one way to do it:
    </p>
<pre><code>git clone https://github.com/kovisoft/slimv.git ~/.vim/pack/plugins/start/slimv
vim +'helptags ~/.vim/pack/plugins/start/slimv/doc' +q</code></pre>
    <p>
      That is it!  Slimv is set up.  It's that straightforward.  The
      commands above show how to set up Slimv with just two shell
      commands.  You could also use a Vim plugin manager to install
      Slimv for you but I am not going to cover that here.
    </p>
  </li>
  <li>
    <p>
      This is an optional step.  Slimv supports starting Swank server
      automatically if you are running Vim in tmux, GNU Screen or a
      desktop environment.  To start tmux, enter this command:
    </p>
    <pre><code>tmux</code></pre>
    <p>
      If you use GNU screen or a desktop environment, you don't have
      to run tmux.
    </p>
    <p>
      If you do not use tmux, GNU Screen or a desktop environment,
      then you must start Swank server manually as explained in the
      next point.
    </p>
  </li>
  <li>
    <p>
      This step is necessary only if you are not using tmux, GNU
      Screen or a desktop environment.  The following command shows
      how to start Swank server manually:
    </p>
    <pre><code>sbcl --load ~/.vim/pack/plugins/start/slimv/slime/start-swank.lisp</code></pre>
    <p>
      If you are using tmux, GNU Screen or a desktop environment,
      Slimv can start Swank server automatically when needed and you
      don't need to perform this step.
    </p>
  </li>
  <li>
    <p>
      Create a new Lisp source code file, say, <code>foo.lisp</code>
      with this command:
    </p>
    <pre><code>vim foo.lisp</code></pre>
  </li>
  <li>
    <p>
      To connect to Swank server, enter the following command in
      normal mode:
    </p>
    <p>
      <kbd>,</kbd><kbd>c</kbd>
    </p>
    <p>
      If Vim is running within tmux, GNU Screen or desktop
      environment, Slimv would automatically launch Swank server and
      connect to it.
    </p>
    <p>
      After Slimv connects to Swank successfully, Vim window should
      split into two and the following prompt should appear in the new
      split window:
    </p>
    <pre><samp>CL-USER&gt;</samp></pre>
    <p>
      This is the integrated REPL.  It is now alive and ready for
      interactive programming.
    </p>
    <p>
      We assume here that Slimv is using the default Slimv leader
      key <kbd>,</kbd>.  If you have overridden the Vim leader key,
      then the Slimv leader key might be same as the Vim leader key.
      Enter the command <code>:echo g:slimv_leader</code> in Vim
      command-line mode to find the leader key being used by Slimv.
    </p>
  </li>
  <li>
    <p>
      Type some code into the buffer for the new file.  To do so,
      first type <kbd>i</kbd> to enter insert mode and type this code:
    </p>
    <pre><code>(format t "hello, world~%")</code></pre>
    <p>
      Type <kbd>esc</kbd> to return to normal mode.
    </p>
  </li>
  <li>
    <p>
      To evaluate the current expression under the cursor, enter the
      following command in normal mode:
    </p>
    <p>
      <kbd>,</kbd><kbd>e</kbd>
    </p>
    <p>
      Both the current expression and its result should appear in the
      REPL window.
    </p>
  </li>
  <li>
    <p>
      The REPL is interactive.  Type
      <kbd>ctrl</kbd>+<kbd>w</kbd><kbd>w</kbd> to switch to the REPL
      window.  Then type <kbd>i</kbd> to enter insert mode and type
      this code:
    </p>
    <pre><code>(+ 1 2)</code></pre>
    <p>
      Type <kbd>enter</kbd> to evaluate the expression just like you
      would do in a real REPL.  The result should then appear in the
      REPL.
    </p>
    <p>
      Type <kbd>esc</kbd> to return to normal mode again.  Use the
      normal mode command
      <kbd>ctrl</kbd>&nbsp;+&nbsp;<kbd>w</kbd>&nbsp;<kbd>w</kbd> to
      switch between the split windows.
    </p>
  </li>
  <li>
    <p>
      Now that you have got started with Slimv, here is a brief note
      on uninstallation, in case you ever need it.  If Slimv is
      installed as described in point 2 above, enter the following
      command to uninstall it:
    </p>
    <pre><code>rm -rf ~/.vim/pack/plugins/start/slimv</code></pre>
  </li>
</ol>
<p>
  In steps 7 and 9, you may have noticed that as soon as you type an
  opening parenthesis or double quotation mark, a matching closing one
  is automatically inserted.  That is done by the
  <a href="https://github.com/kovisoft/paredit">Paredit</a> plugin
  which is bundled along with Slimv.  Paredit ensures structured
  editing of Lisp s-expressions and keeps all matched characters
  (parentheses, brackets, braces, quotes) balanced.  It also provides
  many new keybindings to edit s-expressions conveniently.  We will
  look into Paredit in a little more detail in
  the <a href="#get-started-with-paredit"><em>Get Started with
  Paredit</em></a> subsection later.
</p>
<h3 id="get-started-with-vlime-and-sbcl">Get Started with Vlime and SBCL<a href="#get-started-with-vlime-and-sbcl"></a></h3>
<p>
  Here are the steps to set up Vlime and use it:
</p>
<ol>
  <li>
    <p>
      Install the tools required to set up a Common Lisp development
      environment with Vlime with this command:
    </p>
    <pre><code>sudo apt-get install vim sbcl git curl</code></pre>
    <p>
      Note that unlike Slimv, Vlime can work with the default Vim in
      Debian, i.e. <code>vim.basic</code>.  Vlime does not require Vim
      with Python interface.
    </p>
  </li>
  <li>
    <p>
      Install Quicklisp with these commands:
    </p>
<pre><code>curl -O https://beta.quicklisp.org/quicklisp.lisp
sbcl --load quicklisp.lisp --eval '(quicklisp-quickstart:install)' --eval '(exit)'
sbcl --load ~/quicklisp/setup.lisp --eval '(ql:add-to-init-file)' --eval '(exit)'</code></pre>
    <p>
      Type <kbd>enter</kbd> in the end, when prompted, to complete the
      installation.
    </p>
  </li>
  <li>
    <p>
      Install Vlime and Paredit with these commands:
    </p>
<pre><code>git clone https://github.com/l04m33/vlime.git ~/.vim/bundle/vlime
git clone https://github.com/kovisoft/paredit ~/.vim/pack/plugins/start/paredit
echo 'set runtimepath^=~/.vim/bundle/vlime/vim' &gt;&gt; ~/.vimrc
vim +'helptags ~/.vim/bundle/vlime/vim/doc' +'helptags ~/.vim/pack/plugins/start/paredit/doc' +q</code></pre>
    <p>
      Unlike Slimv, Vlime does not bundle
      <a href="https://github.com/kovisoft/paredit">Paredit</a> along
      with itself.  As explained in the previous section, it helps us
      with structured editing of Lisp s-expressions.
    </p>
    <p>
      I recommend that you install Paredit but in case you choose not
      to, ensure that loading of filetype plugins is enabled by
      entering the <code>:filetype</code> command in command-line
      mode.  The output should contain <code>plugin:ON</code>.  If it
      is off, add the command <code>filetype plugin on</code>
      to <code>~/.vimrc</code> to ensure that this is always on.
      Vlime won't work without this being enabled.  If you install
      Paredit, you don't have to bother about this because Paredit
      takes care of enabling this by default.
    </p>
  </li>
  <li>
    <p>
      Create a new Lisp source code file, say, <code>foo.lisp</code>
      with this command:
    </p>
    <pre><code>vim foo.lisp</code></pre>
  </li>
  <li>
    <p>
      To start Vlime server (a wrapper around Swank server) and
      connect to it automatically, enter the following command in
      normal mode:
    </p>
    <p>
      <kbd>\</kbd><kbd>r</kbd><kbd>r</kbd>
    </p>
    <p>
      We assume here that Vim <code>&lt;LocalLeader&gt;</code> is left
      to its default, i.e. backslash.  If it is mapped to some other
      key combination, then that must be used instead of backslash in
      the above command.
    </p>
    <p>
      The first time this command is run after installing Vlime, it
      installs Swank server using Quicklisp.  Therefore, it can take a
      while for Vlime server to start the first time this command is
      run.  On subsequent use of these commands, it would start faster
      because it would be already installed.
    </p>
    <p>
      The console output from Vlime server is displayed in a split
      window.  After Vlime successfully connects to Swank, the
      following message is displayed at the bottom:
    </p>
    <pre><samp>Vlime Connection 1 established.</samp></pre>
    <p>
      After the above message appears, it is okay to close the split
      window for Vlime server by entering this command in Vim
      command-line mode:
    </p>
    <pre><code>:q</code></pre>
    <p>
      Vlime server would continue to run in background.  The following
      command can be used in normal mode to view the console output of
      Vlime server anytime it is required:
    </p>
    <p>
      <kbd>\</kbd><kbd>r</kbd><kbd>v</kbd>
    </p>
  </li>
  <li>
    <p>
      Type some code into the buffer for the new file.  To do so,
      first type <kbd>i</kbd> to enter insert mode and type this code:
    </p>
    <pre><code>(format t "hello, world~%")</code></pre>
    <p>
      Type <kbd>esc</kbd> to return to normal mode.
    </p>
  <li>
    <p>
      To evaluate, the current expression under the cursor, enter the
      following command in normal mode:
    </p>
    <p>
      <kbd>\</kbd><kbd>s</kbd><kbd>s</kbd>
    </p>
    <p>
      Both the current expression and its result should appear in the
      REPL window.
    </p>
    <p>
      Unlike Slimv, the REPL window of Vlime is <em>not</em>
      interactive.  Its <code>nomodifiable</code> option is set, so we
      cannot type code directly into the REPL window.  This can be a
      bit of a problem if we want to type arbitrary expressions into
      the REPL and execute them.  To mitigate this shortcoming to some
      extent, Vlime provides an alternative way to evaluate the
      current expression known as the interaction mode.  This is
      explained in the next point.
    </p>
  </li>
  <li>
    <p>
      Enable interaction mode by entering this command in normal mode:
    </p>
    <p><kbd>\</kbd><kbd>i</kbd></p>
    <p>
      The same command disables interaction mode, i.e. this command
      toggles the state of interaction mode between on and off.  When
      interaction mode is on, evaluate an expression under the cursor
      by simply pressing <kbd>enter</kbd> in normal mode.
    </p>
  </li>
  <li>
    <p>
      Now that you have got started with Vlime, here is a brief note
      on uninstallation, in case you ever need it.  If Quicklisp and
      Vlime are installed as described in the points 2 and 3 above,
      run these commands to uninstall them:
    </p>
<pre><code>rm -rf ~/quicklisp ~/.vim/bundle/vlime ~/.vim/pack/plugins/start/paredit
sed -i.bkp '/runtimepath.*vlime/d' ~/.vimrc</code></pre>
    <p>
      Optionally, remove <code>~/.sblrc</code> or edit it to remove
      the code pertaining to loading
      <code>quicklisp/setup.lisp</code>.
  </li>
</ol>
<h3 id="get-started-with-paredit">Get Started with Paredit<a href="#get-started-with-paredit"></a></h3>
<p>
  You have already got started with Paredit when you wrote Lisp code
  while following one of the previous two subsections.  The moment you
  typed an opening parenthesis, Paredit inserted a closing one for you
  automatically.  Paredit keeps all matched characters such as
  parentheses, double quotes, etc. balanced when you edit code.  Here
  is a very brief exercise to quickly get started with some of the
  very basic features of Paredit:
</p>
<ol>
  <li>
    <p>
      Create a new Lisp source code file, say, <code>foo.lisp</code>
      with this command:
    </p>
    <pre><code>vim foo.lisp</code></pre>
  </li>
  <li>
    <p>
      Type <kbd>i</kbd> to enter insert mode and then type only this:
    </p>
    <pre><code>(defun square (x</code></pre>
    <p>
      At this point, Paredit should have inserted the two closing
      parentheses automatically.  The code should look like this:
    </p>
    <pre><code>(defun square (x<span class="cursor">)</span>)</code></pre>
    <p>
      The cursor should be situated just after the parameter
      <code>x</code>.  The block above shows where the cursor should
      be.
    </p>
  </li>
  <li>
    <p>
      While you are still in insert mode, type the first closing
      parenthesis.  Yes, type it even if the closing parenthesis is
      already present.  The cursor should now skip over the first
      closing parenthesis like this:
    </p>
    <pre><code>(defun square (x)<span class="cursor">)</span></code></pre>
    <p>
      Of course, there was no need to type the closing parenthesis
      because it was already present but typing it out to skip over it
      is more efficient than escaping to normal mode, then moving over
      it and then entering insert mode again.  This is, in fact, a
      very nifty feature of Paredit.  We can enter code with the same
      keystrokes as we would without Paredit.
    </p>
  </li>
  <li>
    <p>
      You should still be in insert mode.  Type <kbd>enter</kbd> to
      create a new line below.  Now one of two things is going to
      happen.  If electric return is disabled, then a newline is
      inserted as expected like this:
    </p>
<pre><code>(defun square (x))
  <span class="cursor">)</span></code></pre>
    <p>
      If electric return is enabled, two newlines are inserted to
      create an empty line in between:
    </p>
<pre><code>(defun square (x)
  <span class="cursor"> </span>
  )</code></pre>
    <p>
      In both cases, indentation of two spaces is inserted
      automatically.  The new empty line inserted by electric return
      allows linewise editing of the code to be entered in this empty
      line.
    </p>
    <p>
      The electric return feature is enabled by default in both
      Paredit and Slimv.  It works by Paredit remapping the "enter"
      key (<code>&lt;CR&gt;</code>) in insert mode to a function that
      inserts electric return.  Slimv needs to remap the "enter" key
      to present the argument list of the current function but it
      takes care of performing an electric return before showing the
      argument list.  Vlime, however, forgets to perform electric
      return before showing the argument list, so this feature does
      not work in Vlime.
    </p>
    <p>
      For now, we will continue with the assumption that electric
      return is enabled and working fine.  If it is disabled or if it
      is not working for you, ignore the steps that discuss electric
      return.
    </p>
  </li>
  <li>
    <p>
      Now, type only this:
    </p>
    <pre><code>(* x x</code></pre>
    <p>
      Again, Paredit would have inserted the closing parenthesis
      automatically.  The code should look like this now:
    </p>
<pre><code>(defun square (x)
  (* x x<span class="cursor">)</span>
  )</code></pre>
  </li>
  <li>
    <p>
      Now, type one more closing parenthesis to advance past the
      automatically inserted closing parenthesis like this:
    </p>
<pre><code>(defun square (x)
  (* x x)<span class="cursor"> </span>
  )</code></pre>
  </li>
  <li>
    <p>
      Then type another closing parenthesis.  Paredit would now pick
      the lone closing parenthesis that is present in its own line and
      move it at the end of the current line like this:
    </p>
<pre><code>(defun square (x)
  (* x x))<span class="cursor"> </span></code></pre>
    <p>
      This behaviour of consuming the extra newline inserted by an
      electric return on typing a closing parenthesis helps the code
      to conform to the popular Lisp coding convention of putting all
      the consecutive closing parentheses next to each other in the
      same line.  In other words, typing closing parentheses
      re-gathers electric returns when applicable.
    </p>
  </li>
  <li>
    <p>
      Let us see what happens if we try to delete the opening
      parenthesis around the product function (the <code>*</code>
      function).  Type <kbd>esc</kbd> to return to normal mode.  Then
      enter <kbd>h</kbd> in normal mode to move the cursor one place
      left so that the cursor is placed on the parenthesis just after
      the last <code>x</code> in the code like this:
    </p>
<pre><code>(defun square (x)
  (* x x<span class="cursor">)</span>)</code></pre>
    <p>
      Type <kbd>x</kbd> to delete the closing parenthesis the cursor
      is on.  Nothing gets deleted!  Instead the cursor just skips
      over the parenthesis like this:
    </p>
<pre><code>(defun square (x)
  (* x x)<span class="cursor">)</span></code></pre>
    <p>
      Paredit refuses to delete the closing parenthesis because it
      encloses a non-empty list.  It would have deleted the closing
      parenthesis along with the opening one if the list were empty.
      This is Paredit trying to ensure that the s-expressions remain
      valid while editing.
    </p>
    <p>
      Note that in this step, <kbd>h</kbd> is a regular Vim motion
      command.  In Vim, by default, <kbd>x</kbd> deletes the character
      under the cursor, but when Paredit is enabled, it remaps this
      command to behave the way it did in this step to ensure that the
      parentheses remain balanced.
    </p>
  </li>
  <li>
    <p>
      Let us now try to delete the current line.  Type
      <kbd>d</kbd><kbd>d</kbd> to do so.  The result looks like this:
    </p>
<pre><code>(defun square (x)
  <span class="cursor">)</span></code></pre>
    <p>
      Note how the closing parenthesis has been left intact to keep
      the parentheses balanced.  Again, Paredit has remapped the
      <kbd>d</kbd><kbd>d</kbd> command to produce this behaviour.
    </p>
  </li>
  <li>
    <p>
      Now type <kbd>d</kbd><kbd>a</kbd><kbd>(</kbd> to delete the
      entire <code>defun</code> expression.  The buffer should look
      empty now.
    </p>
  </li>
  <li>
    <p>
      Type <kbd>i</kbd> to enter insert mode and type out the
      following code:
    </p>
    <pre><code>(list (* 10 20) (+ 30 40))<span class="cursor"> </span></code></pre>
  </li>
  <li>
    <p>
      Type <kbd>esc</kbd> to return to normal mode.
      Type <kbd>h</kbd><kbd>(</kbd><kbd>h</kbd><kbd>h</kbd> to place
      the cursor on the closing parenthesis of the first expression.
    </p>
    <pre><code>(list (* 10 20<span class="cursor">)</span> (+ 30 40))</code></pre>
    <p>
      Now type <kbd>,</kbd><kbd>&gt;</kbd>.  The closing parenthesis
      of the first expression moves right to <em>slurp</em> the next
      expression.  The buffer looks like this:
    </p>
    <pre><code>(list (* 10 20 (+ 30 40)<span class="cursor">)</span>)</code></pre>
    <p>
      We assume here that Paredit is using the default Paredit leader
      key <kbd>,</kbd>.  If you have overridden the Vim leader key,
      then the Paredit leader key might be same as the Vim leader key.
      Enter the command <code>:echo g:paredit_leader</code> in Vim
      command-line mode to find the leader key being used by Paredit.
    </p>
  </li>
  <li>
    <p>
      Now type <kbd>,</kbd><kbd>&lt;</kbd>.  The closing parenthesis
      of the outer expression moves left to <em>barf</em> the inner
      expression out.  The buffer looks like this again:
    </p>
    <pre><code>(list (* 10 20<span class="cursor">)</span> (+ 30 40))</code></pre>
    <p>
      While the cursor is on a parenthesis, the normal mode
      commands <code>,&lt;</code> or <code>,&gt;</code> can be used in
      this manner to move the parenthesis left or right respectively,
      thereby slurping or barfing expressions.
    </p>
  </li>
</ol>
<p>
  That was a very brief overview of what Paredit can do.  There is a
  lot more to Paredit than what is described above.  Paredit has a
  rich set of keybindings to make editing s-expressions very
  convenient.  Enter <code>:help paredit-keys</code> in command-line
  mode to see the list of the keybindings.
</p>
<p>
  I think it is a good idea to read the entire Paredit documentation.
  Enter <code>:help paredit</code> to do so.  It is about 500 lines
  long and takes about 30 to 40 minutes to read.  The time spent
  reading this documentation is worth it because it makes editing Lisp
  code very pleasant and productive.
</p>
<h2 id="use-debugger-and-inspector">Use Debugger and Inspector<a href="#use-debugger-and-inspector"></a></h2>
<p>
  After getting started with Slimv or Vlime, the very next thing you
  might want to know is how to work with the debugger.  The debugger
  window comes up whenever an error or an unhandled condition occurs.
  It might look quite scary to a beginner, so it is a good idea to
  become comfortable with it as soon as possible.  Fortunately, both
  Slimv and Vlime provide excellent key-bindings to inspect the error
  or dismiss it to return to the source code buffer quickly and
  easily.
</p>
<h3 id="use-debugger-and-inspector-with-slimv">Use Debugger and Inspector with Slimv<a href="#use-debugger-and-inspector-with-slimv"></a></h3>
<p>
  The following steps trigger an error and then show how to work with
  the debugger in Slimv:
</p>
<ol>
  <li>
    <p>
      Create a file with Vim, say <code>foo.lisp</code> and enter the
      following code into it:
    </p>
<pre><code>(defun square (x)
  (* x x))

(square "foo")</code></pre>
  </li>
  <li>
    <p>
      Enter <kbd>,</kbd><kbd>b</kbd> to evaluate the buffer.
    </p>
  </li>
  <li>
    <p>
      As soon as the defective form <code>(square "foo")</code> gets
      evaluated, an error occurs.  The error, possible restarts and
      the backtrace is displayed in a new split window for SLDB.  SLDB
      stands for Slime Debugger.  Here is an example of what may
      appear in the SLDB window:
    </p>
<pre><samp>The value
  "foo"
is not of type
  NUMBER
when binding SB-KERNEL::X
   [Condition of type TYPE-ERROR]

Restarts:
  0: [RETRY] Retry SLIME REPL evaluation request.
  1: [*ABORT] Return to SLIME's top level.
  2: [ABORT] abort thread (#&lt;THREAD "repl-thread" RUNNING {1003274E23}&gt;)

Backtrace:
  0: (SB-KERNEL:TWO-ARG-* "foo" "foo") [external]
  1: (SQUARE "foo")
  2: (SB-DEBUG::TRACE-CALL #&lt;SB-DEBUG::TRACE-INFO SQUARE&gt; #&lt;FUNCTION SQUARE&gt; "foo")
  3: (SB-INT:SIMPLE-EVAL-IN-LEXENV (SQUARE "foo") #&lt;NULL-LEXENV&gt;)
  4: (EVAL (SQUARE "foo"))
  5: (SWANK::EVAL-REGION "(defun square (x) ..)
  6: ((LAMBDA NIL :IN SWANK-REPL::REPL-EVAL))
  ...</samp></pre>
    <p>
      The ellipsis in the end is added by me to denote that the actual
      output has been truncated in this article for the sake of
      brevity.
    </p>
  </li>
  <li>
    <p>
      In the SLDB window, move the cursor to the second line of
      backtrace, i.e. on the following line:
    </p>
    <pre><samp>  1: (SQUARE "foo")</samp></pre>
    <p>
      Then type <kbd>enter</kbd>.  This line should now unfold to show
      the following details:
    </p>
<pre><samp>  1: (SQUARE "foo")
      in "(SB-INT:NAMED-LAMBDA SQUARE-----------------------------------
    Locals:
      X = "foo"</samp></pre>
  </li>
  <li>
    <p>
      Move the cursor to the line that begins with <code>in</code>,
      i.e. on this line:
    </p>
    <pre><samp>      in "(SB-INT:NAMED-LAMBDA SQUARE-----------------------------------</samp></pre>
    <p>
      Then type <kbd>enter</kbd>.  Some information about its source
      code should appear like this:
    </p>
<pre><samp>  1: (SQUARE "foo")
      in "(SB-INT:NAMED-LAMBDA SQUARE
    (X)
  (BLOCK SQUARE (#:***HERE*** (* X X))))" byte 1
    Locals:
      X = "foo"</samp></pre>
  </li>
  <li>
    <p>
      Move the cursor to the following line:
    </p>
    <pre><samp>      X = "foo"</samp></pre>
    <p>
      Then type <kbd>,</kbd><kbd>i</kbd> to inspect this variable.  A
      prompt would appear to confirm the variable name.  Type
      <kbd>enter</kbd> to confirm.  An inspector window should now
      appear with more details about this variable.  This window should
      look like this:
    </p>
<pre><samp>Inspecting #&lt;(SIMPLE-ARRAY CHARACTER (3)) {100478AFAF}&gt;
--------------------
Press &lt;F1&gt; for Help

Dimensions: (3)
Element type: CHARACTER
Total size: 3
Adjustable: NIL
Fill pointer: NIL
Contents:
0: #\f
1: #\o
2: #\o


[&lt;&lt;] Exit Inspector</samp></pre>
  </li>
  <li>
    <p>
      Type <kbd>enter</kbd> to inspect any object under the cursor and
      drill down further.
    </p>
  </li>
  <li>
    <p>
      Type <kbd>backspace</kbd> in normal mode to return to the
      previous object.
    </p>
  </li>
  <li>
    <p>
      Enter <kbd>,</kbd><kbd>q</kbd> in normal mode to quit the
      inspector.
    </p>
  </li>
  <li>
    <p>
      Finally, move the cursor to the following line in the SLDB
      window:
    </p>
    <pre><samp>  1: [*ABORT] Return to SLIME's top level.</samp></pre>
    <p>
      Then type <kbd>enter</kbd> to execute this restart.
      Alternatively, enter <kbd>,</kbd><kbd>a</kbd> in normal mode to
      select the abort restart and quit to the previous level or
      <kbd>,</kbd><kbd>q</kbd> to quit to top level.
    </p>
  </li>
</ol>
<p>
  Most of the times when an error occurs, I quickly take a look at the
  stack trace to realise that I have made a silly mistake and enter
  the <kbd>,</kbd><kbd>q</kbd> command to abort and quit to top level.
  This can be quite convenient because it allows returning from
  debugging to coding very quickly with only two keystrokes.
</p>
<h3 id="use-debugger-and-inspector-with-vlime">Use Debugger and Inspector with Vlime<a href="#use-debugger-and-inspector-with-vlime"></a></h3>
<p>
  The following steps trigger an error and then show how to work with
  the debugger in Vlime:
</p>
<ol>
  <li>
    <p>
      Create a file with Vim, say <code>foo.lisp</code> and enter the
      following code into it:
    </p>
<pre><code>(defun square (x)
  (* x x))

(square "foo")</code></pre>
  </li>
  <li>
    <p>
      Save the file, connect to Vlime server and enter
      <kbd>\</kbd><kbd>o</kbd><kbd>f</kbd> in normal mode to compile
      the entire buffer.
    </p>
  </li>
  <li>
    <p>
      As soon as the defective form <code>(square "foo")</code> gets
      evaluated, an error occurs.  The error, possible restarts and
      the backtrace is displayed in a new split window for SLDB.  SLDB
      stands for Slime Debugger.  Here is an example of what may
      appear in the SLDB window:
    </p>
<pre><samp>Thread: 1; Level: 1

The value
  "foo"
is not of type
  NUMBER
when binding SB-KERNEL::X
   [Condition of type TYPE-ERROR]

Restarts:
  0. *ABORT - Return to SLIME's top level.
  1.  ABORT - abort thread (#&lt;THREAD "worker" RUNNING {10045D6F83}&gt;)

Frames:
  0.  (SB-KERNEL:TWO-ARG-* "foo" "foo") [external]
  1.  (SQUARE "foo")
  2.  (SB-FASL::LOAD-FASL-GROUP #S(SB-FASL::FASL-INPUT :STREAM #&lt;SB-SYS:FD-STREAM for "file /home/susam/foo.fasl" {10045E76A3}&gt; :TABLE #(41 #&lt;PACKAGE "SB-IMPL"&gt; SB-IMPL::%DEFUN #&lt;PACKAGE "COMMON-LISP-USER"&gt;..
  3.  (SB-FASL::LOAD-AS-FASL #&lt;SB-SYS:FD-STREAM for "file /home/susam/foo.fasl" {10045E76A3}&gt; NIL NIL)
  4.  ((FLET SB-FASL::THUNK :IN LOAD))
  5.  (SB-FASL::CALL-WITH-LOAD-BINDINGS #&lt;CLOSURE (FLET SB-FASL::THUNK :IN LOAD) {7F7B9B0B60BB}&gt; #&lt;SB-SYS:FD-STREAM for "file /home/susam/foo.fasl" {10045E76A3}&gt;)
  ...</samp></pre>
    <p>
      The ellipsis in the end is added by me to denote that the actual
      output has been truncated in this article for the sake of
      brevity.
    </p>
  </li>
  <li>
    <p>
      In the SLDB window, move the cursor to the second line of
      backtrace, i.e. on the following line:
    </p>
    <pre><samp>  1.  (SQUARE "foo")</samp></pre>
    <p>
      Then type <kbd>d</kbd>.  A new split window should appear with
      the following details about this frame:
    </p>
<pre><samp>Frame: 1 (Restartable)

Locals:
  X: "foo"

Location:
  File: /home/susam/foo.lisp
  Position: 20
  Snippet:
    (* x x))

    (square "foo")</samp></pre>
  </li>
  <li>
	<p>
      While the cursor is on the same line as mentioned in the
      previous point, type <kbd>i</kbd> to bring up the inspector
      window for this frame.
	</p>
  </li>
  <li>
    <p>
      In the inspector window, type <kbd>i</kbd> to enter insert mode.
      Enter the following variable name in insert mode:
    </p>
    <pre><code>x</code></pre>
    <p>
      Then type <kbd>esc</kbd> to return to normal mode.  Then type
      <kbd>enter</kbd>.  The following details about the variable
      <code>x</code> should now appear in the inspector window:
    </p>
<pre><samp>#&lt;(SIMPLE-ARRAY CHARACTER (3)) {1004617ABF}&gt;
============================================

Dimensions: (3)
Element type: CHARACTER
Total size: 3
Adjustable: NIL
Fill pointer: NIL
Contents:
0: #\f
1: #\o
2: #\o</samp></pre>
  </li>
  <li>
    <p>
      Type <kbd>enter</kbd> to inspect any object under the cursor and
      drill down further.
    </p>
  </li>
  <li>
    <p>
      Type <kbd>p</kbd> to return to the previous object.
    </p>
  </li>
  <li>
    <p>
      Enter the regular Vim command <code>:q</code> in command-line
      mode to quit the inspector window.
    </p>
  </li>
  <li>
    <p>
      Finally, move the cursor to the following line in the SLDB
      window:
    </p>
    <pre><samp>  1: [*ABORT] Return to SLIME's top level.</samp></pre>
    <p>
      Then type <kbd>enter</kbd> to execute this restart.
      Alternatively, we can enter <kbd>a</kbd> in normal mode to
      select the abort restart to return to the previous level.  At
      this time, there is no command to return to SLIME's top level.
    </p>
  </li>
</ol>
<h2 id="trace-function">Trace Function<a href="#trace-function"></a></h2>
<h3 id="trace-function-in-slimv">Trace Function in Slimv<a href="#trace-function-in-slimv"></a></h3>
<p>
  The following steps show how to get started with tracing functions
  in Slimv:
</p>
<ol>
  <li>
    <p>
      Create a file with Vim, say <code>foo.lisp</code> and enter the
      following code into it:
    </p>
<pre><code>(defun square (x)
  (* x x))

(square (square 2))</code></pre>
  </li>
  <li>
    <p>
      Enter <kbd>,</kbd><kbd>b</kbd> in normal mode to evaluate the
      entire buffer.
    </p>
  </li>
  <li>
    <p>
      Place the cursor on the function name, i.e. on
      <code>square</code> and enter <kbd>,</kbd><kbd>t</kbd> in normal
      mode to toggle tracing for this function.  A prompt appears to
      confirm the function name.  Type <kbd>enter</kbd> to confirm.
    </p>
  </li>
  <li>
    <p>
      While the cursor is on the last expression, enter
      <kbd>,</kbd><kbd>d</kbd> in normal mode to evaluate the top-level
      form.  The following output appears in the REPL buffer.
    </p>
<pre><code>(square (square 2))
  0: (SQUARE 2)
  0: SQUARE returned 4
  0: (SQUARE 4)
  0: SQUARE returned 16
16</code></pre>
    <p>
      This output contains information about each call to the traced
      function, arguments passed to it and the return values.
    </p>
  </li>
</ol>
<h3 id="trace-function-in-vlime">Trace Function in Vlime<a href="#trace-function-in-vlime"></a></h3>
<p>
  It takes a little more work to start tracing functions in Vlime.
  The following steps show how to do it:
</p>
<ol>
  <li>
    <p>
      Add the following statement to <code>~/.vimrc</code>:
    </p>
<pre><code>let g:vlime_contribs = ['SWANK-ASDF', 'SWANK-PACKAGE-FU',
                      \ 'SWANK-PRESENTATIONS', 'SWANK-FANCY-INSPECTOR',
                      \ 'SWANK-C-P-C', 'SWANK-ARGLISTS', 'SWANK-REPL',
                      \ 'SWANK-FUZZY', 'SWANK-TRACE-DIALOG']</code></pre>
    <p>
      The above variable defines the list of Swank contrib modules to
      load while initialising a Vlime connection.  All modules
      mentioned above except the last one are loaded by default.  The
      <code>SWANK-TRACE-DIALOG</code> module is not loaded by default
      but this module is necessary for tracing functions, so in order
      to load it, we define this variable to load this module in
      addition to all the other modules that are loaded by default.
    </p>
  </li>
  <li>
    <p>
      Create a file with Vim, say <code>foo.lisp</code> and enter the
      following code into it:
    </p>
<pre><code>(defun square (x)
  (* x x))

(square (square 2))</code></pre>
  </li>
  <li>
    <p>
      Save the file, connect to Vlime server and enter
      <kbd>\</kbd><kbd>o</kbd><kbd>f</kbd> in normal mode to compile
      the entire buffer.
    </p>
  </li>
  <li>
    <p>
      Enter <kbd>\</kbd><kbd>T</kbd><kbd>D</kbd> in normal mode to
      show the trace dialog in a split window.
    </p>
  </li>
  <li>
    <p>
      Enter <kbd>ctrl</kbd>&nbsp;+&nbsp;<kbd>w</kbd>&nbsp;<kbd>w</kbd>
      in normal mode to go back to the source code window.
    </p>
  </li>
  <li>
    <p>
      Place the cursor on the function name, i.e. on
      <code>square</code> and enter
      <kbd>\</kbd><kbd>T</kbd><kbd>T</kbd> in normal mode to toggle
      tracing for this function.
    </p>
  </li>
  <li>
    <p>
      While the cursor is on the last expression, enter
      <kbd>\</kbd><kbd>s</kbd><kbd>t</kbd> in normal mode to evaluate
      the top-level form.
    </p>
  </li>
  <li>
    <p>
      Enter <kbd>ctrl</kbd>&nbsp;+&nbsp;<kbd>w</kbd>&nbsp;<kbd>w</kbd>
      in normal mode twice to go to the trace window.
    </p>
  </li>
  <li>
    <p>
      Under <code>Trace Entries</code>, place the cursor on
      <code>[refresh]</code> and type <kbd>enter</kbd>.
    </p>
  </li>
  <li>
    <p>
      Then place the cursor on <code>[fetch next batch]</code> and
      type <kbd>enter</kbd>.  Two results should appear for the two
      <code>square</code> calls that were made due to step 7.  The trace
      information would be folded under each call.
    </p>
  </li>
  <li>
    <p>
      Move the cursor to each fold line and enter
      <kbd>z</kbd><kbd>o</kbd> in normal mode to open the fold.  After
      opening both the folds, the following result should be visible:
    </p>
    <pre><code>0 - COMMON-LISP-USER::SQUARE
    &gt; 2
    &lt; 4
1 - COMMON-LISP-USER::SQUARE
    &gt; 4
    &lt; 16
    16</code></pre>
    <p>
      The lines starting with <code>&gt;</code> show the arguments and
      the ones starting with <code>&lt;</code> show the return values.
    </p>
  </li>
</ol>
<h2 id="nifty-features">Nifty Features<a href="#nifty-features"></a></h2>
<p>
  In this section, we will go over some of the nifty features that
  these plugins offer.  Not all features will be covered here.  I have
  chosen only a few features for the discussion here that I felt would
  be useful to beginners and at the same time also demonstrate the
  versatility of these plugins.
</p>
<h3 id="evaluate-top-level-form">Evaluate Top-Level Form<a href="#evaluate-top-level-form"></a></h3>
<p>
  In the previous sections, we saw how to evaluate the current
  expression under the cursor.  In this section, we will see how to
  evaluate the top-level expression around the current cursor
  position.  Let us do a small exercise to see this:
</p>
<ol>
  <li>
    <p>
      Create a file with Vim, say <code>foo.lisp</code> and enter the
      following code into it:
    </p>
    <pre><code>(+ 1 (* 2 (/ 6 <span class="cursor">2</span>)))</code></pre>
  </li>
  <li>
    <p>
      With Slimv or Vlime connected to Swank, let us do a quick recap
      of how to evaluate the current expression.
    </p>
    <p>
      With Slimv, enter the normal mode
      command <kbd>,</kbd><kbd>e</kbd> to evaluate the current
      expression.
    </p>
    <p>
      With Vlime, enter the normal mode command
      <kbd>\</kbd><kbd>s</kbd><kbd>s</kbd> to evaluate the current
      expression.
    </p>
    <p>
      The current expression, i.e. <code>(/ 6 2)</code> should get
      evaluated and the result <code>3</code> should appear in the
      REPL buffer.
    </p>
  </li>
  <li>
    <p>
      Let us now see how to evaluate the top-level expression.
    </p>
    <p>
      With Slimv, enter the normal mode
      command <kbd>,</kbd><kbd>d</kbd> to evaluate the top-level
      expression.
    </p>
    <p>
      With Vlime, enter the normal mode command
      <kbd>\</kbd><kbd>s</kbd><kbd>t</kbd> to evaluate the top-level
      expression.
    </p>
    <p>
      The top-level expression should get evaluated and the result
      <code>7</code> should appear in the REPL buffer.
    </p>
  </li>
</ol>
<h3 id="rainbow-parentheses">Rainbow Parentheses<a href="#rainbow-parentheses"></a></h3>
<p>
  Rainbow parentheses make it easy to see matching parentheses by
  colouring different levels of parentheses with different colours.
  Matching parentheses have the same colour.  To enable this feature
  in Slimv, add this command to <code>~/.vimrc</code>:
</p>
<pre><code>let g:lisp_rainbow=1</code></pre>
<p>
  This feature is not available in Vlime.  But there are several Vim
  plugins that support rainbow parentheses.  Here are the steps to
  install one such plugin that is quite popular:
</p>
<pre><code>git clone https://github.com/junegunn/rainbow_parentheses.vim.git ~/.vim/pack/plugins/start/rainbow_parentheses
echo 'autocmd FileType lisp,scheme,clojure RainbowParentheses' &gt;&gt; ~/.vimrc</code></pre>
<p>
  In case you ever want to uninstall it, enter these commands:
</p>
<pre><code>rm -rf ~/.vim/pack/plugins/start/rainbow_parentheses
sed -i.bkp '/autocmd.*RainbowParentheses/d' ~/.vimrc</code></pre>
<h3 id="argument-list">Argument List<a href="#argument-list"></a></h3>
<p>
  You must have seen this feature already while trying out the
  sections earlier.  While editing a Lisp source file, after typing a
  function name, as soon as a space is typed or the enter key is
  typed, the argument list for the function appears to serve as a
  reference.  In Slimv, the argument list appears in the status line
  at the bottom.  In Vlime, the argument list appears in a split
  window at the top.
</p>
<h3 id="omni-completion">Omni-Completion<a href="#omni-completion"></a></h3>
<p>
  Type a function name partially, e.g. <code>form</code> and type
  <kbd>tab</kbd> while still in insert mode.  The omni-completion menu
  should appear with the list of completions if there are multiple
  choices.  Type <kbd>ctrl</kbd>+<kbd>n</kbd> to select the next choice
  and <kbd>ctrl</kbd>+<kbd>p</kbd> to select the previous choice.
  Selecting a choice also immediately inserts that choice in the
  buffer.  This works in both Slimv and Vlime.  In Slimv, we can also
  type <kbd>tab</kbd> to select the next choice.
</p>
<p>
  By default, omni-completion is fuzzy.  For example,
  type <code>wl</code> and type <kbd>tab</kbd> and omni-complete
  should insert <code>write-line</code> automatically as well as show
  other matching choices.
</p>
<h3 id="describe-symbol">Describe Symbol<a href="#describe-symbol"></a></h3>
<p>
  With Slimv, enter the normal mode command <kbd>,</kbd><kbd>s</kbd>
  to describe the symbol under the cursor.  This brings up the
  documentation of the symbol in the Vim message area.  This feature
  works while editing Common Lisp and Clojure source files but not
  while editing Scheme source file.  This feature is not supported for
  Scheme at this time.  See
  the <a href="#other-lisp-dialects"><em>Other Lisp Dialects</em></a>
  section for details on how to set up Slimv with Clojure and MIT/GNU
  Scheme.
</p>
<p>
  With Vlime, enter <kbd>\</kbd><kbd>d</kbd><kbd>a</kbd> in normal
  mode to describe the symbol under the cursor.  This brings up the
  documentation of the symbol in a split window.
</p>
<h3 id="expand-macro">Expand Macro<a href="#expand-macro"></a></h3>
<p>
  Here is an excercise that shows how to expand macros interactively
  while editing a Lisp source file:
</p>
<ol>
  <li>
    <p>
      Create a file with Vim, say <code>foo.lisp</code> and enter the
      following code into it:
    </p>
<pre><code>(defmacro calc (a op b)
  (list op a b))

(defmacro square (x)
  (list 'calc x '* x))

(square 2)</code></pre>
  </li>
  <li>
    <p>
      With Slimv, enter <kbd>,</kbd><kbd>b</kbd> in normal mode to
      evaluate the entire buffer.
    </p>
    <p>
      With Vlime, save the file, connect to Vlime server and type
      <kbd>\</kbd><kbd>o</kbd><kbd>f</kbd> in normal mode to compile the
      entire buffer.
    </p>
  </li>
  <li>
    <p>
      With Slimv, while the cursor is on the last expression, enter
      <kbd>,</kbd><kbd>1</kbd> in normal mode to expand the macro form
      once.
    </p>
    <p>
      With Vlime, enter <kbd>\</kbd><kbd>m</kbd><kbd>1</kbd> in normal
      mode to do the same thing.
    </p>
    <p>
      The following expansion should appear as the result:
    </p>
    <pre><code>(CALC 2 * 2)</code></pre>
    <p>
      Slimv displays the expansion in the REPL buffer whereas Vlime
      displays it in a new split window.
    </p>
  </li>
  <li>
    <p>
      With Slimv, enter <kbd>,</kbd><kbd>m</kbd> in normal mode to
      recursively expand the current expression until it is no longer
      a macro.
    </p>
    <p>
      With Vlime, enter <kbd>\</kbd><kbd>m</kbd><kbd>a</kbd> in normal
      mode to do the same thing.
    </p>
    <p>
      The following expansion should appear as the result:
    </p>
    <pre><code>(* 2 2)</code></pre>
  </li>
</ol>
<h3 id="cross-reference">Cross Reference<a href="#cross-reference"></a></h3>
<p>
  Here is an exercise that shows how to use the cross-reference
  commands in Slimv and Vlime:
</p>
<ol>
  <li>
    <p>
      Create a file with Vim, say <code>foo.lisp</code> and enter the
      following code into it:
    </p>
<pre><code>(defun square (x)
  (* x x))

(defun square-of-sum (x y)
  (square (+ x y)))

(defun sum-of-squares (x y)
  (+ (square x) (square y)))

(square-of-sum 2 3)
(sum-of-squares 2 3)</code></pre>
  </li>
  <li>
    <p>
      With Slimv, enter <kbd>,</kbd><kbd>b</kbd> in normal mode to
      evaluate the entire buffer.
    </p>
    <p>
      With Vlime, save the file, connect to Vlime server and type
      <kbd>\</kbd><kbd>o</kbd><kbd>f</kbd> in normal mode to compile the
      entire buffer.
    </p>
  </li>
  <li>
    <p>
      With Slimv, place the cursor on any occurrence of the symbol
      <code>square</code> and enter
      <kbd>,</kbd><kbd>x</kbd><kbd>l</kbd> in normal mode.  A prompt
      would appear to confirm the symbol name.  Type <kbd>enter</kbd>
      to confirm.  The list of all callers should now appear in the
      REPL buffer.
    </p>
    <p>
      With Vlime, place the cursor on any occurrence of the symbol
      <code>square</code> and enter <kbd>\</kbd><kbd>x</kbd><kbd>c</kbd>
      in normal mode to list all callers of the function.  The output
      appears in a split window containing the cross reference (xref)
      buffer.  Type <kbd>enter</kbd> on any item in the xref buffer and
      Vlime will take you directly to the referenced location.
    </p>
  </li>
</ol>
<h2 id="other-common-lisp-implementations">Other Common Lisp Implementations<a href="#other-common-lisp-implementations"></a></h2>
<p>
  The previous sections used SBCL as the implementation of Common
  Lisp.  How well do Slimv and Vlime work with other Common Lisp
  implementations?
</p>
<p>
  I have found that both plugins are pretty well tested with SBCL.
  However, they may not be so well tested with other implementations.
  Due to the lack of sufficient testing with Common Lisp
  implementations other than SBCL, certain errors may occur while
  using other implementations.  Sometimes it is possible to work
  around these errors and sometimes it isn't.  We will see an example
  of this in an upcoming section when we try to start Swank server
  automatically using Vlime and CLISP.
</p>
<p>
  For this section, I choose CLISP and Embeddable Common-Lisp (ECL) as
  two other implementations of Common Lisp that will be used with
  Slimv and Vlime.  After following the upcoming subsections, you
  should get the hang of how to make Slimv or Vlime work with other
  implementations of Common Lisp.
</p>
<h3 id="use-slimv-with-clisp">Use Slimv with CLISP<a href="#use-slimv-with-clisp"></a></h3>
<p>
  If you have read and tried the steps in the
  <a href="#get-started-with-slimv-and-sbcl"><em>Get Started with
  Slimv and SBCL</em></a> section, it is going to be quite easy to use
  Slimv with CLISP.  The steps are similar with a few minor
  modifications.  They are explained below:
</p>
<ol>
  <li>
    <p>
      Uninstall SBCL and install CLISP with these commands:
    </p>
    <pre><code>sudo apt-get remove sbcl
sudo apt-get install clisp</code></pre>
  </li>
  <li>
    <p>
      To start Swank server manually, enter this command:
    </p>
    <pre><code>clisp ~/.vim/pack/plugins/start/slimv/slime/start-swank.lisp</code></pre>
    <p>
      Then edit a Lisp source file and enter the normal command
      <kbd>,</kbd><kbd>c</kbd> to connect to it and bring up the REPL
      window.
    </p>
  </li>
  <li>
    <p>
      To start Swank automatically from Slimv, there is nothing more
      to be done.  Just edit a Lisp source file and enter the normal
      mode command <kbd>,</kbd><kbd>c</kbd>.  While running in GNU
      Screen, tmux or a desktop environment, Slimv can automatically
      detect CLISP and start Swank server with it.
    </p>
  </li>
</ol>
<p>
  In general, to start Swank server manually with another Common Lisp
  implementation, we need to figure out how to load
  <code>start-swank.lisp</code> with it.
</p>
<h3 id="use-slimv-with-ecl">Use Slimv with ECL<a href="#use-slimv-with-ecl"></a></h3>
<p>
  The steps to use Slimv with Embeddable Common-Lisp (ECL) are very
  similar too.  Once again, only if we need to start Swank server
  manually, we need to figure out the command to do so.  Otherwise,
  there is no other difference.  Here are the steps:
</p>
<ol>
  <li>
    <p>
      Ensure that SBCL and CLISP are uninstalled and ECL is installed.
    </p>
    <pre><code>sudo apt-get remove sbcl clisp
sudo apt-get install ecl</code></pre>
  </li>
  <li>
    <p>
      To start Swank server manually, enter this command:
    </p>
    <pre><code>ecl --load ~/.vim/pack/plugins/start/slimv/slime/start-swank.lisp</code></pre>
    <p>
      Then edit a Lisp source file and enter the normal command
      <kbd>,</kbd><kbd>c</kbd> to connect to it and bring up the REPL
      window.
    </p>
  </li>
  <li>
    <p>
      To start Swank automatically from Slimv, there is nothing more
      to be done.  Just edit a Lisp source file and enter the normal
      mode command <kbd>,</kbd><kbd>c</kbd>.  While running in GNU
      Screen, tmux or a desktop environment, Slimv can automatically
      detect CLISP and start Swank server with it.
    </p>
    <p>
      There is a possible timeout issue to be aware of though.  ECL
      can take a minute or two to compile the code it loads the first
      time Swank server is started.  However, Slimv has a default
      timeout period of 20 seconds, so Slimv may fail with the
      following error message:
    </p>
    <pre><samp>SWANK server is not running.  Press ENTER to continue.</samp></pre>
    <p>
      If this happens, just wait for ECL to complete compiling Swank
      server.  Once it starts Swank server, enter the normal mode
      command <kbd>,</kbd><kbd>c</kbd> again and it should connect
      immediately.
    </p>
  </li>
</ol>
<h3 id="use-vlime-with-clisp">Use Vlime with CLISP<a href="#use-vlime-with-clisp"></a></h3>
<p>
  This subsection assumes that you have already read and tried the
  <a href="#get-started-with-vlime-and-sbcl"><em>Get Started with
  Vlime and SBCL</em></a> section, so you are familiar with Vlime
  basics.  Now we will see what more it takes to use Vlime with CLISP
  in the steps below:
</p>
<ol>
  <li>
    <p>
      Let us assume we want to start afresh with CLISP, i.e. we do not
      have previous artefacts created by SBCL.  To clean up old
      artefacts, enter these commands:
    </p>
<pre><code>rm -rf ~/.sbclrc ~/quicklisp
sudo apt-get remove sbcl</code></pre>
  </li>
  <li>
    <p>
      Install CLISP with this command:
    </p>
    <pre><code>sudo apt-get install clisp</code></pre>
  </li>
  <li>
    <p>
      Install Quicklisp using CLISP with these commands:
    </p>
    <pre><code>curl -O https://beta.quicklisp.org/quicklisp.lisp
clisp -i quicklisp.lisp -x '(quicklisp-quickstart:install)'
clisp -i ~/quicklisp/setup.lisp -x '(ql:add-to-init-file)'</code></pre>
    <p>
      Type <kbd>enter</kbd> in the end, when prompted, to complete the
      installation.
    </p>
  </li>
  <li>
    <p>
      Add the following code to <code>~/.vimrc</code>:
    </p>
<pre><code>let g:vlime_cl_impl = 'clisp'
function! VlimeBuildServerCommandFor_clisp(vlime_loader, vlime_eval)
    return ['clisp', '-i', a:vlime_loader,
                   \ '-x', a:vlime_eval,
                   \ '-repl']
endfunction</code></pre>
    <p>
      Unlike Slimv, automatic start of Swank server with Common Lisp
      implementations other than SBCL are not supported out of the
      box, so the above Vim script tells Vlime how to start Swank
      server with CLISP.  The <code>-repl</code> option is used to
      work around an issue that is explained in the next point.
    </p>
  </li>
  <li>
    <p>
      Vlime is now ready to be used with CLISP.  Just edit a Lisp
      source file and enter the normal mode command
      <kbd>\</kbd><kbd>r</kbd><kbd>r</kbd> to start Swank server and
      connect to it automatically.
    </p>
    <p>
      You may see the following error in the SLIME debugger
      (<code>sldb</code>) split window:
    </p>
    <pre><samp>SOCKET-STATUS on #1=#&lt;INPUT STRING-INPUT-STREAM&gt; is illegal</samp></pre>
    <p>
      Despite the above error, the following message should appear at
      the bottom:
    </p>
    <pre><samp>Vlime Connection 1 established.</samp></pre>
    <p>
      If the above message occurs, you can ignore this error, close
      the debugger window as well as the console output window and
      continue to use Vlime normally.
    </p>
    <p>
      The <code>-repl</code> option used in the previous step ensures
      that the REPL starts despite this error.  Without it, this step
      would not have succeeded.  This is what I meant when I said
      earlier that we may need to work around certain errors while
      using these plugins with a Common Lisp implementation other than
      SBCL.
    </p>
  </li>
</ol>
<h3 id="use-vlime-with-ecl">Use Vlime with ECL<a href="#use-vlime-with-ecl"></a></h3>
<p>
  Here are the steps to use Vlime with ECL:
</p>
<ol>
  <li>
    <p>
      Let us assume we want to start afresh with ECL, i.e. we do not
      have previous artefacts created by SBCL or ECL.  To clean up old
      artefacts, enter these commands:
    </p>
<pre><code>rm -rf ~/.sbclrc ~/.clisprc.lisp ~/quicklisp
sudo apt-get remove sbcl clisp</code></pre>
  </li>
  <li>
    <p>
      Install ECL with this command:
    </p>
    <pre><code>sudo apt-get install ecl</code></pre>
  </li>
  <li>
    <p>
      Install Quicklisp using ECL with these commands:
    </p>
    <pre><code>curl -O https://beta.quicklisp.org/quicklisp.lisp
ecl --load quicklisp.lisp --eval '(quicklisp-quickstart:install)' --eval '(quit)'
ecl --load ~/quicklisp/setup.lisp --eval '(ql:add-to-init-file)' --eval '(quit)'</code></pre>
    <p>
      Type <kbd>enter</kbd> in the end, when prompted, to complete the
      installation.
    </p>
  </li>
  <li>
    <p>
      Add the following code to <code>~/.vimrc</code>:
    </p>
<pre><code>let g:vlime_cl_impl = 'ecl'
function! VlimeBuildServerCommandFor_ecl(vlime_loader, vlime_eval)
    return ['ecl', '--load', a:vlime_loader,
                 \ '--eval', a:vlime_eval]
endfunction</code></pre>
  </li>
  <li>
    <p>
      Edit a Lisp source file and enter the normal mode command
      <kbd>\</kbd><kbd>r</kbd><kbd>r</kbd> to start Swank server and
      connect to it automatically.
    </p>
  </li>
</ol>
<h2 id="other-lisp-dialects">Other Lisp Dialects<a href="#other-lisp-dialects"></a></h2>
<p>
  So far, we have seen how to use Slimv or Vlime with a Common Lisp
  implementation.  Now let us see how well these plugins work with
  other Lisp dialects.  Vlime does not support other Lisp dialects.
  It supports Common Lisp only.  Slimv supports two other popular
  dialects of Lisp: Scheme and Clojure.  In the next two subsections,
  we see how
</p>
<h3 id="use-slimv-with-mit-gnu-scheme">Use Slimv with MIT/GNU Scheme<a href="#use-slimv-with-mit-gnu-scheme"></a></h3>
<p>
  Slimv is documented to work with MIT/GNU Scheme on Linux only.
  Enter
  <code>:help slimv-installation</code> in Vim to read more about it.
  It says the following under the "Prerequisites" section.
</p>
<blockquote>
  Lisp or Clojure or MIT/GNU Scheme (Linux only) installed.
</blockquote>
<p>
  Further, the Swank loader script for MIT/GNU Scheme named
  <code>swank-mit-scheme.scm</code> says the following in its source code
  comments:
</p>
<blockquote>
  You need MIT/GNU Scheme 9.2
</blockquote>
<p>
  At the time of writing this article, I have confirmed that both
  these requirements indeed need to be met to use Slimv with MIT/GNU
  Scheme.  Here are the steps to use Slimv with MIT/GNU Scheme:
</p>
<ol>
  <li>
    <p>
      Install MIT/GNU Scheme with this command:
    </p>
    <pre><code>sudo apt-get mit-scheme</code></pre>
    <p>
      Ensure that <code>vim-nox</code>, tmux and Slimv are installed
      as explained in the
      <a href="#get-started-with-slimv-and-sbcl"><em>Get Started with
      Slimv and SBCL</em></a> subsection earlier.
    </p>
  </li>
  <li>
    <p>
      This is an optional step.  To start Swank server automatically
      from Slimv, run Vim in tmux, GNU Screen or a desktop
      environment.  In this article, we use tmux, so start tmux with
      this command:
    </p>
    <pre><code>tmux</code></pre>
  </li>
  <li>
    <p>
      This step is necessary only if you are not using tmux, GNU
      Screen or a desktop environment.  In such a case, enter this
      command to start Swank server manually:
    </p>
    <pre><code>scheme --load ~/.vim/pack/plugins/start/slimv/slime/contrib/swank-mit-scheme.scm</code></pre>
  </li>
  <li>
    <p>
      Create a new Scheme source code file, say, <code>foo.scm</code>
      with this command:
    </p>
    <pre><code>vim foo.scm</code></pre>
  </li>
  <li>
    <p>
      To connect to Swank server, enter the following command in Vim
      normal mode:
    </p>
    <p>
      <kbd>,</kbd><kbd>c</kbd>
    </p>
  </li>
  <li>
    <p>
      Type some code into the buffer for the new file.  To do so,
      first type <kbd>i</kbd> to enter insert mode and type this code:
    </p>
    <pre><code>(display "hello, world\n")</code></pre>
    <p>
      Type <kbd>esc</kbd> to return to normal mode.  To evaluate, the
      current expression under the cursor, enter the following command
      in normal mode:
    </p>
    <p>
      <kbd>,</kbd><kbd>e</kbd>
    </p>
    <p>
      Both the current expression and its result should appear in the
      REPL window.
    </p>
  </li>
</ol>
<p>
  I have confirmed that the steps above work fine with MIT/GNU Scheme
  9.1.1 on Debian GNU/Linux 9.11 (stretch).  Like I mentioned before,
  Slimv requires Linux to work with MIT/GNU Scheme.  For example,
  trying to start Swank server with MIT/GNU Scheme 9.2 on macOS High
  Sierra 10.13.6 fails with this error:
</p>
<pre><samp>; /usr/local/Cellar/mit-scheme/9.2_2/lib/mit-scheme-c/include/config.h:879:10:
fatal error: 'sys/types.h' file not found</samp></pre>
<p>
  Further, the version of MIT/GNU Scheme really needs to be 9.x.  For
  example, when I try to start Swank with MIT/GNU Scheme 10.1.5 on
  Debian GNU/Linux 10.1 (buster), the following error occurs:
</p>
<pre><samp>;The object #[package 12 (user)], passed as an argument to -&gt;environment, is not an environment.</samp></pre>
<h3 id="use-slimv-with-clojure">Use Slimv with Clojure<a href="#use-slimv-with-clojure"></a></h3>
<p>
  Slimv works fine with Clojure too.  However, it may have some
  trouble locating Clojure on the system if we attempt to start Swank
  server automatically with Clojure.  That is because where and how
  Clojure is installed varies from operating system to operating
  system and also depends on the installation procedure chosen to set
  up Clojure.
</p>
<p>
  On Unix-like systems, Slimv looks for JAR files that match the glob
  pattern <code>clojure*.jar</code> at paths that match the glob
  pattern <code>/usr/local/bin/*clojure*</code>
  and <code>~/*clojure</code>, in that order.  On Windows, it looks
  for the JAR files at directory paths that match the glob
  pattern <code>C:\*clojure*</code> and <code>C:\*clojure*\lib</code>.
  Additionally, Slimv also looks for the JAR files at the paths
  mentioned in the <code>PATH</code> environment variable.  There are
  a few more strategies too to locate Clojure but we will not get into
  that here.
</p>
<p>
  In this section, I will show how to build Clojure from source with
  Maven and install it at <code>~/clojure/clojure.jar</code>, a path
  Slimv can easily find, so installing it here would mean that the
  steps below would work everywhere regardless of the operating
  system.  If you are on Windows, install Clojure
  at <code>C:\clojure\clojure.jar</code> instead.
</p>
<p>
  Here are the steps to install Clojure at
  <code>~/clojure/clojure.jar</code> and use it with Slimv:
</p>
<ol>
  <li>
    <p>
      Choose one of the two sets of commands below to install Maven:
    </p>
<pre><code># On Debian, Ubuntu, etc.
sudo apt-get install maven

# On macOS
brew install openjdk maven
export JAVA_HOME=/usr/local/opt/openjdk
export PATH="$JAVA_HOME/bin:$PATH"</code></pre>
  </li>
  <li>
    <p>
      Enter these commands to install Clojure:
    </p>
<pre><code>git clone https://github.com/clojure/clojure.git ~/clojure
git -C ~/clojure checkout clojure-1.10.1
mvn -f ~/clojure/pom.xml -Plocal -Dmaven.test.skip=true package</code></pre>
  </li>
  <li>
    <p>
      Ensure that <code>vim-nox</code>, tmux and Slimv are installed
      as explained in
      the <a href="#get-started-with-slimv-and-sbcl"><em>Get Started
      with Slimv and SBCL</em></a> subsection earlier.
    </p>
  </li>
  <li>
    <p>
      This is an optional step.  To start Swank server automatically
      from Slimv, run Vim in tmux, GNU Screen or a desktop
      environment.  In this article, we use tmux, so start tmux with
      this command:
    </p>
    <pre><code>tmux</code></pre>
  </li>
  <li>
    <p>
      This step is necessary only if you are not using tmux, GNU
      Screen or a desktop environment.  In such a case, enter these
      commands to start Swank server manually:
    </p>
<pre><code>SWANK_DIR=~/.vim/pack/plugins/start/slimv/swank-clojure
java -cp "$HOME/clojure/clojure.jar:$SWANK_DIR" clojure.main -i "$SWANK_DIR/swank/swank.clj" -e '(swank.swank/start-repl)' -r</code></pre>
  </li>
  <li>
    <p>
      Create a new Clojure source code file, say, <code>foo.clj</code>
      with this command:
    </p>
    <pre><code>vim foo.clj</code></pre>
  </li>
  <li>
    <p>
      To connect to Swank server, enter the following command in Vim
      normal mode:
    </p>
    <p>
      <kbd>,</kbd><kbd>c</kbd>
    </p>
  </li>
  <li>
    <p>
      Type some code into the buffer for the new file.  To do so,
      first type <kbd>i</kbd> to enter insert mode and type this code:
    </p>
<pre><code>(println "hello, world")</code></pre>
    <p>
      Type <kbd>esc</kbd> to return to normal mode.  To evaluate, the
      current expression under the cursor, enter the following command
      in normal mode:
    </p>
    <p>
      <kbd>,</kbd><kbd>e</kbd>
    </p>
    <p>
      Both the current expression and its result should appear in the
      REPL window.
    </p>
  </li>
</ol>
<h2 id="comparison-of-slimv-and-vlime">Comparison of Slimv and Vlime<a href="#comparison-of-slimv-and-vlime"></a></h2>
<p>
  Finally, let me provide a comparison of both Slimv and Vlime side by
  side.  This comparison table below is not exhaustive.  There are
  more differences between the tools than what is mentioned below.
</p>
<table class="grid top">
  <thead>
    <tr>
      <th>Slimv</th>
      <th>Vlime</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td style="width: 50%">
        <p>
          Slimv's directory structure conforms to the directory
          structure of plugins in a Vim package as well as the default
          directory structure expected by popular Vim plugin managers,
          so installing Slimv is quite straightforward.
        </p>
      </td>
      <td style="width: 50%">
        <p>
          Vlime's directory structure does not conform to the
          directory structure of plugins in a Vim package or the
          default directory structure expected by popular Vim plugin
          managers.  As a result, Vim's native support for packages
          cannot be used to install Vlime.  Installing it via a plugin
          manager requires fiddling with
          Vim's <code>runtimepath</code> option in order to load it
          successfully.
        </p>
      </td>
    </tr>
    <tr>
      <td style="width: 50%">
        <p>
          Slimv requires a Vim package that is compiled with support
          for Python interface.
        </p>
      </td>
      <td style="width: 50%">
        <p>
          Vlime does not have this requirement.  It can work with
          basic Vim that does not have Python interface.
        </p>
      </td>
    </tr>
    <tr>
      <td>
        <p>
          Slimv requires Vim to be running within tmux, GNU Screen or
          a desktop environment to be able to start Swank server
          automatically.  If you have none of these, Swank server
          needs to be started manually.
        </p>
      </td>
      <td>
        <p>
          Vlime does not require tmux, GNU Screen or a desktop
          environment in order to start Vlime server automatically.
          It can start Vlime server on its own.
        </p>
      </td>
    </tr>
    <tr>
      <td>
        <p>
          Slimv does not require Quicklisp to install Swank.  Slimv
          bundles the Swank server code with itself.
        </p>
      </td>
      <td>
        <p>
          Vlime requires Quicklisp to be installed.  It relies on
          Quicklisp to install Swank the first time it is needed.
        </p>
      </td>
    </tr>
    <tr>
      <td>
        <p>
          Slimv bundles Paredit with itself.  Installing Slimv also
          provides Paredit.
        </p>
      </td>
      <td>
        <p>
          Vlime does not bundle Paredit with itself.  Paredit needs to
          be installed separately.
        </p>
      </td>
    </tr>
    <tr>
      <td>
        <p>
          The buffer for REPL is interactive in Slimv.  We can type
          code directly into the REPL window and type <kbd>enter</kbd>
          to execute it.
        </p>
      </td>
      <td>
        <p>
          The buffer for REPL is not interactive in Vlime.  Its
          <code>nomodifiable</code> option is set, so we cannot type
          code directly into the REPL window.
        </p>
      </td>
    </tr>
    <tr>
      <td>
        <p>
          Paredit electric returns work fine with Slimv.  Slimv remaps
          the "enter" key to show argument list of the current
          function after inserting electric returns.  It takes care of
          preserving the electric return functionality of Paredit.
        </p>
      </td>
      <td>
        <p>
          Paredit electric returns do not work fine with Vlime.  Vlime
          remaps the "enter" key to show argument list of the current
          function without inserting electric returns.
        </p>
      </td>
    </tr>
    <tr>
      <td>
        <p>
          Slimv shows argument list of a function, symbol description,
          etc. in the status line or message area at the bottom.
        </p>
      </td>
      <td>
        <p>
          Vlime shows argument list of a function, symbol description,
          etc. in separate split windows.  These are extra windows to
          skip over while cycling between windows with the normal mode
          <kbd>ctrl</kbd>&nbsp;+&nbsp;<kbd>w</kbd>&nbsp;<kbd>w</kbd>
          command which could feel inconvenient.
        </p>
      </td>
    </tr>
    <tr>
      <td>
        <p>
          Slimv shows trace results, macro expansion, cross reference,
          etc. in the REPL buffer.
        </p>
      </td>
      <td>
        <p>
          Vlime shows resultions of trace results, macro expansion,
          cross reference, etc. in split windows.  These are extra
          windows to skip over while cycling between windows.  This
          could feel inconvenient.
        </p>
      </td>
    </tr>
    <tr>
      <td>
        <p>
          Slimv supports programming in Common Lisp, MIT/GNU Scheme
          and Clojure.
        </p>
      </td>
      <td>
        <p>
          Vlime supports programming in Common Lisp only.  It does not
          support Scheme or Clojure.
        </p>
      </td>
    </tr>
    <tr>
      <td>
        <p>
          Slimv supports rainbow parentheses by adding
          <code>let g:lisp_rainbow=1</code> to <code>~/.vimrc</code>.
          With this feature, parentheses at different levels have
          different colours and matching parentheses have the same
          colour.
        </p>
      </td>
      <td>
        <p>
          Vlime does not have rainbow parentheses.  However, this is
          not a major problem because there are several independent
          plugins available that provide rainbow parentheses.
        </p>
      </td>
    </tr>
    <tr>
      <td>
        <p>
          Slimv cross-reference commands do not help us to jump
          directly to a function listed in the results.
        </p>
      </td>
      <td>
        <p>
          Vlime cross-reference commands create a xref buffer that
          allows us to jump directly to a function listed in the
          results by moving the cursor to the function name in the
          xref buffer and typing <code>enter</code>.
        </p>
      </td>
    </tr>
  </tbody>
</table>
<h2 id="quick-recommendation">Quick Recommendation<a href="#quick-recommendation"></a></h2>
<p>
  If you are looking for a quick recommendation on which plugin to
  use, I am going to recommend Slimv.  It has been around for much
  longer.  It supports a wider variety of Lisp implementations.  I
  find its default key bindings more convenient.  A truly interactive
  REPL buffer is also a bonus.  Also, Slimv supports Scheme and
  Clojure whereas Vlime does not.  Having said that, I think it is a
  good idea to try out both the plugins on your own and then find out
  which one suits you more.
</p>
<h2 id="disclosure">Disclosure<a href="#disclosure"></a></h2>
<p>
  Four bugs were harmed while writing this article!
</p>
<p>
  While writing this article, I found the following four bugs in Slimv
  which were then promptly squashed:
  <a href="https://github.com/kovisoft/slimv/pull/87">#87</a>,
  <a href="https://github.com/kovisoft/slimv/pull/88">#88</a>,
  <a href="https://github.com/kovisoft/slimv/pull/89">#89</a> and
  <a href="https://github.com/kovisoft/slimv/pull/90">#90</a>.
</p>
<h2 id="references">References<a href="#references"></a></h2>
<ul>
  <li>
    <a href="https://web.archive.org/web/20160303225220/http://osdir.com/ml/lisp.cmucl.devel/2003-08/msg00302.html">Couple of Emacs hacks</a>
  </li>
  <li>
    <a href="https://groups.google.com/forum/#!topic/vim_announce/EKTuhjF3ET0">Vim 8.0 Released</a>
  </li>
  <li>
    <a href="https://kovisoft.github.io/slimv-tutorial/tutorial.html">Slimv Tutorial</a>
  </li>
  <li>
    <a href="https://github.com/l04m33/vlime/blob/master/vim/doc/vlime-tutor.txt">A Tutorial for Vlime</a>
  </li>
</ul>
<!-- ### -->
<p>
  <a href="https://susam.net/lisp-in-vim.html">Read on website</a> |
  <a href="https://susam.net/tag/lisp.html">#lisp</a> |
  <a href="https://susam.net/tag/programming.html">#programming</a> |
  <a href="https://susam.net/tag/vim.html">#vim</a> |
  <a href="https://susam.net/tag/technology.html">#technology</a> |
  <a href="https://susam.net/tag/how-to.html">#how-to</a>
</p>
]]>
</description>
</item>
<item>
<title>Timing With Curl</title>
<link>https://susam.net/timing-with-curl.html</link>
<guid isPermaLink="false">tmcva</guid>
<pubDate>Sat, 10 Jul 2010 00:00:00 +0000</pubDate>
<description>
<![CDATA[
<p>
  Here is a command I use often while measuring why an HTTP request is
  taking too long:
</p>
<pre><code>curl -L -w "time_namelookup: %{time_namelookup}
time_connect: %{time_connect}
time_appconnect: %{time_appconnect}
time_pretransfer: %{time_pretransfer}
time_redirect: %{time_redirect}
time_starttransfer: %{time_starttransfer}
time_total: %{time_total}
" https://example.com/</code></pre>
<p>
  Here is the same command written as a one-liner, so that I can copy
  it easily from this page with a triple-click whenever I need it in
  future:
</p>
<pre><code>curl -L -w "time_namelookup: %{time_namelookup}\ntime_connect: %{time_connect}\ntime_appconnect: %{time_appconnect}\ntime_pretransfer: %{time_pretransfer}\ntime_redirect: %{time_redirect}\ntime_starttransfer: %{time_starttransfer}\ntime_total: %{time_total}\n" https://example.com/</code></pre>
<p>
  Here is how the output of the above command typically looks:
</p>
<pre><samp>$ <kbd>curl -L -w "namelookup: %{time_namelookup}\nconnect: %{time_connect}\nappconnect: %{time_appconnect}\npretransfer: %{time_pretransfer}\nstarttransfer: %{time_starttransfer}\ntotal: %{time_total}\n" https://example.com/</kbd>
&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"&gt;
&lt;html&gt;
...
&lt;/html&gt;
time_namelookup: 0.001403
time_connect: 0.245464
time_appconnect: 0.757656
time_pretransfer: 0.757823
time_redirect: 0.000000
time_starttransfer: 0.982111
time_total: 0.982326</samp></pre>
<p>
  In the output above, I have omitted most of the HTML output and
  replaced the omitted part with ellipsis for the sake of brevity.
</p>
<p>
  The list below provides a description of each number in the output
  above.  This information is picked straight from the manual page of
  curl 7.20.0.  Here are the details:
</p>
<ul>
  <li>
    <p>
      <em>time_namelookup:</em> The time, in seconds, it took from the
      start until the name resolving was completed.
    </p>
  </li>
  <li>
    <p>
      <em>time_connect:</em> The time, in seconds, it took from the
      start until the TCP connect to the remote host (or proxy) was
      completed.
    </p>
  </li>
  <li>
    <p>
      <em>time_appconnect:</em> The time, in seconds, it took from the
      start until the SSL/SSH/etc connect/handshake to the remote host
      was completed.  (Added in 7.19.0)
    </p>
  </li>
  <li>
    <p>
      <em>time_pretransfer:</em> The time, in seconds, it took from
      the start until the file transfer was just about to begin.  This
      includes all pre-transfer commands and negotiations that are
      specific to the particular protocol(s) involved.
    </p>
  </li>
  <li>
    <p>
      <em>time_redirect:</em> The time, in seconds, it took for all
      redirection steps include name lookup, connect, pretransfer and
      transfer before the final transaction was started.
      time_redirect shows the complete execution time for multiple
      redirections.  (Added in 7.12.3)
    </p>
  </li>
  <li>
    <p>
      <em>time_starttransfer:</em> The time, in seconds, it took from
      the start until the first byte was just about to be transferred.
      This includes time_pretransfer and also the time the server
      needed to calculate the result.
    </p>
  <li>
    <p>
      <em>time_total:</em> The total time, in seconds, that the full
      operation lasted.  The time will be displayed with millisecond
      resolution.
    </p>
  </li>
</ul>
<p>
  An important thing worth noting here is that the difference in the
  numbers for <code>time_appconnect</code>
  and <code>time_connect</code> time tells us how much time is spent
  in SSL/TLS handshake.  For a cleartext connection without SSL/TLS,
  <code>time_appconnect</code> is reported as zero.  Here is an example
  output that demonstrates this:
</p>
<pre><samp>$ <kbd>curl -L -w "time_namelookup: %{time_namelookup}\ntime_connect: %{time_connect}\ntime_appconnect: %{time_appconnect}\ntime_pretransfer: %{time_pretransfer}\ntime_redirect: %{time_redirect}\ntime_starttransfer: %{time_starttransfer}\ntime_total: %{time_total}\n" http://example.com/</kbd>
&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"&gt;
&lt;html&gt;
...
&lt;/html&gt;
time_namelookup: 0.001507
time_connect: 0.247032
time_appconnect: 0.000000
time_pretransfer: 0.247122
time_redirect: 0.000000
time_starttransfer: 0.512645
time_total: 0.512853</samp></pre>
<p>
  Also note that <code>time_redirect</code> is zero in both outputs
  above.  That is because no redirection occurs while visiting
  <a href="https://example.com">example.com</a>.  Here is another
  example that shows how the output looks when a redirection occurs:
</p>
<pre><samp>$ <kbd>curl -L -w "time_namelookup: %{time_namelookup}\ntime_connect: %{time_connect}\ntime_appconnect: %{time_appconnect}\ntime_pretransfer: %{time_pretransfer}\ntime_redirect: %{time_redirect}\ntime_starttransfer: %{time_starttransfer}\ntime_total: %{time_total}\n" https://susam.net/blog</kbd>
&lt;!DOCTYPE HTML&gt;
&lt;html&gt;
...
&lt;/html&gt;
time_namelookup: 0.001886
time_connect: 0.152445
time_appconnect: 0.465326
time_pretransfer: 0.465413
time_redirect: 0.614289
time_starttransfer: 0.763997
time_total: 0.765413</samp></pre>
<p>
  When faced with a potential latency issue in web services, this is
  often one of the first commands I run several times from multiple
  clients because the results from this command help to get a quick
  sense of the layer that might be responsible for the latency issue.
</p>
<!-- ### -->
<p>
  <a href="https://susam.net/timing-with-curl.html">Read on website</a> |
  <a href="https://susam.net/tag/networking.html">#networking</a> |
  <a href="https://susam.net/tag/technology.html">#technology</a> |
  <a href="https://susam.net/tag/how-to.html">#how-to</a>
</p>
]]>
</description>
</item>
<item>
<title>Writing Boot Sector Code</title>
<link>https://susam.net/writing-boot-sector-code.html</link>
<guid isPermaLink="false">qtplr</guid>
<pubDate>Mon, 19 Nov 2007 00:00:00 +0000</pubDate>
<description>
<![CDATA[
<h2 id="introduction">Introduction<a href="#introduction"></a></h2>
<p>
  In this article, we discuss how to write our own
  <code>"hello, world"</code> program into the boot sector.  At the
  time of this writing, most such code examples available on the web
  are meant for the Netwide Assembler (NASM).  Very little material is
  available that could be tried with the readily available GNU tools
  like the GNU assembler (as) and the GNU linker (ld).  This article
  is an effort to fill this gap.
</p>
<h2 id="boot-sector">Boot Sector<a href="#boot-sector"></a></h2>
<p>
  When the computer starts, the processor starts executing
  instructions at the memory address 0xffff:0x0000 (CS:IP).  This is
  an address in the BIOS ROM.  The machine instructions at this
  address begins the boot sequence.  In practice, this memory address
  contains a <code>JMP</code> instruction to another address,
  typically 0xf000:0xe05b.  This latter address contains the code to
  perform power-on self test (POST), perform several initialisations,
  find the boot device, load the code from the boot sector into memory
  and execute it.  From here, the code in the boot sector takes
  control.  In IBM-compatible PCs, the boot sector is the first sector
  of a data storage device.  This is 512 bytes in length.  The
  following table shows what the boot sector contains.
</p>
<table class="grid center textcenter">
  <tr>
    <th colspan="2">Address</th>
    <th rowspan="2">Description</th>
    <th rowspan="2">Size in bytes</th>
  </tr>
  <tr>
    <th>Hex</th><th>Dec</th>
  </tr>
  <tr>
    <td>000</td><td>0</td><td>Code</td><td>440</td>
  </tr>
  <tr>
    <td>1b8</td><td>440</td><td>Optional disk signature</td><td>4</td>
  </tr>
  <tr>
    <td>1bc</td><td>444</td><td>0x0000</td><td>2</td>
  </tr>
  <tr>
    <td>1be</td><td>446</td>
    <td>Four 16-byte entries for primary partitions</td><td>64</td>
  </tr>
  <tr>
    <td>1fe</td><td>510</td><td>0xaa55</td><td>2</td>
  </tr>
</table>
<p>
  This type of boot sector found in IBM-compatible PCs is also known
  as master boot record (MBR).  The next two sections explain how to
  write executable code into the boot sector.  Two programs are
  discussed in the these two sections: one that merely prints a
  character and another that prints a string.
</p>
<p>
  The reader is expected to have a working knowledge of x86 assembly
  language programming using GNU assembler.  The details of assembly
  language won't be discussed here.  Only how to write code for boot
  sector will be discussed.
</p>
<p>
  The code examples were verified by using the following tools while
  writing this article:
</p>
<ol>
  <li>Debian GNU/Linux 4.0 (etch)</li>
  <li>GNU assembler (GNU Binutils for Debian) 2.17</li>
  <li>GNU ld (GNU Binutils for Debian) 2.17</li>
  <li>dd (coreutils) 5.97</li>
  <li>DOSBox 0.65</li>
  <li>QEMU 0.8.2</li>
</ol>
<!--
Version information available here:
http://archive.debian.org/debian/dists/etch/main/binary-i386/Packages.gz
-->
<h2 id="print-character">Print Character<a href="#print-character"></a></h2>
<p>
  The following code prints the character 'A' in yellow on a blue
  background:
</p>
<pre><code>.code16
.section .text
.globl _start
_start:
  mov $0xb800, %ax
  mov %ax, %ds
  mov $0x1e41, %ax
  xor %di, %di
  mov %ax, (%di)
idle:
  hlt
  jmp idle</code></pre>
<p>
  We save the above code in a file, say <code>a.s</code>, then
  assemble and link this code with the following commands:
</p>
<pre><code>as -o a.o a.s
ld --oformat binary -o a.com a.o</code></pre>
<p>
  The above commands should generate a 15-byte output file
  named <code>a.com</code>.  The <code>.code16</code> directive in the
  source code tells the assembler that this code is meant for 16-bit
  mode.  The <code>_start</code> label is meant to tell the linker
  that this is the entry point in the program.
</p>
<p>
  The video memory of the VGA is mapped to various segments between
  0xa000 and 0xc000 in the main memory.  The colour text mode is
  mapped to the segment 0xb800.  The first two instructions copy
  0xb800 into the data segment register, so that any data offsets
  specified is an offset in this segment.  Then the ASCII code for the
  character 'A' (i.e. 0x41 or 65) is copied into the first location in
  this segment and the attribute (0x1e) of this character to the
  second location.  The higher nibble (0x1) is the attribute for
  background colour and the lower nibble (0xe) is that of the
  foreground colour.  The highest bit of each nibble is the
  intensifier bit.  Depending on the video mode setup, the highest bit
  may also represent a blinking character.  The other three bits
  represent red, green and blue.  This is represented in a tabular
  form below.
</p>
<table class="grid center textcenter">
  <tr>
    <td colspan="8">Attribute</td>
  </tr>
  <tr>
    <td colspan="4">Background</td>
    <td colspan="4">Foreground</td>
  </tr>
  <tr>
    <td>I</td>
    <td>R</td>
    <td>G</td>
    <td>B</td>
    <td>I</td>
    <td>R</td>
    <td>G</td>
    <td>B</td>
  </tr>
  <tr>
    <td>0</td>
    <td>0</td>
    <td>0</td>
    <td>1</td>
    <td>1</td>
    <td>1</td>
    <td>1</td>
    <td>0</td>
  </tr>
  <tr>
    <td colspan="4">0x1</td>
    <td colspan="4">0xe</td>
  </tr>
</table>
<p>
  We can be see from the table that the background colour is dark blue
  and the foreground colour is bright yellow.  We assemble and link
  the code with the <code>as</code> and <code>ld</code> commands
  mentioned earlier and generate an executable binary consisting of
  machine code.
</p>
<p>
  Before writing the executable binary into the boot sector, we might
  want to verify whether the code works correctly with an emulator.
  DOSBox is a pretty good emulator for this purpose.  It is available
  as the <code>dosbox</code> package in Debian.  Here is one way to
  run the executable binary file using DOSBox:
</p>
<pre><code>dosbox -c cls a.com</code></pre>
<p>
  The letter <code>A</code> printed in yellow on a blue foreground
  should appear in the first column of the first row of the screen.
</p>
<p>
  In the <code>ld</code> command earlier to generate the executable
  binary, we used the extension name <code>com</code> for the binary
  file to make DOSBox believe that it is a DOS COM file, i.e. merely
  machine code and data with no headers.  In fact, the <code>--oformat
  binary</code> option in the <code>ld</code> command ensures that the
  output file contains only machine code.  This is why we are able to
  run the binary with DOSBox for verification.  If we do not use
  DOSBox, any extension name or no extension name for the binary would
  suffice.
</p>
<p>
  Once we are satisfied with the output of <code>a.com</code> running
  in DOSBox, we create a boot image file with this command: sector
  with these commands:
</p>
<pre><code>cp a.com a.img
echo 55 aa | xxd -r -p | dd seek=510 bs=1 of=hello.img</code></pre>
<p>
  This boot image can be tested with DOSBox using the following
  command:
</p>
<pre><code>dosbox -c cls -c 'boot a.img'</code></pre>
<p>
  Yet another way to test this image would be to make QEMU x86 system
  emulator boot using this image.  Here is the command to do so:
</p>
<pre><code>qemu-system-i386 -fda a.img</code></pre>
<p>
  Finally, if you are feeling brave enough, you could write this image
  to the boot sector of an actual physical storage device, such as a
  USB flash drive and then boot your computer with it.  To do so, you
  first need to determine the device file that represents the storage
  device.  There are many ways to do this.  A couple of commands that
  may be helpful to locate the storage device are <code>mount</code>
  and <code>fdisk -l</code>.  Assuming that there is a USB flash drive
  at <code>/dev/sdx</code>, the boot image can be written to its boot
  sector using this command:
</p>
<pre><code>cp a.img /dev/sdx</code></pre>
<p>
  <em>
    CAUTION: You need to be absolutely sure of the device path of the
    device being written to.  The device path <code>/dev/sdx</code> is
    only an example here.  If the boot image is written to the wrong
    device, access to the data on that would be lost.
  </em>
</p>
<p>
  Now booting the computer with this device should show display the
  letter 'A' in yellow on a blue background.
</p>
<h2 id="print-string">Print String<a href="#print-string"></a></h2>
<p>
  The following code prints the string "hello, world" in yellow on a
  blue background:
</p>
<pre><code>.code16

.section .text
.globl _start
_start:
  ljmp $0, $start
start:
  mov $0xb800, %ax
  mov %ax, %ds
  xor %di, %di
  mov $message, %si
  mov $0x1e, %ah
print:
  mov %cs:(%si), %al
  mov %ax, (%di)
  inc %si
  inc %di
  inc %di
  cmp $24, %di
  jne print
idle:
  hlt
  jmp idle

.section .data
message:
  .ascii "hello, world"</code></pre>
<p>
  The BIOS reads the code from the first sector of the boot device
  into the memory at physical address 0x7c00 and jumps to that
  address.  While most BIOS implementations jump to 0x0000:0x7c00
  (CS:IP) to execute the boot sector code loaded at this address,
  unfortunately there are some BIOS implementations that jump to
  0x07c0:0x0000 instead to reach this address.  We will soon see that
  we are going to use offsets relative to the code segment to locate
  our string and copy it to video memory.  While the physical address
  of the string is always going to be the same regardless of which of
  the two types of BIOS implementations run our program, the offset of
  the string is going to differ based on the BIOS implementation.  If
  the register CS is set to 0 and the register IP is set to 0x7c00
  when the BIOS jumps to our program, the offset of the string is
  going to be greater than 0x7c00.  But if CS and IP are set to 0x07c0
  and 0 respectively, when the BIOS jumps to our program, the offset
  of the string is going to be much smaller.
</p>
<p>
  We cannot know in advance which type of BIOS implementation is going
  to load our program into memory, so we need to prepare our program
  to handle both scenarios: one in which the BIOS executes our program
  by jumping to 0x0000:0x7c00 as well as the other in which the BIOS
  jumps to 0x07c0:0x0000 to execute our program.  We do this by using
  a very popular technique of setting the register CS to 0 ourselves
  by executing a far jump instruction to the code segment 0.  The very
  first instruction in this program that performs <code>ljmp $0,
  $start</code> accomplishes this.
</p>
<p>
  There are two sections in this code.  The text section has the
  executable instructions.  The data section has the string we want to
  print.  The code copies the first byte of the string to the memory
  location 0xb800:0x0000, its attribute to 0xb800:0x0001, the second
  byte of the string to 0xb800:0x0002, its attribute to 0xb800:0x0003
  and so on until it has advanced to 0xb800:0x0018 after having
  written 24 bytes for the 12 characters we need to print.  The
  instruction <code>movb %cs:(%si), %al</code> copies one character
  from the string indexed by the SI register in the code segment into
  the AL register.  We are reading the characters from the code
  segment because we will place the string in the code segment using
  the linker commands discussed later.
</p>
<p>
  However, while testing with DOSBox, things are a little different.
  In DOS, the text section is loaded at an offset 0x0100 in the code
  segment.  This should be specified to the linker while linking so
  that it can correctly resolve the value of the label
  named <code>message</code>.  Therefore we will assemble and link our
  program twice: once for testing it with DOSBox and once again for
  creating the boot image.
</p>
<p>
  To understand the offset at which the data section can be put, it is
  worth looking at how the binary code looks like with a trial linking
  with the following commands:
</p>
<pre><code>as -o hello.o hello.s
ld --oformat binary -Ttext 0 -Tdata 40 -o hello.com hello.o
objdump -bbinary -mi8086 -D hello.com
xxd -g1 hello.com</code></pre>
<p>
  The <code>-Ttext 0</code> option tells the linker to assume that the
  text section should be loaded at offset 0x0 in the code segment.
  Similarly, the <code>-Tdata 40</code> tells the linker to assume
  that the data section is at offset 0x40.
</p>
<p>
  The <code>objdump</code> command mentioned above disassembles the
  generated binary file.  This shows where the text section and data
  section are placed.
</p>
<pre><samp>$ <kbd>objdump -bbinary -mi8086 -D hello.com</kbd>

hello.com:     file format binary


Disassembly of section .data:

00000000 &lt;.data&gt;:
   0:   ea 05 00 00 00          ljmp   $0x0,$0x5
   5:   b8 00 b8                mov    $0xb800,%ax
   8:   8e d8                   mov    %ax,%ds
   a:   31 ff                   xor    %di,%di
   c:   be 40 00                mov    $0x40,%si
   f:   b4 1e                   mov    $0x1e,%ah
  11:   2e 8a 04                mov    %cs:(%si),%al
  14:   89 05                   mov    %ax,(%di)
  16:   46                      inc    %si
  17:   47                      inc    %di
  18:   47                      inc    %di
  19:   83 ff 18                cmp    $0x18,%di
  1c:   75 f3                   jne    0x11
  1e:   f4                      hlt
  1f:   eb fd                   jmp    0x1e
        ...
  3d:   00 00                   add    %al,(%bx,%si)
  3f:   00 68 65                add    %ch,0x65(%bx,%si)
  42:   6c                      insb   (%dx),%es:(%di)
  43:   6c                      insb   (%dx),%es:(%di)
  44:   6f                      outsw  %ds:(%si),(%dx)
  45:   2c 20                   sub    $0x20,%al
  47:   77 6f                   ja     0xb8
  49:   72 6c                   jb     0xb7
  4b:   64                      fs</samp></pre>
<p>
  Note that the <samp>...</samp> above indicates zero bytes skipped
  by <code>objdump</code>.  The text section is above these zero bytes
  and the data section is below them.  Let us also see the output of
  the <code>xxd</code> command:
</p>
<pre><samp>$ <kbd>xxd -g1 hello.com</kbd>
00000000: ea 05 00 00 00 b8 00 b8 8e d8 31 ff be 40 00 b4  ..........1..@..
00000010: 1e 2e 8a 04 89 05 46 47 47 83 ff 18 75 f3 f4 eb  ......FGG...u...
00000020: fd 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000040: 68 65 6c 6c 6f 2c 20 77 6f 72 6c 64              hello, world</samp></pre>
<p>
  Both outputs above show that the text section occupies the first
  0x21 bytes (33 bytes).  The data section is 0xc bytes (12 bytes) in
  length.  Let us create a binary where the region from offset 0x0 to
  offset 0x20 contains the text section and the region from offset
  0x21 to offset 0x2c contains the data section.  The total length of
  the binary would then be 0x2d bytes (45 bytes).  We will create a
  new binary as per this plan.
</p>
<p>
  However while creating the new binary, we should remember that DOS
  would load the binary at offset 0x100, so we need to tell the linker
  to assume 0x100 as the offset of the text section and 0x121 as the
  offset of the data section, so that it resolves the value of the
  label named <code>message</code> accordingly.  Moreover while
  testing with DOS, we must remove the far jump instruction at the top
  of our program because DOS does not load our program at physical
  address 0x7c00 of the memory.  We create a new binary in this manner
  and test it with DOSBox with these commands:
</p>
<pre><code>grep -v ljmp hello.s &gt; dos-hello.s
as -o hello.o dos-hello.s
ld --oformat binary -Ttext 100 -Tdata 121 -o hello.com hello.o</code></pre>
<p>
  Now we can test this program with DOSBox with the following command:
</p>
<pre><code>dosbox -c cls hello.com</code></pre>
<p>
  If everything looks fine, we assemble and link our program once
  again for boot sector and create a boot image with these commands:
</p>
<pre><code>as -o hello.o hello.s
ld --oformat binary -Ttext 7c00 -Tdata 7c21 -o hello.img hello.o
echo 55 aa | xxd -r -p | dd seek=510 bs=1 of=hello.img</code></pre>
<p>
  Now we can test this image with DOSBox like this:
</p>
<pre><code>dosbox -c cls -c 'boot hello.img'</code></pre>
<p>
  We can also test the image with QEMU with the following command:
</p>
<pre><code>qemu-system-i386 -fda hello.img</code></pre>
<p>
  Finally, this image can be written to the boot sector as follows:
</p>
<pre><code>cp hello.img /dev/sdx</code></pre>
<p>
  <em>
    CAUTION: Again, one needs to be very careful with the commands
    here.  The device path <code>/dev/sdx</code> is only an example.
    This path must be changed to the path of the actual device one
    wants to write the boot sector binary to.
  </em>
</p>
<p>
  Once written to the device successfully, the computer may be booted
  with this device to display the "hello, world" string on the screen.
</p>
<!-- ### -->
<p>
  <a href="https://susam.net/writing-boot-sector-code.html">Read on website</a> |
  <a href="https://susam.net/tag/assembly.html">#assembly</a> |
  <a href="https://susam.net/tag/programming.html">#programming</a> |
  <a href="https://susam.net/tag/linux.html">#linux</a> |
  <a href="https://susam.net/tag/technology.html">#technology</a> |
  <a href="https://susam.net/tag/how-to.html">#how-to</a>
</p>
]]>
</description>
</item>
<item>
<title>Vim Sudo Write Trick</title>
<link>https://susam.net/vim-sudo-write-trick.html</link>
<guid isPermaLink="false">qjgnc</guid>
<pubDate>Thu, 25 Aug 2005 00:00:00 +0000</pubDate>
<description>
<![CDATA[
<h2 id="trick">The Trick<a href="#trick"></a></h2>
<p>
  You open a file, edit it and save it only to get the E45 error
  message that says:
</p>
<pre><samp>E45: 'readonly' option is set (add ! to override)</samp></pre>
<p>
  You now realise that only root can edit the file.  What do you?
  Start over?  No, instead try this:
</p>
<pre><code>:w !sudo tee "%"</code></pre>
<p>
  I learnt this trick recently from the comment section
  of <a href="https://web.archive.org/web/20051120054527/http://www.vim.org/tips/tip.php?tip_id=975">Tip
  #975</a> on the Vim Tips website.
</p>
<h2 id="explanation">Explanation<a href="#explanation"></a></h2>
<p>
  How does the <code>:w !sudo tee "%"</code> trick work?  Let us look
  at the command part-by-part:
</p>
<ul>
  <li>
    <p><code>:w !{cmd}</code></p>
    <p>
      Execute <code>{cmd}</code> with all lines in buffer as standard
      input.
    </p>
  </li>
  <li>
    <p><code>"%"</code></p>
    <p>
      The <code>%</code> is replaced with the current filename.  The
      quotes around it keeps the filename as a single argument even if
      it contains whitespace.
    </p>
  </li>
  <li>
    <p><code>tee {file}</code></p>
    <p>
      The <code>tee</code> command is a Unix command (not a Vim
      command).  It copies standard input to standard output
      and <code>{file}</code>.
    </p>
  </li>
</ul>
<h2 id="more">More Information<a href="#more"></a></h2>
<p>
  For more information on this command, enter the following commands
  in Vim:
</p>
<pre><code>:help :w_c
:help current-file
:help :_%</code></pre>
<p>
  Also, enter the following command in shell:
</p>
<pre><code>man tee</code></pre>
<p>
  I hope this was fun!
</p>
<!-- ### -->
<p>
  <a href="https://susam.net/vim-sudo-write-trick.html">Read on website</a> |
  <a href="https://susam.net/tag/vim.html">#vim</a> |
  <a href="https://susam.net/tag/unix.html">#unix</a> |
  <a href="https://susam.net/tag/technology.html">#technology</a> |
  <a href="https://susam.net/tag/how-to.html">#how-to</a>
</p>
]]>
</description>
</item>
<item>
<title>Rebooting With JMP Instruction</title>
<link>https://susam.net/rebooting-with-jmp-instruction.html</link>
<guid isPermaLink="false">mqkfs</guid>
<pubDate>Sun, 02 Mar 2003 00:00:00 +0000</pubDate>
<description>
<![CDATA[
<p>
  While learning about x86 microprocessors, I realised that it is
  possible to reboot a computer running MS-DOS or Windows 98 by
  jumping to the memory address FFFF:0000.  Here is an
  example <code>DEBUG.EXE</code> session from MS-DOS 6.22:
</p>
<pre><samp>C:\&gt;<kbd>DEBUG</kbd>
<kbd>G =FFFF:0000</kbd></samp></pre>
<p>
  In the above example, we start the DOS debugger and then enter
  the <code>G</code> (go) command to execute the program at FFFF:0000.
  Just doing this simple operation should reboot the system
  immediately.
</p>
<p>
  When the computer boots, the x86 microprocessor starts in real mode
  and executes the instruction at FFFF:0000.  This is an address in
  the BIOS ROM that contains a far jump instruction to go to another
  address, typically F000:E05B.
</p>
<pre><samp>C:\&gt;<kbd>DEBUG</kbd>
-<kbd>U FFFF:0000 4</kbd>
FFFF:0000 EA5BE000F0    JMP     F000:E05B</samp></pre>
<p>
  The address F000:E05B contains the BIOS start-up program which
  performs a power-on self-test (POST), initialises the peripheral
  devices, loads the boot sector code and executes it.  These
  operations complete the booting sequence.
</p>
<p>
  The important point worth noting here is that the very first
  instruction the microprocessor executes after booting is the
  instruction at FFFF:0000.  We can use this fact to create a tiny
  executable program that can be used to reboot the computer.  Of
  course, we can always perform a soft reboot using the key
  sequence <kbd>ctrl</kbd>+<kbd>alt</kbd>+<kbd>del</kbd>.  However,
  just for fun, let us create a program to reboot the computer with
  a <code>JMP FFFF:0000</code> instruction.
</p>
<h2 id="reboot-program">Reboot Program<a href="#reboot-program"></a></h2>
<p>
  Here is a complete <code>DEBUG.EXE</code> session that shows how we
  could write a simple reboot program:
</p>
<pre><samp>C:\&gt;<kbd>DEBUG</kbd>
-<kbd>A</kbd>
1165:0100 <kbd>JMP FFFF:0000</kbd>
1165:0105
-<kbd>N REBOOT.COM</kbd>
-<kbd>R CX</kbd>
CX 0000
:<kbd>5</kbd>
-<kbd>W</kbd>
Writing 00005 bytes
-<kbd>Q</kbd>

C:\&gt;</samp></pre>
<p>
  Note that the <code>N</code> (name) command specifies the name of
  the file where we write the binary machine code to.  Also, note that
  the <code>W</code> (write) command expects the registers BX and CX
  to contain the number of bytes to be written to the file.  When the
  DOS debugger starts, it already initialises BX to 0 automatically,
  so we only set the register CX to 5 with the <code>R CX</code>
  command above.
</p>
<p>
  Now we can execute this 5-byte program like this:
</p>
<pre><samp>C:&gt;<kbd>REBOOT</kbd></samp></pre>
<h2 id="debugger-scripting">Debugger Scripting<a href="#debugger-scripting"></a></h2>
<p>
  In the previous section, we saw how we can start
  <code>DEBUG.EXE</code> and type the debugger commands and the
  assembly language instruction to jump to FFFF:0000.  We can also keep
  these debugger inputs in a separate text file and feed that to the
  debugger.  Here is how the content of such a text file would look:
</p>
<pre><code>A
JMP FFFF:0000

N REBOOT.COM
R CX
5
W
Q</code></pre>
<p>
  If the above input is saved in a file, say, <code>REBOOT.TXT</code>,
  then we can run the DOS command <code>DEBUG &lt; REBOOT.TXT</code>
  to assemble the program and create the binary executable file.  The
  following DOS session example shows how this command behaves:
</p>
<pre><samp>C:\&gt;<kbd>DEBUG &lt; REBOOT.TXT</kbd>
-A
1165:0100 JMP FFFF:0000
1165:0105
-N REBOOT.COM
-R CX
CX 0000
:5
-W
Writing 00005 bytes
-Q

C:&gt;</samp></pre>
<h2 id="disassembly">Disassembly<a href="#disassembly"></a></h2>
<p>
  Here is a quick demonstration of how we can disassemble the
  executable code:
</p>
<pre><samp>C:\&gt;<kbd>DEBUG REBOOT.COM</kbd>
-<kbd>U 100 104</kbd>
117C:0100 EA0000FFFF    JMP     FFFF:0000</samp></pre>
<p>
  While we did not really need to disassemble this tiny program, the
  above example shows how we can use the debugger
  command <code>U</code> (unassemble) to translate machine code to
  assembly language mnemonics.
</p>
<!-- ### -->
<p>
  <a href="https://susam.net/rebooting-with-jmp-instruction.html">Read on website</a> |
  <a href="https://susam.net/tag/assembly.html">#assembly</a> |
  <a href="https://susam.net/tag/programming.html">#programming</a> |
  <a href="https://susam.net/tag/dos.html">#dos</a> |
  <a href="https://susam.net/tag/technology.html">#technology</a> |
  <a href="https://susam.net/tag/how-to.html">#how-to</a>
</p>
]]>
</description>
</item>
<item>
<title>Programming With DOS Debugger</title>
<link>https://susam.net/programming-with-dos-debugger.html</link>
<guid isPermaLink="false">tkxiv</guid>
<pubDate>Tue, 11 Feb 2003 00:00:00 +0000</pubDate>
<description>
<![CDATA[
<h2 id="introduction">Introduction<a href="#introduction"></a></h2>
<p>
  MS-DOS as well as Windows 98 come with a debugger program
  named <code>DEBUG.EXE</code> that can be used to work with assembly
  language instructions and machine code.  In MS-DOS version 6.22, this
  program is named <code>DEBUG.EXE</code> and it is typically present
  at <code>C:\DOS\DEBUG.EXE</code>.  On Windows 98, this program is
  usually present at <code>C:\Windows\Command\Debug.exe</code>.  It is
  a line-oriented debugger that supports various useful features to
  work with and debug binary executable programs consisting of machine
  code.
</p>
<p>
  In this post, we see how we can use this debugger program to
  assemble a few minimal programs that print some characters to
  standard output.  We first create a 7-byte program that prints a
  single character.  Then we create a 23-byte program that prints the
  "hello, world" string.  All the steps provided in this post work well
  with Windows 98 too.
</p>
<h2 id="contents">Contents<a href="#contents"></a></h2>
<ul>
  <li><a href="#introduction">Introduction</a></li>
  <li><a href="#print-character">Print Character</a></li>
  <li><a href="#hello-world">Hello, World</a></li>
  <li><a href="#debugger-scripting">Debugger Scripting</a></li>
  <li><a href="#disassembly">Disassembly</a></li>
  <li><a href="#int-20-vs-ret">INT 20 vs RET</a></li>
  <li><a href="#conclusion">Conclusion</a></li>
</ul>
<h2 id="print-character">Print Character<a href="#print-character"></a></h2>
<p>
  Let us first see how to create a tiny 7-byte program that prints the
  character <code>A</code> to standard output.  The
  following <code>DEBUG.EXE</code> session shows how we do it.
</p>
<pre><samp>C:\&gt;<kbd>DEBUG</kbd>
-<kbd>A</kbd>
1165:0100 <kbd>MOV AH, 2</kbd>
1165:0102 <kbd>MOV DL, 41</kbd>
1165:0104 <kbd>INT 21</kbd>
1165:0106 <kbd>RET</kbd>
1165:0107
-<kbd>G</kbd>
A
Program terminated normally
-<kbd>N A.COM</kbd>
-<kbd>R CX</kbd>
CX 0000
:<kbd>7</kbd>
-<kbd>W</kbd>
Writing 00007 bytes
-<kbd>Q</kbd>

C:\&gt;</samp></pre>
<p>
  Now we can execute this program as follows:
</p>
<pre><samp>C:\&gt;<kbd>A</kbd>
A
C:\&gt;</samp></pre>
<p>
  The debugger command <code>A</code> creates machine executable code
  from assembly language instructions.  The machine code created is
  written to the main memory at address CS:0100 by default.  The first
  three instructions generate the software interrupt 0x21 (decimal 33)
  with AH set to 2 and DL set to 0x41 (decimal 65) which happens to be
  the ASCII code of the character <code>A</code>.  Interrupt 0x21
  offers a wide variety of DOS services.  Setting AH to 2 tells this
  interrupt to invoke the function that prints a single character to
  standard output.  This function expects DL to be set to the ASCII
  code of the character we want to print.
</p>
<p>
  The command <code>G</code> executes the program in memory from the
  current location.  The current location is defined by the current
  value of CS:IP which is CS:0100 by default.  We use this command to
  confirm that the program runs as expected.
</p>
<p>
  Next we prepare to write the machine code to a binary executable
  file.  The command <code>N</code> is used to specify the name of the
  file.  The command <code>W</code> is used to write the machine code
  to the file.  This command expects the registers BX and CX to contain
  the number of bytes to be written to the file.  When the DOS debugger
  starts, BX is already initialised to 0, so we only set the register
  CX to 7 with the <code>R CX</code> command.  Finally, we use the
  command <code>Q</code> to quit the debugger and return to MS-DOS.
</p>
<h2 id="hello-world">Hello, World<a href="#hello-world"></a></h2>
<p>
  The following <code>DEBUG.EXE</code> session shows how to create a
  program that prints a string.
</p>
<pre><samp>C:\&gt;<kbd>DEBUG</kbd>
-<kbd>A</kbd>
1165:0100 <kbd>MOV AH, 9</kbd>
1165:0102 <kbd>MOV DX, 108</kbd>
1165:0105 <kbd>INT 21</kbd>
1165:0107 <kbd>RET</kbd>
1165:0108 <kbd>DB 'hello, world', D, A, '$'</kbd>
1165:0117
-<kbd>G</kbd>
hello, world

Program terminated normally
-<kbd>N HELLO.COM</kbd>
-<kbd>R CX</kbd>
CX 0000
:<kbd>17</kbd>
-<kbd>W</kbd>
Writing 00017 bytes
-<kbd>Q</kbd>

C:\&gt;</samp></pre>
<p>
  Now we can execute this 23-byte program like this:
</p>
<pre><samp>C:\&gt;<kbd>HELLO</kbd>
hello, world

C:\&gt;</samp></pre>
<p>
  In the program above we use the pseudo-instruction <code>DB</code>
  to define the bytes of the string we want to print.  We add the
  trailing bytes 0xD and 0xA to print the carriage return (CR) and the
  line feed (LF) characters so that the string is terminated with a
  newline.  Finally, the string is terminated with the byte for dollar
  sign (<code>'$'</code>) because the software interrupt we generate
  next expects the string to be terminated with this symbol's byte
  value.
</p>
<p>
  We use the software interrupt 0x21 again.  However, this time we set
  AH to 9 to invoke the function that prints a string.  This function
  expects DS:DX to point to the address of a string terminated with
  the byte value of <code>'$'</code>.  The register <code>DS</code> has
  the same value as that of <code>CS</code>, so we only
  set <code>DX</code> to the offset at which the string begins.
</p>
<h2 id="debugger-scripting">Debugger Scripting<a href="#debugger-scripting"></a></h2>
<p>
  We have already seen above how to assemble a "hello, world" program
  in the previous section.  We started the debugger program, typed
  some commands and typed assembly language instructions to create our
  program.  It is also possible to prepare a separate input file with
  all the debugger commands and assembly language instructions in it.
  We then feed this file to the debugger program.  This can be useful
  while writing more complex programs where we cannot afford to lose
  our assembly language source code if we inadvertently crash the
  debugger by executing an illegal instruction.
</p>
<p>
  To create a separate input file that can be fed to the debugger, we
  may use the DOS command <code>EDIT HELLO.TXT</code> to open a new
  file with MS-DOS Editor, then type in the following debugger
  commands and then save and exit the editor.
</p>
<pre><code>A
MOV AH, 9
MOV DX, 108
INT 21
RET
DB 'hello, world', D, A, '$'

N HELLO.COM
R CX
17
W
Q</code></pre>
<p>
  This is almost the same as the inputs we typed into the debugger in
  the previous section.  The only difference from the previous section
  is that we omit the <code>G</code> command here because we don't
  really need to run the program while assembling it, although we
  could do so if we really wanted to.
</p>
<p>
  Then we can run the DOS command <code>DEBUG &lt; HELLO.TXT</code> to
  assemble the program and create the binary executable file.  Here is
  a DOS session example that shows what the output of this command
  looks like:
</p>
<pre><samp>C:\&gt;<kbd>DEBUG &lt; HELLO.TXT</kbd>
-A
1165:0100 MOV AH, 9
1165:0102 MOV DX, 108
1165:0105 INT 21
1165:0107 RET
1165:0108 DB 'hello, world', D, A, '$'
1165:0117
-N HELLO.COM
-R CX
CX 0000
:17
-W
Writing 00017 bytes
-Q

C:\&gt;</samp></pre>
<p>
  The output is in fact very similar to the debugger session in the
  previous section.
</p>
<h2 id="disassembly">Disassembly<a href="#disassembly"></a></h2>
<p>
  Now that we have seen how to assemble simple programs into binary
  executable files using the debugger, we will now briefly see how to
  disassemble the binary executable files.  This could be useful when
  we want to debug an existing program.
</p>
<pre><samp>C:\&gt;<kbd>DEBUG A.COM</kbd>
-<kbd>U 100 106</kbd>
117C:0100 B402          MOV     AH,02
117C:0102 B241          MOV     DL,41
117C:0104 CD21          INT     21
117C:0106 C3            RET</samp></pre>
<p>
  The debugger command <code>U</code> (unassemble) is used to
  translate the binary machine code to assembly language mnemonics.
</p>
<pre><samp>C:\&gt;<kbd>DEBUG HELLO.COM</kbd>
-<kbd>U 100 116</kbd>
117C:0100 B409          MOV     AH,09
117C:0102 BA0801        MOV     DX,0108
117C:0105 CD21          INT     21
117C:0107 C3            RET
117C:0108 68            DB      68
117C:0109 65            DB      65
117C:010A 6C            DB      6C
117C:010B 6C            DB      6C
117C:010C 6F            DB      6F
117C:010D 2C20          SUB     AL,20
117C:010F 776F          JA      0180
117C:0111 726C          JB      017F
117C:0113 64            DB      64
117C:0114 0D0A24        OR      AX,240A
-<kbd>D 100 116</kbd>
117C:0100  B4 09 BA 08 01 CD 21 C3-68 65 6C 6C 6F 2C 20 77   ......!.hello, w
117C:0110  6F 72 6C 64 0D 0A 24                              orld..$</samp></pre>
<h2 id="int-20-vs-ret">INT 20 vs RET<a href="#int-20-vs-ret"></a></h2>
<p>
  Another way to terminate a .COM program is to simply use the
  instruction <code>INT 20</code>.  This consumes two bytes in the
  machine code: <code>CD 20</code>.  While producing the smallest
  possible executables was not really the goal of this post, the code
  examples above indulge in a little bit of size reduction by using
  the <code>RET</code> instruction to terminate the program.  This
  consumes only one byte: <code>C3</code>.  This works because when a
  .COM file starts, the register SP contains FFFE.  The stack memory
  locations at offset FFFE and FFFF contain 00 and 00 respectively.
  Further, the memory address offset 0000 contains the
  instruction <code>INT 20</code>.  Here is a demonstration of these
  facts using the debugger program:
</p>
<pre><samp>C:\&gt;<kbd>DEBUG HELLO.COM</kbd>
-<kbd>R SP</kbd>
SP FFFE
:
-<kbd>D FFFE</kbd>
117C:FFF0                                            00 00
-<kbd>U 0 1</kbd>
117C:0000 CD20          INT     20</samp></pre>
<p>
  As a result, executing the <code>RET</code> instruction pops 0000
  off the stack at FFFE and loads it into IP.  This results in the
  instruction <code>INT 20</code> at offset 0000 getting executed
  which leads to program termination.
</p>
<p>
  While both <code>INT 20</code> and <code>RET</code> lead to
  successful program termination both in DOS as well as while
  debugging with <code>DEBUG.EXE</code>, there is some difference
  between them which affects the debugging experience.  Terminating the
  program with <code>INT 20</code> allows us to run the program
  repeatedly within the debugger by repeated applications of
  the <code>G</code> debugger command.  But when we terminate the
  program with <code>RET</code>, we cannot run the program repeatedly
  in this manner.  The program runs and terminates successfully the
  first time we run it in the debugger but the stack does not get
  reinitialised with zeros to prepare it for another execution of the
  program within the debugger.  Therefore when we try to run the
  program the second time using the <code>G</code> command, the
  program does not terminate successfully.  It hangs instead.  It is
  possible to work around this by reinitialising the stack with the
  debugger command <code>E FFFE 0 0</code> before
  running <code>G</code> again.
</p>
<h2 id="conclusion">Conclusion<a href="#conclusion"></a></h2>
<p>
  Although the DOS debugger is very limited in features in comparison
  with sophisticated assemblers like NASM, MASM, etc., this humble
  program can perform some of the basic operations involved in working
  with assembly language and machine code.  It can read and write
  binary executable files, examine memory, execute machine
  instructions in memory, modify registers, edit binary files, etc.
  The fact that this debugger program is always available with MS-DOS
  or Windows 98 system means that these systems are ready for some
  rudimentary assembly language programming without requiring any
  additional tools.
</p>
<!-- ### -->
<p>
  <a href="https://susam.net/programming-with-dos-debugger.html">Read on website</a> |
  <a href="https://susam.net/tag/assembly.html">#assembly</a> |
  <a href="https://susam.net/tag/programming.html">#programming</a> |
  <a href="https://susam.net/tag/dos.html">#dos</a> |
  <a href="https://susam.net/tag/technology.html">#technology</a> |
  <a href="https://susam.net/tag/how-to.html">#how-to</a>
</p>
]]>
</description>
</item>
<item>
<title>Editing Binaries in DOS</title>
<link>https://susam.net/editing-binaries-in-dos.html</link>
<guid isPermaLink="false">xomdn</guid>
<pubDate>Thu, 18 Jul 2002 00:00:00 +0000</pubDate>
<description>
<![CDATA[
<p>
  Both MS-DOS and Windows 98 come with a debugger program
  named <code>DEBUG.EXE</code> that make it possible to edit binary
  files without requiring additional tools.  Although the primary
  purpose of this program is to test and debug executable files, it
  can be used to edit binary files too.  Two examples of this are
  shown in this post.  The first example edits a string of bytes in an
  executable file.  The second one edits machine instructions to alter
  the behaviour of the program.  Both examples provided in the next
  two sections can be reproduced on MS-DOS version 6.22.  These
  examples can be performed on Windows 98 too after minor adjustments.
</p>
<h2 id="editing-data">Editing Data<a href="#editing-data"></a></h2>
<p>
  Let us first see an example of editing an error message produced by
  the <code>MODE</code> command.  This DOS command is used for
  displaying and reconfiguring system settings.  For example, the
  following command sets the display to show 40 characters per line:
</p>
<pre><samp>C:\&gt;<kbd>MODE 40</kbd></samp></pre>
<p>
  The following command reverts the display to show 80 characters per
  line:
</p>
<pre><samp>C:\&gt;<kbd>MODE 80</kbd></samp></pre>
<p>
  Here is another example of this command that shows the current
  settings for serial port COM1:
</p>
<pre><samp>C:\&gt;<kbd>MODE COM1</kbd>

Status for device COM1:
-----------------------
Retry=NONE

C:\&gt;</samp></pre>
<p>
  An invalid parameter leads to an error like this:
</p>
<pre><samp>C:\&gt;<kbd>MODE 0</kbd>

Invalid parameter - 0

C:\&gt;</samp></pre>
<p>
  We will edit this error message to be slightly more helpful.  The
  following debugger session shows how.
</p>
<pre><samp>C:\&gt;<kbd>DEBUG C:\DOS\MODE.COM</kbd>
-<kbd>S 0 FFFF 'Invalid parameter'</kbd>
117C:19D1
-<kbd>D 19D0 19FF</kbd>
117C:19D0  13 49 6E 76 61 6C 69 64-20 70 61 72 61 6D 65 74   .Invalid paramet
117C:19E0  65 72 0D 0A 20 0D 0A 49-6E 76 61 6C 69 64 20 6E   er.. ..Invalid n
117C:19F0  75 6D 62 65 72 20 6F 66-20 70 61 72 61 6D 65 74   umber of paramet
-<kbd>E 19D0 12 'No soup for you!' D A</kbd>
-<kbd>D 19D0 19FF</kbd>
117C:19D0  12 4E 6F 20 73 6F 75 70-20 66 6F 72 20 79 6F 75   .No soup for you
117C:19E0  21 0D 0A 0A 20 0D 0A 49-6E 76 61 6C 69 64 20 6E   !... ..Invalid n
117C:19F0  75 6D 62 65 72 20 6F 66-20 70 61 72 61 6D 65 74   umber of paramet
-<kbd>N SOUP.COM</kbd>
-<kbd>W</kbd>
Writing 05C11 bytes
-<kbd>Q</kbd>

C:\&gt;</samp></pre>
<p>
  We first open <code>MODE.COM</code> with the debugger.  When we do
  so, the entire program is loaded into offset 0x100 of the code
  segment (CS).  Then we use the <code>S</code> debugger command to
  search for the string "Invalid parameter".  This prints the offset
  at which this string occurs in memory.
</p>
<p>
  We use the <code>D</code> command to dump the bytes around that
  offset.  In the first row of the output, the byte value 13 (decimal
  19) represents the length of the string that follows it.  Indeed
  there are 19 bytes in the string composed of the text <code>"Invalid
  parameter"</code> and the following carriage return (CR) and line
  feed (LF) characters.  The CR and LF characters have ASCII codes 0xD
  (decimal 13) and 0xA (decimal 10).  These values can be seen at the
  third and fourth places of the second row of the output of this
  command.
</p>
<p>
  Then we use the <code>E</code> command to enter a new string length
  followed by a new string to replace the existing error message.
  Note that we enter a string length of 0x12 (decimal 18) which is
  indeed the length of the string that follows it.  After entering the
  new string, we dump the memory again with <code>D</code> to verify
  that the new string is now present in memory.
</p>
<p>
  After confirming that the edited string looks good, we use
  the <code>N</code> command to specify the name of the file we want
  to write the edited binary to.  This command starts writing the
  bytes from offset 0x100 to the named file.  It reads the number of
  bytes to be written to the file from the BX and CX registers.  These
  registers are already initialised to the length of the file when we
  load a file in the debugger.  Since we have not modified these
  registers ourselves, we don't need to set them again.  In case you
  do need to set the BX and CX registers in a different situation, the
  commands to do so are <code>R BX</code> and <code>R CX</code>
  respectively.
</p>
<p>
  Finally, the <code>W</code> command writes the file and
  the <code>Q</code> command quits the debugger.  Now we can test the
  new program as follows:
</p>
<pre><samp>
C:\&gt;<kbd>SOUP 0</kbd>

No soup for you! - 0

C:\&gt;</samp></pre>
<h2 id="editing-machine-instructions">Editing Machine Instructions<a href="#editing-machine-instructions"></a></h2>
<p>
  In this section, we will see how to edit the binary we created in
  the previous section further to add our own machine instructions to
  print a welcome message when the program starts.  Here is an example
  debugger session that shows how to do it.
</p>
<pre><samp>C:\&gt;<kbd>DEBUG SOUP.COM</kbd>
-<kbd>U</kbd>
117C:0100 E99521        JMP     2298
117C:0103 51            PUSH    CX
117C:0104 8ACA          MOV     CL,DL
117C:0106 D0E1          SHL     CL,1
117C:0108 32ED          XOR     CH,CH
117C:010A 80CD03        OR      CH,03
117C:010D D2E5          SHL     CH,CL
117C:010F 2E            CS:
117C:0110 222E7D01      AND     CH,[017D]
117C:0114 2E            CS:
117C:0115 890E6402      MOV     [0264],CX
117C:0119 59            POP     CX
117C:011A 7505          JNZ     0121
117C:011C EA39E700F0    JMP     F000:E739
-<kbd>D 300</kbd>
117C:0300  07 1F C3 18 18 18 18 18-00 00 00 00 00 00 00 00   ................
117C:0310  00 00 FF 00 00 00 00 00-FF 00 00 00 00 00 00 00   ................
117C:0320  00 00 00 00 00 00 00 00-00 00 FF FF 90 00 40 00   ..............@.
117C:0330  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
117C:0340  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
117C:0350  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
117C:0360  00 00 00 FF 00 00 00 00-00 00 00 00 00 00 00 00   ................
117C:0370  02 00 2B C0 8E C0 A0 71-03 A2 BA 07 A2 BC 07 3C   ..+....q.......<
-<kbd>A</kbd>
117C:0100 <kbd>JMP 330</kbd>
117C:0103
-<kbd>A 330</kbd>
117C:0330 <kbd>MOV AH, 9</kbd>
117C:0332 <kbd>MOV DX, 33A</kbd>
117C:0335 <kbd>INT 21</kbd>
117C:0337 <kbd>JMP 2298</kbd>
117C:033A <kbd>DB 'Welcome to Soup Kitchen!', D, A, '$'</kbd>
117C:0355
-<kbd>W</kbd>
Writing 05C11 bytes
-<kbd>Q</kbd>

C:\&gt;</samp></pre>
<p>
  At the beginning, we use the debugger command <code>U</code> to
  unassemble (disassemble) some bytes at the top of the program to see
  what they look like.  We see that the very first instruction is a
  jump to offset 0x2298.  The debugger command <code>D 300</code>
  shows that there are contiguous zero bytes around offset 0x330.  We
  replace some of these zero bytes with new machine instructions that
  print our welcome message.  To do this, we first replace the jump
  instruction at the top with a jump instruction to offset 0x330 where
  we then place the machine code for our welcome message.  This new
  machine code prints the welcome message and then jumps to offset
  0x2298 allowing the remainder of the program to execute as usual.
</p>
<p>
  The debugger command <code>A</code> is used to assemble the machine
  code for the altered jump instruction at the top.  By default it
  writes the assembled machine code to CS:0100 which is the address at
  which DOS loads executable programs.  Then we use the debugger
  command <code>A 330</code> to add new machine code at offset 0x330.
  We try not to go beyond the region with contiguous zeroes while
  writing our machine instructions.  Fortunately for us, our entire
  code for the welcome message occupies 37 bytes and and the last byte
  of our code lands at offset 0x354.
</p>
<p>
  Finally, we write the updated program in memory back to the file
  named <code>SOUP.COM</code>.  Since the debugger was used to load
  the file named <code>SOUP.COM</code>, we do not need to use
  the <code>N</code> command to specify the name of the file again.
  When a file has just been loaded into the debugger, by default
  the <code>W</code> command writes the program in memory back to the
  same file that was loaded into the memory.
</p>
<p>
  Now our updated program should behave as shown below:
</p>
<pre><samp>C:\&gt;<kbd>SOUP COM1</kbd>
Welcome to Soup Kitchen!

Status for device COM1:
-----------------------
Retry=NONE

C:\&gt;<kbd>SOUP 0</kbd>
Welcome to Soup Kitchen!

No soup for you! - 0

C:\&gt;</samp></pre>
<p>
  That's our modified program that prints a welcome message and our
  own error message created with the humble DOS debugger.
</p>
<!-- ### -->
<p>
  <a href="https://susam.net/editing-binaries-in-dos.html">Read on website</a> |
  <a href="https://susam.net/tag/assembly.html">#assembly</a> |
  <a href="https://susam.net/tag/programming.html">#programming</a> |
  <a href="https://susam.net/tag/dos.html">#dos</a> |
  <a href="https://susam.net/tag/technology.html">#technology</a> |
  <a href="https://susam.net/tag/how-to.html">#how-to</a>
</p>
]]>
</description>
</item>


</channel>
</rss>
