The Programs of the Week of the Big Game
This Week’s Program: Jan 29 - Feb 2
It’s been another couple of weeks since my last Tinyletter. I decided
to shelve Overscan’s ongoing gui
work/debacle/obsession and get back
to basics. I have enough pieces in place to get something to work,
and an open thread on the Racket dev mailing list to try to better
understand some odd behavior on the things that aren’t working.
This week I mostly focused on doing the best thing to recharge energy
on a project: write documentation. Overscan’s gstreamer
module has
evolved and quite a bit has been added since I started down this GUI
path, so I took some time to write out docs for that new
functionality. Writing documentation is like pruning a bonsai:
tranquil, meditative work that doesn’t madden you with subtle platform
implementation differences.
The other thing I’ve spent time on over the past couple of weeks is
mechwarper
, my repository
hosting Ansible playbooks for the care
and feeding of my computer machines.
Recently, the release of Ruby 2.5.0 meant it was time to do a bit of house cleaning on my MacBook. I also decided to upgrade to High Sierra. It made me realize I never want to think about bespoke installations of software again. I want every Mac I interact with to basically run the same suite. I turned to Ansible to figure out how to manage the bootstrapping of a new Mac development machine.
local.yml
The main playbook is located at local/local.yml
and is split into
several roles. The basics
role installs Homebrew, Homebrew-Cask, the
Mac App Store CLI, Git, GNU
Stow, and my
Dotfiles. From there, there are
roles to install Homebrew formula I use frequently, some Mac apps
installed through Cask (including Racket), and apps from the Mac App
Store. I also have roles for setting up a Ruby installation with
rbenv
, getting my Emacs set up just the way I like
it, and for installing the GStreamer components that I
use frequently with Overscan.
Of all the roles that I use here, the one I’m most proud of is the
aesthetics
role.
aesthetics
This is a role to make my Mac look and feel like I want it to.
Like, for instance, pulling out the SF Mono font out of embedded applications into the system font library:
# https://simonfredsted.com/1438
- name: SF Mono font availability
copy:
src: ""
dest: ~/Library/Fonts/
with_fileglob:
- "/Applications/Utilities/Terminal.app/Contents/Resources/Fonts/SFMono*.otf"
tags:
- font
But the pièce de résistance of this role is the little hack to map the Caps Lock key to Control, which is the most important thing a developer can do for their productivity.
The first thing is to fetch information about the hardware from the system:
- name: Apple Internal Keyboard vendor/product id
shell: |
set -e
tmpfile=$(mktemp)
ioreg -c AppleHSSPIDevice -r -d 1 -a > $tmpfile
vendor_id=$(/usr/libexec/PlistBuddy -c 'Print :0:idVendor' $tmpfile)
product_id=$(/usr/libexec/PlistBuddy -c 'Print :0:idProduct' $tmpfile)
echo $vendor_id-$product_id-0
register: keyboard_id
changed_when: false
check_mode: no
ignore_errors: true
tags:
- keyboard
This will pull out a vendor and product id for an internal MacBook
keyboard. It does not work with USB or Bluetooth keyboards. Look at
this shell script! mktemp
, ioreg
, PlistBuddy
— the gang’s all
here! Next, I set some preferences using defaults
:
- name: Caps-Lock -> Ctrl mapping
shell: |
set -e
key='com.apple.keyboard.modifiermapping.'
found=$(defaults -currentHost find $key)
if [[ $found =~ ^Found ]]; then
echo $found
exit 0
else
defaults -currentHost write -globalDomain $key -array \
'<dict><key>HIDKeyboardModifierMappingDst</key><integer>30064771300</integer><key>HIDKeyboardModifierMappingSrc</key><integer>30064771129</integer></dict>'
fi
register: result
changed_when: result.stdout == ''
when: keyboard_id.rc == 0
tags:
- keyboard
This is Incantation TN2450 to tell Apple that one key on your keyboard is actually another key. Preferences are heavily cached, so give it a minute.
Feel free to check out Mechwarper and give it a run, but only if you want your Mac to behave just like my Mac. There’s a bunch more to do to get a machine fully operational, and I expect I’ll be adding those steps over time. Ansible makes this so easy!
For further reference check out some of these projects that served as inspiration:
Have a great weekend!
– Mark