How to use make-frame-on-display and multi-tty in Emacs? - emacs

This page from the Emacs manual describes a function called make-frame-on-display that allows you to access a remote Emacs session. My interest in this function is to use it to share buffers for pair programming remotely with a colleague.
From the page:
It is even possible to use this feature to let two or more users type simultaneously on the two displays, within the same Emacs job. In practice, however, the different users can easily interfere with each others' edits if they are not careful.
How exactly do I set this up? What do I need? What does my partner need? The details are not stated, but I don't know enough about Emacs to know where to start.
Is there any other way to get a shared Emacs session? This page from the Emacs Wiki refers to something called multi-tty. The questions I asked above also apply to this.
Which is better: multi-tty or make-frame-on-display?

I haven't tried multi-tty, but make-frame-on-display is pretty simple. You type M-x make-frame-on-display, hit return, then type the display you want the frame to show up on. For example:
I have my local host (thor) running emacs and I want to make a frame pop up on a machine called zeus, on its only X display (0.0). So I would type M-x make-frame-on-display<ret>zeus:0.0<ret>
All set!
You may need to configure the remote machine's X server to accept incoming connections from your machine with "xhost +thor". You may also need to configure its firewall to allow incoming connections on the X11 port, which is 6000. Keep in mind that X forwarding is not encrypted, so if you aren't working with someone on your LAN you may want to go through a VPN in order to keep things private.
Edited to fix brackets.

You can also have the person at zeus type ssh -X thor emacsclient -c.

Did you ever consider using GNU screen on a shared account for pair programming? It's dead easy to get it to work and you get to pick any console based editor you and your partner like (emacs, vim, joe, nano, zile, ...). However, this does of course not work with editors that cannot run inside a terminal.
To set it up, create a shared account on a computer running ssh. Then both log in to that account. One of the partners starts screen with
screen
and the other connects to it with
screen -x
where -x means "attach to a not detached screen session". The users can detach from their sessions w/ "C-a d".

Old question, new solution for anyone landed on this page from year 2016.
I set this up in Ubuntu 14.04 and it works perfectly:
Suppose I want to co-edit or demo some cool stuffs on emacs with my colleague Joe on the other end of the world.
Make sure an ssh server with emacs installed at either end. That is, either MyPC or JoePC must be a SSH server and have Emacs installed. From now on, let's say I asked Joe to install SSH server and Emacs on his computer.
Make sure byobu is installed on JoePC. Byobu supports both tmux and screen as backends (I prefer tmux for a more mordern and feature-rich).
I connect to JoePC with ssh remoteuser#joepc. No need for X-forwarding.
Open emacs from byobu-ssh terminal: TERM=xterm-256color && emacsclient --alternate-editor="" -t. One can make an alias for this command. I recommend this long command because it enables both better color support in the terminal and running Emacs in daemon mode. The daemon mode make it fast to close and reopen frames.
Now the magic unfold: Ask Joe to login with the same remoteuser I am loggin in; open the terminal and start byobu if it hasn't for him.
Start hacking or fumbling :-)
Comment:
Because the way byobu work. This approach works for any other program inside the byobu terminal.
This setup performs much better than Teamviewer or any other GUI remote desktop solutions.
Because the connection is through ssh to the remote server directly, it is as secure as the ssh conenction can offer.

Related

Is there a way to reconnect to a disconnected VS Code Remote SSH connection?

