Skip to content

Commit d8a207a

Browse files
committed
Add interactive highlights for ex global command pattern
1 parent a7ffa73 commit d8a207a

File tree

4 files changed

+66
-1
lines changed

4 files changed

+66
-1
lines changed

evil-commands.el

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4187,6 +4187,29 @@ Use `evil-flush-lines' if INVERT is nil, or `evil-keep-lines' if not."
41874187
(goto-char end-marker)
41884188
(set-marker end-marker nil)))
41894189

4190+
(evil-ex-define-argument-type global
4191+
"This handler highlights the pattern in :g/pattern/cmd."
4192+
:runner
4193+
(lambda (flag &optional arg)
4194+
(with-current-buffer evil-ex-original-buffer
4195+
(cond
4196+
((eq flag 'start)
4197+
(evil-ex-make-hl 'evil-ex-global
4198+
:face 'evil-ex-global-command-matches
4199+
:win (minibuffer-selected-window))
4200+
(setq flag 'update))
4201+
((eq flag 'stop)
4202+
(evil-ex-delete-hl 'evil-ex-global)))
4203+
4204+
(when (and evil-ex-global-command-interactive-highlight
4205+
(eq flag 'update))
4206+
(condition-case err
4207+
(let ((pattern (car (evil-ex-parse-global (or arg "")))))
4208+
(when (length> pattern 0)
4209+
(evil-ex-hl-change 'evil-ex-global
4210+
(evil-ex-make-pattern pattern evil-ex-search-case nil))))
4211+
(user-error (evil-ex-echo (error-message-string err))))))))
4212+
41904213
(evil-define-operator evil-ex-global
41914214
(beg end pattern command &optional invert)
41924215
"The Ex global command.

evil-tests.el

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8651,17 +8651,39 @@ maybe we need one line more with some text\n")
86518651
(ert-deftest evil-test-global ()
86528652
"Test `evil-ex-global'."
86538653
:tags '(evil ex global)
8654+
8655+
(defun evil-test-force-invoke-ex-hl-update-timer ()
8656+
"Force invoke ex-hl-update-timer."
8657+
(when evil-ex-hl-update-timer
8658+
(timer-event-handler evil-ex-hl-update-timer)))
8659+
(advice-add 'evil-ex-hl-idle-update :after
8660+
#'evil-test-force-invoke-ex-hl-update-timer)
8661+
8662+
(defun evil-test-save-last-ex-global-hls ()
8663+
"Save current 'evil-ex-global highlights to buffer-local variable."
8664+
(when-let* ((hl (cdr (assq 'evil-ex-global evil-ex-active-highlights-alist)))
8665+
(ovs (evil-ex-hl-overlays hl)))
8666+
(setq ovs (sort ovs (lambda (a b) (< (overlay-start a) (overlay-start b)))))
8667+
(setq-local evil-test-last-ex-global-hls
8668+
(seq-map (lambda (ov) (buffer-substring-no-properties (overlay-start ov) (overlay-end ov)))
8669+
ovs))))
8670+
(advice-add 'evil-ex-hl-update-highlights :after
8671+
#'evil-test-save-last-ex-global-hls)
8672+
86548673
(ert-info ("global delete")
86558674
(evil-test-buffer
86568675
"[n]o 1\nno 2\nno 3\nyes 4\nno 5\nno 6\nno 7\n"
86578676
(":g/yes/d" [return])
8677+
(should (equal evil-test-last-ex-global-hls '("yes")))
86588678
"no 1\nno 2\nno 3\n[n]o 5\nno 6\nno 7\n"))
86598679
(ert-info ("global delete, specifying case sensitivty")
86608680
(evil-test-buffer
86618681
"[a]lpha bravo charlie\nalpha Bravo charlie\nalpha BRAVO charlie\nalpha delta charlie"
86628682
(":g/\\CBravo/d" [return])
8683+
(should (equal evil-test-last-ex-global-hls '("Bravo")))
86638684
"alpha bravo charlie\n[a]lpha BRAVO charlie\nalpha delta charlie"
86648685
(":g/\\cBravo/d" [return])
8686+
(should (equal evil-test-last-ex-global-hls '("bravo" "BRAVO")))
86658687
"alpha delta charlie"))
86668688
(ert-info ("global delete with arg")
86678689
(evil-test-buffer
@@ -8694,6 +8716,7 @@ maybe we need one line more with some text\n")
86948716
("/yes" [return])
86958717
"no 1\nno 2\nno 3\nyes 4\nno 5\nno 6\nno 7\n"
86968718
(":g//d" [return])
8719+
(should (equal evil-test-last-ex-global-hls '("yes")))
86978720
"no 1\nno 2\nno 3\n[n]o 5\nno 6\nno 7\n"
86988721
(":v//d" [return])
86998722
""))
@@ -8704,6 +8727,7 @@ maybe we need one line more with some text\n")
87048727
("/isearch" [return])
87058728
"no 1\nno 2\nno 3\nisearch 4\nno 5\nno 6\nno 7\n"
87068729
(":g//d" [return])
8730+
(should (equal evil-test-last-ex-global-hls '("isearch")))
87078731
"no 1\nno 2\nno 3\n[n]o 5\nno 6\nno 7\n"
87088732
(":v//d" [return])
87098733
""))
@@ -8713,27 +8737,35 @@ maybe we need one line more with some text\n")
87138737
(evil-test-buffer
87148738
"this\nThis\n"
87158739
(":g/this/d" [return])
8740+
(should (equal evil-test-last-ex-global-hls '("this")))
87168741
"This\n"))
87178742
(let ((evil-ex-search-case 'insensitive))
87188743
(evil-test-buffer
87198744
"this\nThis\n"
87208745
(":g/this/d" [return])
8746+
(should (equal evil-test-last-ex-global-hls '("this" "This")))
87218747
""))
87228748
(let ((evil-ex-search-case 'smart))
87238749
(evil-test-buffer
87248750
"this\nThis\n"
87258751
(":g/this/d" [return])
8752+
(should (equal evil-test-last-ex-global-hls '("this" "This")))
87268753
"")
87278754
(evil-test-buffer
87288755
"this\nThis\n"
87298756
(":g/This/d" [return])
8757+
(should (equal evil-test-last-ex-global-hls '("This")))
87308758
"this\n"))))
87318759
(ert-info (":global should transform vim-style regexp when appropriate")
87328760
(let ((evil-ex-search-vim-style-regexp t))
87338761
(evil-test-buffer
87348762
"a\n1\nb\n2\nc\n3\n"
87358763
(":g/\\d/>")
8736-
"a\n 1\nb\n 2\nc\n 3\n"))))
8764+
(should (equal evil-test-last-ex-global-hls '("1" "2" "3")))
8765+
"a\n 1\nb\n 2\nc\n 3\n")))
8766+
8767+
(advice-remove 'evil-ex-hl-idle-update #'evil-test-force-invoke-ex-hl-update-timer)
8768+
(advice-remove 'evil-ex-hl-update-highlights #'evil-test-save-last-ex-global-hls))
87378769

87388770
(ert-deftest evil-test-normal ()
87398771
"Test `evil-ex-normal'."

evil-types.el

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,7 @@ If visual state is inactive then those values are nil."
388388

389389
(evil-define-interactive-code "<g/>"
390390
"Ex global argument."
391+
:ex-arg global
391392
(when evil-called-from-ex-p
392393
(evil-ex-parse-global (or evil-ex-argument ""))))
393394

evil-vars.el

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1353,6 +1353,15 @@ line. If this option is non-nil, this behavior is reversed."
13531353
"Face for interactive replacement text."
13541354
:group 'evil)
13551355

1356+
(defcustom evil-ex-global-command-interactive-highlight t
1357+
"If non-nil, pattern matches in Ex global commands are interactively highlighted."
1358+
:type 'boolean
1359+
:group 'evil)
1360+
1361+
(defface evil-ex-global-command-matches '((t :inherit lazy-highlight))
1362+
"Face for interactive global command matches."
1363+
:group 'evil)
1364+
13561365
(defcustom evil-command-window-height 7
13571366
"Height (in lines) of the command line window.
13581367
Set to 0 to use the default height for `split-window'."

0 commit comments

Comments
 (0)