zsh-workers
 help / color / mirror / code / Atom feed
From: Oliver Kiddle <okiddle@yahoo.co.uk>
To: Zsh workers <zsh-workers@sunsite.dk>
Subject: bash completion functions
Date: Tue, 28 Jan 2003 10:18:09 +0100	[thread overview]
Message-ID: <15299.1043745489@finches.logica.co.uk> (raw)

Attached is the bash completion emulation as promised. I've called the
function which enables the system bashcompinit so if you have an idea
for a better name, please say now. Which directory should it go in? I
was thinking just the Completion directory. It contains three
functions. compgen and complete correspond to the bash builtins.
_bash_complete is a wrapper function which gets run from the zsh
completion system. It requires 4.1, mainly because I stuff the
arguments all into the _comps array elements so for the 4.0 back port
(which I will do), I'll have to use a separate (_bash_comps) array.

The only things I've knowingly left unimplemented is completion for
jobs (because compgen is always run in a subshell) and complete -r
(because I couldn't be bothered). Actually compdef perhaps ought to
have -L and -r (remove) options. I've also commented out support for
the last compgen argument which is something I'm a little unsure about.
Also, $COMP_POINT might be iffy but it never seems to be used anyway.
Finally bash's compgen -C option does something weird so either it is
buggy or I don't understand but I've gone mostly by the documentation
there.

If you want to attempt to source the bash_completion project, the
following may help a little.

# their have function doesn't work in zsh (unset -v)
have() {
  unset have
  (( ${+commands[$1]} )) && have=yes
}

# shopt is bash's setopt
alias shopt=':'

# resolve function name clash (if you don't use autoload -U)
alias _expand=_bash_expand

# these are the options I seem to need to best emulate bash. Some may be
# missing and noshglob is questionable (but solved a specific issue)
emulate -L sh
setopt kshglob noshglob braceexpand

Oliver

#autoload

_bash_complete() {
  local ret=1
  local -a suf matches
  local COMP_POINT COMP_CWORD
  local -a COMP_WORDS COMPREPLY BASH_VERSINFO
  local COMP_LINE="$words"

  (( COMP_POINT = ${#${(j. .)words}} + $$#QIPREFIX + $#IPREFIX + $#PREFIX ))
  (( COMP_CWORD = CURRENT - 1))
  COMP_WORDS=( $words )
  BASH_VERSINFO=( 2 05b 0 1 release )
  
  [[ ${argv[${argv[(I)nospace]:-0}-1]} = -o ]] && suf=( -S '' )
 
  matches=( ${(f)"$(compgen $@)"} )
  
  if [[ -n $matches ]]; then
    if [[ ${argv[${argv[(I)filenames]:-0}-1]} = -o ]]; then
      compset -P '*/' && matches=( ${matches##*/} )
      compset -S '/*' && matches=( ${matches%%/*} )
      compadd -f "${suf[@]}" -a matches && ret=0
    else
      compadd "${suf[@]}" -a matches && ret=0
    fi
  fi

  if (( ret )); then
    if [[ ${argv[${argv[(I)default]:-0}-1]} = -o ]]; then
      _default "${suf[@]}" && ret=0
    elif [[ ${argv[${argv[(I)dirnames]:-0}-1]} = -o ]]; then
      _directories "${suf[@]}" && ret=0
    fi
  fi

  return ret
}

compgen() {
  local opts prefix suffix ret=1 OPTARG OPTIND
  local -a name res results
  local -A shortopts
  
  emulate -L sh
  setopt kshglob noshglob braceexpand nokshautoload

  shortopts=(
    a alias b builtin c command d directory e export f file
    g group j job k keyword u user v variable
  )

  while getopts "o:A:G:C:F:P:S:W:X:abcdefgjkuv" name; do
    case $name in
      [abcdefgjkuv]) OPTARG="${shortopts[$name]}" ;&
      A)
        case $OPTARG in
	  alias) results+=( "${(k)aliases[@]}" ) ;;
	  arrayvar) results+=( "${(k@)parameters[(R)array*]}" ) ;;
	  binding) results+=( "${(k)widgets[@]}" ) ;;
	  builtin) results+=( "${(k)builtins[@]}" "${(k)dis_builtins[@]}" ) ;;
	  command)
	    results+=(
	      "${(k)commands[@]}" "${(k)aliases[@]}" "${(k)builtins[@]}"
	      "${(k)functions[@]}" "${(k)reswords[@]}"
	    )
	  ;;
	  directory)
	    setopt bareglobqual
	    results+=( ${IPREFIX}${PREFIX}*${SUFFIX}${ISUFFIX}(N-/) )
	    setopt nobareglobqual
	  ;;
	  disabled) results+=( "${(k)dis_builtins[@]}" ) ;;
	  enabled) results+=( "${(k)builtins[@]}" ) ;;
	  export) results+=( "${(k)parameters[(R)*export*]}" ) ;;
	  file)
	    setopt bareglobqual
	    results+=( ${IPREFIX}${PREFIX}*${SUFFIX}${ISUFFIX}(N) )
	    setopt nobareglobqual
	  ;;
	  function) results+=( "${(k)functions[@]}" ) ;;
	  group)
	    emulate zsh
	    _groups -U -O res
	    emulate sh
	    setopt kshglob noshglob braceexpand
	    results+=( "${res[@]}" )
	  ;;
	  hostname)
	    emulate zsh
	    _hosts -U -O res
	    emulate sh
	    setopt kshglob noshglob braceexpand
	    results+=( "${res[@]}" )
	  ;;
	  keyword) results+=( "${(k)reswords[@]}" ) ;;
	  setopt|shopt) results+=( "${(k)options[@]}" ) ;;
	  signal) results+=( "SIG${^signals[@]}" ) ;;
	  user) results+=( "${(k)userdirs[@]}" ) ;;
      	  variable) results+=( "${(k)parameters[@]}" ) ;;
	  helptopic|job|running|stopped) ;;
	esac
      ;;
      F)
        COMPREPLY=()
	$OPTARG "${words[0]}" "${words[CURRENT-1]}" "${words[CURRENT-2]}"
	results+=( "${COMPREPLY[@]}" )
      ;;
      G)
        setopt nullglob
        results+=( ${~OPTARG} )
	unsetopt nullglob
      ;;
      W) eval "results+=( $OPTARG )" ;;
      C) results+=( $(eval $OPTARG) ) ;;
      P) prefix="$OPTARG" ;;
      S) suffix="$OPTARG" ;;
      X)
        if [[ ${OPTARG[0]} = '!' ]]; then
	  results=( "${(M)results[@]:#${OPTARG#?}}" )
	else
 	  results=( "${results[@]:#$OPTARG}" )
	fi
      ;;
    esac
  done
  
  # support for the last, `word' option to compgen. Not particularly valuable
  # and without it zsh matching can do a better job. Comment in if needed.
  #shift $(( OPTIND - 1 ))
  #(( $# )) && results=( "${(M)results[@]:#$1*}" )

  print -l -- "$prefix${^results[@]}$suffix"
}

complete() {
  emulate -L zsh
  local args void cmd print remove
  args=( "$@" )
  zparseopts -D -a void o: A: G: W: C: F: P: S: X: a b c d e f g j k u v \
      p=print r=remove
  if [[ -n $print ]]; then
    for cmd print in ${(kv)_comps[(R)_bash*]}; do
      print "complete ${print#* } $cmd"
    done
  elif [[ -n $remove ]]; then
    print "not implemented: -r option"
  else
    compdef _bash_complete\ ${(j. .)${(q)args[1,-1-$#]}} "$@"
  fi
}

unfunction bashcompinit
autoload -U bashcompinit
return 0

This e-mail and any attachment is for authorised use by the intended recipient(s) only.  It may contain proprietary material, confidential information and/or be subject to legal privilege.  It should not be copied, disclosed to, retained or used by, any other party.  If you are not an intended recipient then please promptly delete this e-mail and any attachment and all copies and inform the sender.  Thank you.


             reply	other threads:[~2003-01-28  9:15 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2003-01-28  9:18 Oliver Kiddle [this message]
2003-01-28  9:25 ` Zefram
2003-01-28 16:42 ` Bart Schaefer
2003-01-29 10:17   ` Oliver Kiddle
2003-01-29 11:16     ` Peter Stephenson
2003-01-29 11:26       ` Peter Stephenson
2003-01-29 14:11       ` Oliver Kiddle
2003-02-03 12:51 ` Clemens Fischer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=15299.1043745489@finches.logica.co.uk \
    --to=okiddle@yahoo.co.uk \
    --cc=zsh-workers@sunsite.dk \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).