]> git.eshelyaron.com Git - emacs.git/commitdiff
Provide completion candidates for remote containers over a multi-hop
authorGene Goykhman <gene@indigo1.com>
Tue, 29 Aug 2023 08:10:06 +0000 (10:10 +0200)
committerMichael Albinus <michael.albinus@gmx.de>
Tue, 29 Aug 2023 08:10:06 +0000 (10:10 +0200)
* 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.

lisp/net/tramp-container.el
lisp/net/tramp.el

index 7f8d4473ad7898026e5ff97b9aa0378e59e3a397..e5ad3a55e27058d2c84e00e03ff19730c44ce0f9 100644 (file)
@@ -165,7 +165,12 @@ PROGRAM is the program to be run for \"ps\", either
 
 This function is used by `tramp-set-completion-function', please
 see its function help for a description of the format."
-  (when-let ((default-directory tramp-compat-temporary-file-directory)
+  ;; Set the default-directory to the directory of the last hop
+  ;; of a multi-hop path so that we can run the container program
+  ;; from there. If this is not a multi-hop path, run from the local
+  ;; temp file directory.
+  (when-let ((default-directory (or (and tramp-completion-remote-containers tramp--last-hop-directory)
+                                    tramp-compat-temporary-file-directory))
             (raw-list (shell-command-to-string
                        (concat program " ps --format '{{.ID}}\t{{.Names}}'")))
              (lines (split-string raw-list "\n" 'omit))
@@ -383,12 +388,12 @@ see its function help for a description of the format."
  (tramp-set-completion-function
   tramp-docker-method
   `((tramp-container--completion-function
-     ,(executable-find tramp-docker-program))))
+     ,tramp-docker-program)))
 
  (tramp-set-completion-function
   tramp-podman-method
   `((tramp-container--completion-function
-     ,(executable-find tramp-podman-program))))
+     ,tramp-podman-program)))
 
  (tramp-set-completion-function
   tramp-kubernetes-method
index 05d28e8494f3768b771007a678fe8639b10d5c27..01a8356697509bb5281ace851d1b188b093964a8 100644 (file)
@@ -81,6 +81,8 @@
 (defvar tramp-file-name-regexp)
 (defvar tramp-completion-method-regexp)
 (defvar tramp-completion-file-name-regexp)
+(defvar tramp--last-hop-directory nil
+  "Tracks the directory from which to run container executable programs.")
 
 ;; Reload `tramp-compat' when we reload `tramp-autoloads' of the GNU
 ;; ELPA package.
@@ -2141,8 +2143,10 @@ Example:
                      tramp-dns-sd-service-regexp (nth 1 (car v))))
                    ;; Method.
                    ((string-equal method (nth 1 (car v))))
-                   ;; Configuration file or empty string.
-                   (t (file-exists-p (nth 1 (car v))))))
+                    ;; FIXME: for now do not check local existence of file
+                    ;; to allow allow arbitrary container program executable
+                    ;; name for container completion on remote systems.
+                    (t t)))
        (setq r (delete (car v) r)))
       (setq v (cdr v)))
 
