[ andrewho dot co dot uk ]

Patching GNU screen on Mac OS X for vertical split

The ability in GNU screen to vertically split a display so that two windows are visible side-by-side (which is what GNU screen means by “vertical split”) is not available in the latest stable release (4.0.3). It is, however, available in the latest HEAD slated for screen 4.1. Various distributions such as debian have merged the upstream changes into their stable versions; Mac OS X (10.7) is not one of them. Here’s how to compile it in.

First, clone the latest HEAD (450e8f38 at the moment):

% git clone git://git.savannah.gnu.org/screen.git ./screen.git
% cd ./screen.git/src
% ./autogen.sh

Then apply all of Apple’s patches to make it 10.7-friendly. Some of the patches will need to be manually applied as HEAD has diverged a bit from 4.0.3:

% for x in Makefile.in config.h.in configure process.c pty.c screen.c \
> window.c; do
%   curl "http://www.opensource.apple.com/source/screen/screen-16/patches/${x}.diff?txt" \
>   | patch -p0
% done

Finally, there’s one header file that needs to be included:

% curl -O http://launchd.macosforge.org/trac/export/23964/trunk/launchd/src/vproc_priv.h

Then compile the source and you’re done:

% ./configure --prefix=/usr/local
% make
% sudo make install

Clean URLs on jekyll/Apache

I use a static site generator, specifically jekyll, to transform some templates into a set of static *.html files. However, I like to keep the URLs looking clean, and not display the .html extension both because I think it looks better and also so that the URLs purely reflect the content and not the underlying files or CMS used to serve that content. In short, whilst the file being served might be $DOCUMENT_ROOT/weblog/title.html, the canonical URL for that resource should be /weblog/title. Here’s how I do that in .htaccess.

The first step is to turn on mod_rewrite:

RewriteEngine On

Create 404.html and let .htaccess know about it:

ErrorDocument 404 /404.html

All resources should be accessed via the main domain name, not a subdomain:

RewriteCond %{HTTP_HOST} ^[^\.]+\.andrewho\.co\.uk$ [NC]
RewriteRule ^(.*)$ http://andrewho.co.uk/$1 [R=301,L]

Remove trailing slashes (note that mod_dir fiddles around with them so disable that behaviour here too):

RewriteRule ^(.+)/$ http://%{HTTP_HOST}/$1 [R=301,]
Options -Indexes
DirectorySlash Off

Hide the *.html files by redirecting all requests for foo.html to foo:

RewriteCond %{THE_REQUEST} ^(GET|HEAD)\ /.+\.html\ HTTP
RewriteRule ^(.+)\.html$ http://%{HTTP_HOST}/$1 [R=301,L]

If the client requests /foo but that doesn’t exist, then try /foo.html:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME}.html -f
RewriteRule ^.+$ %{REQUEST_FILENAME}.html [L]

Throw that all into .htaccess (in that order) and you should have clean URLs.

vim-pathogen with mutt and git

