How Omarchy's CLI Router Uses Longest-Prefix Matching for Command Dispatch
Omarchy's CLI router implements longest-prefix matching through a Bash associative array called GROUP_DESCRIPTIONS, iterating over all defined prefixes to find the longest match before dispatching to the appropriate sub-command script.
The Omarchy command-line interface routes user commands using a deterministic pattern-matching algorithm built entirely in shell script. Located at bin/omarchy, this dispatcher enables intuitive sub-command handling while resolving ambiguous inputs through prefix length comparison.
The Core Routing Algorithm in bin/omarchy
The router operates in three distinct phases: prefix registration, match evaluation, and script execution.
Phase 1: Prefix Registration via GROUP_DESCRIPTIONS
The dispatcher maintains authoritative command vocabulary in a Bash associative array defined near the top of bin/omarchy:
# EXCERPT from bin/omarchy (lines 22-45)
declare -A GROUP_DESCRIPTIONS=(
[theme]="Manage desktop themes"
[install]="Install Omarchy components"
[update]="Update Omarchy installation"
[toggle]="Toggle system features"
[toggle-touchscreen]="Toggle touchscreen support specifically"
# ... additional groups
)
Each key represents a valid command-group prefix. The values provide human-readable descriptions for help generation, but the keys themselves drive the routing logic.
Phase 2: Longest-Prefix Match Evaluation
When a user executes omarchy <arguments>, the router evaluates every prefix against the supplied input:
# EXCERPT from bin/omarchy (lines 80-98)
best_match=""
best_len=0
for prefix in "${!GROUP_DESCRIPTIONS[@]}"; do
# Check if user arguments start with this prefix
if [[ "$@" == "$prefix"* ]]; then
prefix_len=${#prefix}
# Keep the longest matching prefix
if (( prefix_len > best_len )); then
best_match="$prefix"
best_len=$prefix_len
fi
fi
done
This loop implements the longest-prefix matching rule explicitly: longer matches supersede shorter ones, even when multiple prefixes technically satisfy the condition.
Phase 3: Dispatch to Resolved Handler
After identifying the optimal prefix, the router constructs and executes the target script:
# EXCERPT from bin/omarchy (lines 105-113)
if [[ -n "$best_match" ]]; then
# Transform prefix to script name: theme -> omarchy-theme
script_path="$OMARCHY_ROOT/bin/omarchy-${best_match}"
# Execute with remaining arguments preserved
exec "$script_path" "${@:$best_len+1}"
else
show_help
fi
The exec call replaces the current process, ensuring signal handling and exit codes propagate correctly to the sub-command.
Practical Examples of Prefix Resolution
Example 1: Non-Overlapping Prefixes
$ omarchy theme set preferred
Match evaluation:
themematches (length 5) ✓- No longer prefix matches
Dispatch result: Executes bin/omarchy-theme with arguments set preferred
Example 2: Overlapping Prefixes (Demonstrating Longest-Prefix Rule)
$ omarchy toggle touchscreen enable
Match evaluation:
togglematches (length 6) ✓toggle-touchscreenmatches (length 17) ✓
Longest-prefix wins: Executes bin/omarchy-toggle-touchscreen with argument enable
This behavior ensures specific handlers take precedence over generic ones without requiring exact argument parsing.
Example 3: Exact Prefix Match
$ omarchy update
Match evaluation:
updatematches exactly (length 6) ✓
Dispatch result: Executes bin/omarchy-update with no additional arguments
Architecture Benefits of This Design
The longest-prefix matching approach provides several structural advantages:
- Extensibility: New command groups add single entries to
GROUP_DESCRIPTIONSwithout modifying router logic - Predictability: Users intuit that more specific commands (
toggle-touchscreen) override general ones (toggle) - Discoverability: The associative array doubles as the help system's data source
- Performance: For typical command sets (under 50 prefixes), linear scan overhead remains negligible
Key Source Files and Locations
| File | Purpose | Critical Lines |
|---|---|---|
bin/omarchy |
Central dispatcher implementing longest-prefix matching | 22-45 (GROUP_DESCRIPTIONS), 80-98 (matching loop), 105-113 (exec dispatch) |
bin/omarchy-<group> |
Individual command implementations (e.g., omarchy-theme, omarchy-toggle-touchscreen) |
Varies by command |
docs/cli.md |
CLI design documentation and command reference | N/A |
Summary
- Omarchy's CLI router resides in
bin/omarchyand implements longest-prefix matching through pure Bash - The
GROUP_DESCRIPTIONSassociative array registers all valid command-group prefixes with their descriptions - A linear scan compares each prefix against user input, tracking the longest successful match via
best_matchandbest_lenvariables - The winning prefix determines which
bin/omarchy-<prefix>script receives execution viaexec - This design resolves ambiguity deterministically: specific prefixes always defeat generic ones
Frequently Asked Questions
What happens if two prefixes have identical length and both match?
The loop processes GROUP_DESCRIPTIONS in arbitrary hash order, making behavior undefined for equal-length matches. In practice, Omarchy's prefix design avoids this scenario—no two command groups share identical length with overlapping character sequences.
Can users create custom command groups?
Yes, by adding entries to GROUP_DESCRIPTIONS and creating corresponding bin/omarchy-<prefix> scripts. The router treats user-defined prefixes identically to built-in ones during longest-prefix evaluation.
Does longest-prefix matching affect performance with many commands?
No. Bash associative array iteration over typical command sets (dozens of prefixes) completes in sub-millisecond times. The algorithm's O(n) complexity where n equals prefix count remains imperceptible for CLI interaction latencies.
How does the router handle completely unmatched input?
When no prefix satisfies the [[ "$@" == "$prefix"* ]] condition, best_match remains empty and the router invokes show_help, displaying available command groups from GROUP_DESCRIPTIONS in alphabetical order.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →