You should not try to fontify the buffer yourself.
I describe here a method that works in buffers with font-lock
activated.
Add the keywords with font-lock-add-keywords
as long as you need them and remove them afterwards with font-lock-remove-keywords
.
After such actions you should invalidate the buffer fontification with font-lock-flush
.
This method has two main advantages:
- It fontifies the buffer just in time. Only the visible part of the buffer is fontified. The fontification is extented as needed when the visible part of the buffer changes.
- The keyword is also highlighted in parts of the buffer that you insert/modify after the keyword has been added.
There follows example code that shows how keywords can be added to font-lock
.
(defface propertize-command-arg-face
'((t (:foreground "Red")))
"Face for highlighting command args with `propertize-command-arg'.
I am a bit lazy here and do not differentiate the faces terminal-wise.
See (info \"(elisp) Defining Faces\") for details."
:group 'latex)
(defvar propertize-command-arg-keywords nil
"Keywords highlighted by `propertize-command-arg'.")
(setq propertize-command-arg-keywords
'(("\\\\command{\\([a-z]+\\)}" 1 'propertize-command-arg-face)))
(defun propertize-command-arg ()
"Highlight command arguments in current buffer."
(interactive)
(font-lock-add-keywords
nil
propertize-command-arg-keywords
)
(font-lock-flush))
(defun unpropertize-command-arg ()
"Unhighlight command arguments in current buffer."
(interactive)
(font-lock-remove-keywords
nil
propertize-command-arg-keywords)
(font-lock-flush))
You indicated in the comments that you want to use the command with
latex-mode
and that your MATCHER should also match more general
arguments of LaTeX macros. The Elisp Manual describes that you can
also use functions as matchers. That function can use scan-sexps
for parsing the macro argument.
The following Elisp code defines a new function propertize-command-scanner
as matcher and
re-defines the keywords list for font-lock-add-keywords
to use propertize-command-scanner
.
Also note the comments given in the source code.
(defun propertize-command-scanner (bound)
"Search for LaTeX macro \\command{...}.
Start at point and do not search beyond BOUND.
Set match data such that the embraced macro
argument is the first group."
(when
(let (found)
(while (and (search-forward "\\command" bound t)
;; avoid matches in strings and comments
(null (setq found
(null
(nth 8
(syntax-ppss (point))))))))
found)
(let* ((b (match-beginning 0))
(comment-forward most-positive-fixnum) ;; also skips whitespace
(b1 (point))
(parse-sexp-ignore-comments t)
(e1 (scan-sexps b1 1)))
(set-match-data (list b e1 b1 e1 (current-buffer)))
(goto-char e1))))
(setq propertize-command-arg-keywords
'((propertize-command-scanner 1 'propertize-command-arg-face t)))
;; OVERRIDE must be non-nil since fontification of $...$ is syntax based
;; and syntax based fontification comes first.
I only outline a strategy for the case that font-lock
is not active:
Define your own special face as it is done above for the font-lock
case.
You can register a fontification function via jit-lock-register
.
That function gets the boundaries of the region to be fontified
and should set the face
property of the text-stretches that match your keyword.
When you want to get rid of the highlighting for your keyword search for the stretches of text that have
your special face as face property and remove their face property.
recursive-edit
session? Or maybe, do you fontify for printing orhtmlize-buffer
? It is often better to mention your primary task instead of some problem on the way of its solution.emac
's features to speed up and make more confortable myLaTeX
typesetting tasks. In this particular case I simply want to highlight some text (not easily detectable by regexp) during somequery-replace
routines. I'm also exploring the fontification as a method to discriminate region in my replacing routines (see emacs.stackexchange.com/q/47302/15606).