Skip to content

Commit c1a3017

Browse files
florommelSbozzolo
authored andcommitted
Allow using the default login shell for remote connections
Lets the user specify 'login-shell as a SHELL in `vterm-tramp-shells', which leads to vterm starting with the remote location's login shell.
1 parent 09d0192 commit c1a3017

File tree

1 file changed

+60
-2
lines changed

1 file changed

+60
-2
lines changed

vterm.el

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,18 @@ the executable."
176176
"The shell that gets run in the vterm for tramp.
177177
178178
`vterm-tramp-shells' has to be a list of pairs of the format:
179-
\(TRAMP-METHOD SHELL)"
179+
\(TRAMP-METHOD SHELL)
180+
181+
Set SHELL to \\='login-shell to use the user's login shell on the host.
182+
The login-shell detection currently works for POSIX-compliant remote
183+
hosts that have the getent command (regular GNU/Linux distros, *BSDs,
184+
but not MacOS X unfortunately).
185+
186+
You can specify an additional second SHELL command as a fallback
187+
that is used when the login-shell detection fails, e.g.,
188+
\\='((\"ssh\" login-shell \"/bin/bash\") ...)
189+
If no second SHELL command is specified with \\='login-shell, vterm will
190+
fall back to tramp's shell."
180191
:type '(alist :key-type string :value-type string)
181192
:group 'vterm)
182193

@@ -826,11 +837,58 @@ Exceptions are defined by `vterm-keymap-exceptions'."
826837
(setq next-error-function 'vterm-next-error-function)
827838
(setq-local bookmark-make-record-function 'vterm--bookmark-make-record))
828839

840+
(defun vterm--tramp-get-shell (method)
841+
"Get the shell for a remote location as specified in `vterm-tramp-shells'.
842+
The argument METHOD is the method string (as used by tramp) to get the shell
843+
for, or t to get the default shell for all methods."
844+
(let* ((specs (cdr (assoc method vterm-tramp-shells)))
845+
(first (car specs))
846+
(second (cadr specs)))
847+
;; Allow '(... login-shell) or '(... 'login-shell).
848+
(if (or (eq first 'login-shell)
849+
(and (consp first) (eq (cadr first) 'login-shell)))
850+
;; If the first element is 'login-shell, try to determine the user's
851+
;; login shell on the remote host. This should work for all
852+
;; POSIX-compliant systems with the getent command in PATH. This
853+
;; includes regular GNU/Linux distros, *BSDs, but not MacOS X. If
854+
;; the login-shell determination fails at any point, the second
855+
;; element in the shell spec is used (if present, otherwise nil is
856+
;; returned).
857+
(let* ((entry (ignore-errors
858+
(with-output-to-string
859+
(with-current-buffer standard-output
860+
;; The getent command returns the passwd entry
861+
;; for the specified user independently of the
862+
;; used name service (i.e., not only for static
863+
;; passwd files, but also for LDAP, etc).
864+
;;
865+
;; Use a shell command here to get $LOGNAME.
866+
;; Using the tramp user does not always work as
867+
;; it can be nil, e.g., with ssh host configs.
868+
;; $LOGNAME is defined in all POSIX-compliant
869+
;; systems.
870+
(unless (= 0 (process-file-shell-command
871+
"getent passwd $LOGNAME"
872+
nil (current-buffer) nil))
873+
(error "Unexpected return value"))
874+
;; If we have more than one line, the output is
875+
;; not the expected single passwd entry.
876+
;; Most likely, $LOGNAME is not set.
877+
(when (> (count-lines (point-min) (point-max)) 1)
878+
(error "Unexpected output"))))))
879+
(shell (when entry
880+
;; The returned Unix passwd entry is a colon-
881+
;; separated line. The 6th (last) element specifies
882+
;; the user's shell.
883+
(nth 6 (split-string entry ":" nil "[ \t\n\r]+")))))
884+
(or shell second))
885+
first)))
886+
829887
(defun vterm--get-shell ()
830888
"Get the shell that gets run in the vterm."
831889
(if (ignore-errors (file-remote-p default-directory))
832890
(with-parsed-tramp-file-name default-directory nil
833-
(or (cadr (assoc method vterm-tramp-shells))
891+
(or (vterm--tramp-get-shell method)
834892
(with-connection-local-variables shell-file-name)
835893
vterm-shell))
836894
vterm-shell))

0 commit comments

Comments
 (0)