zsh-users
 help / color / mirror / code / Atom feed
* help with command completion
@ 2000-01-05  2:08 Shao Zhang
  0 siblings, 0 replies; 7+ messages in thread
From: Shao Zhang @ 2000-01-05  2:08 UTC (permalink / raw)
  To: ZSH Mail List

Hi,
	I am trying to learn programming command completion using
	zstyle. After a long read of /usr/share/zsh/functions, I still
	have to idea, not even how to start.

	I have the following two cases to do, can someone please give me
	a hand and tell me how to start??


	lpr -P[TAB] complets to a list a printer name, read from
	/etc/printcap.


	rm -rf completes fine, but sudo rm -rf does not work.


	Thanks for the help.

Shao.

-- 
____________________________________________________________________________
Shao Zhang - Running Debian 2.1  ___ _               _____
Department of Communications    / __| |_  __ _ ___  |_  / |_  __ _ _ _  __ _ 
University of New South Wales   \__ \ ' \/ _` / _ \  / /| ' \/ _` | ' \/ _` |
Sydney, Australia               |___/_||_\__,_\___/ /___|_||_\__,_|_||_\__, |
Email: shao@cia.com.au                                                  |___/ 
_____________________________________________________________________________


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: help with command completion
@ 2000-01-05 14:37 Sven Wischnowsky
  0 siblings, 0 replies; 7+ messages in thread
From: Sven Wischnowsky @ 2000-01-05 14:37 UTC (permalink / raw)
  To: zsh-users


Shao Zhang wrote:

> Hi,
> 	I am trying to learn programming command completion using
> 	zstyle. After a long read of /usr/share/zsh/functions, I still
> 	have to idea, not even how to start.
>
>
> 	I have the following two cases to do, can someone please give me
> 	a hand and tell me how to start??
> 
> 
> 	lpr -P[TAB] complets to a list a printer name, read from
> 	/etc/printcap.

It's not `using zstyle'. zstyle is only the mechanism used for
configuration it can be used by completion functions but it need not.

The first step is always to create a file named like _lp (the
underscore is the important bit). Place that in a directory in your
$fpath (so that compinit will find it). In the first line in that file 
you specify the commands this file will provide completion
functionality for, e.g.:

  #compdef lpr

Since there is already a function offering completion for lpr (namely
_ps, which completes only names of postscript files) you have to make
sure that the file you created will be found before that (i.e. it is
in a directory earlier in $fpath than the User directory from the
distribution).

In the rest of the file you use the basic mechanisms described in the
compwid manual page and/or the utility functions described in the
compsys manual page to generate the completions. Since this is only a
simple example I'll use only the basic ones.

First we want to see if we have to complete printer names, which is
the case if we are after a -P option, directly after it in the same
word or in the word after it. For this kind of stuff there are the
special parameters like $PREFIX and $words. We could do:

  if [[ "$PREFIX" = -P* || "$words[CURRENT-1]" = -P ]]; then
    ...
  fi

Since $PREFIX is the beginning of the string the cursor is on (up to
the cursor position), the first test is true if we are on a word
beginning with -P and the second one uses the $words array which
contains all words from the line and the $CURRENT special parameter
which gives the index for the word we are on into $words array. So
$words[CURRENT-1] gives the previous word.

