summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJim Porter <jporterbugs@gmail.com>2024-05-05 13:09:08 -0700
committerJim Porter <jporterbugs@gmail.com>2024-05-05 13:21:55 -0700
commit1529ad0315f8d4a96ca07969c1c91c1c50bb6075 (patch)
tree71a648b495d91485b4ca26c91ee3a4d98ce5dfa8
parent451863adf942bf4e3c1b9346c0f37e546e16b1fd (diff)
downloademacs-1529ad0315f8d4a96ca07969c1c91c1c50bb6075.tar.gz
Fix Eshell handling of remote files like "/ssh:remote:~/file.txt"
* 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.
-rw-r--r--lisp/eshell/em-glob.el30
-rw-r--r--test/lisp/eshell/em-glob-tests.el19
2 files changed, 35 insertions, 14 deletions
diff --git a/lisp/eshell/em-glob.el b/lisp/eshell/em-glob.el
index 7fc6958a00f..89a40151d00 100644
--- a/lisp/eshell/em-glob.el
+++ b/lisp/eshell/em-glob.el
@@ -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)
diff --git a/test/lisp/eshell/em-glob-tests.el b/test/lisp/eshell/em-glob-tests.el
index fc460a59eed..40cdfd1a676 100644
--- a/test/lisp/eshell/em-glob-tests.el
+++ b/test/lisp/eshell/em-glob-tests.el
@@ -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)))))
;; 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