zsh-users
 help / color / mirror / code / Atom feed
* append to history entry?
@ 2016-12-26 23:16 Ray Andrews
  2016-12-27  1:28 ` Ray Andrews
       [not found] ` <5288b537-f06a-d18a-60ea-1f962856c80c__41345.3811700039$1482803962$gmane$org@eastlink.ca>
  0 siblings, 2 replies; 21+ messages in thread
From: Ray Andrews @ 2016-12-26 23:16 UTC (permalink / raw)
  To: Zsh Users

Can I arrange for a function to append something to it's own entry into 
history when it is run? My function 'rap' is a wrapper around all the 
various 'apt' 'dpkg' and sundry Debian package managers and I might:


$ rap ,I libapt-pkg.so.4.12

... which installs that package. But, I tend to install things in backup 
clones of my install so that if the package screws things up royally, 
which happens far too often, I can just back out of the clone and 
restore it to a previous condition and no harm has been done.  But, 
there can be situations where I've installed something I want to keep to 
one of these clones, and I can forget what has been installed where. For 
example here's just a few days mucking things up:

18270  rap ,F libapt-pkg.so.4.12
18272  rap ,F libapt-pkg.so
18290  rap ,N regex*
18291  rap ,I regexxer
18296  rap ,N draftsight
18369  rap ,I xdg-utils
18370  rap ,I libaudio2
18386  rap ,N epiphany
18388  rap ,I epiphany-browser
18390  rap ,N dosemu
18391  rap ,I dosemu
18462  rap ,I librecad
18472  rap ,F libicuuc
18473  rap ,I libicu57
18474  rap ,R libreoffice
18475  rap ,I libreoffice
18482  rap ,N pptview

... now, 'draftsight' made a shambles of the clone, but stuff before and 
after that might have gone to different clones so if it were possible to 
have the above lines (as retrieved from history) somehow stored with 
'$HOST' appended to them automatically (my $HOST always being the name 
of the clone I'm running) it would look something like this:

18296  rap ,N draftsight HP-b6--9-Debian2

... which would let me know that I installed draftsight to clone #2 on 
partition 6 of disk 'b' on machine 'HP'.

So I'm asking for the variable '$HOST' to be added to the command before 
it is appended to history.  Doable?


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

* Re: append to history entry?
  2016-12-26 23:16 append to history entry? Ray Andrews
@ 2016-12-27  1:28 ` Ray Andrews
  2016-12-27  4:47   ` Bart Schaefer
       [not found] ` <5288b537-f06a-d18a-60ea-1f962856c80c__41345.3811700039$1482803962$gmane$org@eastlink.ca>
  1 sibling, 1 reply; 21+ messages in thread
From: Ray Andrews @ 2016-12-27  1:28 UTC (permalink / raw)
  To: zsh-users

On 26/12/16 03:16 PM, Ray Andrews wrote:
> Can I arrange for a function to append something to it's own entry 
> into history when it is run? My function 'rap' is a wrapper around all 
> the various 'apt' 'dpkg' and sundry Debian package managers and I might:
>
>
> $ rap ,I libapt-pkg.so.4.12

This seems to work:

    alias rap=' noglob _rap'
    function _rap ()
    {

    print -S "rap $* ; echo $HOST"
    ...
    ...

Leading space keeps the command out of history as usual, then I just 
replace it with the massaged version.  On recall:


     $ rap ,N libreoffice ; echo HP-b6--9-Debian2

... so the $HOST information is harmless on re-execution but I have my 
reminder  as to which clone I was running at the time.

Sound?


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

* Re: append to history entry?
  2016-12-27  1:28 ` Ray Andrews
@ 2016-12-27  4:47   ` Bart Schaefer
  0 siblings, 0 replies; 21+ messages in thread
From: Bart Schaefer @ 2016-12-27  4:47 UTC (permalink / raw)
  To: zsh-users

On Dec 26,  5:28pm, Ray Andrews wrote:
} Subject: Re: append to history entry?
}
} On 26/12/16 03:16 PM, Ray Andrews wrote:
} > Can I arrange for a function to append something to it's own entry 
} > into history when it is run?

You might also want to look at the zshaddhistory hook function.

} This seems to work:
}     ...
} Leading space keeps the command out of history as usual, then I just 
} replace it with the massaged version.

This looks fine.  My only suggestion would be to use the ":" command
instead of "echo".


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

* Re: append to history entry?
       [not found] ` <5288b537-f06a-d18a-60ea-1f962856c80c__41345.3811700039$1482803962$gmane$org@eastlink.ca>
@ 2016-12-27 12:55   ` Daniel Shahaf
  2016-12-27 16:00     ` Bart Schaefer
  0 siblings, 1 reply; 21+ messages in thread
From: Daniel Shahaf @ 2016-12-27 12:55 UTC (permalink / raw)
  To: Ray Andrews; +Cc: zsh-users

Ray Andrews wrote on Mon, Dec 26, 2016 at 17:28:05 -0800:
>    print -S "rap $* ; echo $HOST"

This will not reproduce arguments with literal whitespace or backslashes
correctly.  Two changes are required to support them:

1) Pass -r to print.

