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 '("\\(?:=\\|\\_<\\)\\(" . "\\)\\(?:\\_>\\|=\\)"))
=
is a symbol-constituent character in the syntax table used bylisp-interaction-mode
(which is what the*scratch*
buffer is using). In other modes it might not be a symbol character (inc-mode
it is a punctuation character, for example). I'm not sure why you would be writingtest=this
in elisp code, but I wouldn't particularly recommend changing the elisp syntax table. In other modes it might be more reasonable to customize syntax entries, if desired. So, what kind of text is this? For which mode(s) do you want this behaviour?