Menu

My Development Setup

04 November 2014

When I tell people that I'm a web developer and that I use Vim as my primary IDE, it often drives them to ask more questions about my development environment. I've answered this question enough times that I thought it might make for a decent blog post. I'm going to describe the various aspects of my preferred development setup for OS X and Ubuntu. I used to do a lot of .NET development on Windows years ago using an IDE called Visual Studio, but I've since grown to dislike Windows as a development platform and try to stick to Mac as much as possible. On the rare occasion when I must work on a PC I prefer to install Ubuntu.

Homebrew

The first thing I do if I'm on OS X is install Homebrew, which is a simple command line based package manager. Once Homebrew is installed and up to date I use it to install Git and Node.

$ brew install git
$ brew install node

Installing node also installs npm. The devs like to pretend it doesn't stand for Node Package Manager, but anyone who uses it knows that's pretty much exactly what it is. Npm will allow us to install some useful command-line tools later. If I'm on Ubuntu npm tends to have issues with file system permissions when trying to install or update global modules. To get around this problem I use a super nifty tool called NVM.

NVM could be used on OS X as well but because I don't care about using different Node versions and npm doesn't seem to have any permissions issues on OS X, I just install it via Homebrew. NVM makes it easy to manage node/npm versions and switch between them as needed. It also changes where npm installs global modules and removes the need to use sudo with npm, which almost always results in hair-pulling frustration at some point.

Vim

The next thing I install through Homebrew or apt-get is Vim. OS X and Ubuntu both come with Vim preinstalled which is nice, but it's almost always out of date.

OS X:

$ brew install macvim

I rarely use the Macvim GUI anymore, but occasionally it's nice to have so I install it anyway.

Ubuntu:

$ sudo apt-get install vim
$ sudo apt-get install vim-gnome

I install vim-gnome because it has clipboard support enabled.

Don't worry about configuring vim quite yet. Once we get some more things installed I'll cover my nifty dotfiles repository that will automatically configure a lot of things on my machine.

iTerm 2

The next thing I usually install is iTerm 2. The default OS X terminal supports 256 colors now, but it lacks a bunch of other features, one of them being mouse support. iTerm 2 is highly customizeable and provides a lot more options than the default terminal. While there are a ton of options to pour over, it's also nice to note that iTerm is perfectly functional right out of the box so you don't need to sit down and configure it right away if you don't have time.

Git Aliases

You may have noticed in one of the above screenshots I was running a git st command. It's basically the same as a normal git status command except the output is pruned to be a little easier to read. I have a number of Git aliases that do similar things. I wrote a separate blog post about them in the past that can be found here.

tmux

Tmux stands for Terminal Multiplexer. That may sound complicated but it's not. What tmux allows you to do is split up a single terminal window into multiple terminal windows. I discovered tmux because I went looking for a way to keep a terminal prompt open while I'm developing in Vim. I used to use an IDE caleld Webstorm before I became a vimhead. Webstorm had a built in terminal window at the bottom that was always present and I missed having that convenience.

Typically I would have a terminal open in a separate tab and Vim open in another. That works well but I still wanted to see what else I could do so I installed tmux.

In the above video you can see how I start with a bare terminal, open tmux, and begin splitting the terminal window into multiple panes. I keep Vim in the main pane that takes up most of the room and I open two smaller panes below for easy terminal access.

Note: When I first installed tmux and opened Vim inside a tmux pane I noticed that Vim forgot its color scheme. After some hunting I realized that Vim reads in the TERM environment variable. On OS X if you run echo $TERM you'll see that it says xterm-256color. That tells Vim that the terminal is capable of handing 256 colors. However, for some reason inside tmux if you run echo $TERM you'll see that it just says xterm, which Vim interprets to mean that 256 colors are not supported by the running terminal.