2) When interpolating a variable into a command, it should be
(q)-esacped.

Putting all that and Bart's suggestion together gives:

    print -rS -- "rap ${(q)@} ; : ${(q)HOST}"

[just in case somebody puts a backslash in their hostnames ;)]

Cheers,

Daniel


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

* Re: append to history entry?
  2016-12-27 12:55   ` Daniel Shahaf
@ 2016-12-27 16:00     ` Bart Schaefer
  2016-12-27 18:23       ` Ray Andrews
  0 siblings, 1 reply; 21+ messages in thread
From: Bart Schaefer @ 2016-12-27 16:00 UTC (permalink / raw)
  To: zsh-users

On Dec 27, 12:55pm, Daniel Shahaf wrote:
}
}     print -rS -- "rap ${(q)@} ; : ${(q)HOST}"

Well, if we're being really pedantic, that's not right either, because
print -S requires a single string argument, but ${(q)@} in double quotes
results in multiple strings quoted individually, whereas ${(q)*} results
in backslashing the spaces between the arguments.

An extra level of nested expansion fixes that, and for readability it'd
be better to use (q+) on the arguments and (q-) on the host name:

    print -rS -- "rap ${${(q+)@}} ; : ${(q-)HOST}"


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

* Re: append to history entry?
  2016-12-27 16:00     ` Bart Schaefer
@ 2016-12-27 18:23       ` Ray Andrews
  2016-12-27 19:09         ` Bart Schaefer
  0 siblings, 1 reply; 21+ messages in thread
From: Ray Andrews @ 2016-12-27 18:23 UTC (permalink / raw)
  To: zsh-users

On 27/12/16 08:00 AM, Bart Schaefer wrote:
> On Dec 27, 12:55pm, Daniel Shahaf wrote:
> }
> }     print -rS -- "rap ${(q)@} ; : ${(q)HOST}"
>
> Well, if we're being really pedantic, that's not right either, because
> print -S requires a single string argument, but ${(q)@} in double quotes
> results in multiple strings quoted individually, whereas ${(q)*} results
> in backslashing the spaces between the arguments.
>
> An extra level of nested expansion fixes that, and for readability it'd
> be better to use (q+) on the arguments and (q-) on the host name:
>
>      print -rS -- "rap ${${(q+)@}} ; : ${(q-)HOST}"
>
Jesus! I'm goin' back, to where ah' come from. ;-)

Seriously, I wish I knew if stuff like that really is part of the best 
of all possible worlds or if it is a case of fundamental errors in 
design of the first shells gradually accumulating more and more 
band-aids as time went on until we have exceptions to the exceptions to 
the exceptions and funny little gotchas within funny little gotchas.  
Can't we have "print --Just-Do-It" ?  Anyway I'll take the above on faith.


One thing tho Bart, it seems it should be 'echo' because when the 
command line is recalled and executed, the colon throws an error whereas 
the 'echo' just dumbly prints the host name which is harmless.   Anyway 
I'm intrigued by the idea of sending little messages to history like 
this.  As it is, I just 'echo' messages to myself which are of course 
there in history to remind me what I was doing at the time.  But maybe 
this whole thing is a bit smart-assy.  Thanks gentlemen.



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

* Re: append to history entry?
  2016-12-27 18:23       ` Ray Andrews
@ 2016-12-27 19:09         ` Bart Schaefer
  2016-12-27 23:16           ` Ray Andrews
  0 siblings, 1 reply; 21+ messages in thread
From: Bart Schaefer @ 2016-12-27 19:09 UTC (permalink / raw)
  To: Ray Andrews, zsh-users

On Dec 27, 10:23am, Ray Andrews wrote:
}
} Seriously, I wish I knew if stuff like that really is part of the best 
} of all possible worlds or if it is a case of fundamental errors in 
} design of the first shells

Neither, really.  It's a case of gradually accumulating requirements
on what shells do, rather than any flaw in the original design.  In
the original design you'd have relied on external programs for all
of this stuff.

} Can't we have "print --Just-Do-It" ?

That's what the -r option is, but print doesn't control how its
arguments are processed as part of the command line parse, which is
necessary for what you asked about.

Seriously, you can't ask for a way to muck with something that is
normally handled transparently by the shell internals and then gripe
about having to replicate some of that hidden processing.  Well, you
can, but it doesn't really help. :-)

Daniel is rather dogmatic about handling edge cases that I tend to
ignore for the sake of not throwing out all the details that make you
"take it on faith" (a phrase that makes ME grind my teeth whenever you
write it).

} One thing tho Bart, it seems it should be 'echo' because when the 
} command line is recalled and executed, the colon throws an error

It shouldn't.  There's no difference between "echo" and ":" except
that ":" discards its arguments without printing them.  If you're
getting an error on ":" you've done something else to cause it.

What error?


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

* Re: append to history entry?
  2016-12-27 19:09         ` Bart Schaefer
