For Emacs, how to store what view-lossage collects into an external file?
Asked Answered
L

1

2

For Emacs, how do I store what view-lossage collects into an external file? Ideally I'd like to store these keystroke data into an external log file incrementally and automatically, meaning it is done so by default when Emacs is started.

Lublin answered 18/3, 2012 at 19:13 Comment(0)
T
8

In Emacs 24 at least (I can't check a prior version right now), the docstring for view-lossage states:

Display last 300 input keystrokes.

To record all your input on a file, use `open-dribble-file'.

And C-hf open-dribble-file RET tells me:

open-dribble-file is an interactive built-in function in `C source code'.

(open-dribble-file FILE)

Start writing all keyboard characters to a dribble file called FILE. If FILE is nil, close any open dribble file. The file will be closed when Emacs exits.

So simply add something like the following to your .emacs file:

(open-dribble-file (expand-file-name "~/.emacs.d/lossage.txt"))

Experimentally this clobbers the file if it already exists, so you'll need to deal with that.

Here's one approach. It accounts for multiple Emacs sessions by using make-temp-name to generate a semi-random filename for the dribble file, and then appends the contents of that to a primary lossage log file when Emacs exists. (If Emacs crashes, it would leave behind the temp file for you to deal with manually.)

(defmacro my-persistent-dribble-file (file)
  "Append the dribble-file for this session to persistent lossage log FILE."
  `(let* ((persistent-file (expand-file-name ,file))
          (temporary-file (make-temp-name (concat persistent-file "-")))
          (persistent-arg (shell-quote-argument persistent-file))
          (temporary-arg (shell-quote-argument temporary-file))
          (append-dribble-command (format
                                   "cat %s >>%s && rm %s"
                                   temporary-arg persistent-arg temporary-arg)))
     (open-dribble-file temporary-file)
     (eval `(add-hook 'kill-emacs-hook
                      (lambda () (shell-command ,append-dribble-command))))))

(my-persistent-dribble-file "~/.emacs.d/lossage")
Theocritus answered 18/3, 2012 at 20:17 Comment(6)
This stores lots of strings <help-echo> in the log file. Any idea what are those?Lublin
Search for help-echo in here: M-: (info "(elisp) Misc Events") RET. FYI I found that simply by going to the elisp manual and using the index: C-h i g (elisp) RET I help-echo RET (you can also use the menus).Theocritus
An easier way to deal with a unique filename is to use a timestamp: (open-dribble-file (expand-file-name (format-time-string "~/.emacs.d/%Y-%m-%dT%H:%M.txt")))Apocopate
pmielke: I have to disagree with you: (a) timestamps (especially with only per-minute granularity, as in your example) are not always unique; (b) creating unique filenames is the purpose of make-temp-name; (c) I don't think your code is "easier". That said, I think a timestamp-based approach is fine in this instance, provided the granularity is per-second (otherwise you're not sufficiently well protected against over-writing that file), as it saves you checking the creation date of the file if you end up with remnants of a crash. You could also combine the methods (timestamp + temp-name).Theocritus
My use of make-temp-name was flawed in that I wasn't passing an absolute prefix path argument, though. An absolute path enables Emacs to guarantee uniqueness by verifying that the generated name doesn't exist. I've just fixed that.Theocritus
That is a very cool technique. Has anyone been able to analyze it? or what would you use to read the lossage.txt file?Devotee

© 2022 - 2024 — McMap. All rights reserved.