bug-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: RFE: remove duplicate entries from the result of `compgen -W'


From: Clark Wang
Subject: Re: RFE: remove duplicate entries from the result of `compgen -W'
Date: Tue, 9 Sep 2014 09:19:43 +0800

On Mon, Sep 8, 2014 at 1:07 AM, Chet Ramey <chet.ramey@case.edu> wrote:

> On 9/4/14, 10:33 PM, Clark Wang wrote:
> > See following example:
> >
> >   $ echo $BASH_VERSION
> >   4.3.18(1)-release
> >   $ compgen -W 'hello hello' h
> >   hello
> >   hello
> >   $
> >
> > It'll be good if only one "hello" is outputted.
>
> `complete' and `compgen' only generate lists of possible completions.
> Readline performs duplicate removal when it is deciding what to do
> with that list.
>

Thanks, Chet. I did not realized this.

In the following example I'll describe my use case and you can understand
why my requirement.

Many commands like ping and ssh would take a hostname as their parameter.
I'm trying to define a common compspec for all these commands since
bash-4.1 added the `complete -D' option which is very cool. My idea is just
like bash's builtin completion behavior when we input `@<TAB>' but I'd like
the `@' char to be automatically removed when there's only one host
matching. See following demo code:

  function compgen_hosts
  {
      local cmd=$1
      local cur=$2
      local pre=$3
      local -a hosts
      local host

      hosts=( $(awk '$1 !~ /^ *#/' /etc/hosts) )

      if [[ $cur == @* ]]; then
          host=${cur#*@}
          COMPREPLY=( $( compgen -P @ -W "${hosts[*]}" "$host") )
      fi

      if [[ ${#COMPREPLY[@]} == 1 ]]; then
          COMPREPLY[0]=${COMPREPLY[0]#@}
      fi
  }

  complete -D -o nospace -F compgen_hosts

For most of the time this works fine. For example:

  $ foo @host-<TAB><TAB>
  @host-a.us  @host-b.us
  $ foo @host-a<TAB>
  $ foo host-a.us

But there's a small problem because there are duplicate hostnames. For
example both `127.0.0.1` and `::1` are mapping to `localhost' and then my
code would not work:

  $ foo @localhost<TAB><TAB>
  @localhost
  $

The reason is the `if [[ ${#COMPREPLY[@]} == 1 ]]' condition. For
`localhost' there are two candidates in COMPREPLY:

  COMPREPLY=( localhost localhost )

I know I can manually remove duplicate entries (either when reading
/etc/hosts or from the output of compgen) but it would be convenient if the
result of compgen has already done that for me. :)

Thanks.

-clark

>
> Chet
>
> --
> ``The lyf so short, the craft so long to lerne.'' - Chaucer
>                  ``Ars longa, vita brevis'' - Hippocrates
> Chet Ramey, ITS, CWRU    chet@case.edu
> http://cnswww.cns.cwru.edu/~chet/
>


reply via email to

[Prev in Thread] Current Thread [Next in Thread]