@ 2016-12-27 23:16           ` Ray Andrews
  2016-12-27 23:55             ` Bart Schaefer
  0 siblings, 1 reply; 21+ messages in thread
From: Ray Andrews @ 2016-12-27 23:16 UTC (permalink / raw)
  To: zsh-users

On 27/12/16 11:09 AM, Bart Schaefer wrote:
> Neither, really.  It's a case of gradually accumulating requirements
> on what shells do, rather than any flaw in the original design.
Well, the flaw is just that the additional stuff wasn't anticipated.  
Mind, foretelling the future
can be difficult.

> Seriously, you can't ask for a way to muck with something that is
> normally handled transparently by the shell internals and then gripe
> about having to replicate some of that hidden processing.  Well, you
> can, but it doesn't really help. :-)
Yeah, the chaffing is just because however useful some of that is in 
most situations,
it would be nice to be able to occasionally have a string be just a 
string be just a string
in a C sort of way.  Plain vanilla a literal.  Like my old gripe about a 
command not being
able to know the literal keystrokes that called it *except* that it's 
perfectly literal in history
*except* that if commands are chained with semicolons one can't just 
grab it back from
history for the obvious reason that any given command doesn't know where 
it is in a string
of chained commands -- one would think that one should be able to 
intercept the string
before all the expansions.  So I hafta do all this 'noglob'.  Most of my 
irritations with zsh
are in trying to *stop* it from doing things on occasion.
>
> Daniel is rather dogmatic about handling edge cases that I tend to
> ignore for the sake of not throwing out all the details that make you
> "take it on faith" (a phrase that makes ME grind my teeth whenever you
> write it).
Well, I trust you guys and until I see the logic, I'm just going to take 
your words for it.
There is so much to know.

>
> } One thing tho Bart, it seems it should be 'echo' because when the
> } command line is recalled and executed, the colon throws an error
>
> It shouldn't.  There's no difference between "echo" and ":" except
> that ":" discards its arguments without printing them.  If you're
> getting an error on ":" you've done something else to cause it.
>
> What error?
>
Ah ... seems there must be a space after the colon:


     print -rS -- "rap ${${(q+)@}}; : ${(q-)HOST}"

... that works fine, and doesn't bother with the echo, so it seems to be 
exactly the sort of
thing I'm looking for as to writing to history.  So much to love, 
frustrations or no.


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

* Re: append to history entry?
  2016-12-27 23:16           ` Ray Andrews
@ 2016-12-27 23:55             ` Bart Schaefer
  2016-12-28  0:57               ` Ray Andrews
       [not found]               ` <f87d7f79-3529-d832-eed5-83d4130ea128__16005.139592062$1482888562$gmane$org@eastlink.ca>
  0 siblings, 2 replies; 21+ messages in thread
From: Bart Schaefer @ 2016-12-27 23:55 UTC (permalink / raw)
  To: Ray Andrews, zsh-users

On Dec 27,  3:16pm, Ray Andrews wrote:
}
} it would be nice to be able to occasionally have a string be just a 
} string be just a string in a C sort of way.

That's what $'...' does, but you can't ask for a C string and for
variable interpolation at the same time.  Well, you can, but it
doesn't really help. ;-)

Maybe this would be easier (in the "should have thought of this before"
category):

    print -s -f '%s' rap "$@" ";" ":" "$HOST"

