Subject: bug#46351: 28.0.50; Add convenient way to bypass Eshell's own pipelining

From: Michael Albinus <[email-masked]>
Date: Mon, 27 Dec 2021 15:42:37 +0100

Sean Whitton <[email-masked]> writes:

> Hello Michael,

Hi Sean,

>> Thinking more about, perhaps we could solve it a little bit
>> differently. Eshell knows how to invoke external commands explicitly, by
>> prefixing the command with a star like '*ls'. What if we do it the same
>> with pipes? That means, '*|' would mean to call an external pipe. So my
>> command above would be 'cat .emacs *| grep a'. And an external pipe
>> shall convert all other commands in that line into external commands as
>> well, like '*cat .emacs *| *grep a'.
>>
>> By this you wouldn't need your restore-unexpanded-input patch any more, yes?
>
> This is an intriguing suggestion.  It would need to be implemented in
> `eshell-parse-pipeline, rather than `eshell-expand-input-functions',
> because parsing is required to determine which *| are unquoted, etc.  We
> also require *> and *< redirections, also in `eshell-parse-pipeline'.
>
> So, I guess when A *| B is parsed, it would be rewritten to a single
> call to `shell-file-name' in the way that `eshell-shell-command' does.
> I am not sure how feasible it will be to implement that within the
> existing structure of `eshell-parse-pipeline', but I can give it a try.

Perhaps. I'm not so familar with the eshell code, so I cannot give you
much recommendation on implementation details.

> I have one unresolved design question.  A disadvantage of your proposal
> compared to mine is that it is much more laborious to convert an
> existing pipeline to use the external shell: you have to replace each |
> with *| and > with *>, etc., instead of just putting || at the
> beginning.

Yep, but this isn't relevant for the user. This replacement shall happen
by eshell itself, in the background. And it isn't necessary to show this
replacement by the commands in the history.

> I think it's important that it is easy to switch this feature on and
> off, because it is often only after you start figuring out a pipeline
> that you realise you ought to bypass Eshell's pipelining.

As I said: switching on this feature just needs the asterisk to *|.

> One option would be to add an entry to `eshell-expand-input-functions'
> which converts all | to *| and > to *> when the input begins with ||.
> But that is too simple, because you need to parse the input to know
> which | to replace ... any ideas?  I don't think it can be done inside
> `eshell-parse-command'.

Again, I don't see the need for the heading ||. When there is a *| in
the command line, DTRT.

Best regards, Michael.