Firstly, I am unaware of a native elisp ssh client (and do not imagine there is a great deal of motivation for writing one), so you will certainly need to interact with an external ssh client process.
As you wish to use ssh interactively, the ssh process requires a terminal on the local side of the connection.
The question therefore becomes: Does Emacs implement a terminal to which an ssh process can be attached?
The answer is: yes -- term.el provides a robust terminal implementation, through which ssh can be run directly, without the requirement for a shell.
If you run M-x term
RET you will be prompted for a program. (It defaults to a shell, but that is certainly not the only type of process you can run.)
For reasons unknown, the interactive term
(and ansi-term
) functions do not support passing arguments to the specified program, which renders them less useful if you wished to run something like ssh user@host
. You could instead specify a script which handled the arguments, but we can manage that in elisp as well:
The term
function is actually a simple wrapper which calls make-term
to start the program and then sets the appropriate modes. As make-term
does accept program arguments, it is quite straightforward to copy-and-modify the definition of term
to suit your own purposes.
Here is a very simple implementation:
(defun my-ssh (user host port)
"Connect to a remote host by SSH."
(interactive "sUser: \nsHost: \nsPort (default 22): ")
(let* ((port (if (equal port "") "22" port))
(switches (list host "-l" user "-p" port)))
(set-buffer (apply 'make-term "ssh" "ssh" nil switches))
(term-mode)
(term-char-mode)
(switch-to-buffer "*ssh*")))
or perhaps this is preferable:
(defun my-ssh (args)
"Connect to a remote host by SSH."
(interactive "sssh ")
(let ((switches (split-string-and-unquote args)))
(set-buffer (apply 'make-term "ssh" "ssh" nil switches))
(term-mode)
(term-char-mode)
(switch-to-buffer "*ssh*")))
Obviously there is scope for improvements, but I think that's fairly useful as-is.
You should ensure that you are familiar with the quirks of term-mode
. See:
- M-:
(info "(emacs) Terminal emulator")
RET
- M-:
(info "(emacs) Terminal Mode")
RET
- C-hf
term-mode
RET