Skip to content

Commit 0d13073

Browse files
committed
feat: arrow key menu, hot corners audit table, misc fixes
- Arrow key navigation in show_menu: Up/Down, Enter/Right to select, Left to go back - Hot corners refactored to audit table pattern, removed unnecessary Dock restart - Hot corners fallback "not set" → 0 for defaults write safety - Install command switched to pipe syntax for fish compatibility - VERSION bumped to 26.03.1
1 parent cf9ea57 commit 0d13073

5 files changed

Lines changed: 108 additions & 86 deletions

File tree

CHANGELOG.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,19 @@
99
- **DNS provider menu** — 11 providers: Cloudflare, Google, Quad9, OpenDNS, AdGuard, NextDNS, Comodo, ControlD (Ads/Family/Uncensored), Hagezi Pro Plus
1010
- **Homebrew Cleanup** — dedicated option in Cleanup menu: `brew cleanup --prune=all && brew autoremove`, dry-run aware
1111
- **Ghostty Catppuccin themes** — Mocha and Latte auto-downloaded from `catppuccin/ghostty` on config apply
12+
- **Arrow key menu navigation** — Up/Down to move, Enter/Right to select, Left to go back; number keys still work
1213

1314
### Changed
1415

1516
- **Spicetify Marketplace** moved from Customize menu → Spotify submenu ("Spicetify — restore marketplace")
1617
- **Menu cursor** hidden during display (`\033[?25l/h`) for cleaner rendering
1718
- **Menu number width** dynamic — aligns correctly for menus with 10+ items
1819
- **Audit table** — booleans normalized (1/0 → true/false); unset values shown as `default` (dim instead of red); cancel and no-change flows auto-`wait_enter`
19-
- **Hot Corners**"Press enter to keep current" hint added; early return if nothing changed
20+
- **Hot Corners**refactored to audit table pattern (current vs new); no longer restarts Dock unnecessarily
2021
- **`apply_all_tweaks`** — confirmation prompt removed; function moved before `tweaks_menu`
2122
- **Label renames** — "Terminal" → "Terminal Emulator", "Install macrift profile" → "Apply theme profile", "Both" → "Starship + .zshrc", "Apply config from macrift" → "Apply config"
2223
- **Spotify menu item** relabeled to "Spotify (SpotX + Spicetify)"
24+
- **Install command** — switched from process substitution to pipe (`curl | bash`) for fish shell compatibility
2325

2426
### Packages
2527

@@ -33,6 +35,10 @@
3335
- Complete overhaul with annotated sections: Workbench, Explorer, Tabbar, Cursor, Editor, Fonts & Lines
3436
- Sidebar left; status bar hidden; single active tab; compact tabs; `Maple Mono` UI font; `Fira Code` 16px; `source.organizeImports` on save; tabs (not spaces)
3537

38+
### Fixed
39+
40+
- **Hot Corners** — fallback for unset corners changed from `"not set"` string to `0`, preventing `defaults write -int` errors
41+
3642
### Removed
3743

3844
- `stubs/status-bar.md`

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ Fresh Mac → full setup in minutes.
4040
## Quick Start
4141

4242
```bash
43-
bash <(curl -fsSL https://raw.githubusercontent.com/emylfy/macrift/main/install.sh)
43+
curl -fsSL https://raw.githubusercontent.com/emylfy/macrift/main/install.sh | bash
4444
```
4545

4646
Installs to `~/.macrift`, creates a global `macrift` command, and launches automatically.

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
26.03
1+
26.03.1

common.sh

