<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="/stylesheets/rss.css" type="text/css"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>Chris Ball: Productivity</title>
    <link>http://blog.printf.net/articles/2006/03/21/productivity</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description></description>
    <item>
      <title>Productivity</title>
      <description>&lt;p&gt;The main purpose of this post is to show off a link I found documenting some of the under-used features of emacs &amp;#8212; &lt;a href="http://www.cabochon.com/~stevey/blog-rants/effective-emacs.html"&gt;Effective Emacs&lt;/a&gt;.  (Thanks to &lt;a href="http://emacsen.org"&gt;Edward O'Connor's blog&lt;/a&gt; for the link.)
&lt;br&gt;&lt;br&gt;
I've been on an optimisation binge recently, making sure that I'm getting the best out of my &lt;a href="http://www.gnu.org/software/emacs/"&gt;editor&lt;/a&gt; and &lt;a href="http://www.zsh.org/"&gt;shell&lt;/a&gt;.  I decided to document some of the features I'm using:&lt;/p&gt;

&lt;h2&gt;zsh:&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Hostname completion based on the contents of your &lt;code&gt;~/.ssh/known_hosts&lt;/code&gt; file.  This requires you to turn off &lt;code&gt;HashKnownHosts&lt;/code&gt; (see below), and add the following to your &lt;code&gt;~/.zshrc&lt;/code&gt;:&lt;/li&gt;
&lt;/ul&gt;

