Attach an emacsclient to a specified running emacs server - emacs

Multiple named emacs servers might be invoked by the the commands
{
emacs --daemon="test1"
emacs --daemon="test2"
emacs --daemon='test3"
} &> /dev/null
As there are three emacs server running on background,
How could attach an emacsclient to a specified one , saying "test2"?

From https://www.gnu.org/software/emacs/manual/html_node/emacs/Emacs-Server.html:
The emacsclient program can specify a server by name, using the ‘-s’
or the ‘-f’ option (see emacsclient Options), depending on whether or
not the server uses a TCP socket (see TCP Emacs server).

Related

Run Emacs as a daemon and then the emacs binary

On a Mac OS, I am able to run Emacs as a daemon and then the emacs binary. But, according to "Mastering Emacs" of Mickey Peterson (see the quote below), I should not be able to do that. Where do I misunderstand the book?
emacs --daemon will run Emacs as a daemon. It will call server-start,
as above, but will return control to your terminal immediately and run in the background, waiting for client
requests.
If you go the server route, you cannot use the default emacs binary
any more.
On a Mac Os, I launch Emacs with "/Applications/Emacs.app/Contents/MacOS/Emacs" from the command line.
The quote is misleading. After you have started a server you can happily run either emacs or emacsclient as you wish. The latter will connect to your server; the former will (as usual) start a new separate instance of Emacs.

remote emacs client connects, but doesn't create new frame in terminal

