zsh-users
 help / color / mirror / code / Atom feed
* which-command help
@ 2005-05-17 13:20 Francisco Borges
  2005-05-17 14:47 ` Peter Stephenson
  0 siblings, 1 reply; 7+ messages in thread
From: Francisco Borges @ 2005-05-17 13:20 UTC (permalink / raw)
  To: Zsh User

Hello,

I can't get which-command ("^[?") to work as I would like:

 ~ % echo $ZSH_VERSION
4.3.0-dev-1

 ~ % whence -c ls
ls: aliased to /bin/ls -h -N --color=auto -F -v

 ~ % which-command /bin/ls
zsh: command not found: which-command

 ~ % alias which-command='whence -c'

# If I just run the command I get

 ~ % which-command ls
ls: aliased to /bin/ls -h -N --color=auto -F -v

# but if I use "^[?" (is which-command) I get:

 ~ % which-command /bin/ls
/bin/ls

How can I get ^[? to behave the same as a command line "which-command"?

-- 
Francisco Borges
Alfa Informatica - RuG


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

* Re: which-command help
  2005-05-17 13:20 which-command help Francisco Borges
@ 2005-05-17 14:47 ` Peter Stephenson
  2005-05-17 15:32   ` Bart Schaefer
  0 siblings, 1 reply; 7+ messages in thread
From: Peter Stephenson @ 2005-05-17 14:47 UTC (permalink / raw)
  To: Zsh User

Francisco Borges wrote:
> Hello,
> 
> I can't get which-command ("^[?") to work as I would like:
> 
>  ~ % whence -c ls
> ls: aliased to /bin/ls -h -N --color=auto -F -v
> 
>  ~ % alias which-command='whence -c'
> # If I just run the command I get
> 
>  ~ % which-command ls
> ls: aliased to /bin/ls -h -N --color=auto -F -v
> 
> # but if I use "^[?" (is which-command) I get:
> 
>  ~ % which-command /bin/ls
> /bin/ls
> 
> How can I get ^[? to behave the same as a command line "which-command"?

The problem is that the processing of which-command within the editor
expands the alias, so that the command line that which-command sees
already has the /bin/ls expanded.

I think this is a bug, fixed below: we don't want to expand aliases when
getting the name of the command.

For now, you can use a workaround along the lines of:

  unalias which-command
  zle -N which-command
  which-command() { zle -I; whence -c ${${(zQ)LBUFFER}[1]}; }

That should cover almost any case where the builtin editor function
works.  (Don't forget the "unalias": the interaction between aliases and
function definitions isn't pretty.)

I note that quoted forms of the command don't work with the builtin
implementation of which-command, i.e. you can't expand 'ls' or \ls.
That's a bug, but it's rather harder to fix---probably not *that* hard,
though I haven't worked out the best way.

That's one area where the function works better.  However, it's still
not smart enough to realise that if the word is quoted it's not subject to
alias expansion.  Hmm, actually...

which-command() {
  zle -I
  local -a wds
  wds=(${(z)LBUFFER})
  local wd=${wds[1]}
  local rawwd=${(Q)wd}

  # replace "whence -c" with your favourite function
  # (but NOT which-command!)
  if [[ $rawwd != $wd ]]; then
    # quoted, don't expand alias
    (unalias -- $rawwd 2>/dev/null; whence -c $rawwd)
  else
    # turn on globsubst for =ls etc.
    whence -c ${~rawwd}
  fi
}

It also handles =cmd and even baroque constructions like /bin/l[sS]
correctly.

Unless anyone can see a flaw, I think I can probably recommend this over
the builtin editor function.

Index: Src/Zle/zle_tricky.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/Zle/zle_tricky.c,v
retrieving revision 1.51
diff -u -r1.51 zle_tricky.c
--- Src/Zle/zle_tricky.c	23 Feb 2005 13:50:45 -0000	1.51
+++ Src/Zle/zle_tricky.c	17 May 2005 14:18:31 -0000
@@ -2354,8 +2354,10 @@
 getcurcmd(void)
 {
     int curlincmd;
+    int onoaliases = noaliases;
     char *s = NULL;
 
+    noaliases = 1;
     zleparse = 2;
     lexsave();
     metafy_line();
@@ -2381,6 +2383,7 @@
     inpop();
     errflag = zleparse = 0;
     lexrestore();
+    noaliases = onoaliases;
 
     return s;
 }

-- 
Peter Stephenson <pws@csr.com>                  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.

**********************************************************************


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

* Re: which-command help
  2005-05-17 14:47 ` Peter Stephenson