For a long time I’ve used vim as my editor for both composing messages in mutt and commit messages for git. I do this with the following line in my ~/.muttrc (and a similar one in my ~/.gitconfig:

set editor = "vim -c 'set wrap tw=76 fo=toqwal12 nonumber spell' +1"

Recently I refactored my vim configuration files using Tim Pope’s excellent pathogen script. Doing so required me to place the following lines in my ~/.vimrc to load all plugins from ~/.vim/bundle:

call pathogen#runtime_append_all_bundles()
call pathogen#helptags()

However, on debian filetype detection is turned on by default which causes problems with pathogen. The fix is to turn it off before calling pathogen:

filetype off
call pathogen#runtime_append_all_bundles()
call pathogen#helptags()
filetype plugin indent on

This produces another problem, however. For some unknown reason, filetype off causes vim to exit with a non-zero exit code on Mac OS X. When used with mutt, this throws up an ugly warning after editing a message. Git flat out refuses to acknowledge a commit message in this case. The solution is to turn it on then off again:

filetype on
filetype off
call pathogen#runtime_append_all_bundles()
call pathogen#helptags()
filetype plugin indent on

This vim configuration will work on both debian-based and Mac OS X systems.

Deploying jekyll (on a Joyent Shared Accelerator)

This website is based on jekyll (a static site generator). I store the text files for jekyll in a git repository. Here is how I setup automatic deployment of this website. Whilst a lot of this post is generally applicable, some of it (specifically the installation section) is only of relevance if, like me, you are hosted on a Joyent Shared Accelerator.

Before we get started, just note that the git repository storing my website is a bare one in ~/git/design/andrewho.co.uk.git. I’ll assume you’re happy creating such a repository and pushing to it.

So the first step is to install rubygems 1.3.7, as this is needed for liquid (on cooper, at least, 1.3.5 is the installed version). Everything is done in ~/local.

% mkdir -p ~/local/src && cd ~/local/src
% curl -O http://production.cf.rubygems.org/rubygems/rubygems-1.3.7.tgz
% tar xzf rubygems-1.3.7.tgz
% cd rubygems-1.3.7
% ruby setup.rb --prefix=/users/home/andrewlkho/local

I like to symlink gem to gem18:

% cd ~/local/bin
% ln -s gem gem18

Next, we need to make sure that the gem command finds our new libraries and that gems are installed in the correct place. So create ~/.gemrc with the following (replacing as appropriate):

gemhome: /users/home/andrewlkho/local/gems
gempath:
- /users/home/andrewlkho/local/gems
- /usr/local/lib/ruby/gems/1.8

Place the following (or an equivalent syntax) in your shell’s startup file (~/.zshrc for me), and then source it:

export GEM_HOME=/users/home/andrewlkho/local/gems
export GEM_PATH=/users/home/andrewlkho/local/gems:/usr/local/lib/ruby/gems/1.8
export RUBYLIB=/users/home/andrewlkho/local/lib
export PATH="/users/home/andrewlkho/local/bin:/users/home/andrewlkho/local/gems/bin:${PATH}"

The RUBYLIB variable is needed otherwise even your local version of gem will still pick up system-wide libraries and report itself as version 1.3.5.

The final installation is jekyll itself:

% gem install jekyll

So that jekyll would deploy automatically, I put in a post-receive hook. Here’s the script I use (you can grab a copy here):

#!/bin/sh

REPO=/users/home/andrewlkho/git/design/andrewho.co.uk.git
PUBLIC=/users/home/andrewlkho/web/public

GEM_HOME=/users/home/andrewlkho/local/gems
GEM_PATH=/users/home/andrewlkho/local/gems:/usr/local/lib/ruby/gems/1.8
RUBYLIB="/users/home/andrewlkho/local/lib:${RUBYLIB}"
PATH="/users/home/andrewlkho/local/bin:/users/home/andrewlkho/local/gems/bin:${PATH}"

# It took a while to discover this non-intuitive requirement:
export GEM_HOME GEM_PATH RUBYLIB

while read OLDREV NEWREV REFNAME; do
    if [ ${REFNAME} = "refs/heads/master" ]; then
        MASTER_UPDATED=1
    fi
done

if [ ${MASTER_UPDATED} ]; then
    # Setup a temporary staging directory
    COMMITID=`cat ${REPO}/refs/heads/master`
    TMP=/users/home/andrewlkho/tmp
    STAGING="${TMP}/${COMMITID}"
    mkdir -p ${STAGING}

    # Grab a copy of master's HEAD
    git archive --format=tar refs/heads/master | gtar -C ${STAGING} -x -f -

    # Generate the site with jekyll
    cd ${STAGING}
    jekyll > /dev/null

    # Copy it over to the public directory
    rsync -aqz --delete ${STAGING}/_site/ ${PUBLIC}

    # Clean up
    cd
    rm -rf ${STAGING}
fi

Place it as your equivalent of ~/git/design/andrewho.co.uk.git/hooks/post-receive and set it as executable with chmod +x. You should read through the whole script, though, as you’ll want to change a lot of the paths (unless you have an eerily similar setup to me). Note that the script will only deploy when the master branch is pushed to. This means that you can whatever branch setup you want (drafts, develop etc) but not have all of your changes immediately deployed.

That’s it! You should now have automatic deployment of your website setup.

Instagram and a multitude of Cassie photos

I have recently discovered Instagram and its corresponding iPhone app. It’s a fun and easy way to share photos with a slew of preset filters for various retro film looks. I have to admit, I’ve been rather guilty of applying the filters just to make my photos a bit more interesting. Furthermore, having returned to my parents’ house for a bit over the Christmas period I’ve rediscovered the fun of taking a prolific number of photos of Cassie.

Here’s one that I took recently. Cassie is enjoying a plastic sheet that was covering my bed whilst I was away.

Cassie enjoying a plastic sheet