[Top][All Lists]

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

Re: [Emacs-diffs] fix/no-undo-boundary-on-secondary-buffer-change e5ff57

From: Phillip Lord
Subject: Re: [Emacs-diffs] fix/no-undo-boundary-on-secondary-buffer-change e5ff575 2/2: Add a timer to ensure undo-boundaries in buffers.
Date: Tue, 01 Sep 2015 18:19:49 +0100
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/24.5 (gnu/linux)

Stefan Monnier <address@hidden> writes:

>> It's possible, but it then negates the utility of the
>> `under-outer-limit' functionality.  The point is that after
>> undo-outer-limit GC ditches the undo data anyway in the absence of any
>> boundaries, but does so noisily.  But, if we run undo-ensure-boundary
>> before compaction, the boundary will mean the undo-list is always
>> GC'able with noise.
> Hmm... making under-outer-limit (virtually) useless would be good,

Yes, I think that having a bit of emacs which is there just to say to
the user "hey, this might be bug I want to tell you about". It might be
a sensible thing to leave in as a developer message (like "Garbage

> actually (and your patch also goes in that direction), but indeed doing
> it in the GC doesn't work quite the way I hoped.
> Basically, the problem with too-long undo steps is that we can't safely
> cut them into smaller pieces once they're created (it's not clear what
> is a safe cut-point).
> [ I mean "safe" in a soft sense: it's not like we risk a crash.  ]
> So pushing a boundary is safer, if we can assume that the current state
> of the undo-log corresponds to a safe cut-point.

I don't think we can assume that is "safe" but at least (while emacs is
synchronous) is will be running *between* process interactions, if I
understand correctly. I guess a process interaction happens the C
library Emacs uses for each process decides, which is probably buffered
in many cases. Safe? Don't know. Can't think of anything better though,
abstracted from knowledge of the process.

The disadvantage of this is that when it happens it makes all of the
undo-log open for GC.

> And for some reason I thought that indeed the current state
> of the undo-log during GC would usually correspond to a safe cut-point,
> but actually this is not really true.

I guess that a GC can happen at any point at all, including in the
middle of a process interaction?.

> So, yes, I now think your solution is better.
> So let's go with your approach, but we need to fix an efficiency problem
> with it: with the code you have now, we always run a timer every 10
> seconds which always loops through all buffers.
> For power-saving reasons, doing that 24/7 on a mostly-idle machine can
> be a bad idea, so we should try and make sure we don't wake up Emacs
> when there's nothing to do.
> Here's a plan:
> - change the C code so that it keeps track of a set of "buffers that
>   might need a boundary".
> - when we push an undo element, we add the corresponding buffer to that
>   set.  If the set was empty, call an Elisp function (that can start
>   the timer).

Iff I do this, I would like to keep into elisp as much as possible.
Partly because the only reason I am doing this is too little of the undo
machinary can only be modified in C. Mostly, though, because I never
actually learned C and am doing it rather blind at the moment. I'm not
adverse to learning, of course, but that Emacs is big system to learn on.

I guess adding undo-pre-extend and undo-post-extend hooks should do the
trick? Run with the relevant buffer current. The post-extend one would
let me know if the last element is NOT a boundary. Then I can add the
buffer to the list and kick off the timer unless it's already running.
Then anyone could switch this behaviour off. Then undo-outer-limit would
become the final backstop.

Two issues. simple.el does not depend on timer, so I am not clear where
to add this. And, I am aware that `buffer-undo-list' is just a list.
Anyone can change it anywhere in lisp, which would make the hooks
difficult to enforce.

> - BTW shouldn't `undo-size' be called `undo-step-size' since it should
>   only concern itself with the size of the current step.

Yes. Probably. Or, better, to have both. I had to implement undo-size
because AFAICT, it's not possible to do from lisp.

> The "set" could be represented as a list (and the timer can limit its
> scan to the given set of buffers), or as a boolean.
> BTW, we could also use the same "set" to change the "post command push
> undo boundary" so it pushes boundaries on all modified buffers (so we
> can through away the "push boundary upon buffer change" which causes
> problems for your code).

Just to clarify, you are suggesting a post-command add undo-boundary,
rather than post-change (i.e. potentially many times per command)? I
would need to think on this.


reply via email to

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