unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
From: martin rudalics <rudalics@gmx.at>
To: Chris Moore <christopher.ian.moore@gmail.com>
Cc: emacs-pretest-bug@gnu.org
Subject: Re: undo after repeatedly calling 'repeat' leaves cursor in the wrong place
Date: Thu, 04 Oct 2007 10:27:22 +0200	[thread overview]
Message-ID: <4704A3EA.3010902@gmx.at> (raw)
In-Reply-To: <a9691ee20709151432r579a186du41e8a160e2aff88a@mail.gmail.com>

[-- Attachment #1: Type: text/plain, Size: 552 bytes --]

> Type
>   "x C-x z z z z C-x u"
> (to insert an 'x', repeat the insert 4 times, then undo the last of the 4)
> 
> Before the "C-x u" there were 5 'x's with the cursor after them all.
> After the "C-x u" there are 4 'x's, as expected, but the cursor is on
> the 2nd one, whereas I would expect it to be after the 4th one.
> 
> If "C-x z" is used in full each time, instead of just hitting 'z' over
> and over, then the undo works as expected.

Could you please try the attached patch - against EMACS_22_BASE - and
tell whether it does the right thing.

[-- Attachment #2: repeat-undo.patch --]
[-- Type: text/plain, Size: 5217 bytes --]

*** undo.c	Wed Jul 25 07:15:32 2007
--- undo.c	Thu Oct  4 10:04:52 2007
***************
*** 53,60 ****
     an undo-boundary.  */
  Lisp_Object pending_boundary;
  
  /* Record point as it was at beginning of this command (if necessary)
!    And prepare the undo info for recording a change.
     PT is the position of point that will naturally occur as a result of the
     undo record that will be added just after this command terminates.  */
  
--- 53,64 ----
     an undo-boundary.  */
  Lisp_Object pending_boundary;
  
+ /* Nonzero means do not record point in record_point.  */
+ 
+ int undo_inhibit_record_point;
+ 
  /* Record point as it was at beginning of this command (if necessary)
!    and prepare the undo info for recording a change.
     PT is the position of point that will naturally occur as a result of the
     undo record that will be added just after this command terminates.  */
  
***************
*** 64,69 ****
--- 68,81 ----
  {
    int at_boundary;
  
+   /* Don't record position of pt when undo_inhibit_record_point holds.
+      This should avoid inserting a position record in buffer-undo-list
+      when last_point_position has not been set up correctly by
+      command_loop_1, for example, when running a repeat-repeat-char
+      event.  */
+   if (undo_inhibit_record_point)
+     return;
+ 	    
    /* Allocate a cons cell to be the undo boundary after this command.  */
    if (NILP (pending_boundary))
      pending_boundary = Fcons (Qnil, Qnil);
***************
*** 719,724 ****
--- 731,740 ----
  Garbage collection is inhibited around the call to this function,
  so it must make sure not to do a lot of consing.  */);
    Vundo_outer_limit_function = Qnil;
+ 
+   DEFVAR_BOOL ("undo-inhibit-record-point", &undo_inhibit_record_point,
+ 	       doc: /* Non-nil means do not record `point' in `buffer-undo-list'.  */);
+   undo_inhibit_record_point = 0;
  }
  
  /* arch-tag: d546ee01-4aed-4ffb-bb8b-eefaae50d38a

*** repeat.el	Wed Aug 29 10:36:26 2007
--- repeat.el	Thu Oct  4 10:13:58 2007
***************
*** 200,205 ****
--- 200,213 ----
  (defvar repeat-previous-repeated-command nil
    "The previous repeated command.")
  
+ ;; The following variable counts repeated self-insertions.  The idea is
+ ;; that repeating a self-insertion command and subsequently undoing it
+ ;; should have nearly the same effect as if the characters were inserted
+ ;; manually.  The basic difference is that we leave in one undo-boundary
+ ;; between the original insertion and its first repetition.
+ (defvar repeat-undo-count nil
+   "Number of self-insertions since last `undo-boundary'.")
+ 
  ;;;###autoload
  (defun repeat (repeat-arg)
    "Repeat most recently executed command.
***************
*** 293,303 ****
--- 301,323 ----
  		  (i 0))
  	      ;; Run pre- and post-command hooks for self-insertion too.
  	      (run-hooks 'pre-command-hook)
+ 	      (cond
+ 	       ((not repeat-undo-count))
+ 	       ((< repeat-undo-count 20)
+ 		;; Don't make an undo-boundary for 20 repetitions just
+ 		;; as the command loop does.
+ 		(setq repeat-undo-count (1+ repeat-undo-count)))
+ 	       (t
+ 		;; Make an undo-boundary now.
+ 		(undo-boundary)
+ 		(setq repeat-undo-count 1)))
  	      (while (< i count)
  		(repeat-self-insert insertion)
  		(setq i (1+ i)))
  	      (run-hooks 'post-command-hook)))
  	(let ((indirect (indirect-function last-repeatable-command)))
+ 	  ;; Make each repetition undo separately.
+ 	  (undo-boundary)
  	  (if (or (stringp indirect)
  		  (vectorp indirect))
  	      ;; Bind real-last-command so that executing the macro does
***************
*** 314,325 ****
        ;; (only 32 repetitions are possible given the default value of 200 for
        ;; max-lisp-eval-depth), but if I now locally disable the repeat char I
        ;; can iterate indefinitely here around a single level of recursion.
!       (let (repeat-on-final-keystroke)
  	(setq real-last-command 'repeat)
!         (while (eq (read-event) repeat-repeat-char)
! 	  ;; Make each repetition undo separately.
! 	  (undo-boundary)
!           (repeat repeat-arg))
          (setq unread-command-events (list last-input-event))))))
  
  (defun repeat-self-insert (string)
--- 334,353 ----
        ;; (only 32 repetitions are possible given the default value of 200 for
        ;; max-lisp-eval-depth), but if I now locally disable the repeat char I
        ;; can iterate indefinitely here around a single level of recursion.
!       (let (repeat-on-final-keystroke
! 	    ;; Bind `undo-inhibit-record-point' to t in order to avoid
! 	    ;; recording point in `buffer-undo-list' here.  We have to
! 	    ;; do this since the command loop does not set the last
! 	    ;; position of point thus confusing the point recording
! 	    ;; mechanism when inserting or deleting text.
! 	    (undo-inhibit-record-point t))
  	(setq real-last-command 'repeat)
! 	(setq repeat-undo-count 1)
! 	(unwind-protect
! 	    (while (eq (read-event) repeat-repeat-char)
! 	      (repeat repeat-arg))
! 	  ;; Make sure `repeat-undo-count' is reset.
! 	  (setq repeat-undo-count nil))
          (setq unread-command-events (list last-input-event))))))
  
  (defun repeat-self-insert (string)


[-- Attachment #3: Type: text/plain, Size: 142 bytes --]

_______________________________________________
Emacs-devel mailing list
Emacs-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/emacs-devel

      parent reply	other threads:[~2007-10-04  8:27 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-09-15 21:32 undo after repeatedly calling 'repeat' leaves cursor in the wrong place Chris Moore
2007-09-16 13:12 ` martin rudalics
2007-10-04  8:27 ` martin rudalics [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4704A3EA.3010902@gmx.at \
    --to=rudalics@gmx.at \
    --cc=christopher.ian.moore@gmail.com \
    --cc=emacs-pretest-bug@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).