@ 2005-05-17 15:32   ` Bart Schaefer
  2005-05-17 15:55     ` Peter Stephenson
  0 siblings, 1 reply; 7+ messages in thread
From: Bart Schaefer @ 2005-05-17 15:32 UTC (permalink / raw)
  To: Peter Stephenson, Zsh User

On May 17,  3:47pm, Peter Stephenson wrote:
} Subject: Re: which-command help
}
} > # but if I use "^[?" (is which-command) I get:
} > 
} >  ~ % which-command /bin/ls
} > /bin/ls
} 
} The problem is that the processing of which-command within the editor
} expands the alias, so that the command line that which-command sees
} already has the /bin/ls expanded.
} 
} I think this is a bug, fixed below: we don't want to expand aliases when
} getting the name of the command.

Compare zsh-workers/20895 and surrounding thread.  Are we breaking one
thing to fix another?


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

* Re: which-command help
  2005-05-17 15:32   ` Bart Schaefer
@ 2005-05-17 15:55     ` Peter Stephenson
  2005-05-17 17:06       ` Bart Schaefer
  2005-05-18 10:27       ` PATCH: " Peter Stephenson
  0 siblings, 2 replies; 7+ messages in thread
From: Peter Stephenson @ 2005-05-17 15:55 UTC (permalink / raw)
  To: Bart Schaefer; +Cc: Zsh User

Bart Schaefer wrote:
> On May 17,  3:47pm, Peter Stephenson wrote:
> } Subject: Re: which-command help
> }
> } > # but if I use "^[?" (is which-command) I get:
> } > 
> } >  ~ % which-command /bin/ls
> } > /bin/ls
> } 
> } The problem is that the processing of which-command within the editor
> } expands the alias, so that the command line that which-command sees
> } already has the /bin/ls expanded.
> } 
> } I think this is a bug, fixed below: we don't want to expand aliases when
> } getting the name of the command.
> 
> Compare zsh-workers/20895 and surrounding thread.  Are we breaking one
> thing to fix another?

Well, your reply in that message was:

> Suppose you have
> 
>   alias LL='ls -lL'
> 
> Do you want run-help to display the man page for "ls", or do you want it
> to simply fail because there is no LL command?

Actually, it *doesn't* fail after the patch:

% alias LL='ls -lL'
% which-command LL
ls -lL

I would have said that's more useful, because it's clearer about what's
going on (even more so if which-command is aliased to something more
verbose).  However, I'm certainly not set on the patch.  I would be
happy to suggest using the editor widget instead.  That could even be
modified to expand the alias and lookup the first word as a command,
noting that aliases work recursively:

which-command() {
  zmodload -i zsh/parameter

  zle -I
  local -a wds
  wds=(${(z)LBUFFER})
  local wd=${wds[1]}
  local rawwd=${(Q)wd}
  local -A seen

  while true; do
    wd=${wds[1]}
    rawwd=${(Q)wd}

    # replace "whence -c" with your favourite function
    # (but NOT which-command!)
    if [[ $rawwd != $wd || -n $seen[$rawwd] ]]; then
      # quoted or already expanded, don't expand alias
      (unalias -- $rawwd 2>/dev/null; whence -c $rawwd)
    else
      # turn on globsubst for =ls etc.
      whence -c ${~rawwd}
      if [[ -n $aliases[$rawwd] && -z $seen[$rawwd] ]]; then
        # Recursively expand aliases
        seen[$rawwd]=1
        wds=(${(z)aliases[$rawwd]})
	continue
      fi
    fi
    break
  done
}

This might be worth sticking in Functions/Zle.

-- 
Peter Stephenson <pws@csr.com>                  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.

**********************************************************************


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

* Re: which-command help
  2005-05-17 15:55     ` Peter Stephenson
@ 2005-05-17 17:06       ` Bart Schaefer
  2005-05-17 17:47         ` Peter Stephenson
  2005-05-18 10:27       ` PATCH: " Peter Stephenson
  1 sibling, 1 reply; 7+ messages in thread
From: Bart Schaefer @ 2005-05-17 17:06 UTC (permalink / raw)
  To: Peter Stephenson; +Cc: Zsh User

On May 17,  4:55pm, Peter Stephenson wrote:
} Subject: Re: which-command help
}
} Well, your reply in that message was:
} 
} > Suppose you have
} > 
} >   alias LL='ls -lL'
} > 
} > Do you want run-help to display the man page for "ls", or do you want it
} > to simply fail because there is no LL command?
} 
} Actually, it *doesn't* fail after the patch:

I know which-command doesn't fail.  What about run-help?

} % which-command LL
} ls -lL
} 
} I would have said that's more useful, because it's clearer

No disagreement there.  I'm worried about shared code between two
widgets that (maybe) should have different behavior.


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

* Re: which-command help
  2005-05-17 17:06       ` Bart Schaefer
@ 2005-05-17 17:47         ` Peter Stephenson
  0 siblings, 0 replies; 7+ messages in thread
From: Peter Stephenson @ 2005-05-17 17:47 UTC (permalink / raw)
  To: Zsh User

Bart Schaefer wrote:
> } > Suppose you have
> } > 
> } >   alias LL='ls -lL'
> } > 
> } > Do you want run-help to display the man page for "ls", or do you want it
> } > to simply fail because there is no LL command?
> } 
> } Actually, it *doesn't* fail after the patch:
> 
> I know which-command doesn't fail.  What about run-help?

Oh, I see, it's one of those annoying messages you actually have to read
to see what it says.

Well, the simplest way around is something like the following... this
may be OK because we're only dealing with builtin widgets with fixed
names here.

Index: Src/Zle/zle_tricky.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/Zle/zle_tricky.c,v
retrieving revision 1.51
diff -u -r1.51 zle_tricky.c
--- Src/Zle/zle_tricky.c	23 Feb 2005 13:50:45 -0000	1.51
+++ Src/Zle/zle_tricky.c	17 May 2005 17:44:25 -0000
@@ -2390,9 +2390,12 @@
 processcmd(UNUSED(char **args))
 {
     char *s;
-    int m = zmult;
+    int m = zmult, na = noaliases;
 
+    if (!strcmp(bindk->nam, "which-command"))
+	noaliases = 1;
     s = getcurcmd();
+    noaliases = na;
     if (!s)
 	return 1;
     zmult = 1;

-- 
Peter Stephenson <pws@csr.com>                  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.

**********************************************************************


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

* PATCH: Re: which-command help
  2005-05-17 15:55     ` Peter Stephenson
  2005-05-17 17:06       ` Bart Schaefer
@ 2005-05-18 10:27       ` Peter Stephenson
  1 sibling, 0 replies; 7+ messages in thread
From: Peter Stephenson @ 2005-05-18 10:27 UTC (permalink / raw)
  To: Zsh User

Latest version of the which-command widget.  Added a style to give the
`whence' variant.  Also fixed up the correct behaviour in the case of
some abstruse aliases:  for example, after 'alias \ls=ls', you might get
something like

% \ls<Esc-?>
\ls: aliased to ls
ls: aliased to ls --color=tty
ls () {
        local ls
        if [[ -n $LS_COLORS ]]
        then
                ls=(ls --color=auto)
        else
                ls=(ls -F)
        fi
        command $ls $*
}

(The remainder is an example of what happens when your distributed
initialisation scripts are over-clever...)

"whence -c" might not be the best default for the type command seeing
that functions can be arbitrarily long.

You should be able to use this with any recent zsh by taking the second
hunk and stripping off the initial +'s.

[I meant to send this yesterday but didn't hit C-c C-c for some
reason... I hope I haven't forgotten something...]

Index: Doc/Zsh/contrib.yo
===================================================================
RCS file: /cvsroot/zsh/zsh/Doc/Zsh/contrib.yo,v
retrieving revision 1.41
diff -u -r1.41 contrib.yo
--- Doc/Zsh/contrib.yo	21 Feb 2005 14:40:35 -0000	1.41
+++ Doc/Zsh/contrib.yo	17 May 2005 18:04:24 -0000
@@ -858,6 +858,18 @@
 zstyle :insert-last-assignment match '[[:alpha:]][][[:alnum:]]#=*'
 bindkey '\e=' insert-last-assignment)
 )
