I am editing a file on a remote server via Tramp, and I decide that I want to open up an ansi-term
session on the remote server (as opposed to relying on shell-command
). How do I do this? When I run ansi-term
, it just opens up a new session on my local computer.
Asked
Active
Viewed 2,300 times
0

Andrew
- 541
- 6
- 17
-
`ansi-term` is 'just' a terminal emulator, running on the local Emacs instance. Are you asking how to connect to a *remote shell* process (inside an `ansi-term` buffer) ? – phils Mar 16 '17 at 21:26
-
3Possible duplicate of [Honor default-directory in ansi-term](http://emacs.stackexchange.com/questions/20877/honor-default-directory-in-ansi-term) – phils Mar 18 '17 at 11:49
-
You are right, phils. And what is shocking to myself: I answered there with the gnome-term solution and totally forgot about it.... so much about getting older. – dfeich Mar 18 '17 at 20:22
2 Answers
2
You can use the following function
(defun dfeich/ansi-terminal (&optional path name)
"Opens an ansi terminal at PATH. If no PATH is given, it uses
the value of `default-directory'. PATH may be a tramp remote path.
The ansi-term buffer is named based on `name' "
(interactive)
(unless path (setq path default-directory))
(unless name (setq name "ansi-term"))
(ansi-term "/bin/bash" name)
(let ((path (replace-regexp-in-string "^file:" "" path))
(cd-str
"fn=%s; if test ! -d $fn; then fn=$(dirname $fn); fi; cd $fn;")
(bufname (concat "*" name "*" )))
(if (tramp-tramp-file-p path)
(let ((tstruct (tramp-dissect-file-name path)))
(cond
((equal (tramp-file-name-method tstruct) "ssh")
(process-send-string bufname (format
(concat "ssh -t %s '"
cd-str
"exec bash'; exec bash; clear\n")
(tramp-file-name-host tstruct)
(tramp-file-name-localname tstruct))))
(t (error "not implemented for method %s"
(tramp-file-name-method tstruct)))))
(process-send-string bufname (format (concat cd-str " exec bash;clear\n")
path)))))
This code is also linked this gist. I have a similar gist for opening gnome-terminals at the current path (or any given path) here.
With the ansi terminal there may just some small but non-critical problem with the remote server not knowing the 'eterm-color' type. E.g. look at this stackoverflow question.
-
If you were keen, you could integrate http://emacs.stackexchange.com/q/18672 with your solution here, in order to *directly* run the ssh command in the terminal, as opposed to starting a local shell and then running commands in the local shell. – phils Mar 16 '17 at 22:02
1
I have implemented @phils suggestion based on the answer provided by @dfeich. The advantage is that without the local shell indirection, the terminal management is "instant".
(defun aratiu/terminal (&optional path name)
"Opens a terminal at PATH. If no PATH is given, it uses
the value of `default-directory'. PATH may be a tramp remote path.
The term buffer is named based on `name' "
(interactive)
(require 'term)
(unless path (setq path default-directory))
(unless name (setq name "term"))
(let ((path (replace-regexp-in-string "^file:" "" path))
(cd-str "fn=%s; if test ! -d $fn; then fn=$(dirname $fn); fi; cd $fn; exec bash")
(start-term (lambda (termbuf)
(progn
(set-buffer termbuf)
(term-mode)
(term-char-mode)
(switch-to-buffer termbuf)))))
(if (tramp-tramp-file-p path)
(let* ((tstruct (tramp-dissect-file-name path))
(cd-str-ssh (format cd-str (tramp-file-name-localname tstruct)))
(user (if (tramp-file-name-user tstruct)
(tramp-file-name-user tstruct)
user-login-name))
(switches (list "-l" user
"-t" (tramp-file-name-host tstruct)
cd-str-ssh))
(termbuf (apply 'make-term name "ssh" nil switches)))
(cond
((equal (tramp-file-name-method tstruct) "ssh")
(funcall start-term termbuf))
(t (error "not implemented for method %s"
(tramp-file-name-method tstruct)))))
(let* ((cd-str-local (format cd-str path))
(termbuf (apply 'make-term name "/bin/sh" nil (list "-c" cd-str-local))))
(funcall start-term termbuf)))))

gimmesudo
- 111
- 2
-
I think you'll want to add `"-l" (tramp-file-name-user tstruct)` to your switches. I had a stab at [something similar](https://emacs.stackexchange.com/a/21533) years ago but at the time I couldn't see how to generate the command in a way that could support multi-hop tramp connections, and I think this has the same problem; but it seems to work nicely otherwise. – phils Dec 17 '21 at 04:16
-
Thanks @phils, I added user handling to my function and updated the answer. It is true it does not work for multi-hop tramp connections, that is something I do not use personally very often, but I guess this function could be generalized a bit to chain ssh commands, shouldn't be to hard I guess, just needs someone willing to do it. :) – gimmesudo Dec 17 '21 at 11:14