The initial regexp "\\_<.+?\\_>"
and the subsequent (regexp-opt unique 'symbols)
are connected, as the 'symbols
argument wraps \_<
and \_>
(being symbol start/end delimiters) around the result. This ensures that the latter search will only match instances of the original search. If you weren't matching symbols, you'd need to change both patterns, with appropriate care taken.
(defun my-highlight-unique-symbols ()
"In each block, highlight all symbols which occur exactly once."
(interactive)
(font-lock-ensure)
(save-excursion
(goto-char (point-min))
(let ((regexp "\\_<.+?\\_>")
(case-fold-search nil)
(blockstart (point))
(blockdelimiter "\n\n\n"))
;; Establish the next block.
(while (and (not (eobp))
(or (search-forward "\n\n\n"blockdelimiter nil t)
(goto-char (point-max))))
(let ((blockend (point)))
(goto-char blockstart)
;; Highlight unique identifiers in this block.
(let ((identifiers (obarray-make))
unique)
(save-excursion
(while (re-search-forward "\\_<.+?\\_>"regexp blockend t)
;; Count theHave occurrenceswe ofseen eachthis match. before?
(letlet* ((sym (intern (match-string 0) identifiers)))
(put sym 'count (1+ (orregion (get sym 'count) 0)))'region)))
(if region ;; ExtractThis theis uniquea instancesduplicate.
(obarray-mapunless (lambdaeq region 'duplicate)
(put sym 'region 'duplicate))
;; This is the first time we've (whenseen (eqlthis (getmatch.
sym 'count) 1)
;; Store the region boundaries for the match.
(push (symbol-nameput sym) unique))'region (cons (match-beginning 0)
identifiers (match-end 0)))))))
;; Highlight the unique instances.
(letsave-excursion
((regexp (regexpwith-optsilent-modifications
unique 'symbols)))
(saveobarray-excursionmap
(with-silent-modificationslambda (sym)
(whilelet (re-search-forward(region regexp(get blockendsym t'region)))
(unless (eq region 'duplicate)
(put-text-property (match-beginningcar 0region) (match-endcdr 0region)
'face 'highlight))))
identifiers)))
;; Prepare for the next block.
(setq blockstart blockend)))))))