+tindex(which-command)
+item(tt(which-command))(
+This function is a drop-in replacement for the builtin widget
+tt(which-command).  It has enhanced behaviour, in that it correctly
+detects whether or not the command word needs to be expanded as an
+alias; if so, it continues tracing the command word from the expanded
+alias until it reaches the command that will be executed.
+
+The style tt(whence) is available in the context tt(:zle:$WIDGET); this
+may be set to an array to give the command and options that will be used to
+investigate the command word found.  The default is tt(whence -c).
+)
 enditem()
 
 subsect(Styles)
Index: Functions/Zle/which-command
===================================================================
RCS file: Functions/Zle/which-command
diff -N Functions/Zle/which-command
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ Functions/Zle/which-command	17 May 2005 18:04:24 -0000
@@ -0,0 +1,42 @@
+zmodload -i zsh/parameter zsh/zutil
+
+zle -I
+
+local -a whencecmd wds
+
+# Set the whence style to your favourite function
+# (but NOT which-command!)
+zstyle -a :zle:$WIDGET whence whencecmd || whencecmd=(whence -c --)
+
+wds=(${(z)LBUFFER})
+local wd barewd
+local -A seen
+
+while true; do
+  wd=${wds[1]}
+  barewd=${(Q)wd}
+
+  if [[ $barewd != $wd || -n $seen[$barewd] ]]; then
+    # quoted or already expanded, see if original word is an alias...
+    if [[ -z $seen[$barewd] && -n $aliases[$wd] ]]; then
+      # yes, so we need to decode that, with no extra expansion...
+      $whencecmd $wd
+      seen[$wd]=1
+      wds=(${(z)aliases[$wd]})
+      continue
+    else
+      # use unquoted word, don't expand alias
+      (unalias -- $barewd 2>/dev/null; $whencecmd $barewd)
+    fi
+  else
+    # turn on globsubst for =ls etc.
+    $whencecmd ${~barewd}
+    if [[ -n $aliases[$barewd] && -z $seen[$barewd] ]]; then
+      # Recursively expand aliases
+      seen[$barewd]=1
+      wds=(${(z)aliases[$barewd]})
+      continue
+    fi
+  fi
+  break
+done

-- 
Peter Stephenson <pws@csr.com>                  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.

**********************************************************************


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

end of thread, other threads:[~2005-05-18 10:28 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-05-17 13:20 which-command help Francisco Borges
2005-05-17 14:47 ` Peter Stephenson
2005-05-17 15:32   ` Bart Schaefer
2005-05-17 15:55     ` Peter Stephenson
2005-05-17 17:06       ` Bart Schaefer
2005-05-17 17:47         ` Peter Stephenson
2005-05-18 10:27       ` PATCH: " Peter Stephenson

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