zsh-users
 help / color / mirror / code / Atom feed
* print -s and History Expansion
@ 2006-05-02 19:10 Chris Johnson
  2006-05-02 21:47 ` Peter Stephenson
  0 siblings, 1 reply; 5+ messages in thread
From: Chris Johnson @ 2006-05-02 19:10 UTC (permalink / raw)
  To: zsh-users

Multiword lines issued to history with print -s don't appear to be
considered as multiple words, as evidenced by the unexpected history
expansion found in the following interaction:

[cjohnson@sissy] ~ S1: echo a b c
a b c
[cjohnson@sissy] ~ S1: echo !!:1
echo a
a
[cjohnson@sissy] ~ S1:  print -s 'echo a b c'
[cjohnson@sissy] ~ S1: echo !!:1
zsh: no such word in event
[cjohnson@sissy] ~ S1:  print -s 'echo a b c'
[cjohnson@sissy] ~ S1: echo !!
echo echo a b c
echo a b c
[cjohnson@sissy] ~ S1:  print -s 'echo a b c'
[cjohnson@sissy] ~ S1: echo !!:0
echo echo a b c
echo a b c

The whole line is considered !!:0 and not just the command name.  I'm
not running the latest version of zsh, so I don't know if this is
changed in a newer version.  Perhaps it's a feature that I don't
understand.  Can any verify that this is or isn't supposed to happen?

Thanks!

-- 
Chris Johnson
cjohnson@cs.utk.edu
http://www.cs.utk.edu/~cjohnson


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

* Re: print -s and History Expansion
  2006-05-02 19:10 print -s and History Expansion Chris Johnson
@ 2006-05-02 21:47 ` Peter Stephenson
  2006-05-04 19:06   ` Chris Johnson
  0 siblings, 1 reply; 5+ messages in thread
From: Peter Stephenson @ 2006-05-02 21:47 UTC (permalink / raw)
  To: Zsh users list

Chris Johnson wrote:
> Multiword lines issued to history with print -s don't appear to be
> considered as multiple words, as evidenced by the unexpected history
> expansion found in the following interaction:
> 
> [cjohnson@sissy] ~ S1:  print -s 'echo a b c'
> [cjohnson@sissy] ~ S1: echo !!:1
> zsh: no such word in event

You'll kick yourself when I tell you... to get the line entered in the
history as multiple words, pass multiple words to echo:

% print -s echo a b c
% echo !!:1
a

No quotes.


You may have come across this obliquely, because the line you were
saving came from a scalar variable.  In that case, the best thing to do
is probably to zplit it.  If you've got histverify set it looks like
this (else you don't see the final line, just the result of it):

% var='echo one "two three" "four five"'
% print -s ${(z)var}
% print !!:2
% print "two three"


A more complicated case is where you already have a set of arguments,
but they aren't yet quoted, for example:

% array=(echo one 'two three' 'four five')

Here, the quotes have already been "used up" in generating the array.
You can requote the arguments to get all the parts of a command line
like this (again with histverify):

% print -s ${(qq)array}
% echo !!:$
% print 'four five'

That came up with single quotes; (q) would have used backslashes.


In other words, there are plenty of ways of doing it, it depends what
you're starting with.  That should give you enough to be getting on with.

-- 
Peter Stephenson <p.w.stephenson@ntlworld.com>
Web page now at http://homepage.ntlworld.com/p.w.stephenson/


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

* Re: print -s and History Expansion
  2006-05-02 21:47 ` Peter Stephenson
@ 2006-05-04 19:06   ` Chris Johnson
  2006-05-05  8:55     ` Peter Stephenson
  0 siblings, 1 reply; 5+ messages in thread
From: Chris Johnson @ 2006-05-04 19:06 UTC (permalink / raw)
  To: zsh-users

Peter Stephenson sent me the following 1.5K:

> > Multiword lines issued to history with print -s don't appear to be
> > considered as multiple words, as evidenced by the unexpected history
> > expansion found in the following interaction:
> > 
> > [cjohnson@sissy] ~ S1:  print -s 'echo a b c'
> > [cjohnson@sissy] ~ S1: echo !!:1
> > zsh: no such word in event
> 
> You'll kick yourself when I tell you... to get the line entered in the
> history as multiple words, pass multiple words to echo:
> 
> % print -s echo a b c
> % echo !!:1
> a

That fixes the problem.  Thanks!  The oblique way that I ran into this
was actually through a post from 1997 (maybe) you made to zsh-users.
Someone asked how to commit a line to history without executing it, and
you offered

   bindkey -s "^X^H" "^['^A print -s ^M"

