aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Dalziel <tom_dl@hotmail.com>2022-11-01 00:16:08 +0000
committerTom Dalziel <33435574+tomdl89@users.noreply.github.com>2022-11-01 21:39:41 +0100
commitf9218169f1f39225e9f631209d285bb7af50c8fd (patch)
treef00e03a413de3334da47823815280b9b394bce46
parente0e68d006320557a34c72102cd08c421fbf68ce5 (diff)
Add evil-keep-lines and evil-flush-lines
-rw-r--r--evil-commands.el53
-rw-r--r--evil-tests.el7
2 files changed, 57 insertions, 3 deletions
diff --git a/evil-commands.el b/evil-commands.el
index eb3169c..fca933b 100644
--- a/evil-commands.el
+++ b/evil-commands.el
@@ -4086,17 +4086,64 @@ This is the same as :%s//~/&"
(apply #'evil-ex-substitute (point-min) (point-max)
(evil-ex-get-substitute-info (concat "//~/&"))))
+(defun evil-keep-lines (pattern beg end)
+ "Stripped down version of `keep-lines'.
+Delete lines between BEG & END which don't match PATTERN."
+ (goto-char (min beg end))
+ (setq end
+ (progn
+ (save-excursion
+ (goto-char (max beg end))
+ (unless (or (bolp) (eobp))
+ (forward-line 0))
+ (point-marker))))
+ (save-excursion
+ (or (bolp) (forward-line 1))
+ (let ((start (point)))
+ (while (< (point) end)
+ ;; Start is first char not preserved by previous match.
+ (if (not (re-search-forward pattern end 'move))
+ (delete-region start end)
+ (let ((end (save-excursion (goto-char (match-beginning 0))
+ (forward-line 0)
+ (point))))
+ ;; Now end is first char preserved by the new match.
+ (if (< start end)
+ (delete-region start end))))
+
+ (setq start (save-excursion (forward-line 1) (point)))
+ ;; If the match was empty, avoid matching again at same place.
+ (and (< (point) end)
+ (= (match-beginning 0) (match-end 0))
+ (forward-char 1)))))
+ (set-marker end nil)
+ nil)
+
+(defun evil-flush-lines (pattern beg end)
+ "Stripped down version of `flush-lines'.
+Delete lines between BEG & END which match PATTERN."
+ (goto-char (min beg end))
+ (setq end (copy-marker (max beg end)))
+ (save-excursion
+ (while (and (< (point) end)
+ (re-search-forward pattern end t))
+ (delete-region (save-excursion (goto-char (match-beginning 0))
+ (forward-line 0)
+ (point))
+ (progn (forward-line 1) (point)))))
+ (set-marker end nil))
+
(defun evil--ex-performant-global-delete (beg end pattern invert)
"Use fast functions for fast line deletion.
Delete lines between BEG & END which match PATTERN.
-Use `flush-lines' if INVERT is nil, or `keep-lines' if not."
+Use `evil-flush-lines' if INVERT is nil, or `evil-keep-lines' if not."
(goto-char end)
(re-search-backward pattern beg t)
(let ((end-marker (make-marker)))
(set-marker end-marker (point))
(if invert
- (keep-lines pattern beg end)
- (flush-lines pattern beg end))
+ (evil-keep-lines pattern beg end)
+ (evil-flush-lines pattern beg end))
(goto-char end-marker)
(set-marker end-marker nil)))
diff --git a/evil-tests.el b/evil-tests.el
index f2a7e86..2e069af 100644
--- a/evil-tests.el
+++ b/evil-tests.el
@@ -8458,6 +8458,13 @@ maybe we need one line more with some text\n")
"[n]o 1\nno 2\nno 3\nyes 4\nno 5\nno 6\nno 7\n"
(":g/yes/d" [return])
"no 1\nno 2\nno 3\n[n]o 5\nno 6\nno 7\n"))
+ (ert-info ("global delete, specifying case sensitivty")
+ (evil-test-buffer
+ "[a]lpha bravo charlie\nalpha Bravo charlie\nalpha BRAVO charlie\nalpha delta charlie"
+ (":g/\\CBravo/d" [return])
+ "alpha bravo charlie\n[a]lpha BRAVO charlie\nalpha delta charlie"
+ (":g/\\cBravo/d" [return])
+ "alpha delta charlie"))
(ert-info ("global substitute")
(evil-test-buffer
"[n]o 1\nno 2\nno 3\nyes 4\nno 5\nno 6\nno 7\n"