First of all note that the behavior of highlight-symbol
in your first example is actually right. The *scratch*
buffer is in lisp-interaction-mode
. The contents of the buffer is supposed to be Elisp and test=this
is a symbol in Elisp. For an instance the following is a legal Elisp form and you can eval it in the *scratch*
-buffer:
(setq test=this t)
Phil stated this clearly in his comment.
Symbols are built from characters with word syntax and symbol syntax.
The syntax is stored in the syntax table of a buffer and usually comes with the major-mode
of the buffer.
An example of a major mode where =
does not have symbol syntax but punctuation syntax is c-mode
.
If you put your buffer into c-mode
with M-x c-mode
RET the command highlight-symbol
works as you want it to work. If point is in test
of the string test=this
only test
is highlighted and not the full string test=this
.
You made your second attempt with text-mode
. What syntax does =
have in text-mode
? Does it end a sentence? No actually not. Is it a symbol. Yeah that fits better. So =
ended up with symbol syntax in text mode. That has the effect that test=this
is interpreted as one symbol in text mode.
But, that is a rather weak decision. If you like you can change the syntax of =
in text mode with the following hook:
(defun my-=-is-punctuation ()
"Give ?= punctuation syntax."
(modify-syntax-entry ?= "."))
(add-hook 'text-mode-hook #'my-=-is-punctuation)
If you activate text-mode
in a buffer after installing that hook you get the wanted behavior of highlight-symbol
there.
Changing the syntax table of some established major mode as personal customization is a quite drastic measure. It may be that some syntax based features of that mode do not work anymore afterwards.
Alternatively you can advise highlight-symbol
a bit to fit your purpose.
We can just temporarily modify the syntax table when calling highlight-syntax
and we can modify highlight-syntax-border-pattern
such that also the equal sign =
counts as a border.
If we do not like that the equal sign is also highlighted we need to exclude it from the regexp group to be highlighted. Therefore it is important to know that font-lock-add-keywords
allows to identify the regexp group to be highlighted.
In highlight-symbol-add-symbol-with-face
the regexp group to be highlighted is hard-coded as 0 -- the full regexp. We want to replace it with 1 -- the group excluding the potentially present equal signs.
Because its hard-coded we need an :override
advice for highlight-symbol-add-symbol-with-face
. That is a pity since such an :override
advice does not follow development changes in highlight-symbol-add-symbol-with-face
. At least it works with highlight-symbol-20160102.2009
.
As long as highlight-symbol-add-symbol-with-face
does not change you can use the following code in your init file.
(It is likely that it is possible to adapt the advice of highlight-symbol-add-symbol-with-face
if it changes.)
Install the Elisp code restart Emacs and call highlight-symbol
as you are used to. It will no longer interpret test=this
as one symbol but as two symbols separated by a punctuation.
(defun my-highlight-symbol-ad (oldfun &rest args)
"Call 'highlight-symbol' with modified syntax table."
(let ((orig (char-syntax ?=)))
(unwind-protect
(progn
(modify-syntax-entry ?= ".")
(apply oldfun args))
(modify-syntax-entry ?= (string orig)))))
(advice-add 'highlight-symbol :around #'my-highlight-symbol-ad)
(defun my-highlight-symbol-add-symbol-with-face-ad (symbol face)
"Put SYMBOL with FACE into `font-lock-keywords'.
Do it like `highlight-symbol-add-symbol-with-face' does
but use regexp group 1 instead of 0.
Note that after installing that advice you need to
use a group in `highlight-symbol-border-pattern'.
The original setting of `highlight-symbol-border-pattern'
without groups does not work anymore."
(let ((keywords `(,symbol 1 ',face prepend)))
(push keywords highlight-symbol-keyword-alist)
(font-lock-add-keywords nil (list keywords) 'append)
(highlight-symbol-flush)))
(advice-add 'highlight-symbol-add-symbol-with-face :override #'my-highlight-symbol-add-symbol-with-face-ad)
(setq highlight-symbol-border-pattern '("\\(?:=\\|\\_<\\)\\(" . "\\)\\(?:\\_>\\|=\\)"))