(Note this doesn't work with -S, which currently is silently ignored if
the -f option is given, but as you already have all the words separated
here there's no reason to re-parse them.)


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

* Re: append to history entry?
  2016-12-27 23:55             ` Bart Schaefer
@ 2016-12-28  0:57               ` Ray Andrews
  2016-12-28  6:04                 ` Bart Schaefer
       [not found]               ` <f87d7f79-3529-d832-eed5-83d4130ea128__16005.139592062$1482888562$gmane$org@eastlink.ca>
  1 sibling, 1 reply; 21+ messages in thread
From: Ray Andrews @ 2016-12-28  0:57 UTC (permalink / raw)
  To: zsh-users

On 27/12/16 03:55 PM, Bart Schaefer wrote:
> That's what $'...' does, but you can't ask for a C string and for
> variable interpolation at the same time.  Well, you can, but it
> doesn't really help. ;-)
Indeed.  Be careful what you ask for ... I am expecting the variables to 
expand.
It's all  this backslash and 'is it one string or several strings' 
stuff.  Dunno ...
is that really different?  It just seems that the expansion of the 
variables is 'visible'
for lack of a better word -- you expect it, it's not a gotcha the way 
the rest is.
For me, the task is to see the 'naturalness' for lack of a better word 
of the way
that zsh does this:

     print -rS -- "rap ${${(q+)@}}; : ${(q-)HOST}"

... it seems that the backslashes need protecting and reprotecting and 
yet more
protecting and each stage of the protection is different from the last.  
Couldn't we just:

     setopt protect-backslashes-thanks
     print -S "rap $@; : $HOST"

... it's not that the backslashes are presumed special, it's that I'd 
say we should only have to
press one button once to literalise them.  Is it impossible that this 
could be simple and intuitive?
No ordinary mortal would know to do what you guys showed me, one must be 
shown and even
Bart and Daniel didn't get it exactly right the first time.  What hope 
do I have?

>
> Maybe this would be easier (in the "should have thought of this before"
> category):
>
>      print -s -f '%s' rap "$@" ";" ":" "$HOST"
>
> (Note this doesn't work with -S, which currently is silently ignored if
> the -f option is given, but as you already have all the words separated
> here there's no reason to re-parse them.)
>
I'll chew on that.


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

* Re: append to history entry?
       [not found]               ` <f87d7f79-3529-d832-eed5-83d4130ea128__16005.139592062$1482888562$gmane$org@eastlink.ca>
@ 2016-12-28  5:28                 ` Daniel Shahaf
  2016-12-28  6:31                   ` Bart Schaefer
  2016-12-28 16:33                   ` Ray Andrews
  0 siblings, 2 replies; 21+ messages in thread
From: Daniel Shahaf @ 2016-12-28  5:28 UTC (permalink / raw)
  To: Ray Andrews; +Cc: zsh-users

Ray Andrews wrote on Tue, Dec 27, 2016 at 16:57:48 -0800:
> On 27/12/16 03:55 PM, Bart Schaefer wrote:
> >That's what $'...' does, but you can't ask for a C string and for
> >variable interpolation at the same time.  Well, you can, but it
> >doesn't really help. ;-)
> Indeed.  Be careful what you ask for ... I am expecting the variables
> to expand.  It's all  this backslash and 'is it one string or several
> strings' stuff.  Dunno ...  is that really different?  It just seems
> that the expansion of the variables is 'visible' for lack of a better
> word -- you expect it, it's not a gotcha the way the rest is.  For me,
> the task is to see the 'naturalness' for lack of a better word of the
> way that zsh does this:
> 
>     print -rS -- "rap ${${(q+)@}}; : ${(q-)HOST}"
> 
> ... it seems that the backslashes need protecting and reprotecting and
> yet more protecting and each stage of the protection is different from
> the last.  Couldn't we just:

Actually, there's just one escaping: instead of using «${foo}»,
use «${(q)foo}» if $foo is a scalar and «${${(q)foo}}» if it is an
array.  The - and + are cosmetic.

>     setopt protect-backslashes-thanks
>     print -S "rap $@; : $HOST"
> 
> ... it's not that the backslashes are presumed special, it's that I'd
> say we should only have to press one button once to literalise them.

Most programming languages don't work this way.

When zsh parses the line «print -S -r -- "rap $@; : $HOST"», it does not
yet know that 'print' denotes the shell builtin and that 'print -S'
re-parses its argument according to shell syntax; and even if it did, it
_still_ wouldn't necessarily be correct for zsh to automatically escape
every variable that's interpolated into the string argument at the end,
because people sometimes use variable interpolations that _must not_ be
${(q)}-escaped.

The selling point of this strategy is that the parsing of string
literals is consistent: the string literal «"rap $@; : $HOST"» always
means the same thing, regardless of what command it is an argument to;
the string literal «"foo $*"» always means '"foo" followed by the
positional arguments joined by spaces without any escaping'.  Then, if
a particular command needs quoting, it is up to the programmer to supply
the appropriate quoting.

The strategy you're describing amounts to a macro expansion language;
such languages are generally a lot more hairy than zsh.

> Is it impossible that this could be simple and intuitive?  No ordinary
> mortal would know to do what you guys showed me, one must be shown and
> even Bart and Daniel didn't get it exactly right the first time.  What
> hope do I have?

I didn't get it right, but Bart was right all along.  Anyway, the rules
are simple:

1) When using the 'print' builtin, always pass '-r --'.

2) When interpolating a variable into a string that will be parsed as
zsh code, escape that variable using ${${(q)}}.

But yes, you have to do (2) yourself.

I hope this helped...

Cheers,

Daniel

> 
> 


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

