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

Re: VMS Style auto command-complition



Ziggy wrote:
> 	Recently I have tried using OpenVMS. So far I pretty much like
> everything there.
> 	One thing that I liked specifically about it is that it completes
> commands automatically if there is only one match.
> 	For example - if I want to purge all the previous versions of all files
> in the directory, instead of typing 'PURGE' I can type 'PU' because
> there is no any other command that starts with PU, so it knows that I'm
> talking about the command PURGE:
> 
> $ pu	<- here the command went out fine
> $ p 	<- here it says that there are other commands that start with p
> %DCL-W-ABVERB, ambiguous command verb - supply more characters
>  \P\
> 
> I wish you could tell me if it is possible to do with ZSH, because this
> feature is simply one of OpenVMS' best features.

There are lots of answers to this which deserve thinking about.

First, Unix command names tend to be short and it's much harder to find
unambiguous completions in many cases.

Second, you can explicitly ask for a completion of the command name with
a TAB.  Because of the first point, this is very often more useful than
assuming an unambiguous expansion.

Third, you can assign an explicit alias "alias pu=purge".  Since in
practice you tend to use only one abbreviation, you don't have to go
through the full equivalent ("alias pu=purge pur=purge purg=purge").

If, despite all that, you still want to try it this way, have a go at
the following function.  Assuming it's called autoexpand in your
function path, you activate it with

autoload autoexec
zle -N autoexec
alias -A autoexpand accept-line

and deactivate it with

alias -A .accept-line accept-line

Be careful, since it's not well tested and I'm sure there are additional
safety tests it could usefully have.  However, I don't think it's liable
to reformat your disk.

Instead of trying to execute a command and failing if it finds
multiple possibilities, it outputs an error message underneath and
allows you to edit the line again.  This is likely to be the biggest
source of grief.  You can turn that off by replacing

    zle -M "Multiple $hash matches: $expn"
    return 1

with

    zle .accept-line
    return 0


# start autoexpand
integer curpos len
local hash cmd line expn found

line=(${(z)BUFFER})
len=${#line[1]}
cmd=${(Q)line[1]}

if [[ -z $cmd ]]; then
  zle .accept-line
  return 0
fi

for hash in aliases reswords functions builtins commands; do
  # always accept exact match
  if [[ $hash = reswords ]]; then
    # actually it's an array
    expn=${reswords[(r)$cmd]}
  else
    # expn=${(P)hash[$cmd]} doesn't do the right thing
    eval expn='${(k)'$hash'[$cmd]}'
  fi
  if [[ -n $expn ]]; then
    zle .accept-line
    return 0
  fi
done

for hash in aliases reswords functions builtins commands; do
  if [[ $hash = reswords ]]; then
    # actually it's an array
    expn=(${reswords:#^$cmd*})
  else
    eval expn='(${(k)'$hash'[(I)$cmd*]})'
  fi
  if (( ${#expn} > 1 )); then
    zle -M "Multiple $hash matches: $expn"
    return 1
  elif (( ${#expn} == 1 )); then
    (( curpos = CURSOR ))
    BUFFER[1,$len]="$expn"
    (( curpos <= len )) && (( CURSOR = ${#expn[1]} ))
    zle .accept-line
    return 0
  else
    continue
  fi
done

zle .accept-line
# end autoexpand

-- 
Peter Stephenson <pws@xxxxxxx>                  Software Engineer
CSR PLC, Churchill House, Cambridge Business Park, Cowley Road
Cambridge, CB4 0WZ, UK                          Tel: +44 (0)1223 692070


**********************************************************************
This email and any files transmitted with it are confidential and
intended solely for the use of the individual or entity to whom they
are addressed. If you have received this email in error please notify
the system manager.

This footnote also confirms that this email message has been swept by
MIMEsweeper for the presence of computer viruses.

www.mimesweeper.com
**********************************************************************



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