From 871877debf0a5a85c034cf057aa1eab96a52ada3 Mon Sep 17 00:00:00 2001 From: Mark Norman Francis Date: Mon, 7 Feb 2022 06:25:49 +0000 Subject: [PATCH] Add command to set keyboard shortcuts In more recent macOS versions it is almost impossible to set keyboard shortcuts automatically, so instead kitout checks to see if the shortcut is already set and prompts you to set it interactively if not. --- documentation/kitfile.markdown | 32 ++++++++++++++++ kitout.sh | 67 +++++++++++++++++++++++++++++++++- 2 files changed, 98 insertions(+), 1 deletion(-) diff --git a/documentation/kitfile.markdown b/documentation/kitfile.markdown index 6081533..6d9d39f 100644 --- a/documentation/kitfile.markdown +++ b/documentation/kitfile.markdown @@ -134,6 +134,38 @@ Available commands are: application to use Accessibility features) without them being buried among the entire output of a run. +* shortcuts _FILE_ _APPLICATION_ + + A specialised reminder type for setting keyboard shortcuts for + _APPLICATION_. Since it is now almost impossible to set them + automatically, `kitout` will instead check if the custom shortcuts are + set, and if not open the Keyboards preference pane and prompt you to set + the shortcut, waiting until you hit \[Return\]. + + The shortcut _FILE_ should be the same name as the application's + preferences domain (eg for Things 3, use `com.culturedcode.ThingsMac` + — this can be found by looking in `~/Library/Preferences`). + The contents of the file uses the form: + + # remember to enable the Developer menu + cmd-opt-j Disable JavaScript + cmd+opt+c Disable Styles + + Blank lines and comments are ignored. The keyboard modifiers are: + + * `cmd` or `command` + * `alt`, `opt` or `option` + * `ctrl` or `control` + * `shift` + + The key is expected to be a letter, a number, or: + + * `up`, `down`, `left`, `right` + * `return` + * `tab` + * `F1` through `F12` + + * dock\_add _POSITION_ [_TYPE_] _APPLICATION_ Adds _APPLICATION_ to the Dock at _POSITION_. For applications that are diff --git a/kitout.sh b/kitout.sh index 7f42686..088851d 100755 --- a/kitout.sh +++ b/kitout.sh @@ -134,7 +134,7 @@ function process_kitfile { local -a lines while IFS= read -r line; do lines+=("$line") - done < "$kitfile" + done < <( cat "$kitfile"; echo '' ) for line in "${lines[@]}"; do line=$( @@ -164,6 +164,7 @@ function process_kitfile { run) run_script $argument ;; brew_update) brew_update ;; + shortcuts) shortcuts $argument ;; dock_add) dock_add $argument ;; dock_remove) dock_remove $argument ;; cron_entry) add_to_crontab "$argument" ;; @@ -355,6 +356,70 @@ function loginitem { EOF } +function shortcuts { + local defaults_file="$1" + shift + local app="$*" + local header=0 code menu shortcut menu_item + + local -a lines + while IFS= read -r line; do + lines+=("$line") + done < <( cat "$defaults_file"; echo '' ) + + for line in "${lines[@]}"; do + read shortcut menu_item <<<"$line" + [ -z "$shortcut" ] && continue + [[ "$shortcut" == \#* ]] && continue + + # convert human readable shortcuts + menu=$( + echo "$menu_item" \ + | sed -e 's/…/..U2026./' \ + | sed -e 's/\(.* .*\)/"\1"/' + ) + code=$( + echo "$shortcut" \ + | perl -pe ' + s{\bF1\b}{\\\\\\\\Uf704}; + s{\bF2\b}{\\\\\\\\Uf705}; + s{\bF3\b}{\\\\\\\\Uf706}; + s{\bF4\b}{\\\\\\\\Uf707}; + s{\bF5\b}{\\\\\\\\Uf708}; + s{\bF6\b}{\\\\\\\\Uf709}; + s{\bF7\b}{\\\\\\\\Uf70a}; + s{\bF8\b}{\\\\\\\\Uf70b}; + s{\bF9\b}{\\\\\\\\Uf70c}; + s{\bF10\b}{\\\\\\\\Uf70d}; + s{\bF11\b}{\\\\\\\\Uf70e}; + s{\bF12\b}{\\\\\\\\Uf70f}; + s{(cmd|command)[+-]}{@}; + s{(alt|opt(ion)?)[+-]}{~}; + s{shift[+-]}{\$}; + s{(control|ctrl)[+-]}{^}; + s{left}{\\\\\\\\U2190}; + s{up}{\\\\\\\\U2191}; + s{right}{\\\\\\\\U2192}; + s{down}{\\\\\\\\U2193}; + s{return}{\\\\\\\\U21a9}; + s{tab}{\\\\\\\\U21e5}; + ' + ) + + if ! defaults read "$defaults_file" NSUserKeyEquivalents \ + | grep "$menu = \"$code\"" >/dev/null + then + if [ $header = 0 ]; then + action "Keyboard shortcuts for '$app':" + header=1 + open /System/Library/PreferencePanes/Keyboard.prefPane \ + || true + fi + alert "Set '$menu_item' shortcut to '$shortcut'" + fi + done +} + function brew_update { action 'updating homebrew' brew update