RepetitionDetection

This is something I wanted a long time from Emacs. This page serves as a brainstorming area and to draw attention toward the idea.

I currently dont know how to implement this, maybe someone has useful idea.

What is it

kbd-macros in Emacs are great. Only problem is that sometimes you dont realize what you repeat often and what you could save as kbd-macro. RepetitionDetection should automatically detect when you repeat a certain sequence more than a configurable number of times and prompt you about that. You should be offered to automatically make that sequence a kbd-macro, optionally name it, bind it to a key, and maybe even save it into .emacs.

Options

Random ideas

The abbrev-mode stuff works as a result of the C code in src/cmds.c’s internal_self_insert() function explicitly calling Fexpand_abbrev() for each character that is inserted (Emacs 21.1). For this RepetitionDetection to work we would need the pattern detection code to run on every keystroke, not just the ones which result in a character being inserted into a buffer, so we cannot directly use the abbrev-mode functionality, although we could conceivably add a call into the appropriate (presumably C) code which handles keystrokes.

record_char() in src/keyboard.c looks like the best place to put the call to the RepetitionDetection code, since that gets called for all keystrokes, not just the ones that insert characters. There’s also a vector in keyboard.c, recent_keys, which looks like it might be what we want to scan for patterns, although it might be too short if the pattern that has been repeated is quite long.

There are problems with using pre-command-hook. Try typing “C-u 12345 M->” and you will see that pre-command-hook gets run several times.

Using command-history

I made a start on this a while ago, but didn’t complete it. You can pick up the code from http://www.cb1.com/~john/computing/emacs/lisp/startup/predict-future.el if you’d like to try completing it. It tries to do for command sequences what dynabrev does for text input.

“Markov chains” is probably the area of theory needed to do this properly.

Things to Avoid

When processing lossage, there are some key events that should probably be ignored for the purposes of repetition detection. Here’s an (incomplete) list:

 <help-echo>
 <mouse-movement>

Contributors: ZwaX, MarioLang, CharlesSebold.

See also

Discussion

I have a need for something simpler than this. I would like to have Emacs record not each key but each command that I execute (save maybe stuff like ‘self-insert-command’ and ‘newline’). Using this statistic I could decide which commands are worth putting on my function keys, or other “easy” keys like C-<some char> and M-<some char>. I assume this would be quite easy to do but I am not sure where to start looking. I will post back my own findings here if no one beats me to it. – MaDa

This is almost exactly command-frequency. To get it to display the binds for each command, eval the following:
      (put 'command-frequency 'interactive-form
            '(interactive
              (list
               (if current-prefix-arg t "")
               nil
               (when current-prefix-arg (prefix-numeric-value current-prefix-arg))
               (lambda (num-calls percent-calls cmd)
                 (let ((bind-list (mapconcat
                                   'key-description
                                   ;; delete the boring menu binds
                                   (delete-if (apply-partially 'some ''symbolp)
                                              (where-is-internal
                                               cmd
                                               overriding-local-map))
                                   ", ")))
                   (if bind-list
                       (format "%6d  %5.2f  %-35s  %s\n"
                                num-calls percent-calls cmd bind-list)
                     ""))))))
This code just specifies the fourth argument for interactive calls. A fair number of commands don’t get their binds listed, and I believe it’s simply because the keymaps to which they belong are bound (or brought into effect, in the case of mode maps) on the fly, so this can’t really be fixed. Also, in command-frequency.el, change the line
      (message (prin1-to-string l))
to
      (message "%s" l)
It’s interesting to see if your frequency rankings follow Zipf’s law (this commenter’s do: zort-command-frequency-zipf-plot).

I’d say that if you can’t tell what repetition is annoying you, then it isn’t annoying you enough! – DrewAdams

Well, I am also lazy… Switching to the .emacs buffer, adding a new key binding (finding a free key that fits) etc makes me pretend that I don’t know what commands I use often. I will try Aaron’s tip below, maybe the statistics will wake me up… :)MaDa

CommandLogMode keeps track of what commands you type. You could pipe its contents to `uniq -c’ to generate statistics. – AaronHawley


CategoryKeys