I have a tiny script in my path on the remote host at ~/bin/ec
, shorthand for emacsclient.
#!/bin/bash
params=()
for p in "$@"; do
if [ "$p" == "-n" ]; then
params+=( "$p" )
elif [ "${p:0:1}" == "+" ]; then
params+=( "$p" )
else
params+=( "/ssh:z:"$(readlink -f $p) )
fi
done
emacsclient --server-file=$HOME/.emacs.d/server/server "${params[@]}"
This script passes -n
and +
args unchanged to emacsclient, otherwise args are treated as files for your local Emacs to open. Each file is prefixed with the TRAMP protocol and host so Emacs knows how to open it. You might be able to change ssh:
to a different TRAMP protocol if you prefer.
You must replace z
with the hostname of your remote machine. This is used by local Emacs to connect via TRAMP. (You might be able to use hostname
here for generality. I prefer to use tiny entries like z
in my local ssh_config
for brevity, and the remote has no idea I'm doing this. Try it!)
Usage:
ec file
in the remote shell opens file in local Emacs and waits
ec -n file
in the remote shell opens file in local Emacs and returns
export EDITOR=~/bin/ec
in remote .bashrc
makes the magic happen
To ensure my server
file is good I have this in my local .emacs
, again using the tiny hostname z
:
(setq server-use-tcp t
server-port 9999)
(defun server-start-and-copy ()
"Start server and copy server file to remote box."
(interactive)
(server-start)
(copy-file "~/.emacs.d/server/server" "/z:.emacs.d/server/server" t)
(chmod "/z:.emacs.d/server/server" (string-to-number "644" 8))
)
(add-hook 'emacs-startup-hook 'server-start-and-copy)
Port 9999 is a RemoteForward. I put this in my local ~/.ssh/ssh_config
to automate the forwarding, plus the ControlMaster stuff for speed.
Host z
HostName dev.example.com
User dev
ControlMaster auto
ControlPath ~/.ssh/z.sock
RemoteForward 9999 localhost:9999
Finally, make sure TRAMP knows about your ssh_config
if you use it:
(require 'tramp)
(tramp-set-completion-function "ssh"
'((tramp-parse-sconfig "~/.ssh/config")))