When you're running VS Code Remote SSH and loose network connectivity over a long period of time and return to VS Code, the status on the bottom left show's "Disconnected from SSH: ". However, there doesn't seem to be a way to reconnect the session. I always have to revert to starting a new VS Code Remote SSH session. How can I reconnect?
You can reload the window. It keeps unsaved changes even.
Press F1 to search for commands, then search for:
Developer: Reload Window
Version of VSCode when trying this: 1.53.2.
EDIT: This does NOT work to reestablish the connection. It only helps to keep it alive. Thanks for the comments. I misinterpreted the question while looking for something similar for myself.
I'll leave the answer just in case it helps someone else.
You need to set a custom ssh file and add parameters to keep the connection to your host alive :
Host SomeRemoteHost
HostName MyRemoteHostName
User MyUsername
ServerAliveInterval 60
ServerAliveCountMax 30
Go to the SSH extension settings and set the new custom ssh config file path. This won't work if your machine goes into sleep mode, but it will keep the connection alive in the background while you work on other things.
PS: Make sure your ssh settings are correct for the host or you won't be able to log in.
It seems that there is something that drops your idle connection. As I know SSH doesn't have any configuration for dropping an idle connection but firewalls has. there might be some sort of firewall or monitoring software or hardware device which drops your connection. if you are using Linux OS the following command might help you:
ssh -o "ServerAliveInterval 60" <SERVER_ADDRESS>
this command sends keep alive request to ssh every 60 seconds.
In line with #PaulOmta answer, the easiest way is now adding this Reload button extension! It adds a Reload button to your status bar on the bottom right.
I found that ⌘-R shortcut didn't work on mine (maybe because I have other keybinders on)
VS Marketplace Link: https://marketplace.visualstudio.com/items?itemName=natqe.reload

Docker with shared X11 socket: Why can it "start" Firefox outside of the container?

I have the following scenario:
I set up a Docker container with access to the X11 socket, essentially I did this: https://stackoverflow.com/a/25334301
Then I installed Firefox within the container and started it using the "firefox" command in bash.
What I noticed: If Firefox was already running on my host machine when I started it in the container, it essentially "escaped" the container as it just opened a new window of the host instance of Firefox. It therefore had access to everything on the host machine and the container became useless.
This also works vice versa: If Firefox is not running on the host and I start an instance in the container, it is really running inside the container. If I then start Firefox on the host, the new instance is also running inside the container.
However, I couldn't reproduce this behavior with gvim instead of Firefox.
I am well aware of the security problems inherent with X11 socket sharing, but I cannot explain the scenario I described above. Why can a container start a "process"---or rather a window---outside of its restricted environment? And how is it even possible that my host system starts a process within a container only because the same program is already running inside a container?
(Please note that I didn't know how to call such a graphical instance of a program other than "process", although it's probably not a real process in this case...)
System: Ubuntu GNOME 14.10, Docker 1.5, ubuntu:latest Docker image.
UPDATE: This doesn't happen if I start Firefox using the -new-instance flag, so it seems to be more of a Firefox problem than a X11 socket problem.
UPDATE 2: Seems that this happens in other scenarios as well, for example using ssh with X-forwarding:
https://unix.stackexchange.com/questions/104476/why-starting-firefox-from-command-line-in-vm-starts-the-firefox-in-the-host-ma
and
https://superuser.com/questions/462055/launching-firefox-on-remote-server-causes-local-firefox-to-open-the-page-instead
Now the question is, how the hell does Firefox do this? What kind of X11 sorcery do they use to find out if Firefox is already running?
Because you forward the x11 socket into the container, any graphical program, whether inside the container or outside the container, will be talking to the same Xorg server. This is the same as when using ssh with X-forwarding.
Now let's say that one firefox instance is already started and communicating with that xserver. If we are the second firefox process starting up, we might find that first process by navigating the window tree from the root. We might be able to identify a window belonging to firefox through some properties that it sets on it's windows. Once we found a window belonging to firefox, we might send a message to the process owning that window, asking it to add a new tab.
Perhaps if we find such a process and ask it to open a new tab, we just die off as our job is done.
Of course, we could always just look at the source and find out that indeed firefox does basically this. In particular they:
find an existing window
and then notify it
But they don't notify it with a client message. They do it by changing a window property. Presumably the process that creates the window also subscribes to property change notifications. In case you're curious the full path through the code is:
from parsing the command line, StartRemoteClient
which creats a client (note that they do this over d-bus/wayland also) and then calls SendCommandLine()
which is a virtual function, so find it's override XRemoteClient
and in there you see where it calls the previous two functions linked to FindBestWindow() and then DoSendCommandLine().