Lines changed: 87 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -56,85 +56,110 @@ show_menu() {
5656
local count=${#items[@]}
5757
local last_idx=$((count - 1))
5858

59-
# Calculate box width from longest item (skip separators)
60-
local max_len=0
61-
local i
62-
for ((i=0; i<count; i++)); do
59+
# Build selectable items: sel_nums[i]=choice number, sel_labels[i]=label
60+
local sel_nums=() sel_labels=()
61+
local i num=0
62+
for ((i=0; i<last_idx; i++)); do
6363
[[ "${items[$i]}" == "---" ]] && continue
64-
if [[ ${#items[$i]} -gt $max_len ]]; then
65-
max_len=${#items[$i]}
66-
fi
64+
num=$((num + 1))
65+
sel_nums+=("$num")
66+
sel_labels+=("${items[$i]}")
6767
done
68+
sel_nums+=(0)
69+
sel_labels+=("${items[$last_idx]}")
70+
local sel_total=${#sel_nums[@]}
6871

69-
# Count real items (skip separators) to get max number width
70-
local real_count=0
71-
for ((i=0; i<last_idx; i++)); do
72+
# Box dimensions
73+
local max_len=0
74+
for ((i=0; i<count; i++)); do
7275
[[ "${items[$i]}" == "---" ]] && continue
73-
real_count=$((real_count + 1))
76+
[[ ${#items[$i]} -gt $max_len ]] && max_len=${#items[$i]}
7477
done
78+
local real_count=$num
7579
local num_w=${#real_count}
76-
# inner = " " + num + " › " + item + " "
7780
local inner_w=$((2 + num_w + 3 + max_len + 2))
7881
local title_min=$((${#title} + 5))
79-
if [[ $title_min -gt $inner_w ]]; then
80-
inner_w=$title_min
81-
fi
82-
82+
[[ $title_min -gt $inner_w ]] && inner_w=$title_min
8383
local top_fill=$((inner_w - ${#title} - 3))
8484

85-
local BP="${BOLD}${GRAY}"
86-
local R="${RESET}"
85+
local BP="${BOLD}${GRAY}" R="${RESET}"
86+
local total_lines=$((last_idx + 8))
87+
local sel=0 first_draw=true
8788

8889
printf "\033[?25l" >&2
8990

90-
printf "\n" >&2
91-
# ╭─ Title ───╮
92-
printf ' %b╭─ %b%s%b ' "$BP" "${R}${BOLD}${ICE}" "$title" "${R}${BP}" >&2
93-
printf '─%.0s' $(seq 1 $top_fill) >&2
94-
printf '╮%b\n' "$R" >&2
95-
# │ (empty) │
96-
printf ' %b│%b%*s%b│%b\n' "$BP" "$R" "$inner_w" "" "$BP" "$R" >&2
97-
# │ N › Item │ (items 1..N-1, "---" renders as blank separator line)
98-
local num=0
99-
for ((i=0; i<last_idx; i++)); do
100-
if [[ "${items[$i]}" == "---" ]]; then
101-
printf ' %b│%b%*s%b│%b\n' "$BP" "$R" "$inner_w" "" "$BP" "$R" >&2
102-
continue
91+
while true; do
92+
if $first_draw; then
93+
first_draw=false
94+
else
95+
printf "\033[%dA\r" "$total_lines" >&2
10396
fi
104-
num=$((num + 1))
105-
local vis=$((2 + num_w + 3 + ${#items[$i]}))
97+
98+
printf "\n" >&2
99+
printf ' %b╭─ %b%s%b ' "$BP" "${R}${BOLD}${ICE}" "$title" "${R}${BP}" >&2
100+
printf '─%.0s' $(seq 1 $top_fill) >&2
101+
printf '╮%b\n' "$R" >&2
102+
printf ' %b│%b%*s%b│%b\n' "$BP" "$R" "$inner_w" "" "$BP" "$R" >&2
103+
104+
local num=0 sel_idx=0
105+
for ((i=0; i<last_idx; i++)); do
106+
if [[ "${items[$i]}" == "---" ]]; then
107+
printf ' %b│%b%*s%b│%b\n' "$BP" "$R" "$inner_w" "" "$BP" "$R" >&2
108+
continue
109+
fi
110+
num=$((num + 1))
111+
local vis=$((2 + num_w + 3 + ${#items[$i]}))
112+
local pad=$((inner_w - vis))
113+
if [[ $sel_idx -eq $sel ]]; then
114+
printf ' %b│%b %b%*d › %s%b%*s%b│%b\n' \
115+
"$BP" "$R" "${BOLD}${ICE}" "$num_w" "$num" "${items[$i]}" "$R" "$pad" "" "$BP" "$R" >&2
116+
else
117+
printf ' %b│%b %b%*d%b %b›%b %s%*s%b│%b\n' \
118+
"$BP" "$R" "$CYAN" "$num_w" "$num" "$R" "$DIM" "$R" "${items[$i]}" "$pad" "" "$BP" "$R" >&2
119+
fi
120+
((sel_idx++))
121+
done
122+
123+
printf ' %b│%b%*s%b│%b\n' "$BP" "$R" "$inner_w" "" "$BP" "$R" >&2
124+
local vis=$((2 + num_w + 3 + ${#items[$last_idx]}))
106125
local pad=$((inner_w - vis))
107-
printf ' %b│%b %b%*d%b %b›%b %s%*s%b│%b\n' "$BP" "$R" "$CYAN" "$num_w" "$num" "$R" "$DIM" "$R" "${items[$i]}" "$pad" "" "$BP" "$R" >&2
108-
done
109-
# │ (empty) │
110-
printf ' %b│%b%*s%b│%b\n' "$BP" "$R" "$inner_w" "" "$BP" "$R" >&2
111-
# │ 0 › Back │ (last item = 0)
112-
local vis=$((2 + num_w + 3 + ${#items[$last_idx]}))
113-
local pad=$((inner_w - vis))
114-
printf ' %b│%b %b%*d › %s%b%*s%b│%b\n' "$BP" "$R" "$DIM" "$num_w" 0 "${items[$last_idx]}" "$R" "$pad" "" "$BP" "$R" >&2
115-
# │ (empty) │
116-
printf ' %b│%b%*s%b│%b\n' "$BP" "$R" "$inner_w" "" "$BP" "$R" >&2
117-
# ╰───────────╯
118-
printf ' %b╰' "$BP" >&2
119-
printf '─%.0s' $(seq 1 $inner_w) >&2
120-
printf '╯%b\n' "$R" >&2
126+
if [[ $sel_idx -eq $sel ]]; then
127+
printf ' %b│%b %b%*d › %s%b%*s%b│%b\n' \
128+
"$BP" "$R" "${BOLD}${ICE}" "$num_w" 0 "${items[$last_idx]}" "$R" "$pad" "" "$BP" "$R" >&2
129+
else
130+
printf ' %b│%b %b%*d › %s%b%*s%b│%b\n' \
131+
"$BP" "$R" "$DIM" "$num_w" 0 "${items[$last_idx]}" "$R" "$pad" "" "$BP" "$R" >&2
132+
fi
121133

122-
printf "\n" >&2
123-
local key=""
124-
IFS= read -rsn1 key < /dev/tty || true
125-
126-
if [[ "$key" == $'\x1b' ]]; then
127-
local seq=""
128-
read -rsn2 -t 1 seq < /dev/tty || true
129-
if [[ "$seq" == '[D' ]]; then
130-
printf "‹\n" >&2
131-
echo "0"
134+
printf ' %b│%b%*s%b│%b\n' "$BP" "$R" "$inner_w" "" "$BP" "$R" >&2
135+
printf ' %b╰' "$BP" >&2
136+
printf '─%.0s' $(seq 1 $inner_w) >&2
137+
printf '╯%b\n' "$R" >&2
138+
printf "\n" >&2
139+
140+
local key=""
141+
IFS= read -rsn1 key < /dev/tty || true
142+
143+
if [[ "$key" == $'\x1b' ]]; then
144+
local ansi=""
145+
read -rsn2 -t 1 ansi < /dev/tty || true
146+
case "$ansi" in
147+
'[A') ((sel > 0)) && ((sel--)) ;;
148+
'[B') ((sel < sel_total - 1)) && ((sel++)) ;;
149+
'[C'|'[M') printf "\033[?25h" >&2; echo "${sel_nums[$sel]}"; return ;;
150+
'[D') printf "‹\n" >&2; printf "\033[?25h" >&2; echo "0"; return ;;
151+
esac
152+
elif [[ "$key" == "" ]]; then
153+
printf "\033[?25h" >&2
154+
echo "${sel_nums[$sel]}"
155+
return
156+
elif [[ "$key" =~ ^[0-9]$ ]]; then
157+
printf "%s\n" "$key" >&2
158+
printf "\033[?25h" >&2
159+
echo "$key"
160+
return
132161
fi
133-
elif [[ -n "$key" ]]; then
134-
printf "%s\n" "$key" >&2
135-
echo "$key"
136-
fi
137-
printf "\033[?25h" >&2
162+
done
138163
}
139164

140165
#

tweaks/dock.sh

Lines changed: 12 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,10 @@ hot_corners_tweaks() {
4040

4141
local tl tr bl br
4242
local cur_tl cur_tr cur_bl cur_br
43-
cur_tl=$(defaults read com.apple.dock wvous-tl-corner 2>/dev/null || echo "not set")
44-
cur_tr=$(defaults read com.apple.dock wvous-tr-corner 2>/dev/null || echo "not set")
45-
cur_bl=$(defaults read com.apple.dock wvous-bl-corner 2>/dev/null || echo "not set")
46-
cur_br=$(defaults read com.apple.dock wvous-br-corner 2>/dev/null || echo "not set")
43+
cur_tl=$(defaults read com.apple.dock wvous-tl-corner 2>/dev/null || echo "0")
44+
cur_tr=$(defaults read com.apple.dock wvous-tr-corner 2>/dev/null || echo "0")
45+
cur_bl=$(defaults read com.apple.dock wvous-bl-corner 2>/dev/null || echo "0")
46+
cur_br=$(defaults read com.apple.dock wvous-br-corner 2>/dev/null || echo "0")
4747

4848
printf '\n %bCurrent: TL=%s TR=%s BL=%s BR=%s%b\n' "$DIM" "$cur_tl" "$cur_tr" "$cur_bl" "$cur_br" "$RESET"
4949
printf ' %bPress enter to keep current value%b\n\n' "$DIM" "$RESET"
@@ -57,32 +57,23 @@ hot_corners_tweaks() {
5757
printf ' %bBottom-right%b [%s]: ' "$CYAN" "$RESET" "$cur_br"
5858
read -r br < /dev/tty
5959

60-
# Use current values if empty
6160
tl="${tl:-$cur_tl}"
6261
tr="${tr:-$cur_tr}"
6362
bl="${bl:-$cur_bl}"
6463
br="${br:-$cur_br}"
6564

66-
printf "\n"
67-
if [[ "$tl" == "$cur_tl" && "$tr" == "$cur_tr" && "$bl" == "$cur_bl" && "$br" == "$cur_br" ]]; then
68-
log_info "No changes"
69-
wait_enter
70-
return
71-
fi
72-
if [[ "$MACRIFT_DRY_RUN" == true ]]; then
73-
log_info "Dry run — would set TL=$tl TR=$tr BL=$bl BR=$br"
74-
elif confirm "Apply corners: TL=$tl TR=$tr BL=$bl BR=$br?"; then
75-
defaults write com.apple.dock wvous-tl-corner -int "$tl"
65+
audit_reset
66+
audit_default "com.apple.dock" "wvous-tl-corner" "-int" "$tl" "Top-left corner"
67+
audit_default "com.apple.dock" "wvous-tr-corner" "-int" "$tr" "Top-right corner"
68+
audit_default "com.apple.dock" "wvous-bl-corner" "-int" "$bl" "Bottom-left corner"
69+
audit_default "com.apple.dock" "wvous-br-corner" "-int" "$br" "Bottom-right corner"
70+
71+
if show_audit_table "Hot Corners"; then
72+
apply_audited_defaults
7673
defaults write com.apple.dock wvous-tl-modifier -int 0
77-
defaults write com.apple.dock wvous-tr-corner -int "$tr"
7874
defaults write com.apple.dock wvous-tr-modifier -int 0
79-
defaults write com.apple.dock wvous-bl-corner -int "$bl"
8075
defaults write com.apple.dock wvous-bl-modifier -int 0
81-
defaults write com.apple.dock wvous-br-corner -int "$br"
8276
defaults write com.apple.dock wvous-br-modifier -int 0
83-
killall Dock 2>/dev/null || true
8477
log_ok "Hot corners applied"
8578
fi
86-
87-
wait_enter
8879
}

0 commit comments

Comments
 (0)