[Please pose a separate question for what you're really trying to do (your first paragraph, which I've removed): how to highlight all the words in the buffer that match the word under cursor, when the cursor is moved. This question should just be about
add-variable-watcher (the rest of your post).]
The variable watcher actually works. But
last-command is apparently not being set.
To see that it works:
(defun my-watch (symbol newval op where)
(message "SYM: %S, VAL: %S, OP: %S, WHERE: %S" symbol newval op where))
(add-variable-watcher 'last-command #'my-watch)
(setq last-command 'foobar)
That shows this in the echo area (and buffer
SYM: last-command, VAL: foobar, OP: set, WHERE: nil
But note the limitations documented in node Watching Variables of the Elisp manual:
There are a couple of ways in which a variable could be modified (or at least appear to be modified) without triggering a watchpoint.
Since watchpoints are attached to symbols, modification to the objects contained within variables (e.g., by a list modification function see Modifying Lists) is not caught by this mechanism.
Additionally, C code can modify the value of variables directly, bypassing the watchpoint mechanism.
A minor limitation of this feature, again because it targets symbols, is that only variables of dynamic scope may be watched. This poses little difficulty, since modifications to lexical variables can be discovered easily by inspecting the code within the scope of the variable (unlike dynamic variables, which can be modified by any code at all, see Variable Scoping).