If I evaluate this form:
(open-dribble-file "/home/joe/keys.log")
then type something, Emacs saves what I type to the keys.log
file:
<return>hellow<backspace> keyloggi<down-mouse-5><mouse-5>ng world<down><down>
^E^X<C-down-mouse-4><C-mouse-4>^E^X^F^N^N<return>yes<return>
Let's stop that nonsense immediately.
(open-dribble-file nil)
What I would like is a similar function that would save each keypress together with a timestamp and some other metadata.
State of the art
There is command-log-mode, which can be adjusted to log every interactive command by setting
(setq clm/log-command-exceptions* '(nil))
It stores the time of the command on a :time text property, and that can be given a milisecond resolution by appending .%3N
to the relevant format-time-string
command. The only thing it doesn't do yet is actually save the text that I type. Instead, it records the first letter, and the number of letters typed:
t self-insert-command [47 times]
I'm guessing it will not be too hard to collect and save the entered text. I guess I'll report back when I figure out the text storage, unless someone beats me to it. :-)
(I won't need the exact text for basic analytics, for which what I have here is sufficient -- but it could be useful to save it for broader life-logging purposes.)
related
In the mean time, I noticed that there is a logkeys
package in Ubuntu. It does something similar to what I want, but I actually only want to track Emacs keypresses, because anything else is not likely to be productive work. Here is some logkeys
output as a sample:
2015-06-05 23:02:15+0100 > 3;<E-e1><E-e1>3<#+10>b3;ȁ
2015-06-05 23:02:22+0100 >
2015-06-05 23:02:22+0100 >
2015-06-05 23:02:22+0100 > 7'''u܂ccȁ3<#+7><CpsLk>3;q
(It is typing garbage because it doesn't know my keyboard layout, and only creates a timestamp when I press RET
.)
note
When I first posted this question, I thought it would make sense to approach it via Emacs C, with a patch to record_char
from keyboard.c
, which is where the dribble file is written. But given that there's a nearly complete solution in Lisp, that was almost certainly the wrong intuition. I've mostly revised that out but I thought I should record the initial idea, even though it wasn't that apt.