I am trying to implement a minor mode that displays in the modeline the current word count and the number of new words since the file was last opened.
There are some existing implementations with this type of functionality (e.g., nanowrimo.el). But as far as I can tell, all of the implementations I've found so far seem to re-count the entire buffer after each change (i.e. after each character insertion or deletion, kill, yank, undo, etc.) This makes emacs a bit slow and unresponsive on on large files. This would seem to be a very common problem, but I haven't found a solution.
I am trying to keep track of the current word count in a variable and use before-change-functions and after-change-functions to update that count after every insertion, deletion, kill, yank, undo, etc. This involves counting only the changed character(s) and the immediately surrounding characters. (For example, if a space is inserted between two non-word characters, the word count increases by 1.) This approach is much faster/more efficient - but I haven't quite figured out all the details to make it work.
Is there existing code that already does this, either using change hooks or any other method? Or, any thoughts about a good approach to do this?
flyspell
"displacement-commands" and also an idle-timer. If idle, then check. If not idle, then ifthis-command
iseq
to thelast-command
, then don't check -- otherwise, check. Thepre-command-hook
can recordthis-command
and thepost-command-hook
can check to see ifthis-command
iseq
tolast-command
. You can also have a list of commands that are excluded from the check, or a list of commands that are specifically included in the check.(info "(elisp) Change Hooks")
, because these hooks may not work as you'd expect, i.e. they may not be called in a balanced manner in every case.this-command
is noteq
thelast-command
?(make-variable-buffer-local 'before-change-functions)
but the function I added tobefore-change-functions
seems to be called in all buffers.