all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Stefan Monnier <monnier@iro.umontreal.ca>
To: phillip.lord@russet.org.uk (Phillip Lord)
Cc: emacs-devel@gnu.org
Subject: Re: [Emacs-diffs] fix/no-undo-boundary-on-secondary-buffer-change f59d1be: Move undo amalgamation to lisp.
Date: Sun, 18 Oct 2015 12:51:41 -0400	[thread overview]
Message-ID: <jwv4mho2meo.fsf-monnier+emacsdiffs@gnu.org> (raw)
In-Reply-To: <87h9lqbk8m.fsf@russet.org.uk> (Phillip Lord's message of "Fri, 16 Oct 2015 22:02:01 +0100")

> So, I think I mostly have this now, although I need to do some more
> testing on it to make sure, and clearly the code needs cleaning up (all
> the debug infrastructure will need to go, and docstrings be put in
> place). I have a few questions inline, however.

See some comments on the latest code below.

> The alternative is sticking a direct call to simple.el into the command
> loop, but I would just put it immediately before post-command-hook.

The current behavior is to call it right *before* running the command,
i.e. after running post-command-hook, and even after running the next
pre-command-hook.

I recommend you keep the bikeshed of the same color.
If someone wants to change the behavior she can use an advice anyway.
And we can move it to a hook later on if we want.

> delete-char does indeed call "remove_excessive_boundaries", but for the
> life of me I can not reproduce any affect that this has at the user level.

Try C-d C-d C-d C-d C-x u.  It should undo all 4 C-d rather than only
the last one.  This is new in Emacs-25.

> If I type "abcde" into a clean buffer, then "undo" all the letters
> disappear at once (since they have amalgamated). If, though I have
> "abcde" in the buffer and do 5x delete followed by "undo" the letters
> reappear one at a time.

Have you tested with Emacs<25 by any chance?

> current_kboard? KVAR?

    KVAR (current_kboard, Vlast_command)

is the C code needed to find the value of Elisp's `last-command',
because it is a "keyboard-local" variable.

> And why the "executing_kbd_macro" check?

IIUC this is inherited from Emacs<19 and I just blindly preserved it.
I recommend you just do the same unless it causes problems.

>   current_buffer = buf;
>   set_buffer_internal(b);

This break because set_buffer_internal needs to know what was the
previous current_buffer to do its job correctly.  IOW either you use
"current_buffer = buf;" and you're super extra careful to only do
trivial things, or you do "set_buffer_internal(b);", but you don't want
to do both.


        Stefan


>  ;;; Code:
> -
>  (eval-when-compile (require 'cl-lib))

Spurious change.

> +    ;; We need to set `undo-last-boundary' to nil as we are about to
> +    ;; delete the last boundary, so we want to not assume anything about
> +    ;; the boundary before this one
> +    (setq undo-last-boundary nil)

Why is this needed?  The undo-last-boundary handling should work for
"any" command without any extra code (except for self-insert-command or
delete-char, obviously) and I don't see why undo should be different here.

I could imagine the above code as something hypothetically useful as an
optimization, but if it's really needed, I think it hints at a problem
elsewhere.  E.g. maybe uses of undo-last-boundary should always check
(eq this-command last-command), or undo-last-boundary should (just like
the old last_undo_boundary) keep a reference to the value of
buffer-undo-list, or the *command-loop* should set undo-last-boundary to
nil whenever this-command is different from last-command, ...

> +;; This section helps to prevent undo-lists from getting too large. It
> +;; achieves by checking that no buffer has an undo-list which is large
> +;; and has no `undo-boundary', a condition that will block garbage
> +;; collection of that list. This happens silently and in most cases
> +;; not at all, as generally, buffers add their own undo-boundary.
> +;;
> +;; It will still fail if a large amount of material is added or
> +;; removed from a buffer with any rapidity and no undo-boundary. In
> +;; this case, the `undo-outer-limit' machinary will operate; this is
> +;; considered to be exceptional the user is warned.

I think this comment reflects an older version of the code.

> +(defun undo-needs-boundary-p ()

I recommend you use an "undo--" prefix for most of the funs&vars you've
introduced, unless you explicitly want to encourage people to make use
of it from third-party packages.

> +  "Returns non-nil if `buffer-undo-list' needs a boundary at the start."
      ^^^^^^^
M-x checkdoc-current-buffer RET will tell you how to fix this.

> +  (and
> +   ;; `buffer-undo-list' can be t.
> +   (listp buffer-undo-list)
> +   ;; The first element of buffer-undo-list is not nil.
> +   (car buffer-undo-list)))

aka (car-safe buffer-undo-list).

> +(defun undo-last-boundary-sic-p (last-boundary)

The arg is always undo-last-boundary, so you could just drop the arg.

> +  (mapc
> +   (lambda (b)

Use dolist instead.

> +(defun undo-auto-pre-self-insert-command()
                                          ^^
                                      Missing space
> +  (condition-case err
> +      (let ((last-sic-count
> +             (undo-last-boundary-sic-p undo-last-boundary)))
> +        (when
> +            last-sic-count
> +          (if
> +              (< last-sic-count 20)
> +              (progn (undo-auto-message "(changed) Removing last undo")
> +                     (setq buffer-undo-list
> +                           (cdr buffer-undo-list)))
> +            (progn (undo-auto-message "Reset sic to 0")
> +                   (setq undo-last-boundary
> +                         '(command self-insert-command 0))))))
> +    (error
> +     (undo-auto-message "pre-command-error %s"
> +                        (error-message-string err)))))

After self-insert-command, undo-undoably-changed-buffers now tells us
all the buffers that self-insert-command modified, so if we keep this
list in undo-last-boundary, we can (better: should) here remove the
boundaries in all those buffers.

> +  // PWL remove for now
> +  //if (XFASTINT (n) < 2)
> +  //remove_excessive_undo_boundaries ();
> +  call0(Qundo_auto_pre_self_insert_command);

Better keep the (XFASTINT (n) < 2) test.

> -            if (NILP (KVAR (current_kboard, Vprefix_arg))) /* FIXME: Why?  --Stef  */
> -              {
> -		Lisp_Object undo = BVAR (current_buffer, undo_list);
> -		Fundo_boundary ();
> -		last_undo_boundary
> -		  = (EQ (undo, BVAR (current_buffer, undo_list))
> -		     ? Qnil : BVAR (current_buffer, undo_list));
> -	      }

Here's where you want to call your undo-auto-post-command-hook (which
should be renamed to describe what it does rather than when it's called).

> +  call0(Qundo_undoable_change);
         ^^
   Missing space.

> +  // PWL running with the wrong current-buffer

Please use /*...*/ comments rather than //...\n comments.  It's not
really important, but that's what we use everywhere else.

> +  Fset(Qundo_last_boundary,Qnil);
        ^^
Another missing space.

> +  DEFVAR_LISP ("undo-last-boundary",
> +               Vundo_last_boundary,
> +               doc: /* TODO
> +*/);

This belongs in the Lisp code.



  reply	other threads:[~2015-10-18 16:51 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <20151005134118.10933.50859@vcs.savannah.gnu.org>
     [not found] ` <E1Zj610-0002qx-SM@vcs.savannah.gnu.org>
2015-10-05 15:15   ` [Emacs-diffs] fix/no-undo-boundary-on-secondary-buffer-change f59d1be: Move undo amalgamation to lisp Stefan Monnier
2015-10-05 16:24     ` Phillip Lord
2015-10-07 19:28       ` Stefan Monnier
2015-10-08 19:56         ` Phillip Lord
2015-10-08 20:53           ` Stefan Monnier
2015-10-09  8:31             ` Phillip Lord
2015-10-16 21:02         ` Phillip Lord
2015-10-18 16:51           ` Stefan Monnier [this message]
2015-10-21 19:27             ` Phillip Lord
2015-10-26 17:56               ` Stefan Monnier
2015-10-27 12:45                 ` Phillip Lord
2015-10-27 14:50                   ` Stefan Monnier
2015-10-28 10:01                     ` Phillip Lord
2015-10-28 13:05                       ` Stefan Monnier
2015-10-29 14:44                         ` Phillip Lord
2015-10-29 15:47                           ` Stefan Monnier
2015-10-30  8:44                             ` Phillip Lord
2015-10-30 13:28                               ` Stefan Monnier
2015-10-30 14:21                                 ` David Kastrup
2015-11-02 16:56                                   ` Phillip Lord
2015-11-02 19:37                                     ` David Kastrup

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

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

  git send-email \
    --in-reply-to=jwv4mho2meo.fsf-monnier+emacsdiffs@gnu.org \
    --to=monnier@iro.umontreal.ca \
    --cc=emacs-devel@gnu.org \
    --cc=phillip.lord@russet.org.uk \
    /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 external index

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

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.