Allow format specifiers in `tramp-login-program'

* doc/misc/tramp.texi (Extension packages): Explain how to use own
format specifiers.

* lisp/net/tramp.el (tramp-expand-args): Make DEFAULT argument
optional.  Handle also ARGS being an atom.
(tramp-handle-make-process):
* lisp/net/tramp-container.el (tramp-skeleton-completion-function):
* lisp/net/tramp-sh.el (tramp-ssh-or-plink-options)
(tramp-maybe-open-connection):
* lisp/net/tramp-sshfs.el (tramp-sshfs-handle-process-file):
Call `tramp-expand-args' for `tramp-login-program'.
This commit is contained in:
Michael Albinus 2026-03-30 08:18:00 +02:00
parent 8c481ac944
commit 9c75d761a5
5 changed files with 56 additions and 16 deletions

View file

@ -6728,6 +6728,45 @@ See the docstring of variable @code{tramp-methods} for possible
@code{foo-tramp-executable} in this example would be a Lisp constant,
which is the program name of @command{foo}.
If a parameter doesn't have a static value but must be computed at
runtime, a format specifier can be used, like @t{"%h"} in the example
above. See the docstring of @code{tramp-methods}, which patterns are
expanded in which parameter. Furthermore, other format specifiers can
be added via the variable @code{tramp-extra-expand-args}.
The following parameters expand format specifiers for the
@code{tramp-sh} backend: @code{tramp-copy-args},
@code{tramp-copy-env}, @code{tramp-copy-file-name},
@code{tramp-login-args}, @code{tramp-login-program},
@code{tramp-remote-copy-args}.
The example above could use
@lisp
(tramp-login-program "%1")
@end lisp
And you could set @code{tramp-extra-expand-args} as connection-local value:
@lisp
@group
(defun foo-tramp-get-login-program (vec)
"Return connection-local value of `tramp-login-program'."
@dots{})
@end group
@group
(connection-local-set-profile-variables
'foo-tramp-connection-local-default-profile
'((tramp-extra-expand-args
?1 (foo-tramp-get-login-program (car tramp-current-connection)))))
(connection-local-set-profiles
'(:application tramp :protocol "foo")
foo-tramp-connection-local-default-profile)
@end group
@end lisp
Another initialization could tell @value{tramp} which are the default
user and host name for method @option{foo}. This is done by calling
@code{tramp-set-completion-function}:

View file

@ -266,7 +266,7 @@ BODY is the backend specific code."
tramp--last-hop-directory)
tramp-compat-temporary-file-directory))
(program (let ((tramp-verbose 0))
(tramp-get-method-parameter
(tramp-expand-args
(make-tramp-file-name :method ,method)
'tramp-login-program)))
(vec (when (tramp-tramp-file-p default-directory)
@ -656,10 +656,9 @@ see its function help for a description of the format."
'((tramp-config-check . tramp-kubernetes--current-context-data)
;; This variable will be eval'ed in `tramp-expand-args'.
(tramp-extra-expand-args
. (?a (tramp-kubernetes--container (car tramp-current-connection))
?h (tramp-kubernetes--pod (car tramp-current-connection))
?x (tramp-kubernetes--context-namespace
(car tramp-current-connection)))))
?a (tramp-kubernetes--container (car tramp-current-connection))
?h (tramp-kubernetes--pod (car tramp-current-connection))
?x (tramp-kubernetes--context-namespace (car tramp-current-connection))))
"Default connection-local variables for remote kubernetes connections.")
(connection-local-set-profile-variables

View file

@ -5037,7 +5037,7 @@ Goes through the list `tramp-inline-compress-commands'."
;; Use plink options.
((string-match-p
(rx "plink" (? ".exe") eol)
(tramp-get-method-parameter vec 'tramp-login-program))
(tramp-expand-args vec 'tramp-login-program))
(concat
(if (eq tramp-use-connection-share 'suppress)
"-noshare" "-share")
@ -5398,7 +5398,7 @@ connection if a previous connection has died for some reason."
hop 'tramp-connection-timeout
tramp-connection-timeout))
(command
(tramp-get-method-parameter
(tramp-expand-args
hop 'tramp-login-program))
;; We don't create the temporary file. In
;; fact, it is just a prefix for the

View file

@ -269,7 +269,7 @@ arguments to pass to the OPERATION."
(setq ret
(apply
#'tramp-call-process
v (tramp-get-method-parameter v 'tramp-login-program)
v (tramp-expand-args v 'tramp-login-program)
nil outbuf display
(tramp-expand-args
v 'tramp-login-args nil

View file

@ -5325,7 +5325,7 @@ Do not set it manually, it is used buffer-local in `tramp-get-lock-pid'.")
(defvar tramp-extra-expand-args nil
"Method specific arguments.")
(defun tramp-expand-args (vec parameter default &rest spec-list)
(defun tramp-expand-args (vec parameter &optional default &rest spec-list)
"Expand login arguments as given by PARAMETER in `tramp-methods'.
PARAMETER is a symbol like `tramp-login-args', denoting a list of
list of strings from `tramp-methods', containing %-sequences for
@ -5348,12 +5348,14 @@ a connection-local variable."
(setq spec-list (cddr spec-list)))
(setq spec (apply #'format-spec-make extra-spec-list))
;; Expand format spec.
(flatten-tree
(mapcar
(lambda (x)
(setq x (mapcar (lambda (y) (tramp-format-spec y spec)) x))
(unless (member "" x) x))
args))))
(if (atom args)
(tramp-format-spec args spec)
(flatten-tree
(mapcar
(lambda (x)
(setq x (mapcar (lambda (y) (tramp-format-spec y spec)) x))
(unless (member "" x) x))
args)))))
(defun tramp-post-process-creation (proc vec)
"Apply actions after creation of process PROC."
@ -5476,7 +5478,7 @@ processes."
`(,(string-join command " ")))
command))
(login-program
(tramp-get-method-parameter v 'tramp-login-program))
(tramp-expand-args v 'tramp-login-program))
;; We don't create the temporary file. In fact, it is just
;; a prefix for the ControlPath option of ssh; the real
;; temporary file has another name, and it is created and