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
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.
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
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!
PlistBuddy — the gang’s all
here! Next, I set some preferences using
- 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!