We would now start generating names of printers as possible
completions, the completion code will use the strings in $PREFIX and
$SUFFIX to see if the names we generate match the stuff from the
line. But since in the first case there is the -P at the beginning
this wouldn't match, so we have to `remove' that. More precisely, we
have to ensure that the completion code still knows about it but
doesn't use it for matching. This is done by removing it from $PREFIX
and appending it to another special parameter: $IPREFIX (that's
`ignored prefix'). We could do it by hand:

  IPREFIX="${IPREFIX}-P"
  PREFIX="${PREFIX#??}"

But since such tests followed by such modifications are needed quite
often, there is support for it: the compset builtin. This does the
test and if it succeeds, immediatly modifies the parameters that need
to be modified. So we can do everything together with:

  if compset -P -P || [[ "$words[CURRENT-1] = -P ]]; then
    ...
  fi

Then we can just start generating the printer names in this `if'. One
possibility is something like:

  compadd - "${(@)${(@s:|:)${(@)${(@f)$(< /etc/printcap)}:#[    \#]*}%%:*}%%[ 	]*}"

The compadd builtin gets the possible completions as arguments. It
also supports several options but these are indeed needed relatively
seldom. In the functions from the distribution most options used are
generated more or less automatically by some helper functions. These
mainly make the completion function more fun to use or the completion
listing more fun to look at (at least I hope that).

But lets first continue with the example. Until now the function can
complete only printer names after -P which isn't really useful for a
command like lpr, so we have to make it complete file names, too, but
only for the other arguments:

  if ...; then
    ...
  else
    _ps
  fi

This uses the utility function _ps from the distribution which
completes Postscript files (or directories or all files if there are
no Postscript files). _ps itself, btw, mainly uses another helper
function: _files. This is used throughout the completion system and
completes filenames allowing partial pathname completion
(i.e. /u/inc<TAB> can be completed to /usr/include).

So, the whole function (file) could look like:

  #compdef lpr

  if compset -P -P || [[ "$words[CURRENT-1] = -P ]]; then
    compadd - "${(@)${(@s:|:)${(@)${(@f)$(< /etc/printcap)}:#[    \#]*}%%:*}%%[ 	]*}"
  else
    _ps
  fi

Since in the completion system we generally want to avoid the extra
processes needed for $(...), we would use caching for the printer
names there (and the function for the lp commands I just sent to
zsh-workers does that). And we would also make this nicer by
supporting the other mechanisms used throughout the completion system.

One of these is that matches are always added with descriptions that
can be made visible in completion lists using the format style for the 
`descriptions' and `messages' tags. Everything a completion function
needs to do for that is call the utility function _description. It
gets a tag name (users are completely free to chose any tag name they
want), the name of an array and a short description as
arguments. E.g.:

  local expl

  _description printers expl printer

(That `printer' is the description.) _description will set up the
array $expl to contain options for compadd that add the description if 
requested by the user and several other things users can request for
all matches generated (this `requesting', btw, is what is done using
zstyle).

Another thing all completion functions (I mean those in the
distribution) should support is tags. More precisely, users should be
able to configure (using the tag-order style) if they want to see
completions of a certain type or not. For this, there are utility
functions like _wanted and _requested which get a tag name as
argument. In the example above we can use the first one:

  _wanted printers && compadd ...

_wanted and _requested only return zero if the user requested the type 
of matches represented by the tag (more precisely: didn't say
explicitly that he doesn't want them).

With that users can say that they don't want printer names to be
completed (this sounds weird when talking about contexts where only
one type of matches can be generated, but if multiple types are
possible, this quickly makes sense).

And since every decent completion function should use both
descriptions and tags, _wanted and _requested can also be made to call 
_description by giving them the same arguments that would be given to
that, so:

  #compdef lpr

  if compset -P -P || [[ "$words[CURRENT-1] = -P ]]; then
    local expl

    _wanted printers expl printer &&
      compadd - "${(@)${(@s:|:)${(@)${(@f)$(< /etc/printcap)}:#[    \#]*}%%:*}%%[ 	]*}"
  else
    _ps
  fi

That's all that's needed to make the function behave like the other
functions in the completion system (_ps already does all the
description and tag stuff, so we don't have to do anything there).


As Peter already said I, too, would suggest that people who want to
write completion functions first start by copying and modifying
existing functions. Then continue with simple functions using the
basic stuff from the compwid manual and then start using the utility
functions. Note that there is also the completion-style-guide in the
Etc directory of the distribution which should help a bit with the
more complicated stuff (mainly the utility functions from the
completion system).

And if you then arrive at some interesting completion function I would 
be glad if you could send it to the list and at least I (and I guess
others, too) will look at it and see if and how it can be improved or
made more standard in its behaviour.


> 
> 
> 	rm -rf completes fine, but sudo rm -rf does not work.

Hm. The current development version (and some older version, too) have 
a completion function for sudo and it works nicely for me. Don't you
have _sudo or do you have aliased sudo to something?


Bye
 Sven


--
Sven Wischnowsky                         wischnow@informatik.hu-berlin.de


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: help with command completion
@ 2000-01-05 13:42 Sven Wischnowsky
  0 siblings, 0 replies; 7+ messages in thread
From: Sven Wischnowsky @ 2000-01-05 13:42 UTC (permalink / raw)
  To: zsh-users


[ This one moved to zsh-workers... ]

Shao Zhang wrote:

> 	lpr -P[TAB] complets to a list a printer name, read from
> 	/etc/printcap.

Here is _lp for lpr, lp, lpq, and lprm. Could definitely be improved,
but I don't know how (non-)standard the options supported by my lpr
are.


Bye
 Sven

P.S.: On top of Alexandre's _prcs.

diff -ru ../z.old/Completion/User/.distfiles Completion/User/.distfiles
--- ../z.old/Completion/User/.distfiles	Wed Jan  5 14:38:27 2000
+++ Completion/User/.distfiles	Wed Jan  5 14:38:30 2000
@@ -2,7 +2,7 @@
     .distfiles
     _a2ps _archie _bison _bunzip2 _bzip2 _chown _compress _configure _cvs
     _dd _dir_list _dirs _dvi _find _flex _gcc _gdb _gprof _groups _gs
-    _gunzip _gv _gzip _hosts _ispell _killall _lynx _mailboxes _make _man
+    _gunzip _gv _gzip _hosts _ispell _killall _lp _lynx _mailboxes _make _man
     _mh _mount _mutt _my_accounts _netscape _nslookup _other_accounts
     _pack _patch _pbm _pdf _perl_basepods _perl_builtin_funcs
     _perl_modules _perldoc _ports _prcs _prompt _ps _pspdf _rcs _rlogin _sh
diff -ru ../z.old/Completion/User/_lp Completion/User/_lp
--- ../z.old/Completion/User/_lp	Wed Jan  5 14:38:45 2000
+++ Completion/User/_lp	Wed Jan  5 14:36:18 2000
@@ -0,0 +1,58 @@
+#compdef lp lpr lpq lprm
+
+local file expl ret=1 list disp strs shown
+
+if (( ! $+_lp_cache )); then
+   file=( /etc/(printcap|printers.conf)(N) )
+
+  if (( $#file )); then
+    _lp_cache=( "${(@)${(@s:|:)${(@)${(@f)$(< $file[1])}:#[    \#]*}%%:*}%%[ 	]*}" )
+  else
+    # Default value. Could probably be improved
+
+    _lp_cache=( lp0 )
+  fi
+fi
+
+if compset -P -P || [[ "$words[CURRENT-1]" = -P ]]; then
+  _wanted printers expl printer && compadd "$expl" - "$_lp_cache[@]"
+else
+  if [[ "$words[1]" = (lpq|lprm) ]]; then
+    list=( "${(@M)${(f@)$(lpq)}:#[0-9]*}" )
+
+    if (( $#list )); then
+      _tags users jobs
+
+      while _tags; do
+        if _requested users expl user; then
+          strs=( "${(@)${(@)list##[^ 	]##[ 	]##[^ 	]##[ 	]##}%%[ 	]*}" )
+          if [[ -z "$shown" ]] &&
+             zstyle -t ":completion:${curcontext}:users" verbose; then
+            disp=(-ld list)
+  	  shown=yes
+          else
+  	  disp=()
+          fi
+          compadd "$expl[@]" "$disp[@]" - "$strs[@]" || _users && ret=0
+        fi
+        if _requested jobs expl job; then
+          strs=( "${(@)${(@)list##[^ 	]##[ 	]##[^ 	]##[ 	]##[^ 	]##[ 	]##}%%[ 	]*}" )
+          if [[ -z "$shown" ]] &&
+             zstyle -t ":completion:${curcontext}:jobs" verbose; then
+            disp=(-ld list)
+  	  shown=yes
+          else
+  	  disp=()
+          fi
+          compadd "$expl[@]" "$disp[@]" - "$strs[@]" && ret=0
+        fi
+        (( ret )) || return 0
+      done
+    else
+      _message 'no print jobs'
+    fi
+    return 1
+  else
+    _ps
+  fi
+fi
diff -ru ../z.old/Completion/User/_ps Completion/User/_ps
--- ../z.old/Completion/User/_ps	Tue Jan  4 14:57:55 2000
+++ Completion/User/_ps	Wed Jan  5 13:43:06 2000
@@ -1,4 +1,4 @@
-#compdef ps2epsi ps2pdf epsffit extractres fixdlsrps fixfmps fixmacps fixpsditps fixpspps fixscribeps fixtpps fixwfwps fixwpps fixwwps includeres psbook psmerge psnup psresize psselect pstops psmulti pswrap lpr lp
+#compdef ps2epsi ps2pdf epsffit extractres fixdlsrps fixfmps fixmacps fixpsditps fixpspps fixscribeps fixtpps fixwfwps fixwpps fixwwps includeres psbook psmerge psnup psresize psselect pstops psmulti pswrap
 
 local expl
 

--
Sven Wischnowsky                         wischnow@informatik.hu-berlin.de


^ permalink raw reply	[flat|nested] 7+ messages in thread

* help with command completion
@ 2000-01-05  5:09 Shao Zhang
  0 siblings, 0 replies; 7+ messages in thread
From: Shao Zhang @ 2000-01-05  5:09 UTC (permalink / raw)
  To: ZSH Mail List

Hi,                                                                                                                                                              
        I am trying to learn programming command completion using                                                                                                
        zstyle. After a long read of /usr/share/zsh/functions, I still                                                                                           
        have to idea, not even how to start.                                                                                                                     
                                                                                                                                                                 
        I have the following two cases to do, can someone please give me                                                                                         
        a hand and tell me how to start??                                                                                                                        
                                                                                                                                                                 
                                                                                                                                                                 
        lpr -P[TAB] complets to a list a printer name, read from                                                                                                 
        /etc/printcap.                                                                                                                                           
                                                                                                                                                                 
                                                                                                                                                                 
        rm -rf completes fine, but sudo rm -rf does not work.                                                                                                    
                                                                                                                                                                 
                                                                                                                                                                 
        Thanks for the help.                                                                                                                                     
                                                                                                                                                                 
Shao.                                                                                                                                                            
                                                                                                            

-- 
____________________________________________________________________________
Shao Zhang - Running Debian 2.1  ___ _               _____
Department of Communications    / __| |_  __ _ ___  |_  / |_  __ _ _ _  __ _ 
University of New South Wales   \__ \ ' \/ _` / _ \  / /| ' \/ _` | ' \/ _` |
Sydney, Australia               |___/_||_\__,_\___/ /___|_||_\__,_|_||_\__, |
Email: shao@cia.com.au                                                  |___/ 
_____________________________________________________________________________


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: help with command completion
  1999-12-21  9:48 ` Alexandre Duret-Lutz
@ 1999-12-22  0:01   ` Shao Zhang
  0 siblings, 0 replies; 7+ messages in thread
From: Shao Zhang @ 1999-12-22  0:01 UTC (permalink / raw)
  To: Alexandre Duret-Lutz; +Cc: ZSH Mail List

Alexandre Duret-Lutz [alexandre.duret@greyc.ismra.fr] wrote:
> Note that `compstyle' will be obsoleted by `zstyle', 
> so prefer the later if you have it.

	Sorry, this really confuses me. I just install zsh version
	3.1.6.0zw19991220-1. And I can see the new command zstyle.

	But when it comes to command completion, which one should I use?
	compctl or compstyle or zstyle.

	Will both compctl and compstyle be available in the future
	version, or they will be obsolute soon??

	Thanks.

Shao.

-- 
____________________________________________________________________________
Shao Zhang - Running Debian 2.1  ___ _               _____
Department of Communications    / __| |_  __ _ ___  |_  / |_  __ _ _ _  __ _ 
University of New South Wales   \__ \ ' \/ _` / _ \  / /| ' \/ _` | ' \/ _` |
Sydney, Australia               |___/_||_\__,_\___/ /___|_||_\__,_|_||_\__, |
Email: shao@cia.com.au                                                  |___/ 
_____________________________________________________________________________


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: help with command completion
  1999-12-21  4:59 Shao Zhang
@ 1999-12-21  9:48 ` Alexandre Duret-Lutz
  1999-12-22  0:01   ` Shao Zhang
  0 siblings, 1 reply; 7+ messages in thread
From: Alexandre Duret-Lutz @ 1999-12-21  9:48 UTC (permalink / raw)
  To: ZSH Mail List; +Cc: Shao Zhang

>>> "SZ" == Shao Zhang <shao@cia.com.au> writes:

[...]

 SZ> 	HOSTS=(juggler.cse.unsw.edu.au haydn.cse.unsw.edu.au godzilla)
 SZ> 	compstyle '*' telnet $HOSTS

Please try :

        compstyle '*:telnet:*:hosts' hosts $HOST

for the more general case you may want

        compstyle '*:hosts' hosts $HOST

so that it work for ftp, rlogin, etc. too.

Note that `compstyle' will be obsoleted by `zstyle', 
so prefer the later if you have it.

[...]

-- 
Alexandre Duret-Lutz



^ permalink raw reply	[flat|nested] 7+ messages in thread

* help with command completion
@ 1999-12-21  4:59 Shao Zhang
  1999-12-21  9:48 ` Alexandre Duret-Lutz
  0 siblings, 1 reply; 7+ messages in thread
From: Shao Zhang @ 1999-12-21  4:59 UTC (permalink / raw)
  To: ZSH Mail List

Hi,
	I am trying to learn the new command completion system.

	I have these lines in my .zshrc:

	HOSTS=(juggler.cse.unsw.edu.au haydn.cse.unsw.edu.au godzilla)
	compstyle '*' telnet $HOSTS


	but when I type telnet [TAB], I got this:

	[15:58|pts/13]shao@shao % telnet 
	host
	localhost                    shao.penguinpowered.com
	shao                         www.shao.penguinpowered.com

	which is using the function defined in
	/usr/share/zsh/functions/_telnet.

	Please help me. Thanks.

Shao.

-- 
____________________________________________________________________________
Shao Zhang - Running Debian 2.1  ___ _               _____
Department of Communications    / __| |_  __ _ ___  |_  / |_  __ _ _ _  __ _ 
University of New South Wales   \__ \ ' \/ _` / _ \  / /| ' \/ _` | ' \/ _` |
Sydney, Australia               |___/_||_\__,_\___/ /___|_||_\__,_|_||_\__, |
Email: shao@cia.com.au                                                  |___/ 
_____________________________________________________________________________


^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2000-01-05 14:38 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2000-01-05  2:08 help with command completion Shao Zhang
  -- strict thread matches above, loose matches on Subject: below --
2000-01-05 14:37 Sven Wischnowsky
2000-01-05 13:42 Sven Wischnowsky
2000-01-05  5:09 Shao Zhang
1999-12-21  4:59 Shao Zhang
1999-12-21  9:48 ` Alexandre Duret-Lutz
1999-12-22  0:01   ` Shao Zhang

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).