在某些情况下,zsh 需要很长时间才能生成完成列表。也许它需要列出远程服务器上的一些文件,或者可能需要运行一个启动时间较长的工具。在这些情况下,当我按下Tab开始补全后,屏幕显示不会立即改变,并且并不总是清楚 zsh 是否仍在生成补全列表,它已经生成了列表,但我的内容没有补全。已经输入,或者当前上下文不支持完成。
有没有办法在 zsh 构建完成列表时显示某种指示器?更一般地说,有没有办法让 zsh 在开始构建列表之前运行用户定义的函数,然后在完成后让它运行不同的函数?
答案1
完成的入口点是函数_main_complete
。它compprefuncs
在设置 shell 选项和完成相关变量之后、分析完成显示设置和执行完成之前调用挂钩。comppostfuncs
无论是否找到完成,它都会在正常返回之前调用挂钩,但不会在键盘中断 ( Ctrl+ C)返回之前调用挂钩。
每个钩子都是一个函数名称数组;这些函数按顺序调用,并且忽略它们的返回状态。_main_complete_
在调用函数之前擦除数组,因此它们需要重新插入自己。
我用zsh/terminfo
模块在字符串的右下角显示一个指示器。完成后会删除该指示器,至少在我测试的配置中是这样。
zmodload zsh/terminfo
function set_completion_indicator {
echoti sc # save_cursor
echoti cup $((LINES - 1)) $((COLUMNS - $#1)) # cursor_position
echoti setaf $2 # set_foreground (color)
printf %s $1
echoti sgr 0 # exit_attribute_mode
echoti rc # restore_cursor
#sleep 1
}
completion_indicator_text='(completing)'
completion_indicator_color=3
function display_completion_indicator {
compprefuncs+=(display_completion_indicator)
set_completion_indicator $completion_indicator_text $completion_indicator_color
}
function hide_completion_indicator {
comppostfuncs+=(hide_completion_indicator)
# The completion code erases the indicator, so there's nothing to do.
}
compprefuncs+=(display_completion_indicator)
comppostfuncs+=(hide_completion_indicator)