Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 32 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ The service will:

### Additional Features (New in skhd.zig!)

- **Key aliases**: Define reusable aliases for modifiers, keys, and key combinations
- **Process groups**: Define named groups of applications for cleaner configs
- **Command definitions**: Define reusable commands with placeholders to reduce repetition
- **Key Forwarding**: Forward / remap key binding to another key binding
Expand Down Expand Up @@ -184,6 +185,12 @@ The configuration syntax is fully compatible with the original skhd. See [SYNTAX
# Load additional config files
.load "~/.config/skhd/extra.skhdrc"

# Define key aliases for reusable modifier/key combinations (New in skhd.zig!)
.alias $super cmd + alt
.alias $mega cmd + alt + shift + ctrl
.alias $grave 0x32 # UK keyboard backtick
.alias $nav_left $super - h

# Define process groups for reuse (New in skhd.zig!)
.define terminal_apps ["kitty", "wezterm", "terminal"]
.define native_apps ["kitty", "wezterm", "chrome", "whatsapp"]
Expand Down Expand Up @@ -369,23 +376,31 @@ resize < escape ; winmode
### Window Management Example

```bash
# Focus windows using command definitions (New in skhd.zig!)
cmd - h : @yabai_focus("west")
cmd - j : @yabai_focus("south")
cmd - k : @yabai_focus("north")
cmd - l : @yabai_focus("east")

# Move/swap windows using command definitions
cmd + shift - h : @yabai_swap("west")
cmd + shift - j : @yabai_swap("south")
cmd + shift - k : @yabai_swap("north")
cmd + shift - l : @yabai_swap("east")

# Resize windows using command definitions
cmd + ctrl - h : @resize_window("left", "-20", "0")
cmd + ctrl - l : @resize_window("right", "20", "0")

# Switch spaces
# Define aliases for cleaner config (New in skhd.zig!)
.alias $super cmd + alt
.alias $mega $super + shift

# Focus windows using command definitions and aliases
$super - h : @yabai_focus("west")
$super - j : @yabai_focus("south")
$super - k : @yabai_focus("north")
$super - l : @yabai_focus("east")

# Move/swap windows using nested alias
$mega - h : @yabai_swap("west")
$mega - j : @yabai_swap("south")
$mega - k : @yabai_swap("north")
$mega - l : @yabai_swap("east")

# Define keysym aliases for common operations
.alias $focus_west $super - h
.alias $focus_east $super - l

# Use keysym alias standalone or with additional modifiers
$focus_west : @yabai_focus("west")
ctrl + $focus_west : @yabai_focus("west") # With extra modifier
Copy link

Copilot AI Nov 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These two examples (lines 400-401) demonstrate the same keybinding calling the same command, which doesn't effectively showcase the feature. Line 400 shows $focus_west (which expands to $super - h = cmd + alt - h) and line 401 shows ctrl + $focus_west (which adds ctrl to make ctrl + cmd + alt - h). However, both execute the identical command @yabai_focus("west"), making it unclear why you'd bind different key combinations to the same action. Consider either:

  1. Using different commands (e.g., @yabai_focus("west") vs @yabai_focus_and_warp("west"))
  2. Adding a comment explaining this is just demonstrating the syntax flexibility
  3. Removing the duplicate binding as was done in the test on line 2594-2596
Suggested change
ctrl + $focus_west : @yabai_focus("west") # With extra modifier
ctrl + $focus_west : @yabai_focus("west") # Demonstrates that key aliases can be used with extra modifiers; both bindings perform the same action for syntax flexibility illustration

Copilot uses AI. Check for mistakes.

# Traditional syntax still works
cmd - 1 : yabai -m space --focus 1
cmd - 2 : yabai -m space --focus 2
```
Expand Down
161 changes: 161 additions & 0 deletions SYNTAX.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,167 @@ name = desired name for this mode
command = command is executed through '$SHELL -c'
```


## Key Aliases

Key aliases allow you to define reusable names for modifiers, keys, and key combinations, making configurations more readable and maintainable.

### Syntax

```
alias_def = '.alias' <alias_name> <alias_value>

alias_name = '$' <identifier>

alias_value = <modifier_combo> | # Modifier alias
<key_spec> | # Key alias
<modifier_combo> '-' <key_spec> # Keysym alias

modifier_combo = <modifier> | <modifier> '+' <modifier_combo> | <alias_name>

key_spec = <literal> | <keycode> | <alias_name>
```

### Alias Types

#### 1. Modifier Alias
Defines a modifier combination that can be reused and combined with other modifiers.

```bash
.alias $super cmd + alt
.alias $hyper cmd + alt + ctrl + shift

# Use standalone
$super - h : echo "Super+H"

# Combine with other modifiers (like built-in hyper/meh)
$super + shift - h : echo "Super+Shift+H"
```

#### 2. Key Alias
Defines a key (with optional modifiers baked in) that can be used in key position.

```bash
.alias $grave 0x32 # Hex keycode
.alias $exclaim shift - 1 # Key with modifier

# Use in key position
ctrl - $grave : echo "Ctrl+Grave"
ctrl - $exclaim : echo "Ctrl+Shift+1" # Modifiers merge!
```

#### 3. Keysym Alias
Defines a complete key combination (modifier + key) that can be used standalone or with additional modifiers.

```bash
.alias $nav_left cmd - h
.alias $terminal_key cmd + shift - t

# Use standalone (macro expansion)
$nav_left : yabai -m window --focus west

# Add more modifiers
ctrl + $nav_left : yabai -m window --focus west # Becomes: ctrl+cmd - h
```

### Nesting

Aliases can reference other aliases, and they are fully expanded at parse time:

```bash
# Nested modifiers
.alias $super cmd + alt
.alias $mega $super + shift + ctrl # Expands to: cmd+alt+shift+ctrl

# Nested keys
.alias $grave 0x32
.alias $tilde shift - $grave # Expands to: shift - 0x32

# Nested keysyms
.alias $nav_left $super - h # Expands to: cmd+alt - h
.alias $special_nav ctrl + $nav_left # Expands to: ctrl+cmd+alt - h
```

### Valid Usage Contexts

| Alias Type | Standalone | As Modifier | In Key Position | With + Modifier |
|------------|------------|-------------|-----------------|-----------------|
| Modifier | ✗ | ✓ | ✗ | ✓ |
| Key | ✗ | ✗ | ✓ | ✗ |
| Keysym | ✓ | ✗ | ✗ | ✓ |

### Examples

```bash
# Define aliases
.alias $super cmd + alt
.alias $mega $super + shift + ctrl
.alias $grave 0x32
.alias $tilde shift - $grave
.alias $nav_left $super - h

# Modifier alias - can combine like hyper/meh
$super - t : open -a Terminal.app
$super + shift - t : open -a "New Terminal"

# Key alias - only in key position
ctrl - $grave : open -a Notes.app
$super - $tilde : open -a "System Settings"

# Keysym alias - standalone or with additional modifiers
$nav_left : yabai -m window --focus west
ctrl + $nav_left : yabai -m window --focus west # Add ctrl
```

### Common Errors

#### Using Wrong Alias Type

```bash
# ✗ WRONG: Key alias as modifier
.alias $grave 0x32
$grave - t : echo "bad" # Error: $grave is a key, not a modifier

# ✓ CORRECT: Use in key position
ctrl - $grave : echo "good"

# ✗ WRONG: Modifier alias in key position
.alias $hyper cmd + alt
ctrl - $hyper : echo "bad" # Error: $hyper is a modifier, not a key

# ✓ CORRECT: Use as modifier
$hyper - t : echo "good"

# ✗ WRONG: Modifier alias standalone
.alias $hyper cmd + alt
$hyper : echo "bad" # Error: needs a key

# ✓ CORRECT: Add a key
$hyper - t : echo "good"
```

#### Missing $ Prefix

```bash
.alias $hyper cmd + alt
hyper - t : echo "bad" # Error! Did you mean '$hyper'?
```

#### Circular References

```bash
.alias $a $b + shift # Error: $b not defined yet
.alias $b $a + ctrl
```
Comment on lines +252 to +257
Copy link

Copilot AI Nov 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This example shows forward reference (using an undefined alias), not a circular reference. A true circular reference would be:

.alias $a $b + shift
.alias $b $a + ctrl   # Both depend on each other

However, this would also fail with "Undefined alias" since $b isn't defined when $a tries to use it. Consider either:

  1. Showing a different example that better illustrates the concept (though true circularity may be hard to achieve in practice)
  2. Renaming this section to "Forward References" or "Undefined Aliases" to match what the example actually demonstrates
  3. Clarifying that circular reference detection exists but most circular cases manifest as undefined alias errors

Copilot uses AI. Check for mistakes.

### Benefits

- **Readability**: Complex modifier combinations get meaningful names
- **Maintainability**: Change definition once, affects all uses
- **Keyboard Layouts**: Abstract away layout-specific hex codes
- **Consistency**: Same modifier combo everywhere
- **Composability**: Combine aliases like built-in hyper/meh

## Modifiers

### Basic Modifiers
Expand Down
Loading