These pages are for anyone who wants to understand, fix or extend XCommander, including future me. I'm an iOS developer who learned AppKit, event taps and the Accessibility API while building this, so the guides assume you know Swift and some UIKit or SwiftUI, and nothing about macOS internals.
- Architecture: the map. Targets, the keystroke path, who owns what, threads, where things are stored.
- AppKit for iOS developers: menu-bar apps, windows that never take focus, upside-down coordinates, the run loop.
- The journey of a keystroke: event taps, keyboard layouts, the leader, the session state machine, the which-key panel.
- Driving Xcode with Accessibility: reading Xcode's menus, pressing items, following its window, editing the selection, panes.
- Permissions, signing and the dev loop: building, running, why the Accessibility grant keeps disappearing, and what releasing involves.
- Debugging: logs,
xcmdr doctor, the Accessibility Inspector, common problems. - Configuration: the
config.tomlformat, for users and for working on the config code. - Surviving Xcode upgrades: how the app absorbs Xcode changes, why one
install serves every Xcode, what happens to your config, every case and what to do, the
xcmdrtool, and how to help with an Xcode beta. - Decisions: why things are the way they are.
If you learn best by doing, as I do, here's a path through the codebase. Each step is an hour or two: read the files, read their tests, change something, watch a test fail, put it back.
| Day | Read | Try |
|---|---|---|
| 1 | Companion/main.swift, AppDelegate.applicationDidFinishLaunching, MenuBarController |
Run the app, change the text of a menu item |
| 2 | EventTap.swift, AppDelegate.handleKey, EventBridge, KeyIdentity |
Write a test that feeds KeymapSession a sequence and checks each decision |
| 3 | KeymapSession, Keymap, DefaultKeymap and their tests |
Add a binding, then add a test for it |
| 4 | OverlayController, WindowTracker |
Change the panel's delay or position |
| 5 | XcodeContext, CommandExecutor, MenuScanner |
Bind a menu item that isn't bound yet, found with xcmdr list |
| 6 | Picker.swift, FuzzyMatcher, PickerOverlay |
Change how picker results are ranked |
| 7 | PaneController, PaneLayout, XcodeAXSchema |
Use the Accessibility Inspector on Xcode's editor panes |
The tests are the best documentation of the rules: each one names a situation, often a bug that really happened.