The dot Command not able to repeat text inserted by "Auto-complete"

Frank Fischer frank.fischer at mathematik.tu-chemnitz.de
Mon Aug 22 09:44:49 CEST 2011


Am Freitag, 19. August 2011 schrieb York Zhao:
> Here's the sequence:
>
> 1. make emacs
> 2. "C-h v evil-move-cursor-back"
> 3. Click on "customize this variable"
> 4. Toggle the value to "off"
> 5. Click on "Set for current session"
> 6. Click on "Exit"
> 7. In the "Scratch" buffer type "i"
> 8. Type "aaa"
> 9. Type ESC
> 10. Type "i"
> 11. Type "eee"
> 12. Type ESC
> 13. Type "."
> 14. Type "C-."
> 15. Type "C-." again and you end up in the "Customize" buffer.

You ran into two problems here, one that can (and should) be fixed 
relatively easily, the other is very hard to make right.

The easy one (I haven't fixed yet) is the following. pop-repeat works by 
using undo to unrepeat the repeated command and then replay the next 
command in the repeat ring. The problem arises if the first repeated 
command (the one that should be reverted and replaced by the next one) 
did not perform any change in the buffer. In this case no undo 
information is recored und the call to `evil-pop-repeat', which just 
undos the last command would undo not the repeated command (because 
this one did not do anything) but the command before that. That's the 
reason why you may end up with an empty *scratch* buffer - the 
insertion of the inserted text is actually reverted accidentally. Well, 
this should not be too difficult to fix.

The second issue is much more serious and probably impossible to do 
right. The repeat system records *any* command that is performed in a 
buffer, this includes editing command but also any other thinkable 
command. C-h v is bound to `describe-variable' which is just another 
command. Evil-commands have a special :repeat property which specifies 
if and how those commands should be recorded for repeation. Standard 
Emacs commands do not have such information. Therefore it is very 
difficult for Emacs to decide whether a certain command is an editing 
command or not. They all look the same. But editing commands *have to* 
be recorded and can't be ignored because otherwise all those little 
mode-specific editing functions, which usually are no Evil commands, 
won't be repeatable anymore (e.g., indent-region).

Therefore Evil currently has the following rules, which all abort the 
recording of repeat information for the active command:

1. commands that end up in a different buffer (e.g., switch-buffer)
2. commands that force an abort (i.e., have the property :repeat abort)
3. commands that are invoked by mouse events
4. commands in the minibuffer
5. in Emacs-state nothing is recorded

So one way to prevent certain commands from being recorded would be to 
use `evil-declare-abort-repeat' on that commands (e.g., for all 
describe-* commands, `eval-expression', 
`execute-extended-command', ...) but this would require a lot of 
functions to be marked.

Another compromise could be to record non-Evil commands only in 
insert-state (as it is done with motions) and to ignore them in 
normal-state. This would cause, e.g., `describe-variable' to be ignored 
when called from normal-state (which should be the usual case) but go 
into the repeat-info when used in insert-state. But it would also make 
other non-Evil commands to be unrepeatable when called from 
normal-state.

In any case, it will always be possible to make unusual commands invade 
the repeat-information and I see no 100% safe way to prevent this.

Frank



More information about the implementations-list mailing list