[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Character repeation detection

From: Stefan Monnier
Subject: Re: Character repeation detection
Date: Sun, 09 Mar 2014 21:20:38 -0400
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/24.3.50 (gnu/linux)

> For example, I want to invoke occur. I press o and keep it pressed.
> After auto repeat types 3 o characters this function kicks in, removes
> the 3 typed Os from the buffer, removes the additional Os from the
> keyboard buffer (if I kept it pressed for two long) and calls occur.

I think that dealing with auto-repeat would be ugly: you have to
wait "1 / auto-repeat-rate" before you know if you've seen the last
repetition and in general you don't know auto-repeat-rate so it's
a bit hackish.  And if you additionally want to check if the event is
really an auto-repeat and not some other event that also came quickly,
then you need to "peek" at the events, which is somewhere between hard
and impossible to do reliably.

OTOH if you only want to handle the "3 presses" case, you can probably
do it as follows:

   (defvar my-multi-self-insert-trick-map '((?o . occur)))
   (defun my-multi-self-insert-trick ()
     (and (eq this-command last-command)
          (not current-prefix-arg)
          (looking-back "\\(.\\)\\1\\{2\\}" (- (point) 3)) ;; 3rd in a row.
          (let ((cmd (cdr (assq (char-before)
            (when cmd
              (delete-region (match-beginning 0) (match-end 0))
              (call-interactively cmd)))))
   (add-hook 'post-self-insert-hook 'my-multi-self-insert-trick)

To handle auto-repeat, you'd have to add a loop along the lines of

   (let ((evt last-command-event))
     (while (and (not (sit-for (/ 1.0 my-auto-repeat-rate) 'nodisp))
                 (let ((k (read-key "")))
                   (if (and (eq (length k) 1) (eq (aref k 0) evt))
                       ;; It's a repetition; just drop it.
                     ;; It's not a repetition; put it back.
                     ;; FIXME: we basically can't do it 100% right because
                     ;; read-key already had to decide whether the incoming
                     ;; events are bytes or characters.
                     (setq unread-command-events
                           (nconc (append (this-single-command-raw-keys) nil)

after the `when cmd'.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]