Subject: bug#70792: 30.0.50; [PATCH] Add Eshell support for expanding absolute file names within the current remote connection

From: Eli Zaretskii <[email-masked]>
Date: Tue, 07 May 2024 14:55:05 +0300

> Date: Mon, 6 May 2024 13:05:28 -0700
> Cc: [email-masked]
> From: Jim Porter <[email-masked]>
> 
> Currently, for Lisp-based commands, you have to type the the full remote 
> part of the file name again, like "/ssh:user@remote:/some/file". For 
> external commands, you have to type just the local part, like 
> "/some/file". For commands that could be *either* Lisp-based or external 
> (this includes most Eshell built-ins), there's no way to do this. 
> (Unless you know exactly how Eshell implements things.)

I think asking the user to specify the full "/ssh:..." file name for
remote files makes this easier, because Eshell could then
transparently handle also the commands which can be external or
internal.  That's one confusing problem down.

> > So you are saying that to chdir to the _local_ /etc I must quote it as
> > in "/:/etc", or somesuch?  If not, how do I chdir to a local directory
> > by its absolute file name?
> 
> If your current working directory is local, "cd /etc" is enough (since 
> the current host is the local one). If your current working directory is 
> remote, any of the following would change back to the local /etc:
> 
>    cd /:/etc
>    cd \/etc
>    cd "/etc"
>    cd '/etc'

The first form I could maybe agree to.  But the others are standard
shell quoting, so I think repurposing them for "escape to local file
names" is not a good idea, since quoting is used in shell commands for
other reasons, notably for quoting special characters.  We need to
allow user to quote file names without implying the name is local.

So I think the last 3 examples should not mean local file names.

> >>     ##### 5. Change to the *local* home directory, stop being root
> >> /sudo:root@host:~ # cd /:~; pwd; *pwd
> >> /home/jim
> >> /home/jim
> > 
> > That's awful!  Completely un-natural, let alone a lot of typing!
> 
> It's only two extra characters

Two extra characters _per_file_name_!

> > The simplest solution is to introduce a special command for that, so
> > that the user could tell Eshell explicitly whether he/she wants to
> > consider him/herself on the local or the remote host.  Similar to what
> > we did with rlogin or ssh.
> 
> Eshell users already have a command for explicitly moving between local 
> and remote hosts: it's just "cd".

Then why do we need to change anything at all?

My suggestion is to introduce a notion of "state", either local or
remote, and make it so that the "state" defines the semantics of file
names without the Tramp "/METHOD:..." prefix: such names _always_ mean
files on the host specified by the "state".  In particular, quoted
file names also specify files according to the "state"; they do not
"escape" to the other host.

This matches what you get from a normal shell: if you login to a
remote host, _all_ the file names are from the remote host.

It is okay to use the value of default-directory as the "state", but
we should use it consistently.  the only way of "escaping" from the
current host is by using fully-qualified file names that specify the
host explicitly.

The advantage of this is twofold: (a) users will always know what do
file names refer to, and (b) Eshell will always know that, and will be
able to DTRT in all such cases by converting the file names the user
typed to the appropriate form under the hood as needed.

> I'm not familiar with what we do about rlogin and ssh though. Where 
> would I find that info? If someone else has come up with a better way to 
> handle a similar scenario, I'd be happy to take a look.

See above.  The advantage of those is that they never allow you to mix
file names on different hosts except explicitly.

> > If Eshel knew that I consider myself on the remote, it could have
> > modified the logic accordingly, to DTRT.  Without such an explicit
> > knowledge, we are _guessing_, and our guesses are bound to be wrong
> > sometimes.
> 
> Unless I'm misunderstanding what you mean here, Eshell *does* know that 
> you consider yourself on the remote.

Then why is external vs internal commands an issue? why cannot Eshell
DTRT by invoking the command which can handle the file names the user
typed?

> Without using this option, I don't think there's a way to DTRT in 
> general.

My point is that we should try to find such a way.  Personally, I
don't think it's a problem to find it.

> Currently, the string "/foo/bar" is just that, a string. It 
> carries no information about the host Emacs should look on.

The "state" should supply the missing information, and the
"/METHOD:..." notation should allow the user to override what the
"state" says implicitly.

> Existing commands (whether Lisp-based or external) will just look on
> the host where the process is running.

Some kind of dispatch should look at the "state" before it runs the
command, and decide which variety of the command to run.