I configured and started an emacs server in TCP mode:
Added (setq server-host "10.16.184.33") and (setq server-use-tcp t) to .emacs
ran emacs --daemon
On the same host, running emacsclient -t brings up an emacs frame in the current terminal, and running emacsclient -c brings up a new graphical client frame, as expected.
On a different host, running emacsclient -t -f ~/.emacs.d/server/server appears to successfully connect to the remote emacs server, but no frame is created in the terminal:
$ emacsclient -t -f ~/.emacs.d/server/server
emacsclient: connected to remote socket at 10.16.184.33
At this point, emacsclient is running in the foreground, and a Ctrl-c stops it with a SIGTERM.
the value of the server-client variable shows that remote emacs client is connected:
server-clients's value is
(#<process server <10.16.184.33:52710>> #<process server <10.16.177.8:59460>>)
Things that I've checked:
versions of Emacs and emacsclient: all 24.3
when swapping which machines are the server and the remote client, the same problem occurs, except...
emacsclient prints an extra error message
emacsclient: connected to remote socket at 10.16.177.8
*ERROR*: Could not open file: /dev/pts/26
Any ideas of what else to check or configure?
There is nothing you could “check or configure”. You simply cannot use emacsclient remotely, because both processes share the frame, which does not work remotely for obvious reasons.
If a client connects to an Emacs server, it does not actually create the frame itself. Rather, it merely tells the server what kind of frame to create, i.e. whether a GUI frame or a terminal frame. The server then creates the frame based on the client's request and parameters.
Specifically, in case of a TTY client (i.e. emacsclient -t) the server attempts to create a frame on the client's TTY. Obviously this won't work if the server runs on a different system. TTYs are local and not remotely accessible.
FYI, the “TCP mode” of the Emacs server was never intended for remote access. It is simply a workaround for systems which do not support local Unix sockets, that is, Windows.
You don't even want to try and make it work, because it's horribly insecure. Being intended as local protocol, Emacs server does neither support traffic encryption nor authentication. By running a remotely accessible Emacs server, you allow any other system to execute arbitrary Emacs Lisp on your machine.
The right way to use Emacs remotely is SSH. Setup an SSH server on the remote system, then connect to the system via SSH and start emacsclient -t in the remote shell.

Detaching and Re-attaching to Emacs server

I am already using Emacs server for some of the problems described in the documentation, For example, I have (server-start) in my .emacs init file, and I have set the EDITOR env. variable to emacsclient so that git and other programs don't open a new instance of Emacs when they need me to type text or log message. This is working great so far.
I am now wondering if I can use Emacs server for something else: I often launch Emacs remotely through an ssh -X session. Sometimes I need to close the ssh session (e.g. I need to reboot my local computer) and re-connect. It would be great if instead of fully closing Emacs for this, I could detach from Emacs, and reattach later.
Is this possible with Emacs server? I believe from things I have read online that the answer is yes, but:
My question:
How can I safely detach from an Emacs server and reattach later?
If you directly start Emacs from within the SSH session, you cannot gracefully detach, because the Emacs process becomes part of the process group created by the remote shell, and if the shell exists it will terminate all processes in its process groups.
However, you can start Emacs in Daemon mode first, with emacs --daemon. Emacs will load the configuration, start an edit server (even without an explicit (server-start) in your configuration), and detach from the terminal. This Emacs daemon will stay alive across different SSH session.
Subsequently, only use emacsclient to connect to the running daemon.
emacs --daemon or (server-start) in .emacs.
Next use emacsclient file, emacsclient -n file or emacsclient -c for just an attaching.
To leave attach as usual C-x C-c.

Tramp mode in emacs using ssh config

I think this is very basic question in using tramp, but it doesn't work for me.
I have my ~/.ssh/config file that points to my amazon ec2 machine
Host amazon
Hostname xxxx.amazonaws.com
Port yyy
User me
IdentityFile ~/.ssh/ubuntu
ForwardAgent yes
I can easily do ssh amazon from my terminal and I go to amazon ec2 (so my config is right), but in emacs
I do:
C-x C-f /ssh1:amazon:
I always get this error
In Aquamacs:
Process *tramp/ssh1 amz* exited abnormally with code 255
In Emacs:
tramp: Opening connection at amz using ssh1...
tramp: Waiting for prompts from remote shell
tramp: Waiting 60s for prompt from remote shell
tramp-process-actions: Login failed
I also have other ssh configurations that they ssh to my virtual boxes on my local machine and they have the same problem.
I really appreciate any help.
One thing that's worth trying is using the sshx connection method. That makes tramp try to avoid any non-standard shell configuration on the remote host.
Like this:
C-x C-f /sshx:amazon:
The tramp method ssh1 forces ssh to be run in ssh v1 protocol mode with the parameter -1. ssh v1 has known weaknesses and is insecure. Hence a lot of sites disable the ssh v1 protocol.
You can verify this from the shell with ssh -1 me#xxxx.amazonaws.com.
Try other tramp connection methods like ssh, sftp or scpx. You can see all pre-configured connection methods with C-h v tramp-methods.
If Moritz Bunkus's answer doesn't solve the issue, then you can configure the verbosity of tramp's output with
M-x customize-variable RET tramp-verbose RET
In particular, level 6 is "sent and received strings" which might help you to determine whether the "Waiting for prompts from remote shell" is because it isn't receiving a prompt pattern that it recognises, or because of some more critical failure.
If it's simply receiving a prompt it doesn't recognise, then you might look at customizing the tramp-login-prompt-regexp or tramp-shell-prompt-pattern variables.
(Of course if your ssh agent is working correctly, then login prompts shouldn't be relevant.)
If you're running Emacs in Windows, then also see these Q&As:
Emacs: Tramp doesn't work
Using tramp with EmacsW32 and cygwin, possible?

Can Emacs server edit remote files specified by Emacs client?

I'm looking to set up an emacs server such that the files specified by emacsclients
are relative to the emacsclients' filesystem and not the server's filesystem. For instance, if I set up an
emacs server on a machine "darkstar" and I connect to this server through an emacsclient
on "brightstar" with the command
emacsclient -nw '~/fantastic'
The emacs server will attempt to edit the file ~/fantastic on darkstar and not on
brightstar. Id like the reverse of this. I'm open to all sorts of zany suggestions.
*Background note:
I want an emacs process that tracks all the buffers I open on various
machines, keeps track of my color settings, bindings, etc. I want all of this
available and replicated on any arbitrary machine with emacs. The emacs server
seems to do just this but without the ability to edit client's local files!
You should be able to set to set up a shell function which uses tramp, like
edit-local() {
emacsclient -e "(find-file (expand-file-name \"$1\" \"/ssh:$USER#$(hostname):$PWD\"))"
}
Of course you may have to change the tramp protocol to whatever you have setup.
Does the remote machine (the one running Emacs) have mounted the filesystem of the local machine? If so, you could issue something like:
emacsclient --eval ´(my-open-file "~/fantastic" "my-local-machine")´
You could then write the function my-open-file that could, for example, open the file //mounts/my-local-machine/home/YOUR-ACCOUNT/fantastic (assuming this is the mount point).
It will require some elisp-hacking and some script hacking (using, for example, Ruby) to build up the emacsclient command-line.