Computing stuff tied to the physical world

Greasing the “make” cycle on Mac

In Musings on Jul 8, 2015 at 00:01

I’m regularly on the lookout for ways to optimise my software development workflow. Anything related to editing, building, testing, uploading – if I can shave off a little time, or better still, find a way to automate more and get tasks into my muscle memory, I’m game.

It may not be everyone’s favourite, but I keep coming back to vim as my editor of choice, or more specifically the GUI-aware MacVim (when I’m not working on some Linux system).

And some tasks need to be really fast. Simply Because I Do Them All The Time.

Such as running “make”.

So I have a keyboard shortcut in vim which saves all the changes and runs make in a shell window. For quite some time, I’ve used the Vim Tmux Navigator for this. But that’s not optimal: you need to have tmux running locally, you need to type in the session, window, and pane to send the make command to (once after every vim restart), and things … break at times (occasional long delays, wrong tmux pane, etc). Unreliable automation is awful.

Time to look for a better solution. Using as few “moving parts” as possible, because the more components take part in these custom automation tricks, the sooner they’ll break.

The following is what I came up with, and it works really well for me:

  • hitting “,m” (i.e. “<leader>m“) initiates a make, without leaving my vim context
  • there needs to be a “Terminal” app running, with a window named “⌘1” open
  • it will receive this command line:  clear; date; make $MAKING

So all I have to do is leave that terminal window open – set to the proper directory. I can move around at will in vim or MacVim, run any number of them, and “,m” will run “make”.

By temporarily setting a value in the “MAKING” shell variable, I can alter the make target. This can be changed as needed, and I can also change the make directory as needed.

The magic incantation for vim is this one line, added to the ~/.vimrc config file:

    nnoremap <leader>m :wa<cr>:silent !makeit<cr>

In my ~/bin/ directory, I have a shell script called “makeit” with the following contents:

    exec osascript >/dev/null <<EOF
        tell application "Terminal"
            repeat with w in windows
                if name of w ends with "⌘1" then
                    do script "clear; date; make $MAKING" in w
                end if
            end repeat
        end tell

The looping is needed to always find the proper window. Note that the Terminal app must be configured to include the “⌘«N»” command shortcut in each window title.

This all works out of the box with no dependency on any app, tool, or utility – other than what is present in a vanilla Mac OSX installation. Should be easy to adapt to other editors.

It can also be used from the command line: just type “makeit”.

That’s all there is to it. A very simple and clean convention to remember and get used to!