From 7430617d3d84dc111e1a28f4f3884bf827d4fec9 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Fri, 19 May 2017 11:51:16 +0300 Subject: [PATCH] Support remote editing in emacsclient via Tramp * lib-src/emacsclient.c (main, decode_options) (print_help_and_exit, longopts): New option '--tramp' / '-T' which specifies how emacs should use tramp to find remote files. * doc/emacs/misc.texi (TCP Emacs server): New subsection describing the various knobs to tune server.el for TCP opereation. (emacsclient Options): Reference "TCP Emacs server" from description of --server-file. Document the new '--tramp' / '-T' options. * doc/emacs/emacs.texi (Top): Update the top-level menu. * etc/NEWS: Mention the new option. --- doc/emacs/emacs.texi | 1 + doc/emacs/misc.texi | 120 +++++++++++++++++++++++++++++++++++------- etc/NEWS | 8 +++ lib-src/emacsclient.c | 20 ++++++- 4 files changed, 128 insertions(+), 21 deletions(-) diff --git a/doc/emacs/emacs.texi b/doc/emacs/emacs.texi index 5c8977c6b09..a3eb4225a75 100644 --- a/doc/emacs/emacs.texi +++ b/doc/emacs/emacs.texi @@ -1082,6 +1082,7 @@ Shell Command History Using Emacs as a Server +* TCP Emacs server:: Listening to a TCP socket. * Invoking emacsclient:: Connecting to the Emacs server. * emacsclient Options:: Emacs client startup options. diff --git a/doc/emacs/misc.texi b/doc/emacs/misc.texi index bcc20a6db16..84681f2269a 100644 --- a/doc/emacs/misc.texi +++ b/doc/emacs/misc.texi @@ -1661,10 +1661,68 @@ expression @code{(+ 1 2)} on the @samp{foo} server, and returns signaled.) Currently, this feature is mainly useful for developers. @menu +* TCP Emacs server:: Listening to a TCP socket. * Invoking emacsclient:: Connecting to the Emacs server. * emacsclient Options:: Emacs client startup options. @end menu +@node TCP Emacs server +@subsection TCP Emacs server +@cindex TCP Emacs server + +@vindex server-use-tcp + An Emacs server usually listens to connections on a local Unix +domain socket. Some operating systems, such as MS-Windows, do not +support local sockets; in that case, the server uses TCP sockets +instead. In some cases it is useful to have the server listen on a +TCP socket even if local sockets are supported, e.g., if you need to +contact the Emacs server from a remote machine. You can set +@code{server-use-tcp} to non-@code{nil} to have Emacs listen on a TCP +socket instead of a local socket. This is the default if your OS does +not support local sockets. + +@vindex server-host +@vindex server-port + If the Emacs server is set to use TCP, it will by default listen to +a random port on the localhost interface. This can be changed to +another interface and/or a fixed port using the variables +@code{server-host} and @code{server-port}. + +@vindex server-auth-key + A TCP socket is not subject to file system permissions. To retain +some control over which users can talk to an Emacs server over TCP +sockets, the @command{emacsclient} program must send an authorization +key to the server. This key is normally randomly generated by the +Emacs server. This is the recommended mode of operation. + +@findex server-generate-key + If needed, you can set the authorization key to a static value by +setting the @code{server-auth-key} variable. The key must consist of +64 ASCII printable characters except for space (this means characters +from @samp{!} to @samp{~}, or from decimal code 33 to 126). You can +use @kbd{M-x server-generate-key} to get a random key. + +@vindex server-auth-dir +@cindex server file + When you start a TCP Emacs server, Emacs creates a @dfn{server file} +containing the TCP information to be used by @command{emacsclient} to +connect to the server. The variable @code{server-auth-dir} specifies +the directory containing the server file; by default, this is +@file{~/.emacs.d/server/}. In the absence of a local socket with file +permissions, the permissions of this directory determine which users +can have their @command{emacsclient} processes talk to the Emacs +server. + +@vindex EMACS_SERVER_FILE@r{, environment variable} + To tell @command{emacsclient} to connect to the server over TCP with +a specific server file, use the @samp{-f} or @samp{--server-file} +option, or set the @env{EMACS_SERVER_FILE} environment variable +(@pxref{emacsclient Options}). If @code{server-auth-dir} is set to a +non-standard value, @command{emacsclient} needs an absolute file name +to the server file, as the default @code{server-auth-dir} is +hard-coded in @command{emacsclient} to be used as the directory for +resolving relative filenames. + @node Invoking emacsclient @subsection Invoking @code{emacsclient} @cindex @code{emacsclient} invocation @@ -1810,25 +1868,18 @@ evaluate, @emph{not} as a list of files to visit. @item -f @var{server-file} @itemx --server-file=@var{server-file} -@cindex @env{EMACS_SERVER_FILE} environment variable -Specify a @dfn{server file} for connecting to an Emacs server via TCP. - -An Emacs server usually uses a -local socket to listen for connections. Some operating systems, -such as Microsoft Windows, do not support local sockets; in that case, -the server communicates with @command{emacsclient} via TCP. - -@vindex server-auth-dir -@cindex server file -@vindex server-port -When you start a TCP Emacs server, Emacs creates a @dfn{server file} -containing the TCP information to be used by @command{emacsclient} to -connect to the server. The variable @code{server-auth-dir} specifies -the directory containing the server file; by default, this is -@file{~/.emacs.d/server/}. To tell @command{emacsclient} to connect -to the server over TCP with a specific server file, use the @samp{-f} -or @samp{--server-file} option, or set the @env{EMACS_SERVER_FILE} -environment variable. +Specify a server file (@pxref{TCP Emacs server}) for connecting to an +Emacs server via TCP. Alternatively, you can set the +@env{EMACS_SERVER_FILE} environment variable to point to the server +file. + +An Emacs server usually uses a local socket to listen for connections, +but also supports connections over TCP. To connect to a TCP Emacs +server, @command{emacsclient} needs to read a @dfn{server file} +containing the connection details of the Emacs server. The name of +this file is specified with this option, either as a file name +relative to @file{~/.emacs.d/server} or as an absolute file name. +@xref{TCP Emacs server}. @item -n @itemx --no-wait @@ -1872,6 +1923,37 @@ On MS-Windows, @samp{-t} behaves just like @samp{-c} if the Emacs server is using the graphical display, but if the Emacs server is running on a text terminal, it creates a new frame in the current text terminal. + +@item -T @var{tramp-prefix} +@itemx --tramp-prefix=@var{tramp-prefix} +Set the prefix to add to filenames for Emacs to locate files on remote +machines using TRAMP (@pxref{Top, The Tramp Manual,, tramp, The Tramp +Manual}). This is mostly useful in combination with using the Emacs +server over TCP (@pxref{TCP Emacs server}). By ssh-forwarding the +listening port and making the @var{server-file} available on a remote +machine, programs on the remote machine can use @command{emacsclient} +as the value for the @env{EDITOR} and similar environment variables, +but instead of talking to an Emacs server on the remote machine, the +files will be visited in the local Emacs session using TRAMP. + +@vindex EMACSCLIENT_TRAMP@r{, environment variable} +Setting the environment variable @env{EMACSCLIENT_TRAMP} has the same +effect as using the @samp{-T} option. If both are specified, the +command-line option takes precedence. + +For example, assume two hosts, @samp{local} and @samp{remote}, and +that the local Emacs listens on tcp port 12345. Assume further that +@file{/home} is on a shared file system, so that the server file +@file{~/.emacs.d/server/server} is readable on both hosts. + +@example +local$ ssh -R12345:localhost:12345 remote +remote$ export EDITOR="emacsclient \ + --server-file=server \ + --tramp=/ssh:remote:" +remote$ $EDITOR /tmp/foo.txt #Should open in local emacs. +@end example + @end table The new graphical or text terminal frames created by the @samp{-c} diff --git a/etc/NEWS b/etc/NEWS index 4121c44b0c2..340718ecbc4 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -344,6 +344,14 @@ for DNS-querying functions 'nslookup-host', 'dns-lookup-host', and 'run-dig'. Each function now accepts an optional name server argument interactively (with a prefix argument) and non-interactively. ++++ +** Emacsclient has a new option -T/--tramp. +This helps with using a local Emacs session as the server for a remote +emacsclient. With appropriate setup, one can now set the EDITOR +environment variable on a remote machine to emacsclient, and +use the local Emacs to edit remote files via Tramp. See the node +"emacsclient Options" in the user manual for the details. + * Editing Changes in Emacs 26.1 diff --git a/lib-src/emacsclient.c b/lib-src/emacsclient.c index 7b735dfb05d..c21ee6bd395 100644 --- a/lib-src/emacsclient.c +++ b/lib-src/emacsclient.c @@ -149,6 +149,9 @@ const char *socket_name = NULL; /* If non-NULL, the filename of the authentication file. */ const char *server_file = NULL; +/* If non-NULL, the tramp prefix emacs must use to find the files. */ +const char *tramp_prefix = NULL; + /* PID of the Emacs server process. */ int emacs_pid = 0; @@ -178,6 +181,7 @@ struct option longopts[] = { "server-file", required_argument, NULL, 'f' }, { "display", required_argument, NULL, 'd' }, { "parent-id", required_argument, NULL, 'p' }, + { "tramp", required_argument, NULL, 'T' }, { 0, 0, 0, 0 } }; @@ -468,14 +472,15 @@ static void decode_options (int argc, char **argv) { alternate_editor = egetenv ("ALTERNATE_EDITOR"); + tramp_prefix = egetenv ("EMACSCLIENT_TRAMP"); while (1) { int opt = getopt_long_only (argc, argv, #ifndef NO_SOCKETS_IN_FILE_SYSTEM - "VHnequa:s:f:d:F:tc", + "VHnequa:s:f:d:F:tcT:", #else - "VHnequa:f:d:F:tc", + "VHnequa:f:d:F:tcT:", #endif longopts, 0); @@ -554,6 +559,10 @@ decode_options (int argc, char **argv) frame_parameters = optarg; break; + case 'T': + tramp_prefix = optarg; + break; + default: message (true, "Try '%s --help' for more information\n", progname); exit (EXIT_FAILURE); @@ -654,6 +663,9 @@ The following OPTIONS are accepted:\n\ Editor to fallback to if the server is not running\n" " If EDITOR is the empty string, start Emacs in daemon\n\ mode and try connecting again\n" +"-T PREFIX, --tramp=PREFIX\n\ + PREFIX to prepend to filenames sent by emacsclient\n\ + for locating files remotely via Tramp\n" "\n\ Report bugs with M-x report-emacs-bug.\n"); exit (EXIT_SUCCESS); @@ -1687,6 +1699,8 @@ main (int argc, char **argv) } } send_to_emacs (emacs_socket, "-dir "); + if (tramp_prefix) + quote_argument (emacs_socket, tramp_prefix); quote_argument (emacs_socket, cwd); send_to_emacs (emacs_socket, "/"); send_to_emacs (emacs_socket, " "); @@ -1791,6 +1805,8 @@ main (int argc, char **argv) #endif send_to_emacs (emacs_socket, "-file "); + if (tramp_prefix && file_name_absolute_p (argv[i])) + quote_argument (emacs_socket, tramp_prefix); quote_argument (emacs_socket, argv[i]); send_to_emacs (emacs_socket, " "); } -- 2.39.2