@@ -176,7 +176,18 @@ the executable."
176
176
" The shell that gets run in the vterm for tramp.
177
177
178
178
`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."
180
191
:type '(alist :key-type string :value-type string)
181
192
:group 'vterm )
182
193
@@ -826,11 +837,58 @@ Exceptions are defined by `vterm-keymap-exceptions'."
826
837
(setq next-error-function 'vterm-next-error-function )
827
838
(setq-local bookmark-make-record-function 'vterm--bookmark-make-record ))
828
839
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
+
829
887
(defun vterm--get-shell ()
830
888
" Get the shell that gets run in the vterm."
831
889
(if (ignore-errors (file-remote-p default-directory))
832
890
(with-parsed-tramp-file-name default-directory nil
833
- (or (cadr ( assoc method vterm-tramp-shells) )
891
+ (or (vterm-- tramp-get-shell method )
834
892
(with-connection-local-variables shell-file-name)
835
893
vterm-shell))
836
894
vterm-shell))
0 commit comments