Skip to content

Commit 5310f5d

Browse files
committed
Add a new prompter for meow-visit.
- Add user option `meow-vist-prompter`. - Add `meow--prompt-buffer-highlight`, which highlights matches in the buffer similar to Isearch, and highlights all matches in the secondary selection while in Beacon Mode and point is in the secondary selection.
1 parent f553db1 commit 5310f5d

File tree

3 files changed

+115
-7
lines changed

3 files changed

+115
-7
lines changed

meow-command.el

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1349,18 +1349,45 @@ Argument REVERSE if selection is reversed."
13491349
The input will be pushed into `regexp-search-ring'. So
13501350
\\[meow-search] can be used for further searching with the same condition.
13511351
1352-
A list of words and symbols in the current buffer will be provided for completion.
1353-
To search for regexp instead, set `meow-visit-sanitize-completion' to nil.
1354-
In that case, completions will be provided in regexp form, but also covering
1352+
When `meow-prompter' is `completion' (the default), a list of
1353+
words and symbols in the current buffer will be provided for
1354+
completion. To search for a regexp instead, set
1355+
`meow-visit-sanitize-completion' to nil. In that case,
1356+
completions will be provided in regexp form, but also covering
13551357
the words and symbols in the current buffer.
13561358
1359+
When `meow-prompter' is `buffer-highlight', matches are
1360+
highlighted in the current buffer from point until then end of
1361+
the visible text. When `meow-visit-sanitize-completion' is
1362+
non-nil, only whole words and symbols are highlighted, and the
1363+
input is treated literally. When `meow-beacon-mode' is active
1364+
and point is inside the secondary selection, matches back to the
1365+
start or end of the selection are highlighted, depending on whether
1366+
`meow-visit' is searching backward or forward.
1367+
13571368
To search backward, use \\[negative-argument]."
13581369
(interactive "P")
13591370
(let* ((reverse arg)
13601371
(pos (point))
1361-
(text (meow--prompt-symbol-and-words
1362-
(if arg "Visit backward: " "Visit: ")
1363-
(point-min) (point-max)))
1372+
(prompt (if reverse "Visit backward: " "Visit: "))
1373+
(text (pcase meow-visit-prompter
1374+
('buffer-highlight
1375+
(apply #'meow--prompt-buffer-highlight
1376+
prompt
1377+
(let* ((ov-start (overlay-start mouse-secondary-overlay))
1378+
(ov-end (overlay-end mouse-secondary-overlay))
1379+
(use-sec (and (meow-beacon-mode-p)
1380+
(secondary-selection-exist-p)
1381+
(>= pos ov-start)
1382+
(< pos ov-end))))
1383+
(if reverse
1384+
(list (window-start (selected-window))
1385+
(if use-sec ov-end pos))
1386+
(list (if use-sec ov-start pos)
1387+
(window-end (selected-window)))))))
1388+
((or 'completion _)
1389+
(meow--prompt-symbol-and-words prompt
1390+
(point-min) (point-max)))))
13641391
(visit-point (meow--visit-point text reverse)))
13651392
(if visit-point
13661393
(let* ((m (match-data))

meow-util.el

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,66 @@ Looks up the state in meow-replace-state-name-list"
290290
(regexp-quote selected))
291291
selected))))
292292

293+
(defun meow--prompt-buffer-highlight (prompt beg end)
294+
"PROMPT from the minibuffer while highlighting matches between BEG and END.
295+
296+
When `meow-visit-sanitize-completion' is non-nil, matches are
297+
literal instead of regexps and only words and symbols are
298+
matched.
299+
300+
Highlights are only visible in the selected window."
301+
(let ((current-buffer (current-buffer))
302+
(selected-window (selected-window))
303+
(timer)
304+
(overlays)
305+
(prompter-minibuffer))
306+
(cl-labels ((transform-text (txt &optional quote-regexp)
307+
(cond (meow-visit-sanitize-completion
308+
(rx (or (seq symbol-start
309+
(literal txt)
310+
symbol-end)
311+
(seq word-start
312+
(literal txt)
313+
word-end))))
314+
(quote-regexp (regexp-quote txt))
315+
(t txt)))
316+
(delete-overlays ()
317+
(mapc #'delete-overlay overlays)
318+
(setq overlays nil))
319+
(highlight-matches ()
320+
;; Before highlighting the minibuffer contents, we need to
321+
;; check that we are still in the prompter's minibuffer, not
322+
;; some other minibuffer.
323+
(when (or (not enable-recursive-minibuffers)
324+
(equal prompter-minibuffer (current-buffer)))
325+
(delete-overlays)
326+
(let ((regexp (transform-text (minibuffer-contents))))
327+
(unless (string-empty-p regexp)
328+
(save-excursion
329+
(with-current-buffer current-buffer
330+
(goto-char beg)
331+
(while (ignore-error invalid-regexp
332+
;; If the user is still typing the regexp it
333+
;; might not be valid. In that case, we
334+
;; treat it as valid but not matching.
335+
(re-search-forward regexp end t))
336+
(let ((ov (make-overlay (match-beginning 0)
337+
(match-end 0))))
338+
(overlay-put ov 'face 'lazy-highlight)
339+
;; Same priority as Isearch lazy-highlight.
340+
(overlay-put ov 'priority 1000)
341+
(overlay-put ov 'window selected-window)
342+
(push ov overlays)))))))))
343+
(make-hl-timer ()
344+
(run-with-idle-timer 0.01 'repeat #'highlight-matches)))
345+
(unwind-protect
346+
(minibuffer-with-setup-hook
347+
(lambda () (setq timer (make-hl-timer)
348+
prompter-minibuffer (current-buffer)))
349+
(transform-text (read-from-minibuffer prompt) t))
350+
(cancel-timer timer)
351+
(delete-overlays)))))
352+
293353
(defun meow--on-window-state-change (&rest _args)
294354
"Update cursor style after switching window."
295355
(meow--update-cursor)

meow-var.el

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,8 +153,29 @@ This will affect how selection is displayed."
153153
:group 'meow
154154
:type '(repeat function))
155155

156+
(defcustom meow-visit-prompter 'completion
157+
"How `meow-visit' should prompt for a target.
158+
159+
- `completion' (the default) means to present a lists of regexps
160+
in the minibuffer, respecting the value of
161+
`meow-visit-sanitize-completion'.
162+
163+
- `buffer-highlight' means to highlight in the buffer the region
164+
matching the text in the minibuffer, whether after or before
165+
point. If point is within the secondary selection and
166+
`meow-beacon-mode' is active, then matches within the
167+
secondary selection are also highlighted. When
168+
`meow-visit-sanitize-completion' is non-nil, this treats the
169+
input literally and only matches whole words and symbols.
170+
171+
Any other value is treated as `completion'."
172+
:group 'meow
173+
:type '(choice (const :tag "Show regexps in the minibuffer" completion)
174+
(const :tag "Highlight text in the buffer" buffer-highlight)))
175+
156176
(defcustom meow-visit-collect-min-length 1
157-
"Minimal length when collecting symbols for `meow-visit'."
177+
"Minimal length when collecting symbols for `meow-visit' in the default prompter.
178+
See also `meow-visit-prompter'."
158179
:group 'meow
159180
:type 'integer)
160181

0 commit comments

Comments
 (0)