Subject: Re: bug#11378: 24.1.50; Suggestion: Let M-i in isearch cycle `search-invisible'

From: Juri Linkov <[email-masked]>
Date: Thu, 31 May 2012 03:55:10 +0300

>> Then the combination of comments and strings could be named "text" with
>> its filter bound to `M-s f t'.  And the inverse filter to exclude
>> comments and strings could be bound to `M-s f T'.  Also it could be
>> enabled only in prog-mode.
>
> I was thinking that maybe a cycling behavior would be better than
> toggling for these: off / foo-only / foo-excluded.

Maybe something like this:

(define-key isearch-mode-map "\M-sft" 'isearch-cycle-filter-text)

(defun isearch-cycle-filter-text ()
  "Cycle searching inside code vs strings/comments vs off."
  (interactive)
  (setq isearch-filter-predicates
	(cond ((memq 'isearch-filter-text isearch-filter-predicates)
               (cons 'isearch-filter-nontext
                     (delq 'isearch-filter-text isearch-filter-predicates)))
              ((memq 'isearch-filter-nontext isearch-filter-predicates)
               (delq 'isearch-filter-nontext isearch-filter-predicates))
              (t (cons 'isearch-filter-text isearch-filter-predicates))))
  (setq isearch-success t isearch-adjusted t)
  (isearch-update))

(defun isearch-filter-nontext (beg end)
  "Test whether the current search hit is not inside text.
Return non-nil if the text from BEG to END is not inside
strings or comments."
  (not (isearch-filter-text beg end)))

(put 'isearch-filter-nontext 'isearch-message-prefix "code ")

(defun isearch-filter-text (beg end)
  "Test whether the current search hit is inside text.
Return non-nil if the text from BEG to END is inside
strings or comments."
  (or (isearch-filter-comments beg end)
      (isearch-filter-strings beg end)))

(put 'isearch-filter-text 'isearch-message-prefix "text ")

(defun isearch-filter-strings (beg end)
  "Test whether the current search hit is inside strings.
Return non-nil if the text from BEG to END is inside strings."
  (save-match-data (nth 3 (syntax-ppss))))

(put 'isearch-filter-strings 'isearch-message-prefix "string ")

(defun isearch-filter-comments (beg end)
  "Test whether the current search hit is inside comments.
Return non-nil if the text from BEG to END is inside comments."
  (save-match-data (nth 4 (syntax-ppss))))

(put 'isearch-filter-comments 'isearch-message-prefix "comment ")