diff options
| author | Michael Albinus | 2023-02-18 18:27:56 +0100 |
|---|---|---|
| committer | Michael Albinus | 2023-02-18 18:27:56 +0100 |
| commit | 2ac8d7e64a08ea6e22bb90ad16e2880440fbcf16 (patch) | |
| tree | 707d87bff3751bf849a6fe1b4c777e9523282592 | |
| parent | b3502b922821fd100fb86b8cda6a0a62fba7d394 (diff) | |
| download | emacs-2ac8d7e64a08ea6e22bb90ad16e2880440fbcf16.tar.gz emacs-2ac8d7e64a08ea6e22bb90ad16e2880440fbcf16.zip | |
Improve Tramp's user and host name completion
* lisp/net/tramp.el (tramp-completion-handle-file-exists-p):
Improve user name completion.
(tramp-skeleton-file-exists-p): New defmacro, which also handles
host name completion.
(tramp-handle-file-exists-p):
* lisp/net/tramp-adb.el (tramp-adb-handle-file-exists-p):
* lisp/net/tramp-sh.el (tramp-sh-handle-file-exists-p):
* lisp/net/tramp-sudoedit.el (tramp-sudoedit-handle-file-exists-p):
Use it.
| -rw-r--r-- | lisp/net/tramp-adb.el | 13 | ||||
| -rw-r--r-- | lisp/net/tramp-sh.el | 21 | ||||
| -rw-r--r-- | lisp/net/tramp-sudoedit.el | 13 | ||||
| -rw-r--r-- | lisp/net/tramp.el | 58 |
4 files changed, 51 insertions, 54 deletions
diff --git a/lisp/net/tramp-adb.el b/lisp/net/tramp-adb.el index 38fd8a4e258..f8c38859477 100644 --- a/lisp/net/tramp-adb.el +++ b/lisp/net/tramp-adb.el | |||
| @@ -487,16 +487,9 @@ Emacs dired can't find files." | |||
| 487 | 487 | ||
| 488 | (defun tramp-adb-handle-file-exists-p (filename) | 488 | (defun tramp-adb-handle-file-exists-p (filename) |
| 489 | "Like `file-exists-p' for Tramp files." | 489 | "Like `file-exists-p' for Tramp files." |
| 490 | ;; `file-exists-p' is used as predicate in file name completion. | 490 | (tramp-skeleton-file-exists-p filename |
| 491 | ;; We don't want to run it when `non-essential' is t, or there is | 491 | (tramp-adb-send-command-and-check |
| 492 | ;; no connection process yet. | 492 | v (format "test -e %s" (tramp-shell-quote-argument localname))))) |
| 493 | (when (tramp-connectable-p filename) | ||
| 494 | (with-parsed-tramp-file-name (expand-file-name filename) nil | ||
| 495 | (with-tramp-file-property v localname "file-exists-p" | ||
| 496 | (if (tramp-file-property-p v localname "file-attributes") | ||
| 497 | (not (null (tramp-get-file-property v localname "file-attributes"))) | ||
| 498 | (tramp-adb-send-command-and-check | ||
| 499 | v (format "test -e %s" (tramp-shell-quote-argument localname)))))))) | ||
| 500 | 493 | ||
| 501 | (defun tramp-adb-handle-file-readable-p (filename) | 494 | (defun tramp-adb-handle-file-readable-p (filename) |
| 502 | "Like `file-readable-p' for Tramp files." | 495 | "Like `file-readable-p' for Tramp files." |
diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el index 7a6c9658aa9..b3d837f9514 100644 --- a/lisp/net/tramp-sh.el +++ b/lisp/net/tramp-sh.el | |||
| @@ -1186,20 +1186,13 @@ Operations not mentioned here will be handled by the normal Emacs functions.") | |||
| 1186 | 1186 | ||
| 1187 | (defun tramp-sh-handle-file-exists-p (filename) | 1187 | (defun tramp-sh-handle-file-exists-p (filename) |
| 1188 | "Like `file-exists-p' for Tramp files." | 1188 | "Like `file-exists-p' for Tramp files." |
| 1189 | ;; `file-exists-p' is used as predicate in file name completion. | 1189 | (tramp-skeleton-file-exists-p filename |
| 1190 | ;; We don't want to run it when `non-essential' is t, or there is | 1190 | (tramp-send-command-and-check |
| 1191 | ;; no connection process yet. | 1191 | v |
| 1192 | (when (tramp-connectable-p filename) | 1192 | (format |
| 1193 | (with-parsed-tramp-file-name (expand-file-name filename) nil | 1193 | "%s %s" |
| 1194 | (with-tramp-file-property v localname "file-exists-p" | 1194 | (tramp-get-file-exists-command v) |
| 1195 | (if (tramp-file-property-p v localname "file-attributes") | 1195 | (tramp-shell-quote-argument localname))))) |
| 1196 | (not (null (tramp-get-file-property v localname "file-attributes"))) | ||
| 1197 | (tramp-send-command-and-check | ||
| 1198 | v | ||
| 1199 | (format | ||
| 1200 | "%s %s" | ||
| 1201 | (tramp-get-file-exists-command v) | ||
| 1202 | (tramp-shell-quote-argument localname)))))))) | ||
| 1203 | 1196 | ||
| 1204 | (defun tramp-sh-handle-file-attributes (filename &optional id-format) | 1197 | (defun tramp-sh-handle-file-attributes (filename &optional id-format) |
| 1205 | "Like `file-attributes' for Tramp files." | 1198 | "Like `file-attributes' for Tramp files." |
diff --git a/lisp/net/tramp-sudoedit.el b/lisp/net/tramp-sudoedit.el index 1f646253579..fa1689d6851 100644 --- a/lisp/net/tramp-sudoedit.el +++ b/lisp/net/tramp-sudoedit.el | |||
| @@ -454,16 +454,9 @@ the result will be a local, non-Tramp, file name." | |||
| 454 | 454 | ||
| 455 | (defun tramp-sudoedit-handle-file-exists-p (filename) | 455 | (defun tramp-sudoedit-handle-file-exists-p (filename) |
| 456 | "Like `file-exists-p' for Tramp files." | 456 | "Like `file-exists-p' for Tramp files." |
| 457 | ;; `file-exists-p' is used as predicate in file name completion. | 457 | (tramp-skeleton-file-exists-p filename |
| 458 | ;; We don't want to run it when `non-essential' is t, or there is | 458 | (tramp-sudoedit-send-command |
| 459 | ;; no connection process yet. | 459 | v "test" "-e" (file-name-unquote localname)))) |
| 460 | (when (tramp-connectable-p filename) | ||
| 461 | (with-parsed-tramp-file-name (expand-file-name filename) nil | ||
| 462 | (with-tramp-file-property v localname "file-exists-p" | ||
| 463 | (if (tramp-file-property-p v localname "file-attributes") | ||
| 464 | (not (null (tramp-get-file-property v localname "file-attributes"))) | ||
| 465 | (tramp-sudoedit-send-command | ||
| 466 | v "test" "-e" (file-name-unquote localname))))))) | ||
| 467 | 460 | ||
| 468 | (defun tramp-sudoedit-handle-file-name-all-completions (filename directory) | 461 | (defun tramp-sudoedit-handle-file-name-all-completions (filename directory) |
| 469 | "Like `file-name-all-completions' for Tramp files." | 462 | "Like `file-name-all-completions' for Tramp files." |
diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el index 95b42fb1c43..baa9f966dd8 100644 --- a/lisp/net/tramp.el +++ b/lisp/net/tramp.el | |||
| @@ -2976,8 +2976,9 @@ not in completion mode." | |||
| 2976 | ;; We need special handling only when a method is needed. Then we | 2976 | ;; We need special handling only when a method is needed. Then we |
| 2977 | ;; regard all files "/method:" or "/[method/" as existent, if | 2977 | ;; regard all files "/method:" or "/[method/" as existent, if |
| 2978 | ;; "method" is a valid Tramp method. And we regard all files | 2978 | ;; "method" is a valid Tramp method. And we regard all files |
| 2979 | ;; "/method:user@host" or "/[method/user@host" as existent, if | 2979 | ;; "/method:user@", "/user@" or "/[method/user@" as existent, if |
| 2980 | ;; "user@host" is a valid file name completion. | 2980 | ;; "user@" is a valid file name completion. Host completion is |
| 2981 | ;; performed in the respective backen operation. | ||
| 2981 | (or (and (cond | 2982 | (or (and (cond |
| 2982 | ;; Completion styles like `flex' and `substring' check for | 2983 | ;; Completion styles like `flex' and `substring' check for |
| 2983 | ;; the file name "/". This does exist. | 2984 | ;; the file name "/". This does exist. |
| @@ -2989,27 +2990,30 @@ not in completion mode." | |||
| 2989 | (regexp tramp-prefix-regexp) | 2990 | (regexp tramp-prefix-regexp) |
| 2990 | (* (regexp tramp-remote-file-name-spec-regexp) | 2991 | (* (regexp tramp-remote-file-name-spec-regexp) |
| 2991 | (regexp tramp-postfix-hop-regexp)) | 2992 | (regexp tramp-postfix-hop-regexp)) |
| 2992 | (group (regexp tramp-method-regexp)) | 2993 | (group-n 9 (regexp tramp-method-regexp)) |
| 2993 | (? (regexp tramp-postfix-method-regexp)) | 2994 | (? (regexp tramp-postfix-method-regexp)) |
| 2994 | eos) | 2995 | eos) |
| 2995 | filename)) | 2996 | filename)) |
| 2996 | (assoc (match-string 1 filename) tramp-methods)) | 2997 | (assoc (match-string 9 filename) tramp-methods)) |
| 2997 | ;; Is it a valid user@host? | 2998 | ;; Is it a valid user? |
| 2998 | ((string-match | 2999 | ((string-match |
| 2999 | (rx | 3000 | (rx |
| 3000 | (regexp tramp-prefix-regexp) | 3001 | (regexp tramp-prefix-regexp) |
| 3001 | (* (regexp tramp-remote-file-name-spec-regexp) | 3002 | (* (regexp tramp-remote-file-name-spec-regexp) |
| 3002 | (regexp tramp-postfix-hop-regexp)) | 3003 | (regexp tramp-postfix-hop-regexp)) |
| 3003 | (group (regexp tramp-remote-file-name-spec-regexp)) | 3004 | (group-n 10 |
| 3005 | (regexp tramp-method-regexp) | ||
| 3006 | (regexp tramp-postfix-method-regexp)) | ||
| 3007 | (group-n 11 | ||
| 3008 | (regexp tramp-user-regexp) | ||
| 3009 | (regexp tramp-postfix-user-regexp)) | ||
| 3004 | eos) | 3010 | eos) |
| 3005 | filename) | 3011 | filename) |
| 3006 | (member | 3012 | (member |
| 3007 | (concat | 3013 | (match-string 11 filename) |
| 3008 | (file-name-nondirectory filename) tramp-postfix-host-format) | 3014 | (file-name-all-completions |
| 3009 | (file-name-all-completions | 3015 | "" (concat tramp-prefix-format (match-string 10 filename)))))) |
| 3010 | (file-name-nondirectory filename) | 3016 | t) |
| 3011 | (file-name-directory filename))))) | ||
| 3012 | t) | ||
| 3013 | 3017 | ||
| 3014 | (tramp-run-real-handler #'file-exists-p (list filename)))) | 3018 | (tramp-run-real-handler #'file-exists-p (list filename)))) |
| 3015 | 3019 | ||
| @@ -3629,6 +3633,25 @@ BODY is the backend specific code." | |||
| 3629 | (tramp-dissect-file-name ,directory) 'file-missing ,directory) | 3633 | (tramp-dissect-file-name ,directory) 'file-missing ,directory) |
| 3630 | nil))) | 3634 | nil))) |
| 3631 | 3635 | ||
| 3636 | (defmacro tramp-skeleton-file-exists-p (filename &rest body) | ||
| 3637 | "Skeleton for `tramp-*-handle-file-exists-p'. | ||
| 3638 | BODY is the backend specific code." | ||
| 3639 | (declare (indent 1) (debug t)) | ||
| 3640 | ;; `file-exists-p' is used as predicate in file name completion. | ||
| 3641 | `(or (and minibuffer-completing-file-name | ||
| 3642 | (file-name-absolute-p ,filename) | ||
| 3643 | (tramp-string-empty-or-nil-p | ||
| 3644 | (tramp-file-name-localname (tramp-dissect-file-name ,filename)))) | ||
| 3645 | ;; We don't want to run it when `non-essential' is t, or there | ||
| 3646 | ;; is no connection process yet. | ||
| 3647 | (when (tramp-connectable-p ,filename) | ||
| 3648 | (with-parsed-tramp-file-name (expand-file-name ,filename) nil | ||
| 3649 | (with-tramp-file-property v localname "file-exists-p" | ||
| 3650 | (if (tramp-file-property-p v localname "file-attributes") | ||
| 3651 | (not | ||
| 3652 | (null (tramp-get-file-property v localname "file-attributes"))) | ||
| 3653 | ,@body)))))) | ||
| 3654 | |||
| 3632 | (defmacro tramp-skeleton-file-local-copy (filename &rest body) | 3655 | (defmacro tramp-skeleton-file-local-copy (filename &rest body) |
| 3633 | "Skeleton for `tramp-*-handle-file-local-copy'. | 3656 | "Skeleton for `tramp-*-handle-file-local-copy'. |
| 3634 | BODY is the backend specific code." | 3657 | BODY is the backend specific code." |
| @@ -4066,13 +4089,8 @@ Let-bind it when necessary.") | |||
| 4066 | 4089 | ||
| 4067 | (defun tramp-handle-file-exists-p (filename) | 4090 | (defun tramp-handle-file-exists-p (filename) |
| 4068 | "Like `file-exists-p' for Tramp files." | 4091 | "Like `file-exists-p' for Tramp files." |
| 4069 | ;; `file-exists-p' is used as predicate in file name completion. | 4092 | (tramp-skeleton-file-exists-p filename |
| 4070 | ;; We don't want to run it when `non-essential' is t, or there is | 4093 | (not (null (file-attributes filename))))) |
| 4071 | ;; no connection process yet. | ||
| 4072 | (when (tramp-connectable-p filename) | ||
| 4073 | (with-parsed-tramp-file-name (expand-file-name filename) nil | ||
| 4074 | (with-tramp-file-property v localname "file-exists-p" | ||
| 4075 | (not (null (file-attributes filename))))))) | ||
| 4076 | 4094 | ||
| 4077 | (defun tramp-handle-file-in-directory-p (filename directory) | 4095 | (defun tramp-handle-file-in-directory-p (filename directory) |
| 4078 | "Like `file-in-directory-p' for Tramp files." | 4096 | "Like `file-in-directory-p' for Tramp files." |