Zsh内联自动补全打印:删除字符时出现多余空格求助
Zsh内联补全删除字符后出现多余空格的问题修复
问题描述
开发带自动补全功能的zsh脚本时,用tput和echo实现内联输入建议,输入字符时功能正常,但删除字符后,被删除字符的位置会出现多余空格。
最小复现代码
function __keypress() { zle .$WIDGET __get_cur_pos tput cup $__fut_row $((__fut_col + 1)) echo "works\033[K" tput cup $__fut_row $__fut_col } function __delete() { # remove the last character from buffer BUFFER=${BUFFER%?} __get_cur_pos echo "fail\033[K" tput cup $__fut_row $__fut_col } function __get_cur_pos(){ echo -ne "\033[6n" read -t 1 -s -d 'R' line < /dev/tty line="${line##*\[}" __fut_row=$((${line%%;*}-1)) # extract the row number __fut_col=$((${line##*;}-1)) # extract the column number unset line } zle -N self-insert __keypress zle -N __del __delete # change the action of delete key to deleting most recent and updating __current_input bindkey "^?" __del
问题原因
__delete函数直接修改BUFFER但未触发zle内置的刷新机制,导致终端光标位置与实际输入缓冲区状态不同步,__get_cur_pos获取的光标位置不准确- 删除操作后未正确清除当前行残留内容,直接输出提示文本时,旧字符残留形成多余空格
修复方案
修改__delete函数,借助zle内置删除小部件同步缓冲区与光标位置,调整提示输出逻辑确保残留内容被清除:
function __keypress() { zle .$WIDGET __get_cur_pos tput cup $__fut_row $((__fut_col + 1)) echo -n "works\033[K" tput cup $__fut_row $__fut_col } function __delete() { # 调用zle内置删除小部件,自动同步缓冲区与光标位置 zle .backward-delete-char __get_cur_pos # 定位到光标右侧,输出提示并清除右侧残留内容 tput cup $__fut_row $((__fut_col + 1)) echo -n "fail\033[K" tput cup $__fut_row $__fut_col } function __get_cur_pos(){ echo -ne "\033[6n" read -t 1 -s -d 'R' line < /dev/tty line="${line##*\[}" __fut_row=$((${line%%;*}-1)) # extract the row number __fut_col=$((${line##*;}-1)) # extract the column number unset line } zle -N self-insert __keypress zle -N __del __delete bindkey "^?" __del
关键修改点
- 替换直接修改
BUFFER的逻辑,改用zle .backward-delete-char让zle自动处理缓冲区更新与光标同步,保证__get_cur_pos获取正确位置 - 统一
__delete与__keypress的提示输出逻辑,确保残留内容被\033[K清除 - 用
echo -n替代echo,避免额外换行符干扰终端输出
内容的提问来源于stack exchange,提问作者BigWinnz101
相关产品推荐
相关产品推荐

