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
EOF
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!