<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
<title>Mark Aufflick's Weblog</title>
<link>http://mark.aufflick.com/blog/</link>
<description>Mark Aufflick's Weblog</description>
<generator>OpenACS 5.0</generator>
<lastBuildDate>Mon, 20 Jan 2014 05:30:15 GMT</lastBuildDate>
<image>
<title>Mark Aufflick's Weblog</title>
<url>http://mark.aufflick.com/rss-support/images/openacs_logo_rss.gif</url>
<link>http://mark.aufflick.com/blog/</link>
<width>126</width>
<height>48</height>
</image>
<item>
<title>Load Interface Inspector's framework without modifying your Xcode project</title>
<link>http://mark.aufflick.com/blog/2014/01/20/load-interface-inspector-s-framework-without-modifying-your-xcode-project</link>
<guid isPermaLink="true">http://mark.aufflick.com/blog/2014/01/20/load-interface-inspector-s-framework-without-modifying-your-xcode-project</guid>
<description>&lt;p&gt;Along the lines of Oliver Jones'�� &lt;a href=&quot;http://blog.ittybittyapps.com/blog/2013/11/07/integrating-reveal-without-modifying-your-xcode-project/&quot;&gt;great tip&lt;/a&gt; about loading Reveal App'��s* library into your iOS app without restarting the app or modifying your Xcode project, loading Interface Inspector'��s** library into your Mac app at runtime is even easier thanks to Framework Bundles***. Simply add this into your .lldbinit:&lt;/p&gt;
&lt;blockquote&gt;
&lt;pre&gt;command alias interface_inspector p (BOOL)[[NSBundle bundleWithPath:@&quot;/Applications/Interface Inspector.app/Contents/Resources/InterfaceInspectorRemote.framework&quot;] load]&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;p&gt;and now at your lldb prompt just type &quot;��interface_inspector&quot; (or some unique part of that followed by tab) and then continue and you'��ll be up and running.&lt;/p&gt;
&lt;p&gt;* If you'��ve been living in a cave you may not know about &lt;a href=&quot;http://revealapp.com/&quot;&gt;Reveal&lt;/a&gt; - the best thing for iOS developers since iOS 2.0.&lt;/p&gt;
&lt;p&gt;** &lt;a href=&quot;http://www.interface-inspector.com/&quot;&gt;Interface Inspector&lt;/a&gt; is like Reveal for Mac apps (except not as good of course! No complaints about Interface Inspector, but you have to back your friends ;)&lt;/p&gt;
&lt;p&gt;*** If you're thinking &quot;��why can't it be this easy on iOS?&quot; - read Landon Fuller's excellent post:�&lt;a href=&quot;http://landonf.bikemonkey.org/2014/01/index.html&quot;&gt;iOS Static Libraries Are, Like, Really Bad, And Stuff (Radar 15800975)&lt;/a&gt; and dupe his radar :)&lt;/p&gt;</description>
<pubDate>Mon, 20 Jan 2014 05:30:15 GMT</pubDate>
</item>
<item>
<title>GNUstep bleeding edge</title>
<link>http://mark.aufflick.com/blog/2013/05/29/gnustep-bleeding-edge</link>
<guid isPermaLink="true">http://mark.aufflick.com/blog/2013/05/29/gnustep-bleeding-edge</guid>
<description>&lt;p&gt;For a client project I'm looking into Mac/Linux GUI cross platform options. Naturally GNUstep is high on my list. It's been a while (maybe 10 years) since I even played with GNUstep and I've struggled a bit getting all the latest things to compile together. So, like everyone else, I'm putting together a guide for how I did it since none of the other guides seem to be up to date (and I'm sure mine will be out of date shortly too!)&lt;/p&gt;
&lt;p&gt;I'm installing on Ubuntu 12.04, but other Linux platforms will be very similar - just the dependencies might be different.&lt;/p&gt;
&lt;p&gt;So firstly about those package dependencies. I've done so many apt-get installs that I've lost track exactly what I needed. Something a bit like this:&lt;/p&gt;
&lt;blockquote&gt;sudo aptitude install build-essential git subversion ninja cmake libffi-dev libxml2-dev libgnutls-dev libicu-dev libblocksruntime-dev libkqueue-dev libpthread-workqueue-dev autoconf libtool&lt;/blockquote&gt;
&lt;p&gt;Make sure you've uninstalled any older clang or libobjc libraries (otherwise you'll need to be very careful with configure args etc. to specify our compiled versions) and also any older version of libdispatch&lt;/p&gt;
&lt;p&gt;Firstly we want the trunk version of llvm/clang. Grit your teeth, because we're going to have to use subversion:&lt;/p&gt;
&lt;blockquote&gt;cd&lt;br /&gt;mkdir -p src/gnustep&lt;br /&gt; cd src/gnustep&lt;br /&gt;svn co http://llvm.org/svn/llvm-project/llvm/trunk llvm&lt;br /&gt; cd llvm/tools&lt;br /&gt; svn co http://llvm.org/svn/llvm-project/cfe/trunk clang&lt;br /&gt;cd ..&lt;br /&gt; mkdir build&lt;br /&gt; cd build&lt;br /&gt; cmake ..&lt;br /&gt; make -j4&lt;/blockquote&gt;
&lt;p&gt;Now add the following to your .bashrc etc:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;export PATH=$PATH:~/src/gnustep/llvm/build/bin&lt;br /&gt;export CC=clang&lt;br /&gt;export CXX=clang++&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Now reload your bashrc:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;. ~/.bashrc&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Check you can find clang:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;which clang&lt;br /&gt; clang -v&lt;br /&gt; clang++ 0v&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Now we want the latest gnustep libobjc2 with all the latest modern runtime goodies:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;cd ~/src/gnustep&lt;br /&gt;git clone https://github.com/gnustep/gnustep-libobjc2.git&lt;br /&gt;cd gnustep-libobjc2&lt;br /&gt;mkdir build&lt;br /&gt; cd build&lt;br /&gt;cmake ..&lt;br /&gt;make -j4&lt;br /&gt;sudo -E make install&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Now add the following to your .bashrc:&lt;/p&gt;
&lt;p&gt;export OBJCFLAGS=&quot;-fblocks -fobjc-runtime=gnustep&quot;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;cd ~/src/gnustep&lt;br /&gt;git clone https://github.com/gnustep/gnustep-make.git&lt;br /&gt;cd gnustep-make&lt;br /&gt;./configure --enable-debug-by-default --with-layout=gnustep --enable-objc-nonfragile-abi&lt;br /&gt;make&lt;br /&gt; sudo -E make install&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Now add the following to your .bashrc:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;. /usr/GNUstep/System/Library/Makefiles/GNUstep.sh&lt;br /&gt;. ~/.bashrc&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Now we can start installing gnustep itself:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;cd ~/src/gnustep&lt;br /&gt; git clone https://github.com/gnustep/gnustep-base.git&lt;br /&gt; cd gnustep-base&lt;br /&gt; ./configure&lt;br /&gt; make -j4&lt;br /&gt; sudo -E make install&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If you get warnings about blocks during make, check that you don't have old libobjc libraries on your system. You can specify a particular libobjc library version when you build the gnustep-make package, but easier to just uninstall them.&lt;/p&gt;
&lt;p&gt;Now lets run some tests.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;make check&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The gnustep-base check tests are very handy for making sure you have all the latest things. Warnings you should look out for are things like you haven't enabled blocks or subscripting. If you get warnings like that you should check your OBJCFLAGS etc. At this point I get no failures or skips:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;7913 Passed tests 21 Dashed hopes&lt;br /&gt;&lt;br /&gt;All OK!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Now we want the latest lib dispatch for all our GCD goodness:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;cd ~/src/gnustep git clone git://github.com/nickhutchinson/libdispatch.git&lt;br /&gt; cd libdispatch&lt;br /&gt; sh autogen.sh&lt;br /&gt; ./configure CFLAGS=&quot;-I/usr/include/kqueue&quot; LDFLAGS=&quot;-lkqueue -lpthread_workqueue -pthread -lm&quot;&lt;br /&gt; make clean make -j4&lt;br /&gt;sudo -E make install sudo ldconfig&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Now we can compile some test code from this post (http://lists.gnu.org/archive/html/discuss-gnustep/2012-12/msg00036.html) which I have pasted into a gist: &lt;a href=&quot;https://gist.github.com/aufflick/5674798&quot;&gt;https://gist.github.com/aufflick/5674798&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;clang `gnustep-config --objc-flags` `gnustep-config --objc-libs` -lobjc blocktest.m&lt;br /&gt; ./a.out&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;clang `gnustep-config --objc-flags` `gnustep-config --objc-libs` -lobjc -ldispatch -lgnustep-base Fraction.m helloGCD_objc.m&lt;br /&gt; ./a.out&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;And there we are! Ready to install the other gnustep-* modules from github.&lt;/p&gt;</description>
<pubDate>Wed, 29 May 2013 20:10:47 GMT</pubDate>
</item>
<item>
<title>AQXMLParser + OAuth</title>
<link>http://mark.aufflick.com/blog/2012/08/02/aqxmlparser-oauth</link>
<guid isPermaLink="true">http://mark.aufflick.com/blog/2012/08/02/aqxmlparser-oauth</guid>
<description>&lt;p&gt;I've been enjoying using Jim Dovey's excellent AQXMLParser lately, and in fact am giving a talk on it tonight at Sydney CocoaHeads. To use it in a new project, I need to be able to authorise the outbound REST request with some OAuth 1 tokens etc.&lt;/p&gt;
&lt;p&gt;OAuth can be a right pain, and the Cocoa implementations aren't awesome. gtm-oauth (the OAuth 1 library from the Google Toolbox for Mac) is a little odd in its implementation, but doing your own OAuth implementation would be so tedious it's one of the better options out there.&lt;/p&gt;
&lt;p&gt;It's all pretty easy. Firstly, use gtm-oauth like normal to have your user authorise your app and receive a token.&lt;/p&gt;
&lt;p&gt;Next, to make a request, gtm-oauth provides a way to authorise an NSMutableURLRequest, but AQXMLParser uses it's own HTTPMessage class (which wraps the lower level CFHTTPMessage from Core Foundation).&lt;/p&gt;
&lt;p&gt;What I have done is extend HTTPMessage to provide a copy of itself as an NSURLRequest, and then write a category that auths that with gtm-oauth and then cribs the headers from that and applies them to the HTTPMessage. It's a little roundabout, but because of the need to sign the whole request and the way that gtm-oauth internals work, anything else would be very complicated. So in use, it looks like this:&lt;/p&gt;
&lt;blockquote&gt;&lt;tt&gt;
&lt;p&gt;#import &quot;HTTPMessage+GTMOAuth.h&quot;&lt;/p&gt;
&lt;p&gt;...&lt;/p&gt;
&lt;p&gt;GTMOAuthAuthentication * oauth = ...; // &lt;a href=&quot;http://code.google.com/p/gtm-oauth/wiki/GTMOAuthIntroduction&quot;&gt;setup gtm-oauth like normal&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;HTTPMessage * myMessage = ...; // &lt;a href=&quot;http://quatermain.tumblr.com/parser-example&quot;&gt;create the http request like normal&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[myMessage authorizeWithGTMOAuth:oauth];&lt;/p&gt;
&lt;p&gt;// now create the parser and use the http message etc. like normal&lt;/p&gt;
&lt;/tt&gt;&lt;/blockquote&gt;
&lt;p&gt;For now the changes and category are only in my fork, but I have a &lt;a href=&quot;https://github.com/AlanQuatermain/aqtoolkit/pull/15&quot;&gt;pending pull request&lt;/a&gt; with Jim that I will work out the best way to incorporate them into his master repository. My fork also contains tweaks to work with the latest llvm and ARC (although note neither gtm-oauth nor HTTPMessage or AQXMLParser use ARC, so you'll have to add the -fno-objc-arc compiler flag where appropriate).&lt;/p&gt;
&lt;p&gt;gtm-outh:�&lt;a href=&quot;http://code.google.com/p/gtm-oauth/&quot;&gt;http://code.google.com/p/gtm-oauth/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;My fork of aqtoolkit:�&lt;a href=&quot;https://github.com/aufflick/aqtoolkit&quot;&gt;https://github.com/aufflick/aqtoolkit&lt;/a&gt;&lt;/p&gt;</description>
<pubDate>Thu, 02 Aug 2012 02:25:20 GMT</pubDate>
</item>
<item>
<title>supervisord supervisorctl cheat sheet</title>
<link>http://mark.aufflick.com/blog/2012/03/25/supervisord-supervisorctl-cheat-sheet</link>
<guid isPermaLink="true">http://mark.aufflick.com/blog/2012/03/25/supervisord-supervisorctl-cheat-sheet</guid>
<description>&lt;p&gt;On my new server I made the switch from daemontools to supervisor. As if to make daemontools users feel at home the documentation for supervisorctl use is a bit thin :)&lt;br /&gt;So far my biggest gotcha was that after adding a new .conf file in your includes (or to the main file itself, but you wouldn't do that would you?) is that you need to do *both* of the following:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;gt; &lt;strong&gt;supervisorctl reread&lt;/strong&gt;&lt;br&gt;
new.app.conf: available&lt;br&gt;
&amp;gt; &lt;strong&gt;supervisorctl update&lt;/strong&gt;&lt;br&gt;
new.app.conf: added process group&lt;br&gt;
&amp;gt; &lt;strong&gt;supervisorctl&lt;/strong&gt;&lt;br&gt;
new.app � � � � RUNNING ...
&lt;/blockquote&gt;
&lt;p&gt;�&lt;/p&gt;

&lt;h3&gt;haproxy&lt;/h3&gt;
&lt;p&gt;Unfortunately supervisor doesn't offer a way to provide a custom restart command, so doing an uninterrupted haproxy restart via supervisor isn't possible. Instead make sure you have autorestart set to unexpected (the default) rather than true (which is what I usually do) - that way if you want a clean haproxy restart you can just do it yourself at the commandline using the -sf option as normal.</description>
<pubDate>Sun, 25 Mar 2012 23:14:32 GMT</pubDate>
</item>
<item>
<title>SAPI Cocoa SDK</title>
<link>http://mark.aufflick.com/blog/2012/03/24/sapi-cocoa-sdk</link>
<guid isPermaLink="true">http://mark.aufflick.com/blog/2012/03/24/sapi-cocoa-sdk</guid>
<description>The Cocoa Sensis SAPI SDK is live, ready for this weekend's Sensis SAPI hackathon. https://github.com/pumptheory/SAPI-Cocoa-SDK

&lt;img src=&quot;http://img.tweetimag.es/i/SensisAPI_b&quot; alt=&quot;SAPI Logo&quot; align=&quot;middle&quot;&gt; &lt;img src=&quot;http://developers.sensis.com.au/files/yp-api-poweredby-sticky-71x78.png&quot; alt=&quot;Yellow Pages Logo&quot; align=&quot;middle&quot;&gt;</description>
<pubDate>Sat, 24 Mar 2012 01:13:24 GMT</pubDate>
</item>
<item>
<title>Stunnel + Thin + Rails for the world's easiest ssl hosting</title>
<link>http://mark.aufflick.com/blog/2012/03/20/stunnel-thin-rails-for-the-world-s-easiest-ssl-hosting</link>
<guid isPermaLink="true">http://mark.aufflick.com/blog/2012/03/20/stunnel-thin-rails-for-the-world-s-easiest-ssl-hosting</guid>
<description>&lt;p&gt;These days I do most quick and dirty web stuff with Ruby on Rails, and any open source web stuff I install I prefer Rails based code for easy hacking.�Every so often you want to host something for internal or other small-volume usage, but it has to be SSL. Traditionally this is a pain in the backside, especially with Rails. Back in the day I did everything with &lt;a href=&quot;http://openacs.org&quot;&gt;OpenACS&lt;/a&gt; or plain &lt;a href=&quot;http://aolserver.com&quot;&gt;AOLServer&lt;/a&gt;. This meant I had to install a bunch of stuff by hand (although debian packages are now available), but once it was done it was a simple config tweak to change the number of threads and/or add ssl etc.�With Rails it's kind of the opposite. Getting things up and running is incredibly easy, but scaling it or adding ssl usually means�Apache, or Nginx, or some other (relatively) heavy server plus other stuff. Doing this all as a non-super user is even more painful.&lt;/p&gt;
&lt;p&gt;For a client I wanted to setup a &lt;a href=&quot;http://redmine.org&quot;&gt;Redmine&lt;/a&gt; instance for a wiki and browsing internal git repositories. It's a Rails 2.x app. Initial setup is easy. Using the latest trunk version of Redmine (which supports Ruby 1.9 and uses bundler) it's a simple matter of the following steps (which assume pretty much nothing is installed except base libraries like sqlite3):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;checking out the svn trunk&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote class=&quot;sourcebox&quot; style=&quot;border-left: 5px solid #ccc; margin-left: 45px; padding-left: 5px; color: #000000; background-color: #ffffff;&quot;&gt;
&lt;p&gt;svn co svn co http://redmine.rubyforge.org/svn/trunk redmine&lt;br /&gt;cd�redmine&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;installing &lt;a href=&quot;http://beginrescueend.com&quot;&gt;rvm&lt;/a&gt;,�setting up the right ruby &amp;amp; gem set&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote class=&quot;sourcebox&quot; style=&quot;border-left: 5px solid #ccc; margin-left: 45px; padding-left: 5px; color: #000000; background-color: #ffffff;&quot;&gt;
&lt;p&gt;bash &lt;span style=&quot;color: #ff0000;&quot;&gt;-s&lt;/span&gt; stable &amp;lt; &amp;lt;(curl &lt;span style=&quot;color: #ff0000;&quot;&gt;-s&lt;/span&gt; https://raw.github.com/wayneeseguin/rvm/master/binscripts/rvm-installer)&lt;br /&gt;. ~/.bashrc&lt;br /&gt;rvm install ruby-1.9.3&lt;br /&gt;rvm use ruby-1.9.3@redmine &lt;span style=&quot;color: #ff0000;&quot;&gt;--create&lt;/span&gt;&lt;br /&gt;rvm install bundler&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;installing bundler and using it to prepare all the ruby gems (I am using sqlite and don't have mysql libraries installed)&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote class=&quot;sourcebox&quot; style=&quot;border-left: 5px solid #ccc; margin-left: 45px; padding-left: 5px; color: #000000; background-color: #ffffff;&quot;&gt;
&lt;p&gt;gem install bundler&lt;br /&gt;bundle install &lt;span style=&quot;color: #ff0000;&quot;&gt;--without=mysql&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;follow the main redmine installation steps from step 3, but make the database adapter sqlite3 and the database db/production.sqlite&lt;br /&gt;&lt;a href=&quot;http://www.redmine.org/projects/redmine/wiki/RedmineInstall&quot;&gt;http://www.redmine.org/projects/redmine/wiki/RedmineInstall&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You now have Redmine up and running, via the test webrick server, on port 3000. But that's no good for two reasons, one we obviously don't have ssl, and two webrick is a single process (and ruby is always a single processor thread) so it's not very scalable.&lt;/p&gt;
&lt;p&gt;A nice simple, and yet fast, way to scale Ruby http servers is &lt;a href=&quot;http://code.macournoyer.com/thin/&quot;&gt;Thin&lt;/a&gt;. It's Ruby and C. It's only http though, so we need to put ssl in front some how. A great way of doing this is &lt;a href=&quot;http://www.stunnel.org/&quot;&gt;stunnel&lt;/a&gt;, which can tunnel just about anything to anything when it comes to ssl. So we run a couple of Thin instances, and stunner to proxy it to ssl. The great thing is we can arrange for the communication between the two to be via Unix sockets so we don't even need to reserve localhost TCP ports so we can scale the number of instances without checking with anyone else.&lt;/p&gt;
&lt;p&gt;Here are my steps for Thin and stunnel:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Install Thin:&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote class=&quot;sourcebox&quot; style=&quot;border-left: 5px solid #ccc; margin-left: 45px; padding-left: 5px; color: #000000; background-color: #ffffff;&quot;&gt;
&lt;p&gt;gem install thin&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Install stunnel:&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote class=&quot;sourcebox&quot; style=&quot;border-left: 5px solid #ccc; margin-left: 45px; padding-left: 5px; color: #000000; background-color: #ffffff;&quot;&gt;
&lt;p&gt;# get the latest version of stunner from�&lt;a href=&quot;http://www.stunnel.org/?page=downloads&quot;&gt;http://www.stunnel.org/?page=downloads&lt;br /&gt;&lt;/a&gt;tar zxf stunnel-4.xx.tar.gz&lt;br /&gt;cd stunnel-4.xx&lt;br /&gt;mkdir ~/usr�&lt;br /&gt;./configure &lt;span style=&quot;color: #ff0000;&quot;&gt;--prefix=~/usr &lt;/span&gt;&lt;br /&gt;make&lt;br /&gt;make install&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;You need a .pem certificate for stunnel. If you don't have a real certificate, you can create a self-signed one like so:&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote class=&quot;sourcebox&quot; style=&quot;border-left: 5px solid #ccc; margin-left: 45px; padding-left: 5px; color: #000000; background-color: #ffffff;&quot;&gt;
&lt;p&gt;openssl req &lt;span style=&quot;color: #ff0000;&quot;&gt;-new -x509 -days &lt;/span&gt;365 &lt;span style=&quot;color: #ff0000;&quot;&gt;-nodes -config&lt;/span&gt; stunnel.cnf &lt;span style=&quot;color: #ff0000;&quot;&gt;-out&lt;/span&gt; stunnel.pem &lt;span style=&quot;color: #ff0000;&quot;&gt;-keyout &lt;/span&gt;my_stunnel.pem&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;where the stunnel.cnf file is in the source distribution. Answer the questions appropriately.&lt;/li&gt;
&lt;li&gt;stunnel needs a config file, something like this (in this case for three thin instances)&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote class=&quot;sourcebox&quot; style=&quot;border-left: 5px solid #ccc; margin-left: 45px; padding-left: 5px; color: #000000; background-color: #ffffff;&quot;&gt;
&lt;p style=&quot;margin: 0.0px 0.0px 0.0px 0.0px; font: 13.0px Monaco;&quot;&gt;&lt;span style=&quot;font-family: Monaco; font-size: 12px;&quot;&gt;&lt;span style=&quot;color: #a0532d;&quot;&gt;pid&lt;/span&gt; = &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Monaco; font-size: 12px;&quot;&gt; &lt;span style=&quot;color: #a0532d;&quot;&gt;cert&lt;/span&gt; = /path/to/my_stunnel.pem&lt;/span&gt;&lt;br /&gt; &lt;br /&gt;&lt;span style=&quot;font-family: Monaco; font-size: 12px;&quot;&gt; [&lt;span style=&quot;color: #208b22;&quot;&gt;redmine&lt;/span&gt;]&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Monaco; font-size: 12px;&quot;&gt; &lt;span style=&quot;color: #a0532d;&quot;&gt;accept&lt;/span&gt; = 12345&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #a0532d; font-family: Monaco; font-size: 12px;&quot;&gt; connect&lt;/span&gt; = /path/to/my_rails_app/tmp/thin.0.sock&lt;/p&gt;
&lt;p style=&quot;margin: 0.0px 0.0px 0.0px 0.0px; font: 13.0px Monaco;&quot;&gt;&lt;span style=&quot;color: #a0532d; font-family: Monaco; font-size: 12px;&quot;&gt;connect&lt;/span&gt; = /path/to/my_rails_app/tmp/thin.1.sock&lt;/p&gt;
&lt;p style=&quot;margin: 0.0px 0.0px 0.0px 0.0px; font: 13.0px Monaco;&quot;&gt;&lt;span style=&quot;color: #a0532d; font-family: Monaco; font-size: 12px;&quot;&gt;connect&lt;/span&gt; = /path/to/my_rails_app/tmp/thin.2.sock&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;start up stunnel&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote class=&quot;sourcebox&quot; style=&quot;border-left: 5px solid #ccc; margin-left: 45px; padding-left: 5px; color: #000000; background-color: #ffffff;&quot;&gt;
&lt;p&gt;~/usr/bin/stunnel /path/to/my/stunnel.conf&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style=&quot;line-height: 0px;&quot;&gt; start up your rails app with Thin&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote class=&quot;sourcebox&quot; style=&quot;border-left: 5px solid #ccc; margin-left: 45px; padding-left: 5px; color: #000000; background-color: #ffffff;&quot;&gt;
&lt;p&gt;thin start &lt;span style=&quot;color: #ff0000;&quot;&gt;-s3&lt;/span&gt; --socket /path/to/my_rails_app/tmp/thin.sock &lt;span style=&quot;color: #ff0000;&quot;&gt;-e&lt;/span&gt; production&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;And that's it, your site running on https port 12345! All this has not required root access at any point. If you want to listen on a low port, eg. 443, the only thing that needs to run as root is stunnel.&lt;/p&gt;
&lt;p&gt;But don't break out the champagne yet - we have a problem. Your rails app knows the hostname and port thanks to the Host: header, but it�has no idea that it's running behind stunnel and is therefore ssl. This is only a problem in the occasions where a full url is needed, and the primary case is for http redirect headers. I take care of this by rewriting the Location header in application_controller.rb:&lt;/p&gt;
&lt;blockquote class=&quot;sourcebox&quot; style=&quot;border-left: 5px solid #ccc; margin-left: 45px; padding-left: 5px; color: #000000; background-color: #ffffff;&quot;&gt;
&lt;pre style=&quot;margin: 0.0px 0.0px 13.0px 0.0px; font: 12.0px Monaco;&quot;&gt;after_filter &lt;span style=&quot;color: #008b8b;&quot;&gt;:force_https_for_redirects&lt;/span&gt;&lt;br /&gt; &lt;span style=&quot;color: #7f007f;&quot;&gt;def &lt;/span&gt; &lt;span style=&quot;color: #3800ff;&quot;&gt;force_https_for_redirects&lt;/span&gt;&lt;br /&gt; &lt;span style=&quot;color: #7f007f;&quot;&gt; if&lt;/span&gt; response.headers.has_key?(&lt;span style=&quot;color: #8b2252;&quot;&gt;&quot;Location&quot;&lt;/span&gt;)&lt;br /&gt; response.headers[&lt;span style=&quot;color: #8b2252;&quot;&gt;&quot;Location&quot;&lt;/span&gt;].sub!(&lt;span style=&quot;color: #8b2252;&quot;&gt;/^http:/&lt;/span&gt;, &lt;span style=&quot;color: #8b2252;&quot;&gt;'https:'&lt;/span&gt;)&lt;br /&gt; &lt;span style=&quot;color: #7f007f;&quot;&gt; end&lt;/span&gt;&lt;br /&gt; &lt;span style=&quot;color: #7f007f;&quot;&gt;end&lt;/span&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;p&gt;You may have other cases that need fixing, like constructing urls for emails. Note that I wouldn't recommend mucking about with the X-Forwarded-Proto patches for stunnel. I just don't trust third party patches for security software, and in any case I'm not sure it would work with using Unix sockets for the intermediary transport.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; Here's how to monkey patch ActionController::UrlWriter::url_for() so your emails will have correct links. In Rails 2 (in my case for redmine), I did it in environment.rb - for Rails 3 I think you could do it in application.rb, but it doesn't really matter where you do it as long as it gets compiled after ActionController::UrlWriter is loaded.&lt;/p&gt;
&lt;blockquote class=&quot;sourcebox&quot; style=&quot;border-left: 5px solid #ccc; margin-left: 45px; padding-left: 5px; color: #000000; background-color: #ffffff;&quot;&gt;
&lt;pre style=&quot;margin: 0.0px 0.0px 13.0px 0.0px; font: 12.0px Monaco;&quot;&gt;&lt;span style=&quot;color: #7e297f;&quot;&gt;module &lt;/span&gt; &lt;span style=&quot;color: #228b23;&quot;&gt;ActionController&lt;/span&gt;&lt;br /&gt;  &lt;span style=&quot;color: #7e297f;&quot;&gt; module &lt;/span&gt; &lt;span style=&quot;color: #228b23;&quot;&gt;UrlWriter&lt;/span&gt;&lt;br /&gt;    &lt;span style=&quot;color: #7e297f;&quot;&gt; alias &lt;/span&gt; &lt;span style=&quot;color: #038b8b;&quot;&gt;:original_url_for&lt;/span&gt; &lt;span style=&quot;color: #038b8b;&quot;&gt;:url_for&lt;/span&gt;&lt;br /&gt;    &lt;span style=&quot;color: #7e297f;&quot;&gt; def &lt;/span&gt; &lt;span style=&quot;color: #353ff9;&quot;&gt;url_for&lt;/span&gt;(options = {})&lt;br /&gt;      options[&lt;span style=&quot;color: #038b8b;&quot;&gt;:host&lt;/span&gt;] = &lt;span style=&quot;color: #8a2452;&quot;&gt;'efserv.com'&lt;/span&gt; &lt;span style=&quot;color: #7e297f;&quot;&gt;unless&lt;/span&gt; options[&lt;span style=&quot;color: #038b8b;&quot;&gt;:host&lt;/span&gt;]&lt;br /&gt;      options[&lt;span style=&quot;color: #038b8b;&quot;&gt;:protocol&lt;/span&gt;] = &lt;span style=&quot;color: #8a2452;&quot;&gt;'https'&lt;/span&gt; &lt;span style=&quot;color: #7e297f;&quot;&gt; unless&lt;/span&gt; options[&lt;span style=&quot;color: #038b8b;&quot;&gt;:protocol&lt;/span&gt;]&lt;br /&gt;      options[&lt;span style=&quot;color: #038b8b;&quot;&gt;:port&lt;/span&gt;] = 7022 &lt;span style=&quot;color: #7e297f;&quot;&gt; unless&lt;/span&gt; options[&lt;span style=&quot;color: #038b8b;&quot;&gt;:port&lt;/span&gt;]&lt;br /&gt; &lt;br /&gt;      original_url_for(options)&lt;br /&gt;    &lt;span style=&quot;color: #7e297f;&quot;&gt; end&lt;/span&gt;&lt;br /&gt;  &lt;span style=&quot;color: #7e297f;&quot;&gt; end&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #7e297f;&quot;&gt;end&lt;/span&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Another update:&lt;/strong&gt; There's another patch you need to make in the redmine code itself, in app/controllers/application_controller.rb, make the following change to the require_login method, adding in the&lt;strong&gt; :protocol =&amp;gt; 'https://'. &lt;/strong&gt;This is required since it doesn't use url_for to generate the redirect url.&lt;/p&gt;
&lt;blockquote class=&quot;sourcebox&quot; style=&quot;border-left: 5px solid #ccc; margin-left: 45px; padding-left: 5px; color: #000000; background-color: #ffffff;&quot;&gt;
&lt;pre style=&quot;margin: 0.0px 0.0px 13.0px 0.0px; font: 12.0px Monaco;&quot;&gt;respond_to do |format|
  � format.html { redirect_to &lt;strong&gt;:protocol =&amp;gt; 'https://',&lt;/strong&gt; :controller =&amp;gt; &quot;account&quot;, :action =&amp;gt; &quot;login&quot;, :back_url =&amp;gt; url }
  � format.atom { redirect_to &lt;strong&gt;:protocol =&amp;gt; 'https://',&lt;/strong&gt; :controller =&amp;gt; &quot;account&quot;, :action =&amp;gt; &quot;login&quot;, :back_url =&amp;gt; url }
&lt;/pre&gt;
&lt;/blockquote&gt;</description>
<pubDate>Tue, 20 Mar 2012 21:12:12 GMT</pubDate>
</item>
<item>
<title>PMPKVObservation ? Yet Another KVO-improvement project</title>
<link>http://mark.aufflick.com/blog/2012/03/13/pmpkvobservation-yet-another-kvo-improvement-project</link>
<guid isPermaLink="true">http://mark.aufflick.com/blog/2012/03/13/pmpkvobservation-yet-another-kvo-improvement-project</guid>
<description>&lt;p&gt;If you?re reading this then you?re probably as frustrated by seemingly random KVO crashes and/or the pain of huge if/else blocks in your observers. I?ve never been happy with the other KVO-improvement classes I?ve seen, and never having had any bright insights myself I kept doing things the normal way. This becomes especially painful with things like view based NSTableViews when you are re-using objects and so need to observe a new object, being very careful to un-observe the prior object (unless it?s been released, which you need to either track yourself if you can, or retain it, which has its own problems).&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;It was clear that the dealloc swizzling approach of Mike Ash?s &lt;a href=&quot;https://github.com/mikeash/MAKVONotificationCenter&quot;&gt;MAKVONotificationCenter&lt;/a&gt; was unavoidable, but I didn?t like the complexity. Recently Gwynne Raskind posted a &lt;a href=&quot;http://www.mikeash.com/pyblog/friday-qa-2012-03-02-key-value-observing-done-right-take-2.html&quot;&gt;somewhat updated MAKVONotificationCenter&lt;/a&gt; which sparked some discussion, including a comment discussing &lt;a href=&quot;https://github.com/nevyn/SPSuccinct/blob/master/SPSuccinct/SPKVONotificationCenter.m&quot;&gt;SPKVONotificationCenter&lt;/a&gt; by Joachim Bengtsson. Joachim?s brainwave was that observations should be modelled as standalone objects and simply managing the lifecycle of that object appropriately should remove the observation. Clean and simple.&lt;/p&gt;
&lt;p&gt;Except it?s not quite that simple because you still need to swizzle the dealloc of the observed object since it can go away at any time. And as much as I love a good macro as much as the next hacker, Joachim?s $depends() macro looks about as much fun as a &lt;a href=&quot;http://okmij.org/ftp/Computation/Make-functional.txt&quot;&gt;turing complete makefile&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;Enter &lt;a href=&quot;https://github.com/aufflick/PMPKVObservation&quot;&gt;PMPKVObservation&lt;/a&gt;!&lt;/h3&gt;
&lt;p&gt;Include PMPKVObservation.m and .h in your project, then do something like:&lt;/p&gt;
&lt;blockquote class=&quot;sourcebox&quot; style=&quot;border-left: 5px solid #ccc; margin-left: 45px; padding-left: 5px; color: #000000; background-color: #ffffff;&quot;&gt;
&lt;pre style=&quot;margin: 0.0px 0.0px 13.0px 0.0px; font: 12.0px Monaco;&quot;&gt;&lt;span style=&quot;color: #7a378b;&quot;&gt;#import&lt;/span&gt; &lt;span style=&quot;color: #8a2452;&quot;&gt;&quot;PMPKVObservation.h&quot;&lt;/span&gt;&lt;br /&gt; &lt;br /&gt;&lt;span style=&quot;color: #7e297f;&quot;&gt;@interface &lt;/span&gt; &lt;span style=&quot;color: #228b23;&quot;&gt;PMPKVOTests&lt;/span&gt; ()&lt;br /&gt;@property (retain) &lt;span style=&quot;color: #228b23;&quot;&gt;PMPKVObservation&lt;/span&gt; * &lt;span style=&quot;color: #a0522d;&quot;&gt;kvo&lt;/span&gt;;&lt;br /&gt;&lt;span style=&quot;color: #7e297f;&quot;&gt;@end&lt;/span&gt;&lt;br /&gt; &lt;br /&gt;&lt;span style=&quot;color: #7e297f;&quot;&gt;@implementation &lt;/span&gt; &lt;span style=&quot;color: #228b23;&quot;&gt;PMPKVOTests&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #228b23;&quot;&gt;@synthesize&lt;/span&gt; &lt;span style=&quot;color: #228b23;&quot;&gt;kvo&lt;/span&gt; = _kvo;&lt;br /&gt; &lt;br /&gt;- (&lt;span style=&quot;color: #228b23;&quot;&gt;void&lt;/span&gt;)&lt;span style=&quot;color: #353ff9;&quot;&gt;observationFired&lt;/span&gt;:(&lt;span style=&quot;color: #228b23;&quot;&gt;PMPKVObservation&lt;/span&gt; *)&lt;span style=&quot;color: #a0522d;&quot;&gt;observation&lt;/span&gt; &lt;span style=&quot;color: #353ff9;&quot;&gt;changes&lt;/span&gt;:(&lt;span style=&quot;color: #228b23;&quot;&gt;NSDictionary&lt;/span&gt; *)&lt;span style=&quot;color: #a0522d;&quot;&gt;changes&lt;/span&gt;;&lt;br /&gt;{&lt;br /&gt;    NSLog(@&lt;span style=&quot;color: #8a2452;&quot;&gt;&quot;observation fired for object: %@ keyPath: %@ changes: %@&quot;&lt;/span&gt;,&lt;br /&gt;        observation.observee,&lt;br /&gt;        observation.keyPath,&lt;br /&gt;        changes);&lt;br /&gt;}&lt;br /&gt; &lt;br /&gt;- (&lt;span style=&quot;color: #228b23;&quot;&gt;void&lt;/span&gt;)&lt;span style=&quot;color: #353ff9;&quot;&gt;selectorObservation&lt;/span&gt;&lt;br /&gt;{&lt;br /&gt;&lt;span style=&quot;color: #7e297f;&quot;&gt;    self&lt;/span&gt;.kvo = [&lt;span style=&quot;color: #228b23;&quot;&gt;PMPKVObservation&lt;/span&gt; observe:anObjectToObserve&lt;br /&gt;                                observer:&lt;span style=&quot;color: #7e297f;&quot;&gt;self&lt;/span&gt;&lt;br /&gt;                                selector:&lt;span style=&quot;color: #7e297f;&quot;&gt;@selector&lt;/span&gt;(observationFired:changes:)&lt;br /&gt;                                 keyPath:@&lt;span style=&quot;color: #8a2452;&quot;&gt;&quot;observeMe&quot;&lt;/span&gt;&lt;br /&gt;                                 options:0];&lt;br /&gt;}&lt;br /&gt; &lt;br /&gt;- (&lt;span style=&quot;color: #228b23;&quot;&gt;void&lt;/span&gt;)&lt;span style=&quot;color: #353ff9;&quot;&gt;blockObservation&lt;/span&gt;&lt;br /&gt;{&lt;br /&gt;&lt;span style=&quot;color: #7e297f;&quot;&gt;&lt;/span&gt;&lt;span style=&quot;color: #7e297f;&quot;&gt;    self&lt;/span&gt;.kvo = [&lt;span style=&quot;color: #228b23;&quot;&gt;PMPKVObservation&lt;/span&gt; observe:anObjectToObserve&lt;br /&gt;                                 keyPath:@&lt;span style=&quot;color: #8a2452;&quot;&gt;&quot;observeMe&quot;&lt;/span&gt;&lt;br /&gt;                                 options:0&lt;br /&gt;                                callback:^(&lt;span style=&quot;color: #228b23;&quot;&gt;PMPKVObservation&lt;/span&gt; *&lt;span style=&quot;color: #a0522d;&quot;&gt;observation&lt;/span&gt;, &lt;span style=&quot;color: #228b23;&quot;&gt;NSDictionary&lt;/span&gt; *&lt;span style=&quot;color: #a0522d;&quot;&gt;changeDictionary&lt;/span&gt;) {&lt;br /&gt;                                              NSLog(@&lt;span style=&quot;color: #8a2452;&quot;&gt;&quot;observation fired for object: %@ keyPath: %@ changes: %@&quot;&lt;/span&gt;,&lt;br /&gt;                                                  observation.observee,&lt;br /&gt;                                                  observation.keyPath,&lt;br /&gt;                                                  changes);&lt;br /&gt;                                 }];&lt;br /&gt;}&lt;br /&gt; &lt;br /&gt;- (&lt;span style=&quot;color: #228b23;&quot;&gt;void&lt;/span&gt;)&lt;span style=&quot;color: #353ff9;&quot;&gt;dealloc&lt;/span&gt;&lt;br /&gt;{&lt;br /&gt;    [ _kvo release];&lt;br /&gt; &lt;br /&gt;    [&lt;span style=&quot;color: #7e297f;&quot;&gt;super&lt;/span&gt; dealloc];&lt;br /&gt;}&lt;br /&gt; &lt;br /&gt;&lt;span style=&quot;color: #7e297f;&quot;&gt;@end&lt;/span&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;p&gt;The options and change dictionary are as per normal KVO. You need to be wary of the block causing retain cycles of self as usual.&lt;/p&gt;
&lt;p&gt;Unlike MAKVONotificationCenter and others, you are responsible for managing the lifecycle of the kvo object ? when it is dealloc-ed the observation will be removed. Like MAKVONotificationCenter, a minimum of magic is used to swizzle the dealloc method of the observed object and remove the observation if it still exists (tracked via an associated NSHashTable). If for some reason you want to find out if the kvo object you hold has been released early you can check the isValid accessor (which you can observe with KVO).&lt;/p&gt;
&lt;h3&gt;Caveats&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;While I am using this in a client project, that project has not yet shipped so I can?t promise wide-spread testing. Take a look at the tests in the test app and if you are using scenarios that you don?t thing are tested pull requests are welcome!&lt;/li&gt;
&lt;li&gt;I haven?t tried this under ARC, but I think I?ve made PMPKVObservation.m so it will compile and work as-is (the same can?t be said for the test app). Please let me know how you go.&lt;/li&gt;
&lt;li&gt;No attempt is made to stop you changing the observed object etc. after creation, but doing so isn?t going to be very effective?&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Repository:�&lt;a href=&quot;https://github.com/aufflick/PMPKVObservation&quot;&gt;https://github.com/aufflick/PMPKVObservation&lt;/a&gt;&lt;/p&gt;</description>
<pubDate>Tue, 13 Mar 2012 18:49:13 GMT</pubDate>
</item>
<item>
<title>Apple Museum</title>
<link>http://mark.aufflick.com/blog/2012/02/22/apple-museum</link>
<guid isPermaLink="true">http://mark.aufflick.com/blog/2012/02/22/apple-museum</guid>
<description>After a rejig of my office, there is finally room for the Apple museum. More pieces to come!&lt;p&gt;

&lt;a href=&quot;http://www.flickr.com/photos/markaufflick/6775994798/&quot; title=&quot;Apple Museum by Mark Aufflick, on Flickr&quot;&gt;&lt;img src=&quot;http://farm8.staticflickr.com/7066/6775994798_c08c13b188_b.jpg&quot; width=&quot;1024&quot; height=&quot;539&quot; alt=&quot;Apple Museum&quot;&gt;&lt;/a&gt;&lt;p&gt;

Your eyes don't deceive you, that is a 5 1/4 inch drive - the processor direct slot has an Apple // card in it (which was designed for the LC, which my parents bought it with, but it works great in the Colour Classic).&lt;p&gt;</description>
<pubDate>Wed, 22 Feb 2012 21:10:49 GMT</pubDate>
</item>
<item>
<title>Emacs Programmed Completion</title>
<link>http://mark.aufflick.com/blog/2012/02/21/emacs-programmed-completion</link>
<guid isPermaLink="true">http://mark.aufflick.com/blog/2012/02/21/emacs-programmed-completion</guid>
<description>&lt;p&gt;Subtitle - how &lt;tt&gt;(completing-read)&lt;/tt&gt; stole my afternoon.&lt;/p&gt;

&lt;p&gt;I thought I'd post my experiences since &lt;tt&gt;completing-read&lt;/tt&gt; is so poorly understood based on the forum and blog posts out there. When you write an interactive Elisp command, many will know that you can easily read a value from the user. Eg: this will ask you how you feel and log it:&lt;/p&gt;

&lt;pre class=&quot;sourcebox&quot; style=&quot;border-left: 5px solid #ccc; margin-left: 45px; padding-left: 5px; color: #000000; background-color: #ffffff;&quot;&gt;
&lt;span style=&quot;color: #696969;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #7f007f;&quot;&gt;defun &lt;/span&gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;mood&lt;/span&gt; &lt;span style=&quot;color: #696969;&quot;&gt;(&lt;/span&gt;mood&lt;span style=&quot;color: #696969;&quot;&gt;)&lt;/span&gt;&lt;br&gt;
  &lt;span style=&quot;color: #8b4513;&quot;&gt;&quot;Logs your mood&quot;&lt;/span&gt;&lt;br&gt;
  &lt;span style=&quot;color: #696969;&quot;&gt;(&lt;/span&gt;interactive &lt;span style=&quot;color: #8b4513;&quot;&gt;&quot;sHow are you feeling? &quot;&lt;/span&gt;&lt;span style=&quot;color: #696969;&quot;&gt;)&lt;/span&gt;&lt;br&gt;
  &lt;span style=&quot;color: #696969;&quot;&gt;(&lt;/span&gt;message mood&lt;span style=&quot;color: #696969;&quot;&gt;))&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;But the string form of argument to &lt;tt&gt;interactive&lt;/tt&gt; is just a shortcut. You can easily supply some code instead, with a static completion list:&lt;/p&gt;

&lt;pre class=&quot;sourcebox&quot; style=&quot;border-left: 5px solid #ccc; margin-left: 45px; padding-left: 5px; color: #000000; background-color: #ffffff;&quot;&gt;
&lt;span style=&quot;color: #696969;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #7f007f;&quot;&gt;defun &lt;/span&gt;  &lt;span style=&quot;color: #0000ff;&quot;&gt;mood&lt;/span&gt; &lt;span style=&quot;color: #696969;&quot;&gt;(&lt;/span&gt;mood&lt;span style=&quot;color: #696969;&quot;&gt;)&lt;/span&gt;&lt;br&gt;
  &lt;span style=&quot;color: #8b4513;&quot;&gt;&quot;Logs your mood&quot;&lt;/span&gt;&lt;br&gt;
  &lt;span style=&quot;color: #696969;&quot;&gt;(&lt;/span&gt;interactive &lt;span style=&quot;color: #696969;&quot;&gt;(&lt;/span&gt;list
                &lt;span style=&quot;color: #696969;&quot;&gt;(&lt;/span&gt;completing-read &lt;span style=&quot;color: #8b4513;&quot;&gt;&quot;How are you feeling? &quot;&lt;/span&gt; '&lt;span style=&quot;color: #696969;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #8b4513;&quot;&gt;&quot;happy&quot;&lt;/span&gt; &lt;span style=&quot;color: #8b4513;&quot;&gt;&quot;sad&quot;&lt;/span&gt;&lt;span style=&quot;color: #696969;&quot;&gt;)))&lt;/span&gt;&lt;br&gt;
               &lt;span style=&quot;color: #696969;&quot;&gt;(&lt;/span&gt;insert arg&lt;span style=&quot;color: #696969;&quot;&gt;))&lt;/span&gt;&lt;br&gt;
  &lt;span style=&quot;color: #696969;&quot;&gt;(&lt;/span&gt;message mood&lt;span style=&quot;color: #696969;&quot;&gt;))&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;If you want something more complex though, instead of supplying a completion list, you can supply a function and that function receives as one of it's arguments the string to be completed. But it's not as simple as that function just returning a list unfortunately, and that's where people come unstuck. Your function is now embedded in the guts of the Emacs completion mechanism and as such it has to answer a whole range of questions about completions. It is &lt;i&gt;reasonably&lt;/i&gt; well documented (if a bit terse) in the &lt;a href=&quot;http://www.gnu.org/software/emacs/manual/html_node/elisp/Programmed-Completion.html&quot;&gt;Programmed Completion&lt;/a&gt; section of the Emacs manual. There is a second argument which contains an optional predicate function (I'm ignoring that), but the important bit is the third argument which effectively sets the mode in which your function is being called.&lt;/p&gt;

&lt;p&gt;In fact, your function will usually be called multiple times for each completion tab press. Essentially, your function may be asked to provide the best completion string possible, if there string is an exact match, if there are no matches, or to provide a list of possible matches. There is one final thing that will be asked, and that is the substring your completion is for. So in the example you're about to see I am completing directories, so the completion being offered at any given time only applies to the part after the last forward slash.&lt;/p&gt;

&lt;p&gt;An example is as good as a thousand or so words, so here's my interactive function &lt;tt&gt;cdsrc&lt;/tt&gt;. Basically it's a convenience function to quickly change directory into one of my client projects, which may be one or two levels deep in my main company source directory. The hard work is done by &lt;tt&gt;cdsrc-completions&lt;/tt&gt; and you can see in the &lt;tt&gt;(cond)&lt;/tt&gt; at the end where it responds to the different modes discussed briefly above and in detail in &lt;a href=&quot;http://www.gnu.org/software/emacs/manual/html_node/elisp/Programmed-Completion.html&quot;&gt;Programmed Completion&lt;/a&gt;.&lt;/p&gt;

&lt;pre class=&quot;sourcebox&quot; style=&quot;border-left: 5px solid #ccc; margin-left: 45px; padding-left: 5px; color: #000000; background-color: #ffffff;&quot;&gt;
&lt;span style=&quot;color: #696969;&quot;&gt;(&lt;/span&gt;setq cdsrc-completions-prefix &lt;span style=&quot;color: #8b4513;&quot;&gt;&quot;~/src/_Pumptheory/&quot;&lt;/span&gt;&lt;span style=&quot;color: #696969;&quot;&gt;)&lt;/span&gt;&lt;br&gt;
&lt;br&gt;
&lt;span style=&quot;color: #696969;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #7f007f;&quot;&gt;defun &lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;safe-fill-common-string-prefix&lt;/span&gt;&lt;span style=&quot;color: #696969;&quot;&gt; (&lt;/span&gt;s1 s2&lt;span style=&quot;color: #696969;&quot;&gt;)&lt;/span&gt;&lt;br&gt;
&lt;span style=&quot;color: #696969;&quot;&gt;  (&lt;/span&gt;&lt;span style=&quot;color: #7f007f;&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: #696969;&quot;&gt; (&lt;/span&gt;and s1 s2&lt;span style=&quot;color: #696969;&quot;&gt;)&lt;/span&gt;&lt;br&gt;
&lt;span style=&quot;color: #696969;&quot;&gt;      (&lt;/span&gt;fill-common-string-prefix s1 s2&lt;span style=&quot;color: #696969;&quot;&gt;)&lt;/span&gt;
    nil&lt;span style=&quot;color: #696969;&quot;&gt;))&lt;/span&gt;&lt;br&gt;
&lt;br&gt;
&lt;span style=&quot;color: #696969;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #7f007f;&quot;&gt;defun &lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;cdsrc-completions&lt;/span&gt;&lt;span style=&quot;color: #696969;&quot;&gt; (&lt;/span&gt;str pred mode&lt;span style=&quot;color: #696969;&quot;&gt;)&lt;/span&gt;&lt;br&gt;
&lt;span style=&quot;color: #696969;&quot;&gt;  (&lt;/span&gt;&lt;span style=&quot;color: #7f007f;&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color: #696969;&quot;&gt; ((&lt;/span&gt;dirname&lt;span style=&quot;color: #696969;&quot;&gt; (&lt;/span&gt;replace-regexp-in-string &lt;span style=&quot;color: #8b4513;&quot;&gt;&quot;[&lt;/span&gt;&lt;span style=&quot;color: #8b4513;&quot;&gt;^&lt;/span&gt;&lt;span style=&quot;color: #8b4513;&quot;&gt;/]+$&quot;&lt;/span&gt; &lt;span style=&quot;color: #8b4513;&quot;&gt;&quot;&quot;&lt;/span&gt; str&lt;span style=&quot;color: #696969;&quot;&gt;))&lt;/span&gt;&lt;br&gt;
&lt;span style=&quot;color: #696969;&quot;&gt;        (&lt;/span&gt;filename&lt;span style=&quot;color: #696969;&quot;&gt; (&lt;/span&gt;replace-regexp-in-string &lt;span style=&quot;color: #8b4513;&quot;&gt;&quot;^.*/&quot;&lt;/span&gt; &lt;span style=&quot;color: #8b4513;&quot;&gt;&quot;&quot;&lt;/span&gt; str&lt;span style=&quot;color: #696969;&quot;&gt;))&lt;/span&gt;&lt;br&gt;
&lt;span style=&quot;color: #696969;&quot;&gt;        (&lt;/span&gt;slashpos&lt;span style=&quot;color: #696969;&quot;&gt; (&lt;/span&gt;or&lt;span style=&quot;color: #696969;&quot;&gt; (&lt;/span&gt;string-match &lt;span style=&quot;color: #8b4513;&quot;&gt;&quot;/.*$&quot;&lt;/span&gt; str&lt;span style=&quot;color: #696969;&quot;&gt;)&lt;/span&gt; 0&lt;span style=&quot;color: #696969;&quot;&gt;)))&lt;/span&gt;&lt;br&gt;
&lt;br&gt;
&lt;span style=&quot;color: #696969;&quot;&gt;    (&lt;/span&gt;&lt;span style=&quot;color: #7f007f;&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color: #696969;&quot;&gt; ((&lt;/span&gt;completions&lt;span style=&quot;color: #696969;&quot;&gt; (&lt;/span&gt;all-completions filename&lt;span style=&quot;color: #696969;&quot;&gt; (&lt;/span&gt;delq nil &lt;br&gt;
&lt;span style=&quot;color: #696969;&quot;&gt;                                                  (&lt;/span&gt;mapcar&lt;span style=&quot;color: #696969;&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color: #7f007f;&quot;&gt;lambda&lt;/span&gt;&lt;span style=&quot;color: #696969;&quot;&gt; (&lt;/span&gt;x&lt;span style=&quot;color: #696969;&quot;&gt;)&lt;/span&gt;&lt;br&gt;
&lt;span style=&quot;color: #696969;&quot;&gt;                                                            (&lt;/span&gt;and&lt;span style=&quot;color: #696969;&quot;&gt; (&lt;/span&gt;file-directory-p&lt;span style=&quot;color: #696969;&quot;&gt; (&lt;/span&gt;concat cdsrc-completions-prefix dirname x&lt;span style=&quot;color: #696969;&quot;&gt;))&lt;/span&gt;&lt;br&gt;
&lt;span style=&quot;color: #696969;&quot;&gt;                                                                 (&lt;/span&gt;not&lt;span style=&quot;color: #696969;&quot;&gt; (&lt;/span&gt;string-match &lt;span style=&quot;color: #8b4513;&quot;&gt;&quot;^\\.&quot;&lt;/span&gt; x&lt;span style=&quot;color: #696969;&quot;&gt;))&lt;/span&gt;&lt;br&gt;
&lt;span style=&quot;color: #696969;&quot;&gt;                                                                 (&lt;/span&gt;concat x &lt;span style=&quot;color: #8b4513;&quot;&gt;&quot;/&quot;&lt;/span&gt;&lt;span style=&quot;color: #696969;&quot;&gt;)))&lt;/span&gt;&lt;br&gt;
&lt;span style=&quot;color: #696969;&quot;&gt;                                                          (&lt;/span&gt;directory-files&lt;span style=&quot;color: #696969;&quot;&gt; (&lt;/span&gt;concat cdsrc-completions-prefix dirname&lt;span style=&quot;color: #696969;&quot;&gt;)))))))&lt;/span&gt;&lt;br&gt;
&lt;br&gt;
      &lt;span style=&quot;color: #b22222;&quot;&gt;;; &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;return differently based on what mode we were called in
&lt;/span&gt;      &lt;span style=&quot;color: #b22222;&quot;&gt;;; &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;see http://www.gnu.org/software/emacs/manual/html_node/elisp/Programmed-Completion.html&lt;br&gt;
&lt;/span&gt;&lt;span style=&quot;color: #696969;&quot;&gt;      (&lt;/span&gt;&lt;span style=&quot;color: #7f007f;&quot;&gt;cond&lt;/span&gt;&lt;br&gt;
&lt;span style=&quot;color: #696969;&quot;&gt;       ((&lt;/span&gt;not mode&lt;span style=&quot;color: #696969;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #696969;&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color: #7f007f;&quot;&gt;cond&lt;/span&gt;&lt;br&gt;
&lt;span style=&quot;color: #696969;&quot;&gt;                    ((&lt;/span&gt;and&lt;span style=&quot;color: #696969;&quot;&gt; (&lt;/span&gt;eq 0&lt;span style=&quot;color: #696969;&quot;&gt; (&lt;/span&gt;length completions&lt;span style=&quot;color: #696969;&quot;&gt;))&lt;/span&gt;&lt;span style=&quot;color: #696969;&quot;&gt; (&lt;/span&gt;eq 0&lt;span style=&quot;color: #696969;&quot;&gt; (&lt;/span&gt;length filename&lt;span style=&quot;color: #696969;&quot;&gt;)))&lt;/span&gt;
                     't&lt;span style=&quot;color: #696969;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #b22222;&quot;&gt;;; &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;in our case, only report exact match when no nested dirs left&lt;br&gt;
&lt;/span&gt;&lt;span style=&quot;color: #696969;&quot;&gt;                    ((&lt;/span&gt;&amp;gt;&lt;span style=&quot;color: #696969;&quot;&gt; (&lt;/span&gt;length completions&lt;span style=&quot;color: #696969;&quot;&gt;)&lt;/span&gt; 1&lt;span style=&quot;color: #696969;&quot;&gt;)&lt;/span&gt;&lt;br&gt;
&lt;span style=&quot;color: #696969;&quot;&gt;                     (&lt;/span&gt;concat dirname&lt;span style=&quot;color: #696969;&quot;&gt; (&lt;/span&gt;or&lt;span style=&quot;color: #696969;&quot;&gt; (&lt;/span&gt;reduce 'safe-fill-common-string-prefix completions&lt;span style=&quot;color: #696969;&quot;&gt;)&lt;/span&gt; filename&lt;span style=&quot;color: #696969;&quot;&gt;)))&lt;/span&gt;&lt;br&gt;
&lt;span style=&quot;color: #696969;&quot;&gt;                    ((&lt;/span&gt;eq&lt;span style=&quot;color: #696969;&quot;&gt; (&lt;/span&gt;length completions&lt;span style=&quot;color: #696969;&quot;&gt;)&lt;/span&gt; 1&lt;span style=&quot;color: #696969;&quot;&gt;)&lt;/span&gt;&lt;br&gt;
&lt;span style=&quot;color: #696969;&quot;&gt;                     (&lt;/span&gt;concat dirname&lt;span style=&quot;color: #696969;&quot;&gt; (&lt;/span&gt;car completions&lt;span style=&quot;color: #696969;&quot;&gt;)))&lt;/span&gt;&lt;br&gt;
&lt;span style=&quot;color: #696969;&quot;&gt;                    (&lt;/span&gt;'t
                     nil&lt;span style=&quot;color: #696969;&quot;&gt;)))&lt;/span&gt;&lt;br&gt;
&lt;br&gt;
&lt;span style=&quot;color: #696969;&quot;&gt;       ((&lt;/span&gt;eq mode 't&lt;span style=&quot;color: #696969;&quot;&gt;)&lt;/span&gt; completions&lt;span style=&quot;color: #696969;&quot;&gt;)&lt;/span&gt;&lt;br&gt;
&lt;br&gt;
&lt;span style=&quot;color: #696969;&quot;&gt;       ((&lt;/span&gt;eq mode 'lambda&lt;span style=&quot;color: #696969;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #696969;&quot;&gt; (&lt;/span&gt;member&lt;span style=&quot;color: #696969;&quot;&gt; (&lt;/span&gt;concat filename &lt;span style=&quot;color: #8b4513;&quot;&gt;&quot;/&quot;&lt;/span&gt;&lt;span style=&quot;color: #696969;&quot;&gt;)&lt;/span&gt; completions&lt;span style=&quot;color: #696969;&quot;&gt;))&lt;/span&gt;&lt;br&gt;
&lt;br&gt;
&lt;span style=&quot;color: #696969;&quot;&gt;       (&lt;/span&gt;'t&lt;span style=&quot;color: #696969;&quot;&gt; (&lt;/span&gt;cons&lt;span style=&quot;color: #696969;&quot;&gt; (&lt;/span&gt;list 'boundaries slashpos&lt;span style=&quot;color: #696969;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #696969;&quot;&gt; (&lt;/span&gt;length filename&lt;span style=&quot;color: #696969;&quot;&gt;))))&lt;/span&gt; &lt;span style=&quot;color: #b22222;&quot;&gt;;; &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;let completion know our completions only apply after the last /
&lt;/span&gt;&lt;span style=&quot;color: #696969;&quot;&gt;      )))&lt;/span&gt;&lt;br&gt;
&lt;br&gt;
&lt;span style=&quot;color: #696969;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #7f007f;&quot;&gt;defun &lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;cdsrc&lt;/span&gt;&lt;span style=&quot;color: #696969;&quot;&gt; (&lt;/span&gt;path&lt;span style=&quot;color: #696969;&quot;&gt;)&lt;/span&gt;&lt;br&gt;
  &lt;span style=&quot;color: #8b4513;&quot;&gt;&quot;Changes to a subdir of cdsrc-completions-prefix in the current active interactive shell buffer&quot;&lt;/span&gt;&lt;br&gt;
&lt;span style=&quot;color: #696969;&quot;&gt;  (&lt;/span&gt;interactive&lt;span style=&quot;color: #696969;&quot;&gt; (&lt;/span&gt;list&lt;br&gt;
&lt;span style=&quot;color: #696969;&quot;&gt;                (&lt;/span&gt;&lt;span style=&quot;color: #7f007f;&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color: #696969;&quot;&gt; ((&lt;/span&gt;completion-ignore-case 't&lt;span style=&quot;color: #696969;&quot;&gt;))&lt;/span&gt;&lt;br&gt;
&lt;span style=&quot;color: #696969;&quot;&gt;                  (&lt;/span&gt;completing-read&lt;br&gt;
&lt;span style=&quot;color: #696969;&quot;&gt;                   (&lt;/span&gt;concat &lt;span style=&quot;color: #8b4513;&quot;&gt;&quot;Enter subdir of &quot;&lt;/span&gt; cdsrc-completions-prefix &lt;span style=&quot;color: #8b4513;&quot;&gt;&quot;: &quot;&lt;/span&gt;&lt;span style=&quot;color: #696969;&quot;&gt;)&lt;/span&gt;&lt;br&gt;
                   'cdsrc-completions&lt;span style=&quot;color: #696969;&quot;&gt;))))&lt;/span&gt;&lt;br&gt;
&lt;span style=&quot;color: #696969;&quot;&gt;  (&lt;/span&gt;&lt;span style=&quot;color: #7f007f;&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color: #696969;&quot;&gt; ((&lt;/span&gt;path2&lt;span style=&quot;color: #696969;&quot;&gt; (&lt;/span&gt;concat cdsrc-completions-prefix path&lt;span style=&quot;color: #696969;&quot;&gt;)))&lt;/span&gt;&lt;br&gt;
&lt;span style=&quot;color: #696969;&quot;&gt;    (&lt;/span&gt;cd path2&lt;span style=&quot;color: #696969;&quot;&gt;)&lt;/span&gt;&lt;br&gt;
&lt;span style=&quot;color: #696969;&quot;&gt;    (&lt;/span&gt;&lt;span style=&quot;color: #7f007f;&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: #696969;&quot;&gt; (&lt;/span&gt;string-match mode-name &lt;span style=&quot;color: #8b4513;&quot;&gt;&quot;Shell&quot;&lt;/span&gt;&lt;span style=&quot;color: #696969;&quot;&gt;)&lt;/span&gt;&lt;br&gt;
&lt;span style=&quot;color: #696969;&quot;&gt;        (&lt;/span&gt;&lt;span style=&quot;color: #7f007f;&quot;&gt;progn&lt;/span&gt;&lt;span style=&quot;color: #696969;&quot;&gt; (&lt;/span&gt;end-of-buffer&lt;span style=&quot;color: #696969;&quot;&gt;)&lt;/span&gt;&lt;br&gt;
&lt;span style=&quot;color: #696969;&quot;&gt;               (&lt;/span&gt;comint-kill-input&lt;span style=&quot;color: #696969;&quot;&gt;)&lt;/span&gt;&lt;br&gt;
&lt;span style=&quot;color: #696969;&quot;&gt;               (&lt;/span&gt;comint-send-string&lt;span style=&quot;color: #696969;&quot;&gt; (&lt;/span&gt;current-buffer&lt;span style=&quot;color: #696969;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #696969;&quot;&gt; (&lt;/span&gt;concat &lt;span style=&quot;color: #8b4513;&quot;&gt;&quot;cd &quot;&lt;/span&gt; path2&lt;span style=&quot;color: #696969;&quot;&gt;))&lt;/span&gt;&lt;br&gt;
&lt;span style=&quot;color: #696969;&quot;&gt;               (&lt;/span&gt;comint-send-input&lt;span style=&quot;color: #696969;&quot;&gt;)))))&lt;/span&gt;&lt;br&gt;
&lt;/pre&gt;

&lt;p&gt;This is out of my &lt;a href=&quot;https://github.com/aufflick/emacs.d&quot;&gt;emacs.d&lt;/a&gt;, specifically &lt;a href=&quot;https://github.com/aufflick/emacs.d/blob/master/aufflick-shell-hooks.el&quot;&gt;aufflick-shell-hooks.el&lt;/a&gt;.&lt;/p&gt;</description>
<pubDate>Tue, 21 Feb 2012 05:36:05 GMT</pubDate>
</item>
<item>
<title>Comments are broken</title>
<link>http://mark.aufflick.com/blog/2012/02/10/comments-are-broken</link>
<guid isPermaLink="true">http://mark.aufflick.com/blog/2012/02/10/comments-are-broken</guid>
<description>It seems that adding comments is broken after the server move. I'll get right on it...

&lt;b&gt;Update:&lt;/b&gt; Comments are now fixed, both for registered and anonymous persons.</description>
<pubDate>Fri, 10 Feb 2012 01:44:17 GMT</pubDate>
</item>
</channel>
</rss>

