Stefan Monnier writes: >> This patch makes sure that faces used for highlighting are always >> distinct and recycles them only when it is inevitable. > > Installed with 2 changes: > - replace "delete" with "remove" because it was applied to a list which > is reachable from other places (basically, from other buffer's > hi-lock--unused-faces). Attaching a patch with following changes. (This is the last lap) 1. Fix following bug when `font-lock-mode' is disabled. ,---- | Debugger entered--Lisp error: (wrong-type-argument integer-or-marker-p nil) | buffer-substring-no-properties(nil nil) | (let* ((hi-text (buffer-substring-no-properties (previous-single-property-change (point) (quote face)) (next-single-property-change (point) (quote face))))) (progn (let ((--dolist-tail-- hi-lock-interactive-patterns)) (while --dolist-tail-- (let ((hi-lock-pattern (car --dolist-tail--))) (let ((regexp ...)) (if (string-match regexp hi-text) (setq regexps ...))) (setq --dolist-tail-- (cdr --dolist-tail--))))))) | (and (memq (face-at-point) (mapcar (function hi-lock-keyword->face) hi-lock-interactive-patterns)) (let* ((hi-text (buffer-substring-no-properties (previous-single-property-change (point) (quote face)) (next-single-property-change (point) (quote face))))) (progn (let ((--dolist-tail-- hi-lock-interactive-patterns)) (while --dolist-tail-- (let ((hi-lock-pattern ...)) (let (...) (if ... ...)) (setq --dolist-tail-- (cdr --dolist-tail--)))))))) | (let ((regexps (quote nil))) (let ((regexp (get-char-property (point) (quote hi-lock-overlay-regexp)))) (if regexp (progn (setq regexps (cons regexp regexps))))) (and (memq (face-at-point) (mapcar (function hi-lock-keyword->face) hi-lock-interactive-patterns)) (let* ((hi-text (buffer-substring-no-properties (previous-single-property-change (point) (quote face)) (next-single-property-change (point) (quote face))))) (progn (let ((--dolist-tail-- hi-lock-interactive-patterns)) (while --dolist-tail-- (let (...) (let ... ...) (setq --dolist-tail-- ...))))))) regexps) | hi-lock--regexps-at-point() | (or (hi-lock--regexps-at-point) (mapcar (function car) hi-lock-interactive-patterns)) | (let* ((defaults (or (hi-lock--regexps-at-point) (mapcar (function car) hi-lock-interactive-patterns)))) (list (completing-read (if (null defaults) "Regexp to unhighlight: " (format "Regexp to unhighlight (default %s): " (car defaults))) hi-lock-interactive-patterns nil t nil nil defaults))) | (cond (current-prefix-arg (list t)) ((and (display-popup-menus-p) (listp last-nonmenu-event) use-dialog-box) (catch (quote snafu) (or (x-popup-menu t (cons (quote keymap) (cons "Select Pattern to Unhighlight" (mapcar ... hi-lock-interactive-patterns)))) (throw (quote snafu) (quote ("")))))) (t (if hi-lock-interactive-patterns nil (error "No highlighting to remove")) (let* ((defaults (or (hi-lock--regexps-at-point) (mapcar (function car) hi-lock-interactive-patterns)))) (list (completing-read (if (null defaults) "Regexp to unhighlight: " (format "Regexp to unhighlight (default %s): " (car defaults))) hi-lock-interactive-patterns nil t nil nil defaults))))) | call-interactively(unhighlight-regexp nil nil) `---- 2. Add a NEWS entry. 3. Re-works how hi-lock--unused-faces is allocated.