From 3986522d6e37029bff14ff7316e57e42308fcb89 Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Wed, 27 May 2026 11:20:42 +0200 Subject: [PATCH] Extend shell bar config command --- bin/omarchy-config-shell-bar | 64 +++++++++++++++++++++++++++-- default/bash/completions | 79 ++++++++++++++++++++++++++++++++---- test/shell.d/config-test.sh | 20 ++++++++- 3 files changed, 150 insertions(+), 13 deletions(-) diff --git a/bin/omarchy-config-shell-bar b/bin/omarchy-config-shell-bar index 07df242f..87e7c0a8 100755 --- a/bin/omarchy-config-shell-bar +++ b/bin/omarchy-config-shell-bar @@ -1,8 +1,8 @@ #!/bin/bash # omarchy:summary=Mutate the user shell.json bar layout -# omarchy:args=add [left|center|right] | drop | show -# omarchy:examples=omarchy config shell bar add omarchy.tailscale | omarchy config shell bar drop omarchy.tailscale | omarchy config shell bar show +# omarchy:args=add [left|center|right] | drop | position | transparent | show +# omarchy:examples=omarchy config shell bar add omarchy.tailscale | omarchy config shell bar position top | omarchy config shell bar transparent true | omarchy config shell bar show set -euo pipefail @@ -11,7 +11,7 @@ OMARCHY_ROOT="${OMARCHY_PATH:-}" DEFAULTS_FILE="$OMARCHY_ROOT/config/omarchy/shell.json" usage() { - echo "Usage: omarchy-config-shell-bar add [left|center|right] | drop | show" >&2 + echo "Usage: omarchy-config-shell-bar add [left|center|right] | drop | position | transparent | show" >&2 } fail() { @@ -40,7 +40,7 @@ case "$command" in exit 1 fi - jq . "$(source_file)" + jq '.bar // {}' "$(source_file)" ;; add) if (( $# < 2 || $# > 3 )); then @@ -93,6 +93,62 @@ case "$command" in trap - EXIT omarchy-shell -q shell rescanPlugins >/dev/null 2>&1 || true ;; + position) + if (( $# != 2 )); then + usage + exit 1 + fi + + position="${2:-}" + + [[ $position =~ ^(top|bottom|left|right)$ ]] || fail "position must be top, bottom, left, or right" + + mkdir -p "$(dirname "$CONFIG_FILE")" + + source="$(source_file)" + tmp=$(mktemp) + trap 'rm -f "$tmp"' EXIT + + jq --arg position "$position" ' + def object_or_empty: if type == "object" then . else {} end; + + object_or_empty + | .version = 1 + | .bar = (.bar | object_or_empty) + | .bar.position = $position + ' "$source" >"$tmp" + + mv "$tmp" "$CONFIG_FILE" + trap - EXIT + ;; + transparent) + if (( $# != 2 )); then + usage + exit 1 + fi + + transparent="${2:-}" + + [[ $transparent =~ ^(true|false)$ ]] || fail "transparent must be true or false" + + mkdir -p "$(dirname "$CONFIG_FILE")" + + source="$(source_file)" + tmp=$(mktemp) + trap 'rm -f "$tmp"' EXIT + + jq --argjson transparent "$transparent" ' + def object_or_empty: if type == "object" then . else {} end; + + object_or_empty + | .version = 1 + | .bar = (.bar | object_or_empty) + | .bar.transparent = $transparent + ' "$source" >"$tmp" + + mv "$tmp" "$CONFIG_FILE" + trap - EXIT + ;; drop) if (( $# != 2 )); then usage diff --git a/default/bash/completions b/default/bash/completions index 8a827137..0b693423 100644 --- a/default/bash/completions +++ b/default/bash/completions @@ -40,14 +40,79 @@ _omarchy_complete() { candidates+=("--all" "--json" "--markdown" "--check") fi - if (( ${#candidates[@]} == 0 )) && [[ -x $bin_dir/$prefix ]]; then - local args enum - args=$(grep -m 1 '^# omarchy:args=<' "$bin_dir/$prefix" 2>/dev/null) - enum="${args#*<}" - enum="${enum%%>*}" + if (( ${#candidates[@]} == 0 )); then + local command_prefix command_path first_arg_index n j + for ((n = COMP_CWORD - 1; n >= 0; n--)); do + command_prefix="omarchy" + for ((j = 1; j <= n; j++)); do + part="${COMP_WORDS[j]}" + [[ -z $part || $part == -* ]] && continue + command_prefix+="-$part" + done - if [[ $enum == *"|"* && $enum != *" "* ]]; then - read -r -a candidates <<<"${enum//|/ }" + command_path="$bin_dir/$command_prefix" + if [[ -x $command_path ]]; then + first_arg_index=$((n + 1)) + break + fi + done + + if [[ -n ${command_path:-} && -x $command_path ]]; then + local args spec alt token actual alts value match current_arg_index + args=$(grep -m 1 '^# omarchy:args=' "$command_path" 2>/dev/null) + args="${args#*omarchy:args=}" + current_arg_index=$((COMP_CWORD - first_arg_index)) + + alts="${args// | /$'\n'}" + while IFS= read -r alt; do + read -r -a spec <<<"$alt" + match=true + + for ((j = 0; j < current_arg_index; j++)); do + token="${spec[j]:-}" + actual="${COMP_WORDS[first_arg_index + j]:-}" + if [[ -z $token ]]; then + match=false + break + fi + + if [[ $token == \<*\> || $token == \[*\] ]]; then + value="${token#<}" + value="${value#\[}" + value="${value%>}" + value="${value%\]}" + if [[ $value == *"|"* ]]; then + [[ " ${value//|/ } " == *" $actual "* ]] || match=false + fi + elif [[ $token != "$actual" ]]; then + match=false + fi + done + + [[ $match == true ]] || continue + + token="${spec[current_arg_index]:-}" + [[ -n $token ]] || continue + + if [[ $token == \<*\> || $token == \[*\] ]]; then + value="${token#<}" + value="${value#\[}" + value="${value%>}" + value="${value%\]}" + if [[ $value == *"|"* ]]; then + read -r -a spec <<<"${value//|/ }" + for actual in "${spec[@]}"; do + [[ -n ${seen[$actual]:-} ]] && continue + seen[$actual]=1 + candidates+=("$actual") + done + fi + else + [[ -n ${seen[$token]:-} ]] && continue + seen[$token]=1 + candidates+=("$token") + fi + done <<<"$alts" fi fi diff --git a/test/shell.d/config-test.sh b/test/shell.d/config-test.sh index 1f8960b0..95968702 100755 --- a/test/shell.d/config-test.sh +++ b/test/shell.d/config-test.sh @@ -139,9 +139,25 @@ pass "shell config moves existing widgets without duplicates" HOME="$TMPDIR/home" OMARCHY_PATH="$ROOT" omarchy-config-shell-bar show | jq -e ' def ids: map(.id // .); - .bar.layout.right | ids == ["omarchy.tray", "local.first", "omarchy.tailscale", "omarchy.bluetooth"] + (.layout.right | ids == ["omarchy.tray", "local.first", "omarchy.tailscale", "omarchy.bluetooth"]) and + has("version") | not ' >/dev/null -pass "shell config shows bar json" +pass "shell config shows only bar json" + +HOME="$TMPDIR/home" OMARCHY_PATH="$ROOT" omarchy-config-shell-bar position bottom +jq -e ' + .bar.position == "bottom" and + .plugins == [] +' "$TMPDIR/home/.config/omarchy/shell.json" >/dev/null +pass "shell config sets bar position" + +HOME="$TMPDIR/home" OMARCHY_PATH="$ROOT" omarchy-config-shell-bar transparent true +jq -e ' + .bar.transparent == true and + .bar.position == "bottom" and + .plugins == [] +' "$TMPDIR/home/.config/omarchy/shell.json" >/dev/null +pass "shell config sets bar transparency" HOME="$TMPDIR/home" OMARCHY_PATH="$ROOT" omarchy-config-shell-bar drop local.left jq -e '