* Re: append to history entry?
  2016-12-28  0:57               ` Ray Andrews
@ 2016-12-28  6:04                 ` Bart Schaefer
  2016-12-28 17:39                   ` Ray Andrews
  0 siblings, 1 reply; 21+ messages in thread
From: Bart Schaefer @ 2016-12-28  6:04 UTC (permalink / raw)
  To: zsh-users

On Dec 27,  4:57pm, Ray Andrews wrote:
} Subject: Re: append to history entry?
}
} It's all  this backslash and 'is it one string or several strings' 
} stuff.

The "one or several" distinction of course has to do with the way
arguments are processed.  You definitely want to be able to preserve
inside the function whatever argument division was supplied to it
at the call, so you need a way to indicate that; you just have to
be sure you're only making that indication when you mean it.

} ... it seems that the backslashes need protecting and reprotecting and 
} yet more protecting and each stage of the protection is different from
} the last.  

The backslash stuff is borrowed conceptually from C (\t for tab, etc.).
Having that same paradigm applied at multiple levels of processing stems
from the language being interpreted rather than compiled.

} For me, the task is to see the 'naturalness' for lack of a better word 
} of the way that zsh does this:
} 
}      print -rS -- "rap ${${(q+)@}}; : ${(q-)HOST}"

The point is that this isn't "natural," because what you asked for isn't
natural.  Think through what you said you want:

1. Take a command line and parse it.
2. When the parsed arguments are received by the command ...
   a. reconstitute the original command line
   b. append another command that includes the host name
3. Put all of that into the history, formatted such that
   a. it shows what you want when you recall the history, and
   b. it executes again without errors

Which step of that after the first one is "natural" for the shell?

Of course you can fudge any one of those steps.  The host name most
probably doesn't have any special characters, so ${(q-)HOST} is
likely going overboard and all you really need is $HOST; but for the
sake of everyone else who's going to see this and copy-paste, it
may be worth forestopping any future problems.

Similarly you may never have any quoted spaces or backslashes or
anything like that in the arguments of "rap" and therefore ${(q+)@}
might also be unnecessary, but someone might try to use this same
recipe for some other command that does have those things.  I tend
to want those people to make their own mistakes and come back with
more questions; Daniel tries to cover all corner cases up front.

} Couldn't we just:
} 
}      setopt protect-backslashes-thanks
}      print -S "rap $@; : $HOST"

That still wouldn't work because $@ is the way you preserve argument
divisions.  You can't get away from thinking about what you mean.

} Bart and Daniel didn't get it exactly right the first time.  What hope 
} do I have?

Stop worrying about getting it exactly right.  What you had in the
first place was going to work in 90%+ of cases, and when you found
a case that didn't, then someone could have explained why not.


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

* Re: append to history entry?
  2016-12-28  5:28                 ` Daniel Shahaf
@ 2016-12-28  6:31                   ` Bart Schaefer
  2016-12-28 16:33                   ` Ray Andrews
  1 sibling, 0 replies; 21+ messages in thread
From: Bart Schaefer @ 2016-12-28  6:31 UTC (permalink / raw)
  To: zsh-users

On Dec 28,  5:28am, Daniel Shahaf wrote:
}
} Actually, there's just one escaping: instead of using «${foo}»,
} use «${(q)foo}» if $foo is a scalar and $«{${(q)foo}}» if it is an
} array.

Unfortunately that's not quite right: you mean «${${(q)foo[@]}}» or
«${${(@q)foo}}» -- if it's just "an array" then it'll be joined
before (q)-ting.

} I didn't get it right, but Bart was right all along.  Anyway, the rules
} are simple:
} 
} 1) When using the 'print' builtin, always pass '-r --'.

I'd avoid this kind of blanket statement, because it leads to the question,
"if you should ALWAYS do that, why doesn't print just do that without being
told?"

} 2) When interpolating a variable into a string that will be parsed as
} zsh code, escape that variable using ${${(q)}}.

... and put that (@) or [@] in there so the (q) applies to each array
element separately ... unless that's not what you mean.


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

* Re: append to history entry?
  2016-12-28  5:28                 ` Daniel Shahaf
  2016-12-28  6:31                   ` Bart Schaefer
@ 2016-12-28 16:33                   ` Ray Andrews
  1 sibling, 0 replies; 21+ messages in thread
From: Ray Andrews @ 2016-12-28 16:33 UTC (permalink / raw)
  To: zsh-users

On 27/12/16 09:28 PM, Daniel Shahaf wrote:

...
> 2) When interpolating a variable into a string that will be parsed as
> zsh code, escape that variable using ${${(q)}}.
>
> But yes, you have to do (2) yourself.
>
> I hope this helped...
>
> Cheers,
>
> Daniel

Yes, it helps a great deal.  I can't say I get it yet, but I see where 
you are coming from.  Indeed, consistency must trump everything.  " 
${${(q)}} " seems byzantine but if it really is unavoidable -- it could 
not have been made simpler -- then that's the way it is.  I don't care 
about the 'extra' keystrokes, I care that code helps you to do what you 
want to do, instead of fighting against you.  And that it does what you 
might reasonably expect it to do.  Transparency should be a virtue.  
When I see the necessity, I'll stop chafing.  Anyway, I tax everyone's 
patience, so enough of this for now.
>
>>


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

* Re: append to history entry?
  2016-12-28  6:04                 ` Bart Schaefer
@ 2016-12-28 17:39                   ` Ray Andrews
  2016-12-28 18:22                     ` Bart Schaefer
  0 siblings, 1 reply; 21+ messages in thread
From: Ray Andrews @ 2016-12-28 17:39 UTC (permalink / raw)
  To: zsh-users

On 27/12/16 10:04 PM, Bart Schaefer wrote:
> The backslash stuff is borrowed conceptually from C (\t for tab, etc.).
> Having that same paradigm applied at multiple levels of processing stems
> from the language being interpreted rather than compiled.
I think what I'm not really getting is the multiple level thing. When I 
get that, maybe difficulties
will melt away.  Of course the backslash is special, hasta be.

