In an earlier article 1, you learned how to highlight portions of your text file to get a better overview of it’s organization and contents. In this article, you will learn how to highlight variables in your program to make better sense of it.
This article is a continuation of the earlier article, and introduces two convenience features that you could put to good use.
As a motivation for this article, let us note the two inconveniences you may stumble upon as part of your highlight operations.
- Regular expression for matching program variables is hard to type and remember: The regular expression for a program variable is a bit hard to remember and type. For example, in order to highlight an identifier called
hi-lock-set-pattern, the regular expression you need to type is\_<hi-lock-set-pattern\_>. (If you can remember the regexp backslash patterns for beginning and end of symbols1, you definitely need to consider applying for a memory championship) - When you need to highlight in quick succession, choosing a face gets in the way: In the article linked above, you learn that highlighting was a two step-process. In the first step, you chose a pattern. In the second step, you picked a face. When you highlight stuff in quick succession, inputting a face to be used for highlighting gets in the way.
To alleviate (1), Emacs provides a highlight-symbol-at-point command. To alleviate (2), Emacs provides a hi-lock-auto-select-face option.
This article is primarily intended for programmers. If you are not a programmer, it is possible that you lose interest in this article. In that case, it would suffice if you note how to turn on auto-selection of faces.
Motivation
When you are a programmer, you spend most of the time looking at and analyzing source code. Much of analyzing and comprehending a program code, comes down to tracking how a data or a value (transforms and) flows through different program variables. When doing this analysis, you will find that highlighting the variables helps you in understanding the data flow better.
For the purpose of this article, we will spend some time analyzing hi-lock-set-pattern1, the workhorse function of hi-lock-mode1. Before you do that, here are a few preparatory steps.
Step 1: Install a custom menu
Copy the Emacs Lisp snippet1 below to your .emacs and restart your Emacs. This snippet adds a submenu named Customize Regexp Highlighting to the Edit menu.
(easy-menu-define my-hi-lock-menu nil "Menu for customizing regexp highlighting."
`("Customize Regexp Highlighting"
["Global Hi Lock Mode"
(progn
(customize-set-variable 'global-hi-lock-mode
(not global-hi-lock-mode))
(customize-save-variable 'global-hi-lock-mode global-hi-lock-mode))
:style toggle :selected global-hi-lock-mode :help "Toggle Hi-Lock mode in all buffers"]
["Hi Lock Mode" hi-lock-mode :style toggle :selected hi-lock-mode :help "Toggle selective highlighting of patterns"]
["Auto Select Face"
(customize-save-variable 'hi-lock-auto-select-face
(not hi-lock-auto-select-face))
:style toggle :selected hi-lock-auto-select-face :enable
(featurep 'hi-lock)
:help "\"Non-nil means highlighting commands do not prompt for the face to use.\nInstead, each hi-lock command will cycle through the faces in\n`hi-lock-face-defaults'.\""]
"--"
["Customize"
(customize-group 'hi-lock)]))
(easy-menu-add-item menu-bar-edit-menu nil my-hi-lock-menu)
(with-eval-after-load 'hi-lock
(define-key-after hi-lock-menu
[unhighlight-regexp-all]
`(menu-item "Remove All Highlighting"
(lambda nil
(interactive)
(unhighlight-regexp t))
:enable hi-lock-interactive-patterns :help ,(documentation 'unhighlight-regexp))
'unhighlight-regexp))
Step 2: Enable global-hi-lock-mode or hi-lock-mode

Step 3: Enable Auto Select Face

Step 4: Jump to a function, say hi-lock-set-pattern
For the purpose of this article, we will spend some time analyzing hi-lock-set-pattern1, the workhorse function of hi-lock-mode1. Here is a screenshot of this function.

Note the Hi in the modeline. If you aren’t seeing a Hi, it means that you haven’t enabled hi-lock-mode. Please revisit the previous step.
Step 4: Highlight a variable / symbol that you would like to track
In this article we will trace how the first formal parameter regexp flows and transforms itself within the function, hi-lock-set-pattern. To this end, place your cursor over regexp and highlight it as below.


From the screenshot above, you realize that formal parameter regexp transforms in to the local variable pattern. It is also used as input to re-search-forward to identify places where the regexp pattern appears.
Step 3: Highlight more symbols, based on results from earlier step
Now highlight the local variable pattern identified in the previous step. You would see that it gets collected in to hi-lock-interactive-patterns and it is used to construct an argument to font-lock-add-keywords.
The matches from re-search-forward for pattern, is used to construct an overlay. So, highlight the local variable overlay as well.
At the end of the above steps, this is what your buffer looks like.

A quick look at screenshot above shows that hi-lock library achieves highlighting using font-lock in buffers that are in font-lock-mode and uses overlays in buffers that aren’t in font-lock-mode.
Step 4: Un-highlight all symbols
Once your analysis is over, you can remove all the highlights and start all over again. For example, you can track down how the path of the second formal parameter, face.

Step 4′: Unhighlight a symbol
Occasionally, you might want to turn off highlights on a particular symbol. This could either be because you highlighted the wrong symbol or you have so many highlights that your code becomes less comprehensible.
For the sake of illustration, let us un-highlight one of the symbols from the previous step.



A note on faces used for highlighting
When you are using auto-selection for faces, Emacs circles among a set of 9 faces, and picks a face that is as yet unused in that buffer. This ensures that each subsequent highlight is distinct from earlier highlights.
You can look at the 9 faces as below. Some of these faces uses a background color (just like a conventional highlighter), but others use foreground color and other text properties. This mix of foreground and background highlighting annoys me at times. So, I tend to use background colors on all faces.



How to turn-off auto-selection
I usually leave auto-selection of highlight faces on. There are instances, where one might want to momentarily turn-off auto selection and pick a face explicitly. You ran across one such instance in the earlier article. In such cases, you can use the C-u prefix to highlight commands above, and you will be prompted for a face to use. Generally speaking, the C-u prefix to highlight commands, momentarily toggles your custom setting for auto-selection of faces.
Gotcha for Emacs 27 (and later) users
In future Emacs 27, the prefix arg for highlight commands is interpreted differently1
and gets in the way of how the prefix arg is interpreted now 1. You may want to bring the above conflict to the notice of Emacs Developers, and explore ways that will get you both the current behaviour and the proposed enhancement. The two behaviours, which are right now in direct conflict, are useful in their own rights.
Highlighting FIXMES, TODOs etc in your program
When you are working on large codebases, it is very common to find FIXMEs and TODOs. Whether you are tracking down a bug or implementing new features, you would very much want to be aware of these. In that case, you can add the following snippet to your .emacs
(add-hook 'hi-lock-mode-hook
(lambda nil
(highlight-regexp "FIXME" (quote hi-red-b))
(highlight-regexp "TODO" (quote hi-red-b))
)
t)
Once you restart Emacs, this is how FIXMEs1 in hi-lock.el gets displayed.

The snippet above uses highlight-regexp, and easy for a layman to comprehend and modify. If you are comfortable with Emacs Lisp, and want more sophisticated highlighting you could explore font-lock-add-keywords 1.
I’m a big fan of highlighting symbols to help spot changes to a variable I’m interested in 🙂
Have you tried highlight-symbols-mode? This automatically highlights other instance of the symbol under point. It’s very lightweight and gives a similar workflow.
LikeLike