diff options
| author | Gene Goykhman | 2023-08-29 10:10:06 +0200 |
|---|---|---|
| committer | Michael Albinus | 2023-08-29 10:10:06 +0200 |
| commit | 2f5d0606cb7f1629f2fcc8fc4f00a43420a4974a (patch) | |
| tree | 2df891852bb507ecc21ed7cd6edbdc099ef6ae60 | |
| parent | 804a96af28235b8a1a1199fc9c2e96e367ce14f6 (diff) | |
| download | emacs-2f5d0606cb7f1629f2fcc8fc4f00a43420a4974a.tar.gz emacs-2f5d0606cb7f1629f2fcc8fc4f00a43420a4974a.zip | |
Provide completion candidates for remote containers over a multi-hop
* lisp/net/tramp-container.el (tramp-container--completion-function):
Set default directory to last hop.
(tramp-set-completion-function): Don't use executable-find for
container program since it might not be running locally.
* lisp/net/tramp.el (tramp--last-hop-directory): Add new variable.
(tramp-completion-handle-file-name-all-completions): Use container
host directory to execute container program on remote host.
(tramp-set-completion-function): FIXME: for now, don't constrain
allowable completion methods to only those present on the local system.
(tramp-completion-remote-containers): Add customize option to
provide completion candidates for containers running on remote hosts.
| -rw-r--r-- | lisp/net/tramp-container.el | 11 | ||||
| -rw-r--r-- | lisp/net/tramp.el | 136 |
2 files changed, 82 insertions, 65 deletions
diff --git a/lisp/net/tramp-container.el b/lisp/net/tramp-container.el index 7f8d4473ad7..e5ad3a55e27 100644 --- a/lisp/net/tramp-container.el +++ b/lisp/net/tramp-container.el | |||
| @@ -165,7 +165,12 @@ PROGRAM is the program to be run for \"ps\", either | |||
| 165 | 165 | ||
| 166 | This function is used by `tramp-set-completion-function', please | 166 | This function is used by `tramp-set-completion-function', please |
| 167 | see its function help for a description of the format." | 167 | see its function help for a description of the format." |
| 168 | (when-let ((default-directory tramp-compat-temporary-file-directory) | 168 | ;; Set the default-directory to the directory of the last hop |
| 169 | ;; of a multi-hop path so that we can run the container program | ||
| 170 | ;; from there. If this is not a multi-hop path, run from the local | ||
| 171 | ;; temp file directory. | ||
| 172 | (when-let ((default-directory (or (and tramp-completion-remote-containers tramp--last-hop-directory) | ||
| 173 | tramp-compat-temporary-file-directory)) | ||
| 169 | (raw-list (shell-command-to-string | 174 | (raw-list (shell-command-to-string |
| 170 | (concat program " ps --format '{{.ID}}\t{{.Names}}'"))) | 175 | (concat program " ps --format '{{.ID}}\t{{.Names}}'"))) |
| 171 | (lines (split-string raw-list "\n" 'omit)) | 176 | (lines (split-string raw-list "\n" 'omit)) |
| @@ -383,12 +388,12 @@ see its function help for a description of the format." | |||
| 383 | (tramp-set-completion-function | 388 | (tramp-set-completion-function |
| 384 | tramp-docker-method | 389 | tramp-docker-method |
| 385 | `((tramp-container--completion-function | 390 | `((tramp-container--completion-function |
| 386 | ,(executable-find tramp-docker-program)))) | 391 | ,tramp-docker-program))) |
| 387 | 392 | ||
| 388 | (tramp-set-completion-function | 393 | (tramp-set-completion-function |
| 389 | tramp-podman-method | 394 | tramp-podman-method |
| 390 | `((tramp-container--completion-function | 395 | `((tramp-container--completion-function |
| 391 | ,(executable-find tramp-podman-program)))) | 396 | ,tramp-podman-program))) |
| 392 | 397 | ||
| 393 | (tramp-set-completion-function | 398 | (tramp-set-completion-function |
| 394 | tramp-kubernetes-method | 399 | tramp-kubernetes-method |
diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el index 05d28e8494f..01a83566975 100644 --- a/lisp/net/tramp.el +++ b/lisp/net/tramp.el | |||
| @@ -81,6 +81,8 @@ | |||
| 81 | (defvar tramp-file-name-regexp) | 81 | (defvar tramp-file-name-regexp) |
| 82 | (defvar tramp-completion-method-regexp) | 82 | (defvar tramp-completion-method-regexp) |
| 83 | (defvar tramp-completion-file-name-regexp) | 83 | (defvar tramp-completion-file-name-regexp) |
| 84 | (defvar tramp--last-hop-directory nil | ||
| 85 | "Tracks the directory from which to run container executable programs.") | ||
| 84 | 86 | ||
| 85 | ;; Reload `tramp-compat' when we reload `tramp-autoloads' of the GNU | 87 | ;; Reload `tramp-compat' when we reload `tramp-autoloads' of the GNU |
| 86 | ;; ELPA package. | 88 | ;; ELPA package. |
| @@ -2141,8 +2143,10 @@ Example: | |||
| 2141 | tramp-dns-sd-service-regexp (nth 1 (car v)))) | 2143 | tramp-dns-sd-service-regexp (nth 1 (car v)))) |
| 2142 | ;; Method. | 2144 | ;; Method. |
| 2143 | ((string-equal method (nth 1 (car v)))) | 2145 | ((string-equal method (nth 1 (car v)))) |
| 2144 | ;; Configuration file or empty string. | 2146 | ;; FIXME: for now do not check local existence of file |
| 2145 | (t (file-exists-p (nth 1 (car v)))))) | 2147 | ;; to allow allow arbitrary container program executable |
| 2148 | ;; name for container completion on remote systems. | ||
| 2149 | (t t))) | ||
| 2146 | (setq r (delete (car v) r))) | 2150 | (setq r (delete (car v) r))) |
| 2147 | (setq v (cdr v))) | 2151 | (setq v (cdr v))) |
| 2148 | 2152 | ||
| @@ -2728,16 +2732,8 @@ not in completion mode." | |||
| 2728 | "Like `file-name-all-completions' for partial Tramp files." | 2732 | "Like `file-name-all-completions' for partial Tramp files." |
| 2729 | (let ((fullname | 2733 | (let ((fullname |
| 2730 | (tramp-drop-volume-letter (expand-file-name filename directory))) | 2734 | (tramp-drop-volume-letter (expand-file-name filename directory))) |
| 2731 | ;; When `tramp-syntax' is `simplified', we need a default method. | 2735 | (directory (tramp-drop-volume-letter directory)) |
| 2732 | (tramp-default-method | 2736 | tramp--last-hop-directory hop result result1) |
| 2733 | (and (string-empty-p tramp-postfix-method-format) | ||
| 2734 | tramp-default-method)) | ||
| 2735 | (tramp-default-method-alist | ||
| 2736 | (and (string-empty-p tramp-postfix-method-format) | ||
| 2737 | tramp-default-method-alist)) | ||
| 2738 | tramp-default-user tramp-default-user-alist | ||
| 2739 | tramp-default-host tramp-default-host-alist | ||
| 2740 | hop result result1) | ||
| 2741 | 2737 | ||
| 2742 | ;; Suppress hop from completion. | 2738 | ;; Suppress hop from completion. |
| 2743 | (when (string-match | 2739 | (when (string-match |
| @@ -2747,56 +2743,68 @@ not in completion mode." | |||
| 2747 | (regexp tramp-postfix-hop-regexp)))) | 2743 | (regexp tramp-postfix-hop-regexp)))) |
| 2748 | fullname) | 2744 | fullname) |
| 2749 | (setq hop (match-string 1 fullname) | 2745 | (setq hop (match-string 1 fullname) |
| 2750 | fullname (replace-match "" nil nil fullname 1))) | 2746 | fullname (replace-match "" nil nil fullname 1) |
| 2751 | 2747 | tramp--last-hop-directory | |
| 2752 | ;; Possible completion structures. | 2748 | (tramp-make-tramp-file-name (tramp-dissect-hop-name hop)))) |
| 2753 | (dolist (elt (tramp-completion-dissect-file-name fullname)) | 2749 | |
| 2754 | (let* ((method (tramp-file-name-method elt)) | 2750 | (let (;; When `tramp-syntax' is `simplified', we need a default method. |
| 2755 | (user (tramp-file-name-user elt)) | 2751 | (tramp-default-method |
| 2756 | (host (tramp-file-name-host elt)) | 2752 | (and (string-empty-p tramp-postfix-method-format) |
| 2757 | (localname (tramp-file-name-localname elt)) | 2753 | tramp-default-method)) |
| 2758 | (m (tramp-find-method method user host)) | 2754 | (tramp-default-method-alist |
| 2759 | all-user-hosts) | 2755 | (and (string-empty-p tramp-postfix-method-format) |
| 2760 | 2756 | tramp-default-method-alist)) | |
| 2761 | (unless localname ;; Nothing to complete. | 2757 | tramp-default-user tramp-default-user-alist |
| 2762 | 2758 | tramp-default-host tramp-default-host-alist) | |
| 2763 | (if (or user host) | 2759 | |
| 2764 | 2760 | ;; Possible completion structures. | |
| 2765 | ;; Method dependent user / host combinations. | 2761 | (dolist (elt (tramp-completion-dissect-file-name fullname)) |
| 2766 | (progn | 2762 | (let* ((method (tramp-file-name-method elt)) |
| 2767 | (mapc | 2763 | (user (tramp-file-name-user elt)) |
| 2768 | (lambda (x) | 2764 | (host (tramp-file-name-host elt)) |
| 2769 | (setq all-user-hosts | 2765 | (localname (tramp-file-name-localname elt)) |
| 2770 | (append all-user-hosts | 2766 | (m (tramp-find-method method user host)) |
| 2771 | (funcall (nth 0 x) (nth 1 x))))) | 2767 | all-user-hosts) |
| 2772 | (tramp-get-completion-function m)) | 2768 | |
| 2773 | 2769 | (unless localname ;; Nothing to complete. | |
| 2774 | (setq result | 2770 | |
| 2775 | (append result | 2771 | (if (or user host) |
| 2776 | (mapcar | 2772 | |
| 2777 | (lambda (x) | 2773 | ;; Method dependent user / host combinations. |
| 2778 | (tramp-get-completion-user-host | 2774 | (progn |
| 2779 | method user host (nth 0 x) (nth 1 x))) | 2775 | (mapc |
| 2780 | (delq nil all-user-hosts))))) | 2776 | (lambda (x) |
| 2781 | 2777 | (setq all-user-hosts | |
| 2782 | ;; Possible methods. | 2778 | (append all-user-hosts |
| 2783 | (setq result | 2779 | (funcall (nth 0 x) (nth 1 x))))) |
| 2784 | (append result (tramp-get-completion-methods m hop))))))) | 2780 | (tramp-get-completion-function m)) |
| 2785 | 2781 | ||
| 2786 | ;; Unify list, add hop, remove nil elements. | 2782 | (setq result |
| 2787 | (dolist (elt result) | 2783 | (append result |
| 2788 | (when elt | 2784 | (mapcar |
| 2789 | (setq elt (replace-regexp-in-string | 2785 | (lambda (x) |
| 2790 | tramp-prefix-regexp (concat tramp-prefix-format hop) elt)) | 2786 | (tramp-get-completion-user-host |
| 2791 | (push (substring elt (length directory)) result1))) | 2787 | method user host (nth 0 x) (nth 1 x))) |
| 2792 | 2788 | (delq nil all-user-hosts))))) | |
| 2793 | ;; Complete local parts. | 2789 | |
| 2794 | (delete-dups | 2790 | ;; Possible methods. |
| 2795 | (append | 2791 | (setq result |
| 2796 | result1 | 2792 | (append result (tramp-get-completion-methods m hop))))))) |
| 2797 | (ignore-errors | 2793 | |
| 2798 | (tramp-run-real-handler | 2794 | ;; Unify list, add hop, remove nil elements. |
| 2799 | #'file-name-all-completions (list filename directory))))))) | 2795 | (dolist (elt result) |
| 2796 | (when elt | ||
| 2797 | (setq elt (replace-regexp-in-string | ||
| 2798 | tramp-prefix-regexp (concat tramp-prefix-format hop) elt)) | ||
| 2799 | (push (substring elt (length directory)) result1))) | ||
| 2800 | |||
| 2801 | ;; Complete local parts. | ||
| 2802 | (delete-dups | ||
| 2803 | (append | ||
| 2804 | result1 | ||
| 2805 | (ignore-errors | ||
| 2806 | (tramp-run-real-handler | ||
| 2807 | #'file-name-all-completions (list filename directory)))))))) | ||
| 2800 | 2808 | ||
| 2801 | ;; Method, host name and user name completion for a file. | 2809 | ;; Method, host name and user name completion for a file. |
| 2802 | (defun tramp-completion-handle-file-name-completion | 2810 | (defun tramp-completion-handle-file-name-completion |
| @@ -3002,6 +3010,10 @@ This function is added always in `tramp-get-completion-function' | |||
| 3002 | for all methods. Resulting data are derived from default settings." | 3010 | for all methods. Resulting data are derived from default settings." |
| 3003 | `((,(tramp-find-user method nil nil) ,(tramp-find-host method nil nil)))) | 3011 | `((,(tramp-find-user method nil nil) ,(tramp-find-host method nil nil)))) |
| 3004 | 3012 | ||
| 3013 | (defcustom tramp-completion-remote-containers nil | ||
| 3014 | "Whether container hosts in multi-hop paths should be queried for completions." | ||
| 3015 | :type 'boolean) | ||
| 3016 | |||
| 3005 | (defcustom tramp-completion-use-auth-sources auth-source-do-cache | 3017 | (defcustom tramp-completion-use-auth-sources auth-source-do-cache |
| 3006 | "Whether to use `auth-source-search' for completion of user and host names. | 3018 | "Whether to use `auth-source-search' for completion of user and host names. |
| 3007 | This could be disturbing, if it requires a password / passphrase, | 3019 | This could be disturbing, if it requires a password / passphrase, |