How to let Emacs jump to the remote Linux machine?

I am working on a remote Linux machine a little complex right now. Firstly, I use Putty to login a jump machine which is also a Linux system in my office, then I use command go to jump to the remote machine outside of my office. There is also a key file I need when using putty. The Linux jump command is like this:
ssh 119.11.11.11 -p 22
The IP should be changed according to the remote machine IP.
The usual way of my development is always using Emacs Tramp to edit files remotely.
I don't want to copy my Emacs config files to the remote machine, for it is a little bit hard to sync the config files between machines. I also don't want to download the files to local for it isn't conveniently to debug.
In this suitation, how can I use Emacs to jump to the remote machine? Is it possible to do the jump by using Cygwin, Putty or something else?
My desktop is Windows 7, and my Emacs is 24.2
Assuming you can't SSH directly to the destination server, it sounds like you could resolve this by configuring a multi-hop proxy for tramp.
I've only tried that once, but it was for a slightly different situation, and I had problems getting it working; so I'll just point you at the documentation, and leave it to someone more knowledgeable to provide other details if need be.
C-hig (tramp) Multi-hops RET
I would strongly recommend using either scpc or rsyncc as the method for the second hop, if possible, as that will automatically utilise SSH ControlMaster to keep the connection open, which dramatically improves Tramp performance.
I'm not sure whether or not there's an equivalent to that for PuTTY/plink? I do know that Cygwin isn't able to support ControlMaster for some technical reasons (or at least this was the case a few years ago), so using that probably wouldn't help.
Another alternative Cygwin's SSH and PuTTY is to host a Linux(*) VM on your Windows box and run Emacs inside that (which means you can use Linux's SSH and ControlMaster). Cygwin can provide an X display in that instance. That's complicating matters, of course, so I would certainly try out the simpler options first; but if performance is lacking, and your local PC is reasonably powerful, the VM approach might surprise you.
* or similar
Ignoring Tramp entirely, sshfs is often used to mount a remote filesystem locally, in which case Emacs doesn't even know that it's talking to a remote server. I've never used it myself, and certainly not on Windows, but it could be worth a look as well.

Automatic backup of emacs file edit on a server

I have a large repository of C++ code on a remote cluster (linux OS). When I need to work on this code from my home computer (Ubuntu OS), I try to access these codes through emacs on X windows. However the X window connection is very slow making the editing a painful process. So I sometimes move files manually between my local drive and remote cluster to edit the files. My question is: is there a way to configure my local emacs, such that when I edit the file in my local space, it would automatically be backed up in the cluster where it can then be compiled?
UPDATE:1
I installed TRAMP and it works well for servers that can be connected directly. However I also have servers which can be connected only when I activate VPN. How to provide the VPN information to TRAMP to connect to this server?
The other question I had was how to stop the TRAMP when it waits for prompts from remote shell without having to kill the whole emacs buffer.
This is typically a use case where TRAMP would be useful.
Instead of connecting to the server using SSH and opening Emacs there with X forwarding, run Emacs on your box and open your files remotely using TRAMP. For example:
C-xC-f/ssh:user#host:/remote/path/to/the/fileRET
This way, your Emacs process runs locally, but all file operations (e.g. save, revert, ...) are forwarded to the server, and all shell commands issued from TRAMP buffers also run on the remote server (this includes M-x compile)
UPDATE:1
When TRAMP hangs waiting for a remote shell prompt (which tends to happen frequently for reasons which are still obscure to me), I usually kill the underlying ssh process (htop with tree-like view is a good tool to do this) . TRAMP notices this and automatically respawns the killed process to resume operations.
Wouldn't it be easier to run Emacs in a console on the remote server? All Emacs functions can be access via the keyboard and once you get used to the key combinations it usually works out faster.
That way you will be running faster than forwarding an X session - running in a console is what Emacs was designed for.
As an added bonus - if you get used to using Gnu screen - http://www.gnu.org/software/screen/ you can pick up your sessions exactly as they were if the connection drops. In fact with screen you can shutdown your laptop at the end of the day - login over SSH the next day and pick up all your 'screens' exactly as they were the day before. This will include any open editors, debug sessions etc.
Gnu screen is available as a package on Debian and probably most Linux distributions.

Emacs-client - whats the minimal installation?

Lets say I have an Emacs-Server running on some remote server, with all the libraries and software necessary for running my application.
Then I want several clients to connect to that remote machine, using Emacs-client. Does each client need a full Emacs installation, or is there a minimal installation that is just enough to communicate with the remote server, where all the action is?
Could this (Emacs-)client installation be so minimal, that almost all software-updates can be done on the server, without affecting the Emacs-clients?
Is there a reason not to run the clients remotely as well, and simply use a local display? That way, pretty much all you need on the local machines is the ssh client and the X Window server.
ssh -X (user)#(server) "emacsclient -c"
Edits for the comments:
This command starts a new client to connect to an existing Emacs server (which it assumes is already running). You can use "emacsclient -a '' -c" to automatically start emacs --daemon if there is no existing server, but I don't know whether you want the connecting user to be starting the server.
In fact, I'm pretty unsure about the whole multi-user side of this to be honest, as I've never done that before. Authentication for the above is handled by ssh, but there may well be subsequent permission issues to deal with, or similar, when the server and the clients are started by different users.
This approach should be possible with Windows/Cygwin as client and/or server, as Cygwin provides Emacs, OpenSSH, and X.org packages. (I regularly use Windows/Cygwin as a local display for Emacs running on Linux.) It may be harder to set up, though, and any permissions issues are probably different when you're using Cygwin.
I'm less sure how this would work without Cygwin. NTEmacs certainly won't talk to X.org, so I imagine you'd be terminal based in that instance. (There are probably other options, but Cygwin sounds to me like the best-integrated approach to using all of Emacs, SSH, and X on Windows).
Lastly, I imagine you're probably getting your "Connection refused" error because localhost is not running a sshd daemon? I would say that configuration of ssh is outside the scope of this question, but there are lots of resources online for that.
Depending on what you're trying to achieve, you may be able to use a combination of Emacs and Screen. By starting up Emacs from Screen on the remote machine and detaching from it, you can subsequently re-attach from a different machine that doesn't have Emacs. Again, whether this will work for you or not depends on what you're trying to do; however, for many Emacs use-cases, this can be very effective. If you're not familiar with using Screen in this manner, here is some reading material:
screen - The Terminal Multiplexer
I am not sure that would be possible. emacsclient uses tramp to connect to a remote server, and just by looking at the number of requires in the tramp elisp files (41) it seems very unlikely. You can try it yourself with the following:
zgrep -oE "\(require '[a-z-]+\)" *el.gz | sed -e 's%[a-z0-9-]\+\.el\.gz:%%g' | sort | uniq -cu | wc -l
I'm not an expert in emacsclient, but I don't think is was designed to do what you're looking for. I think the general use case is that emacsclient allows you to redirect new requests to open a file with emacs to a persistent emacs process to avoid what may be a bit of an overhead in startup time. You seem to be looking for more of a true client/server relationship.
I think to meet the goal you're aiming at you'll probably need to look a little outside emacs, probably a project unto itself - 'emacsRemoteClient. It boils down to one or two models; the file you want to edit would need to have it's path sent over to the server machine so that emacs could do some sort of remote tramp access & then spawn the xwindow locally (using the local X env or requiring an x server on windows)... or two, transferring the file to some temp location on the server box and again spawning the remote x window locally (followed by syncing the changes between the tmp & local file).
Would be cool to have something like that... but suspecting it'll involve a bit of work. Maybe we just need a version of emacs written in javascript and it can live in the cloud or on your browser... oh to have emacs keybindings in the browser ;-)
-Steve