]> git.eshelyaron.com Git - emacs.git/commitdiff
Fix Eshell handling of remote files like "/ssh:remote:~/file.txt"
authorJim Porter <jporterbugs@gmail.com>
Sun, 5 May 2024 20:09:08 +0000 (13:09 -0700)
committerEshel Yaron <me@eshelyaron.com>
Mon, 6 May 2024 16:56:04 +0000 (18:56 +0200)
* lisp/eshell/em-glob.el (eshell-glob-convert): Use 'concat' instead of
'file-name-concat' to avoid extraneous slashes.
(eshell-extended-glob): Bail out if we didn't find a glob after all.

* test/lisp/eshell/em-glob-tests.el (tramp): Require.
(em-glob-test/convert/remote-start-directory): Use the mock remote
connection.
(em-glob-test/remote-user-directory): New test.

(cherry picked from commit 1529ad0315f8d4a96ca07969c1c91c1c50bb6075)

lisp/eshell/em-glob.el
test/lisp/eshell/em-glob-tests.el

index 7fc6958a00f498a9fd38d29136ed2ea3e2c708e0..89a40151d003813bc93a31bfdf1a7c0508e470a8 100644 (file)
@@ -317,7 +317,7 @@ The result is a list of three elements:
                   result)
           ;; We haven't seen a glob yet, so instead append to the start
           ;; directory.
-          (setq start-dir (file-name-concat start-dir (car globs))))
+          (setq start-dir (concat start-dir (car globs))))
         (setq last-saw-recursion nil))
       (setq globs (cdr globs)))
     (list start-dir
@@ -341,16 +341,24 @@ Mainly they are not supported because file matching is done with Emacs
 regular expressions, and these cannot support the above constructs."
   (let ((globs (eshell-glob-convert glob))
         eshell-glob-matches message-shown)
-    (unwind-protect
-        (apply #'eshell-glob-entries globs)
-      (if message-shown
-         (message nil)))
-    (or (and eshell-glob-matches (sort eshell-glob-matches #'string<))
-       (if eshell-error-if-no-glob
-           (error "No matches found: %s" glob)
-          (if eshell-glob-splice-results
-              (list glob)
-            glob)))))
+    (if (null (cadr globs))
+        ;; If, after examining GLOB, there are no actual globs, just
+        ;; bail out.  This can happen for remote file names using "~",
+        ;; like "/ssh:remote:~/file.txt".  During parsing, we can't
+        ;; always be sure if the "~" is a home directory reference or
+        ;; part of a glob (e.g. if the argument was assembled from
+        ;; variables).
+        glob
+      (unwind-protect
+          (apply #'eshell-glob-entries globs)
+        (if message-shown
+            (message nil)))
+      (or (and eshell-glob-matches (sort eshell-glob-matches #'string<))
+          (if eshell-error-if-no-glob
+              (error "No matches found: %s" glob)
+            (if eshell-glob-splice-results
+                (list glob)
+              glob))))))
 
 ;; FIXME does this really need to abuse eshell-glob-matches, message-shown?
 (defun eshell-glob-entries (path globs only-dirs)
index fc460a59eeda8e1235a8cb26298c27c2ad356b9c..40cdfd1a67661aa370783cb21c18f25cc1c566ce 100644 (file)
@@ -23,6 +23,7 @@
 
 ;;; Code:
 
+(require 'tramp)
 (require 'ert)
 (require 'em-glob)
 
@@ -138,9 +139,12 @@ value of `eshell-glob-splice-results'."
 
 (ert-deftest em-glob-test/convert/remote-start-directory ()
   "Test converting a glob starting in a remote directory."
-  (should (equal (eshell-glob-convert "/ssh:nowhere.invalid:some/where/*.el")
-                 '("/ssh:nowhere.invalid:/some/where/"
-                   (("\\`.*\\.el\\'" . "\\`\\.")) nil))))
+  (skip-unless (eshell-tests-remote-accessible-p))
+  (let* ((default-directory ert-remote-temporary-file-directory)
+         (remote (file-remote-p default-directory)))
+    (should (equal (eshell-glob-convert (format "%s/some/where/*.el" remote))
+                 `(,(format "%s/some/where/" remote)
+                   (("\\`.*\\.el\\'" . "\\`\\.")) nil)))))
 
 \f
 ;; Glob matching
@@ -288,4 +292,13 @@ value of `eshell-glob-splice-results'."
     (let ((eshell-error-if-no-glob t))
       (should-error (eshell-extended-glob "*.txt")))))
 
+(ert-deftest em-glob-test/remote-user-directory ()
+  "Test that remote directories using \"~\" pass through unchanged."
+  (skip-unless (eshell-tests-remote-accessible-p))
+  (let* ((default-directory ert-remote-temporary-file-directory)
+         (remote (file-remote-p default-directory))
+         (eshell-error-if-no-glob t))
+    (should (equal (eshell-extended-glob (format "%s~/file.txt" remote))
+                   (format "%s~/file.txt" remote)))))
+
 ;; em-glob-tests.el ends here