diff options
| -rw-r--r-- | lisp/eshell/em-glob.el | 141 | ||||
| -rw-r--r-- | lisp/eshell/em-ls.el | 19 | ||||
| -rw-r--r-- | test/lisp/eshell/em-glob-tests.el | 48 |
3 files changed, 140 insertions, 68 deletions
diff --git a/lisp/eshell/em-glob.el b/lisp/eshell/em-glob.el index 57bb0c53b57..b94c4e3ed46 100644 --- a/lisp/eshell/em-glob.el +++ b/lisp/eshell/em-glob.el | |||
| @@ -149,23 +149,48 @@ This mimics the behavior of zsh if non-nil, but bash if nil." | |||
| 149 | "Don't glob the command argument. Reflect this by modifying TERMS." | 149 | "Don't glob the command argument. Reflect this by modifying TERMS." |
| 150 | (ignore | 150 | (ignore |
| 151 | (pcase (car terms) | 151 | (pcase (car terms) |
| 152 | ((or `(eshell-extended-glob ,term) | 152 | ((or `(eshell-expand-glob ,term) |
| 153 | `(eshell-splice-args (eshell-extended-glob ,term))) | 153 | `(eshell-splice-args (eshell-expand-glob ,term))) |
| 154 | (setcar terms term))))) | 154 | (setcar terms term))))) |
| 155 | 155 | ||
| 156 | (defun eshell-add-glob-modifier () | 156 | (defun eshell-add-glob-modifier () |
| 157 | "Add `eshell-extended-glob' to the argument modifier list." | 157 | "Add `eshell-expand-glob' to the argument modifier list." |
| 158 | (when eshell-glob-splice-results | 158 | (when eshell-glob-splice-results |
| 159 | (add-hook 'eshell-current-modifiers #'eshell-splice-args 99)) | 159 | (add-hook 'eshell-current-modifiers #'eshell-splice-args 99)) |
| 160 | (add-hook 'eshell-current-modifiers #'eshell-extended-glob)) | 160 | (add-hook 'eshell-current-modifiers #'eshell-expand-glob)) |
| 161 | 161 | ||
| 162 | (defun eshell-parse-glob-chars () | 162 | (defun eshell-parse-glob-chars () |
| 163 | "Parse a globbing delimiter. | 163 | "Parse a globbing character." |
| 164 | The character is not advanced for ordinary globbing characters, so | ||
| 165 | that other function may have a chance to override the globbing | ||
| 166 | interpretation." | ||
| 167 | (when (memq (char-after) eshell-glob-chars-list) | 164 | (when (memq (char-after) eshell-glob-chars-list) |
| 168 | (ignore (eshell-add-glob-modifier)))) | 165 | (eshell-add-glob-modifier) |
| 166 | (prog1 | ||
| 167 | (propertize (char-to-string (char-after)) 'eshell-glob-char t) | ||
| 168 | (forward-char)))) | ||
| 169 | |||
| 170 | (defvar eshell-glob-chars-regexp nil) | ||
| 171 | (defsubst eshell-glob-chars-regexp () | ||
| 172 | "Return the lazily-created value for `eshell-glob-chars-regexp'." | ||
| 173 | (or eshell-glob-chars-regexp | ||
| 174 | (setq-local eshell-glob-chars-regexp | ||
| 175 | (rx-to-string `(+ (any ,@eshell-glob-chars-list)) t)))) | ||
| 176 | |||
| 177 | (defun eshell-parse-glob-string (glob) | ||
| 178 | "Add text properties to glob characters in GLOB and return the result." | ||
| 179 | (let ((regexp (rx-to-string | ||
| 180 | `(or (seq (group-n 1 "\\") anychar) | ||
| 181 | (group-n 2 (regexp ,(eshell-glob-chars-regexp)))) | ||
| 182 | t))) | ||
| 183 | (with-temp-buffer | ||
| 184 | (insert glob) | ||
| 185 | (goto-char (point-min)) | ||
| 186 | (while (re-search-forward regexp nil t) | ||
| 187 | (cond | ||
| 188 | ((match-beginning 1) ; Remove backslash escape. | ||
| 189 | (delete-region (match-beginning 1) (match-end 1))) | ||
| 190 | ((match-beginning 2) ; Propertize globbing character. | ||
| 191 | (put-text-property (match-beginning 2) (match-end 2) | ||
| 192 | 'eshell-glob-char t)))) | ||
| 193 | (buffer-string)))) | ||
| 169 | 194 | ||
| 170 | (defvar eshell-glob-matches) | 195 | (defvar eshell-glob-matches) |
| 171 | (defvar message-shown) | 196 | (defvar message-shown) |
| @@ -174,12 +199,16 @@ interpretation." | |||
| 174 | '(("**/" . recurse) | 199 | '(("**/" . recurse) |
| 175 | ("***/" . recurse-symlink))) | 200 | ("***/" . recurse-symlink))) |
| 176 | 201 | ||
| 177 | (defvar eshell-glob-chars-regexp nil) | 202 | (defsubst eshell--glob-char-p (string index) |
| 178 | (defsubst eshell-glob-chars-regexp () | 203 | (get-text-property index 'eshell-glob-char string)) |
| 179 | "Return the lazily-created value for `eshell-glob-chars-regexp'." | 204 | |
| 180 | (or eshell-glob-chars-regexp | 205 | (defsubst eshell--contains-glob-char-p (string) |
| 181 | (setq-local eshell-glob-chars-regexp | 206 | (text-property-any 0 (length string) 'eshell-glob-char t string)) |
| 182 | (rx-to-string `(+ (any ,@eshell-glob-chars-list)) t)))) | 207 | |
| 208 | (defun eshell--all-glob-chars-p (string) | ||
| 209 | (and (length> string 0) | ||
| 210 | (not (text-property-not-all | ||
| 211 | 0 (length string) 'eshell-glob-char t string)))) | ||
| 183 | 212 | ||
| 184 | (defun eshell-glob-regexp (pattern) | 213 | (defun eshell-glob-regexp (pattern) |
| 185 | "Convert glob-pattern PATTERN to a regular expression. | 214 | "Convert glob-pattern PATTERN to a regular expression. |
| @@ -196,9 +225,10 @@ The basic syntax is: | |||
| 196 | [a-b] [a-b] matches a character or range | 225 | [a-b] [a-b] matches a character or range |
| 197 | [^a] [^a] excludes a character or range | 226 | [^a] [^a] excludes a character or range |
| 198 | 227 | ||
| 199 | If any characters in PATTERN have the text property `escaped' | 228 | This function only considers in PATTERN that have the text property |
| 200 | set to true, then these characters will match themselves in the | 229 | `eshell-glob-char' set to t for conversion from glob to regexp syntax. |
| 201 | resulting regular expression." | 230 | All other characters are treated as literals. See also |
| 231 | `eshell-parse-glob-chars' and `eshell-parse-glob-string'." | ||
| 202 | (let ((matched-in-pattern 0) ; How much of PATTERN handled | 232 | (let ((matched-in-pattern 0) ; How much of PATTERN handled |
| 203 | regexp) | 233 | regexp) |
| 204 | (while (string-match (eshell-glob-chars-regexp) | 234 | (while (string-match (eshell-glob-chars-regexp) |
| @@ -209,7 +239,7 @@ resulting regular expression." | |||
| 209 | (concat regexp | 239 | (concat regexp |
| 210 | (regexp-quote | 240 | (regexp-quote |
| 211 | (substring pattern matched-in-pattern op-begin)))) | 241 | (substring pattern matched-in-pattern op-begin)))) |
| 212 | (if (get-text-property op-begin 'escaped pattern) | 242 | (if (not (eshell--glob-char-p pattern op-begin)) |
| 213 | (setq regexp (concat regexp | 243 | (setq regexp (concat regexp |
| 214 | (regexp-quote (char-to-string op-char))) | 244 | (regexp-quote (char-to-string op-char))) |
| 215 | matched-in-pattern (1+ op-begin)) | 245 | matched-in-pattern (1+ op-begin)) |
| @@ -229,6 +259,7 @@ resulting regular expression." | |||
| 229 | 259 | ||
| 230 | (defun eshell-glob-p (pattern) | 260 | (defun eshell-glob-p (pattern) |
| 231 | "Return non-nil if PATTERN has any special glob characters." | 261 | "Return non-nil if PATTERN has any special glob characters." |
| 262 | (declare (obsolete nil "31.1")) | ||
| 232 | ;; "~" is an infix globbing character, so one at the start of a glob | 263 | ;; "~" is an infix globbing character, so one at the start of a glob |
| 233 | ;; must be a literal. | 264 | ;; must be a literal. |
| 234 | (let ((start (if (string-prefix-p "~" pattern) 1 0))) | 265 | (let ((start (if (string-prefix-p "~" pattern) 1 0))) |
| @@ -249,8 +280,8 @@ include, and the second for ones to exclude." | |||
| 249 | ;; Split the glob if it contains a negation like x~y. | 280 | ;; Split the glob if it contains a negation like x~y. |
| 250 | (while (and (eq incl glob) | 281 | (while (and (eq incl glob) |
| 251 | (setq index (string-search "~" glob index))) | 282 | (setq index (string-search "~" glob index))) |
| 252 | (if (or (get-text-property index 'escaped glob) | 283 | (if (or (not (eshell--glob-char-p glob index)) |
| 253 | (or (= (1+ index) len))) | 284 | (= (1+ index) len)) |
| 254 | (setq index (1+ index)) | 285 | (setq index (1+ index)) |
| 255 | (setq incl (substring glob 0 index) | 286 | (setq incl (substring glob 0 index) |
| 256 | excl (substring glob (1+ index))))) | 287 | excl (substring glob (1+ index))))) |
| @@ -294,13 +325,18 @@ The result is a list of three elements: | |||
| 294 | (setq start-dir (pop globs)) | 325 | (setq start-dir (pop globs)) |
| 295 | (setq start-dir (file-name-as-directory "."))) | 326 | (setq start-dir (file-name-as-directory "."))) |
| 296 | (while globs | 327 | (while globs |
| 297 | (if-let* ((recurse (cdr (assoc (car globs) | 328 | ;; "~" is an infix globbing character, so one at the start of a |
| 298 | eshell-glob-recursive-alist)))) | 329 | ;; glob component must be a literal. |
| 330 | (when (eq (aref (car globs) 0) ?~) | ||
| 331 | (remove-text-properties 0 1 '(eshell-glob-char) (car globs))) | ||
| 332 | (if-let* ((recurse (cdr (assoc (car globs) eshell-glob-recursive-alist))) | ||
| 333 | ((eshell--all-glob-chars-p | ||
| 334 | (string-trim-right (car globs) "/")))) | ||
| 299 | (if last-saw-recursion | 335 | (if last-saw-recursion |
| 300 | (setcar result recurse) | 336 | (setcar result recurse) |
| 301 | (push recurse result) | 337 | (push recurse result) |
| 302 | (setq last-saw-recursion t)) | 338 | (setq last-saw-recursion t)) |
| 303 | (if (or result (eshell-glob-p (car globs))) | 339 | (if (or result (eshell--contains-glob-char-p (car globs))) |
| 304 | (push (eshell-glob-convert-1 (car globs) (null (cdr globs))) | 340 | (push (eshell-glob-convert-1 (car globs) (null (cdr globs))) |
| 305 | result) | 341 | result) |
| 306 | ;; We haven't seen a glob yet, so instead append to the start | 342 | ;; We haven't seen a glob yet, so instead append to the start |
| @@ -312,6 +348,38 @@ The result is a list of three elements: | |||
| 312 | (nreverse result) | 348 | (nreverse result) |
| 313 | isdir))) | 349 | isdir))) |
| 314 | 350 | ||
| 351 | (defun eshell-expand-glob (glob) | ||
| 352 | "Return a list of files matched by GLOB. | ||
| 353 | Each globbing character in GLOB should have a non-nil value for the text | ||
| 354 | property `eshell-glob-char' (e.g. by `eshell-parse-glob-chars') in order | ||
| 355 | for it to have syntactic meaning; otherwise, this function treats the | ||
| 356 | character literally. | ||
| 357 | |||
| 358 | This function is primarily intended for use within Eshell command | ||
| 359 | forms. If you want to use an ordinary string as a glob, use | ||
| 360 | `eshell-extended-glob' instead." | ||
| 361 | (let ((globs (eshell-glob-convert glob)) | ||
| 362 | eshell-glob-matches message-shown) | ||
| 363 | (unwind-protect | ||
| 364 | ;; After examining GLOB, make sure we actually got some globs | ||
| 365 | ;; before computing the results. We can get zero globs for | ||
| 366 | ;; remote file names using "~", like "/ssh:remote:~/file.txt". | ||
| 367 | ;; During Eshell argument parsing, we can't always be sure if | ||
| 368 | ;; the "~" is a home directory reference or part of a glob | ||
| 369 | ;; (e.g. if the argument was assembled from variables). | ||
| 370 | (when (cadr globs) | ||
| 371 | (apply #'eshell-glob-entries globs)) | ||
| 372 | (when message-shown | ||
| 373 | (message nil))) | ||
| 374 | (cond | ||
| 375 | (eshell-glob-matches | ||
| 376 | (sort eshell-glob-matches #'string<)) | ||
| 377 | ((and eshell-error-if-no-glob (cadr globs)) | ||
| 378 | (error "No matches found: %s" glob)) | ||
| 379 | (t | ||
| 380 | (let ((result (substring-no-properties glob))) | ||
| 381 | (if eshell-glob-splice-results (list result) result)))))) | ||
| 382 | |||
| 315 | (defun eshell-extended-glob (glob) | 383 | (defun eshell-extended-glob (glob) |
| 316 | "Return a list of files matched by GLOB. | 384 | "Return a list of files matched by GLOB. |
| 317 | If no files match, signal an error (if `eshell-error-if-no-glob' | 385 | If no files match, signal an error (if `eshell-error-if-no-glob' |
| @@ -327,26 +395,9 @@ syntax. Things that are not supported are: | |||
| 327 | 395 | ||
| 328 | Mainly they are not supported because file matching is done with Emacs | 396 | Mainly they are not supported because file matching is done with Emacs |
| 329 | regular expressions, and these cannot support the above constructs." | 397 | regular expressions, and these cannot support the above constructs." |
| 330 | (let ((globs (eshell-glob-convert glob)) | 398 | (eshell-expand-glob (eshell-parse-glob-string glob))) |
| 331 | eshell-glob-matches message-shown) | 399 | |
| 332 | (if (null (cadr globs)) | 400 | (defconst eshell--glob-anything (eshell-parse-glob-string "*")) |
| 333 | ;; If, after examining GLOB, there are no actual globs, just | ||
| 334 | ;; bail out. This can happen for remote file names using "~", | ||
| 335 | ;; like "/ssh:remote:~/file.txt". During parsing, we can't | ||
| 336 | ;; always be sure if the "~" is a home directory reference or | ||
| 337 | ;; part of a glob (e.g. if the argument was assembled from | ||
| 338 | ;; variables). | ||
| 339 | (if eshell-glob-splice-results (list glob) glob) | ||
| 340 | (unwind-protect | ||
| 341 | (apply #'eshell-glob-entries globs) | ||
| 342 | (if message-shown | ||
| 343 | (message nil))) | ||
| 344 | (or (and eshell-glob-matches (sort eshell-glob-matches #'string<)) | ||
| 345 | (if eshell-error-if-no-glob | ||
| 346 | (error "No matches found: %s" glob) | ||
| 347 | (if eshell-glob-splice-results | ||
| 348 | (list glob) | ||
| 349 | glob)))))) | ||
| 350 | 401 | ||
| 351 | ;; FIXME does this really need to abuse eshell-glob-matches, message-shown? | 402 | ;; FIXME does this really need to abuse eshell-glob-matches, message-shown? |
| 352 | (defun eshell-glob-entries (path globs only-dirs) | 403 | (defun eshell-glob-entries (path globs only-dirs) |
| @@ -363,7 +414,7 @@ directories and files." | |||
| 363 | (if (rassq (car globs) eshell-glob-recursive-alist) | 414 | (if (rassq (car globs) eshell-glob-recursive-alist) |
| 364 | (setq recurse-p (car globs) | 415 | (setq recurse-p (car globs) |
| 365 | glob (or (cadr globs) | 416 | glob (or (cadr globs) |
| 366 | (eshell-glob-convert-1 "*" t)) | 417 | (eshell-glob-convert-1 eshell--glob-anything t)) |
| 367 | glob-remainder (cddr globs)) | 418 | glob-remainder (cddr globs)) |
| 368 | (setq glob (car globs) | 419 | (setq glob (car globs) |
| 369 | glob-remainder (cdr globs))) | 420 | glob-remainder (cdr globs))) |
diff --git a/lisp/eshell/em-ls.el b/lisp/eshell/em-ls.el index 8bf2e20d320..e8cdb9c82c4 100644 --- a/lisp/eshell/em-ls.el +++ b/lisp/eshell/em-ls.el | |||
| @@ -246,6 +246,17 @@ scope during the evaluation of TEST-SEXP." | |||
| 246 | 246 | ||
| 247 | (declare-function eshell-extended-glob "em-glob" (glob)) | 247 | (declare-function eshell-extended-glob "em-glob" (glob)) |
| 248 | (defvar eshell-error-if-no-glob) | 248 | (defvar eshell-error-if-no-glob) |
| 249 | (defvar eshell-glob-splice-results) | ||
| 250 | |||
| 251 | (defun eshell-ls--expand-wildcards (file) | ||
| 252 | "Expand the shell wildcards in FILE if any." | ||
| 253 | (if (and (atom file) | ||
| 254 | (not (file-exists-p file))) | ||
| 255 | (let ((eshell-error-if-no-glob t) | ||
| 256 | ;; Ensure `eshell-extended-glob' returns a list. | ||
| 257 | (eshell-glob-splice-results t)) | ||
| 258 | (mapcar #'file-relative-name (eshell-extended-glob file))) | ||
| 259 | (list (file-relative-name file)))) | ||
| 249 | 260 | ||
| 250 | (defun eshell-ls--insert-directory | 261 | (defun eshell-ls--insert-directory |
| 251 | (orig-fun file switches &optional wildcard full-directory-p) | 262 | (orig-fun file switches &optional wildcard full-directory-p) |
| @@ -277,13 +288,7 @@ instead." | |||
| 277 | (require 'em-glob) | 288 | (require 'em-glob) |
| 278 | (let* ((insert-func 'insert) | 289 | (let* ((insert-func 'insert) |
| 279 | (error-func 'insert) | 290 | (error-func 'insert) |
| 280 | (eshell-error-if-no-glob t) | 291 | (target (eshell-ls--expand-wildcards file)) |
| 281 | (target ; Expand the shell wildcards if any. | ||
| 282 | (if (and (atom file) | ||
| 283 | (string-match "[[?*]" file) | ||
| 284 | (not (file-exists-p file))) | ||
| 285 | (mapcar #'file-relative-name (eshell-extended-glob file)) | ||
| 286 | (file-relative-name file))) | ||
| 287 | (switches | 292 | (switches |
| 288 | (append eshell-ls-dired-initial-args | 293 | (append eshell-ls-dired-initial-args |
| 289 | (and (or (consp dired-directory) wildcard) (list "-d")) | 294 | (and (or (consp dired-directory) wildcard) (list "-d")) |
diff --git a/test/lisp/eshell/em-glob-tests.el b/test/lisp/eshell/em-glob-tests.el index 16ae9be1bce..57343eced6b 100644 --- a/test/lisp/eshell/em-glob-tests.el +++ b/test/lisp/eshell/em-glob-tests.el | |||
| @@ -134,17 +134,19 @@ value of `eshell-glob-splice-results'." | |||
| 134 | 134 | ||
| 135 | (ert-deftest em-glob-test/convert/current-start-directory () | 135 | (ert-deftest em-glob-test/convert/current-start-directory () |
| 136 | "Test converting a glob starting in the current directory." | 136 | "Test converting a glob starting in the current directory." |
| 137 | (should (equal (eshell-glob-convert "*.el") | 137 | (should (equal (eshell-glob-convert (eshell-parse-glob-string "*.el")) |
| 138 | '("./" (("\\`.*\\.el\\'" . "\\`\\.")) nil)))) | 138 | '("./" (("\\`.*\\.el\\'" . "\\`\\.")) nil)))) |
| 139 | 139 | ||
| 140 | (ert-deftest em-glob-test/convert/relative-start-directory () | 140 | (ert-deftest em-glob-test/convert/relative-start-directory () |
| 141 | "Test converting a glob starting in a relative directory." | 141 | "Test converting a glob starting in a relative directory." |
| 142 | (should (equal (eshell-glob-convert "some/where/*.el") | 142 | (should (equal (eshell-glob-convert |
| 143 | (eshell-parse-glob-string "some/where/*.el")) | ||
| 143 | '("./some/where/" (("\\`.*\\.el\\'" . "\\`\\.")) nil)))) | 144 | '("./some/where/" (("\\`.*\\.el\\'" . "\\`\\.")) nil)))) |
| 144 | 145 | ||
| 145 | (ert-deftest em-glob-test/convert/absolute-start-directory () | 146 | (ert-deftest em-glob-test/convert/absolute-start-directory () |
| 146 | "Test converting a glob starting in an absolute directory." | 147 | "Test converting a glob starting in an absolute directory." |
| 147 | (should (equal (eshell-glob-convert "/some/where/*.el") | 148 | (should (equal (eshell-glob-convert |
| 149 | (eshell-parse-glob-string "/some/where/*.el")) | ||
| 148 | '("/some/where/" (("\\`.*\\.el\\'" . "\\`\\.")) nil)))) | 150 | '("/some/where/" (("\\`.*\\.el\\'" . "\\`\\.")) nil)))) |
| 149 | 151 | ||
| 150 | (ert-deftest em-glob-test/convert/remote-start-directory () | 152 | (ert-deftest em-glob-test/convert/remote-start-directory () |
| @@ -152,16 +154,30 @@ value of `eshell-glob-splice-results'." | |||
| 152 | (skip-unless (eshell-tests-remote-accessible-p)) | 154 | (skip-unless (eshell-tests-remote-accessible-p)) |
| 153 | (let* ((default-directory ert-remote-temporary-file-directory) | 155 | (let* ((default-directory ert-remote-temporary-file-directory) |
| 154 | (remote (file-remote-p default-directory))) | 156 | (remote (file-remote-p default-directory))) |
| 155 | (should (equal (eshell-glob-convert (format "%s/some/where/*.el" remote)) | 157 | (should (equal (eshell-glob-convert |
| 158 | (format (eshell-parse-glob-string "%s/some/where/*.el") | ||
| 159 | remote)) | ||
| 156 | `(,(format "%s/some/where/" remote) | 160 | `(,(format "%s/some/where/" remote) |
| 157 | (("\\`.*\\.el\\'" . "\\`\\.")) nil))))) | 161 | (("\\`.*\\.el\\'" . "\\`\\.")) nil))))) |
| 158 | 162 | ||
| 159 | (ert-deftest em-glob-test/convert/quoted-start-directory () | 163 | (ert-deftest em-glob-test/convert/start-directory-with-spaces () |
| 160 | "Test converting a glob starting in a quoted directory name." | 164 | "Test converting a glob starting in a directory with spaces in its name." |
| 161 | (should (equal (eshell-glob-convert | 165 | (should (equal (eshell-glob-convert |
| 162 | (concat (eshell-escape-arg "some where/") "*.el")) | 166 | (eshell-parse-glob-string "some where/*.el")) |
| 163 | '("./some where/" (("\\`.*\\.el\\'" . "\\`\\.")) nil)))) | 167 | '("./some where/" (("\\`.*\\.el\\'" . "\\`\\.")) nil)))) |
| 164 | 168 | ||
| 169 | (ert-deftest em-glob-test/convert/literal-characters () | ||
| 170 | "Test converting a \"glob\" with only literal characters." | ||
| 171 | (should (equal (eshell-glob-convert "*.el") '("./*.el" nil nil))) | ||
| 172 | (should (equal (eshell-glob-convert "**/") '("./**/" nil t)))) | ||
| 173 | |||
| 174 | (ert-deftest em-glob-test/convert/mixed-literal-characters () | ||
| 175 | "Test converting a glob with some literal characters." | ||
| 176 | (should (equal (eshell-glob-convert (eshell-parse-glob-string "\\*\\*/*.el")) | ||
| 177 | '("./**/" (("\\`.*\\.el\\'" . "\\`\\.")) nil))) | ||
| 178 | (should (equal (eshell-glob-convert (eshell-parse-glob-string "**/\\*.el")) | ||
| 179 | '("./" (recurse ("\\`\\*\\.el\\'" . "\\`\\.")) nil)))) | ||
| 180 | |||
| 165 | 181 | ||
| 166 | ;; Glob matching | 182 | ;; Glob matching |
| 167 | 183 | ||
| @@ -262,11 +278,11 @@ value of `eshell-glob-splice-results'." | |||
| 262 | 278 | ||
| 263 | (ert-deftest em-glob-test/match-n-or-more-groups () | 279 | (ert-deftest em-glob-test/match-n-or-more-groups () |
| 264 | "Test that \"(x)#\" and \"(x)#\" match zero or more instances of \"(x)\"." | 280 | "Test that \"(x)#\" and \"(x)#\" match zero or more instances of \"(x)\"." |
| 265 | (with-fake-files '("h.el" "ha.el" "hi.el" "hii.el" "dir/hi.el") | 281 | (with-fake-files '("h.el" "ha.el" "hi.el" "hah.el" "hahah.el" "dir/hah.el") |
| 266 | (should (equal (eshell-extended-glob "hi#.el") | 282 | (should (equal (eshell-extended-glob "h(ah)#.el") |
| 267 | '("h.el" "hi.el" "hii.el"))) | 283 | '("h.el" "hah.el" "hahah.el"))) |
| 268 | (should (equal (eshell-extended-glob "hi##.el") | 284 | (should (equal (eshell-extended-glob "h(ah)##.el") |
| 269 | '("hi.el" "hii.el"))))) | 285 | '("hah.el" "hahah.el"))))) |
| 270 | 286 | ||
| 271 | (ert-deftest em-glob-test/match-n-or-more-character-sets () | 287 | (ert-deftest em-glob-test/match-n-or-more-character-sets () |
| 272 | "Test that \"[x]#\" and \"[x]#\" match zero or more instances of \"[x]\"." | 288 | "Test that \"[x]#\" and \"[x]#\" match zero or more instances of \"[x]\"." |
| @@ -300,11 +316,11 @@ value of `eshell-glob-splice-results'." | |||
| 300 | (ert-deftest em-glob-test/no-matches () | 316 | (ert-deftest em-glob-test/no-matches () |
| 301 | "Test behavior when a glob fails to match any files." | 317 | "Test behavior when a glob fails to match any files." |
| 302 | (with-fake-files '("foo.el" "bar.el") | 318 | (with-fake-files '("foo.el" "bar.el") |
| 303 | (should (equal (eshell-extended-glob "*.txt") | 319 | (should (equal-including-properties (eshell-extended-glob "*.txt") |
| 304 | "*.txt")) | 320 | "*.txt")) |
| 305 | (let ((eshell-glob-splice-results t)) | 321 | (let ((eshell-glob-splice-results t)) |
| 306 | (should (equal (eshell-extended-glob "*.txt") | 322 | (should (equal-including-properties (eshell-extended-glob "*.txt") |
| 307 | '("*.txt")))) | 323 | '("*.txt")))) |
| 308 | (let ((eshell-error-if-no-glob t)) | 324 | (let ((eshell-error-if-no-glob t)) |
| 309 | (should-error (eshell-extended-glob "*.txt"))))) | 325 | (should-error (eshell-extended-glob "*.txt"))))) |
| 310 | 326 | ||