v0.8.3: tab-completion trailing-space no longer breaks command dispatch
The slash-command completer (__larry_complete_slash) intentionally appends a trailing space after a unique match for arg-command ergonomics, but the main_loop dispatcher matched exact `case` globs — so a completed `/quit ` missed the `/quit)` arm and fell through to "unknown command". Latent since v0.6.6 (tab completion). Fixed by rtrimming the dispatch key once at the `case "$input"` boundary, which also transitively protects the sub-command dispatchers (/origin, /phi-auto, /phi-sidecar, /mouse) that consume the same $input via _slash_args. Interior `/load FILE` spacing is preserved. Added a shared rtrim() helper to lib/cygwin-safe.sh next to strip_cr. Co-Authored-By: Clover (Claude Opus 4.7) <noreply@anthropic.com>
This commit is contained in:
parent
60b8f0e1c8
commit
d4c382dc6d
13
CHANGELOG.md
13
CHANGELOG.md
@ -4,6 +4,19 @@ All notable changes to `cloverleaf-larry` / `larry-anywhere` are recorded here.
|
|||||||
Versioning is loose-semver; bumps trigger the in-process self-update on every
|
Versioning is loose-semver; bumps trigger the in-process self-update on every
|
||||||
running client via `LARRY_BASE_URL` + `MANIFEST`.
|
running client via `LARRY_BASE_URL` + `MANIFEST`.
|
||||||
|
|
||||||
|
## v0.8.3 — 2026-05-27
|
||||||
|
|
||||||
|
- **Tab-completion trailing space no longer breaks command dispatch.** The
|
||||||
|
slash-command completer intentionally appends a trailing space after a
|
||||||
|
unique match (so arg-taking commands feel snappy), but the main_loop
|
||||||
|
dispatcher matched exact `case` globs, so `/quit ` (completed) missed the
|
||||||
|
`/quit)` arm and fell through to "unknown command". Latent since v0.6.6
|
||||||
|
when tab completion shipped. Fixed by rtrimming the dispatch key once at
|
||||||
|
the `case "$input"` boundary (`larry.sh`), which tolerates the completer's
|
||||||
|
space, a user-typed trailing space, and any CR remnant while preserving
|
||||||
|
interior `/load FILE` argument spacing. Added a shared `rtrim()` helper to
|
||||||
|
`lib/cygwin-safe.sh` (and the inline fallback) next to `strip_cr`.
|
||||||
|
|
||||||
## v0.8.2 — 2026-05-27
|
## v0.8.2 — 2026-05-27
|
||||||
|
|
||||||
Microsoft Presidio sidecar for free-text NER. Closes V1 from Vera's audit —
|
Microsoft Presidio sidecar for free-text NER. Closes V1 from Vera's audit —
|
||||||
|
|||||||
14
larry.sh
14
larry.sh
@ -57,7 +57,7 @@ set -o pipefail
|
|||||||
# ─────────────────────────────────────────────────────────────────────────────
|
# ─────────────────────────────────────────────────────────────────────────────
|
||||||
# Config
|
# Config
|
||||||
# ─────────────────────────────────────────────────────────────────────────────
|
# ─────────────────────────────────────────────────────────────────────────────
|
||||||
LARRY_VERSION="0.8.2"
|
LARRY_VERSION="0.8.3"
|
||||||
LARRY_HOME="${LARRY_HOME:-$HOME/.larry}"
|
LARRY_HOME="${LARRY_HOME:-$HOME/.larry}"
|
||||||
|
|
||||||
# ─────────────────────────────────────────────────────────────────────────────
|
# ─────────────────────────────────────────────────────────────────────────────
|
||||||
@ -850,6 +850,7 @@ if [ -n "$LARRY_LIB_DIR" ] && [ -r "$LARRY_LIB_DIR/cygwin-safe.sh" ]; then
|
|||||||
else
|
else
|
||||||
coerce_int() { local r="${1:-}" d="${2:-0}" c; c=$(printf '%s' "$r" | tr -cd '0-9'); printf '%s' "${c:-$d}"; }
|
coerce_int() { local r="${1:-}" d="${2:-0}" c; c=$(printf '%s' "$r" | tr -cd '0-9'); printf '%s' "${c:-$d}"; }
|
||||||
strip_cr() { local v="${1:-}"; printf '%s' "${v//$'\r'/}"; }
|
strip_cr() { local v="${1:-}"; printf '%s' "${v//$'\r'/}"; }
|
||||||
|
rtrim() { local v="${1:-}"; printf '%s' "${v%"${v##*[![:space:]]}"}"; }
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# v0.7.0: HL7 v2.x schema for inline tab completion + /hl7 / /hl7-fields slash
|
# v0.7.0: HL7 v2.x schema for inline tab completion + /hl7 / /hl7-fields slash
|
||||||
@ -4742,6 +4743,17 @@ main_loop() {
|
|||||||
local input="$LARRY_INPUT"
|
local input="$LARRY_INPUT"
|
||||||
[ -z "$input" ] && continue
|
[ -z "$input" ] && continue
|
||||||
|
|
||||||
|
# v0.8.3 — rtrim the dispatch key before the exact-match `case` below.
|
||||||
|
# Tab completion (__larry_complete_slash) intentionally appends a trailing
|
||||||
|
# space after a unique match, but bash `case` globs are literal: "/quit "
|
||||||
|
# never matches the "/quit)" arm and falls through to "unknown command".
|
||||||
|
# Stripping trailing whitespace here tolerates the completer's space, a
|
||||||
|
# user-typed trailing space, and any CR remnant in one defensive line.
|
||||||
|
# Trailing-only: interior "/load FILE" spacing is preserved, so argument
|
||||||
|
# parsing (${input#/load } etc.) is unaffected. Pure parameter expansion,
|
||||||
|
# no subshell. See lib/cygwin-safe.sh rtrim() for the shared helper.
|
||||||
|
input="${input%"${input##*[![:space:]]}"}"
|
||||||
|
|
||||||
case "$input" in
|
case "$input" in
|
||||||
/quit|/exit|/q) larry_say "bye."; break ;;
|
/quit|/exit|/q) larry_say "bye."; break ;;
|
||||||
/help) print_help; continue ;;
|
/help) print_help; continue ;;
|
||||||
|
|||||||
@ -66,6 +66,29 @@ strip_cr() {
|
|||||||
printf '%s' "${v//$'\r'/}"
|
printf '%s' "${v//$'\r'/}"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# rtrim VAL — return VAL with all TRAILING whitespace removed (spaces, tabs,
|
||||||
|
# and CR — anything in [:space:]). Leading and interior whitespace untouched.
|
||||||
|
#
|
||||||
|
# Use immediately before a `case "$X" in ...) esac` pattern dispatcher whose
|
||||||
|
# arms are exact-string globs (e.g. /quit) /help)). Bash case patterns are
|
||||||
|
# literal globs, so a trailing space makes "/quit " miss "/quit)" and fall
|
||||||
|
# through to the catch-all. This bites tab completion: __larry_complete_slash
|
||||||
|
# intentionally appends a friendly trailing space after a unique match (so
|
||||||
|
# arg-taking commands feel snappy), which the exact-match dispatcher then
|
||||||
|
# rejects for no-arg commands. rtrim at the dispatch boundary tolerates the
|
||||||
|
# completer's space, a user-typed trailing space, and any CR remnant in one
|
||||||
|
# defensive line — without removing the completer's UX nicety.
|
||||||
|
#
|
||||||
|
# Trailing-only by design: interior spaces separate a command from its
|
||||||
|
# argument (/load FILE), so we must never collapse those. The expansion
|
||||||
|
# below strips the run of trailing whitespace chars only.
|
||||||
|
#
|
||||||
|
# Pure bash parameter expansion — no subshell, no external tools.
|
||||||
|
rtrim() {
|
||||||
|
local v="${1:-}"
|
||||||
|
printf '%s' "${v%"${v##*[![:space:]]}"}"
|
||||||
|
}
|
||||||
|
|
||||||
# read_clean VAR [PROMPT] — like `read -r VAR`, but every captured byte that
|
# read_clean VAR [PROMPT] — like `read -r VAR`, but every captured byte that
|
||||||
# is \r gets stripped before the assignment.
|
# is \r gets stripped before the assignment.
|
||||||
#
|
#
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user