diff options
Diffstat (limited to 'lisp/net/tramp-compat.el')
-rw-r--r-- | lisp/net/tramp-compat.el | 238 |
1 files changed, 59 insertions, 179 deletions
diff --git a/lisp/net/tramp-compat.el b/lisp/net/tramp-compat.el index f176476a73a..420d6cadb9c 100644 --- a/lisp/net/tramp-compat.el +++ b/lisp/net/tramp-compat.el @@ -23,9 +23,9 @@ ;;; Commentary: -;; Tramp's main Emacs version for development is Emacs 29. This -;; package provides compatibility functions for Emacs 26, Emacs 27 and -;; Emacs 28. +;; Tramp's main Emacs version for development is Emacs 30. This +;; package provides compatibility functions for Emacs 27, Emacs 28 and +;; Emacs 29. ;;; Code: @@ -36,9 +36,7 @@ (require 'shell) (require 'subr-x) -(declare-function tramp-compat-rx "tramp") (declare-function tramp-error "tramp") -(declare-function tramp-file-name-handler "tramp") (declare-function tramp-tramp-file-p "tramp") (defvar tramp-temp-name-prefix) @@ -85,153 +83,6 @@ Add the extension of F, if existing." tramp-temp-name-prefix tramp-compat-temporary-file-directory) dir-flag (file-name-extension f t))) -;; `file-name-quoted-p', `file-name-quote' and `file-name-unquote' got -;; a second argument in Emacs 27.1. -;;;###tramp-autoload -(defalias 'tramp-compat-file-name-quoted-p - (if (equal (func-arity #'file-name-quoted-p) '(1 . 2)) - #'file-name-quoted-p - (lambda (name &optional top) - "Whether NAME is quoted with prefix \"/:\". -If NAME is a remote file name and TOP is nil, check the local part of NAME." - (let ((file-name-handler-alist (unless top file-name-handler-alist))) - (string-prefix-p "/:" (file-local-name name)))))) - -(defalias 'tramp-compat-file-name-quote - (if (equal (func-arity #'file-name-quote) '(1 . 2)) - #'file-name-quote - (lambda (name &optional top) - "Add the quotation prefix \"/:\" to file NAME. -If NAME is a remote file name and TOP is nil, the local part of NAME is quoted." - (let ((file-name-handler-alist (unless top file-name-handler-alist))) - (if (tramp-compat-file-name-quoted-p name top) - name - (concat (file-remote-p name) "/:" (file-local-name name))))))) - -(defalias 'tramp-compat-file-name-unquote - (if (equal (func-arity #'file-name-unquote) '(1 . 2)) - #'file-name-unquote - (lambda (name &optional top) - "Remove quotation prefix \"/:\" from file NAME. -If NAME is a remote file name and TOP is nil, the local part of -NAME is unquoted." - (let* ((file-name-handler-alist (unless top file-name-handler-alist)) - (localname (file-local-name name))) - (when (tramp-compat-file-name-quoted-p localname top) - (setq - localname (if (= (length localname) 2) "/" (substring localname 2)))) - (concat (file-remote-p name) localname))))) - -;; `tramp-syntax' has changed its meaning in Emacs 26.1. We still -;; support old settings. -(defsubst tramp-compat-tramp-syntax () - "Return proper value of `tramp-syntax'." - (defvar tramp-syntax) - (cond ((eq tramp-syntax 'ftp) 'default) - ((eq tramp-syntax 'sep) 'separate) - (t tramp-syntax))) - -;; The signature of `tramp-make-tramp-file-name' has been changed. -;; Therefore, we cannot use `url-tramp-convert-url-to-tramp' prior -;; Emacs 26.1. We use `temporary-file-directory' as indicator. -(defconst tramp-compat-use-url-tramp-p (fboundp 'temporary-file-directory) - "Whether to use url-tramp.el.") - -;; `exec-path' is new in Emacs 27.1. -(defalias 'tramp-compat-exec-path - (if (fboundp 'exec-path) - #'exec-path - (lambda () - "List of directories to search programs to run in remote subprocesses." - (if (tramp-tramp-file-p default-directory) - (tramp-file-name-handler 'exec-path) - exec-path)))) - -;; `time-equal-p' has appeared in Emacs 27.1. -(defalias 'tramp-compat-time-equal-p - (if (fboundp 'time-equal-p) - #'time-equal-p - (lambda (t1 t2) - "Return non-nil if time value T1 is equal to time value T2. -A nil value for either argument stands for the current time." - (equal (or t1 (current-time)) (or t2 (current-time)))))) - -;; `flatten-tree' has appeared in Emacs 27.1. -(defalias 'tramp-compat-flatten-tree - (if (fboundp 'flatten-tree) - #'flatten-tree - (lambda (tree) - "Take TREE and \"flatten\" it." - (let (elems) - (setq tree (list tree)) - (while (let ((elem (pop tree))) - (cond ((consp elem) - (setq tree (cons (car elem) (cons (cdr elem) tree)))) - (elem - (push elem elems))) - tree)) - (nreverse elems))))) - -;; `progress-reporter-update' got argument SUFFIX in Emacs 27.1. -(defalias 'tramp-compat-progress-reporter-update - (if (equal (func-arity #'progress-reporter-update) '(1 . 3)) - #'progress-reporter-update - (lambda (reporter &optional value _suffix) - (progress-reporter-update reporter value)))) - -;; `ignore-error' is new in Emacs 27.1. -(defmacro tramp-compat-ignore-error (condition &rest body) - "Execute BODY; if the error CONDITION occurs, return nil. -Otherwise, return result of last form in BODY. - -CONDITION can also be a list of error conditions." - (declare (debug t) (indent 1)) - `(condition-case nil (progn ,@body) (,condition nil))) - -;; `rx' in Emacs 26 doesn't know the `literal', `anychar' and -;; `multibyte' constructs. The `not' construct requires an `any' -;; construct as argument. The `regexp' construct requires a literal -;; string. -(defvar tramp-compat-rx--runtime-params) - -(defun tramp-compat-rx--transform-items (items) - (mapcar #'tramp-compat-rx--transform-item items)) - -;; There is an error in Emacs 26. `(rx "a" (? ""))' => "a?". -;; We must protect the string in regexp and literal, therefore. -(defun tramp-compat-rx--transform-item (item) - (pcase item - ('anychar 'anything) - ('multibyte 'nonascii) - (`(not ,expr) - (if (consp expr) item (list 'not (list 'any expr)))) - (`(regexp ,expr) - (setq tramp-compat-rx--runtime-params t) - `(regexp ,(list '\, `(concat "\\(?:" ,expr "\\)")))) - (`(literal ,expr) - (setq tramp-compat-rx--runtime-params t) - `(regexp ,(list '\, `(concat "\\(?:" (regexp-quote ,expr) "\\)")))) - (`(eval . ,_) item) - (`(,head . ,rest) (cons head (tramp-compat-rx--transform-items rest))) - (_ item))) - -(defun tramp-compat-rx--transform (items) - (let* ((tramp-compat-rx--runtime-params nil) - (new-rx (cons ': (tramp-compat-rx--transform-items items)))) - (if tramp-compat-rx--runtime-params - `(rx-to-string ,(list '\` new-rx) t) - (rx-to-string new-rx t)))) - -(if (ignore-errors (rx-to-string '(literal "a"))) ;; Emacs 27+. - (defalias 'tramp-compat-rx #'rx) - (defmacro tramp-compat-rx (&rest items) - (tramp-compat-rx--transform items))) - -;; This is needed for compilation in the Emacs source tree. -;;;###autoload (defalias 'tramp-compat-rx #'rx) - -(put #'tramp-compat-rx 'tramp-autoload t) - ;; `file-modes', `set-file-modes' and `set-file-times' got argument ;; FLAG in Emacs 28.1. (defalias 'tramp-compat-file-modes @@ -326,6 +177,48 @@ CONDITION can also be a list of error conditions." (car components)) (cdr components))))))) +;; Function `replace-regexp-in-region' is new in Emacs 28.1. +(defalias 'tramp-compat-replace-regexp-in-region + (if (fboundp 'replace-regexp-in-region) + #'replace-regexp-in-region + (lambda (regexp replacement &optional start end) + (if start + (when (< start (point-min)) + (error "Start before start of buffer")) + (setq start (point))) + (if end + (when (> end (point-max)) + (error "End after end of buffer")) + (setq end (point-max))) + (save-excursion + (let ((matches 0) + (case-fold-search nil)) + (goto-char start) + (while (re-search-forward regexp end t) + (replace-match replacement t) + (setq matches (1+ matches))) + (and (not (zerop matches)) + matches)))))) + +;; `length<', `length>' and `length=' are added to Emacs 28.1. +(defalias 'tramp-compat-length< + (if (fboundp 'length<) + #'length< + (lambda (sequence length) + (< (length sequence) length)))) + +(defalias 'tramp-compat-length> + (if (fboundp 'length>) + #'length> + (lambda (sequence length) + (> (length sequence) length)))) + +(defalias 'tramp-compat-length= + (if (fboundp 'length=) + #'length= + (lambda (sequence length) + (= (length sequence) length)))) + ;; `permission-denied' is introduced in Emacs 29.1. (defconst tramp-permission-denied (if (get 'permission-denied 'error-conditions) 'permission-denied 'file-error) @@ -353,7 +246,7 @@ CONDITION can also be a list of error conditions." #'take (lambda (n list) (when (and (natnump n) (> n 0)) - (if (>= n (length list)) + (if (tramp-compat-length< list n) list (butlast list (- (length list) n))))))) ;; Function `ntake' is new in Emacs 29.1. @@ -362,7 +255,7 @@ CONDITION can also be a list of error conditions." #'ntake (lambda (n list) (when (and (natnump n) (> n 0)) - (if (>= n (length list)) + (if (tramp-compat-length< list n) list (nbutlast list (- (length list) n))))))) ;; Function `string-equal-ignore-case' is new in Emacs 29.1. @@ -382,28 +275,18 @@ CONDITION can also be a list of error conditions." (autoload 'netrc-parse "netrc") (netrc-parse file)))) -;; Function `replace-regexp-in-region' is new in Emacs 28.1. -(defalias 'tramp-compat-replace-regexp-in-region - (if (fboundp 'replace-regexp-in-region) - #'replace-regexp-in-region - (lambda (regexp replacement &optional start end) - (if start - (when (< start (point-min)) - (error "Start before start of buffer")) - (setq start (point))) - (if end - (when (> end (point-max)) - (error "End after end of buffer")) - (setq end (point-max))) - (save-excursion - (let ((matches 0) - (case-fold-search nil)) - (goto-char start) - (while (re-search-forward regexp end t) - (replace-match replacement t) - (setq matches (1+ matches))) - (and (not (zerop matches)) - matches)))))) +;; User option `password-colon-equivalents' is new in Emacs 30.1. +(if (boundp 'password-colon-equivalents) + (defvaralias + 'tramp-compat-password-colon-equivalents + 'password-colon-equivalents) + (defvar tramp-compat-password-colon-equivalents + '(?\N{COLON} + ?\N{FULLWIDTH COLON} + ?\N{SMALL COLON} + ?\N{PRESENTATION FORM FOR VERTICAL COLON} + ?\N{KHMER SIGN CAMNUC PII KUUH}) + "List of characters equivalent to trailing colon in \"password\" prompts.")) (dolist (elt (all-completions "tramp-compat-" obarray 'functionp)) (put (intern elt) 'tramp-suppress-trace t)) @@ -419,8 +302,5 @@ CONDITION can also be a list of error conditions." ;; ;; * Starting with Emacs 27.1, there's no need to escape open ;; parentheses with a backslash in docstrings anymore. -;; -;; * Starting with Emacs 27.1, there's `make-empty-file'. Could be -;; used instead of `(write-region "" ...)'. ;;; tramp-compat.el ends here |