In a previous question, Make region(s) invisible (not evaluated) to query-replacy and similar commands, I learned about isearch-filter-predicate
. Now, I wonder if is there a similar method to make regions invisible to functions like string-match
, occur
etc.
For example I have this LaTeX
code:
\begin{eqnarray}
\begin{matrix}
\newline
\end{matrix}
\end{eqnarray}
I use string-match-p
to test if the \newline
(\\
) string occurs in the LaTeX
eqnarray
environment. If nil
I replace "eqnarray" --> "equation". I also need to "ignore" newlines that occur in sub-enviroments like matrix
, so I thought I could make the regions of these sub-enviroments "invisible" to the string-match-p
function.
Is there a way to do it? Alternatively I thought I could write the isearch-filter-predicate
combined with the search-forward-regexp
function to test for the occurrence of my target string in the region.
This is the code I wrote:
(defun skip-if-my-ignore (beg end)
"Return nil if some text BEG to END has non-`nil' property `my-ignore'."
(catch 'skip-if-my-ignore
(let ((pos beg))
(while (< pos end)
(when (get-text-property pos 'my-ignore) (throw 'skip-if-my-ignore nil))
(setq pos (1+ pos))))
t))
(defun test-invisibility ()
(interactive)
(save-excursion
(let* ((a (copy-marker (point-min)))
(SUB_ENVIRONMENTS (regexp-opt '(
"array"
"cases"
"pmatrix"
"matrix"
))))
(unwind-protect
(progn
(goto-char a)
(while (search-forward-regexp (concat
"\\\\begin{"
"\\(" SUB_ENVIRONMENTS "\\)"
"}")
nil t)
(save-excursion
(let* ((b (copy-marker (match-beginning 0)))
(SUB_ENV (match-string 1))
(e (copy-marker (search-forward-regexp
(concat "\\\\end{" SUB_ENV "}") nil t))))
(put-text-property b e 'my-ignore t)
(save-restriction
(narrow-to-region b e)
(let ((isearch-filter-predicate 'skip-if-my-ignore))
;; should not ask for replacements (in sub-environments)
(perform-replace "\\\\newline" "MATCHED" t t nil 1 nil b e)
(if (string-match-p "\\\\newline" (buffer-substring b e))
(read-string "string-match-p matched the string. I don't want this!")
(read-string "string-match-p didn't match the string. I WANT THIS!"))
(if (search-forward-regexp "\\\\newline" e t)
(read-string "search-forward-regexp matched the string. I don't want this!")
(read-string "search-forward-regexp didn't match the string. I WANT THIS!"))
;; should not find occurrences in the sub-environments:
(occur "\\\\newline" 1))))))))
;; *UNWINDFORMS
(remove-list-of-text-properties (point-min) (point-max) '(my-ignore))))))
string-match(-p)
oroccur
to be sensitive toisearch-filter-predicate
? They are not, nor are functions such asre-search-forward
(used byoccur-1
). Isearch andperform-replace
are sensitive to it.test...
). Something like that is what you'll need to do. You could define a function that does only that and use that in other code. Seenext-single-char-property-change
, for a start.string-match
and similar functions. This would make my job easier.isearch-filter-predicate
, to my knowledge anyway. But perhaps someone will post a relevant and helpful answer for you.cmdbufmod
. You could look for aneqnarray
environment, restrict the buffer to that region, delete the sub-environments in the entries ofBUFMOD-LIST
ofcmdbufmod
, run your command, and leavecmdbufmod
restoring the deleted sub-environments.