1

I'd like to search a buffer for headlines only. A headline is anything starting with the "*" character. Ideally, I'd invoke an interactive function which would take user input at the minibuffer. I'd only give it the string I'd like to search for (for example foo) and not worry about the regex (which would be the headline prefix "^\*.* " + foo). The function should behave the same as the classic regexp-isearch : reading input from the minibuffer, and search for next occurrence if you invoke it again.

Any ideas how I could do this?

EDIT

I found this code here. I edited it like this :

(defun search-headings ()
  "search for selected text"
  (interactive)
  (isearch-mode t t) ; forward + REGEXP
  (isearch-yank-string "^\*.* " ))

When I call search-headings the minibuffer shows a modified version of my regex, instead of "^\*.* "it shows "\^\*\.\* "

1 Answer 1

2

Two minor points to begin with:

  1. You forgot to escape your backslash — "^\\*.* ".
  2. "^\\*.* " should probably be "^\\*[^ ]* ".

isearch-yank-string will regexp-quote the string if isearch-regexp is non-nil. Here is its implementation in my Emacs:

(defun isearch-yank-string (string)
  "Pull STRING into search string."
  ;; Downcase the string if not supposed to case-fold yanked strings.
  (if (and isearch-case-fold-search
           (eq 'not-yanks search-upper-case))
      (setq string (downcase string)))
  (if isearch-regexp (setq string (regexp-quote string)))
  ;; Don't move cursor in reverse search.
  (setq isearch-yank-flag t)
  (isearch-process-search-string
   string (mapconcat 'isearch-text-char-description string "")))

We can implement a “literal” variation of it ourselves:

(defun isearch-yank-string-literal (string)
  "Pull STRING literally into search string."
  ;; Don't move cursor in reverse search.
  (setq isearch-yank-flag t)
  (isearch-process-search-string
   string (mapconcat 'isearch-text-char-description string "")))

Your function now becomes:

(defun search-headings ()
  "search for selected text"
  (interactive)
  (isearch-mode t t) ; forward + REGEXP
  (isearch-yank-string-literal "^\\*[^ ]* "))

If you us Isearch Plus, there is isearchp-regexp-quote-yank-flag which control the quoting behavior. You can simply let-bind it to nil before calling isearch-yank-string.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.