Tramp: Use when-let*', if-let*' and `and-let*' consequently

* lisp/net/tramp-adb.el:
* lisp/net/tramp-androidsu.el:
* lisp/net/tramp-cache.el:
* lisp/net/tramp-cmds.el:
* lisp/net/tramp-compat.el:
* lisp/net/tramp-container.el:
* lisp/net/tramp-crypt.el:
* lisp/net/tramp-ftp.el:
* lisp/net/tramp-fuse.el:
* lisp/net/tramp-gvfs.el:
* lisp/net/tramp-integration.el:
* lisp/net/tramp-message.el:
* lisp/net/tramp-rclone.el:
* lisp/net/tramp-sh.el:
* lisp/net/tramp-smb.el:
* lisp/net/tramp-sshfs.el:
* lisp/net/tramp-sudoedit.el:
* lisp/net/tramp.el:
* test/lisp/net/tramp-tests.el:
Use `when-let*', `if-let*' and `and-let*' consequently.  (Bug#73441)
This commit is contained in:
Michael Albinus 2024-10-30 10:39:02 +01:00
parent 679c0c7b94
commit 1bf1753d79
19 changed files with 473 additions and 468 deletions

View file

@ -205,15 +205,15 @@ It is used for TCP/IP devices."
;;;###tramp-autoload
(defsubst tramp-adb-file-name-p (vec-or-filename)
"Check if it's a VEC-OR-FILENAME for ADB."
(when-let* ((vec (tramp-ensure-dissected-file-name vec-or-filename)))
(string= (tramp-file-name-method vec) tramp-adb-method)))
(and-let* ((vec (tramp-ensure-dissected-file-name vec-or-filename))
((string= (tramp-file-name-method vec) tramp-adb-method)))))
;;;###tramp-autoload
(defun tramp-adb-file-name-handler (operation &rest args)
"Invoke the ADB handler for OPERATION.
First arg specifies the OPERATION, second arg is a list of
arguments to pass to the OPERATION."
(if-let ((fn (assoc operation tramp-adb-file-name-handler-alist)))
(if-let* ((fn (assoc operation tramp-adb-file-name-handler-alist)))
(prog1 (save-match-data (apply (cdr fn) args))
(setq tramp-debug-message-fnh-function (cdr fn)))
(prog1 (tramp-run-real-handler operation args)
@ -620,7 +620,7 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored."
(tramp-shell-quote-argument l2))
"Error copying %s to %s" filename newname))
(if-let ((tmpfile (file-local-copy filename)))
(if-let* ((tmpfile (file-local-copy filename)))
;; Remote filename.
(condition-case err
(rename-file tmpfile newname ok-if-already-exists)

View file

@ -502,15 +502,15 @@ FUNCTION."
;;;###tramp-autoload
(defsubst tramp-androidsu-file-name-p (vec-or-filename)
"Check whether VEC-OR-FILENAME is for the `androidsu' method."
(when-let* ((vec (tramp-ensure-dissected-file-name vec-or-filename)))
(equal (tramp-file-name-method vec) tramp-androidsu-method)))
(and-let* ((vec (tramp-ensure-dissected-file-name vec-or-filename))
((equal (tramp-file-name-method vec) tramp-androidsu-method)))))
;;;###tramp-autoload
(defun tramp-androidsu-file-name-handler (operation &rest args)
"Invoke the `androidsu' handler for OPERATION.
First arg specifies the OPERATION, second arg is a list of
arguments to pass to the OPERATION."
(if-let ((fn (assoc operation tramp-androidsu-file-name-handler-alist)))
(if-let* ((fn (assoc operation tramp-androidsu-file-name-handler-alist)))
(prog1 (save-match-data (apply (cdr fn) args))
(setq tramp-debug-message-fnh-function (cdr fn)))
(prog1 (tramp-run-real-handler operation args)

View file

@ -243,8 +243,8 @@ Return VALUE."
"Remove some properties of FILE's upper directory."
(when (file-name-absolute-p file)
;; `file-name-directory' can return nil, for example for "~".
(when-let ((file (file-name-directory file))
(file (directory-file-name file)))
(when-let* ((file (file-name-directory file))
(file (directory-file-name file)))
(setq key (tramp-file-name-unify key file))
(unless (eq key tramp-cache-undefined)
(dolist (property (hash-table-keys (tramp-get-hash-table key)))
@ -409,7 +409,7 @@ is `tramp-cache-undefined', nothing is set.
PROPERTY is set persistent when KEY is a `tramp-file-name' structure.
Return VALUE."
(setq key (tramp-file-name-unify key))
(when-let ((hash (tramp-get-hash-table key)))
(when-let* ((hash (tramp-get-hash-table key)))
(puthash property value hash))
(setq tramp-cache-data-changed
(or tramp-cache-data-changed (tramp-file-name-p key)))
@ -433,7 +433,7 @@ KEY identifies the connection, it is either a process or a
used to cache connection properties of the local machine.
PROPERTY is set persistent when KEY is a `tramp-file-name' structure."
(setq key (tramp-file-name-unify key))
(when-let ((hash (tramp-get-hash-table key)))
(when-let* ((hash (tramp-get-hash-table key)))
(remhash property hash))
(setq tramp-cache-data-changed
(or tramp-cache-data-changed (tramp-file-name-p key)))
@ -448,7 +448,7 @@ used to cache connection properties of the local machine."
(setq key (tramp-file-name-unify key))
(tramp-message
key 7 "%s %s" key
(when-let ((hash (gethash key tramp-cache-data)))
(when-let* ((hash (gethash key tramp-cache-data)))
(hash-table-keys hash)))
(setq tramp-cache-data-changed
(or tramp-cache-data-changed (tramp-file-name-p key)))

View file

@ -65,24 +65,24 @@ SYNTAX can be one of the symbols `default' (default),
"method: "
(tramp-compat-seq-keep
(lambda (x)
(when-let ((name (symbol-name x))
;; It must match `tramp-enable-METHOD-method'.
((string-match
(rx "tramp-enable-"
(group (regexp tramp-method-regexp))
"-method")
name))
(method (match-string 1 name))
;; It must not be enabled yet.
((not (assoc method tramp-methods))))
(when-let* ((name (symbol-name x))
;; It must match `tramp-enable-METHOD-method'.
((string-match
(rx "tramp-enable-"
(group (regexp tramp-method-regexp))
"-method")
name))
(method (match-string 1 name))
;; It must not be enabled yet.
((not (assoc method tramp-methods))))
method))
;; All method enabling functions.
(mapcar
#'intern (all-completions "tramp-enable-" obarray #'functionp))))))
(when-let (((not (assoc method tramp-methods)))
(fn (intern (format "tramp-enable-%s-method" method)))
((functionp fn)))
(when-let* (((not (assoc method tramp-methods)))
(fn (intern (format "tramp-enable-%s-method" method)))
((functionp fn)))
(funcall fn)
(message "Tramp method \"%s\" enabled" method)))
@ -672,7 +672,7 @@ This is needed if there are compatibility problems."
(declare (completion tramp-recompile-elpa-command-completion-p))
(interactive)
;; We expect just one Tramp package is installed.
(when-let
(when-let*
((dir (tramp-compat-funcall
'package-desc-dir
(car (alist-get 'tramp (bound-and-true-p package-alist))))))
@ -763,8 +763,8 @@ buffer in your bug report.
(defun tramp-reporter-dump-variable (varsym mailbuf)
"Pretty-print the value of the variable in symbol VARSYM."
(when-let ((reporter-eval-buffer reporter-eval-buffer)
(val (buffer-local-value varsym reporter-eval-buffer)))
(when-let* ((reporter-eval-buffer reporter-eval-buffer)
(val (buffer-local-value varsym reporter-eval-buffer)))
(if (hash-table-p val)
;; Pretty print the cache.

View file

@ -76,9 +76,9 @@
;; an infloop. We try to follow the XDG specification, for security reasons.
(defconst tramp-compat-temporary-file-directory
(file-name-as-directory
(if-let ((xdg (xdg-cache-home))
((file-directory-p xdg))
((file-writable-p xdg)))
(if-let* ((xdg (xdg-cache-home))
((file-directory-p xdg))
((file-writable-p xdg)))
(prog1 (setq xdg (file-name-concat xdg "emacs"))
(make-directory xdg t))
(eval (car (get 'temporary-file-directory 'standard-value)) t)))
@ -221,7 +221,7 @@ value is the default binding of the variable."
(if (not criteria)
,variable
(hack-connection-local-variables criteria)
(if-let ((result (assq ',variable connection-local-variables-alist)))
(if-let* ((result (assq ',variable connection-local-variables-alist)))
(cdr result)
,variable)))))

View file

@ -288,19 +288,19 @@ or `tramp-podmancp-method'.
This function is used by `tramp-set-completion-function', please
see its function help for a description of the format."
(tramp-skeleton-completion-function method
(when-let ((raw-list
(shell-command-to-string
(concat program " ps --format '{{.ID}}\t{{.Names}}'")))
(lines (split-string raw-list "\n" 'omit))
(names
(tramp-compat-seq-keep
(lambda (line)
(when (string-match
(rx bol (group (1+ nonl))
"\t" (? (group (1+ nonl))) eol)
line)
(or (match-string 2 line) (match-string 1 line))))
lines)))
(when-let* ((raw-list
(shell-command-to-string
(concat program " ps --format '{{.ID}}\t{{.Names}}'")))
(lines (split-string raw-list "\n" 'omit))
(names
(tramp-compat-seq-keep
(lambda (line)
(when (string-match
(rx bol (group (1+ nonl))
"\t" (? (group (1+ nonl))) eol)
line)
(or (match-string 2 line) (match-string 1 line))))
lines)))
(mapcar (lambda (name) (list nil name)) names))))
;;;###tramp-autoload
@ -310,19 +310,19 @@ see its function help for a description of the format."
This function is used by `tramp-set-completion-function', please
see its function help for a description of the format."
(tramp-skeleton-completion-function method
(when-let ((raw-list
(shell-command-to-string
(concat
program " "
(tramp-kubernetes--context-namespace vec)
" get pods --no-headers"
;; We separate pods by "|". Inside a pod, its name
;; is separated from the containers by ":".
;; Containers are separated by ",".
" -o jsonpath='{range .items[*]}{\"|\"}{.metadata.name}"
"{\":\"}{range .spec.containers[*]}{.name}{\",\"}"
"{end}{end}'")))
(lines (split-string raw-list "|" 'omit)))
(when-let* ((raw-list
(shell-command-to-string
(concat
program " "
(tramp-kubernetes--context-namespace vec)
" get pods --no-headers"
;; We separate pods by "|". Inside a pod, its name
;; is separated from the containers by ":".
;; Containers are separated by ",".
" -o jsonpath='{range .items[*]}{\"|\"}{.metadata.name}"
"{\":\"}{range .spec.containers[*]}{.name}{\",\"}"
"{end}{end}'")))
(lines (split-string raw-list "|" 'omit)))
(let (names)
(dolist (line lines)
(setq line (split-string line ":" 'omit))
@ -349,16 +349,16 @@ see its function help for a description of the format."
;;;###tramp-autoload
(defun tramp-kubernetes--container (vec)
"Extract the container name from a kubernetes host name in VEC."
(or (when-let ((host (and vec (tramp-file-name-host vec)))
((string-match tramp-kubernetes--host-name-regexp host)))
(or (when-let* ((host (and vec (tramp-file-name-host vec)))
((string-match tramp-kubernetes--host-name-regexp host)))
(match-string 1 host))
""))
;;;###tramp-autoload
(defun tramp-kubernetes--pod (vec)
"Extract the pod name from a kubernetes host name in VEC."
(or (when-let ((host (and vec (tramp-file-name-host vec)))
((string-match tramp-kubernetes--host-name-regexp host)))
(or (when-let* ((host (and vec (tramp-file-name-host vec)))
((string-match tramp-kubernetes--host-name-regexp host)))
(match-string 2 host))
""))
@ -366,8 +366,8 @@ see its function help for a description of the format."
(defun tramp-kubernetes--namespace (vec)
"Extract the namespace from a kubernetes host name in VEC.
Use `tramp-kubernetes-namespace' otherwise."
(or (when-let ((host (and vec (tramp-file-name-host vec)))
((string-match tramp-kubernetes--host-name-regexp host)))
(or (when-let* ((host (and vec (tramp-file-name-host vec)))
((string-match tramp-kubernetes--host-name-regexp host)))
(match-string 3 host))
tramp-kubernetes-namespace))
@ -413,7 +413,7 @@ Obey `tramp-kubernetes-context'"
(defun tramp-kubernetes--current-context-data (vec)
"Return Kubernetes current context data as JSON string."
(when-let ((current-context (tramp-kubernetes--current-context vec)))
(when-let* ((current-context (tramp-kubernetes--current-context vec)))
(tramp-skeleton-kubernetes-vector vec
(with-temp-buffer
(when (zerop
@ -430,9 +430,9 @@ Obey `tramp-kubernetes-context'"
(mapconcat
#'identity
(delq nil
`(,(when-let ((context (tramp-kubernetes--current-context vec)))
`(,(when-let* ((context (tramp-kubernetes--current-context vec)))
(format "--context=%s" context))
,(when-let ((namespace (tramp-kubernetes--namespace vec)))
,(when-let* ((namespace (tramp-kubernetes--namespace vec)))
(format "--namespace=%s" namespace))))
" "))
@ -443,18 +443,18 @@ Obey `tramp-kubernetes-context'"
This function is used by `tramp-set-completion-function', please
see its function help for a description of the format."
(tramp-skeleton-completion-function method
(when-let ((raw-list (shell-command-to-string (concat program " list -c")))
;; Ignore header line.
(lines (cdr (split-string raw-list "\n" 'omit)))
;; We do not show container IDs.
(names (tramp-compat-seq-keep
(lambda (line)
(when (string-match
(rx bol (1+ (not space))
(1+ space) (group (1+ (not space))) space)
line)
(match-string 1 line)))
lines)))
(when-let* ((raw-list (shell-command-to-string (concat program " list -c")))
;; Ignore header line.
(lines (cdr (split-string raw-list "\n" 'omit)))
;; We do not show container IDs.
(names (tramp-compat-seq-keep
(lambda (line)
(when (string-match
(rx bol (1+ (not space))
(1+ space) (group (1+ (not space))) space)
line)
(match-string 1 line)))
lines)))
(mapcar (lambda (name) (list nil name)) names))))
;;;###tramp-autoload
@ -464,19 +464,19 @@ see its function help for a description of the format."
This function is used by `tramp-set-completion-function', please
see its function help for a description of the format."
(tramp-skeleton-completion-function method
(when-let ((raw-list (shell-command-to-string (concat program " list")))
;; Ignore header line.
(lines (cdr (split-string raw-list "\n" 'omit)))
;; We do not show container IDs.
(names (tramp-compat-seq-keep
(lambda (line)
(when (string-match
(rx bol (1+ (not space))
(1+ space) "|" (1+ space)
(group (1+ (not space))) space)
line)
(match-string 1 line)))
lines)))
(when-let* ((raw-list (shell-command-to-string (concat program " list")))
;; Ignore header line.
(lines (cdr (split-string raw-list "\n" 'omit)))
;; We do not show container IDs.
(names (tramp-compat-seq-keep
(lambda (line)
(when (string-match
(rx bol (1+ (not space))
(1+ space) "|" (1+ space)
(group (1+ (not space))) space)
line)
(match-string 1 line)))
lines)))
(mapcar (lambda (name) (list nil name)) names))))
;;;###tramp-autoload
@ -488,19 +488,19 @@ ID, instance IDs.
This function is used by `tramp-set-completion-function', please
see its function help for a description of the format."
(tramp-skeleton-completion-function method
(when-let ((raw-list
(shell-command-to-string
;; Ignore header line.
(concat program " ps --columns=instance,application | cat -")))
(lines (split-string raw-list "\n" 'omit))
(names (tramp-compat-seq-keep
(lambda (line)
(when (string-match
(rx bol (* space) (group (+ (not space)))
(? (+ space) (group (+ (not space)))) eol)
line)
(or (match-string 2 line) (match-string 1 line))))
lines)))
(when-let* ((raw-list
(shell-command-to-string
;; Ignore header line.
(concat program " ps --columns=instance,application | cat -")))
(lines (split-string raw-list "\n" 'omit))
(names (tramp-compat-seq-keep
(lambda (line)
(when (string-match
(rx bol (* space) (group (+ (not space)))
(? (+ space) (group (+ (not space)))) eol)
line)
(or (match-string 2 line) (match-string 1 line))))
lines)))
(mapcar (lambda (name) (list nil name)) names))))
;;;###tramp-autoload
@ -510,19 +510,19 @@ see its function help for a description of the format."
This function is used by `tramp-set-completion-function', please
see its function help for a description of the format."
(tramp-skeleton-completion-function method
(when-let ((raw-list
(shell-command-to-string (concat program " instance list")))
;; Ignore header line.
(lines (cdr (split-string raw-list "\n" 'omit)))
(names (tramp-compat-seq-keep
(lambda (line)
(when (string-match
(rx bol (group (1+ (not space)))
(1+ space) (1+ (not space))
(1+ space) (1+ (not space)))
line)
(match-string 1 line)))
lines)))
(when-let* ((raw-list
(shell-command-to-string (concat program " instance list")))
;; Ignore header line.
(lines (cdr (split-string raw-list "\n" 'omit)))
(names (tramp-compat-seq-keep
(lambda (line)
(when (string-match
(rx bol (group (1+ (not space)))
(1+ space) (1+ (not space))
(1+ space) (1+ (not space)))
line)
(match-string 1 line)))
lines)))
(mapcar (lambda (name) (list nil name)) names))))
(defun tramp-nspawn--completion-function (method)
@ -531,13 +531,13 @@ see its function help for a description of the format."
This function is used by `tramp-set-completion-function', please
see its function help for a description of the format."
(tramp-skeleton-completion-function method
(when-let ((raw-list
(shell-command-to-string (concat program " list --all -q")))
;; Ignore header line.
(lines (cdr (split-string raw-list "\n")))
(first-words (mapcar (lambda (line) (car (split-string line)))
lines))
(machines (seq-take-while (lambda (name) name) first-words)))
(when-let* ((raw-list
(shell-command-to-string (concat program " list --all -q")))
;; Ignore header line.
(lines (cdr (split-string raw-list "\n")))
(first-words
(mapcar (lambda (line) (car (split-string line))) lines))
(machines (seq-take-while (lambda (name) name) first-words)))
(mapcar (lambda (m) (list nil m)) machines))))
;;;###tramp-autoload

View file

@ -281,10 +281,10 @@ arguments to pass to the OPERATION."
"Invoke the encrypted remote file related OPERATION.
First arg specifies the OPERATION, second arg is a list of
arguments to pass to the OPERATION."
(if-let ((filename
(apply #'tramp-crypt-file-name-for-operation operation args))
(fn (and (tramp-crypt-file-name-p filename)
(assoc operation tramp-crypt-file-name-handler-alist))))
(if-let* ((filename
(apply #'tramp-crypt-file-name-for-operation operation args))
((tramp-crypt-file-name-p filename))
(fn (assoc operation tramp-crypt-file-name-handler-alist)))
(prog1 (save-match-data (apply (cdr fn) args))
(setq tramp-debug-message-fnh-function (cdr fn)))
(prog1 (tramp-crypt-run-real-handler operation args)
@ -429,11 +429,11 @@ ARGS are the arguments. It returns t if ran successful, and nil otherwise."
"Return encrypted / decrypted NAME if NAME belongs to an encrypted directory.
OP must be `encrypt' or `decrypt'. Raise an error if this fails.
Otherwise, return NAME."
(if-let ((tramp-crypt-enabled t)
(dir (tramp-crypt-file-name-p name))
;; It must be absolute for the cache.
(localname (substring name (1- (length dir))))
(crypt-vec (tramp-crypt-dissect-file-name dir)))
(if-let* ((tramp-crypt-enabled t)
(dir (tramp-crypt-file-name-p name))
;; It must be absolute for the cache.
(localname (substring name (1- (length dir))))
(crypt-vec (tramp-crypt-dissect-file-name dir)))
;; Preserve trailing "/".
(funcall
(if (directory-name-p name) #'file-name-as-directory #'identity)
@ -469,9 +469,9 @@ Otherwise, return NAME."
Both files must be local files. OP must be `encrypt' or `decrypt'.
If OP is `decrypt', the basename of INFILE must be an encrypted file name.
Raise an error if this fails."
(when-let ((tramp-crypt-enabled t)
(dir (tramp-crypt-file-name-p root))
(crypt-vec (tramp-crypt-dissect-file-name dir)))
(when-let* ((tramp-crypt-enabled t)
(dir (tramp-crypt-file-name-p root))
(crypt-vec (tramp-crypt-dissect-file-name dir)))
(let ((coding-system-for-read
(if (eq op 'decrypt) 'binary coding-system-for-read))
(coding-system-for-write
@ -546,7 +546,7 @@ The structure consists of the `tramp-crypt-method' method, the
local user name, the hexlified directory NAME as host, and the
localname."
(save-match-data
(if-let ((dir (tramp-crypt-file-name-p name)))
(if-let* ((dir (tramp-crypt-file-name-p name)))
(make-tramp-file-name
:method tramp-crypt-method :user (user-login-name)
:host (url-hexify-string dir))

View file

@ -186,8 +186,8 @@ pass to the OPERATION."
;;;###tramp-autoload
(defsubst tramp-ftp-file-name-p (vec-or-filename)
"Check if it's a VEC-OR-FILENAME that should be forwarded to Ange-FTP."
(when-let* ((vec (tramp-ensure-dissected-file-name vec-or-filename)))
(string= (tramp-file-name-method vec) tramp-ftp-method)))
(and-let* ((vec (tramp-ensure-dissected-file-name vec-or-filename))
((string= (tramp-file-name-method vec) tramp-ftp-method)))))
;;;###tramp-autoload
(tramp--with-startup

View file

@ -128,8 +128,8 @@
(defun tramp-fuse-mount-spec (vec)
"Return local mount spec of VEC."
(if-let ((host (tramp-file-name-host vec))
(user (tramp-file-name-user vec)))
(if-let* ((host (tramp-file-name-host vec))
(user (tramp-file-name-user vec)))
(format "%s@%s:/" user host)
(format "%s:/" host)))

View file

@ -881,9 +881,9 @@ Operations not mentioned here will be handled by the default Emacs primitives.")
;;;###tramp-autoload
(defsubst tramp-gvfs-file-name-p (vec-or-filename)
"Check if it's a VEC-OR-FILENAME handled by the GVFS daemon."
(when-let* ((vec (tramp-ensure-dissected-file-name vec-or-filename)))
(let ((method (tramp-file-name-method vec)))
(and (stringp method) (member method tramp-gvfs-methods)))))
(and-let* ((vec (tramp-ensure-dissected-file-name vec-or-filename))
(method (tramp-file-name-method vec))
((member method tramp-gvfs-methods)))))
;;;###tramp-autoload
(defun tramp-gvfs-file-name-handler (operation &rest args)
@ -893,11 +893,11 @@ arguments to pass to the OPERATION."
;; `file-remote-p' must not return an error. (Bug#68976)
(unless (or tramp-gvfs-enabled (eq operation 'file-remote-p))
(tramp-user-error nil "Package `tramp-gvfs' not supported"))
(if-let ((filename (apply #'tramp-file-name-for-operation operation args))
(tramp-gvfs-dbus-event-vector
(and (tramp-tramp-file-p filename)
(tramp-dissect-file-name filename)))
(fn (assoc operation tramp-gvfs-file-name-handler-alist)))
(if-let* ((filename (apply #'tramp-file-name-for-operation operation args))
(tramp-gvfs-dbus-event-vector
(and (tramp-tramp-file-p filename)
(tramp-dissect-file-name filename)))
(fn (assoc operation tramp-gvfs-file-name-handler-alist)))
(prog1 (save-match-data (apply (cdr fn) args))
(setq tramp-debug-message-fnh-function (cdr fn)))
(prog1 (tramp-run-real-handler operation args)
@ -930,9 +930,9 @@ arguments to pass to the OPERATION."
"Like `dbus-byte-array-to-string' but remove trailing \\0 if exists.
Return nil for null BYTE-ARRAY."
;; The byte array could be a variant. Take care.
(when-let ((byte-array
(if (and (consp byte-array) (atom (car byte-array)))
byte-array (car byte-array))))
(when-let* ((byte-array
(if (and (consp byte-array) (atom (car byte-array)))
byte-array (car byte-array))))
(dbus-byte-array-to-string
(if (and (consp byte-array) (zerop (car (last byte-array))))
(butlast byte-array) byte-array))))
@ -1405,7 +1405,7 @@ If FILE-SYSTEM is non-nil, return file system attributes."
(or (cdr (assoc "standard::size" attributes)) "0")))
;; ... file mode flags
(setq res-filemodes
(if-let ((n (cdr (assoc "unix::mode" attributes))))
(if-let* ((n (cdr (assoc "unix::mode" attributes))))
(tramp-file-mode-from-int (string-to-number n))
(format
"%s%s%s%s------"
@ -1421,11 +1421,11 @@ If FILE-SYSTEM is non-nil, return file system attributes."
"-" "x"))))
;; ... inode and device
(setq res-inode
(if-let ((n (cdr (assoc "unix::inode" attributes))))
(if-let* ((n (cdr (assoc "unix::inode" attributes))))
(string-to-number n)
(tramp-get-inode (tramp-dissect-file-name filename))))
(setq res-device
(if-let ((n (cdr (assoc "unix::device" attributes))))
(if-let* ((n (cdr (assoc "unix::device" attributes))))
(string-to-number n)
(tramp-get-device (tramp-dissect-file-name filename))))
@ -1675,19 +1675,21 @@ ID-FORMAT valid values are `string' and `integer'."
;; The result is cached in `tramp-get-remote-uid'.
(if (equal id-format 'string)
(tramp-file-name-user vec)
(when-let ((localname
(tramp-get-connection-property (tramp-get-process vec) "share")))
(file-attribute-user-id
(file-attributes (tramp-make-tramp-file-name vec localname) id-format)))))
(and-let* ((localname
(tramp-get-connection-property (tramp-get-process vec) "share"))
((file-attribute-user-id
(file-attributes
(tramp-make-tramp-file-name vec localname) id-format)))))))
(defun tramp-gvfs-handle-get-remote-gid (vec id-format)
"The gid of the remote connection VEC, in ID-FORMAT.
ID-FORMAT valid values are `string' and `integer'."
;; The result is cached in `tramp-get-remote-gid'.
(when-let ((localname
(tramp-get-connection-property (tramp-get-process vec) "share")))
(file-attribute-group-id
(file-attributes (tramp-make-tramp-file-name vec localname) id-format))))
(and-let* ((localname
(tramp-get-connection-property (tramp-get-process vec) "share"))
((file-attribute-group-id
(file-attributes
(tramp-make-tramp-file-name vec localname) id-format))))))
(defun tramp-gvfs-handle-set-file-uid-gid (filename &optional uid gid)
"Like `tramp-set-file-uid-gid' for Tramp files."
@ -1720,12 +1722,12 @@ ID-FORMAT valid values are `string' and `integer'."
(setq method "davs"
localname
(concat (tramp-gvfs-get-remote-prefix v) localname)))
(when (string-equal "mtp" method)
(when-let
((media (tramp-get-connection-property v "media-device")))
(setq method (tramp-media-device-method media)
host (tramp-media-device-host media)
port (tramp-media-device-port media))))
(when-let*
(((string-equal "mtp" method))
(media (tramp-get-connection-property v "media-device")))
(setq method (tramp-media-device-method media)
host (tramp-media-device-host media)
port (tramp-media-device-port media)))
(when (and user domain)
(setq user (concat domain ";" user)))
(url-recreate-url
@ -1922,10 +1924,10 @@ Their full names are \"org.gtk.vfs.MountTracker.mounted\" and
(when (member method tramp-media-methods)
;; Ensure that media devices are cached.
(tramp-get-media-devices nil)
(when-let ((v (tramp-get-connection-property
(make-tramp-media-device
:method method :host host :port port)
"vector" nil)))
(when-let* ((v (tramp-get-connection-property
(make-tramp-media-device
:method method :host host :port port)
"vector" nil)))
(setq method (tramp-file-name-method v)
host (tramp-file-name-host v)
port (tramp-file-name-port v))))
@ -2022,10 +2024,10 @@ Their full names are \"org.gtk.vfs.MountTracker.mounted\" and
(when (member method tramp-media-methods)
;; Ensure that media devices are cached.
(tramp-get-media-devices vec)
(when-let ((v (tramp-get-connection-property
(make-tramp-media-device
:method method :host host :port port)
"vector")))
(when-let* ((v (tramp-get-connection-property
(make-tramp-media-device
:method method :host host :port port)
"vector")))
(setq method (tramp-file-name-method v)
host (tramp-file-name-host v)
port (tramp-file-name-port v))))
@ -2440,8 +2442,8 @@ It checks for registered GNOME Online Accounts."
(defun tramp-get-media-device (vec)
"Transform VEC into a `tramp-media-device' structure.
Check, that respective cache values do exist."
(if-let ((media (tramp-get-connection-property vec "media-device"))
(prop (tramp-get-connection-property media "vector")))
(if-let* ((media (tramp-get-connection-property vec "media-device"))
(prop (tramp-get-connection-property media "vector")))
media
(tramp-get-media-devices vec)
(tramp-get-connection-property vec "media-device")))

View file

@ -578,11 +578,11 @@ See `tramp-process-attributes-ps-format'.")
;; Preset default "ps" profile for local hosts, based on system type.
(when-let ((local-profile
(cond ((eq system-type 'darwin)
'tramp-connection-local-darwin-ps-profile)
;; ... Add other system types here.
)))
(when-let* ((local-profile
(cond ((eq system-type 'darwin)
'tramp-connection-local-darwin-ps-profile)
;; ... Add other system types here.
)))
(connection-local-set-profiles
`(:application tramp :machine ,(system-name))
local-profile)

View file

@ -485,7 +485,7 @@ to `tramp-message'."
"Goto the linked message in debug buffer at place."
(declare (tramp-suppress-trace t))
(when (mouse-event-p last-input-event) (mouse-set-point last-input-event))
(when-let ((point (button-get button 'position)))
(when-let* ((point (button-get button 'position)))
(goto-char point)))
(define-button-type 'tramp-debug-button-type

View file

@ -167,15 +167,15 @@ Operations not mentioned here will be handled by the default Emacs primitives.")
;;;###tramp-autoload
(defsubst tramp-rclone-file-name-p (vec-or-filename)
"Check if it's a VEC-OR-FILENAME for rclone."
(when-let* ((vec (tramp-ensure-dissected-file-name vec-or-filename)))
(string= (tramp-file-name-method vec) tramp-rclone-method)))
(and-let* ((vec (tramp-ensure-dissected-file-name vec-or-filename))
((string= (tramp-file-name-method vec) tramp-rclone-method)))))
;;;###tramp-autoload
(defun tramp-rclone-file-name-handler (operation &rest args)
"Invoke the rclone handler for OPERATION and ARGS.
First arg specifies the OPERATION, second arg is a list of
arguments to pass to the OPERATION."
(if-let ((fn (assoc operation tramp-rclone-file-name-handler-alist)))
(if-let* ((fn (assoc operation tramp-rclone-file-name-handler-alist)))
(prog1 (save-match-data (apply (cdr fn) args))
(setq tramp-debug-message-fnh-function (cdr fn)))
(prog1 (tramp-run-real-handler operation args)

View file

@ -1812,7 +1812,7 @@ ID-FORMAT valid values are `string' and `integer'."
;; be expected that this is always a directory.
(or (tramp-string-empty-or-nil-p localname)
(with-tramp-file-property v localname "file-directory-p"
(if-let
(if-let*
((truename (tramp-get-file-property v localname "file-truename"))
((tramp-file-property-p
v (tramp-file-local-name truename) "file-attributes")))
@ -2231,8 +2231,8 @@ file names."
;; Handle `preserve-extended-attributes'. We ignore
;; possible errors, because ACL strings could be
;; incompatible.
(when-let ((attributes (and preserve-extended-attributes
(file-extended-attributes filename))))
(when-let* ((attributes (and preserve-extended-attributes
(file-extended-attributes filename))))
(ignore-errors
(set-file-extended-attributes newname attributes)))
@ -2868,7 +2868,7 @@ The method used must be an out-of-band method."
(rx bol (group (* blank) "total")) nil t)
;; Emacs 29.1 or later.
(not (fboundp 'dired--insert-disk-space)))
(when-let ((available (get-free-disk-space ".")))
(when-let* ((available (get-free-disk-space ".")))
;; Replace "total" with "total used", to avoid confusion.
(replace-match "\\1 used in directory")
(end-of-line)
@ -3313,7 +3313,7 @@ will be used."
(defun tramp-sh-handle-file-local-copy (filename)
"Like `file-local-copy' for Tramp files."
(tramp-skeleton-file-local-copy filename
(if-let ((size (file-attribute-size (file-attributes filename))))
(if-let* ((size (file-attribute-size (file-attributes filename))))
(let (rem-enc loc-dec)
(condition-case err
@ -3627,14 +3627,14 @@ filled are described in `tramp-bundle-read-file-names'."
;; requires a remote command (the file cache must be invalidated).
;; Therefore, we apply a kind of optimization. We install the file
;; name handler `tramp-vc-file-name-handler', which does nothing but
;; remembers all file names for which `file-exists-p' or
;; `file-readable-p' has been applied. A first run of `vc-registered'
;; is performed. Afterwards, a script is applied for all collected
;; file names, using just one remote command. The result of this
;; script is used to fill the file cache with actual values. Now we
;; can reset the file name handlers, and we make a second run of
;; `vc-registered', which returns the expected result without sending
;; any other remote command.
;; remembers all file names for which `file-exists-p',
;; `file-readable-p' or `file-directory-p' has been applied. A first
;; run of `vc-registered' is performed. Afterwards, a script is
;; applied for all collected file names, using just one remote
;; command. The result of this script is used to fill the file cache
;; with actual values. Now we can reset the file name handlers, and
;; we make a second run of `vc-registered', which returns the expected
;; result without sending any other remote command.
;; When called during `revert-buffer', it shouldn't spam the echo area
;; and the *Messages* buffer.
(defun tramp-sh-handle-vc-registered (file)
@ -3666,10 +3666,11 @@ filled are described in `tramp-bundle-read-file-names'."
;; Send just one command, in order to fill the cache.
(tramp-bundle-read-file-names v tramp-vc-registered-file-names))
;; Second run. Now all `file-exists-p' or `file-readable-p'
;; calls shall be answered from the file cache. We unset
;; `process-file-side-effects' and `remote-file-name-inhibit-cache'
;; in order to keep the cache.
;; Second run. Now all `file-exists-p', `file-readable-p'
;; or `file-directory-p' calls shall be answered from the
;; file cache. We unset `process-file-side-effects' and
;; `remote-file-name-inhibit-cache' in order to keep the
;; cache.
(let ((vc-handled-backends (copy-sequence vc-handled-backends))
remote-file-name-inhibit-cache process-file-side-effects)
;; Reduce `vc-handled-backends' in order to minimize
@ -3704,7 +3705,7 @@ filled are described in `tramp-bundle-read-file-names'."
(defun tramp-sh-file-name-handler (operation &rest args)
"Invoke remote-shell Tramp file name handler.
Fall back to normal file name handler if no Tramp handler exists."
(if-let ((fn (assoc operation tramp-sh-file-name-handler-alist)))
(if-let* ((fn (assoc operation tramp-sh-file-name-handler-alist)))
(prog1 (save-match-data (apply (cdr fn) args))
(setq tramp-debug-message-fnh-function (cdr fn)))
(prog1 (tramp-run-real-handler operation args)
@ -3726,35 +3727,35 @@ Fall back to normal file name handler if no Tramp handler exists."
(defun tramp-vc-file-name-handler (operation &rest args)
"Invoke special file name handler, which collects files to be handled."
(save-match-data
(let ((filename
(tramp-replace-environment-variables
(apply #'tramp-file-name-for-operation operation args)))
(fn (assoc operation tramp-sh-file-name-handler-alist)))
(if (tramp-tramp-file-p filename)
(with-parsed-tramp-file-name filename nil
(cond
;; That's what we want: file names, for which checks are
;; applied. We assume that VC uses only `file-exists-p'
;; `file-readable-p' and `file-directory-p' checks;
;; otherwise we must extend the list. We do not perform
;; any action, but return nil, in order to keep
;; `vc-registered' running.
((and fn (memq operation
'(file-exists-p file-readable-p file-directory-p)))
(add-to-list 'tramp-vc-registered-file-names localname 'append)
nil)
;; `process-file' and `start-file-process' shall be ignored.
((and fn (eq operation 'process-file) 0))
((and fn (eq operation 'start-file-process) nil))
;; Tramp file name handlers like `expand-file-name'. They
;; must still work.
(fn (save-match-data (apply (cdr fn) args)))
;; Default file name handlers, we don't care.
(t (tramp-run-real-handler operation args))))
(if-let* ((filename
(tramp-replace-environment-variables
(apply #'tramp-file-name-for-operation operation args)))
((tramp-tramp-file-p filename))
(fn (assoc operation tramp-sh-file-name-handler-alist)))
(with-parsed-tramp-file-name filename nil
(cond
;; That's what we want: file names, for which checks are
;; applied. We assume that VC uses only `file-exists-p',
;; `file-readable-p' and `file-directory-p' checks;
;; otherwise we must extend the list. The respective cache
;; value must be set for these functions in
;; `tramp-bundle-read-file-names'.
;; We do not perform any action, but return nil, in order
;; to keep `vc-registered' running.
((memq operation '(file-exists-p file-readable-p file-directory-p))
(add-to-list 'tramp-vc-registered-file-names localname 'append)
nil)
;; `process-file' and `start-file-process' shall be ignored.
((eq operation 'process-file) 0)
((eq operation 'start-file-process) nil)
;; Tramp file name handlers like `expand-file-name'. They
;; must still work.
(t (save-match-data (apply (cdr fn) args)))))
;; When `tramp-mode' is not enabled, or the file name is
;; quoted, we don't do anything.
(tramp-run-real-handler operation args)))))
;; When `tramp-mode' is not enabled, or the file name is not a
;; remote file name, we don't do anything. Same for default
;; file namne handlers.
(tramp-run-real-handler operation args))))
(defun tramp-sh-handle-file-notify-add-watch (file-name flags _callback)
"Like `file-notify-add-watch' for Tramp files."
@ -5258,9 +5259,9 @@ connection if a previous connection has died for some reason."
:host l-host :port l-port)))
;; Set session timeout.
(when-let ((timeout
(tramp-get-method-parameter
hop 'tramp-session-timeout)))
(when-let* ((timeout
(tramp-get-method-parameter
hop 'tramp-session-timeout)))
(tramp-set-connection-property
p "session-timeout" timeout))
@ -5908,37 +5909,37 @@ Nonexistent directories are removed from spec."
(with-tramp-connection-property vec "awk"
(tramp-message vec 5 "Finding a suitable `awk' command")
(or (tramp-find-executable vec "awk" (tramp-get-remote-path vec))
(let* ((busybox (tramp-get-remote-busybox vec))
(command (format "%s %s" busybox "awk")))
(and busybox
(tramp-send-command-and-check
vec (concat command " {} <" (tramp-get-remote-null-device vec)))
command)))))
(when-let*
((busybox (tramp-get-remote-busybox vec))
(command (format "%s %s" busybox "awk"))
((tramp-send-command-and-check
vec (concat command " {} <" (tramp-get-remote-null-device vec)))))
command))))
(defun tramp-get-remote-hexdump (vec)
"Determine remote `hexdump' command."
(with-tramp-connection-property vec "hexdump"
(tramp-message vec 5 "Finding a suitable `hexdump' command")
(or (tramp-find-executable vec "hexdump" (tramp-get-remote-path vec))
(let* ((busybox (tramp-get-remote-busybox vec))
(command (format "%s %s" busybox "hexdump")))
(and busybox
(tramp-send-command-and-check
vec (concat command " <" (tramp-get-remote-null-device vec)))
command)))))
(when-let*
((busybox (tramp-get-remote-busybox vec))
(command (format "%s %s" busybox "hexdump"))
((tramp-send-command-and-check
vec (concat command " <" (tramp-get-remote-null-device vec)))))
command))))
(defun tramp-get-remote-od (vec)
"Determine remote `od' command."
(with-tramp-connection-property vec "od"
(tramp-message vec 5 "Finding a suitable `od' command")
(or (tramp-find-executable vec "od" (tramp-get-remote-path vec))
(let* ((busybox (tramp-get-remote-busybox vec))
(command (format "%s %s" busybox "od")))
(and busybox
(tramp-send-command-and-check
vec
(concat command " -A n <" (tramp-get-remote-null-device vec)))
command)))))
(when-let*
((busybox (tramp-get-remote-busybox vec))
(command (format "%s %s" busybox "od"))
((tramp-send-command-and-check
vec
(concat command " -A n <" (tramp-get-remote-null-device vec)))))
command))))
(defun tramp-get-remote-chmod-h (vec)
"Check whether remote `chmod' supports nofollow argument."

View file

@ -340,15 +340,15 @@ This can be used to disable echo etc."
;;;###tramp-autoload
(defsubst tramp-smb-file-name-p (vec-or-filename)
"Check if it's a VEC-OR-FILENAME for SMB servers."
(when-let* ((vec (tramp-ensure-dissected-file-name vec-or-filename)))
(string= (tramp-file-name-method vec) tramp-smb-method)))
(and-let* ((vec (tramp-ensure-dissected-file-name vec-or-filename))
((string= (tramp-file-name-method vec) tramp-smb-method)))))
;;;###tramp-autoload
(defun tramp-smb-file-name-handler (operation &rest args)
"Invoke the SMB related OPERATION and ARGS.
First arg specifies the OPERATION, second arg is a list of
arguments to pass to the OPERATION."
(if-let ((fn (assoc operation tramp-smb-file-name-handler-alist)))
(if-let* ((fn (assoc operation tramp-smb-file-name-handler-alist)))
(prog1 (save-match-data (apply (cdr fn) args))
(setq tramp-debug-message-fnh-function (cdr fn)))
(prog1 (tramp-run-real-handler operation args)
@ -613,8 +613,8 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored."
;; `file-local-copy' returns a file name also for a local file
;; with `jka-compr-handler', so we cannot trust its result as
;; indication for a remote file name.
(if-let ((tmpfile
(and (tramp-tramp-file-p filename) (file-local-copy filename))))
(if-let* ((tmpfile
(and (tramp-tramp-file-p filename) (file-local-copy filename))))
;; Remote filename.
(condition-case err
(rename-file tmpfile newname ok-if-already-exists)
@ -860,7 +860,7 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored."
"Implement `file-attributes' for Tramp files using `stat' command."
(tramp-message
vec 5 "file attributes with stat: %s" (tramp-file-name-localname vec))
(let* (size id link uid gid atime mtime ctime mode inode)
(let (size id link uid gid atime mtime ctime mode inode)
(when (tramp-smb-send-command
vec (format "stat %s" (tramp-smb-shell-quote-localname vec)))

View file

@ -170,15 +170,15 @@ Operations not mentioned here will be handled by the default Emacs primitives.")
;;;###tramp-autoload
(defsubst tramp-sshfs-file-name-p (vec-or-filename)
"Check if it's a VEC-OR-FILENAME for sshfs."
(when-let* ((vec (tramp-ensure-dissected-file-name vec-or-filename)))
(string= (tramp-file-name-method vec) tramp-sshfs-method)))
(and-let* ((vec (tramp-ensure-dissected-file-name vec-or-filename))
((string= (tramp-file-name-method vec) tramp-sshfs-method)))))
;;;###tramp-autoload
(defun tramp-sshfs-file-name-handler (operation &rest args)
"Invoke the sshfs handler for OPERATION and ARGS.
First arg specifies the OPERATION, second arg is a list of
arguments to pass to the OPERATION."
(if-let ((fn (assoc operation tramp-sshfs-file-name-handler-alist)))
(if-let* ((fn (assoc operation tramp-sshfs-file-name-handler-alist)))
(prog1 (save-match-data (apply (cdr fn) args))
(setq tramp-debug-message-fnh-function (cdr fn)))
(prog1 (tramp-run-real-handler operation args)

View file

@ -161,15 +161,15 @@ See `tramp-actions-before-shell' for more info.")
;;;###tramp-autoload
(defsubst tramp-sudoedit-file-name-p (vec-or-filename)
"Check if it's a VEC-OR-FILENAME for SUDOEDIT."
(when-let* ((vec (tramp-ensure-dissected-file-name vec-or-filename)))
(string= (tramp-file-name-method vec) tramp-sudoedit-method)))
(and-let* ((vec (tramp-ensure-dissected-file-name vec-or-filename))
((string= (tramp-file-name-method vec) tramp-sudoedit-method)))))
;;;###tramp-autoload
(defun tramp-sudoedit-file-name-handler (operation &rest args)
"Invoke the SUDOEDIT handler for OPERATION and ARGS.
First arg specifies the OPERATION, second arg is a list of
arguments to pass to the OPERATION."
(if-let ((fn (assoc operation tramp-sudoedit-file-name-handler-alist)))
(if-let* ((fn (assoc operation tramp-sudoedit-file-name-handler-alist)))
(prog1 (save-match-data (apply (cdr fn) args))
(setq tramp-debug-message-fnh-function (cdr fn)))
(prog1 (tramp-run-real-handler operation args)

View file

@ -1610,9 +1610,9 @@ entry does not exist, return DEFAULT."
;; We use the cached property.
(tramp-get-connection-property vec hash-entry)
;; Use the static value from `tramp-methods'.
(if-let ((methods-entry
(assoc
param (assoc (tramp-file-name-method vec) tramp-methods))))
(if-let* ((methods-entry
(assoc
param (assoc (tramp-file-name-method vec) tramp-methods))))
(cadr methods-entry)
;; Return the default value.
default))))
@ -2128,9 +2128,9 @@ without a visible progress reporter."
;; We start a pulsing progress reporter after 3 seconds.
;; Start only when there is no other progress reporter
;; running, and when there is a minimum level.
(when-let ((pr (and (null tramp-inhibit-progress-reporter)
(<= ,level (min tramp-verbose 3))
(make-progress-reporter ,message))))
(when-let* ((pr (and (null tramp-inhibit-progress-reporter)
(<= ,level (min tramp-verbose 3))
(make-progress-reporter ,message))))
(run-at-time 3 0.1 #'tramp-progress-reporter-update pr))))
(unwind-protect
;; Execute the body.
@ -2152,8 +2152,8 @@ without a visible progress reporter."
(let ((seconds (car list))
(timeout-forms (cdr list)))
;; If non-nil, `seconds' must be a positive number.
`(if-let (((natnump ,seconds))
((not (zerop timeout))))
`(if-let* (((natnump ,seconds))
((not (zerop timeout))))
(with-timeout (,seconds ,@timeout-forms) ,@body)
,@body)))
@ -2538,7 +2538,7 @@ Fall back to normal file name handler if no Tramp file name handler exists."
(defun tramp-completion-file-name-handler (operation &rest args)
"Invoke Tramp file name completion handler for OPERATION and ARGS.
Falls back to normal file name handler if no Tramp file name handler exists."
(if-let
(if-let*
((fn (and tramp-mode minibuffer-completing-file-name
(assoc operation tramp-completion-file-name-handler-alist))))
(save-match-data (apply (cdr fn) args))
@ -2634,7 +2634,7 @@ remote file names."
;; If jka-compr or epa-file are already loaded, move them to the
;; front of `file-name-handler-alist'.
(dolist (fnh '(epa-file-handler jka-compr-handler))
(when-let ((entry (rassoc fnh file-name-handler-alist)))
(when-let* ((entry (rassoc fnh file-name-handler-alist)))
(setq file-name-handler-alist
(cons entry (delete entry file-name-handler-alist))))))
@ -3870,7 +3870,7 @@ BODY is the backend specific code."
(let (last-coding-system-used (need-chown t))
;; Set file modification time.
(when (or (eq ,visit t) (stringp ,visit))
(when-let ((file-attr (file-attributes filename 'integer)))
(when-let* ((file-attr (file-attributes filename 'integer)))
(set-visited-file-modtime
;; We must pass modtime explicitly, because FILENAME
;; can be different from (buffer-file-name), f.e. if
@ -3983,9 +3983,9 @@ Let-bind it when necessary.")
(tramp-dont-suspend-timers t))
(with-tramp-timeout
(timeout
(unless (when-let ((p (tramp-get-connection-process v)))
(and (process-live-p p)
(tramp-get-connection-property p "connected")))
(unless (and-let* ((p (tramp-get-connection-process v))
((process-live-p p))
((tramp-get-connection-property p "connected"))))
(tramp-cleanup-connection v 'keep-debug 'keep-password))
(tramp-error
v 'file-error
@ -4164,8 +4164,8 @@ Let-bind it when necessary.")
(defun tramp-handle-file-modes (filename &optional flag)
"Like `file-modes' for Tramp files."
(when-let ((attrs (file-attributes filename))
(mode-string (file-attribute-modes attrs)))
(when-let* ((attrs (file-attributes filename))
(mode-string (file-attribute-modes attrs)))
(if (and (not (eq flag 'nofollow)) (eq ?l (aref mode-string 0)))
(file-modes (file-truename filename))
(tramp-mode-string-to-int mode-string))))
@ -4304,10 +4304,10 @@ Let-bind it when necessary.")
(or (tramp-check-cached-permissions v ?r)
;; `tramp-check-cached-permissions' doesn't handle symbolic
;; links.
(when-let ((symlink (file-symlink-p filename)))
(and (stringp symlink)
(file-readable-p
(concat (file-remote-p filename) symlink))))))))
(and-let* ((symlink (file-symlink-p filename))
((stringp symlink))
((file-readable-p
(concat (file-remote-p filename) symlink)))))))))
(defun tramp-handle-file-regular-p (filename)
"Like `file-regular-p' for Tramp files."
@ -4317,7 +4317,7 @@ Let-bind it when necessary.")
;; because `file-truename' could raise an error for cyclic
;; symlinks.
(ignore-errors
(when-let ((attr (file-attributes filename)))
(when-let* ((attr (file-attributes filename)))
(cond
((eq ?- (aref (file-attribute-modes attr) 0)))
((eq ?l (aref (file-attribute-modes attr) 0))
@ -4759,7 +4759,7 @@ It is not guaranteed, that all process attributes as described in
(defun tramp-get-lock-file (file)
"Read lockfile info of FILE.
Return nil when there is no lockfile."
(when-let ((lockname (make-lock-file-name file)))
(when-let* ((lockname (make-lock-file-name file)))
(or (file-symlink-p lockname)
(and (file-readable-p lockname)
(with-temp-buffer
@ -4790,8 +4790,8 @@ Do not set it manually, it is used buffer-local in `tramp-get-lock-pid'.")
(defun tramp-handle-file-locked-p (file)
"Like `file-locked-p' for Tramp files."
(when-let ((info (tramp-get-lock-file file))
(match (string-match tramp-lock-file-info-regexp info)))
(when-let* ((info (tramp-get-lock-file file))
(match (string-match tramp-lock-file-info-regexp info)))
(or ; Locked by me.
(and (string-equal (match-string 1 info) (user-login-name))
(string-equal (match-string 2 info) tramp-system-name)
@ -4813,20 +4813,20 @@ Do not set it manually, it is used buffer-local in `tramp-get-lock-pid'.")
;; for remote files.
(ask-user-about-supersession-threat file))
(when-let ((info (tramp-get-lock-file file))
(match (string-match tramp-lock-file-info-regexp info)))
(when-let* ((info (tramp-get-lock-file file))
(match (string-match tramp-lock-file-info-regexp info)))
(unless (ask-user-about-lock
file (format
"%s@%s (pid %s)" (match-string 1 info)
(match-string 2 info) (match-string 3 info)))
(throw 'dont-lock nil)))
(when-let ((lockname (make-lock-file-name file))
;; USER@HOST.PID[:BOOT_TIME]
(info
(format
"%s@%s.%s" (user-login-name) tramp-system-name
(tramp-get-lock-pid file))))
(when-let* ((lockname (make-lock-file-name file))
;; USER@HOST.PID[:BOOT_TIME]
(info
(format
"%s@%s.%s" (user-login-name) tramp-system-name
(tramp-get-lock-pid file))))
;; Protect against security hole.
(with-parsed-tramp-file-name file nil
@ -4866,9 +4866,9 @@ Do not set it manually, it is used buffer-local in `tramp-get-lock-pid'.")
;; When there is no connection, we don't do it. Otherwise,
;; functions like `kill-buffer' would try to reestablish the
;; connection. See Bug#61663.
(if-let ((v (tramp-dissect-file-name file))
((process-live-p (tramp-get-process v)))
(lockname (make-lock-file-name file)))
(if-let* ((v (tramp-dissect-file-name file))
((process-live-p (tramp-get-process v)))
(lockname (make-lock-file-name file)))
(delete-file lockname)
;; Trigger the unlock error. Be quiet if user isn't
;; interested in lock files. See Bug#70900.
@ -4912,8 +4912,8 @@ Do not set it manually, it is used buffer-local in `tramp-get-lock-pid'.")
(defun tramp-add-hops (vec)
"Add ad-hoc proxy definitions to `tramp-default-proxies-alist'."
(when-let ((hops (tramp-file-name-hop vec))
(item vec))
(when-let* ((hops (tramp-file-name-hop vec))
(item vec))
(let (signal-hook-function changed)
(dolist
(proxy (reverse (split-string hops tramp-postfix-hop-regexp 'omit)))
@ -5126,13 +5126,13 @@ should be set connection-local.")
elt (default-toplevel-value 'process-environment))))
(setq env (cons elt env)))))
;; Add remote path if exists.
(env (if-let ((sh-file-name-handler-p)
(remote-path
(string-join (tramp-get-remote-path v) ":")))
(env (if-let* ((sh-file-name-handler-p)
(remote-path
(string-join (tramp-get-remote-path v) ":")))
(setenv-internal env "PATH" remote-path 'keep)
env))
;; Add HISTFILE if indicated.
(env (if-let ((sh-file-name-handler-p))
(env (if sh-file-name-handler-p
(cond
((stringp tramp-histfile-override)
(setenv-internal
@ -5964,8 +5964,8 @@ If the user quits via `C-g', it is propagated up to `tramp-file-name-handler'."
;; communication. This could block the output for the current
;; process. Read such output first. (Bug#61350)
;; The process property isn't set anymore due to Bug#62194.
(when-let (((process-get proc 'tramp-shared-socket))
(v (process-get proc 'tramp-vector)))
(when-let* (((process-get proc 'tramp-shared-socket))
(v (process-get proc 'tramp-vector)))
(dolist (p (delq proc (process-list)))
(when (tramp-file-name-equal-p v (process-get p 'tramp-vector))
(with-tramp-suspended-timers
@ -6277,10 +6277,10 @@ depending whether FILENAME is remote or local. Both parameters
must be non-negative integers.
The setgid bit of the upper directory is respected.
If FILENAME is remote, a file name handler is called."
(let* ((dir (file-name-directory filename))
(modes (file-modes dir)))
(when (and modes (not (zerop (logand modes #o2000))))
(setq gid (file-attribute-group-id (file-attributes dir)))))
(when-let* ((dir (file-name-directory filename))
(modes (file-modes dir))
((not (zerop (logand modes #o2000)))))
(setq gid (file-attribute-group-id (file-attributes dir))))
(if (tramp-tramp-file-p filename)
(funcall (if (tramp-crypt-file-name-p filename)
@ -6338,14 +6338,14 @@ VEC is used for tracing."
"Check `file-attributes' caches for VEC.
Return t if according to the cache access type ACCESS is known to
be granted."
(when-let ((offset (cond
((eq ?r access) 1)
((eq ?w access) 2)
((eq ?x access) 3)
((eq ?s access) 3)))
(file-attr (file-attributes (tramp-make-tramp-file-name vec)))
(remote-uid (tramp-get-remote-uid vec 'integer))
(remote-gid (tramp-get-remote-gid vec 'integer)))
(when-let* ((offset (cond
((eq ?r access) 1)
((eq ?w access) 2)
((eq ?x access) 3)
((eq ?s access) 3)))
(file-attr (file-attributes (tramp-make-tramp-file-name vec)))
(remote-uid (tramp-get-remote-uid vec 'integer))
(remote-gid (tramp-get-remote-gid vec 'integer)))
(or
;; Not a symlink.
(eq t (file-attribute-type file-attr))
@ -6384,103 +6384,103 @@ to cache the result. Return the modified ATTR."
(declare (indent 3) (debug t))
`(with-tramp-file-property
,vec ,localname (format "file-attributes-%s" (or ,id-format 'integer))
(when-let
((result
(when-let*
((attr ,attr)
(result
(with-tramp-file-property ,vec ,localname "file-attributes"
(when-let ((attr ,attr))
(save-match-data
;; Remove ANSI control escape sequences from symlink.
(save-match-data
;; Remove ANSI control escape sequences from symlink.
(when (stringp (car attr))
(while (string-match ansi-color-control-seq-regexp (car attr))
(setcar attr (replace-match "" nil nil (car attr)))))
;; Convert uid and gid. Use `tramp-unknown-id-integer'
;; as indication of unusable value.
(when (consp (nth 2 attr))
(when (and (numberp (cdr (nth 2 attr)))
(< (cdr (nth 2 attr)) 0))
(setcdr (car (nthcdr 2 attr)) tramp-unknown-id-integer))
(when (and (floatp (cdr (nth 2 attr)))
(<= (cdr (nth 2 attr)) most-positive-fixnum))
(setcdr (car (nthcdr 2 attr)) (round (cdr (nth 2 attr))))))
(when (consp (nth 3 attr))
(when (and (numberp (cdr (nth 3 attr)))
(< (cdr (nth 3 attr)) 0))
(setcdr (car (nthcdr 3 attr)) tramp-unknown-id-integer))
(when (and (floatp (cdr (nth 3 attr)))
(<= (cdr (nth 3 attr)) most-positive-fixnum))
(setcdr (car (nthcdr 3 attr)) (round (cdr (nth 3 attr))))))
;; Convert last access time.
(unless (listp (nth 4 attr))
(setcar (nthcdr 4 attr) (seconds-to-time (nth 4 attr))))
;; Convert last modification time.
(unless (listp (nth 5 attr))
(setcar (nthcdr 5 attr) (seconds-to-time (nth 5 attr))))
;; Convert last status change time.
(unless (listp (nth 6 attr))
(setcar (nthcdr 6 attr) (seconds-to-time (nth 6 attr))))
;; Convert file size.
(when (< (nth 7 attr) 0)
(setcar (nthcdr 7 attr) -1))
(when (and (floatp (nth 7 attr))
(<= (nth 7 attr) most-positive-fixnum))
(setcar (nthcdr 7 attr) (round (nth 7 attr))))
;; Convert file mode bits to string.
(unless (stringp (nth 8 attr))
(setcar (nthcdr 8 attr)
(tramp-file-mode-from-int (nth 8 attr)))
(when (stringp (car attr))
(while (string-match ansi-color-control-seq-regexp (car attr))
(setcar attr (replace-match "" nil nil (car attr)))))
;; Convert uid and gid. Use `tramp-unknown-id-integer'
;; as indication of unusable value.
(when (consp (nth 2 attr))
(when (and (numberp (cdr (nth 2 attr)))
(< (cdr (nth 2 attr)) 0))
(setcdr (car (nthcdr 2 attr)) tramp-unknown-id-integer))
(when (and (floatp (cdr (nth 2 attr)))
(<= (cdr (nth 2 attr)) most-positive-fixnum))
(setcdr (car (nthcdr 2 attr)) (round (cdr (nth 2 attr))))))
(when (consp (nth 3 attr))
(when (and (numberp (cdr (nth 3 attr)))
(< (cdr (nth 3 attr)) 0))
(setcdr (car (nthcdr 3 attr)) tramp-unknown-id-integer))
(when (and (floatp (cdr (nth 3 attr)))
(<= (cdr (nth 3 attr)) most-positive-fixnum))
(setcdr (car (nthcdr 3 attr)) (round (cdr (nth 3 attr))))))
;; Convert last access time.
(unless (listp (nth 4 attr))
(setcar (nthcdr 4 attr) (seconds-to-time (nth 4 attr))))
;; Convert last modification time.
(unless (listp (nth 5 attr))
(setcar (nthcdr 5 attr) (seconds-to-time (nth 5 attr))))
;; Convert last status change time.
(unless (listp (nth 6 attr))
(setcar (nthcdr 6 attr) (seconds-to-time (nth 6 attr))))
;; Convert file size.
(when (< (nth 7 attr) 0)
(setcar (nthcdr 7 attr) -1))
(when (and (floatp (nth 7 attr))
(<= (nth 7 attr) most-positive-fixnum))
(setcar (nthcdr 7 attr) (round (nth 7 attr))))
;; Convert file mode bits to string.
(unless (stringp (nth 8 attr))
(setcar (nthcdr 8 attr)
(tramp-file-mode-from-int (nth 8 attr)))
(when (stringp (car attr))
(aset (nth 8 attr) 0 ?l)))
;; Convert directory indication bit.
(when (string-prefix-p "d" (nth 8 attr))
(setcar attr t))
;; Convert symlink from `tramp-do-file-attributes-with-stat'.
;; Decode also multibyte string.
(when (consp (car attr))
(setcar attr
(and (stringp (caar attr))
(string-match
(rx (+ nonl) " -> " nonl (group (+ nonl)) nonl)
(caar attr))
(decode-coding-string
(match-string 1 (caar attr)) 'utf-8))))
;; Set file's gid change bit.
(setcar
(nthcdr 9 attr)
(not (= (cdr (nth 3 attr))
(or (tramp-get-remote-gid ,vec 'integer)
tramp-unknown-id-integer))))
;; Convert inode.
(when (floatp (nth 10 attr))
(setcar (nthcdr 10 attr)
(condition-case nil
(let ((high (nth 10 attr))
middle low)
(aset (nth 8 attr) 0 ?l)))
;; Convert directory indication bit.
(when (string-prefix-p "d" (nth 8 attr))
(setcar attr t))
;; Convert symlink from `tramp-do-file-attributes-with-stat'.
;; Decode also multibyte string.
(when (consp (car attr))
(setcar attr
(and (stringp (caar attr))
(string-match
(rx (+ nonl) " -> " nonl (group (+ nonl)) nonl)
(caar attr))
(decode-coding-string
(match-string 1 (caar attr)) 'utf-8))))
;; Set file's gid change bit.
(setcar
(nthcdr 9 attr)
(not (= (cdr (nth 3 attr))
(or (tramp-get-remote-gid ,vec 'integer)
tramp-unknown-id-integer))))
;; Convert inode.
(when (floatp (nth 10 attr))
(setcar (nthcdr 10 attr)
(condition-case nil
(let ((high (nth 10 attr))
middle low)
(if (<= high most-positive-fixnum)
(floor high)
;; The low 16 bits.
(setq low (mod high #x10000)
high (/ high #x10000))
(if (<= high most-positive-fixnum)
(floor high)
;; The low 16 bits.
(setq low (mod high #x10000)
high (/ high #x10000))
(if (<= high most-positive-fixnum)
(cons (floor high) (floor low))
;; The middle 24 bits.
(setq middle (mod high #x1000000)
high (/ high #x1000000))
(cons (floor high)
(cons (floor middle) (floor low))))))
;; Inodes can be incredible huge. We
;; must hide this.
(error (tramp-get-inode ,vec)))))
;; Set virtual device number.
(setcar (nthcdr 11 attr)
(tramp-get-device ,vec))
;; Set SELinux context.
(when (stringp (nth 12 attr))
(tramp-set-file-property
,vec ,localname "file-selinux-context"
(split-string (nth 12 attr) ":" 'omit)))
;; Remove optional entries.
(setcdr (nthcdr 11 attr) nil)
attr)))))
(cons (floor high) (floor low))
;; The middle 24 bits.
(setq middle (mod high #x1000000)
high (/ high #x1000000))
(cons (floor high)
(cons (floor middle) (floor low))))))
;; Inodes can be incredible huge. We must
;; hide this.
(error (tramp-get-inode ,vec)))))
;; Set virtual device number.
(setcar (nthcdr 11 attr)
(tramp-get-device ,vec))
;; Set SELinux context.
(when (stringp (nth 12 attr))
(tramp-set-file-property
,vec ,localname "file-selinux-context"
(split-string (nth 12 attr) ":" 'omit)))
;; Remove optional entries.
(setcdr (nthcdr 11 attr) nil)
attr))))
;; Return normalized result.
(append (tramp-compat-take 2 result)
@ -6805,13 +6805,15 @@ verbosity of 6."
(catch 'result
(let ((default-directory temporary-file-directory))
(dolist (pid (list-system-processes))
(when-let ((attributes (process-attributes pid))
(comm (cdr (assoc 'comm attributes))))
(and (string-equal (cdr (assoc 'user attributes)) (user-login-name))
;; The returned command name could be truncated to 15
;; characters. Therefore, we cannot check for `string-equal'.
(string-prefix-p comm process-name)
(throw 'result t))))))))
(and-let* ((attributes (process-attributes pid))
(comm (cdr (assoc 'comm attributes)))
((string-equal
(cdr (assoc 'user attributes)) (user-login-name)))
;; The returned command name could be truncated
;; to 15 characters. Therefore, we cannot check
;; for `string-equal'.
((string-prefix-p comm process-name))
((throw 'result t)))))))))
;; When calling "emacs -Q", `auth-source-search' won't be called. If
;; you want to debug exactly this case, call "emacs -Q --eval '(setq

View file

@ -3828,12 +3828,12 @@ The test is derived from TEST and COMMAND."
(skip-unless (tramp--test-enabled))
(skip-unless (tramp--test-sh-p))
(skip-unless (tramp-get-remote-stat tramp-test-vec))
(if-let ((default-directory ert-remote-temporary-file-directory)
(ert-test (ert-get-test ',test))
(result (ert-test-most-recent-result ert-test))
(tramp-connection-properties
(cons '(nil "perl" nil)
tramp-connection-properties)))
(if-let* ((default-directory ert-remote-temporary-file-directory)
(ert-test (ert-get-test ',test))
(result (ert-test-most-recent-result ert-test))
(tramp-connection-properties
(cons '(nil "perl" nil)
tramp-connection-properties)))
(progn
(skip-unless (< (ert-test-result-duration result) 300))
(funcall (ert-test-body ert-test)))
@ -3848,17 +3848,17 @@ The test is derived from TEST and COMMAND."
(skip-unless (tramp--test-enabled))
(skip-unless (tramp--test-sh-p))
(skip-unless (tramp-get-remote-perl tramp-test-vec))
(if-let ((default-directory ert-remote-temporary-file-directory)
(ert-test (ert-get-test ',test))
(result (ert-test-most-recent-result ert-test))
(tramp-connection-properties
(append
'((nil "stat" nil)
;; See `tramp-sh-handle-file-truename'.
(nil "readlink" nil)
;; See `tramp-sh-handle-get-remote-*'.
(nil "id" nil))
tramp-connection-properties)))
(if-let* ((default-directory ert-remote-temporary-file-directory)
(ert-test (ert-get-test ',test))
(result (ert-test-most-recent-result ert-test))
(tramp-connection-properties
(append
'((nil "stat" nil)
;; See `tramp-sh-handle-file-truename'.
(nil "readlink" nil)
;; See `tramp-sh-handle-get-remote-*'.
(nil "id" nil))
tramp-connection-properties)))
(progn
(skip-unless (< (ert-test-result-duration result) 300))
(funcall (ert-test-body ert-test)))
@ -3872,16 +3872,16 @@ The test is derived from TEST and COMMAND."
(tramp--test-set-ert-test-documentation ',test "ls")
(skip-unless (tramp--test-enabled))
(skip-unless (tramp--test-sh-p))
(if-let ((default-directory ert-remote-temporary-file-directory)
(ert-test (ert-get-test ',test))
(result (ert-test-most-recent-result ert-test))
(tramp-connection-properties
(append
'((nil "perl" nil)
(nil "stat" nil)
;; See `tramp-sh-handle-file-truename'.
(nil "readlink" nil))
tramp-connection-properties)))
(if-let* ((default-directory ert-remote-temporary-file-directory)
(ert-test (ert-get-test ',test))
(result (ert-test-most-recent-result ert-test))
(tramp-connection-properties
(append
'((nil "perl" nil)
(nil "stat" nil)
;; See `tramp-sh-handle-file-truename'.
(nil "readlink" nil))
tramp-connection-properties)))
(progn
(skip-unless (< (ert-test-result-duration result) 300))
(funcall (ert-test-body ert-test)))
@ -3908,9 +3908,9 @@ The test is derived from TEST and COMMAND."
(skip-unless (tramp--test-enabled))
(skip-unless
(or (tramp--test-adb-p) (tramp--test-sh-p) (tramp--test-sudoedit-p)))
(if-let ((default-directory ert-remote-temporary-file-directory)
(ert-test (ert-get-test ',test))
(result (ert-test-most-recent-result ert-test)))
(if-let* ((default-directory ert-remote-temporary-file-directory)
(ert-test (ert-get-test ',test))
(result (ert-test-most-recent-result ert-test)))
(progn
(skip-unless (< (ert-test-result-duration result) 300))
(let (tramp-use-file-attributes)
@ -5220,8 +5220,8 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'."
"Timeout handler, reporting a failed test."
(interactive)
(tramp--test-message "proc: %s" (get-buffer-process (current-buffer)))
(when-let ((proc (get-buffer-process (current-buffer)))
((processp proc)))
(when-let* ((proc (get-buffer-process (current-buffer)))
((processp proc)))
(tramp--test-message "cmd: %s" (process-command proc)))
(tramp--test-message "buf: %s\n%s\n---" (current-buffer) (buffer-string))
(ert-fail (format "`%s' timed out" (ert-test-name (ert-running-test)))))
@ -5814,8 +5814,8 @@ If UNSTABLE is non-nil, the test is tagged as `:unstable'."
(setq command '("sleep" "100")
proc (apply #'start-file-process "test" nil command))
(while (accept-process-output proc 0))
(when-let ((pid (process-get proc 'remote-pid))
(attributes (process-attributes pid)))
(when-let* ((pid (process-get proc 'remote-pid))
(attributes (process-attributes pid)))
;; (tramp--test-message "%s" attributes)
(should (equal (cdr (assq 'comm attributes)) (car command)))
(should (equal (cdr (assq 'args attributes))
@ -5832,8 +5832,8 @@ If UNSTABLE is non-nil, the test is tagged as `:unstable'."
;; `memory-info' is supported since Emacs 29.1.
(skip-unless (tramp--test-emacs29-p))
(when-let ((default-directory ert-remote-temporary-file-directory)
(mi (memory-info)))
(when-let* ((default-directory ert-remote-temporary-file-directory)
(mi (memory-info)))
(should (consp mi))
(should (length= mi 4))
(dotimes (i (length mi))
@ -7356,7 +7356,7 @@ This requires restrictions of file name syntax."
(setq buffer (dired-noselect tmp-name1 "--dired -al"))
(goto-char (point-min))
(while (not (eobp))
(when-let ((name (dired-get-filename 'no-dir 'no-error)))
(when-let* ((name (dired-get-filename 'no-dir 'no-error)))
(unless
(string-match-p name directory-files-no-dot-files-regexp)
(should (member name files))))
@ -7636,7 +7636,7 @@ This requires restrictions of file name syntax."
"Check that `file-system-info' returns proper values."
(skip-unless (tramp--test-enabled))
(when-let ((fsi (file-system-info ert-remote-temporary-file-directory)))
(when-let* ((fsi (file-system-info ert-remote-temporary-file-directory)))
(should (consp fsi))
(should (length= fsi 3))
(dotimes (i (length fsi))
@ -7668,10 +7668,10 @@ should all return proper values."
(should (or (stringp (tramp-get-remote-gid v 'string))
(null (tramp-get-remote-gid v 'string))))
(when-let ((groups (tramp-get-remote-groups v 'integer)))
(when-let* ((groups (tramp-get-remote-groups v 'integer)))
(should (consp groups))
(dolist (group groups) (should (integerp group))))
(when-let ((groups (tramp-get-remote-groups v 'string)))
(when-let* ((groups (tramp-get-remote-groups v 'string)))
(should (consp groups))
(dolist (group groups) (should (stringp group)))))))
@ -7820,9 +7820,9 @@ process sentinels. They shall not disturb each other."
buf)
(while buffers
(setq buf (seq-random-elt buffers))
(if-let ((proc (get-buffer-process buf))
(file (process-get proc 'foo))
(count (process-get proc 'bar)))
(if-let* ((proc (get-buffer-process buf))
(file (process-get proc 'foo))
(count (process-get proc 'bar)))
(progn
(tramp--test-message
"Start action %d %s %s" count buf (current-time-string))