Since removing the the quote-line (^[') will introduce trouble with &
and so on which really do need to be quoted, I've had to resort to my
own widget:

   commit-to-history() {
      # zsplit current command, expand result to all its quoted fields
      # ("f1" "f2" "f3"), prepend it with a command to make it written
      # to history, and then execute it.
      BUFFER=" print -s ${${(z)BUFFER}[@]}"
      zle accept-line
   }
   zle -N commit-to-history
   bindkey "^X^H" commit-to-history

I tried using ${(qq){$(z)BUFFER}} but that didn't work.

Perhaps I could have stuck with the simpler bind, but it seems that
somehow I need to get the command into a parameter before I can split
it.  Is there any way to expand literals?

-- 
Chris Johnson
cjohnson@cs.utk.edu
http://www.cs.utk.edu/~cjohnson


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

* Re: print -s and History Expansion
  2006-05-04 19:06   ` Chris Johnson
@ 2006-05-05  8:55     ` Peter Stephenson
  2006-05-05 18:05       ` Chris Johnson
  0 siblings, 1 reply; 5+ messages in thread
From: Peter Stephenson @ 2006-05-05  8:55 UTC (permalink / raw)
  To: zsh-users

Chris Johnson wrote:
>    commit-to-history() {
>       # zsplit current command, expand result to all its quoted fields
>       # ("f1" "f2" "f3"), prepend it with a command to make it written
>       # to history, and then execute it.
>       BUFFER=" print -s ${${(z)BUFFER}[@]}"
>       zle accept-line
>    }
>    zle -N commit-to-history
>    bindkey "^X^H" commit-to-history
> 
> I tried using ${(qq){$(z)BUFFER}} but that didn't work.

To avoid the extra command line execution I would use:

commit-to-history() {
  print -s ${(z)BUFFER}
  BUFFER=
  zle accept-line
}

then there are no quoting problems.  You still need the accept-line if
you plan on using what you've just added to the history immediately,
since otherwise the history isn't reread.  However, it's now on an empty
buffer.

> Perhaps I could have stuck with the simpler bind, but it seems that
> somehow I need to get the command into a parameter before I can split
> it.  Is there any way to expand literals?

There's no way to avoid using a parameter without doing worse things.  Zle
widgets are anyway more readable and predictable than bindkey -s tricks.

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


To access the latest news from CSR copy this link into a web browser:  http://www.csr.com/email_sig.php


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

* Re: print -s and History Expansion
  2006-05-05  8:55     ` Peter Stephenson
@ 2006-05-05 18:05       ` Chris Johnson
  0 siblings, 0 replies; 5+ messages in thread
From: Chris Johnson @ 2006-05-05 18:05 UTC (permalink / raw)
  To: zsh-users

Peter Stephenson sent me the following 1.4K:

> >    commit-to-history() {
> >       # zsplit current command, expand result to all its quoted fields
> >       # ("f1" "f2" "f3"), prepend it with a command to make it written
> >       # to history, and then execute it.
> >       BUFFER=" print -s ${${(z)BUFFER}[@]}"
> >       zle accept-line
> >    }
>
> To avoid the extra command line execution I would use:
> 
> commit-to-history() {
>   print -s ${(z)BUFFER}
>   BUFFER=
>   zle accept-line
> }
> 
> then there are no quoting problems.  You still need the accept-line if
> you plan on using what you've just added to the history immediately,
> since otherwise the history isn't reread.  However, it's now on an empty
> buffer.

I was able to get 

   commit-to-history() {
      print -s ${(z)BUFFER}
      zle send-break
   }
   zle -N commit-to-history

to work just fine.  History expansion pulls in the split words of a just
committed-to-history line just fine, and the command line stays
displayed for reference.  It's just like hitting ^C but adds the line to
history, which is exactly what I was looking for.

As far as your accept-line comment above, is the send-break widget not
supposed to behave the way it is?  The line is immediately available for
history expansion (histverify is set):

[cjohnson@namib] ~: echo one two three
[cjohnson@namib] ~: echo !!:$
[cjohnson@namib] ~: echo three
three

-- 
Chris Johnson
cjohnson@cs.utk.edu
http://www.cs.utk.edu/~cjohnson


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

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

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-05-02 19:10 print -s and History Expansion Chris Johnson
2006-05-02 21:47 ` Peter Stephenson
2006-05-04 19:06   ` Chris Johnson
2006-05-05  8:55     ` Peter Stephenson
2006-05-05 18:05       ` Chris Johnson

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