&lt;pre&gt;
       hosts=(${${${${(f)"$(&lt;$HOME/.ssh/known_hosts)"}:#[0-9]*}%%\*}%%,*})
       zstyle ':completion:*:hosts' hosts $hosts
&lt;/pre&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Remote filename completion over ssh, which works wonderfully with public key auth, remote host completion, and the ssh &lt;code&gt;ControlMaster&lt;/code&gt; tip below.  This is enabled by default; an example use is below, with the bold characters written by tab presses rather than by my keyboard directly:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;% scp foo.html pr&lt;b&gt;intf.net:&lt;/b&gt;pub&lt;b&gt;lic_html/&lt;/b&gt;ind&lt;b&gt;ex.html&lt;/b&gt;&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Colour matches in &lt;code&gt;grep&lt;/code&gt; results (in green):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;export GREP_COLOR='01;32'
alias grep='grep --color'
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;pushd&lt;/code&gt;:  Few people seem to use directory stacks in their shell.  After enabling &lt;code&gt;auto_pushd&lt;/code&gt; as below, you can quickly &lt;code&gt;popd&lt;/code&gt; back to the last directory you were in (and &lt;code&gt;popd&lt;/code&gt; again for the directory before that, etc), or use &lt;code&gt;dirs&lt;/code&gt; to see the stack of past directories that you can &lt;code&gt;cd&lt;/code&gt; to using &lt;code&gt;cd ~n&lt;/code&gt;, where &lt;code&gt;n&lt;/code&gt; is the number given for that directory.  To enable:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;setopt auto_pushd
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The &lt;code&gt;&amp;lt;()&lt;/code&gt; construct lets you avoid having to use temporary files as arguments to commands, like so:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;diff -y &amp;lt;(wc -l 1/*) &amp;lt;(wc -l 2/*)
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;zsh's &lt;code&gt;cd&lt;/code&gt; has a useful three-argument syntax where the third argument is treated as a replacement for the portion of the current directory given in the second argument:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;~/dir % ls
foo1  foo2  foo3  foo4  foo5  foo6
~/dir % cd foo5
~/dir/foo5 % cd 5 6
~/dir/foo6 %
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;ssh:&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;By default, modern ssh hashes the &lt;code&gt;known_hosts&lt;/code&gt; file so that someone who hacks access to your account doesn't have a list of where they might be able to go next.  This is sensible, but breaks the hostname completion above, so I turn it off in &lt;code&gt;~/.ssh/config&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;HashKnownHosts no
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;New (4.0+) versions of OpenSSH have support for multiplexing several shells over a single ssh connection; this means that the &lt;em&gt;second&lt;/em&gt; time you type &lt;code&gt;ssh host&lt;/code&gt;, the first (already established) connection is used and told to spawn a new shell, making your new shell appear immediately instead of in a few seconds.  This cuts login time for a new shell from 1.891s to 0.267s on my work machine.  It also speeds up anything that uses a single ssh session per file such as bash/zsh remote filename completion (see above), or rsync/darcs/svn/etc over ssh.  To enable, in &lt;code&gt;~/.ssh/config&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ControlMaster auto
ControlPath /tmp/%r@%h:%p
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
    &lt;p&gt;I have a few annoyances with ControlMaster &amp;#8212; let me know if you know of a clean way to have the first connection for each host be created as a background process without a tty so that it can't easily be killed by accident.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;emacs:&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;I use &lt;a href="http://www.gnu.org/software/tramp/"&gt;tramp&lt;/a&gt; to edit files remotely &amp;#8212; this has the same host and filename completion as zsh, and is insanely useful for me; some of the machines I use at work are an ssh tunnel away (meaning high latency) and don't have emacs or vim installed (only vi, meaning no syntax highlighting).  Setting up tramp is easy:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(require 'tramp)
C-x C-f /somehost:some/dir/and/file RET
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I use &lt;a href="http://gnus.org/"&gt;gnus&lt;/a&gt; (see also &lt;a href="http://my.gnus.org/"&gt;my.gnus.org&lt;/a&gt;) for mail, news and RSS reading, and think it's the best mailer ever.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I use &lt;a href="http://www.emacswiki.org/cgi-bin/wiki/EmacsIRCClient"&gt;ERC&lt;/a&gt; as an IRC client.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;br&gt;My &lt;a href="http://www.inference.phy.cam.ac.uk/cjb/dotfiles/"&gt;dotfiles&lt;/a&gt; are available online.&lt;/p&gt;</description>
      <pubDate>Tue, 21 Mar 2006 23:12:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:301f652c-7738-4a11-929d-8608e94df8c1</guid>
      <author>Chris Ball</author>
      <link>http://blog.printf.net/articles/2006/03/21/productivity</link>
      <category>emacs</category>
      <trackback:ping>http://blog.printf.net/articles/trackback/3</trackback:ping>
    </item>
    <item>
      <title>"Productivity" by &#31243;&#25511;&#20132;&#25442;&#26426;</title>
      <description>&lt;p&gt;I wouldn't want to need to mount them all beforehand.&lt;/p&gt;</description>
      <pubDate>Fri, 11 May 2007 06:55:50 +0100</pubDate>
      <guid isPermaLink="false">urn:uuid:8ab843ec-7f47-4fb7-92e3-80c7a622e461</guid>
      <link>http://blog.printf.net/articles/2006/03/21/productivity#comment-213</link>
    </item>
    <item>
      <title>"Productivity" by Shae Erisson</title>
      <description>&lt;p&gt;Assuming you use something like ControlPath /tmp/ssh-%h-%p-%r
in your ssh_config, you could have a shell script that wraps the ssh command and peels the hostname out and checks for that file in /tmp before running ssh -fN
I couldn't figure out how to do this with five minutes of hacking though.&lt;/p&gt;</description>
      <pubDate>Thu, 25 May 2006 13:42:48 +0100</pubDate>
      <guid isPermaLink="false">urn:uuid:7b020b4e-6034-4396-bf36-fbf9c88f7715</guid>
      <link>http://blog.printf.net/articles/2006/03/21/productivity#comment-57</link>
    </item>
    <item>
      <title>"Productivity" by Chris</title>
      <description>&lt;a href="http://ajaxxx.livejournal.com/" rel="nofollow"&gt;Adam Jackson&lt;/a&gt; tells me that &lt;code&gt;ssh -fN server &amp;&amp; ssh server&lt;/code&gt; always works &amp;mdash; the -fN has no side effects if a ControlMaster is already present, and starts a master up in the background if it isn't.

The ssh -fN takes about 350ms to return for me, since it does make a connection to the remote machine before returning, so a script that works out whether a master is running without needing to go over the network would be better.</description>
      <pubDate>Wed, 12 Apr 2006 19:29:27 +0100</pubDate>
      <guid isPermaLink="false">urn:uuid:52fb8e7f-8325-41d0-9bfd-6d8dc1d4d820</guid>
      <link>http://blog.printf.net/articles/2006/03/21/productivity#comment-24</link>
    </item>
    <item>
      <title>"Productivity" by Chris</title>
      <description>Thanks for letting me know.  Do you have to establish the mount outside of emacs first?  I'll think about it, but we have a large number of machines at work that I tramp to, I wouldn't want to need to mount them all beforehand.</description>
      <pubDate>Mon, 03 Apr 2006 21:54:41 +0100</pubDate>
      <guid isPermaLink="false">urn:uuid:1e8c49d4-89ad-4a6e-912c-29fef406c71a</guid>
      <link>http://blog.printf.net/articles/2006/03/21/productivity#comment-22</link>
    </item>
    <item>
      <title>"Productivity" by Phil</title>
      <description>I've started using sshfs rather than tramp, and it is a whole lot faster and more convenient.</description>
      <pubDate>Mon, 03 Apr 2006 21:47:39 +0100</pubDate>
      <guid isPermaLink="false">urn:uuid:71bf4b0d-b1d0-4fe4-9f7c-642a3b76d586</guid>
      <link>http://blog.printf.net/articles/2006/03/21/productivity#comment-21</link>
    </item>
    <item>
      <title>"Productivity" by Senji</title>
      <description>&lt;p&gt;hosts=(${${${${(f)"$(&amp;hellip;&lt;/p&gt;
&lt;p&gt;Now &lt;em&gt;that's&lt;/em&gt; ugly.&lt;/p&gt;</description>
      <pubDate>Thu, 23 Mar 2006 10:17:13 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:b8f4890d-7b3a-45f8-9e6c-9d494ec8ea48</guid>
      <link>http://blog.printf.net/articles/2006/03/21/productivity#comment-11</link>
    </item>
    <item>
      <title>"Productivity" by Dean</title>
      <description>Hi, I think you've got an open pre tag somewhere in your post. Posts made before yours are showing up as if 'preformatted' in various planets.</description>
      <pubDate>Wed, 22 Mar 2006 08:47:58 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:9f690731-c5e9-4f29-a40f-2c492fbe0bb6</guid>
      <link>http://blog.printf.net/articles/2006/03/21/productivity#comment-8</link>
    </item>
  </channel>
</rss>
