Connecting to macOS with Emacs Tramp via ssh
If one tries to connect to a macOS machine with Emacs Tramp via ssh, Emacs always hangs without ever connecting. This was bugging me for quite a while; I had to go out and open a separate Terminal window outside Emacs to do things.
After a (setq tramp-verbose 6)
and a re-connection attempt via
Tramp, it looked like Tramp was having a hard time finding the shell
prompt from the output, because the prompt was littered with control
characters.
17:03:07.303779 tramp-process-one-action (5) # Looking for regexp "\(\(?:^\|^M\)[^]#$%>
]*#?[]#$%>] *\(^[\[[[:digit:];]*[[:alpha:]] *\)*\)\'" from remote shell
17:03:07.303812 tramp-process-one-action (5) # Looking for regexp "\(\(Are you sure you want to continue connecting (yes/no\(?:\(?:/\[fingerprint]\)?)\?\)\)\s-*\)\'" from remote shell
17:03:07.303839 tramp-process-one-action (5) # Looking for regexp "\(\(\(?:Store key in cache\? (y/\|Update cached key\? (y/n, Return cancels connectio\)n)\)\s-*\)\'" from remote shell
17:03:07.306464 tramp-process-one-action (5) # Looking for regexp "\(\(TERM = (.*)\|Terminal type\? \[.*\]\)\s-*\)\'" from remote shell
17:03:07.306512 tramp-process-one-action (5) # Looking for regexp "\(Access granted\. Press Return to begin session\. \)\'" from remote shell
17:03:07.306539 tramp-process-one-action (5) # Looking for regexp "\(^^M*Confirm user presence for key .*[^M
]*\)\'" from remote shell
17:03:07.306564 tramp-process-one-action (5) # Looking for regexp "\(\)\'" from remote shell
17:03:07.306588 tramp-process-one-action (5) # Call ‘tramp-action-process-alive’
17:03:07.306653 tramp-accept-process-output (1) # Quit: "Quit", ""
% ^M ^M^Msungbin@sungbin-mbp13 ~ % ^[[?2004h
17:03:07.306693 tramp-accept-process-output (1) # Quit: "Quit", ""
% ^M ^M^Msungbin@sungbin-mbp13 ~ % ^[[?2004h
I first thought that this was due to my config not respecting the
TERM
env variable, but I’ve seen that ^[[?2004
escape before and
searched for it… and it turns out this is because zsh activates
bracketed paste for dumb terminals as well! It’s explained in the
article Zsh 5.1 and bracketed paste.
Essentially the fix (also mentioned in the article) is to add this
snippet to .zshrc
:
if [[ $TERM == "dumb" ]]; then
unset zle_bracketed_paste
else
autoload -Uz bracketed-paste-magic
zle -N bracketed-paste-magic
fi