Super User is a question and answer site for computer enthusiasts and power users. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I want to log my usage of M-x in emacs to a file so that I can see which functions I should learn the shortcut to / bind a shortcut for. This would preferably just append the names of the used functions to a file/emacs-buffer, maybe with a timestamp, so that I can see in what context I use them. Does anyone know how to solve this?

share|improve this question
up vote 3 down vote accepted

I would suggest adding an advisory function to execute-extended-command, and another to read, such that when execute-extended-command is being run, anything read in the minibuffer is logged to your defined buffer with a timestamp.

I have been meaning to learn how to use advise, so I will be editing this comment later with working elisp code once I have code that does this (should be less than ten lines).


based on Trey Jackson's very wonderful work, here is my additional version:

(defvar my-m-x-log-file "~/mx.log")
(defadvice execute-extended-command
  (after log-execute-extended-command activate)
  (let ((logfile (find-file-noselect my-m-x-log-file)))
    (with-current-buffer logfile
      (goto-char (point-max))
      (insert (format "%s --- %s --- "
      (where-is this-command t)
      (insert "\n"))))

This logs the timestamp, the command, and the keybindings, and does not obscure any echos from the m-x commands.

You will have to save the log file manually like you would any other emacs buffer, unlike Trey's version. There may be a compromise possible where the file is written to but there is no message echod to the minibuffer obscuring results of a command.

share|improve this answer
I think advising execute-extended-command should be enough... a post-advise, of course. Not sure though, don't have a running Emacs handy. :( – Jürgen A. Erhard Feb 27 '10 at 17:25
the tricky thing is that the extended command that is read from the minibuffer is not the return value of execute-extended-command - or is there a way to grab internal variables / results via advise? – Justin Smith Feb 27 '10 at 17:27
OK cool trey figured out how to get the command from inside advise, you were right. – Justin Smith Feb 27 '10 at 17:42
having made the edits and being able to scan and see the keybindings for m-x that I run, I am thinking this is kind of awesome and I may just be keeping this in my .emacs – Justin Smith Feb 27 '10 at 18:32

You can start with this elisp, which will simply add the commands you execute to a given log file. You can get fancier and do automatic tallying if you want. Or, you can occasionally just pipe the file through a sort|uniq -c.

(defvar my-m-x-log-file "~/mx.log")
(defadvice execute-extended-command (after log-execute-extended-command activate)
  (let ((logfile (find-file-noselect my-m-x-log-file)))
    (with-current-buffer logfile
      (goto-char (point-max))
      (insert (format "%s\n" this-command))
share|improve this answer
cool, this is probably what I would have ended up with if I knew advise already :) now to go back to figuring out advise for myself. – Justin Smith Feb 27 '10 at 17:45
This works, but it puts the message "Wrote ~/mx.log" (the name of the log file) in the minibuffer after the command being run is finished. Is there any way of suppressing this message so that I can see the output of whatever command I'm running? – petergil Feb 27 '10 at 17:45
one workaround would be to remove (save-buffer) from the code - the consequence would be that you would be prompted to save it manually, like any other buffer, rather than having the buffer automatically saved. Also, for making the time stamp, you could change (format "%s\n" this-command) into (format "%s %s\n" (current-time-string) this-command). There may be a way of printing the keybinding on the same line too... I am looking into it. – Justin Smith Feb 27 '10 at 18:06
Great! This will do for now.. I'm planning on learning more lisp programming, so I'll into this some more myself. As for finding out which keybinding is used, it should be possible to parse the output from describe-function, or try to extract the needed parts from describe-function-1. After a quick look, it seems a bit hairy, though.. – petergil Feb 27 '10 at 18:50

Edit: On re-reading I believe that I have answered the wrong question. You might have been better off asking this on Stack Overflow since the answer probably required hacking elisp.

C-h f function-name

will get you the documentation on function-name, including the current key-binding.

C-h k <key stroke>

will show the current function bound to any key stroke

C-h b

will list all active key binding

share|improve this answer
But I think it really does belong here, since it's not about programming Emacs, but using it (the task will likely require writing some Elisp, but the question itself is not about writing Elisp). – Jürgen A. Erhard Feb 27 '10 at 17:24

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .