Copy-pasting in Spacemacs from within tmux in an ssh session - ssh

My current setup consists of an OS X host machine in which I run iTerm. From inside iTerm I ssh into a second machine in which I do all the development. In there I run tmux, and inside tmux I run Spacemacs.
The experience is quite smooth with the only exception of copy-pasting. When I copy/paste from inside emacs, it interacts with the second machine's clipboard. Is there any way make it also use the host's clipboard instead? I would imagine that for copying it could execute a hook after each yank that would send via ssh the copied text to "pbcopy" in the host machine, and for pasting it could have a custom registry that would use the host's "pbpaste", also via ssh.

I managed to make it work with an xclip integration.
First of all make sure that xclip is installed in your development machine. When you ssh into the development machine forward X11 with ssh -Y.
In the development machine, in dotspacemacs/layers, as dotspacemacs-additional-packages, add xclip:
dotspacemacs-additional-packages '(xclip)
Also in the development machine, in dotspacemacs/user-config add:
;; == Terminal ==
;; XClip integration
(require 'xclip)
(define-globalized-minor-mode global-xclip-mode
xclip-mode xclip-mode)
(global-xclip-mode 1)
There is also an issue open in Spacemacs to add a layer to provide that functionality.

Related

How to create a Linux GUI app short cut for WSL2 on Windows10?

I have properly installed and setup WSL2. It works fine.
I also setup X11 forwarding and X server (VcXsrv). I can launch GUI apps such like konsole or gvim or even google-chrome from a bash shell.
Now I want to launch konsole by simply double clicking a short cut on the desktop without launching the bash command mode terminal. How should I do it?
I tried running this in cmd:
> wsl /usr/bin/konsole
and it reports:
qt.qpa.xcb: could not connect to display
qt.qpa.plugin: Could not load the Qt platform plugin "xcb" in "" even though it was found.
This application failed to start because no Qt platform plugin could be initialized. Reinstalling the application may fix this problem.
Available platform plugins are: eglfs, linuxfb, minimal, minimalegl, offscreen, vnc, wayland-egl, wayland, wayland-xcomposite-egl, wayland-xcomposite-glx, xcb.
I'm guessing it is because some X11 forwarding configurations were not properly setup, so I created a k.sh as follows:
#!/usr/bin/bash
export DISPLAY=$(cat /etc/resolv.conf | grep nameserver | awk '{print $2; exit;}'):0.0
export LIBGL_ALWAYS_INDIRECT=1
/usr/bin/konsole &
The first two lines were the X11 settings in my .bashrc, the last line launches konsole.
It works fine under bash environment; but when I ran
wsl k.sh
from windows cmd environment, it silently quitted without launching the konsole.
I'm out of ideas. What should I do to directly launch konsole or other Linux GUI apps under windows without having to getting into bash?
Thanks in advance.
You are asking about two different command-lines, and while the failures in running them via the wsl command have the same root-cause, the underlying failures are likely slightly different.
In both cases, the wsl <command> invocation results in a non-login, non-interactive shell where the command simply "runs and exits".
Since the shell is non-login/non-interactive, your startup files (such as ~/.bashrc and ~/.bash_profile, among others) are not being processed.
When you run:
wsl /usr/bin/konsole
... the DISPLAY variable is not set, since, as you said, you normally set it in your ~/.bashrc.
Try using:
wsl -e bash -lic "/usr/bin/konsole"
That will force bash to run as a login (-l), interactive (-i) shell. The DISPLAY should be set correctly, and it should run konsole.
Note that the quotes probably aren't necessary in this case, but are useful for delineating the commands you are passing to bash. More complicated command-lines can be passed in via the quotes.
As for:
wsl k.sh
That's likely a similar problem. You are doing the right thing by setting DISPLAY in your script, but I notice that you aren't using a fully-qualified path it. This would normally work, of course, if your script is in a directory on the $PATH.
But I'm guessing that you might add that directory to the $PATH in your startup config, which means (again) that it isn't being set in this non-login, non-interactive shell.
As before, try:
wsl -e bash -lic "k.sh"`
You could also use a fully-qualified path, of course.
And, I'm fairly sure you are going to run into an issue with trying to put konsole in the background via the script. When WSL exits, and the bash shell process ends, the child konsole process will terminate as well.
You could get around this with a nohup in the script, but then you also need to redirect the stderr. It's probably easiest just to move the & from the script itself to the command-line. Change your k.sh to:
#!/usr/bin/bash
export DISPLAY=$(cat /etc/resolv.conf | grep nameserver | awk '{print $2; exit;}'):0.0
export LIBGL_ALWAYS_INDIRECT=1
/usr/bin/konsole
Then run it with:
wsl -e bash -lic "k.sh &"`
Finally, a side note that when and if you can upgrade to Windows 11, it will automatically create Windows Start Menu entries for any Linux GUI app you install that creates a .desktop file. You can manually create .desktop files to have WSL create Start menu items for most applications.
For reference, in Windows 11 it's easier. To run a GUI application without a terminal window popping up, you just need to call wslg.exe instead of wsl.exe.
So, for example:
target: C:\Windows\System32\wslg.exe konsole
start in: C:\WINDOWS\system32
shortcut key: None
comment: Konsole
This tutorial shows how to install VcXsrv and and edit .bashrc to ensure that the "DISPLAY env var is updated on every restart".
DISPLAY env var needs to be dynamic setting.
I've used it successfully with WSL2 on Windows10 Version 21H2 (OS build 19044.2130) to run Chrome, Edge, and thunar. I'm using the Ubuntu 20.04 Linux distro.
To edit .bashrc follow these instructions.

Yank to system: neovim inside tmux inside ssh

I have found a similar question here but without a working answer for me:
System Clipboard Vim within TMUX within SSH session
I'm using Gnome terminal to start a ssh session with X forwarding to Debian 10.
If I start neovim and copy (yank) text, then this text is copied to the Gnome clipboard and everything is fine.
This is the content of .ssh/config :
Host nuc
ForwardX11 yes
I have this in .vimrc:
set clipboard^=unnamed,unnamedplus
But when I start neovim inside tmux, then this doesn't work.
I have tmux with the tmux-yank plugin and this works because when I copy from neovim inside tmux and then exit tmux I can see the selected text with xsel -o
How can I get the selection forwarded to my system clipboard?
Vim and NeoVim support for clipboard use a connection to the X11 server. The address to connect is available from the $DISPLAY environment variable.
The issue with X11 and terminal multiplexers or session managers such as tmux or screen is that the environment of the shells and programs running inside them will be the environment of when the tmux session was first created. That includes the $DISPLAY variable. So it means vim inside tmux will be trying to use the address of the X11 server of when the tmux session was created, not the one from where you just connected now.
A dirty but simple workaround is to update the $DISPLAY variable when you reconnect to tmux, to ensure you'll be connecting to the correct X11 server. Note that you need to do that for every shell or program running inside tmux, since each of them will have its own out-of-sync copy of the environment variable.
Something like the following works:
$ ssh -X nuc
nuc$ echo $DISPLAY
:1234.1
nuc$ tmux attach
tmux$ export DISPLAY=:1234.1
tmux$ vim
This should make clipboard work for that particular Vim.
As mentioned, if you have many tmux windows and panes, you'd have to update $DISPLAY on all of them. Also, if you create new windows or panes, they will start with the wrong $DISPLAY setting too (though you can also update the value of $DISPLAY in tmux's environment to fix new windows and panes, see tmux's set-environment command for that.)

How to enable X11 forwarding in PyCharm SSH session?

The Question
I'm trying to enable X11 forwarding through the PyCharm SSH Terminal which can be executed via
"Tools -> Start SSH session..."
Unfortunately, It seems there is no way of specifying the flags like I would do in my shell for enabling the X11 Forwarding:
ssh -X user#remotehost
Do you know some clever way of achieving this?
Current dirty solution
The only dirty hack I found is to open an external ssh connection with X11 forwarding and than manually update the environment variable DISPLAY.
For example I can run on my external ssh session:
vincenzo#remotehost:$ echo $DISPLAY
localhost:10.0
And than set on my PyCharm terminal:
export DISPLAY=localhost:10.0
or update the DISPLAY variable in the Run/Debug Configuration, if I want to run the program from the GUI.
However, I really don't like this solution of using an external ssh terminal and manually update the DISPLAY variable and I'm sure there's a better way of achieving this!
Any help would be much appreciated.
P.s. Making an alias like:
alias ssh='ssh -X'
in my .bashrc doesn't force PyCharm to enable X11 forwarding.
So I was able to patch up jsch and test this out and it worked great.
Using X11 forwarding
You will need to do the following to use X11 forwarding in PyCharm:
- Install an X Server if you don't already have one. On Windows this might be the VcXsrv project, on Mac OS X the XQuartz project.
- Download or compile the jsch package. See instructions for compilation below.
- Backup jsch-0.1.54.jar in your pycharm's lib folder and replace it with the patched version. Start Pycharm with a remote environment and make sure to remove any instances of the DISPLAY environment variable you might have set in the run/debug configuration.
Compilation
Here is what you need to do on a Mac OS or Linux system with Maven installed.
wget http://sourceforge.net/projects/jsch/files/jsch/0.1.54/jsch-0.1.54.zip/download
unzip download
cd jsch-0.1.54
sed -e 's|x11_forwarding=false|x11_forwarding=true|g' -e 's|xforwading=false|xforwading=true|g' -i src/main/java/com/jcraft/jsch/*.java
sed -e 's|<version>0.1.53</version>|<version>0.1.54</version>|g' -i pom.xml
mvn clean package
This will create jsch-0.1.54.jar in target folder.
Update 2020:
I found a very easy solution. It may be due to the updated PyCharm version (2020.1).
Ensure that X11Forwarding is enabled on server: In /etc/ssh/sshd_config set
X11Forwarding yes
X11DisplayOffset 10
X11UseLocalhost no
On client (MacOS for me): In ~/.ssh/config set
ForwardX11 yes
In PyCharm deselect Include system environment variables. This resolves the issue that the DISPLAY variable gets set to the system variable.
EDIT: As seen in the below image it works. For example I used the PyTorch implementation of DeepLab and visualize sample images from PASCAL VOC:
X11 forwarding was implemented in 2021.1 for all IntelliJ-based IDEs. If it still doesn't work, please consider creating a new issue at youtrack.jetbrains.com.
By the way, the piece of advice about patching jsch won't work for any IDE newer than 2019.1.
In parallel, open MobaXTerm and connect while X11 forwarding checkbox is enabled. Now PyCharm will forward the display through MobaXTerm X11 server.
This until PyCharm add this 'simple' feature.
Also, set DISPLAY environment variable in PyCharm run configuration like this:
DISPLAY=localhost:10.0
(the right hand side should be obtained with the command echo $DISPLAY in the server side)
Update 2022: for PyCharm newer than 2022.1: Plotting in SciView works by only setting ForwardX11 yes in .ssh/config (my laptop OS is ubuntu 22.04). I did not set any other parameters either on the server or local side.

Vagrant stuck in "Waiting for VM to Boot"

I want to preface this question by mentioning that I have indeed looked over most if not all vagrant "Waiting for VM to Boot" troubleshooting threads:
Things I've tried include:
vagrant failed to connect VM
https://superuser.com/questions/342473/vagrant-ssh-fails-with-virtualbox
https://github.com/mitchellh/vagrant/issues/410
http://vagrant.wikia.com/wiki/Usage
http://scotch.io/tutorials/get-vagrant-up-and-running-in-no-time
And more.
Here's how I setup my Vagrant:
Note: We are using Vagrant 1.2.2 since we do not at the moment have time to change configs to newer versions. I am also using VirtualBox 4.2.26.
My office has an /official/ folder which includes things such as Vagrantfile inside. Inside my Vagrantfile are these custom settings:
config.vm.box = "my_box"
config.ssh.private_key_path = "~/.ssh/github_rsa"
config.ssh.forward_agent = true
config.ssh.forward_x11 = true
config.ssh.max_tries = 300
config.vm.provision :shell, :inline => "/etc/init.d/networking restart"
I installed our custom box (called package.box) via vagrant box add my_box absolute_path/package.box which went without a hitch.
Running vagrant up, I would look at the "preview" of the VirtualBox, and it would simply be stuck at the login page. My Terminal would also only say: Waiting for VM to boot. This can take a few minutes. As far as I know, this is an SSH issue. Or my private key issues, though in my Vagrantfile I explicitly pointed to my private key location.
Interesting Notes:
Running dhclient within the VirtualBox GUI, it says command no found. Running sudo dhclient eth0 was one of the suggested fixes.
This fix: https://superuser.com/a/343775/298915 of "modify the /etc/rc.local file to include the line sh /etc/init.d/networking restart just before exit 0." did nothing to fix the issue.
Conclusion:
Having tried to re-install everything thinking I messed up a file, it did not seem to ameliorate the issue. I am unable to work with this issue. Could someone give me some insight?
So after around twelve hours of dejected troubleshooting, I was able to (finally) get the VM to boot.
Setup your private/public keys using the link provided. My box is a Debian Linux 3.2.0-4-amd64, so instead of /root/.ssh/id_rsa.pub, you have to use /home/vagrant/.ssh/id_rsa.pub (and the respective id_rsa path for the private key).
Note: make sure your files have the right permissions. Check using ls -l path, and change using chmod. Your machine may not have /home/vagrant/.ssh/authorized_keys, so generate that file with touch /home/vagrant/.ssh/authorized_keys.
Boot your VM using the VirtualBox GUI using (through either Vagrantfile boot-GUI command, or starting your VM using VirtualBox). Login using vagrant and vagrant when prompted.
Within the GUI, manually start dhclient using sudo dhclient eth0 -v. Why is it off by default? I have no idea. I found out that it was off when I tried to wget the private/public keys in the tutorial above, but was unable to.
Go to your local machine's command line and reload vagrant using vagrant reload. It should boot, and no longer hang at "Waiting for VM to Boot."
This worked for me. Though it may be different for other machines, for whatever reason Vagrant likes to break.
Suggestion: can this be saved as a script so we don't need to manually do this everytime?
EDIT: Update to the latest version of Vagrant, and you will never see this issue again. About time, huh?

conemu + ssh clears console history

I am using ConEmu and am totally satisfied with it except for the fact that if I use PuTTY for SSH access, I can then run commands on the remote machine like vim or nano or mcedit or others which opens some kind of a curses-interface and I can see the console commands history, but when I use CygWin SSH client or OpenSSH for Windows I cannot see the commands history anymore after running vim/nano/mcedit/whatever else.
When I quit those programs (:wq in vim, Esc key in mcedit, Ctrl^X in nano) I can see all the previous commands executed, like this (if I use PuTTY):
Run PuTTY and connect to some host
You will see something like that in history:
host$ whoami
user
host$ vim
...do something in vim then press :wq
And you should see exactly this:
=== Cut ===
host$ whoami
user
host$ vim
host$
=== Cut ===
all the previous commands (whoami) are visible. However if I run ConEmu and then use SSH client from CygWin (or OpenSSH client, it doesn't matter) the following happens:
Run ConEmu
ssh user#somehost
host$ whoami
user
host$ vim
...do something in vim then press :wq
And now the screen is empty! No history! You just see this:
=== Cut ===
host$
=== Cut ===
As if no whoami was executed. Same happens for mcedit, nano or any other programs that has something like a "screen". Also same happens with Ctrl-O in Midnight Commander, in PuTTY everything is nice, but when using ssh from CygWin in ConEmu (or OpenSSH Windows client) and running Midnight Commander each Ctrl-O just shows an empty history. As if nothing was typed previously. That is really not nice at all.
Is there any way to fix that?
The standard TERM environment variable for PuTTY.exe is xterm and that will mostly work for Cygwin ssh.exe as well. However, a better TERM environment variable for ssh.exe is cygwin.
When you use Cygwin ssh.exe to connect to another system, Cygwin processes your escape sequences, not ConEmu. In fact you get the same behavior whether you are running ssh.exe inside or outside of ConEmu. So the problem is not really related to ConEmu at all, at least not its ANSI processor.
The solution is to use the cygwin for the TERM environment variable on the remote system. In fact, the SSH client and server cooperate to do this for you automatically. But perhaps you have accidentally overridden the supplied TERM variable with say xterm in your .bash_profile or whatever. In that case, the escape sequence to restore the screen buffer after exiting the editor won't be correct for the Cygwin ANSI processor.
You can do this test to check whether this solves your problem:
$ export TERM=xterm
$ vim
$ # the screen before is cleared
$ export TERM=cygwin
$ vim
$ # the screen buffer is restored