> The point is that this isn't "natural," because what you asked for isn't
> natural.
No?  It seems simple enough and the ' : ' command seems tailor made for it.
>   but for the
> sake of everyone else who's going to see this and copy-paste, it
> may be worth forestopping any future problems.

Of course!  It's the gotchas that drive me crazy.  Un-robust code is 
alpha code.
I guess that's one of these cultural things -- for me the idea that 
something
more or less works most of the time, but never on Thursday, just doesn't 
cut it.
No, I'll never have a backslash in my $HOST but that's irrelevant because
it hasta be proof against that possibility.  I agree with you 
absolutely. $HOST
is an unformated literal string and should be seen that way every time.
>
> You can't get away from thinking about what you mean.

Indeed not.  The difficulty is that what I mean and what zsh thinks I 
mean ain't the same.

I keep lusting after 'history'.  Sheesh, what I want is already there, 
zsh already knows how
to preserve the literal keystrokes that you typed into history, I just 
can't get at it.
If I could just intercept the command as it goes into history -- but 
with each command
knowing what belongs to itself when there are semicolons -- I'd have 
everything I want:

     $ com1 "\'"{(g+)}()\(\t | @$%^>> /dev/the-void < ; com2 "\t"; echo 
"don't try this at home"

... now hit the up arrow and what I get back is exactly what I typed.  
So why can't we have:

    function com1 ()
    {
    echo "Here's exactly what you typed, absolutely unmolested, when you
    invoked this command:\n
    $MY-LITERAL-ARGUMENTS-AS-HISTORY-WILL-RECORD-THEM"
    }

    $ com1 "\'"{(g+)}()\(\t | @$%^>> /dev/the-void <

    Here's exactly what you typed, absolutely unmolested, when you
    invoked this command:
    com1 "\'"{(g+)}()\(\t | @$%^>> /dev/the-void <

    $


Somewhere, in the deepest bowels of the parser, the literal string 
exists just before it is sent to history.  If I could just grab it 
somehow ...

Don't let me bother you too much Bart, we've been over this, and it 
seems it can't be done.  In practical terms what you've shown me works 
perfectly.


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

* Re: append to history entry?
  2016-12-28 17:39                   ` Ray Andrews
@ 2016-12-28 18:22                     ` Bart Schaefer
  2016-12-28 19:20                       ` Ray Andrews
  0 siblings, 1 reply; 21+ messages in thread
From: Bart Schaefer @ 2016-12-28 18:22 UTC (permalink / raw)
  To: Ray Andrews, zsh-users

On Dec 28,  9:39am, Ray Andrews wrote:
} Subject: Re: append to history entry?
}
} On 27/12/16 10:04 PM, Bart Schaefer wrote:
} > You can't get away from thinking about what you mean.
} 
} Indeed not.  The difficulty is that what I mean and what zsh thinks I 
} mean ain't the same.

As it has ever been in pretty much all programming languages.
 
} If I could just intercept the command as it goes into history --
} but with each command knowing what belongs to itself when there are
} semicolons

That's where your confusion is.  History is *NOT* command history.
It's *command line input* history.  History does NOT know what text
belongs to what command, and it's not processed at the same level as
the parser that figures that out.  It's involved with the lexer,
which decides how to break things into tokens but does not decide
what those tokens mean.  History is thus connected more closely to
the line editor than to the command execution engine.

} Somewhere, in the deepest bowels of the parser, the literal string 
} exists just before it is sent to history.

No, that's completely wrong.  The literal string is long gone by the
time you get that far down in the parser.  When your "com1" function
is called, all the expansions and substitutions have long since been
done and the original text discarded; "setopt xtrace" and look at the
output -- THAT is what exists at the point "com1" runs.

In fact by that point the literal command input is *already in* the
history, unless you've stopped it somehow e.g. histignorespace.

Read up on the "trap" command with the DEBUG pseudo-signal, and the
ZSH_DEBUG_CMD variable, which is the closest thing there is to what
you are imagining.

The zshaddhistory hook is where you get at the literal input string.


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

* Re: append to history entry?
  2016-12-28 18:22                     ` Bart Schaefer
@ 2016-12-28 19:20                       ` Ray Andrews
  2016-12-28 21:24                         ` Ray Andrews
       [not found]                         ` <3b8fe027-d7fb-25fb-bc05-9ecd3a91b08f__38422.8622112007$1482960347$gmane$org@eastlink.ca>
  0 siblings, 2 replies; 21+ messages in thread
From: Ray Andrews @ 2016-12-28 19:20 UTC (permalink / raw)
  To: zsh-users

On 28/12/16 10:22 AM, Bart Schaefer wrote:
> what those tokens mean.  History is thus connected more closely to
> the line editor than to the command execution engine.

Whatever, I can't comment on the stage, I only say that at some point the
string  is literal.
>
> Read up on the "trap" command with the DEBUG pseudo-signal, and the
> ZSH_DEBUG_CMD variable, which is the closest thing there is to what
> you are imagining.
>
> The zshaddhistory hook is where you get at the literal input string.
>
Ok, I'll see what I can figure out.


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

* Re: append to history entry?
  2016-12-28 19:20                       ` Ray Andrews
@ 2016-12-28 21:24                         ` Ray Andrews
       [not found]                         ` <3b8fe027-d7fb-25fb-bc05-9ecd3a91b08f__38422.8622112007$1482960347$gmane$org@eastlink.ca>
  1 sibling, 0 replies; 21+ messages in thread
From: Ray Andrews @ 2016-12-28 21:24 UTC (permalink / raw)
  To: zsh-users

On 28/12/16 11:20 AM, Ray Andrews wrote:
> Ok, I'll see what I can figure out.
>
>
Needless to say this is exploratory:


function zshaddhistory ()
{
LITERAL=( "${(@s/;/)1}" )
#print -rl $LITERAL

LITERAL[1]=${LITERAL[1]/ #/}
LITERAL[2]=${LITERAL[2]/ #/}
LITERAL[3]=${LITERAL[3]/ #/}
LITERAL[4]=${LITERAL[4]/ #/}
LITERAL[5]=${LITERAL[5]/ #/}
#print -r $LITERAL[1]
#print -r $LITERAL[2]
#print -r $LITERAL[3]
#print -r $LITERAL[4]
#print -r $LITERAL[5]
}

function test ()
{
     print -r "you typed: $LITERAL[1]"
}


$ test \r * \n""''
you typed: test \r * \n""''

$ test $HOST
you typed: test $HOST



... but it seems to do exactly what I want the only thing lacking is to 
associate each

member of the array to the appropriate command, if there are several on 
the same line.

I can think of a few hacks that might do it, but is there a robust way?  
Would precmd()

be able to keep count?  Something of that nature?  This is going to come 
out right.



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

* Re: append to history entry?
       [not found]                         ` <3b8fe027-d7fb-25fb-bc05-9ecd3a91b08f__38422.8622112007$1482960347$gmane$org@eastlink.ca>
@ 2016-12-28 23:34                           ` Daniel Shahaf
  2016-12-29  0:51                             ` Bart Schaefer
  2016-12-29  3:27                             ` Ray Andrews
  0 siblings, 2 replies; 21+ messages in thread
From: Daniel Shahaf @ 2016-12-28 23:34 UTC (permalink / raw)
  To: Ray Andrews; +Cc: zsh-users

Ray Andrews wrote on Wed, Dec 28, 2016 at 13:24:25 -0800:
> On 28/12/16 11:20 AM, Ray Andrews wrote:
> >Ok, I'll see what I can figure out.
>
> Needless to say this is exploratory:
> 
> 
> function zshaddhistory ()
> {
> LITERAL=( "${(@s/;/)1}" )
⋮:
> ... but it seems to do exactly what I want the only thing lacking is
> to associate each member of the array to the appropriate command, if
> there are several on the same line.  I can think of a few hacks that
> might do it, but is there a robust way?  Would precmd() be able to
> keep count?  Something of that nature?  This is going to come out
> right.

You can easily convert the string "$1" to a token stream, however, there
is no fully robust way to translate that token stream into a list of
commands without reimplementing the parser.

Just consider the following cases (there are more, but you should get
the gist):

    # quoted semicolon
    echo lorem\;ipsum

    # non-top-level semicolon
    (foo; bar); baz
    () { foo; bar } baz
    for 1 in foo bar; baz $1

    # non-semicolon
    foo& bar& 
    case foo in (bar) : ;; esac

    # INTERACTIVE_COMMENTS
    echo foo # bar ;

What are you trying to do now?  This is no longer your original
question about recording the hostname in history.

Is this about 'rap' being called in the middle of a command line…?

Cheers,

Daniel


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

* Re: append to history entry?
  2016-12-28 23:34                           ` Daniel Shahaf
@ 2016-12-29  0:51                             ` Bart Schaefer
  2016-12-29  3:27                             ` Ray Andrews
  1 sibling, 0 replies; 21+ messages in thread
From: Bart Schaefer @ 2016-12-29  0:51 UTC (permalink / raw)
  To: zsh-users

On Dec 28, 11:34pm, Daniel Shahaf wrote:
}
} You can easily convert the string "$1" to a token stream

Which is in fact what ${(z)...} is for.

} however, there
} is no fully robust way to translate that token stream into a list of
} commands without reimplementing the parser.

Compare for example the state machine in zsh-syntax-highlighting's
main-highlighter.zsh ...


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

* Re: append to history entry?
  2016-12-28 23:34                           ` Daniel Shahaf
  2016-12-29  0:51                             ` Bart Schaefer
@ 2016-12-29  3:27                             ` Ray Andrews
  1 sibling, 0 replies; 21+ messages in thread
From: Ray Andrews @ 2016-12-29  3:27 UTC (permalink / raw)
  To: zsh-users

On 28/12/16 03:34 PM, Daniel Shahaf wrote:
>
> Just consider the following cases (there are more, but you should get
> the gist):

Sure, no surprise there, of course only the parser knows one semicolon 
from the next
but as Bart says, the history string is saved way before the parser gets 
to it, so it sounds
like I can have my strings, but not robustly check for separation of 
commands.
> What are you trying to do now?  This is no longer your original
> question about recording the hostname in history.
>
> Is this about 'rap' being called in the middle of a command line…?
It's mostly for my command wrappers.  The thing is to make it possible 
to see the
'real' command being run by the wrapper. I have it mostly satisfactory 
but the
method is belaboured.  For example 'l' wraps 'ls'.  If I do:

     /boot $ l ,R *amd64                 ( 'R' meaning sort and tabulate 
from the right)

in my /boot directory I get:
|
| || |1   4153384  2016-12-17/09:56:35 vmlinuz-4.8.0-2-amd64||
|| 1   3161213  2016-12-17/09:56:35 System.map-4.8.0-2-amd64||
|| 1  17655948  2016-12-27/15:59:03 initrd.img-4.8.0-2-amd64||
|| 1    183632  2016-12-17/09:56:35 config-4.8.0-2-amd64||
||
|but, what did the wrapper do to get that?  It did this:

$ ls -AGFrgt --time-style=+%F/%T --group-directories-first  *amd64 | 
egrep -v '^total'  | rev |  sort -r | column -t | rev  | cut 
--delimiter=' ' --fields=3-

How it works is that I start the function thusly:

alias l='noglob _l'
function _l ()
{
.... process various switches, cobbling together the real command ending 
up with:
_execute $command-string
}
... and '_execute' essentially does this:
|
||_execute ()||
||{ ||
||||print -rS "$*"||
||    echo "\nEXECUTING: ${@//'\'/\\\\}\n"||( more protecting 
backslashes :( )
||    eval "$@"||
||}||
|
... 'eval' of course expands and executes BUT the command has been 
pushed to history without glob expansion (which would obviously be 
impractical in many situations) so that I can recall the 'real' command 
as I choose.

That's useful for debugging the wrapper -- if the wrapper screws up, I 
just recall the real command and find out where the issue is. Also, I 
might want to modify the real command in some way and re-execute it 
since the wrappers themselves only handle routine usage.  As it is now, 
variables are expanded which is no huge problem but if there was some 
way of grabbing the arguments to the command unexpanded I could just 
chew on those so that the command pushed to history was totally 
unexpanded  as tho I had typed the real command in by hand.  And of 
course 'eval' would take care of everything as far as execution anyway.  
The only time it gets unworkable is if some variable contains something 
huge, but 99% of the time, what I have now is functional, but on 
principal I'd still like to be able to have my entire command string 
unaltered , push the constructed real command to history with wildcards 
and variables as typed, and just have 'eval' expand everything as 
needed.  I know it's sorta the opposite of what zsh is for, but having 
the real command available for recall can be hugely useful.

Here's another example:

/boot $ f ,Hd zsh* /

EXECUTING: find -H -O3  / -warn -xdev -iname "zsh*" -type d | grep -i 
--color=always zsh

/etc/zsh-virgin
/usr/share/zsh

... up arrow brings the real command right back in case I want  to play 
with it some how or just see what the wrapper actually did.


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

end of thread, other threads:[~2016-12-29  3:27 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-12-26 23:16 append to history entry? Ray Andrews
2016-12-27  1:28 ` Ray Andrews
2016-12-27  4:47   ` Bart Schaefer
     [not found] ` <5288b537-f06a-d18a-60ea-1f962856c80c__41345.3811700039$1482803962$gmane$org@eastlink.ca>
2016-12-27 12:55   ` Daniel Shahaf
2016-12-27 16:00     ` Bart Schaefer
2016-12-27 18:23       ` Ray Andrews
2016-12-27 19:09         ` Bart Schaefer
2016-12-27 23:16           ` Ray Andrews
2016-12-27 23:55             ` Bart Schaefer
2016-12-28  0:57               ` Ray Andrews
2016-12-28  6:04                 ` Bart Schaefer
2016-12-28 17:39                   ` Ray Andrews
2016-12-28 18:22                     ` Bart Schaefer
2016-12-28 19:20                       ` Ray Andrews
2016-12-28 21:24                         ` Ray Andrews
     [not found]                         ` <3b8fe027-d7fb-25fb-bc05-9ecd3a91b08f__38422.8622112007$1482960347$gmane$org@eastlink.ca>
2016-12-28 23:34                           ` Daniel Shahaf
2016-12-29  0:51                             ` Bart Schaefer
2016-12-29  3:27                             ` Ray Andrews
     [not found]               ` <f87d7f79-3529-d832-eed5-83d4130ea128__16005.139592062$1482888562$gmane$org@eastlink.ca>
2016-12-28  5:28                 ` Daniel Shahaf
2016-12-28  6:31                   ` Bart Schaefer
2016-12-28 16:33                   ` Ray Andrews

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