You can temporarily fix it for a single Vim session by running TERM=xterm-256color vim from within tmux, but that's not very practical to do everytime you want to open Vim. Luckily, tmux can be configured and one of the configuration options is the TERM environment variable. All you need to do is locate ~/.tmux.conf (or create it if it does not exist) and add set -g default-terminal "xterm-256color" to it. Restart all tmux processes and the setting will take effect. You can test it by running echo $TERM from within tmux; you should see xterm-256color.

In the above note I described the default-terminal configuration option for tmux. There are other options that I set as well. Since I use iTerm for my terminal application I can utilize the mouse support it provides. I usually set the following options for tmux so that I can click within the panes; I can even resize the panes by clicking and dragging the dividers.

setw -g mode-mouse on
set -g mouse-select-pane on
set -g mouse-resize-pane on
set -g mouse-select-window on
setw -g mode-keys vi

By default tmux uses a key configuration that is similar to Emacs. That last configuration option sets mode-keys to vi which is a key configuration that is closer to Vim. I've never really used Emacs myself so I'm more comfortable with the Vim-style key mode. These settings will be automatically added to your .tmux.conf file if you decide to use my dotfiles repository at the end of this post.

Alfred

When I first started using Alfred I thought of it as a fun little toy, but now that it's been over a year I can safely say that it's a must-have for me. Jumping around between applications is made so much easier with Alfred installed. Alfred is free but you do have the option to pay $50 for the powerpack which provides you with some additional features. Right out of the box Alfred will already enhance your experience using OS X. By hitting option + space you pull up a dialog that looks similar to this:

Mine is green because I configured the colors, but of the box I believe it has a white theme. If you've ever used Spotlight which is built into OS X then you're already somewhat familiar with this ability to open applications by starting to type the name. Spotlight is great but it doesn't provide half of the functionality that Alfred does. Spotlight allows you to search the web as well as your locally installed applications while Alfred lets you do that and much more.

Even without paying for the powerpack you can use Alfred to do some pretty cool things. You can issue operating system commands such as "sleep", "lock", "shutdown", "restart", "logout", "emptytrash", "screensaver", etc. You can even "forcequit" applications as you can see below.

You can control iTunes with the "itunes" command, or you can show the "iTunes Mini Player" that Alfred provides.

Alfred also synchronizes with 1Password if you use it to manage your passwords. You can interact with your contacts, search for files, you can even use Alfred as a calculator.

My favorite feature that you get out of the box for free has to be the "Web Search" feature. If you open Alfred preferences you can navigate to Features > Web Search and see a set of options like this:

You'll notice there are a bunch of options already configured. For example, you can see "imdb" is one of the items on the list. If you test it out you'll notice that whatever you type after "imdb" into Alfred will be added to the query portion of the IMDB URL.

If I press enter Alfred will open a browser tab and navigate to http://www.imdb.com/find?s=all&q=Kate+Mulgrew. Notice that all it did was append our query to the portion of the URL that is relevant to the search term. To show how this works, I'll add my own custom search tool. One of the sites I use all the time is the npm registry to search for useful modules and tools. To add our own npm web search entry is simple.

Copy the URL from the address bar while paying attention to where in the URL the site placed your search query.

Open Alfred preferences and navigate to Features > Web Search. Then click "Add Custom Search".

A dialog will slide down allowing you to enter the search URL. Just below that box you'll see some text that says:

Perform a search on a website and copy the resulting URL. Replace your search term with {query} in curly brackets e.g. http://twitter.com/search?q={query}.

So in order for us to add our npm search URL we simply need to replace our search query with {query}, which looks like this: https://www.npmjs.org/search?q={query}.

When you add a custom web search it has no picture by default. Adding one is super easy though. You can see below how I literally drag the npm logo image from the website into Alfred. Once that's done you can simply type "npm" into Alfred followed by a query.

All the features I just covered are free; we haven't even covered what is offered by the $50 powerpack. I think the price tag is a little steep, but the "workflows" feature it offers is pretty awesome. I'll let you decide if you think it's worth the cost.

