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

"Pull just the text of a single command" (was Re: .zsh_history)

On Sat, Apr 15, 2023 at 8:30 AM Ray Andrews <rayandrews@xxxxxxxxxxx> wrote:
> I'm 100% certain you can do that, but not with history expansion, you'll
> > need to use zle for that.
> I'd sure like to know how!  Back in the day nobody seemed to know how to
> do it, not even Bart.

I'm not sure which past discussion you're referencing, but it's
possible you're mixing your metaphors here.

"History expansion" is what happens when you use !! or !-2 or similar
references at the prompt.  That happens before pretty much anything
else as soon as you hit enter (or even sooner if you have setopt
magic-space or similar).  In this case you can use !# to refer
backwards to any words already entered:

% echo first !#:1 last !#:3
first first last last
% echo everything so far !# and more
everything so far echo everything so far and more

References to the stored history with "fc" and related commands like
"history" accesses events (don't think in terms of "lines" -- a
multi-line command like if/while/for is usually one event) that have
previously been executed.  This doesn't have access to the event
currently being executed, and those events are stored with history
expansions (like !# in the foregoing, etc.) already replaced.

ZLE has access to what you're entering as you are entering it and
before either of the above things (or any other expansions like
globbing etc.) happen.  So if you want the unaltered text as you work
with it, ZLE is where you get it.  The best place to grab it after
hitting enter is probably in the zle-line-finish hook, but that won't
always give you full multi-line events (e.g., when the PS2 prompt is
active, you get it a line at a time).

Finally, the preexec function (and hook) gives access to the full
event with only history expansions already done (in $1), before it is
entered into the "fc"-able history, along with the event with all the
other expansions done (in $3).  There's nowhere other than ZLE that
can give you the raw ! references, and preexec can't give you $1 in a
shell script where history isn't available at all.

What you can't do is defer expansions (other than globbing, via
noglob) until "inside" the execution of the command (e.g., your shell
function).  I have a vague recollection that this may relate to you
being accustomed to DOS/Windows where expansion of the arguments is
done by calling a library after the fact, as opposed to the shell
doing all of it first.

Anyway, everything you asked about is there, you just need to adjust
your thinking about the sequence of events to find the right place to
accomplish what you want.

Of course this has NOTHING to do with how SAVING the history is configured.

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