Using Windows is .. a challenge. Running tramp in emacs, especially so.

What is tramp?

So what is TRAMP anyway?

Tramp allows you transparent access to files on remote access. “Transparent” means that usually the user doesn’t have to worry about anything. All that changes is the filename convention to indicate that the file resides on a remote system. One of the neat things about using Tramp via a remote shell, is that Emacs will then automatically invoke other remote shell commands directly on that server.

Editing all occurs locally (so no remote desktop data heavy and slow process) and then is saved to the remote machine. It’s fast and extremely light weight and utterly brilliant when you mix it with babel in Org Mode you can have your literate programming running on a remote machine.

What’s the problem?

Where do I start? Let’s just assume you’ve got a working version of Emacs and ssh installed on your Windows machine.

Using tramp to connect to a remote host just…hangs.

So let’s solve that.

Debugging tramp

Debugging tramp starts with

(setq tramp-verbose 3)                  ;; default
(setq tramp-verbose 6)                  ;; useful
(setq tramp-verbose 10)                 ;; lots of detail

Pick your preferred verbosity and let’s go.

Adding flags to ssh

There’s a section in the tramp manual about the lack of pseudo-terminal support for cygwin. I found this was true still (and I don’t have cygwin). To check for compatibility: type M-x eshell RET, and start ssh test.host RET. Incompatibilities trigger this message:

Pseudo-terminal will not be allocated because stdin is not a terminal.

The option is to force a pseudo-terminal with the ssh flag -tt. I thought I could do it by setting connection information, but I couldn’t get it to work, so I’ve come up with, what I think is neat, solution:

(when (eq system-type 'windows-nt)
  ;; Get the tramp-methods variable populated
  (require 'tramp)
  ;; Add the '-tt' flag to the login arguments for "ssh" ONLY
  (push '("-tt")
        (cadr (assoc 'tramp-login-args
                     (assoc "ssh" tramp-methods)))))

That’s it. Add the -tt flag to the ssh login arguments.

There are all sorts of other explanations around the internet, long lisp functions, references (even in the GNU documentation) to using fakecygpty. We don’t need any of them.

Line ending issues

The next problem under Windows is the CRLF discrepancy from Unix systems.

If you run the following command in Org Mode

#+begin_src sh :dir /ssh:my.host:~
  uname -a
#+end_src

the error is:

uname: invalid option -- '^M'
Try 'uname --help' for more information.
[ Babel evaluation exited with code 1 ]

which I think is because tramp writes the command(s) to file and then sends the file to be executed (look at the debugging if you want more details).

One fix is to put a ; # at the end of every line, i.e. comment out the ^M, but there is a better way.

The way to resolve this is to tell Emacs that you prefer Unix encoding:

(when (eq system-type 'windows-nt)
  (prefer-coding-system 'utf-8-unix))

Easy!

Summary

Tramp can be made to work under windows by simply:

  1. Adding the -tt flag to ssh login arguments
  2. Save your buffers with unix line endings