Painless Emacs remote shells
source link: https://www.eigenbahn.com/2020/07/08/painless-emacs-remote-shells
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Painless Emacs remote shells
July 8, 2020This post is part of a series about shells in Emacs:
Remote interactive shells
In a previous post we dealt with spawning interactive shells.
In it, we defined a new function friendly-shell
, an objectively clearer version of shell
.
It can be used to easilly define commands for spawning local and remote shells with an arbitrary shell interpreter.
But it can be quite cumbersome to have to define a command for each and every remote connection.
Ideally we’d want a command that prompts for a remote path and spawn a shell there.
Prompting for a remote path
The remote path format understood by Emacs looks like this:
/<method>:[<user>[%<domain>]@]<host>[%<port>][:<localname>]
The /<method>:
prefix is mandatory, required for Emacs to detect that the path is remote.
<method>
can have a default value (configured with tramp-default-method
and tramp-default-method-alist
) but the user still need to type in the prefix /-:
to use it.
In the context of a command explicitely prompting for a remote path, it’s quite cumbersome for the user to have to type in this /<method>:
prefix.
We want a light wrapper that also supports this more permissive format:
[<user>[%<domain>]@]<host>[%<port>][:<localname>]
That wrapper is function friendly-tramp-path-dissect
provided by package friendly-tramp-path.
Default remote interpreter configuration
Introduced in Emacs 26.2, connection-local vars allow to have a per host interpreter configuration.
Package friendly-shell comes with its own, more versatile, implementation of connection-local vars.
Both options are explained in details in post: Emacs shell interpreter configuration.
Putting it all together
(require 'friendly-tramp-path)
(require 'with-shell-interpreter)
(require 'prf-shell)
(cl-defun friendly-remote-shell (&key path
interpreter interpreter-args
command-switch
w32-arg-quote)
(interactive)
(let* ((path (or path (read-string "Host: ")))
(path (with-shell-interpreter--normalize-path path))
(vec (friendly-tramp-path-dissect path))
(path (tramp-make-tramp-file-name (tramp-file-name-method vec)
(tramp-file-name-user vec) (tramp-file-name-domain vec)
(tramp-file-name-host vec) (tramp-file-name-port vec)
(tramp-file-name-localname vec))))
(friendly-shell :path path
:interpreter interpreter
:interpreter-args interpreter-args
:command-switch command-switch
:w32-arg-quote w32-arg-quote)))
And voilà! Now to connect to a remote server we just has to type:
M-x friendly-remote-shell <RET>
pi@raspberry <RET>
The code for friendly-remote-shell
can be found in package friendly-remote-shell.
Tagged #emacs.
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK