From eb29cdb33aae9edeca5827168ed602b0dcc89c46 Mon Sep 17 00:00:00 2001 From: Kunpeng Xie <68572236+pentaoa@users.noreply.github.com> Date: Mon, 12 Oct 2026 06:58:22 +0800 Subject: [PATCH] fix(globalias): preserve quoted words and assignment values (#14092) Only invoke alias completion when the complete shell word is an alias name. Completion otherwise treats assignment values and quoted text as standalone alias names, corrupting inputs such as DEBUG=1. Add a real ZLE regression test covering the reported assignments, quotes, escaped aliases, filtering, and existing expansion behavior. Assisted-by: OpenAI Codex --- plugins/globalias/globalias.plugin.zsh | 6 +- plugins/globalias/tests/globalias.test.zsh | 81 ++++++++++++++++++++++ 2 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 plugins/globalias/tests/globalias.test.zsh diff --git a/plugins/globalias/globalias.plugin.zsh b/plugins/globalias/globalias.plugin.zsh index bd27d589d..cfcb5bae1 100644 --- a/plugins/globalias/globalias.plugin.zsh +++ b/plugins/globalias/globalias.plugin.zsh @@ -4,7 +4,11 @@ globalias() { # (A) makes it an array even if there's only one element local word=${${(Az)LBUFFER}[-1]} if [[ $GLOBALIAS_FILTER_VALUES[(Ie)$word] -eq 0 ]]; then - zle _expand_alias + # Completion also considers quoted strings and assignment values as aliases. + # Only expand when the complete shell word is an alias name. + if (( ${+aliases[$word]} || ${+galiases[$word]} )); then + zle _expand_alias + fi zle expand-word fi zle self-insert diff --git a/plugins/globalias/tests/globalias.test.zsh b/plugins/globalias/tests/globalias.test.zsh new file mode 100644 index 000000000..c5a0e39ba --- /dev/null +++ b/plugins/globalias/tests/globalias.test.zsh @@ -0,0 +1,81 @@ +#!/usr/bin/env zsh + +# Exercise the actual ZLE widgets in an isolated interactive shell. +emulate -L zsh +setopt err_return +zmodload zsh/zpty +zmodload zsh/zselect + +local test_dir=$(mktemp -d) +export GLOBALIAS_TEST_PLUGIN=${0:A:h:h}/globalias.plugin.zsh +export GLOBALIAS_TEST_RESULT=$test_dir/result + +wait_for_marker() { + local marker=$1 output received + local -i deadline=$(( SECONDS + 5 )) + while (( SECONDS < deadline )); do + if zpty -r globalias-test output; then + received+=$output + [[ $received == *$marker* ]] && return 0 + else + zselect -t 1 || true + fi + done + print -u2 -r -- "Timed out waiting for ZLE: $received" + return 1 +} + +check_expansion() { + local input=$1 expected=$2 actual + zpty -w -n globalias-test "$input"$' \x18' + wait_for_marker GLOBALIAS_TEST_CAPTURED + actual=$(< "$GLOBALIAS_TEST_RESULT") + if [[ $actual != "$expected" ]]; then + print -u2 -r -- "Input: ${(qqq)input}" + print -u2 -r -- "Expected: ${(qqq)expected}; got: ${(qqq)actual}" + return 1 + fi +} + +{ + cat > "$test_dir/setup.zsh" <<'SETUP' +autoload -Uz compinit +compinit -D +source "$GLOBALIAS_TEST_PLUGIN" +alias 1='cd -1' +alias ll='ls -l' +alias -g G='| grep' +GLOBALIAS_FILTER_VALUES=(ll) +_globalias_test_capture() { + print -rn -- "$BUFFER" > "$GLOBALIAS_TEST_RESULT" + print -r -- $'\nGLOBALIAS_TEST_CAPTURED' + BUFFER= + zle .accept-line +} +zle -N _globalias_test_capture +bindkey '^X' _globalias_test_capture +PS1='GLOBALIAS_TEST_READY> ' +RPROMPT= +SETUP + zpty -b globalias-test zsh -dfi + zpty -w globalias-test "source ${(q)test_dir}/setup.zsh" + wait_for_marker GLOBALIAS_TEST_READY + + check_expansion 'DEBUG=1' 'DEBUG=1 ' + check_expansion 'DEBUG="1"' 'DEBUG="1" ' + check_expansion "DEBUG='1'" "DEBUG='1' " + check_expansion '1' 'cd -1 ' + check_expansion '"1"' '"1" ' + check_expansion "'1'" "'1' " + check_expansion '\1' '\1 ' + check_expansion 'echo G' 'echo | grep ' + check_expansion 'DEBUG=1 1' 'DEBUG=1 cd -1 ' + check_expansion 'll' 'll ' + check_expansion 'echo $((1+2))' 'echo 3 ' + check_expansion 'echo {a,b}' 'echo a b ' + check_expansion '' ' ' + print 'All globalias expansion tests passed.' +} always { + zpty -d globalias-test 2>/dev/null || true + rm -rf -- "$test_dir" +}