[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] externals/m-buffer 84c7fddd48 008/115: Modifed match-data to use
From: |
ELPA Syncer |
Subject: |
[elpa] externals/m-buffer 84c7fddd48 008/115: Modifed match-data to use keyword args, except for first two args. |
Date: |
Tue, 19 Jul 2022 15:58:44 -0400 (EDT) |
branch: externals/m-buffer
commit 84c7fddd48c7baf3099bcb9a71ae8747f2b598ab
Author: Phillip Lord <phillip.lord@newcastle.ac.uk>
Commit: Phillip Lord <phillip.lord@newcastle.ac.uk>
Modifed match-data to use keyword args, except for first two args.
This has resulted in a large number of knock on changes, but has simplified
the argument handling significantly.
---
m-buffer.el | 359 +++++++++++++++++++++++++++++---------------------
test/m-buffer-test.el | 60 ++++++++-
2 files changed, 265 insertions(+), 154 deletions(-)
diff --git a/m-buffer.el b/m-buffer.el
index c123b0aef9..b056b236f7 100644
--- a/m-buffer.el
+++ b/m-buffer.el
@@ -47,146 +47,194 @@
;;
;; Regexp matching
;;
-(defun m-buffer-match-data (&rest match-with)
- "Return a list of `match-data' for all matches based on MATCH-WITH.
-MATCH-WITh may be of the forms:
-BUFFER REGEXP &optional BEGINNING END POST-MATCH
-WINDOW REGEXP &optional POST-MATCH
-
-Matches between BEGINNING and END are returned or for windows
-matches within the visible portion of the window. After a match
-the function POST-MATCH is called. The buffer is searched
-forward."
- (let* ((norm (m-buffer-normalize-region match-with))
- (buffer (nth 0 norm))
- (regexp (nth 1 norm))
- (beginning (nth 2 norm))
- (end (nth 3 norm))
- (post-match (nth 4 norm)))
- (save-match-data
- (save-excursion
- (with-current-buffer
- buffer
- (let ((rtn nil)
- (post-match-return t))
- (goto-char
- (or beginning
- (point-min)))
- (while
- (and
- post-match-return
- (re-search-forward
- regexp
- (or end (point-max))
- t))
- (setq rtn
- (cons
- (match-data)
- rtn))
- (when post-match
- (setq post-match-return (funcall post-match))))
- (reverse rtn)))))))
-
-(defun m-buffer-normalize-region (match-with)
- (cond
- ((bufferp (car match-with))
- match-with)
- ((windowp (car match-with))
- (let ((window (car match-with)))
- (list
- (window-buffer window)
- (cadr match-with)
- (window-start window)
- (window-end window)
- (caadr match-with))))
- (t (error "Invalid arguments"))))
-
-(defun m-buffer-ensure-match (&rest match-on)
+(defun m-buffer-match-data (&rest match)
+ "Return a list of `match-data' for all matches based on MATCH.
+MATCH may be of the forms:
+BUFFER REGEXP &optional MATCH-OPTIONS
+WINDOW REGEXP &optional MATCH-OPTIONS
+MATCH-OPTIONS
+
+If BUFFER is given, search this buffer. If WINDOW is given search
+the visible window. MATCH-OPTIONS is a plist with any of the
+following keys:
+:buffer -- the buffer to search
+:regexp -- the regexp to search with
+:beginning -- the start of the region to search
+:end -- the end of the region to search
+:post-match -- function called after a match
+
+If options are expressed in two places, the plist form takes
+precedence over positional args. So calling with both a first
+position buffer and a :buffer arg will use the second. Likewise,
+if a window is given as first arg and :end is given, then
+the :end value will be used.
+
+REGEXP should advance point (i.e. not be zero-width) or the
+function will loop infinitely. POST-MATCH can be used to avoid
+this. The buffer is searched forward."
+ (apply 'm-buffer-match-data-1
+ (m-buffer-normalize-args match)))
+
+(defun m-buffer-match-data-1 (buffer regexp beginning end post-match)
+ "Return a list of `match-data' for all matches.
+
+This is an internal function: please prefer `m-buffer-match-data'.
+
+BUFFER -- the buffer.
+REGEXP -- the regexp.
+BEGINNING -- the start of the region to search
+END -- the end of the region to search
+POST-MATCH -- function to run after each match
+POST-MATCH is useful for zero-width matches which will otherwise cause
+infinite loop. The buffer is searched forward."
+ (save-match-data
+ (save-excursion
+ (with-current-buffer
+ buffer
+ (let ((rtn nil)
+ (post-match-return t))
+ (goto-char
+ (or beginning
+ (point-min)))
+ (while
+ (and
+ post-match-return
+ (re-search-forward
+ regexp
+ (or end (point-max))
+ t))
+ (setq rtn
+ (cons
+ (match-data)
+ rtn))
+ (when post-match
+ (setq post-match-return (funcall post-match))))
+ (reverse rtn))))))
+
+(defun m-buffer-normalize-args (match-with)
+ "Manipulate args into a standard form and return as a list.
+
+This is an internal function."
+ (let* (
+ ;; split up into keyword and non keyword limits
+ (args
+ (-take-while
+ (lambda (x) (not (keywordp x)))
+ match-with))
+ (pargs
+ (-drop-while
+ (lambda (x) (not (keywordp x)))
+ match-with))
+ ;; sort actual actual parameters
+ (first (car args))
+ ;; buffer may be first
+ (buffer
+ (or (plist-get pargs :buffer)
+ (and (bufferp first) first)))
+ ;; or window may be first
+ (window
+ (or (plist-get pargs :window)
+ (and (windowp first) first)))
+ ;; regexp always comes second
+ (regexp
+ (or (plist-get pargs :regexp)
+ (nth 1 args)))
+ ;; beginning depends on other arguments
+ (beginning
+ (or (plist-get pargs :beginning)
+ (and window (window-start window))))
+ ;; end depends on other arguments
+ (end
+ (or (plist-get pargs :end)
+ (and window (window-end window))))
+ ;; pm
+ (post-match
+ (plist-get pargs :post-match)))
+ (list buffer regexp beginning end post-match)))
+
+(defun m-buffer-ensure-match (&rest match)
"Ensure that we have match data.
If a single arg, assume it is match data and return. If multiple
-args, and the first argument is a buffer, assume MATCH-ON is of
-form buffer regexp &optional beginning end. If the first argument
-is a window assume MATCH-ON is of form window regexp and search
-only in the visible part of the window."
+args, assume they are of the form accepted by
+`m-buffer-match-data'."
(cond
;; we have match data
- ((= 1 (length match-on))
- (car match-on))
- ((< 1 (length match-on))
- (apply 'm-buffer-match-data match-on))
+ ((= 1 (length match))
+ (car match))
+ ((< 1 (length match))
+ (apply 'm-buffer-match-data match))
(t
(error "Invalid arguments"))))
-(defun m-buffer-match-beginning-n (n &rest match-on)
+(defun m-buffer-match-beginning-n (n &rest match)
"Return markers to the start of the match to the nth group.
-MATCH-ON may be of any form accepted by
-`m-buffer-ensure-match'. Use `m-buffer-nil-markers' after the
-markers have been finished with or they will slow future use of
-the buffer."
+MATCH may be of any form accepted by `m-buffer-ensure-match'. Use
+`m-buffer-nil-markers' after the markers have been finished with
+or they will slow future use of the buffer until garbage collected."
(-map
- (lambda (match)
+ (lambda (m)
(nth
- (* 2 n) match))
- (apply 'm-buffer-ensure-match match-on)))
+ (* 2 n) m))
+ (apply 'm-buffer-ensure-match match)))
-(defun m-buffer-match-beginning-n-pos (n &rest match-on)
+(defun m-buffer-match-beginning-n-pos (n &rest match)
"Return positions of the start of the match to the nth group.
-MATCH-ON may be of any form accepted by `m-buffer-ensure-match'.
-If `match-data' is passed markers will be set to nil after this
+MATCH may be of any form accepted by `m-buffer-ensure-match'. If
+`match-data' is passed markers will be set to nil after this
function. See `m-buffer-nil-markers' for details."
(m-buffer-markers-to-pos-nil
(apply 'm-buffer-match-beginning-n
- n match-on)))
+ n match)))
-(defun m-buffer-match-beginning (&rest match-on)
+(defun m-buffer-match-beginning (&rest match)
"Returns a list of markers to the start of matches.
-MATCH-ON may of any form accepted by `m-buffer-ensure-match'. Use
+MATCH may of any form accepted by `m-buffer-ensure-match'. Use
`m-buffer-nil-markers' after the markers have been used or they
will slow future changes to the buffer."
- (apply 'm-buffer-match-beginning-n 0 match-on))
+ (apply 'm-buffer-match-beginning-n 0 match))
-(defun m-buffer-match-beginning-pos (&rest match-on)
+(defun m-buffer-match-beginning-pos (&rest match)
"Returns a list of positions at the start of matcher.
-MATCH-ON may be of any form accepted by `m-buffer-ensure-match'.
+MATCH may be of any form accepted by `m-buffer-ensure-match'.
If `match-data' is passed markers will be set to nil after this
function. See `m-buffer-nil-markers' for details."
- (apply 'm-buffer-match-beginning-n-pos 0 match-on))
+ (apply 'm-buffer-match-beginning-n-pos 0 match))
-(defun m-buffer-match-end-n (n &rest match-on)
+(defun m-buffer-match-end-n (n &rest match)
"Returns markers to the end of the match to the nth group.
-MATCH-ON may be of any form accepted by `m-buffer-ensure-match'.
+MATCH may be of any form accepted by `m-buffer-ensure-match'.
If `match-data' is passed markers will be set to nil after this
function. See `m-buffer-nil-markers' for details."
(-map
- (lambda (match)
+ (lambda (m)
(nth
(+ 1 (* 2 n))
- match))
- (apply 'm-buffer-ensure-match match-on)))
+ m))
+ (apply 'm-buffer-ensure-match match)))
-(defun m-buffer-match-end-n-pos (n &rest match-on)
+(defun m-buffer-match-end-n-pos (n &rest match)
"Return positions of the end of the match to the nth group.
-MATCH-ON may be of any form accepted by `m-buffer-ensure-match'.
+MATCH may be of any form accepted by `m-buffer-ensure-match'.
If `match-data' is passed markers will be set to nil after this
function. See `m-buffer-nil-markers' for details."
(m-buffer-markers-to-pos-nil
(apply 'm-buffer-match-end-n-pos
- n match-on)))
+ n match)))
-(defun m-buffer-match-end (&rest match-on)
+(defun m-buffer-match-end (&rest match)
"Returns a list of markers to the end of matches to regexp in buffer.
-MATCH-ON may be of any form accepted by `m-buffer-ensure-match'.
-Use `m-buffer-nil-markers' after the markers have been used or
-they will slow future changes to the buffer."
- (apply 'm-buffer-match-end-n 0 match-on))
+MATCH may be of any form accepted by `m-buffer-ensure-match'. Use
+`m-buffer-nil-markers' after the markers have been used or they
+will slow future changes to the buffer."
+ (apply 'm-buffer-match-end-n 0 match))
-(defun m-buffer-match-end-pos (&rest match-on)
+(defun m-buffer-match-end-pos (&rest match)
"Returns a list of positions to the end of the matches.
-MATCH-ON may be of any form accepted by `m-buffer-ensure-match'.
+MATCH may be of any form accepted by `m-buffer-ensure-match'.
If `match-data' is passed markers will be set to nil after this
function. See `m-buffer-nil-markers' for details."
(m-buffers-markers-to-pos-nil
- (apply 'm-buffer-match-end match-on)))
+ (apply 'm-buffer-match-end match)))
;; marker/position utility functions
(defun m-buffer-nil-markers (markers)
@@ -225,8 +273,8 @@ See also `m-buffer-nil-markers'"
(make-marker) pos buffer))
positions))
-(defun m-buffer-replace-match (matches replacement &optional subexp)
- "Given a list of MATCHES, replace with REPLACEMENT.
+(defun m-buffer-replace-match (match-data replacement &optional subexp)
+ "Given a list of MATCH-DATA, replace with REPLACEMENT.
SUBEXP should be a number indicating the regexp group to replace."
(-map
(lambda (match)
@@ -237,11 +285,10 @@ SUBEXP should be a number indicating the regexp group to
replace."
(replace-match
replacement nil nil nil
(or subexp 0)))))
- matches))
-
+ match-data))
-(defun m-buffer-match-string (matches &optional subexp)
- "Given a list of MATCHES return the string matches optionally
+(defun m-buffer-match-string (match-data &optional subexp)
+ "Given a list of MATCH-DATA return the string matches optionally
of group SUBEXP."
(-map
(lambda (match)
@@ -251,10 +298,10 @@ of group SUBEXP."
(set-match-data match)
(match-string
(or subexp 0)))))
- matches))
+ match-data))
-(defun m-buffer-match-string-no-properties (matches &optional subexp)
- "Given a list of MATCHES return string matches without properties
+(defun m-buffer-match-string-no-properties (match-data &optional subexp)
+ "Given a list of MATCH-DATA return string matches without properties
optionally of group SUBEXP."
(-map
'substring-no-properties
@@ -264,56 +311,68 @@ optionally of group SUBEXP."
;;;
;;; Block things detection
;;;
-(defun m-buffer-match-data-regexp-first (regexp &rest match-with)
- "Internal convienience function and not part of the API.
-The same as m-buffer-match-data but with the regexp first."
- (apply 'm-buffer-match-data
- (-insert-at 1 regexp match-with)))
-
-
-(defun m-buffer-match-page (&rest match-with)
- "Return a list of match data to all pages in MATCH-WITH.
-MATCH-WITH may be in any form accepted by `m-buffer-normalize-region'."
- (apply 'm-buffer-match-data-regexp-first
- page-delimiter match-with))
-
-(defun m-buffer-match-paragraph-separate (&rest match-with)
- "Returns a list of match data to all pages in MATCH-WITH.
-MATCH-WITH may be in any form accepted by
-`m-buffer-normalize-region'."
- (apply 'm-buffer-match-data-regexp-first
- paragraph-separate match-with))
-
-(defun m-buffer-match-line-start (&rest match-with)
- "Returns a list of matches to all line start."
- (apply 'm-buffer-match-data-regexp-first
- "^"
- (-snoc match-with 'm-buffer-post-match-forward-char)))
-
-(defun m-buffer-match-line-end (&rest match-with)
- "Returns a list of matches to line end."
- (apply 'm-buffer-match-data-regexp-first
- "$"
- (-snoc match-with
- 'm-buffer-post-match-forward-char)))
-
-(defun m-buffer-match-sentence-end (&rest match-with)
- "Returns a list of matches to sentence end."
- (apply 'm-buffer-match-data-regexp-first
- (sentence-end) match-with))
-
-(defun m-buffer-match-word (&rest match-with)
- "Returns a list of matches to all words."
- (apply 'm-buffer-match-data-regexp-first
- "\\\w+" match-with))
+(defun m-buffer-apply-snoc (fn list &rest element)
+ "Apply function to list and all elements."
+ (apply
+ fn (append list element)))
+
+(defun m-buffer-match-page (&rest match)
+ "Return a list of match data to all pages in MATCH.
+MATCH is of form BUFFER-OR-WINDOW MATCH-OPTIONS. See
+`m-buffer-match-data' for further details."
+ (m-buffer-apply-snoc 'm-buffer-match-data
+ match :regexp page-delimiter))
+
+(defun m-buffer-match-paragraph-separate (&rest match)
+ "Returns a list of match data to `paragraph-separate' in MATCH.
+MATCH is of form BUFFER-OR-WINDOW MATCH-OPTIONS. See
+`m-buffer-match-data' for futher details."
+ (m-buffer-apply-snoc
+ 'm-buffer-match-data match :regexp paragraph-separate
+ :post-match 'm-buffer-post-match-forward-line))
+
+(defun m-buffer-match-line-start (&rest match)
+ "Returns a list of match data to all line starts.
+MATCH is of form BUFFER-OR-WINDOW MATCH-OPTIONS. See
+`m-buffer-match-data' for further details."
+ (m-buffer-apply-snoc
+ 'm-buffer-match-beginning
+ match :regexp "^"
+ :post-match 'm-buffer-post-match-forward-char))
+
+(defun m-buffer-match-line-end (&rest match)
+ "Returns a list of matches to line end.
+MATCH is of form BUFFER-OR-WINDOW MATCH-OPTIONS. See
+`m-buffer-match-data' for further details."
+ (m-buffer-apply-snoc
+ 'm-buffer-match-beginning
+ match :regexp "$"
+ :post-match 'm-buffer-post-match-forward-char))
+
+(defun m-buffer-match-sentence-end (&rest match)
+ "Returns a list of matches to sentence end.
+MATCH is of the form BUFFER-OR-WINDOW MATCH-OPTIONS. See
+`m-buffer-match-data' for further details."
+ (m-buffer-apply-snoc
+ 'm-buffer-match-beginning
+ match :regexp (sentence-end)))
+
+(defun m-buffer-match-word (&rest match)
+ "Returns a list of matches to all words.
+MATCH is of the form BUFFER-OR-WINDOW MATCH-OPTIONS. See
+`m-buffer-match-data' for further details."
+ (m-buffer-apply-snoc
+ 'm-buffer-match-data
+ match :regexp "\\\w+"))
;; Useful post-match functions
(defun m-buffer-post-match-forward-line ()
- "Attempts to move forward one line and returns true if succeeds."
+ "Attempt to move forward one line, return true if success."
(= 0 (forward-line)))
(defun m-buffer-post-match-forward-char ()
- "Attempts to move forward one char and returns true if succeeds."
+ "Attempts to move forward one char and returns true if
+succeeds."
(condition-case e
(progn
(forward-char)
diff --git a/test/m-buffer-test.el b/test/m-buffer-test.el
index 5cf8ebca7f..17c52f49fe 100644
--- a/test/m-buffer-test.el
+++ b/test/m-buffer-test.el
@@ -33,6 +33,7 @@
,file))
,@body))
+
(ert-deftest m-with-temp-buffer-of-file ()
"Test my test macro."
(should
@@ -47,6 +48,39 @@
(should
(fboundp 'm-buffer-match-data)))
+
+(ert-deftest normalize-args ()
+ "Normalize Region"
+ ;; just buffer and regexp
+ (should
+ (equal
+ (list (current-buffer) "regexp" nil nil nil)
+ (m-buffer-normalize-args
+ (list (current-buffer) "regexp"))))
+
+ (should
+ (equal
+ (list (current-buffer) "regexp" nil nil nil)
+ (m-buffer-normalize-args
+ (list (current-buffer) :regexp "regexp"))))
+
+ (should
+ (equal
+ (list (current-buffer) "regexp" 1 2 3)
+ (m-buffer-normalize-args
+ (list (current-buffer) "regexp" :beginning 1 :end 2 :post-match 3))))
+
+ (should
+ (equal
+ (list (current-buffer) "regexp" 1 2 3)
+ (m-buffer-normalize-args
+ (list :buffer (current-buffer)
+ :regexp "regexp"
+ :beginning 1
+ :end 2
+ :post-match 3)))))
+
+
(ert-deftest m-buffer-matches ()
(should
(= 3
@@ -77,6 +111,15 @@
"^one$")))))
+(ert-deftest markers-to-pos ()
+ (should
+ (equal '(1 1 1)
+ (m-buffer-markers-to-pos-nil
+ (list
+ (copy-marker 1)
+ (copy-marker 1)
+ (copy-marker 1))))))
+
(ert-deftest m-buffer-match-beginning-pos ()
(should
(equal
@@ -125,11 +168,11 @@
(not
(m-buffer-wtb-of-file
"match-data.txt"
- (m-buffer-page-match (current-buffer))))))
+ (m-buffer-match-page (current-buffer))))))
(ert-deftest paragraph-separate ()
(should
- (m-buffer-paragraph-separate (current-buffer))))
+ (m-buffer-match-paragraph-separate (current-buffer))))
(ert-deftest line-start ()
(should
@@ -138,7 +181,7 @@
(m-buffer-wtb-of-file
"line-start.txt"
(m-buffer-markers-to-pos
- (m-buffer-line-start (current-buffer)))))))
+ (m-buffer-match-line-start (current-buffer)))))))
(ert-deftest line-end ()
(should
@@ -147,7 +190,16 @@
(m-buffer-wtb-of-file
"line-start.txt"
(m-buffer-markers-to-pos
- (m-buffer-line-end (current-buffer)))))))
+ (m-buffer-match-line-end (current-buffer)))))))
+
+(ert-deftest sentence-end ()
+ (should
+ (equal
+ '(15 32 48)
+ (m-buffer-wtb-of-file
+ "sentence-end.txt"
+ (m-buffer-markers-to-pos
+ (m-buffer-match-sentence-end (current-buffer)))))))
;;; m-buffer-test.el ends here
- [elpa] externals/m-buffer 76b65c025d 016/115: Test file for previous tests., (continued)
- [elpa] externals/m-buffer 76b65c025d 016/115: Test file for previous tests., ELPA Syncer, 2022/07/19
- [elpa] externals/m-buffer 94251c2abe 019/115: Package metadata added., ELPA Syncer, 2022/07/19
- [elpa] externals/m-buffer 2e1e7b5d29 021/115: Version Update., ELPA Syncer, 2022/07/19
- [elpa] externals/m-buffer 5784538b01 034/115: v0.4 iteration., ELPA Syncer, 2022/07/19
- [elpa] externals/m-buffer 354e1c6b2a 036/115: Change version suffix to alpha., ELPA Syncer, 2022/07/19
- [elpa] externals/m-buffer dc5f6c4149 038/115: Version 0.4 release., ELPA Syncer, 2022/07/19
- [elpa] externals/m-buffer 72acc99a91 042/115: New function: m-buffer-delete-match, ELPA Syncer, 2022/07/19
- [elpa] externals/m-buffer 2803b1f9b6 048/115: Match functions now accept a :numeric arg., ELPA Syncer, 2022/07/19
- [elpa] externals/m-buffer edfa6ef412 062/115: m-buffer-at added., ELPA Syncer, 2022/07/19
- [elpa] externals/m-buffer ce6dfb0023 006/115: Use Emacs var, ELPA Syncer, 2022/07/19
- [elpa] externals/m-buffer 84c7fddd48 008/115: Modifed match-data to use keyword args, except for first two args.,
ELPA Syncer <=
- [elpa] externals/m-buffer 25995a676e 009/115: README added., ELPA Syncer, 2022/07/19
- [elpa] externals/m-buffer 22760408a5 013/115: Updated normalize tests to cope with extra widen argument., ELPA Syncer, 2022/07/19
- [elpa] externals/m-buffer 5c46bf8102 017/115: Added function m-buffer-on-region -- apply a function to a region., ELPA Syncer, 2022/07/19
- [elpa] externals/m-buffer 8210f4147d 004/115: Move dev to test., ELPA Syncer, 2022/07/19
- [elpa] externals/m-buffer 650235fbdb 011/115: Build URL update., ELPA Syncer, 2022/07/19
- [elpa] externals/m-buffer 22d6b0d640 012/115: Beginning has become begin. Widen option added. New line matching functions., ELPA Syncer, 2022/07/19
- [elpa] externals/m-buffer c65b7b20c0 014/115: match-data-1 was failing on final match due to off-by-one error., ELPA Syncer, 2022/07/19
- [elpa] externals/m-buffer 1cc4d8cffb 015/115: Added functions: m-buffer-marker-tree-to-pos, m-buffer-match-nth-group., ELPA Syncer, 2022/07/19
- [elpa] externals/m-buffer 27380daef5 018/115: Functions to add overlays and properties to buffers., ELPA Syncer, 2022/07/19
- [elpa] externals/m-buffer 41384768bc 024/115: Merge pull request #1 from syohex/fix-typo, ELPA Syncer, 2022/07/19