After I bought the powerpack I got the ability to issue terminal commands right from Alfred. That's cool but it's not $50 cool. The truly remarkable feature is the workflows feature found in preferences > Workflows. Workflows allow you to create complex functions that can be issued from Alfred. Creating workflows is fairly straightforward but if you're like me then you'll mostly be downloading cool workflows from other people.

For example, on the Alfred forums I found a URL shortener workflow (download it here) that allows you to instantly shorten any URL using any of the major URL shortening services. Simply download the workflow and open it. It will open in Alfred automatically and you'll be presented with the workflow diagram.

The workflow has several steps. The first one is a hotkey step that is not filled out. If you open it up you would find a place to specify a hotkey. It would literally allow you to select a URL in any application and press that hotkey to have Alfred shorten it for you. The other option is to open Alfred, type the "short" keyword, and paste the URL you would like shortened. The latter option is available immediately after installing the workflow.

node-inspector

One of the things you get out of the box with Webstorm is a built-in debugging utility for node. You can simply mark lines in your editor with breakpoints and run the application in debug mode to hit them. What I love about working in an adhoc terminal environment during development is just how versatile it is. I can run any script I want in a tmux pane and I'm good to go. As much as I love the full-featured IDE experience that Webstorm and others provide, the freedom and efficiency I get while working in the terminal is still unmatched (at least for me). While debugging node applications is easier in Webstorm, it's not too hard to get a quick debugging setup going from the terminal.

To begin you simply need to have npm installed so you can install node-inspector globally.

$ npm install -g node-inspector

When you install something globally via npm it places the module in a predefined location on your machine that is referenced by your PATH environment variable. In other words, if the module you installed includes some command-line utilities then you'll have access to them immediately after you install the module.

Before we dive into how to debug a node app it's important to understand how debugging actually works. If you've used a debugger like the one provided by Webstorm then you don't really get to see what's going on under the hood. To run a script in node you simply have to supply the script path to the node command, like so: node app.js. To debug a script you have to tell node to run the process in debug mode: node --debug app.js. When you supply the --debug flag you tell node to listen on a port (default is 5858) for a debugger to attach itself. Once a debugger has attached itself then the debugger can place breakpoints and begin debugging the code.

It's common for a lot of apps to simply start up and then begin listening for things like events or incoming requests, such as when your app is a web server. In these scenarios the --debug flag suffices because by the time you attach a debugger to the node process your app has already hit the point where it's just sitting there listening. You can then place breakpoints in request handlers and make requests with your browser to hit those breakpoints. However, sometimes you have a simple script you want to run and the node process exits when it hits the bottom of the script. There's often no way that you could start your script in debug mode and then attach a debugger before it exits. To work around this you would use the --debug-brk flag instead.

When you run node --debug-brk app.js you're telling node to do two things. First, node will start the process in debugging mode causing it to listen for a debugger to attach itself to the process. Second, it immediately halts the execution of your script until a debugger attaches. Essentially it's like manually placing a debugger; statement right at the top of your script, telling the node process to halt on that breakpoint and wait for a debugger to instruct it to continue.

Now that you know how debugging works at a lower level, that should make it easier to understand what node-inspector is doing when we run it. Watch the video below for a complete walkthrough setting up node-inspector. It's not very complicated, but it can appear to be to someone who hasn't done it before. I made the video below so I could take it slow and highlight exactly what is happening each step of the way.

My Dotfiles Repository

One of the most annoying parts of setting up a new machine is setting up all my configuration files (also known as "dotfiles" since they are usually hidden files beginning with a dot). There are a lot of dotfiles setups out there but I prefer simplicity. Simply clone the repository anywhere you want and run the install.sh script that is included with it. The script will run through and create symlinks in your home directory that link to the configuration files stored in the repository.

A nice convenience of doing things this way is the ability to simply create additional git branches for a variety of different settings. For example, I cloned my dotfiles repository onto a remote machine, ran the install script, then simply checked out the remote-server branch instead of master. That branch included changes to my files that would change my vim and promptline themes so they are a different color, making it extremely obvious when I'm on a remote machine. It's common to accidentally make a change on a remote server when your local and remote environments look identical.