Skip to content

Instantly share code, notes, and snippets.

@darius
Created December 13, 2015 01:28
Show Gist options
  • Save darius/bf4d3f82114a937f63bf to your computer and use it in GitHub Desktop.
Save darius/bf4d3f82114a937f63bf to your computer and use it in GitHub Desktop.
;;; Record all keystrokes, with timestamps at millisecond resolution.
;;; (Actually it's Emacs commands instead of keystrokes, but that's close enough.)
;;; Restricted to particular modes, but I really advise NOT RUNNING
;;; THIS AT ALL if you do much of anything sensitive inside Emacs.
(defvar keylogger-path "/home/darius/git/keystroke-analysis/emacs-key-log"
"Where to store the log.")
(defvar keylogger-major-modes '(text-mode)
"What modes to record data for.
Only include a mode if you're sure you won't type in any secrets!")
(defun keylogger-loggable-p ()
(or (memq major-mode keylogger-major-modes)
(equal (buffer-name) "speed-type")))
(defun keylogger-go ()
(interactive)
"Start logging Emacs commands and keystrokes."
(add-hook 'pre-command-hook 'keylogger-log)
(add-hook 'kill-emacs-hook 'keylogger-on-exit))
(defun keylogger-on-exit ()
(with-demoted-errors
(keylogger-save)))
(defun keylogger-stop ()
(interactive)
"Stop logging Emacs commands and keystrokes."
(remove-hook 'pre-command-hook 'keylogger-log))
(defvar keylogger-events '()
"The data not yet saved in the logfile, newer first.")
(defun keylogger-clear-unsaved ()
(interactive)
"Erase that part of the log not yet written to the logfile."
(setq keylogger-events '()))
(defun keylogger-log ()
;; (Would be `with-demoted-errors' instead if not for paranoia from
;; an actual user.)
(ignore-errors
(when (and (this-command-keys)
(keylogger-loggable-p))
(push (vector (current-time) major-mode (this-command-keys))
keylogger-events))))
(defun keylogger-save ()
(interactive)
"Save the keylogger buffer to keylogger-path, and clear it."
;; N.B. not atomic
(when keylogger-events
(with-temp-buffer
(dolist (k (nreverse keylogger-events))
(let ((time (aref k 0))
(mode (aref k 1))
(keys (aref k 2)))
(insert (format "%s %S %s\n"
(format-time-string "%s.%3N" time)
mode
(key-description keys)))))
(append-to-file nil nil keylogger-path)
(setq keylogger-events '()))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment