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

Re: completions which look the same



venus!juno!harman@xxxxxxxxxxxxxxxxx wrote:
> 
> 	If I have two jobs running with the same command name, say,
> 	less a.c and less b.c; then if I want to kill one of them,
> 	the completion for jobs (-j) does not help much.
> 
> 	What differs in those jobs is the job number (say 2 and 3),
> 	so I braced up to do the following sort of completion:
> 
> 	kill -SIGNAL __COMPLETION__
> 
> 	where __COMPLETION__ is (for example)  %2  # less a.c
> 						   ^^^^^^^^^^^
> 					this is part of completion!
> 
> 	Of course, the interactive_comments option has to be set.

Just looked back and didn't see a reply to this...

It's a nice idea, which I might well adopt too.  The following should
work, despite the bug mentioned underneath.  (The file handling in
jobfunc is necessary because jobs needs to be run in the current
shell, so can't write to a pipe --- this was discussed ad nauseam a
couple of years ago.  Ideally, you should trap the odd signal to
delete the file.)  The -Q flag to compctl is the key:  that's only
been around for a few beta versions.  It tells the shell not to quote
spaces and so on, which would destroy the point of the method.

jobfunc() {
   # Function to complete jobnames, with a commented description, as
   # suggested by Harmanjit Singh.
   # Author:  pws@xxxxxx (Peter Stephenson)
   # Usage:  with a compctl such as
   #   compctl -Q -K jobfunc -x 's[-] p[1,1]' -k signals -- kill

   # Make sure interactivecomments is on in the shell running the function.
   unsetopt localoptions
   setopt interactivecomments

   # Use a temporary file to store the jobs, since we can't use a pipe.
   local tmpf=/tmp/zshjobs$$

   # Get the jobs list: looks like
   # [1]  + running    sleep 30
   jobs >&! $tmpf
   reply=()

   local job jobno
   while read -A job
   do
      # Extract the job no. from the square brackets
      jobno=$job[1]
      jobno=${${jobno#\[}%\]}
   
      shift job
      # If this job is marked as - or +, the command starts at the
      # fourth field, else at the third.
      [[ $job[1] = [-+] ]] && shift job
      shift job
      # Now the remaining elements of $job contain the command description.
      # Add the whole completion to the reply.
      reply[$#reply+1]="%$jobno  # $job"
   done < $tmpf

   # Tidy up the job file.
   rm $tmpf
}
compctl -Q -K jobfunc -x 's[-] p[1,1]' -k signals -- kill


[The following is really directed at zsh-workers:]

The bug is this: the printjob() function is too eager to trash the
command line editor, so completing as above reprints the current line
before you get the completion.  This minimal fix tests whether the
output is going to a terminal before doing so.

A better fix would be to tell printjob() when it's being run
synchronously.  That would also allow you a flag to print to stdout on
a genuine call to jobs, which would be more natural (and more
compatible).  If that change is made, probably remaining printjob's
should go directly to the terminal output `shout', rather than stderr
which might be redirected.  This all ought to be easy, I'm just
feeling a bit overpatched at the moment.

*** Src/jobs.c.sigzle	Mon May  6 16:08:58 1996
--- Src/jobs.c	Fri May 31 13:32:27 1996
***************
*** 285,291 ****
  	int len2, fline = 1;
  	Process qn;
  
! 	trashzle();
  	if (doputnl)
  	    putc('\n', stderr);
  	for (pn = jn->procs; pn;) {
--- 285,292 ----
  	int len2, fline = 1;
  	Process qn;
  
! 	if (isatty(2))
! 	    trashzle();
  	if (doputnl)
  	    putc('\n', stderr);
  	for (pn = jn->procs; pn;) {

-- 
Peter Stephenson <pws@xxxxxx>       Tel: +49 33762 77366
WWW:  http://www.ifh.de/~pws/       Fax: +49 33762 77330
Deutches Electronen-Synchrotron --- Institut fuer Hochenergiephysik Zeuthen
DESY-IfH, 15735 Zeuthen, Germany.




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