Personal configuration files for my macOS setup: keyboard remapping, tiling window management and video-editing keyboard layouts. Everything here is plain text so it can be diffed, versioned and restored on a fresh machine.
.
├── karabiner/
│ ├── 01…11-*.json # Karabiner-Elements complex modifications, one rule per file
│ ├── karabiner.json # the complete Karabiner config, ready to drop in
│ └── script_helpers/ # shell scripts the rules shell out to
├── aerospace.toml # AeroSpace tiling window manager config
└── finalcutpro.commandset # Final Cut Pro keyboard command set (binary plist)
- The layered idea behind this setup
karabiner/— Karabiner-Elementsaerospace.toml— AeroSpacefinalcutpro.commandset— Final Cut Pro
The three files are not independent — they are designed around one central idea: turn otherwise wasted keys into modifiers, so that the hands never leave the home area.
| Physical key | What it becomes |
|---|---|
caps lock (held) |
⌃⌥⇧ — the "hyper"/super modifier used by AeroSpace and by the shell-command rules |
caps lock (tapped) |
_ (underscore) |
tab (held) |
⌘ |
tab (tapped) |
tab |
fn |
⌃⌥⌘ + E (a single-key trigger for whatever app listens on that chord) |
home / end |
Instant Finder shortcuts to two frequently used locations |
page up / page down |
⌘+ / ⌘- (zoom), handy with presenter remotes and external keypads |
Because Caps Lock emits ⌃⌥⇧, every AeroSpace binding in aerospace.toml
(alt-ctrl-shift-*) is reachable as Caps Lock + key, and adding ⌘ on top
(cmd-alt-ctrl-shift-*) is Caps Lock + Tab + key.
The two layers also compose in a less obvious way: since Karabiner turns page up/page down into ⌘=/⌘- while letting the held modifiers through, Caps Lock + Page Up/Down
arrives at AeroSpace as cmd-alt-ctrl-shift-equal/-minus — which is exactly what the
window resize bindings listen for.
Karabiner-Elements is a low-level keyboard customizer for macOS. This folder holds the configuration twice over:
karabiner.json— the complete config as Karabiner-Elements writes it, so a fresh machine can be set up by copying one file. The only edit is the removal of themachine_specificblock, which holds a per-device UUID and local paths; Karabiner writes a fresh one on first run.01…11-*.json— the same 11 complex modifications split one per file, so each remap can be read, diffed and copied on its own. Reassembled they are byte-identical to therulesarray of the full config.
The numbers preserve the original rule order, which is also the order Karabiner evaluates them in when two rules could match the same key.
01 — recut cut → X to B · press X to cut in Recut
Active only when Recut is the frontmost app
(^co\.tinywins\.recut$). Remaps X to B, which is Recut's "cut
selection" command. Any modifier may be held ("optional": ["any"]), so ⌘X also arrives
as ⌘B.
The point is muscle memory: X is the blade key in Final Cut Pro, so the same finger does the same job in both apps.
02 — recut delete → Z to Delete · press Z to delete in Recut
Recut only. Remaps Z to ⌫ (delete_or_backspace), putting "remove
this take" under the left pinky instead of on the far side of the keyboard. Modifiers pass
through as optional.
03 — recut playback at 2x → E to L L · one key for double-speed playback
Recut only. A single press of E sends L L in rapid succession. Recut uses the classic JKL transport, where each extra L steps the playback rate up — so two of them means 2× forward playback from one keystroke.
04 — volume up and down for Apple Music · Caps Lock+Space toggles the music volume
Global. ⌃⌥⇧ + Space (i.e. Caps Lock + Space with rule 11 active) runs the shell
script:
/Users/$(whoami)/script_helpers/toggle_music_volume.sh
The script is a one-key ducking switch for when someone starts talking: an osascript call
that reads Music's sound volume and flips it between 100 (anything below 100 jumps
back to full) and 10.
Dependency: the rule shells out to an absolute path, so it is a no-op unless the script sits at
~/script_helpers/toggle_music_volume.shand is executable:cp -R karabiner/script_helpers ~/ && chmod +x ~/script_helpers/*.sh
05 — page up/down → ⌘+/⌘- · turn the paging keys into zoom keys
Global, two manipulators in one rule:
| From | To |
|---|---|
| Page Up | ⌘ + = (zoom in) |
| Page Down | ⌘ + - (zoom out) |
Modifiers are optional, so the mapping fires however the keys are pressed. Useful on full-size keyboards, remote presenters and numeric keypads whose paging keys would otherwise go unused — and it makes zooming a single, non-chorded keystroke in browsers, editors and timelines.
Because held modifiers pass through untouched, Caps Lock + Page Up/Down comes out as
⌃⌥⇧⌘= / ⌃⌥⇧⌘-, which AeroSpace binds to resize smart +50 / -50. Same two keys:
zoom the content on their own, resize the window with the super key held.
06 — accenti vocali · Italian accented vowels on a US keyboard
The biggest rule in the set: 10 manipulators that let a US/ANSI layout type Italian accents without switching input source or holding dead keys.
It works by simultaneous key detection — press a vowel together with a digit within
65 ms (basic.simultaneous_threshold_milliseconds: 65), in any order
(key_down_order/key_up_order are insensitive).
| Chord | Output | How it is produced |
|---|---|---|
| A+1 | à |
` dead key, then a |
| A+2 | á |
⌥E dead key, then a |
| E+1 | è |
` then e |
| E+2 | é |
⌥E then e |
| I+1 | ì |
` then i |
| I+2 | í |
⌥E then i |
| O+1 | ò |
` then o |
| O+2 | ó |
⌥E then o |
| U+1 | ù |
` then u |
| U+2 | ú |
⌥E then u |
So 1 = grave (the common Italian accent) and 2 = acute (needed for perché,
né, poiché…). detect_key_down_uninterruptedly is enabled so ordinary fast typing of
a vowel followed by a digit is not mistaken for a chord.
Requires a layout where
`and⌥Ebehave as dead keys (US / U.S. International / ABC). On a true Italian layout the outputs would differ.
File: 06-accenti-vocali.json
07 — end → open ~/hub/%temp in Finder · one key to the scratch folder
Global. End runs open '/Users/mattia/hub/%temp', opening the personal
scratch/downloads-staging folder in Finder. Modifiers optional.
Machine-specific: the path is hard-coded to
/Users/mattia. Change it when restoring on another account.
08 — home → open /Volumes/vvault in Finder · one key to the external drive
Global. Home runs open /Volumes/vvault, jumping straight to the vvault
volume (the media/archive drive). Modifiers optional. Together with rule 07, the
Home/End pair becomes a two-key file-navigation cluster.
Silently does nothing when the volume is not mounted.
09 — tab → ⌘ when held, tab when tapped · dual-role Tab key
Global dual-role remap:
- Tapped alone (
to_if_alone) → a normal Tab. - Held with another key → ⌘ (
left_command).
This puts Command under the left pinky's home row neighbour, so ⌘C, ⌘V, ⌘T, ⌘W
are all reachable without the thumb stretching under the palm. Combined with rule 11,
holding Caps Lock + Tab produces the full ⌃⌥⇧⌘ "hyper" chord used by the
cmd-alt-ctrl-shift-* AeroSpace bindings.
Note: while Tab is held it is Command, so app-switching with
⌘Tabhas to be done with the physical Command key.
10 — fn → ⌃⌥⌘+E · the globe key as a single-shot trigger
Global. The fn / 🌐 key, which macOS otherwise reserves for its own switcher,
is turned into the chord ⌃⌥⌘ + E — a rare combination that no app claims by default, so
it can be bound as a global hotkey in a launcher, a recorder, or any app that listens for
it. Modifiers optional.
11 — caps lock → ⌃⌥⇧ when held, _ when tapped · the keystone of the layout
_ when tappedGlobal dual-role remap, and the one every other shortcut is built on:
- Held →
⌃⌥⇧(left_shiftwithleft_control+left_option) — the "hyper" modifier. - Tapped alone (
to_if_alone) →_(⇧+-), i.e. an underscore.
Holding Caps Lock is what makes the AeroSpace alt-ctrl-shift-* bindings and the
shell-command rule 04 comfortable to reach; tapping it gives a dedicated
underscore key for snake_case file and variable names. Caps Lock's original function is
given up entirely.
A. Take everything — quit Karabiner-Elements, copy the full config into place, start it again:
cp karabiner/karabiner.json ~/.config/karabiner/karabiner.jsonThe numbered files are bare rule objects (description + manipulators), so they are
not a drop-in config on their own. Two ways to use them individually:
B. Merge into an existing profile — put the rule objects into
~/.config/karabiner/karabiner.json under
profiles[0].complex_modifications.rules:
jq -s '{profiles:[{complex_modifications:{rules:.}}]}' karabiner/[0-9]*.jsonC. Install as an importable asset — wrap them in the asset format and drop the result
into ~/.config/karabiner/assets/complex_modifications/, then enable the rules from
Karabiner-Elements → Complex Modifications → Add rule:
jq -s '{title:"macos-configs",rules:.}' karabiner/[0-9]*.json > ~/.config/karabiner/assets/complex_modifications/macos-configs.jsonKarabiner-Elements picks up changes to its config automatically; assets are read when the "Add rule" sheet is opened.
Config for AeroSpace, an i3-like tiling window
manager for macOS that works without disabling SIP. Lives at
~/.config/aerospace/aerospace.toml.
General behaviour
- Starts at login; no startup commands.
- Container normalization enabled (flatten single-child containers, alternate orientation when nesting).
- Default layout
tiles, orientationauto(horizontal on wide monitors, vertical on tall ones); accordion padding30. - QWERTY key mapping; the mouse re-centers on the newly focused monitor.
- Gaps:
10inner (both axes), outer30left/right,15top,20bottom.
Main mode bindings. Two modifier groups are used throughout — under the Karabiner
layout above, SUPER = Caps Lock and SUPER+⌘ = Caps Lock + Tab:
| Binding | Action |
|---|---|
SUPER H J K L |
Move the focused window (vim directions) |
SUPER+⌘ H J K L |
join-with — merge the window into the neighbouring container |
SUPER 1…5 M F Z C X |
Focus a workspace (M F Z X launch their app if empty) |
SUPER+⌘ 1…5 M F Z C X |
Move the window to that workspace and follow it |
SUPER Page Up / Page Down |
Resize the window smart +50 / -50 |
SUPER T / A |
Layout: tiles / accordion |
SUPER+⌘ T |
Layout: floating ⇄ tiling |
⌥Tab |
Workspace back-and-forth |
⌥⇧Tab |
Move the current workspace to the next monitor (wrapping) |
SUPER+⌘ S |
Enter service mode |
Floating sits on SUPER+⌘ T rather than on F, which is now the Finder workspace. The
resize bindings are written as cmd-alt-ctrl-shift-equal/-minus because that is what
Karabiner's page-key rule actually delivers — see
the note above.
Service mode (a one-shot mode that returns to main):
| Key | Action |
|---|---|
esc |
Reload the config and exit the mode |
r |
Flatten the workspace tree (reset the layout) |
backspace |
Close all windows except the current one |
Workspaces. Numbers are free-form; letters are dedicated to one app each.
| Workspace | Contents | Auto-launched app (open -b) |
|---|---|---|
1 |
Video editing — Recut (co.tinywins.recut), Final Cut Pro (com.apple.FinalCutTrial) |
— |
2 3 4 5 |
Free | — |
M |
Music | com.apple.Music |
F |
Finder | com.apple.finder (opens ~) |
Z |
Zen Browser | app.zen-browser.zen |
C |
Coding — Claude | — (assigned, never launched) |
X |
Calendar — Notion Calendar | com.cron.electron (still its old Cron id) |
Apps reach their workspace through on-window-detected rules, which fire when a window
appears. M, F, Z and X additionally launch their app on demand: the binding
runs workspace <W> and then, guarded by
aerospace list-windows --workspace <W> --count, an open -b <bundle-id> — so the app is
started only when the workspace is empty, and focusing a workspace that already has
windows never steals focus or spawns duplicates. C deliberately opts out: Claude lands
there when it is running, but SUPER + C is a plain workspace switch and never starts it.
Two Karabiner interactions to keep in mind:
- Rule 09 turns a held Tab into ⌘, so the
⌥Tab/⌥⇧Tabbindings need a quick, deliberate Tab tap. - Rule 01 rewrites X into B while Recut is frontmost, whatever
modifiers are held — so
SUPER + Xdoes not reach AeroSpace from inside Recut, and the calendar workspace has to be reached another way there. Every other app is unaffected.
A Final Cut Pro command set: an Apple binary plist mapping command identifiers to key
equivalents, covering ~124 commands. Import it via Final Cut Pro → Commands → Import…,
or copy it to ~/Library/Application Support/ProApps/Command Sets/.
To inspect it as readable JSON without changing the file:
plutil -convert json -o - finalcutpro.commandsetThe layout is built for one-hand, no-modifier editing: the left hand stays on the letter keys for edit operations while the right hand works the mouse/trackpad.
Single-key edit commands
| Key | Command | Key | Command |
|---|---|---|---|
X |
Blade at playhead | S |
Freeze frame |
W |
Detach audio | D |
Create compound clip |
N |
Add default video effect | V |
Enable / disable edit |
Q |
Trim end | Z |
Trim start |
C |
Delete | H |
Retime hold |
M |
Add marker | T |
Zoom to fit |
A |
Arrow / range-selection tool | R |
Range-selection tool |
G |
Insert gap | < |
Cut |
Transport (JKL, extended)
| Key | Command |
|---|---|
J |
Jog backward |
K |
Stop |
L / E |
Jog forward (two keys for the same command) |
Space or ⌃Space |
Play / pause |
? / ⌃⇧? |
Play around current frame |
⌘L |
Loop playback |
⇧⌘F |
Play fullscreen |
Tab |
Next clip |
⌥← / ⌥→ |
Jump to previous / next subframe |
fn← / fn→ |
Jump to previous / next frame |
⇧fn← / ⇧fn→ |
Jump backward / forward 10 frames |
Audio levels — clustered on the right-hand punctuation keys:
| Key | Command |
|---|---|
[ |
Volume up |
' |
Volume down |
; |
Volume zero |
] |
Volume −∞ (mute) |
⌘⌃W |
Toggle waveform |
⌃⌥↑ / ⌃⌥↓ |
Bigger / smaller audio in clip appearance |
⌃T |
Apply audio cross-fades to aligned clips |
Multicam
1–9cut/switch to angles 1–9, withUIOPas alternates for angles 1–4.⌃⇧←/⌃⇧→select previous / next angle.⇧⌘←/⇧⌘→select previous / next video angle.⌥⇧←/⌥⇧→select previous / next audio angle.
Transform, position and timeline
| Binding | Command |
|---|---|
, / . |
Nudge left / right |
⌥↑ / ⌥↓ |
Nudge up / down |
⌥⇧↑ / ⌥⇧↓ |
Nudge up / down (large step) |
⌃⌥⌘ ←→↑↓ |
Pan left/right, tilt up/down |
⌘← / ⌘→ |
Select previous / next item |
⌃⌘← / ⌃⌘→ |
Extend previous / next item |
⌘↑ / ⌘↓ |
Select upper / lower item |
⌘⌥↑ |
Lift from spine (also è) |
⌘⌥↓ |
Collapse to spine (also à) |
⌦ |
Replace with gap |
ò |
Toggle override connections |
⇧⌘- |
Decrease thumbnail size |
⌃⇧1 |
Organize layout |
⌘` |
Toggle events library |
Effects, retiming and color
| Binding | Command |
|---|---|
⌘M |
Add default audio effect |
⌥R |
Show retime editor |
⇧X |
Retime blade speed |
⌘R |
Render selection |
⇧⌘V |
Paste some attributes |
⌥D |
Break apart clip items |
⌥T |
Add basic lower third |
⌘T / ⇧Z |
Add basic title |
⌘⌃S |
Color board — switch to saturation tab |
⇧⌥⌘← / ⇧⌥⌘→ |
Previous / next decision (Cinematic editor) |
⌘⌥W |
Insert placeholder |
⇧⌘R |
Import XML |
⌃1 |
Add keyword group 1 |
⇧⌘- |
Decrease thumbnail size |
Standard system commands (⌘C, ⌘V, ⌘Z, ⌘A, ⌘F, ⌘D, ⌘Q, ⌘W, ⌘H, ⌘,,
⌘⌫ move to trash) keep their usual meanings. The command set also contains several
commands with no key assigned (most Color Board puck nudges, join selection, keyword
editor) — they are present but deliberately left unbound.
-
Install Karabiner-Elements, AeroSpace and Final Cut Pro.
-
Install the Karabiner config with one of the commands in Installing the rules, then enable it in the app.
-
Copy
aerospace.tomlto~/.config/aerospace/aerospace.tomland reload (SUPER+⌘ S, thenesc). -
Import
finalcutpro.commandsetfrom Final Cut Pro → Commands → Import…. -
Install the helper scripts rule 04 depends on:
cp -R karabiner/script_helpers ~/ && chmod +x ~/script_helpers/*.sh
-
Fix the machine-specific bits: the
/Users/mattiapath in rule 07 and the/Volumes/vvaultmount in rule 08.