My reasons for doing so are exactly like https://unix.stackexchange.com/questions/271550/how-can-i-search-for-bolded-or-underlined-text , but the accepted solution there is to use vim. I don't fancy that, especially when we can use man
directly in emacs.
You can filter the interesting isearch-matches by the function registered at the variable isearch-filter-predicate
.
I demonstrate this below in a simplified way.
- I only check the first letter of the match. I accept the match if that letter is bold.
- Apparently
face-attribute
interferes with isearch in Emacs 26.2. For that reason I introduced the variableisearch-face-bold-p-fun
and set it to the more general predicate functionisearch-face-p
which just checks whether there is any face at the beginning of the match. Searching man-pages with that default works quite well.
(defun isearch-face-p (start end)
"Return faces at START, preferring those named in buffer text there."
(save-excursion
(goto-char start)
(face-at-point nil t)))
(defun isearch-face-bold-p (start end)
"Return a bold face at START."
(save-excursion
(goto-char start)
(cl-some (lambda (face) (and (facep face) (face-bold-p face nil t))) (face-at-point nil t))))
(defvar isearch-face-bold-p-fun #'isearch-face-p
"Isearch filter for bold text.
The value should be a function suitable for `isearch-filter-predicate'.")
(defun isearch-bold-forward-end-fun ()
"Uninstall isearch filter `isearch-face-bold-p-fun'."
(remove-function (local 'isearch-filter-predicate) isearch-face-bold-p-fun)
(remove-hook 'isearch-mode-end-hook #'isearch-bold-forward-end-fun))
(defun isearch-bold-forward ()
"Like `isearch-forward' only accepting bold matches."
(interactive)
(add-function :after-while (local 'isearch-filter-predicate) isearch-face-bold-p-fun)
(add-hook 'isearch-mode-end-hook #'isearch-bold-forward-end-fun)
(call-interactively #'isearch-forward))
Tested with emacs -Q
Emacs version GNU Emacs 26.2 (build 2, x86_64-pc-linux-gnu, GTK+ Version 3.22.30) of 2019-04-12
.
EDIT: Adapt Drew's proposal to use INHERIT
arg t for face-bold-p
.
-
See my answer at emacs.stackexchange.com/q/51651/2370, for why your
isearch-face-bold-p
fails on aman
page. – Drew Jul 16 at 20:27
Another answer: Using @Tobias's isearch-face-bold-p
, but corrected per this answer to this:
(defun isearch-face-bold-p (start end)
"Return non-nil if face at START is bold."
(save-excursion
(goto-char start)
(cl-some (lambda (face) (and face (face-bold-p face nil t))) (face-at-point nil t))))
You can do what you want using just C-z & isearch-face-bold-p
while searching. That is, you can add predicate isearch-face-bold-p
on the fly. All you need is the filter predicate. You can also save the resulting behavior, by using C-z n
followed by the search-command name you want, e.g. isearch-bold-forward
.
IOW, you can get the same behavior, including defining the search command, just by doing C-z isearch-face-bold-p C-z n isearch-bold-forward
. (From then on you can just use that new command.)
For this on-the-fly Isearch filtering you need Isearch+. See Dynamic Isearch Filtering.
-
Hi Drew. Ha ha ha. That
THING
arg offace-at-point
is really funny! Generate a*test*
buffer withC-x b
, put the wordbold
in, place point in front ofb
and debugM-:
(face-at-point 'THING)
. I have already replaced(face-at-point t t)
with(face-at-point nil t)
in my answer. – Tobias Jul 16 at 21:47 -
-
@Tobias: I thought that's what you wanted: to preferentially pick up a face name from the buffer text. But since you don't, I've changed my answer to use the same thing, nil. – Drew Jul 17 at 0:27