Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: completion within a function

On Sat, Jan 2, 2021 at 6:47 PM Felipe Contreras
<felipe.contreras@xxxxxxxxx> wrote:
> You do see why I think 'git checkout ' is more friendly than 'git'
> 'checkout' '', right?

Try this one.  I think I'm probably done fooling around with this.

# Usage: complete commandline
# where "commandline" is one or more words, of which the last is the
# prefix of the desired completion.  If the commandline is a single
# argument, it is split into words using expansion flag (z) with any
# trailing whitespace treated as delimiting a final empty word.
# Thus:
#  complete g
#    completes all commands whose name starts with "g"
#  complete git --
#    completes all options of "git" that begin with two hyphens
#  complete 'git checkout -- '
#    completes all modified files in the current repository
# All possible completions are returned, one per line.  There is a
# limit of approximately half a megabyte of total output, as a side-
# effect of vared plus the limit of one megabyte per "zpty -r".
# If the variable CURSOR is defined, that position within commandline
# is used as the start of the completion.  This is only useful when
# the COMPLETE_IN_WORD option is enabled.  Note, if CURSOR does not
# fall either immediately before, within, or after the last word,
# the results are unpredictable.
# Other limitations:
#  Only completion is performed, not expansion.
#  Splitting the input with (z) collapses any consecutive whitespace,
#  which may affect the use of CURSOR.

(( $+_comps )) || { autoload -U compinit; compinit -i -D }
zmodload zsh/zpty

if ! bindkey -M __complete 2>/dev/null
  bindkey -N __complete
  zle -C __complete_all complete-word _generic
  zstyle ':completion:__complete_all::::' completer _all_matches _complete
  zstyle ':completion:__complete_all:*' insert true

  bindkey -M __complete '^Xa' __complete_all
  # bindkey -M __complete '^X?' _complete_debug
  bindkey -M __complete $'\n' .accept-line
  # bindkey -M __complete '^G' .send-break

  __init_complete() {
    zle -U $'\Cxa\n'
  zle -N __init_complete

completion-context() {
  if (( debug )); then
    print -u $debug -C 2 -a -r \
    CONTEXT: ":completion:$curcontext" \
    STATE: '' "${(@kv)compstate}"
hide-vared() { compstate[vared]='' }

run-complete () {
  local -a compprefuncs=(hide-vared "${(@)compprefuncs}")
  vared -M __complete -i __init_complete ${${argv:+argv}:-reply}
  (( ARGC )) || print -nrl -- "~~~${(@)reply}~~~"

debug-complete() {
  local -i debug
  local -a compprefuncs=(completion-context "${(@)compprefuncs}")
  local -a comppostfuncs=("${(@)comppostfuncs}" completion-context)
  exec {debug}>&2
  complete "$@"
  exec {debug}>&-

complete() {
  (( ARGC )) || return 1
  (( ARGC == 1 )) && argv=( "${(@)${(z):-${1}x}%x}" )
  local REPLY reply=( "$@" ) __cursor=$CURSOR
  zpty complete-tty run-complete &&
    zpty -r complete-tty REPLY $'*~~~*~~~'
  } always {
    zpty -d complete-tty
  reply=( "${(@)${(f)${${REPLY%~~~}#*~~~}}%$'\r'}" )
  shift ARGC-1 reply
  print -lr -- "${(@)reply}"

(( ARGC )) && complete "$@"

Messages sorted by: Reverse Date, Date, Thread, Author