I’ve recently switched to development in two Vagrant virtual machines (VMs), one VM running Nginx and one running Apache. This means that are two locations I might need to open files from, with two sets of directories representing the document roots of my various development sites. Eventually I got bored of using the terminal to “subl ~/Vagrants/nginx/www/wordpress-whatever/” and decided to write an Alfred Workflow. Now I just trigger Alfred, hit “v client“, and Alfred shows me all my projects in directories with “client” in the name.

The core of the workflow is a script filter which contains the following Bashscript bound to the v keyword. I’ve commented the code fairly well, so hopefully it makes sense; or you can simply download the whole Workflow.

The structure of the workflow looks like this:


# We could do this in any script type, but I'm using Bash

# My two Vagrant locations for sites are as follows
# This code reads the immediate child directories into a Bash array
NGINX_FILES=($(find /Users/simonwheatley/Vagrants/ubuntu-precise-32-nginx -iname *{query}* -type d -maxdepth 2));
APACHE_FILES=($(find /Users/simonwheatley/Vagrants/ubuntu-precise-32-apache -iname *{query}* -type d -maxdepth 2));

# Concatenate the Nginx and Apache arrays
# get length of an array

# We have to return the results as XML in a certain format
# http://www.alfredforum.com/topic/5-generating-feedback-in-workflows/
echo '<?xml version="1.0"?><items>';

# use for loop read all filenames
for (( I=0; I<${LENGTH}; I++ ));
	# Use Bash string manipulation to get the directory name
	# http://stackoverflow.com/a/2664746
	DIR =${FILES[$I]##*/};
	# Work out if we're Nginx or Apache, and set the icon appropriately
	# If seems that to detect a substring, we have to run it through Grep. Weird.
	if echo "${FILES[$I]}" | grep -q "apache"; then
	# Each selectable result is an item in the XML	
	echo "<item uid='$I' arg='${FILES[$I]}' type='file'><title>${DIR}</title><subtitle>${FILES[$I]}</subtitle><icon>${ICON}</icon></item>";

echo '</items>';

This feeds into a simple one line Bashscript:

subl {query}

Any suggestions or comments?

(Photo: Bowler hat lamps in the jazz corner of Cafe Belgique, © Hornbeam Wildlife Studio)

Join the Conversation


  1. Very cool. I’ve been parsing through some of your auto setup scripts and this similar script vvv-site-wizard which I forked for my own preferences . Now I need to think about turning it into an Alfred workflow!

    On questions on this 2 server setup. Why not have a single work directory that is then symlinked into each server? (note: I’ve been trying to work this out unsuccessfully so I don’t know if it’s actually possible). The idea being to have a single set of site files that could be run under both Apache and Nginx, or a dozen server configs.

    1. Not sure what you mean by “a single set of site files”? We tend to have a site setup in Composer, or less frequently as a monolithic Git repo with everything in, and keep each site separately, which suits us.

      1. Sorry I wasn’t clear. As I understand it you two folders in OS X, one has sites folders for Apache and a VagrantFile that launches a Apache based VM, the other has site folders for Nginx and a VagrantFile that launches a Nginx based VM.

        What I was wondering is if it was possible to have a single folder of sites. For example just using ~/Sites/site_name_1. Then wherever have a folder called /apache-sites with a VagrantFile in it for an Apache VM. Instead of having site folders actually inside /apache-sites like normal vagrant use one could try creating OS X symlinks from /apache-sites/site_name_1/ to ~/Sites/site_name_1/. Similarly one could create symlinks from an /nginx-sites/site_name_1/ to ~/Sites/site_name1/. At least in my head it would mean a single set of real files that could run under each VM server. I still haven’t actually tried it and am not sure if VirtualBox/Vagrant wouldn’t choke on the symlinks in the host OS X.

Leave a comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.