First, here is the full source code of my package.
Currently I'm working on a package that provides a feature which upon the user invoking several times in a row certain command in a short amount of time, an alternative command is invoke instead. The assumption is made on the basis that the user has forgotten that the alternative command exist and that it is better/more efficient to achieve what he wants to achieve than the command he is using now.
Example use case
many invocations of
previous-line through its bindings (either , C-n or , C-p), instead of letting the user keep invoking those two commands many more times, my package comes in and calls
avy-goto-line (because that's how the user previously configured it to work).
I want to force the user to comply with whatever input a command request, right now if the user fall asleep on any binding for
next-line, the alternative command
goto-line never executes, or at least that's how it looks. If the alternative command were
avy-goto-line it will throw an
wrong-type-argument rendering my feature useless for next invocations if I don't
I tried something like this:
(let* ((exit nil)) (while (not exit) (setf exit (ignore-errors (avy-goto-line)))))
And it works, it does what I want to achieve. But for functions like
goto-line or even
avy-goto-word-0 Emacs gets freeze and the mini-buffer never popups asking something to the user.
Here is the relevant parts of my code:
(setf schrute-shortcuts-commands '((goto-char (left-char right-char)) (goto-line (next-line previous-line)))) (defun schrute--run-command () "Helper that will run an alternative-command." (let* ((alternative-command) (command-list)) (dolist (elem schrute-shortcuts-commands) (setf alternative-command (car elem)) (setf command-list (cadr elem)) (when (or (member this-command command-list) (eq this-command command-list)) (funcall-interactively alternative-command))))) (defun schrute-check-last-command () "Check what command was used last time. It also check the time between the last two invocations of the same command and use the alternative command instead." (when (eq this-command last-command) (if (member this-command schrute--interesting-commands) (let* ((time-passed (float-time (time-subtract (current-time) schrute--time-last-command)))) (if (<= time-passed 1.0) (setf schrute--times-last-command (1+ schrute--times-last-command))) (setf schrute--time-last-command (current-time))))) (when (> schrute--times-last-command 2) (setf schrute--times-last-command 0) ;; Call the alternative command for `this-command' (ignore-errors (schrute--run-command))))