diff options
| author | Tom Dalziel <tom_dl@hotmail.com> | 2022-11-01 00:16:08 +0000 |
|---|---|---|
| committer | Tom Dalziel <33435574+tomdl89@users.noreply.github.com> | 2022-11-01 21:39:41 +0100 |
| commit | f9218169f1f39225e9f631209d285bb7af50c8fd (patch) | |
| tree | f00e03a413de3334da47823815280b9b394bce46 | |
| parent | e0e68d006320557a34c72102cd08c421fbf68ce5 (diff) | |
Add evil-keep-lines and evil-flush-lines
| -rw-r--r-- | evil-commands.el | 53 | ||||
| -rw-r--r-- | evil-tests.el | 7 |
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" |
