2

In some situations, zsh takes a long time to generate a list of completions. Maybe it needs to list some files on a remote server or maybe it needs to run a tool that has a long startup time. In these situations, after I press Tab to start completion, the screen display doesn’t change right away, and it’s not always clear whether zsh is still generating the list of completions, it has generated the list but there are no completions for the thing I’ve typed, or completion just isn’t supported in the current context.

Is there any way to display some kind of indicator while zsh builds the completion list? More generally, is there a way to have zsh run a user-defined function before it starts building the list and then have it run a different function when it’s done?

3

The entry point of completion is the function _main_complete. It calls the hook compprefuncs after setting shell options and completion-related variables and before analyzing completion display settings and performing completions. It calls the hook comppostfuncs just before returning normally, whether completions were found or not, but not before returning on a keyboard interrupt (Ctrl+C).

Each hook is an array of function names; the functions are called in order and their return status is ignored. _main_complete_ erases the array before calling the functions, so they need to re-insert themselves.

I use the zsh/terminfo module to display an indicator in the bottom right corner of the string. The completion erases this indicator, at least in the configuration that I tested.

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)
7
  • I'm getting set_completion_indicator:echoti:3: no such terminfo capability: setf message. – BlueManCZ Apr 9 '20 at 9:36
  • @BlueManCZ Your terminal doesn't support colors, or it doesn't advertise that it supports colors (e.g. screen running in a color terminal but with TERM=screen), or your system doesn't support the setf terminfo capability. The zsh part of my answer should still work, but if your terminal is different, you need to adapt the terminal part. – Gilles 'SO- stop being evil' Apr 9 '20 at 10:48
  • Yes, it works, when I comment line with setf. I have gnome-terminal with echo $TERM: xterm-256color. I guess my system doesn't support the setf terminfo capability, as you say. What is that? – BlueManCZ Apr 9 '20 at 15:25
  • @BlueManCZ I don't know. With xterm-256color I would have expected setf to be supported. You should ask a question on this site. – Gilles 'SO- stop being evil' Apr 9 '20 at 18:10
  • Thank you for this! set_completion_indicator doesn’t quite seem to work on my terminal… see the recording at asciinema.org/a/318272. Any idea what might be going wrong? – bdesham Apr 9 '20 at 21:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.