From 031bda288f3ec5ac6caa27e6d8012dca82204231 Mon Sep 17 00:00:00 2001 From: Ramesh Padmanabhaiah Date: Fri, 19 Jun 2026 00:59:20 -0700 Subject: [PATCH] Improve shell completion defaults --- CHANGELOG.md | 2 ++ README.md | 1 + cli/bash/commands/basectl/tests/update-profile.bats | 9 +++++++-- lib/shell/bash_defaults.sh | 9 +++++++++ lib/shell/zsh_defaults.sh | 2 ++ 5 files changed, 21 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3cb725af..b1a81506 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,8 @@ and Base versions are tracked in the repo-root `VERSION` file. ### Changed +- Improved opt-in Bash and Zsh completion ergonomics for interactive shell + defaults. - Added conservative pager and terminal usability behavior to opt-in shell defaults. - Enriched opt-in shell history defaults for `basectl update-profile --defaults`. diff --git a/README.md b/README.md index bc3251b7..0068fa39 100644 --- a/README.md +++ b/README.md @@ -1310,6 +1310,7 @@ Those defaults are intended to stay conservative: - aliases like `rm -i`, `cp -i`, `mv -i` - vi-style command editing +- completion ergonomics - editor defaults - pager defaults - prompt defaults diff --git a/cli/bash/commands/basectl/tests/update-profile.bats b/cli/bash/commands/basectl/tests/update-profile.bats index 80913dd6..e296ff8f 100644 --- a/cli/bash/commands/basectl/tests/update-profile.bats +++ b/cli/bash/commands/basectl/tests/update-profile.bats @@ -501,7 +501,7 @@ EOF -u PAGER -u LESS -u MANPAGER -u GIT_PAGER \ HOME="$TEST_HOME" \ PATH="/usr/bin:/bin:/usr/sbin:/sbin" \ - bash --rcfile "$TEST_HOME/.bashrc" -i -c 'alias cp; printf "EDITOR=%s\n" "$EDITOR"; printf "VISUAL=%s\n" "$VISUAL"; printf "EXINIT=%s\n" "$EXINIT"; printf "PAGER=%s\n" "$PAGER"; printf "LESS=%s\n" "$LESS"; printf "MANPAGER=%s\n" "$MANPAGER"; printf "GIT_PAGER=%s\n" "$GIT_PAGER"; printf "HISTCONTROL=%s\n" "$HISTCONTROL"; printf "HISTSIZE=%s\n" "$HISTSIZE"; printf "HISTFILESIZE=%s\n" "$HISTFILESIZE"; shopt -q checkwinsize && printf "checkwinsize=enabled\n"; shopt -q cmdhist && printf "cmdhist=enabled\n"; shopt -q lithist && printf "lithist=enabled\n"; printf "BASE_HOME=%s\n" "$BASE_HOME"; cd "$BASE_HOME"; printf "git=%s\n" "$(_base_bash_defaults_git_prompt)"; printf "PS1=%s\n" "$PS1"' + bash --rcfile "$TEST_HOME/.bashrc" -i -c 'alias cp; printf "EDITOR=%s\n" "$EDITOR"; printf "VISUAL=%s\n" "$VISUAL"; printf "EXINIT=%s\n" "$EXINIT"; printf "PAGER=%s\n" "$PAGER"; printf "LESS=%s\n" "$LESS"; printf "MANPAGER=%s\n" "$MANPAGER"; printf "GIT_PAGER=%s\n" "$GIT_PAGER"; bind -v | grep -q "^set completion-ignore-case on$" && printf "completion_ignore_case=enabled\n"; bind -v | grep -q "^set show-all-if-ambiguous on$" && printf "show_all_if_ambiguous=enabled\n"; bind -v | grep -q "^set mark-symlinked-directories on$" && printf "mark_symlinked_directories=enabled\n"; printf "HISTCONTROL=%s\n" "$HISTCONTROL"; printf "HISTSIZE=%s\n" "$HISTSIZE"; printf "HISTFILESIZE=%s\n" "$HISTFILESIZE"; shopt -q checkwinsize && printf "checkwinsize=enabled\n"; shopt -q cmdhist && printf "cmdhist=enabled\n"; shopt -q lithist && printf "lithist=enabled\n"; printf "BASE_HOME=%s\n" "$BASE_HOME"; cd "$BASE_HOME"; printf "git=%s\n" "$(_base_bash_defaults_git_prompt)"; printf "PS1=%s\n" "$PS1"' [ "$status" -eq 0 ] [[ "$output" == *"alias cp='cp -i'"* ]] @@ -512,6 +512,9 @@ EOF [[ "$output" == *"LESS=-FRX"* ]] [[ "$output" == *"MANPAGER=less -R"* ]] [[ "$output" == *"GIT_PAGER=less -FRX"* ]] + [[ "$output" == *"completion_ignore_case=enabled"* ]] + [[ "$output" == *"show_all_if_ambiguous=enabled"* ]] + [[ "$output" == *"mark_symlinked_directories=enabled"* ]] [[ "$output" == *"HISTCONTROL=ignoreboth:erasedups"* ]] [[ "$output" == *"HISTSIZE=10000"* ]] [[ "$output" == *"HISTFILESIZE=20000"* ]] @@ -528,13 +531,15 @@ EOF -u PAGER -u LESS -u MANPAGER -u GIT_PAGER \ HOME="$TEST_HOME" \ PATH="/usr/bin:/bin:/usr/sbin:/sbin" \ - zsh -f -i -c 'source "$HOME/.zshrc"; printf "PAGER=%s\n" "$PAGER"; printf "LESS=%s\n" "$LESS"; printf "MANPAGER=%s\n" "$MANPAGER"; printf "GIT_PAGER=%s\n" "$GIT_PAGER"; printf "HISTFILE=%s\n" "$HISTFILE"; printf "HISTSIZE=%s\n" "$HISTSIZE"; printf "SAVEHIST=%s\n" "$SAVEHIST"; setopt | grep -q "^extendedhistory$" && printf "extended_history=enabled\n"; setopt | grep -q "^histignorespace$" && printf "hist_ignore_space=enabled\n"; setopt | grep -q "^histreduceblanks$" && printf "hist_reduce_blanks=enabled\n"; setopt | grep -q "^histexpiredupsfirst$" && printf "hist_expire_dups_first=enabled\n"; setopt | grep -q "^histsavenodups$" && printf "hist_save_no_dups=enabled\n"; setopt | grep -q "^histfindnodups$" && printf "hist_find_no_dups=enabled\n"; setopt | grep -q "^histverify$" && printf "hist_verify=enabled\n"; setopt | grep -q "^interactivecomments$" && printf "interactive_comments=enabled\n"; setopt | grep -q "^nobeep$" && printf "no_beep=enabled\n"; cd "$BASE_HOME"; printf "git=%s\n" "$(_base_zsh_defaults_git_prompt)"; printf "PROMPT=%s\n" "$PROMPT"; setopt | grep -q "^promptsubst$"; printf "prompt_subst=enabled\n"' + zsh -f -i -c 'source "$HOME/.zshrc"; printf "PAGER=%s\n" "$PAGER"; printf "LESS=%s\n" "$LESS"; printf "MANPAGER=%s\n" "$MANPAGER"; printf "GIT_PAGER=%s\n" "$GIT_PAGER"; zstyle -s ":completion:*" matcher-list matcher_list && printf "matcher_list=%s\n" "$matcher_list"; zstyle -s ":completion:*" menu completion_menu && printf "completion_menu=%s\n" "$completion_menu"; printf "HISTFILE=%s\n" "$HISTFILE"; printf "HISTSIZE=%s\n" "$HISTSIZE"; printf "SAVEHIST=%s\n" "$SAVEHIST"; setopt | grep -q "^extendedhistory$" && printf "extended_history=enabled\n"; setopt | grep -q "^histignorespace$" && printf "hist_ignore_space=enabled\n"; setopt | grep -q "^histreduceblanks$" && printf "hist_reduce_blanks=enabled\n"; setopt | grep -q "^histexpiredupsfirst$" && printf "hist_expire_dups_first=enabled\n"; setopt | grep -q "^histsavenodups$" && printf "hist_save_no_dups=enabled\n"; setopt | grep -q "^histfindnodups$" && printf "hist_find_no_dups=enabled\n"; setopt | grep -q "^histverify$" && printf "hist_verify=enabled\n"; setopt | grep -q "^interactivecomments$" && printf "interactive_comments=enabled\n"; setopt | grep -q "^nobeep$" && printf "no_beep=enabled\n"; cd "$BASE_HOME"; printf "git=%s\n" "$(_base_zsh_defaults_git_prompt)"; printf "PROMPT=%s\n" "$PROMPT"; setopt | grep -q "^promptsubst$"; printf "prompt_subst=enabled\n"' [ "$status" -eq 0 ] [[ "$output" == *"PAGER=less"* ]] [[ "$output" == *"LESS=-FRX"* ]] [[ "$output" == *"MANPAGER=less -R"* ]] [[ "$output" == *"GIT_PAGER=less -FRX"* ]] + [[ "$output" == *"matcher_list=m:{a-zA-Z}={A-Za-z}"* ]] + [[ "$output" == *"completion_menu=select"* ]] [[ "$output" == *"HISTFILE=$TEST_HOME/.zsh_history"* ]] [[ "$output" == *"HISTSIZE=10000"* ]] [[ "$output" == *"SAVEHIST=10000"* ]] diff --git a/lib/shell/bash_defaults.sh b/lib/shell/bash_defaults.sh index c180956f..cc61fa9d 100644 --- a/lib/shell/bash_defaults.sh +++ b/lib/shell/bash_defaults.sh @@ -58,6 +58,15 @@ _base_bash_defaults_git_prompt() { export PS1='\[\033[0;35m\]\T \h\[\033[0;33m\] $(_base_bash_defaults_git_prompt)\w\[\033[00m\]: ' +_base_bash_defaults_bind_set() { + bind "set $1" 2>/dev/null || true +} + +_base_bash_defaults_bind_set "completion-ignore-case on" +_base_bash_defaults_bind_set "show-all-if-ambiguous on" +_base_bash_defaults_bind_set "mark-symlinked-directories on" +unset -f _base_bash_defaults_bind_set + export HISTCONTROL="${HISTCONTROL:-ignoreboth:erasedups}" if [[ "${HISTSIZE:-500}" == 500 ]]; then export HISTSIZE=10000 diff --git a/lib/shell/zsh_defaults.sh b/lib/shell/zsh_defaults.sh index 51a56947..fceb1424 100644 --- a/lib/shell/zsh_defaults.sh +++ b/lib/shell/zsh_defaults.sh @@ -42,6 +42,8 @@ source "$base_zsh_defaults_file" || { unset base_zsh_defaults_file bindkey -v +zstyle ':completion:*' matcher-list 'm:{a-zA-Z}={A-Za-z}' +zstyle ':completion:*' menu select _base_zsh_defaults_git_prompt() { local branch