]> git.eshelyaron.com Git - emacs.git/commitdiff
Be more cautious in completing Eshell variable assignments
authorJim Porter <jporterbugs@gmail.com>
Sat, 25 Feb 2023 05:49:54 +0000 (21:49 -0800)
committerJim Porter <jporterbugs@gmail.com>
Sun, 26 Feb 2023 04:38:55 +0000 (20:38 -0800)
Previously, Eshell treated cases like the second argument in "tar
--directory=dir" as a variable assignment, but that prevented
'pcomplete/tar' from implementing its own completion for that
argument (bug#61778).

* lisp/eshell/esh-var.el (eshell-complete-variable-assignment): Only
handle completion when all initial arguments are variable assignments.

* test/lisp/eshell/em-cmpl-tests.el
(em-cmpl-test/variable-assign-completion/non-assignment): New test.

lisp/eshell/esh-var.el
test/lisp/eshell/em-cmpl-tests.el

index 0031324b53705ea6920e6ff2ac50de2e993cfaba..5d6299af5641d14c18b6da22954da8da4c594c35 100644 (file)
@@ -862,11 +862,19 @@ START and END."
 
 (defun eshell-complete-variable-assignment ()
   "If there is a variable assignment, allow completion of entries."
-  (let ((arg (pcomplete-actual-arg)) pos)
-    (when (string-match (concat "\\`" eshell-variable-name-regexp "=") arg)
-      (setq pos (match-end 0))
-      (if (string-match "\\(:\\)[^:]*\\'" arg)
-         (setq pos (match-end 1)))
+  (catch 'not-assignment
+    ;; The current argument can only be a variable assignment if all
+    ;; arguments leading up to it are also variable assignments.  See
+    ;; `eshell-handle-local-variables'.
+    (dotimes (offset (1+ pcomplete-index))
+      (unless (string-match (concat "\\`" eshell-variable-name-regexp "=")
+                            (pcomplete-actual-arg 'first offset))
+        (throw 'not-assignment nil)))
+    ;; We have a variable assignment.  Handle it.
+    (let ((arg (pcomplete-actual-arg))
+          (pos (match-end 0)))
+      (when (string-match "\\(:\\)[^:]*\\'" arg)
+       (setq pos (match-end 1)))
       (setq pcomplete-stub (substring arg pos))
       (throw 'pcomplete-completions (pcomplete-entries)))))
 
index ecab73328227db193b835962096784f1e6c203cf..be2199c0464f8eba1de94e322d446768c8d8f44c 100644 (file)
@@ -217,6 +217,20 @@ See <lisp/eshell/esh-var.el>."
      (should (equal (eshell-insert-and-complete "VAR=f")
                     "VAR=file.txt ")))))
 
+(ert-deftest em-cmpl-test/variable-assign-completion/non-assignment ()
+  "Test completion of things that look like variable assignment, but aren't.
+For example, the second argument in \"tar --directory=dir\" looks
+like it could be a variable assignment, but it's not.  We should
+let `pcomplete-tar' handle it instead.
+
+See <lisp/eshell/esh-var.el>."
+  (with-temp-eshell
+   (ert-with-temp-directory default-directory
+     (write-region nil nil (expand-file-name "file.txt"))
+     (make-directory "dir")
+     (should (equal (eshell-insert-and-complete "tar --directory=")
+                    "tar --directory=dir/")))))
+
 (ert-deftest em-cmpl-test/user-ref-completion ()
   "Test completion of user references like \"~user\".
 See <lisp/eshell/em-dirs.el>."