@@ -2728,16 +2732,8 @@ not in completion mode."
   "Like `file-name-all-completions' for partial Tramp files."
   (let ((fullname
         (tramp-drop-volume-letter (expand-file-name filename directory)))
-       ;; When `tramp-syntax' is `simplified', we need a default method.
-       (tramp-default-method
-        (and (string-empty-p tramp-postfix-method-format)
-             tramp-default-method))
-       (tramp-default-method-alist
-        (and (string-empty-p tramp-postfix-method-format)
-             tramp-default-method-alist))
-       tramp-default-user tramp-default-user-alist
-       tramp-default-host tramp-default-host-alist
-       hop result result1)
+       (directory (tramp-drop-volume-letter directory))
+       tramp--last-hop-directory hop result result1)
 
     ;; Suppress hop from completion.
     (when (string-match
@@ -2747,56 +2743,68 @@ not in completion mode."
                      (regexp tramp-postfix-hop-regexp))))
           fullname)
       (setq hop (match-string 1 fullname)
-           fullname (replace-match "" nil nil fullname 1)))
-
-    ;; Possible completion structures.
-    (dolist (elt (tramp-completion-dissect-file-name fullname))
-      (let* ((method (tramp-file-name-method elt))
-            (user (tramp-file-name-user elt))
-            (host (tramp-file-name-host elt))
-            (localname (tramp-file-name-localname elt))
-            (m (tramp-find-method method user host))
-            all-user-hosts)
-
-       (unless localname ;; Nothing to complete.
-
-         (if (or user host)
-
-             ;; Method dependent user / host combinations.
-             (progn
-               (mapc
-                (lambda (x)
-                  (setq all-user-hosts
-                        (append all-user-hosts
-                                (funcall (nth 0 x) (nth 1 x)))))
-                (tramp-get-completion-function m))
-
-               (setq result
-                     (append result
-                             (mapcar
-                              (lambda (x)
-                                (tramp-get-completion-user-host
-                                 method user host (nth 0 x) (nth 1 x)))
-                              (delq nil all-user-hosts)))))
-
-           ;; Possible methods.
-           (setq result
-                 (append result (tramp-get-completion-methods m hop)))))))
-
-    ;; Unify list, add hop, remove nil elements.
-    (dolist (elt result)
-      (when elt
-       (setq elt (replace-regexp-in-string
-                  tramp-prefix-regexp (concat tramp-prefix-format hop) elt))
-       (push (substring elt (length directory)) result1)))
-
-    ;; Complete local parts.
-    (delete-dups
-     (append
-      result1
-      (ignore-errors
-        (tramp-run-real-handler
-        #'file-name-all-completions (list filename directory)))))))
+           fullname (replace-match "" nil nil fullname 1)
+           tramp--last-hop-directory
+           (tramp-make-tramp-file-name (tramp-dissect-hop-name hop))))
+
+    (let (;; When `tramp-syntax' is `simplified', we need a default method.
+         (tramp-default-method
+          (and (string-empty-p tramp-postfix-method-format)
+               tramp-default-method))
+         (tramp-default-method-alist
+          (and (string-empty-p tramp-postfix-method-format)
+               tramp-default-method-alist))
+         tramp-default-user tramp-default-user-alist
+         tramp-default-host tramp-default-host-alist)
+
+      ;; Possible completion structures.
+      (dolist (elt (tramp-completion-dissect-file-name fullname))
+        (let* ((method (tramp-file-name-method elt))
+              (user (tramp-file-name-user elt))
+              (host (tramp-file-name-host elt))
+              (localname (tramp-file-name-localname elt))
+              (m (tramp-find-method method user host))
+              all-user-hosts)
+
+         (unless localname ;; Nothing to complete.
+
+           (if (or user host)
+
+               ;; Method dependent user / host combinations.
+               (progn
+                 (mapc
+                  (lambda (x)
+                    (setq all-user-hosts
+                          (append all-user-hosts
+                                  (funcall (nth 0 x) (nth 1 x)))))
+                  (tramp-get-completion-function m))
+
+                 (setq result
+                       (append result
+                               (mapcar
+                                (lambda (x)
+                                  (tramp-get-completion-user-host
+                                   method user host (nth 0 x) (nth 1 x)))
+                                (delq nil all-user-hosts)))))
+
+             ;; Possible methods.
+             (setq result
+                   (append result (tramp-get-completion-methods m hop)))))))
+
+      ;; Unify list, add hop, remove nil elements.
+      (dolist (elt result)
+        (when elt
+         (setq elt (replace-regexp-in-string
+                    tramp-prefix-regexp (concat tramp-prefix-format hop) elt))
+         (push (substring elt (length directory)) result1)))
+
+      ;; Complete local parts.
+      (delete-dups
+       (append
+        result1
+        (ignore-errors
+          (tramp-run-real-handler
+          #'file-name-all-completions (list filename directory))))))))
 
 ;; Method, host name and user name completion for a file.
 (defun tramp-completion-handle-file-name-completion
@@ -3002,6 +3010,10 @@ This function is added always in `tramp-get-completion-function'
 for all methods.  Resulting data are derived from default settings."
   `((,(tramp-find-user method nil nil) ,(tramp-find-host method nil nil))))
 
+(defcustom tramp-completion-remote-containers nil
+  "Whether container hosts in multi-hop paths should be queried for completions."
+  :type 'boolean)
+
 (defcustom tramp-completion-use-auth-sources auth-source-do-cache
   "Whether to use `auth-source-search' for completion of user and host names.
 This could be disturbing, if it requires a password / passphrase,