mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-01-30 04:10:54 -08:00
Use a common set of string delimiters for all Eshell predicates/modifiers
* lisp/eshell/em-pred.el (eshell-pred-delimiter-pairs): New variable. (eshell-get-comparison-modifier-argument) (eshell-get-numeric-modifier-argument) (eshell-get-delimited-modifier-argument): New functions... (eshell-pred-user-or-group, eshell-pred-file-time) (eshell-pred-file-links, eshell-pred-file-size) (eshell-pred-substitute, eshell-join-memebers, eshell-split-members): ... and use them here. (eshell-include-members): Pass 'mod-char' and use 'eshell-get-delimited-modifier-argument'. (eshell-pred-file-type, eshell-pred-file-mode): Use 'when-let'. (eshell-modifier-alist): Pass modifier char to 'eshell-include-members'. * test/lisp/eshell/em-pred-tests.el (em-pred-test/predicate-delimiters): New test. (em-pred-test/predicate-uid, em-pred-test/predicate-gid, em-pred-test/modifier-include, em-pred-test/modifier-exclude): Remove cases covered by 'em-pred-test/predicate-delimiters'. (em-pred-test/modifier-substitute): Add test cases for new delimiter styles. * doc/misc/eshell.texi (Argument Predication and Modification): Explain how string parameters are delimited. (Argument Modifiers): Document some special delimiter behavior with the 's/PATTERN/REPLACE/' modifier (bug#55204). * etc/NEWS: Announce this change, and move the 'eshell-eval-using-options' entry to the Eshell section.
This commit is contained in:
parent
788694d026
commit
ade1424a97
4 changed files with 179 additions and 163 deletions
|
|
@ -1191,6 +1191,13 @@ or modifiers. For example, @samp{*(.)} expands to all regular files
|
|||
in the current directory and @samp{*(^@@:U^u0)} expands to all
|
||||
non-symlinks not owned by @code{root}, upper-cased.
|
||||
|
||||
Some predicates and modifiers accept string parameters, such as
|
||||
@samp{*(u'@var{user}')}, which matches all files owned by @var{user}.
|
||||
These parameters must be surrounded by delimiters; you can use any of
|
||||
the following pairs of delimiters: @code{" @dots{} "}, @code{' @dots{}
|
||||
'}, @code{/ @dots{} /}, @code{| @dots{} |}, @code{( @dots{} )},
|
||||
@code{[ @dots{} ]}, @code{< @dots{} >}, or @code{@{ @dots{} @}}.
|
||||
|
||||
You can customize the syntax and behavior of predicates and modifiers
|
||||
in Eshell via the Customize group ``eshell-pred'' (@pxref{Easy
|
||||
Customization, , , emacs, The GNU Emacs Manual}).
|
||||
|
|
@ -1379,6 +1386,11 @@ meaning.
|
|||
Replaces the first instance of the regular expression @var{pattern}
|
||||
with @var{replace}. Signals an error if no match is found.
|
||||
|
||||
As with other modifiers taking string parameters, you can use
|
||||
different delimiters to separate @var{pattern} and @var{replace}, such
|
||||
as @samp{s'@dots{}'@dots{}'}, @samp{s[@dots{}][@dots{}]}, or even
|
||||
@samp{s[@dots{}]/@dots{}/}.
|
||||
|
||||
@item gs/@var{pattern}/@var{replace}/
|
||||
Replaces all instances of the regular expression @var{pattern} with
|
||||
@var{replace}.
|
||||
|
|
|
|||
26
etc/NEWS
26
etc/NEWS
|
|
@ -174,11 +174,22 @@ files that were compiled with an old EIEIO (Emacs<25).
|
|||
** 'C-x 8 .' has been moved to 'C-x 8 . .'.
|
||||
This is to open up the 'C-x 8 .' map to bind further characters there.
|
||||
|
||||
** Eshell
|
||||
|
||||
---
|
||||
** 'source' and '.' in Eshell no longer accept the '--help' option.
|
||||
*** 'source' and '.' no longer accept the '--help' option.
|
||||
This is for compatibility with the shell versions of these commands,
|
||||
which don't handle options like '--help' in any special way.
|
||||
|
||||
+++
|
||||
*** String delimiters in argument predicates/modifiers are more restricted.
|
||||
Previously, some argument predicates/modifiers allowed arbitrary
|
||||
characters as string delimiters. To provide more unified behavior
|
||||
across all predicates/modifiers, the list of allowed delimiters has
|
||||
been restricted to "...", '...', /.../, |...|, (...), [...], <...>,
|
||||
and {...}. See the "(eshell) Argument Predication and Modification"
|
||||
node in the Eshell manual for more details.
|
||||
|
||||
---
|
||||
** The 'delete-forward-char' command now deletes by grapheme clusters.
|
||||
This command is by default bound to the <Delete> function key
|
||||
|
|
@ -1354,6 +1365,14 @@ Lisp function. This frees you from having to keep track of whether
|
|||
commands are Lisp function or external when supplying absolute file
|
||||
name arguments. See "Electric forward slash" in the Eshell manual.
|
||||
|
||||
---
|
||||
*** Built-in Eshell commands now follow POSIX/GNU argument syntax conventions.
|
||||
Built-in commands in Eshell now accept command-line options with
|
||||
values passed as a single token, such as '-oVALUE' or
|
||||
'--option=VALUE'. New commands can take advantage of this with the
|
||||
'eshell-eval-using-options' macro. See "Defining new built-in
|
||||
commands" in the "(eshell) Built-ins" node of the Eshell manual.
|
||||
|
||||
** Calc
|
||||
|
||||
+++
|
||||
|
|
@ -1937,11 +1956,6 @@ dimensions.
|
|||
Specifying a cons as the FROM argument allows to start measuring text
|
||||
from a specified amount of pixels above or below a position.
|
||||
|
||||
---
|
||||
** 'eshell-eval-using-options' now follows argument syntax conventions.
|
||||
Built-in commands in Eshell now accept command-line options with
|
||||
values passed as a single token, such as '-oVALUE' or '--option=VALUE'.
|
||||
|
||||
** XDG support
|
||||
|
||||
---
|
||||
|
|
|
|||
|
|
@ -116,8 +116,8 @@ The format of each entry is
|
|||
(?U . (lambda (lst) (mapcar #'upcase lst)))
|
||||
(?C . (lambda (lst) (mapcar #'capitalize lst)))
|
||||
(?h . (lambda (lst) (mapcar #'file-name-directory lst)))
|
||||
(?i . (eshell-include-members))
|
||||
(?x . (eshell-include-members t))
|
||||
(?i . (eshell-include-members ?i))
|
||||
(?x . (eshell-include-members ?x t))
|
||||
(?r . (lambda (lst) (mapcar #'file-name-sans-extension lst)))
|
||||
(?e . (lambda (lst) (mapcar #'file-name-extension lst)))
|
||||
(?t . (lambda (lst) (mapcar #'file-name-nondirectory lst)))
|
||||
|
|
@ -219,6 +219,20 @@ FOR LISTS OF ARGUMENTS:
|
|||
EXAMPLES:
|
||||
*.c(:o) sorted list of .c files")
|
||||
|
||||
(defvar eshell-pred-delimiter-pairs
|
||||
'((?\( . ?\))
|
||||
(?\[ . ?\])
|
||||
(?\< . ?\>)
|
||||
(?\{ . ?\})
|
||||
(?\' . ?\')
|
||||
(?\" . ?\")
|
||||
(?/ . ?/)
|
||||
(?| . ?|))
|
||||
"A list of delimiter pairs that can be used in argument predicates/modifiers.
|
||||
Each element is of the form (OPEN . CLOSE), where OPEN and CLOSE
|
||||
are characters representing the opening and closing delimiter,
|
||||
respectively.")
|
||||
|
||||
(defvar-keymap eshell-pred-mode-map
|
||||
"C-c M-q" #'eshell-display-predicate-help
|
||||
"C-c M-m" #'eshell-display-modifier-help)
|
||||
|
|
@ -364,38 +378,68 @@ resultant list of strings."
|
|||
(lambda (file) (funcall pred (file-truename file))))))
|
||||
(cons pred funcs))
|
||||
|
||||
(defun eshell-get-comparison-modifier-argument (&optional functions)
|
||||
"Starting at point, get the comparison modifier argument, if any.
|
||||
These are the -/+ characters, corresponding to `<' and `>',
|
||||
respectively. If no comparison modifier is at point, return `='.
|
||||
|
||||
FUNCTIONS, if non-nil, is a list of comparison functions,
|
||||
specified as (LESS-THAN GREATER-THAN EQUAL-TO)."
|
||||
(let ((functions (or functions (list #'< #'> #'=))))
|
||||
(if (memq (char-after) '(?- ?+))
|
||||
(prog1
|
||||
(if (eq (char-after) ?-) (nth 0 functions) (nth 1 functions))
|
||||
(forward-char))
|
||||
(nth 2 functions))))
|
||||
|
||||
(defun eshell-get-numeric-modifier-argument ()
|
||||
"Starting at point, get the numeric modifier argument, if any.
|
||||
If a number is found, update point to just after the number."
|
||||
(when (looking-at "[0-9]+")
|
||||
(prog1
|
||||
(string-to-number (match-string 0))
|
||||
(goto-char (match-end 0)))))
|
||||
|
||||
(defun eshell-get-delimited-modifier-argument (&optional chained-p)
|
||||
"Starting at point, get the delimited modifier argument, if any.
|
||||
If the character after point is a predicate/modifier
|
||||
delimiter (see `eshell-pred-delimiter-pairs', read the value of
|
||||
the argument and update point to be just after the closing
|
||||
delimiter.
|
||||
|
||||
If CHAINED-P is true, then another delimited modifier argument
|
||||
will immediately follow this one. In this case, when the opening
|
||||
and closing delimiters are the same, update point to be just
|
||||
before the closing delimiter. This allows modifiers like
|
||||
`:s/match/repl' to work as expected."
|
||||
(when-let* ((open (char-after))
|
||||
(close (cdr (assoc open eshell-pred-delimiter-pairs)))
|
||||
(end (eshell-find-delimiter open close nil nil t)))
|
||||
(prog1
|
||||
(buffer-substring-no-properties (1+ (point)) end)
|
||||
(goto-char (if (and chained-p (eq open close))
|
||||
end
|
||||
(1+ end))))))
|
||||
|
||||
(defun eshell-pred-user-or-group (mod-char mod-type attr-index get-id-func)
|
||||
"Return a predicate to test whether a file match a given user/group id."
|
||||
(let (ugid open close end)
|
||||
(if (looking-at "[0-9]+")
|
||||
(progn
|
||||
(setq ugid (string-to-number (match-string 0)))
|
||||
(goto-char (match-end 0)))
|
||||
(setq open (char-after))
|
||||
(if (setq close (memq open '(?\( ?\[ ?\< ?\{)))
|
||||
(setq close (car (last '(?\) ?\] ?\> ?\})
|
||||
(length close))))
|
||||
(setq close open))
|
||||
(forward-char)
|
||||
(setq end (eshell-find-delimiter open close))
|
||||
(unless end
|
||||
(error "Malformed %s name string for modifier `%c'"
|
||||
mod-type mod-char))
|
||||
(setq ugid
|
||||
(funcall get-id-func (buffer-substring (point) end)))
|
||||
(goto-char (1+ end)))
|
||||
(let ((ugid (eshell-get-numeric-modifier-argument)))
|
||||
(unless ugid
|
||||
(let ((ugname (or (eshell-get-delimited-modifier-argument)
|
||||
(error "Malformed %s name string for modifier `%c'"
|
||||
mod-type mod-char))))
|
||||
(setq ugid (funcall get-id-func ugname))))
|
||||
(unless ugid
|
||||
(error "Unknown %s name specified for modifier `%c'"
|
||||
mod-type mod-char))
|
||||
(lambda (file)
|
||||
(let ((attrs (file-attributes file)))
|
||||
(if attrs
|
||||
(= (nth attr-index attrs) ugid))))))
|
||||
(when-let ((attrs (file-attributes file)))
|
||||
(= (nth attr-index attrs) ugid)))))
|
||||
|
||||
(defun eshell-pred-file-time (mod-char mod-type attr-index)
|
||||
"Return a predicate to test whether a file matches a certain time."
|
||||
(let* ((quantum 86400)
|
||||
qual when open close end)
|
||||
qual when)
|
||||
(when (memq (char-after) '(?M ?w ?h ?m ?s))
|
||||
(setq quantum (char-after))
|
||||
(cond
|
||||
|
|
@ -410,36 +454,21 @@ resultant list of strings."
|
|||
((eq quantum ?s)
|
||||
(setq quantum 1)))
|
||||
(forward-char))
|
||||
(when (memq (char-after) '(?+ ?-))
|
||||
(setq qual (char-after))
|
||||
(forward-char))
|
||||
(if (looking-at "[0-9]+")
|
||||
(progn
|
||||
(setq when (time-since (* (string-to-number (match-string 0))
|
||||
quantum)))
|
||||
(goto-char (match-end 0)))
|
||||
(setq open (char-after))
|
||||
(if (setq close (memq open '(?\( ?\[ ?\< ?\{)))
|
||||
(setq close (car (last '(?\) ?\] ?\> ?\})
|
||||
(length close))))
|
||||
(setq close open))
|
||||
(forward-char)
|
||||
(setq end (eshell-find-delimiter open close))
|
||||
(unless end
|
||||
(error "Malformed %s time modifier `%c'" mod-type mod-char))
|
||||
(let* ((file (buffer-substring (point) end))
|
||||
(attrs (file-attributes file)))
|
||||
(unless attrs
|
||||
(error "Cannot stat file `%s'" file))
|
||||
(setq when (nth attr-index attrs)))
|
||||
(goto-char (1+ end)))
|
||||
(let ((f (cond ((eq qual ?-) #'time-less-p)
|
||||
((eq qual ?+) (lambda (a b) (time-less-p b a)))
|
||||
(#'time-equal-p))))
|
||||
(lambda (file)
|
||||
(let ((attrs (file-attributes file)))
|
||||
(if attrs
|
||||
(funcall f when (nth attr-index attrs))))))))
|
||||
(setq qual (eshell-get-comparison-modifier-argument
|
||||
(list #'time-less-p
|
||||
(lambda (a b) (time-less-p b a))
|
||||
#'time-equal-p)))
|
||||
(if-let ((number (eshell-get-numeric-modifier-argument)))
|
||||
(setq when (time-since (* number quantum)))
|
||||
(let* ((file (or (eshell-get-delimited-modifier-argument)
|
||||
(error "Malformed %s time modifier `%c'"
|
||||
mod-type mod-char)))
|
||||
(attrs (or (file-attributes file)
|
||||
(error "Cannot stat file `%s'" file))))
|
||||
(setq when (nth attr-index attrs))))
|
||||
(lambda (file)
|
||||
(when-let ((attrs (file-attributes file)))
|
||||
(funcall qual when (nth attr-index attrs))))))
|
||||
|
||||
(defun eshell-pred-file-type (type)
|
||||
"Return a test which tests that the file is of a certain TYPE.
|
||||
|
|
@ -454,36 +483,23 @@ that `ls -l' will show in the first column of its display."
|
|||
'(?b ?c)
|
||||
(list type))))
|
||||
(lambda (file)
|
||||
(let ((attrs (eshell-file-attributes (directory-file-name file))))
|
||||
(if attrs
|
||||
(memq (aref (file-attribute-modes attrs) 0) set))))))
|
||||
(when-let ((attrs (eshell-file-attributes (directory-file-name file))))
|
||||
(memq (aref (file-attribute-modes attrs) 0) set)))))
|
||||
|
||||
(defsubst eshell-pred-file-mode (mode)
|
||||
"Return a test which tests that MODE pertains to the file."
|
||||
(lambda (file)
|
||||
(let ((modes (file-modes file 'nofollow)))
|
||||
(if modes
|
||||
(not (zerop (logand mode modes)))))))
|
||||
(when-let ((modes (file-modes file 'nofollow)))
|
||||
(not (zerop (logand mode modes))))))
|
||||
|
||||
(defun eshell-pred-file-links ()
|
||||
"Return a predicate to test whether a file has a given number of links."
|
||||
(let (qual amount)
|
||||
(when (memq (char-after) '(?- ?+))
|
||||
(setq qual (char-after))
|
||||
(forward-char))
|
||||
(unless (looking-at "[0-9]+")
|
||||
(error "Invalid file link count modifier `l'"))
|
||||
(setq amount (string-to-number (match-string 0)))
|
||||
(goto-char (match-end 0))
|
||||
(let ((f (if (eq qual ?-)
|
||||
#'<
|
||||
(if (eq qual ?+)
|
||||
#'>
|
||||
#'=))))
|
||||
(lambda (file)
|
||||
(let ((attrs (eshell-file-attributes file)))
|
||||
(if attrs
|
||||
(funcall f (file-attribute-link-number attrs) amount)))))))
|
||||
(let ((qual (eshell-get-comparison-modifier-argument))
|
||||
(amount (or (eshell-get-numeric-modifier-argument)
|
||||
(error "Invalid file link count modifier `l'"))))
|
||||
(lambda (file)
|
||||
(when-let ((attrs (eshell-file-attributes file)))
|
||||
(funcall qual (file-attribute-link-number attrs) amount)))))
|
||||
|
||||
(defun eshell-pred-file-size ()
|
||||
"Return a predicate to test whether a file is of a given size."
|
||||
|
|
@ -498,85 +514,52 @@ that `ls -l' will show in the first column of its display."
|
|||
((eq qual ?p)
|
||||
(setq quantum 512)))
|
||||
(forward-char))
|
||||
(when (memq (char-after) '(?- ?+))
|
||||
(setq qual (char-after))
|
||||
(forward-char))
|
||||
(unless (looking-at "[0-9]+")
|
||||
(error "Invalid file size modifier `L'"))
|
||||
(setq amount (* (string-to-number (match-string 0)) quantum))
|
||||
(goto-char (match-end 0))
|
||||
(let ((f (if (eq qual ?-)
|
||||
#'<
|
||||
(if (eq qual ?+)
|
||||
#'>
|
||||
#'=))))
|
||||
(lambda (file)
|
||||
(let ((attrs (eshell-file-attributes file)))
|
||||
(if attrs
|
||||
(funcall f (file-attribute-size attrs) amount)))))))
|
||||
(setq qual (eshell-get-comparison-modifier-argument))
|
||||
(setq amount (* (or (eshell-get-numeric-modifier-argument)
|
||||
(error "Invalid file size modifier `L'"))
|
||||
quantum))
|
||||
(lambda (file)
|
||||
(when-let ((attrs (eshell-file-attributes file)))
|
||||
(funcall qual (file-attribute-size attrs) amount)))))
|
||||
|
||||
(defun eshell-pred-substitute (&optional repeat)
|
||||
"Return a modifier function that will substitute matches."
|
||||
(let ((delim (char-after))
|
||||
match replace end)
|
||||
(forward-char)
|
||||
(setq end (eshell-find-delimiter delim delim nil nil t)
|
||||
match (buffer-substring-no-properties (point) end))
|
||||
(goto-char (1+ end))
|
||||
(setq end (eshell-find-delimiter delim delim nil nil t)
|
||||
replace (buffer-substring-no-properties (point) end))
|
||||
(goto-char (1+ end))
|
||||
(if repeat
|
||||
(lambda (lst)
|
||||
(mapcar
|
||||
(lambda (str)
|
||||
(replace-regexp-in-string match replace str t))
|
||||
lst))
|
||||
(lambda (lst)
|
||||
(mapcar
|
||||
(lambda (str)
|
||||
(if (string-match match str)
|
||||
(replace-match replace t nil str)
|
||||
(error (concat str ": substitution failed"))))
|
||||
lst)))))
|
||||
(let* ((match (or (eshell-get-delimited-modifier-argument t)
|
||||
(error "Malformed pattern string for modifier `s'")))
|
||||
(replace (or (eshell-get-delimited-modifier-argument)
|
||||
(error "Malformed replace string for modifier `s'")))
|
||||
(function (if repeat
|
||||
(lambda (str)
|
||||
(replace-regexp-in-string match replace str t))
|
||||
(lambda (str)
|
||||
(if (string-match match str)
|
||||
(replace-match replace t nil str)
|
||||
(error (concat str ": substitution failed")))))))
|
||||
(lambda (lst) (mapcar function lst))))
|
||||
|
||||
(defun eshell-include-members (&optional invert-p)
|
||||
"Include only Lisp members matching a regexp."
|
||||
(let ((delim (char-after))
|
||||
regexp end)
|
||||
(forward-char)
|
||||
(setq end (eshell-find-delimiter delim delim nil nil t)
|
||||
regexp (buffer-substring-no-properties (point) end))
|
||||
(goto-char (1+ end))
|
||||
(let ((predicates
|
||||
(list (if invert-p
|
||||
(lambda (elem) (not (string-match regexp elem)))
|
||||
(lambda (elem) (string-match regexp elem))))))
|
||||
(lambda (lst)
|
||||
(eshell-winnow-list lst nil predicates)))))
|
||||
(defun eshell-include-members (mod-char &optional invert-p)
|
||||
"Include only Lisp members matching a regexp.
|
||||
If INVERT-P is non-nil, include only members not matching a regexp."
|
||||
(let* ((regexp (or (eshell-get-delimited-modifier-argument)
|
||||
(error "Malformed pattern string for modifier `%c'"
|
||||
mod-char)))
|
||||
(predicates
|
||||
(list (if invert-p
|
||||
(lambda (elem) (not (string-match regexp elem)))
|
||||
(lambda (elem) (string-match regexp elem))))))
|
||||
(lambda (lst)
|
||||
(eshell-winnow-list lst nil predicates))))
|
||||
|
||||
(defun eshell-join-members ()
|
||||
"Return a modifier function that join matches."
|
||||
(let ((delim (char-after))
|
||||
str end)
|
||||
(if (not (memq delim '(?' ?/)))
|
||||
(setq str " ")
|
||||
(forward-char)
|
||||
(setq end (eshell-find-delimiter delim delim nil nil t)
|
||||
str (buffer-substring-no-properties (point) end))
|
||||
(goto-char (1+ end)))
|
||||
(let ((str (or (eshell-get-delimited-modifier-argument)
|
||||
" ")))
|
||||
(lambda (lst)
|
||||
(mapconcat #'identity lst str))))
|
||||
|
||||
(defun eshell-split-members ()
|
||||
"Return a modifier function that splits members."
|
||||
(let ((delim (char-after))
|
||||
sep end)
|
||||
(when (memq delim '(?' ?/))
|
||||
(forward-char)
|
||||
(setq end (eshell-find-delimiter delim delim nil nil t)
|
||||
sep (buffer-substring-no-properties (point) end))
|
||||
(goto-char (1+ end)))
|
||||
(let ((sep (eshell-get-delimited-modifier-argument)))
|
||||
(lambda (lst)
|
||||
(mapcar
|
||||
(lambda (str)
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
(require 'ert)
|
||||
(require 'esh-mode)
|
||||
(require 'eshell)
|
||||
(require 'em-pred)
|
||||
|
||||
(require 'eshell-tests-helpers
|
||||
(expand-file-name "eshell-tests-helpers"
|
||||
|
|
@ -254,8 +255,6 @@ read, write, and execute predicates to query the file's modes."
|
|||
(cl-letf (((symbol-function 'eshell-user-id)
|
||||
(lambda (name) (seq-position user-names name))))
|
||||
(should (equal (eshell-eval-predicate files "u'one'")
|
||||
'("/fake/uid=1")))
|
||||
(should (equal (eshell-eval-predicate files "u{one}")
|
||||
'("/fake/uid=1")))))))
|
||||
|
||||
(ert-deftest em-pred-test/predicate-gid ()
|
||||
|
|
@ -268,8 +267,6 @@ read, write, and execute predicates to query the file's modes."
|
|||
(cl-letf (((symbol-function 'eshell-group-id)
|
||||
(lambda (name) (seq-position group-names name))))
|
||||
(should (equal (eshell-eval-predicate files "g'one'")
|
||||
'("/fake/gid=1")))
|
||||
(should (equal (eshell-eval-predicate files "g{one}")
|
||||
'("/fake/gid=1")))))))
|
||||
|
||||
(defmacro em-pred-test--time-deftest (name file-attribute predicate
|
||||
|
|
@ -430,6 +427,8 @@ PREDICATE is the predicate used to query that attribute."
|
|||
"Test that \":s/PAT/REP/\" replaces PAT with REP once."
|
||||
(should (equal (eshell-eval-predicate "bar" ":s/a/*/") "b*r"))
|
||||
(should (equal (eshell-eval-predicate "bar" ":s|a|*|") "b*r"))
|
||||
(should (equal (eshell-eval-predicate "bar" ":s{a}{*}") "b*r"))
|
||||
(should (equal (eshell-eval-predicate "bar" ":s{a}'*'") "b*r"))
|
||||
(should (equal (eshell-eval-predicate '("foo" "bar" "baz") ":s/[ao]/*/")
|
||||
'("f*o" "b*r" "b*z")))
|
||||
(should (equal (eshell-eval-predicate '("foo" "bar" "baz") ":s|[ao]|*|")
|
||||
|
|
@ -450,23 +449,15 @@ PREDICATE is the predicate used to query that attribute."
|
|||
(ert-deftest em-pred-test/modifier-include ()
|
||||
"Test that \":i/PAT/\" filters elements to include only ones matching PAT."
|
||||
(should (equal (eshell-eval-predicate "foo" ":i/a/") nil))
|
||||
(should (equal (eshell-eval-predicate "foo" ":i|a|") nil))
|
||||
(should (equal (eshell-eval-predicate "bar" ":i/a/") "bar"))
|
||||
(should (equal (eshell-eval-predicate "bar" ":i|a|") "bar"))
|
||||
(should (equal (eshell-eval-predicate '("foo" "bar" "baz") ":i/a/")
|
||||
'("bar" "baz")))
|
||||
(should (equal (eshell-eval-predicate '("foo" "bar" "baz") ":i|a|")
|
||||
'("bar" "baz"))))
|
||||
|
||||
(ert-deftest em-pred-test/modifier-exclude ()
|
||||
"Test that \":x/PAT/\" filters elements to exclude any matching PAT."
|
||||
(should (equal (eshell-eval-predicate "foo" ":x/a/") "foo"))
|
||||
(should (equal (eshell-eval-predicate "foo" ":x|a|") "foo"))
|
||||
(should (equal (eshell-eval-predicate "bar" ":x/a/") nil))
|
||||
(should (equal (eshell-eval-predicate "bar" ":x|a|") nil))
|
||||
(should (equal (eshell-eval-predicate '("foo" "bar" "baz") ":x/a/")
|
||||
'("foo")))
|
||||
(should (equal (eshell-eval-predicate '("foo" "bar" "baz") ":x|a|")
|
||||
'("foo"))))
|
||||
|
||||
(ert-deftest em-pred-test/modifier-split ()
|
||||
|
|
@ -516,7 +507,7 @@ PREDICATE is the predicate used to query that attribute."
|
|||
'("baz" "bar" "foo"))))
|
||||
|
||||
|
||||
;; Combinations
|
||||
;; Miscellaneous
|
||||
|
||||
(ert-deftest em-pred-test/combine-predicate-and-modifier ()
|
||||
"Test combination of predicates and modifiers."
|
||||
|
|
@ -526,4 +517,20 @@ PREDICATE is the predicate used to query that attribute."
|
|||
(should (equal (eshell-eval-predicate files ".:e:u")
|
||||
'("el" "txt"))))))
|
||||
|
||||
(ert-deftest em-pred-test/predicate-delimiters ()
|
||||
"Test various delimiter pairs with predicates and modifiers."
|
||||
(dolist (delims eshell-pred-delimiter-pairs)
|
||||
(eshell-with-file-attributes-from-name
|
||||
(let ((files '("/fake/uid=1" "/fake/uid=2"))
|
||||
(user-names '("root" "one" "two")))
|
||||
(cl-letf (((symbol-function 'eshell-user-id)
|
||||
(lambda (name) (seq-position user-names name))))
|
||||
(should (equal (eshell-eval-predicate
|
||||
files (format "u%cone%c" (car delims) (cdr delims)))
|
||||
'("/fake/uid=1"))))))
|
||||
(should (equal (eshell-eval-predicate
|
||||
'("foo" "bar" "baz")
|
||||
(format ":j%c-%c" (car delims) (cdr delims)))
|
||||
"foo-bar-baz"))))
|
||||
|
||||
;; em-pred-tests.el ends here
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue