unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* undo in loaddefs.el buffer
@ 2004-12-21 14:14 Luc Teirlinck
  2004-12-21 15:41 ` Luc Teirlinck
                   ` (2 more replies)
  0 siblings, 3 replies; 60+ messages in thread
From: Luc Teirlinck @ 2004-12-21 14:14 UTC (permalink / raw)


During `make bootstrap' (CVS from minutes ago) I got asked:

Buffer loaddefs.el undo info is 301051 bytes long; discard it? (yes or no)

Is there any reason for that buffer record undo history in the first place?

Sincerely,

Luc.

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: undo in loaddefs.el buffer
  2004-12-21 14:14 undo in loaddefs.el buffer Luc Teirlinck
@ 2004-12-21 15:41 ` Luc Teirlinck
  2004-12-22  4:31   ` Katsumi Yamaoka
  2004-12-21 21:57 ` Kevin Rodgers
  2004-12-22  0:17 ` Richard Stallman
  2 siblings, 1 reply; 60+ messages in thread
From: Luc Teirlinck @ 2004-12-21 15:41 UTC (permalink / raw)
  Cc: emacs-devel

>From my previous message:

   During `make bootstrap' (CVS from minutes ago) I got asked:

   Buffer loaddefs.el undo info is 301051 bytes long; discard it? (yes or no)

   Is there any reason for that buffer record undo history in the first place?

What about the following trivial patch to emacs-lisp/autoload.el,
which fixes the problem?  Or is there some strange reason why enabling
undo is _really_ necessary in that buffer?  It is hard to think of
any, since this seems to be just an internally used buffer.

===File ~/autoload.el-diff==================================
*** autoload.el	02 Nov 2004 08:26:32 -0600	1.102
--- autoload.el	21 Dec 2004 09:18:01 -0600	
***************
*** 388,393 ****
--- 388,394 ----
  		      (expand-file-name generated-autoload-file
  					(expand-file-name "lisp"
  							  source-directory)))))
+ 	(buffer-disable-undo)
  	;; This is to make generated-autoload-file have Unix EOLs, so
  	;; that it is portable to all platforms.
  	(setq buffer-file-coding-system 'raw-text-unix))
============================================================

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: undo in loaddefs.el buffer
  2004-12-21 14:14 undo in loaddefs.el buffer Luc Teirlinck
  2004-12-21 15:41 ` Luc Teirlinck
@ 2004-12-21 21:57 ` Kevin Rodgers
  2004-12-22  0:17   ` Luc Teirlinck
  2004-12-22  0:17 ` Richard Stallman
  2 siblings, 1 reply; 60+ messages in thread
From: Kevin Rodgers @ 2004-12-21 21:57 UTC (permalink / raw)


Luc Teirlinck wrote:
> During `make bootstrap' (CVS from minutes ago) I got asked:
> 
> Buffer loaddefs.el undo info is 301051 bytes long; discard it? (yes or no)
> 
> Is there any reason for that buffer record undo history in the first place?

Is there any reason for emacs, when invoked non-interactively as by
`make bootstrap`, to query the user?

-- 
Kevin Rodgers

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: undo in loaddefs.el buffer
  2004-12-21 14:14 undo in loaddefs.el buffer Luc Teirlinck
  2004-12-21 15:41 ` Luc Teirlinck
  2004-12-21 21:57 ` Kevin Rodgers
@ 2004-12-22  0:17 ` Richard Stallman
  2 siblings, 0 replies; 60+ messages in thread
From: Richard Stallman @ 2004-12-22  0:17 UTC (permalink / raw)
  Cc: emacs-devel

    During `make bootstrap' (CVS from minutes ago) I got asked:

    Buffer loaddefs.el undo info is 301051 bytes long; discard it? (yes or no)

    Is there any reason for that buffer record undo history in the first place?

I don't know.  What operation does this occur in?

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: undo in loaddefs.el buffer
  2004-12-21 21:57 ` Kevin Rodgers
@ 2004-12-22  0:17   ` Luc Teirlinck
  0 siblings, 0 replies; 60+ messages in thread
From: Luc Teirlinck @ 2004-12-22  0:17 UTC (permalink / raw)
  Cc: emacs-devel

Kevin Rodgers wrote:

   Is there any reason for emacs, when invoked non-interactively as by
   `make bootstrap`, to query the user?

The new function `undo-outer-limit-truncate' does that.

There definitely are situations where it might be appropriate to query
the user when running in batch mode.  That is why `(elisp)Batch Mode'
says:

    Similarly, input that would normally come from the minibuffer is read
    from the standard input descriptor.

That should however probably not happen during bootstrapping.

I believe that the trivial mini-patch I sent earlier makes sense
regardless of any problems with bootstrapping.  Maybe there are
actually two unrelated bugs (or misfeatures) here.

It seems that enabling undo does not make much sense when invoked
non-interactively.  But the question is what undo-outer-limit-truncate
should do if the person running `emacs --batch' (maybe accidentally)
enabled it anyway.

Maybe the following patch to simple.el makes sense in addition to the
one for autoload.el.  (It sets buffer-undo-list to nil without
querying in the given situation.)  The two compiler defvars seem needed
regardless.  I just point them out because the compiler complained
about them while compiling the other change.
				   
===File ~/simple.el-diff====================================
*** simple.el	21 Dec 2004 07:49:59 -0600	1.673
--- simple.el	21 Dec 2004 16:30:23 -0600	
***************
*** 270,275 ****
--- 270,276 ----
  
  ;;; Internal variable for `next-error-follow-mode-post-command-hook'.
  (defvar next-error-follow-last-line nil)
+ (defvar compilation-current-error)
  
  (define-minor-mode next-error-follow-minor-mode
    "Minor mode for compilation, occur and diff modes.
***************
*** 874,879 ****
--- 875,882 ----
    :type 'boolean
    :version "21.1")
  
+ (defvar edebug-active)
+ 
  (defun eval-expression-print-format (value)
    "Format VALUE as a result of evaluated expression.
  Return a formatted string which is displayed in the echo area
***************
*** 1491,1500 ****
  ;; so it had better not do a lot of consing.
  (setq undo-outer-limit-function 'undo-outer-limit-truncate)
  (defun undo-outer-limit-truncate (size)
!   (if (yes-or-no-p (format "Buffer %s undo info is %d bytes long; discard it? "
! 			   (buffer-name) size))
!       (progn (setq buffer-undo-list nil) t)
!     nil))
  \f
  (defvar shell-command-history nil
    "History list for some commands that read shell commands.")
--- 1494,1505 ----
  ;; so it had better not do a lot of consing.
  (setq undo-outer-limit-function 'undo-outer-limit-truncate)
  (defun undo-outer-limit-truncate (size)
!   (if (or noninteractive
! 	  (yes-or-no-p
! 	   (format "Buffer %s undo info is %d bytes long; discard it? "
! 		   (buffer-name) size))
! 	  (progn (setq buffer-undo-list nil) t))
!       nil))
  \f
  (defvar shell-command-history nil
    "History list for some commands that read shell commands.")
============================================================

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: undo in loaddefs.el buffer
  2004-12-21 15:41 ` Luc Teirlinck
@ 2004-12-22  4:31   ` Katsumi Yamaoka
  2004-12-22  4:58     ` Katsumi Yamaoka
                       ` (3 more replies)
  0 siblings, 4 replies; 60+ messages in thread
From: Katsumi Yamaoka @ 2004-12-22  4:31 UTC (permalink / raw)
  Cc: emacs-devel

>>>>> In <200412211541.iBLFfBc03861@raven.dms.auburn.edu> Luc Teirlinck wrote:

> What about the following trivial patch to emacs-lisp/autoload.el,
> which fixes the problem?  Or is there some strange reason why enabling
> undo is _really_ necessary in that buffer?  It is hard to think of
> any, since this seems to be just an internally used buffer.

> ===File ~/autoload.el-diff==================================
> *** autoload.el	02 Nov 2004 08:26:32 -0600	1.102
> --- autoload.el	21 Dec 2004 09:18:01 -0600	
> ***************
> *** 388,393 ****
> --- 388,394 ----
>   		      (expand-file-name generated-autoload-file
>   					(expand-file-name "lisp"
>   							  source-directory)))))
> + 	(buffer-disable-undo)
>   	;; This is to make generated-autoload-file have Unix EOLs, so
>   	;; that it is portable to all platforms.
>   	(setq buffer-file-coding-system 'raw-text-unix))
> ============================================================

It needs to be inserted here and there!  For instance,
texinfo-format-buffer stops when formatting large texi files.
What a user can do without modifying texinfmt.el is only to bind
`undo-outer-limit' to a large value.  Actually, I needed to bind
it to (eval '(lsh -1 -1))' in order to make some info files.
You will receive many complaints in the near future.  Sigh.

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: undo in loaddefs.el buffer
  2004-12-22  4:31   ` Katsumi Yamaoka
@ 2004-12-22  4:58     ` Katsumi Yamaoka
  2004-12-23  0:01     ` Richard Stallman
                       ` (2 subsequent siblings)
  3 siblings, 0 replies; 60+ messages in thread
From: Katsumi Yamaoka @ 2004-12-22  4:58 UTC (permalink / raw)
  Cc: emacs-devel

>>>>> In <b9yy8freyxs.fsf@jpl.org> Katsumi Yamaoka wrote:

>>>>>> In <200412211541.iBLFfBc03861@raven.dms.auburn.edu> Luc Teirlinck wrote:

>> + 	(buffer-disable-undo)

> It needs to be inserted here and there!  For instance,

[...]

> You will receive many complaints in the near future.  Sigh.

Oops.  I must apologize for my misapprehension.  That was made
not by *you*.

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: undo in loaddefs.el buffer
  2004-12-22  4:31   ` Katsumi Yamaoka
  2004-12-22  4:58     ` Katsumi Yamaoka
@ 2004-12-23  0:01     ` Richard Stallman
  2004-12-23  0:26       ` David Kastrup
  2004-12-24  1:45     ` Juri Linkov
  2005-01-04  9:05     ` Juri Linkov
  3 siblings, 1 reply; 60+ messages in thread
From: Richard Stallman @ 2004-12-23  0:01 UTC (permalink / raw)
  Cc: teirllm, emacs-devel

I think batch mode should do something different to undo-outer-limit.

1. I'll set it up so that nil means "no limit".

2. Perhaps batch mode should set it to nil, normally.

3. Another idea is that batch mode could silently discard undo info
when it reaches undo-outer-limit.  That is what it was doing until
a few days ago

But that doesn't seem entirely right.  I think the right thing to do
is to find the functions that shouldn't really maintain undo info, and
fix them not to do so, regardless of whether they are in batch mode.

For instance, I think texinfo-format-buffer should disable undo
unconditionally for the output Info file.

update-file-autoloads is a special case, because it edits the file
loaddefs.el as a visited file, and it is plausible you might edit it
by hand.  You might also want to undo the effect of one call to
update-file-autoloads.  So it shouldn't just turn off undo.

So I think batch-update-autoloads is the right place to do something
about this problem.

4. Another idea is that batch mode could always turn off undo.  That
is a little drastic as a change, but what do people think of it?

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: undo in loaddefs.el buffer
  2004-12-23  0:01     ` Richard Stallman
@ 2004-12-23  0:26       ` David Kastrup
  2004-12-25 15:13         ` Richard Stallman
  0 siblings, 1 reply; 60+ messages in thread
From: David Kastrup @ 2004-12-23  0:26 UTC (permalink / raw)
  Cc: Katsumi Yamaoka, teirllm, emacs-devel

Richard Stallman <rms@gnu.org> writes:

> So I think batch-update-autoloads is the right place to do something
> about this problem.
>
> 4. Another idea is that batch mode could always turn off undo.  That
> is a little drastic as a change, but what do people think of it?

It depends just on how undo gets turned off.  There are cases where
editing operations are done by making use of undo (X-Symbol does some
sort of association by doing a one-way conversion, placing markers at
positions matched with a string, then undoing everything to see where
the markers end up).  However, those operations will set relevant
variables (in this case, setting undo-limit to most-positive-fixnum,
for example) normally.  undo-outer-limit, however, is new...

-- 
David Kastrup, Kriemhildstr. 15, 44793 Bochum

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: undo in loaddefs.el buffer
  2004-12-22  4:31   ` Katsumi Yamaoka
  2004-12-22  4:58     ` Katsumi Yamaoka
  2004-12-23  0:01     ` Richard Stallman
@ 2004-12-24  1:45     ` Juri Linkov
  2004-12-24 21:39       ` Luc Teirlinck
                         ` (2 more replies)
  2005-01-04  9:05     ` Juri Linkov
  3 siblings, 3 replies; 60+ messages in thread
From: Juri Linkov @ 2004-12-24  1:45 UTC (permalink / raw)
  Cc: teirllm, emacs-devel

Katsumi Yamaoka <yamaoka@jpl.org> writes:
> You will receive many complaints in the near future.  Sigh.

Right.  The same question is asked in auto-compression-mode during
visiting large gzipped files.

And what is unusual for such yes-no prompts is that it can't be
interrupted with C-g.  Typing C-g pops up an unwanted X popup menu.

It's better to ask such question outside GC-protected code.

Even better not to ask anything, but to display a message saying that
to prevent discarding the undo info the user should change the value
of undo-outer-limit.

-- 
Juri Linkov
http://www.jurta.org/emacs/

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: undo in loaddefs.el buffer
  2004-12-24  1:45     ` Juri Linkov
@ 2004-12-24 21:39       ` Luc Teirlinck
  2004-12-26  9:14         ` Richard Stallman
  2004-12-24 23:59       ` Luc Teirlinck
  2004-12-25 15:12       ` Richard Stallman
  2 siblings, 1 reply; 60+ messages in thread
From: Luc Teirlinck @ 2004-12-24 21:39 UTC (permalink / raw)
  Cc: yamaoka, Joakim Verona, emacs-devel

Joakim Verona wrote:

   When I work with tramp, for instance /su:root@localhost:/etc/hosts
   tramp asks me about "undo" information on each save, for the buffer
   *tram su root localhost* buffer.

   emacs asks me if I want to discard a number of bytes of undo
   information. This is very inconvenient.

This is caused by a recent change in undo, but I guess that it could
also be considered a bug in Tramp.

Juri Linkov wrote:

   Katsumi Yamaoka <yamaoka@jpl.org> writes:
   > You will receive many complaints in the near future.  Sigh.

   Right.  The same question is asked in auto-compression-mode during
   visiting large gzipped files.

I guess this could be considered a bug in auto-compression mode.

Moreover, in addition to those two and texinfo-format-buffer and
loaddefs.el, there is a problem when you autorevert the Buffer Menu.
At regular intervals, you get asked the "undo" question, even when the
Buffer Menu is very tiny (like three buffers).

   Even better not to ask anything, but to display a message saying that
   to prevent discarding the undo info the user should change the value
   of undo-outer-limit.

Or file a bug report.

There are several problems with the way various functions and packages
quite simply ignore undo completely and hence rely on the default
behavior of "undo", while it is completely inappropriate for them.

The current way to expose these various problems (by making them a lot
worse and hence more evident) indeed results in quite a bit of
inconvenience.

The problems with undo seem to be spread all over Emacs, but the
correct solution seems to vary and is not always obvious.  There are
programs that:

1.  Fail to disable undo in a buffer where undo is meaningless.

2.  Fail to discard old undo info that is no longer meaningful.

3.  Fail to put in undo boundaries, thus accumulating one huge single
    undo entry, eventually triggering the undo-outer-limit question.

Situation 3 seems to happen rather easily with timers.

>From (elisp)Undo:

     The editor command loop automatically creates an undo boundary
     before each key sequence is executed.

and:

     All buffer modifications add a boundary whenever the previous
     undoable change was made in some other buffer.

But it appears that a function called at regular intervals from a
timer and modifying a single buffer just accumulates one undo entry
that keeps growing until the limit is reached and the question is
asked.

Although the problem with the buffer menu appears to be caused by (3)
I believe that the reasons for discarding undo info when reverting a
file, also apply to reverting the Buffer Menu.  So the patch below,
discards all undo info when reverting the Buffer Menu.  Should the
same also apply to reverting Dired (which does not discard undo info
either)?

There are other ways to solve the "reverting the Buffer Menu" problem
than the one below and, moreover it is _not_ a general solution for
what _appears_ to be a general problem with timers.  I believe that
the patch below makes sense regardless.  I can install if desired.

===File ~/buff-menu.el-diff=================================
*** buff-menu.el	14 Dec 2004 07:57:14 -0600	1.78
--- buff-menu.el	23 Dec 2004 20:07:41 -0600	
***************
*** 207,213 ****
      (while (setq prop (next-single-property-change prop 'buffer))
        (when (eq (get-text-property prop 'buffer) oline)
  	(goto-char prop)
! 	(move-to-column ocol)))))
  
  (defun Buffer-menu-toggle-files-only (arg)
    "Toggle whether the current buffer-menu displays only file buffers.
--- 207,215 ----
      (while (setq prop (next-single-property-change prop 'buffer))
        (when (eq (get-text-property prop 'buffer) oline)
  	(goto-char prop)
! 	(move-to-column ocol))))
!   (or (eq buffer-undo-list t)
!       (setq buffer-undo-list nil)))
  
  (defun Buffer-menu-toggle-files-only (arg)
    "Toggle whether the current buffer-menu displays only file buffers.
============================================================

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: undo in loaddefs.el buffer
  2004-12-24  1:45     ` Juri Linkov
  2004-12-24 21:39       ` Luc Teirlinck
@ 2004-12-24 23:59       ` Luc Teirlinck
  2004-12-25 15:12       ` Richard Stallman
  2 siblings, 0 replies; 60+ messages in thread
From: Luc Teirlinck @ 2004-12-24 23:59 UTC (permalink / raw)
  Cc: yamaoka, emacs-devel

>From my previous message:

   This is caused by a recent change in undo, but I guess that it could
   also be considered a bug in Tramp.

and:

   I guess this could be considered a bug in auto-compression mode.

In both cases I should have said: _maybe_ could be considered bugs.

I did not look at these two cases.  I only looked at the Buffer Menu
and timer problems.

Sincerely,

Luc.

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: undo in loaddefs.el buffer
  2004-12-24  1:45     ` Juri Linkov
  2004-12-24 21:39       ` Luc Teirlinck
  2004-12-24 23:59       ` Luc Teirlinck
@ 2004-12-25 15:12       ` Richard Stallman
  2004-12-26  2:06         ` Luc Teirlinck
  2004-12-26  2:43         ` Juri Linkov
  2 siblings, 2 replies; 60+ messages in thread
From: Richard Stallman @ 2004-12-25 15:12 UTC (permalink / raw)
  Cc: yamaoka, teirllm, emacs-devel

    Right.  The same question is asked in auto-compression-mode during
    visiting large gzipped files.

I'm sure that can be fixed, if you tell me precisely where in the
code it occurs.  Would you please try making C and Lisp level backtraces
while Emacs is asking the question?

    And what is unusual for such yes-no prompts is that it can't be
    interrupted with C-g.  Typing C-g pops up an unwanted X popup menu.

C-g normally should quit out of this question.  Why not in this case?
This too may be fixable, but only with more precise information.

    Even better not to ask anything, but to display a message saying that
    to prevent discarding the undo info the user should change the value
    of undo-outer-limit.

That would not be an improvement.  That way, you could do a command
and be surprised that you can't undo it.

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: undo in loaddefs.el buffer
  2004-12-23  0:26       ` David Kastrup
@ 2004-12-25 15:13         ` Richard Stallman
  0 siblings, 0 replies; 60+ messages in thread
From: Richard Stallman @ 2004-12-25 15:13 UTC (permalink / raw)
  Cc: yamaoka, teirllm, emacs-devel

    > 4. Another idea is that batch mode could always turn off undo.  That
    > is a little drastic as a change, but what do people think of it?

    It depends just on how undo gets turned off.

The most obvious way is to make buffer-undo-list default to t in new
buffers, in batch mode.

						  There are cases where
    editing operations are done by making use of undo (X-Symbol does some
    sort of association by doing a one-way conversion, placing markers at
    positions matched with a string, then undoing everything to see where
    the markers end up).

In order for such packages to work in buffers in which the user has
turned off undo, they have to be able to turn undo on temporarily
in a way that the user won't notice.  Does x-symbol do that?

Once they do this properly, they won't have any trouble if batch
mode turns off undo in all buffers by default.

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: undo in loaddefs.el buffer
  2004-12-25 15:12       ` Richard Stallman
@ 2004-12-26  2:06         ` Luc Teirlinck
  2004-12-26  2:32           ` Juri Linkov
                             ` (2 more replies)
  2004-12-26  2:43         ` Juri Linkov
  1 sibling, 3 replies; 60+ messages in thread
From: Luc Teirlinck @ 2004-12-26  2:06 UTC (permalink / raw)
  Cc: juri, yamaoka, emacs-devel

Richard Stallman wrote (in response to Juri Linkov):

       And what is unusual for such yes-no prompts is that it can't be
       interrupted with C-g.  Typing C-g pops up an unwanted X popup menu.

   C-g normally should quit out of this question.  Why not in this case?
   This too may be fixable, but only with more precise information.

This might be toolkit dependent.  (At least for popup menus).  If the
answer gets asked in the minibuffer, quitting works normally (at least
for me).

Obvious question to Juri:  Which toolkit do you use?

Everything below concerns the behavior with the default Lucid toolkit.

Strange things happen with popup menus, at least using the default
Lucid toolkit.

Do `emacs -q', M-x ielm then:

(let (last-nonmenu-event) (yes-or-no-p "prompt"))

Now if you press any key, regular or modifier, say "a", Control,
Shift, nil is returned, like if you answered "No".  This appears to be
an obvious bug.  For the particular application we are worried about,
this is particularly bad, because "No" is the dangerous answer, the
one that might make Emacs crash.

If we repeat the experiment in 21.3, we see that the bug is not
present there.  However, there is another bug.  If we click the mouse
anywhere inside the Emacs frame, but outside the "Yes" button, nil is
returned.  This is also a bug, which does _not_ occur in current CVS.
This seems to be a case of introducing one bug by fixing another.

Sincerely,

Luc.

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: undo in loaddefs.el buffer
  2004-12-26  2:06         ` Luc Teirlinck
@ 2004-12-26  2:32           ` Juri Linkov
  2004-12-26  3:59             ` Luc Teirlinck
                               ` (2 more replies)
  2004-12-26 16:15           ` Jan D.
  2004-12-27  4:09           ` Richard Stallman
  2 siblings, 3 replies; 60+ messages in thread
From: Juri Linkov @ 2004-12-26  2:32 UTC (permalink / raw)
  Cc: yamaoka, rms, emacs-devel

Luc Teirlinck <teirllm@dms.auburn.edu> writes:
> Richard Stallman wrote (in response to Juri Linkov):
>    C-g normally should quit out of this question.  Why not in this case?
>    This too may be fixable, but only with more precise information.
>
> This might be toolkit dependent.  (At least for popup menus).  If the
> answer gets asked in the minibuffer, quitting works normally (at least
> for me).
>
> Obvious question to Juri:  Which toolkit do you use?

None.  At least, configure says so:

  What window system should Emacs use?                    x11
  What toolkit should Emacs use?                          none

It seems in this case Emacs uses code from oldXMenu.

I don't use popup menus, so this behavior was really unexpected for me, 
and especially annoying was that a X popup menu displayed from undo question
crashed Emacs (before Jan fixed those crashes).

> Everything below concerns the behavior with the default Lucid toolkit.
>
> Strange things happen with popup menus, at least using the default
> Lucid toolkit.
>
> Do `emacs -q', M-x ielm then:
>
> (let (last-nonmenu-event) (yes-or-no-p "prompt"))

This code displays a X popup menu when no toolkit is used.
And it doesn't react to key presses.

> If we repeat the experiment in 21.3, we see that the bug is not
> present there.  However, there is another bug.  If we click the mouse
> anywhere inside the Emacs frame, but outside the "Yes" button, nil is
> returned.  This is also a bug, which does _not_ occur in current CVS.
> This seems to be a case of introducing one bug by fixing another.

nil is returned in current CVS with no toolkit.

-- 
Juri Linkov
http://www.jurta.org/emacs/

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: undo in loaddefs.el buffer
  2004-12-25 15:12       ` Richard Stallman
  2004-12-26  2:06         ` Luc Teirlinck
@ 2004-12-26  2:43         ` Juri Linkov
  2004-12-27  4:09           ` Richard Stallman
  1 sibling, 1 reply; 60+ messages in thread
From: Juri Linkov @ 2004-12-26  2:43 UTC (permalink / raw)
  Cc: yamaoka, teirllm, emacs-devel

Richard Stallman <rms@gnu.org> writes:
>     Right.  The same question is asked in auto-compression-mode during
>     visiting large gzipped files.
>
> I'm sure that can be fixed, if you tell me precisely where in the
> code it occurs.  Would you please try making C and Lisp level backtraces
> while Emacs is asking the question?

The question is asked after `decode-coding-region' is called from
`decode-coding-inserted-region' from `jka-compr-insert-file-contents'.
Perhaps undo should be disabled temporarily in `jka-compr-insert-file-contents'
during visiting a gzipped file, but not permanently because buffers of
gzipped files are editable.

(gdb) xbt
"yes-or-no-p"
"undo-outer-limit-truncate"
"decode-coding-inserted-region"
"jka-compr-insert-file-contents"
"apply"
"jka-compr-handler"
"insert-file-contents"
"byte-code"
"find-file-noselect-1"
"find-file-noselect"
"find-file"
"dired-advertised-find-file"
"call-interactively"
(gdb) bt
#0  0x402acd82 in select () from /lib/libc.so.6
#1  0xbffe969c in ?? ()
#2  0x00000000 in ?? ()
#3  0xbffe971c in ?? ()
#4  0x081576d7 in wait_reading_process_output (time_limit=30, microsecs=0, read_kbd=-1, do_display=1, wait_for_cell=137212809, wait_proc=0x0, just_wait_proc=0)
    at process.c:4349
#5  0x08055dcb in sit_for (sec=30, usec=0, reading=1, display=1, initial_display=0) at dispnew.c:6367
#6  0x080d5471 in read_char (commandflag=1, nmaps=2, maps=0xbffe9984, prev_event=137212809, used_mouse_menu=0xbffe99c8) at keyboard.c:2762
#7  0x080dbddf in read_key_sequence (keybuf=0xbffe9ad4, bufsize=30, prompt=137212809, dont_downcase_last=0, can_return_switch_frame=1, fix_current_buffer=1)
    at keyboard.c:8818
#8  0x080d3420 in command_loop_1 () at keyboard.c:1531
#9  0x0812a791 in internal_condition_case (bfun=0x80d3114 <command_loop_1>, handlers=137276241, hfun=0x80d2cd0 <cmd_error>) at eval.c:1385
#10 0x080d2f98 in command_loop_2 () at keyboard.c:1312
#11 0x0812a301 in internal_catch (tag=137309129, func=0x80d2f74 <command_loop_2>, arg=137212809) at eval.c:1144
#12 0x080d2efd in command_loop () at keyboard.c:1279
#13 0x080d2a78 in recursive_edit_1 () at keyboard.c:984
#14 0x080f41c9 in read_minibuf (map=137241853, initial=137212809, prompt=141424499, backup_n=137212809, expflag=0, histvar=137312433, histpos=0, defalt=137212809, 
    allow_props=0, inherit_input_method=0, keep_all=0) at minibuf.c:700
#15 0x080f482f in Fread_from_minibuffer (prompt=141424499, initial_contents=137212809, keymap=137241853, read=137212809, hist=137312433, default_value=137212809, 
    inherit_input_method=137212809, keep_all=137212809) at minibuf.c:987
#16 0x0813504a in Fyes_or_no_p (prompt=141424643) at fns.c:3307
#17 0x0812c10a in Ffuncall (nargs=2, args=0xbffe9f40) at eval.c:2775
#18 0x0815137c in Fbyte_code (bytestr=136300339, vector=136300372, maxdepth=40) at bytecode.c:686
#19 0x0812c622 in funcall_lambda (fun=136300308, nargs=1, arg_vector=0xbffea074) at eval.c:2962
#20 0x0812c1f1 in Ffuncall (nargs=2, args=0xbffea070) at eval.c:2832
#21 0x0812be47 in call1 (fn=138133401, arg1=9737776) at eval.c:2569
#22 0x08115269 in truncate_undo_list (b=0x852c1c0) at undo.c:379
#23 0x08118a6b in Fgarbage_collect () at alloc.c:4687
#24 0x08151405 in Fbyte_code (bytestr=135998931, vector=135999036, maxdepth=64) at bytecode.c:721
#25 0x0812c622 in funcall_lambda (fun=135998836, nargs=7, arg_vector=0xbffea264) at eval.c:2962
#26 0x0812c1f1 in Ffuncall (nargs=8, args=0xbffea260) at eval.c:2832
#27 0x0815137c in Fbyte_code (bytestr=141297035, vector=141299116, maxdepth=80) at bytecode.c:686
#28 0x0812c622 in funcall_lambda (fun=141299548, nargs=5, arg_vector=0xbffea384) at eval.c:2962
#29 0x0812c1f1 in Ffuncall (nargs=6, args=0xbffea380) at eval.c:2832
#30 0x0812bb18 in Fapply (nargs=2, args=0xbffea444) at eval.c:2280
#31 0x0812c081 in Ffuncall (nargs=3, args=0xbffea440) at eval.c:2756
#32 0x0815137c in Fbyte_code (bytestr=141297579, vector=141325948, maxdepth=32) at bytecode.c:686
#33 0x0812c622 in funcall_lambda (fun=141326228, nargs=6, arg_vector=0xbffea564) at eval.c:2962
#34 0x0812c1f1 in Ffuncall (nargs=7, args=0xbffea560) at eval.c:2832
#35 0x0812bee7 in call6 (fn=137405761, arg1=137361433, arg2=141358851, arg3=137212857, arg4=137212809, arg5=137212809, arg6=137212809) at eval.c:2689
#36 0x080fa6c7 in Finsert_file_contents (filename=141358851, visit=137212857, beg=137212809, end=137212809, replace=137212809) at fileio.c:3724
#37 0x0812c181 in Ffuncall (nargs=3, args=0xbfffec90) at eval.c:2808
#38 0x0815137c in Fbyte_code (bytestr=136065115, vector=136065156, maxdepth=24) at bytecode.c:686
#39 0x0812b7a4 in Feval (form=136065101) at eval.c:2136
#40 0x0812a6a2 in Fcondition_case (args=139313413) at eval.c:1332
#41 0x0815180a in Fbyte_code (bytestr=136064435, vector=136064636, maxdepth=32) at bytecode.c:864
#42 0x0812c622 in funcall_lambda (fun=136064364, nargs=6, arg_vector=0xbfffefd4) at eval.c:2962
#43 0x0812c1f1 in Ffuncall (nargs=7, args=0xbfffefd0) at eval.c:2832
#44 0x0815137c in Fbyte_code (bytestr=136061859, vector=136062532, maxdepth=64) at bytecode.c:686
#45 0x0812c622 in funcall_lambda (fun=136061788, nargs=4, arg_vector=0xbffff0e4) at eval.c:2962
#46 0x0812c1f1 in Ffuncall (nargs=5, args=0xbffff0e0) at eval.c:2832
#47 0x0815137c in Fbyte_code (bytestr=136054931, vector=136054980, maxdepth=48) at bytecode.c:686
#48 0x0812c622 in funcall_lambda (fun=136054876, nargs=1, arg_vector=0xbffff1f4) at eval.c:2962
#49 0x0812c1f1 in Ffuncall (nargs=2, args=0xbffff1f0) at eval.c:2832
#50 0x0815137c in Fbyte_code (bytestr=141413515, vector=141417732, maxdepth=16) at bytecode.c:686
#51 0x0812c622 in funcall_lambda (fun=141417996, nargs=0, arg_vector=0xbffff314) at eval.c:2962
#52 0x0812c1f1 in Ffuncall (nargs=1, args=0xbffff310) at eval.c:2832
#53 0x0812be0e in apply1 (fn=141372657, arg=137212809) at eval.c:2525
#54 0x08127d58 in Fcall_interactively (function=141372657, record_flag=137212809, keys=137271804) at callint.c:411
#55 0x080dd336 in Fcommand_execute (cmd=141372657, record_flag=137212809, keys=137212809, special=137212809) at keyboard.c:9712
#56 0x080d3e2f in command_loop_1 () at keyboard.c:1785
#57 0x0812a791 in internal_condition_case (bfun=0x80d3114 <command_loop_1>, handlers=137276241, hfun=0x80d2cd0 <cmd_error>) at eval.c:1385
#58 0x080d2f98 in command_loop_2 () at keyboard.c:1312
#59 0x0812a301 in internal_catch (tag=137269457, func=0x80d2f74 <command_loop_2>, arg=137212809) at eval.c:1144
#60 0x080d2f47 in command_loop () at keyboard.c:1291
#61 0x080d2a78 in recursive_edit_1 () at keyboard.c:984
#62 0x080d2bb0 in Frecursive_edit () at keyboard.c:1045
#63 0x080d1972 in main (argc=2, argv=0xbffffaa4) at emacs.c:1763

-- 
Juri Linkov
http://www.jurta.org/emacs/

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: undo in loaddefs.el buffer
  2004-12-26  2:32           ` Juri Linkov
@ 2004-12-26  3:59             ` Luc Teirlinck
  2004-12-27  2:40             ` Luc Teirlinck
  2004-12-27  4:09             ` Richard Stallman
  2 siblings, 0 replies; 60+ messages in thread
From: Luc Teirlinck @ 2004-12-26  3:59 UTC (permalink / raw)
  Cc: yamaoka, rms, emacs-devel

Juri Linkov wrote:

   > Obvious question to Juri:  Which toolkit do you use?

   None.  At least, configure says so:

     What window system should Emacs use?                    x11
     What toolkit should Emacs use?                          none


I have (from configure output):

checking X11 version 5 with Xaw... 5 or newer, with Xaw; use toolkit
by default
checking X11 toolkit version... 6 or newer

and:

  What window system should Emacs use?                    x11
  What toolkit should Emacs use?                          LUCID

I guess that explains the difference in behavior.  The behavior I see
seems to be definitely a bug.

Sincerely,

Luc.

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: undo in loaddefs.el buffer
  2004-12-24 21:39       ` Luc Teirlinck
@ 2004-12-26  9:14         ` Richard Stallman
  2004-12-27  5:29           ` Luc Teirlinck
  0 siblings, 1 reply; 60+ messages in thread
From: Richard Stallman @ 2004-12-26  9:14 UTC (permalink / raw)
  Cc: juri, yamaoka, joakim, emacs-devel

    Moreover, in addition to those two and texinfo-format-buffer and
    loaddefs.el, there is a problem when you autorevert the Buffer Menu.
    At regular intervals, you get asked the "undo" question, even when the
    Buffer Menu is very tiny (like three buffers).

That suggests something is making too much undo info.  It would be
good to debug why it makes so much undo info.  Forcing Emacs into the
debugger when it is asking the question would be a way to do that.  Or
stopping Emacs with GDB.

    3.  Fail to put in undo boundaries, thus accumulating one huge single
	undo entry, eventually triggering the undo-outer-limit question.

    Situation 3 seems to happen rather easily with timers.

Maybe that means Emacs should put in undo boundaries at the
beginning and end of a timer.

    Although the problem with the buffer menu appears to be caused by (3)
    I believe that the reasons for discarding undo info when reverting a
    file, also apply to reverting the Buffer Menu.  So the patch below,
    discards all undo info when reverting the Buffer Menu.

I think that is right, and likewise for Dired.  Reverting
should clear out the undo info, since it is supposed to give
a clean slate.

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: undo in loaddefs.el buffer
  2004-12-26  2:06         ` Luc Teirlinck
  2004-12-26  2:32           ` Juri Linkov
@ 2004-12-26 16:15           ` Jan D.
  2004-12-27  2:31             ` Luc Teirlinck
  2004-12-27 18:05             ` Richard Stallman
  2004-12-27  4:09           ` Richard Stallman
  2 siblings, 2 replies; 60+ messages in thread
From: Jan D. @ 2004-12-26 16:15 UTC (permalink / raw)
  Cc: juri, yamaoka, rms, emacs-devel

Luc Teirlinck wrote:

>Do `emacs -q', M-x ielm then:
>
>(let (last-nonmenu-event) (yes-or-no-p "prompt"))
>
>Now if you press any key, regular or modifier, say "a", Control,
>Shift, nil is returned, like if you answered "No".  This appears to be
>an obvious bug.  For the particular application we are worried about,
>this is particularly bad, because "No" is the dangerous answer, the
>one that might make Emacs crash.
>  
>

The behaviour to pop down on key press is present in CVS and 21.3.  But 
this should only happen if the focus is on the frame and not the 
dialog.  It also only happens for Lucid and Lesstif/Motif dialogs.  The 
reason for this being in CVS is because it is in 21.3 :-).  Personally I 
think it is a strange behaviour.

However, I obviously did a typo when making the "pop down on ESC" (see 
below), so the Lucid pops down on any keypress when focus is on the 
dialog.  This is now fixed.

>If we repeat the experiment in 21.3, we see that the bug is not
>present there.  However, there is another bug.  If we click the mouse
>anywhere inside the Emacs frame, but outside the "Yes" button, nil is
>returned.  This is also a bug, which does _not_ occur in current CVS.
>This seems to be a case of introducing one bug by fixing another
>

This way of popping down the dialog has been replaced by popping down by 
pressing ESC, which is more in line with what other applications and 
toolkits use.  But the non-toolkit build uses menus instead of dialogs, 
so the behaviour is different.  For popup menus, clicking outside means 
"cancel" so in that case it is popped down.  The ESC thing was not 
implemented for the non-toolkit build, I guess I thought it wasn't that 
many people that used it and thus not worth it.

So in CVS, dialogs does not pop down because of a click outside the 
dialog.  The non-toolkit build is not a dialog but a menu, so it does 
pop down.

ESC shall pop down dialogs, except for the non-toolkit build (not 
implemented, but easy to add).

Any key pressed when the focus is on the Emacs frame and not the dialog 
pops down the Lucid and Lesstif/Motif dialog, to be compatible with 
21.3.  GTK and non-toolkit does not pop down on keypress outside the 
dialog/menu.

    Jan D.

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: undo in loaddefs.el buffer
  2004-12-26 16:15           ` Jan D.
@ 2004-12-27  2:31             ` Luc Teirlinck
  2004-12-27 10:21               ` Jan D.
  2004-12-27 18:05             ` Richard Stallman
  1 sibling, 1 reply; 60+ messages in thread
From: Luc Teirlinck @ 2004-12-27  2:31 UTC (permalink / raw)
  Cc: juri, yamaoka, rms, emacs-devel

Jan D. wrote:

   The behaviour to pop down on key press is present in CVS and 21.3.  But 
   this should only happen if the focus is on the frame and not the 
   dialog.  It also only happens for Lucid and Lesstif/Motif dialogs.  The 
   reason for this being in CVS is because it is in 21.3 :-).  Personally I 
   think it is a strange behaviour.

I think it is strange too.

   This way of popping down the dialog has been replaced by popping down by 
   pressing ESC, which is more in line with what other applications and 
   toolkits use.

"Popping down" means returning nil, which for y-or-n-p and yes-or-no-p
means answering "No".  Anybody who uses the escape key as a Meta key
can easily answer "No" without wanting to do that.  This is especially
bad for yes-or-no-p which, according to the Elisp manual is meant for
"crucial decisions".  Intuitively, one would expect "popping down" to
mean quitting, not answering "No".  This peculiar behavior is not
documented in the docstrings of y-or-n-p and yes-or-no-p.  I could not
find any reference to it in the Elisp manual.

Apparently, some users expect C-g to _really_ quit from a dialog box,
like it quits in the minibuffer.  Instead, it is treated like any
other key.

Sincerely,

Luc.

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: undo in loaddefs.el buffer
  2004-12-26  2:32           ` Juri Linkov
  2004-12-26  3:59             ` Luc Teirlinck
@ 2004-12-27  2:40             ` Luc Teirlinck
  2004-12-27 20:16               ` Juri Linkov
  2004-12-27  4:09             ` Richard Stallman
  2 siblings, 1 reply; 60+ messages in thread
From: Luc Teirlinck @ 2004-12-27  2:40 UTC (permalink / raw)
  Cc: yamaoka, rms, emacs-devel

Juri Linkov wrote:

   I don't use popup menus, so this behavior was really unexpected for me,

What do you mean with "I don't use popup menus"?  Do you have
`use-dialog-box' set to nil?  Then you should not see a pop-up-menu and
it would be very difficult to understand why you do, since yes-or-no-p
explicitly checks `use-dialog-box'.

Sincerely,

Luc.

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: undo in loaddefs.el buffer
  2004-12-26  2:06         ` Luc Teirlinck
  2004-12-26  2:32           ` Juri Linkov
  2004-12-26 16:15           ` Jan D.
@ 2004-12-27  4:09           ` Richard Stallman
  2004-12-27  4:42             ` Luc Teirlinck
  2 siblings, 1 reply; 60+ messages in thread
From: Richard Stallman @ 2004-12-27  4:09 UTC (permalink / raw)
  Cc: juri, yamaoka, emacs-devel

    This might be toolkit dependent.  (At least for popup menus).  If the
    answer gets asked in the minibuffer, quitting works normally (at least
    for me).

We recently looked at the code in xmenu.c that pops up dialogs,
and concluded it could safely run timers.  If timers are safe,
quitting must be safe.  But there could be some case in which
it doesn't allow quitting.  We should investigate that.

Meanwhile, I am not sure it is right for this question to appear as a
pop-up menu.  yes-or-no-p uses a pop-up menu wen the current command
was invoked with the mouse, and that is right when the command itself
asks the question, but it may not be right for this.  It would be
easy to change undo-outer-limit-truncate to use the minibuffer
unconditionally.

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: undo in loaddefs.el buffer
  2004-12-26  2:43         ` Juri Linkov
@ 2004-12-27  4:09           ` Richard Stallman
  0 siblings, 0 replies; 60+ messages in thread
From: Richard Stallman @ 2004-12-27  4:09 UTC (permalink / raw)
  Cc: yamaoka, teirllm, emacs-devel

    The question is asked after `decode-coding-region' is called from
    `decode-coding-inserted-region' from `jka-compr-insert-file-contents'.
    Perhaps undo should be disabled temporarily in `jka-compr-insert-file-contents'
    during visiting a gzipped file, but not permanently because buffers of
    gzipped files are editable.

Does this replacement function make it work right?
It is designed to make buffer-undo-list empty in the case of visiting
a file, and optimize it in the other case.



(defun decode-coding-inserted-region (from to filename
					   &optional visit beg end replace)
  "Decode the region between FROM and TO as if it is read from file FILENAME.
Optional arguments VISIT, BEG, END, and REPLACE are the same as those
of the function `insert-file-contents'."
  (save-excursion
    (save-restriction
      (let ((coding coding-system-for-read)
	    undo-list-saved)
	(if visit
	    ;; Temporarily turn off undo recording, if we're decoding the
	    ;; text of a visited file.
	    (setq buffer-undo-list t)
	  ;; Otherwise, if we can recognize the undo elt for the insertion,
	  ;; remove it and get ready to replace it later.
	  ;; In the mean time, turn off undo recording.
	  (let ((last (car buffer-undo-list))) 
	    (if (and (consp last) (eql (car last) from) (eql (cdr last) to))
		(setq undo-list-saved (cdr buffer-undo-list)
		      buffer-undo-list t))))
	(narrow-to-region from to)
	(goto-char (point-min))
	(or coding
	    (setq coding (funcall set-auto-coding-function
				  filename (- (point-max) (point-min)))))
	(or coding
	    (setq coding (car (find-operation-coding-system
			       'insert-file-contents
			       filename visit beg end replace))))
	(if (coding-system-p coding)
	    (or enable-multibyte-characters
		(setq coding
		      (coding-system-change-text-conversion coding 'raw-text)))
	  (setq coding nil))
	(if coding
	    (decode-coding-region (point-min) (point-max) coding)
	  (setq last-coding-system-used coding))
	;; If we're decoding the text of a visited file,
	;; the undo list should start out empty.
	(if visit
	    (setq buffer-undo-list nil)
	  ;; If we decided to replace the undo entry for the insertion,
	  ;; do so now.
	  (if undo-list-saved
	      (setq buffer-undo-list
		    (cons (cons from (point-max)) undo-list-saved))))))))

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: undo in loaddefs.el buffer
  2004-12-26  2:32           ` Juri Linkov
  2004-12-26  3:59             ` Luc Teirlinck
  2004-12-27  2:40             ` Luc Teirlinck
@ 2004-12-27  4:09             ` Richard Stallman
  2 siblings, 0 replies; 60+ messages in thread
From: Richard Stallman @ 2004-12-27  4:09 UTC (permalink / raw)
  Cc: yamaoka, teirllm, emacs-devel

    > (let (last-nonmenu-event) (yes-or-no-p "prompt"))

    This code displays a X popup menu when no toolkit is used.
    And it doesn't react to key presses.

In the no-toolkit case, Fx_popup_dialog just calls Fx_popup_menu.  I
think it is a bug that C-g doesn't work during them.  So this is a
bug.  I am not sure it is worth fixing, though.

However, with the x toolkit, Fx_popup_dialog explicitly pops down
when there is input.  Here's the code from popup_get_selection,
with the comment that explains it.  down_on_keypress is 1 for dialogs
and 0 for menus.

      /* If the user presses a key that doesn't go to the menu,
         deactivate the menu.
         The user is likely to do that if we get wedged.
         All toolkits now pop down menus on ESC.
         For dialogs however, the focus may not be on the dialog, so
         in that case, we pop down. */
      else if (event.type == KeyPress
               && down_on_keypress
               && dpyinfo->display == event.xbutton.display)

So it is an intentional feature.  It may not work exactly the right
way, but it's not a bug, ust eliminating it doesn't seem like the
right solution.

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: undo in loaddefs.el buffer
  2004-12-27  4:09           ` Richard Stallman
@ 2004-12-27  4:42             ` Luc Teirlinck
  0 siblings, 0 replies; 60+ messages in thread
From: Luc Teirlinck @ 2004-12-27  4:42 UTC (permalink / raw)
  Cc: juri, yamaoka, emacs-devel

Richard Stallman wrote:

   Meanwhile, I am not sure it is right for this question to appear as a
   pop-up menu.  yes-or-no-p uses a pop-up menu wen the current command
   was invoked with the mouse, and that is right when the command itself
   asks the question, but it may not be right for this.  It would be
   easy to change undo-outer-limit-truncate to use the minibuffer
   unconditionally.

I believe that this would indeed be a lot better.

Sincerely,

Luc.

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: undo in loaddefs.el buffer
  2004-12-26  9:14         ` Richard Stallman
@ 2004-12-27  5:29           ` Luc Teirlinck
  2004-12-27 22:35             ` Richard Stallman
  0 siblings, 1 reply; 60+ messages in thread
From: Luc Teirlinck @ 2004-12-27  5:29 UTC (permalink / raw)
  Cc: juri, yamaoka, joakim, emacs-devel

Richard Stallman wrote:

       Moreover, in addition to those two and texinfo-format-buffer and
       loaddefs.el, there is a problem when you autorevert the Buffer Menu.
       At regular intervals, you get asked the "undo" question, even when the
       Buffer Menu is very tiny (like three buffers).

   That suggests something is making too much undo info.  It would be
   good to debug why it makes so much undo info.  Forcing Emacs into the
   debugger when it is asking the question would be a way to do that.  Or
   stopping Emacs with GDB.

Each time the Buffer Menu reverted (every five seconds), it added more
undo info to the same undo entry without even making an undo boundary.
The patch for the Buffer Menu (clearing out the undo info when
reverting), which I installed, fixes that problem, so it should be
gone now.

       3.  Fail to put in undo boundaries, thus accumulating one huge single
	   undo entry, eventually triggering the undo-outer-limit question.

       Situation 3 seems to happen rather easily with timers.

   Maybe that means Emacs should put in undo boundaries at the
   beginning and end of a timer.

Most timers do not modify the buffer.  But, _maybe_ that is OK.  From
reading the code of Fundo_boundary, it appears that it will never make
consecutive redundant boundaries anyway.  

Timers can switch buffers.  Auto Revert does.  Again, _maybe_ that is
OK because (from `(elisp)Undo'):

All buffer modifications add a boundary whenever the previous
undoable change was made in some other buffer.  This is to ensure
that each command makes a boundary in each buffer where it makes
changes.

       Although the problem with the buffer menu appears to be caused by (3)
       I believe that the reasons for discarding undo info when reverting a
       file, also apply to reverting the Buffer Menu.  So the patch below,
       discards all undo info when reverting the Buffer Menu.

   I think that is right, and likewise for Dired.

At closer look, Dired already does discard all undo Info when
reverting, in dired-readin.

Sincerely,

Luc.

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: undo in loaddefs.el buffer
  2004-12-27  2:31             ` Luc Teirlinck
@ 2004-12-27 10:21               ` Jan D.
  2004-12-27 11:05                 ` Jan D.
                                   ` (2 more replies)
  0 siblings, 3 replies; 60+ messages in thread
From: Jan D. @ 2004-12-27 10:21 UTC (permalink / raw)
  Cc: juri, yamaoka, rms, emacs-devel

Luc Teirlinck wrote:

>   This way of popping down the dialog has been replaced by popping down by 
>   pressing ESC, which is more in line with what other applications and 
>   toolkits use.
>
>"Popping down" means returning nil, which for y-or-n-p and yes-or-no-p
>means answering "No".  Anybody who uses the escape key as a Meta key
>can easily answer "No" without wanting to do that.  This is especially
>bad for yes-or-no-p which, according to the Elisp manual is meant for
>"crucial decisions".  Intuitively, one would expect "popping down" to
>mean quitting, not answering "No".  This peculiar behavior is not
>documented in the docstrings of y-or-n-p and yes-or-no-p.  I could not
>find any reference to it in the Elisp manual.
>
>Apparently, some users expect C-g to _really_ quit from a dialog box,
>like it quits in the minibuffer.  Instead, it is treated like any
>other key.
>

To have ESC or Ctrl-g (basically any close without using dialog buttons, 
for example clicking on a window manager close button in the title) do a 
real quit for a dialog box sounds like a very good idea.  I think it is 
easy to do, because for lucid and lesstif/motif you can already quit 
dialogs with Ctrl-g (i.e. a real quit), but only if the focus is on the 
frame, not the dialog.  We should make this consistent.

For the original case (quitting out of the undo question), that would be 
an improvement as you could continue to hit Ctrl-g until all questions 
are gone :-).  It is a strange case.  I have to hit Ctrl-g three times 
for the yes-or-no question in the minibuffer to be canceled, but then a 
yes-or-no dialog pops up.  It is the same behaviour regardless of toolkit.

     Jan D.

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: undo in loaddefs.el buffer
  2004-12-27 10:21               ` Jan D.
@ 2004-12-27 11:05                 ` Jan D.
  2004-12-27 22:35                 ` Richard Stallman
  2004-12-28  5:03                 ` Luc Teirlinck
  2 siblings, 0 replies; 60+ messages in thread
From: Jan D. @ 2004-12-27 11:05 UTC (permalink / raw)
  Cc: juri, yamaoka, Luc Teirlinck, rms, emacs-devel


> To have ESC or Ctrl-g (basically any close without using dialog 
> buttons, for example clicking on a window manager close button in the 
> title) do a real quit for a dialog box sounds like a very good idea.  
> I think it is easy to do, because for lucid and lesstif/motif you can 
> already quit dialogs with Ctrl-g (i.e. a real quit), but only if the 
> focus is on the frame, not the dialog.  We should make this consistent.


Especially since the file save/dialog already has this behaviour (i.e. a 
real quit when popped down without pressing OK).

    Jan D.

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: undo in loaddefs.el buffer
  2004-12-26 16:15           ` Jan D.
  2004-12-27  2:31             ` Luc Teirlinck
@ 2004-12-27 18:05             ` Richard Stallman
  2004-12-27 19:33               ` Jan D.
  1 sibling, 1 reply; 60+ messages in thread
From: Richard Stallman @ 2004-12-27 18:05 UTC (permalink / raw)
  Cc: juri, yamaoka, teirllm, emacs-devel

    This way of popping down the dialog has been replaced by popping down by 
    pressing ESC, which is more in line with what other applications and 
    toolkits use.

I think it would be an improvement if most characters did not exit the
dialog, only ESC and C-g.  Can you implement this in general?

Perhaps ESC should cause a quit rather than returning nil.  Of course,
C-g definitely ought to quit.

Should ESC exit a menu too?  It seems to me that would
be a coherent interface.  Is that easy to do?

    Any key pressed when the focus is on the Emacs frame and not the dialog 
    pops down the Lucid and Lesstif/Motif dialog, to be compatible with 
    21.3.

I don't think we need to be backwards-compatible in that regard.  If
only-ESC-exits is a better policy, let's switch to that in all cases
if we can.

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: undo in loaddefs.el buffer
  2004-12-27 18:05             ` Richard Stallman
@ 2004-12-27 19:33               ` Jan D.
  2004-12-28  4:57                 ` Richard Stallman
  2004-12-28 21:05                 ` Jason Rumney
  0 siblings, 2 replies; 60+ messages in thread
From: Jan D. @ 2004-12-27 19:33 UTC (permalink / raw)
  Cc: juri, yamaoka, teirllm, emacs-devel

>     This way of popping down the dialog has been replaced by popping 
> down by
>     pressing ESC, which is more in line with what other applications 
> and
>     toolkits use.
>
> I think it would be an improvement if most characters did not exit the
> dialog, only ESC and C-g.  Can you implement this in general?
>
> Perhaps ESC should cause a quit rather than returning nil.  Of course,
> C-g definitely ought to quit.

I've implemented ESC and C-g to do a quit for the X window versions.  
I'll try to do it for OSX, and perhaps W32, but if someone has the time 
to do at least W32, that would be great.  I really don't know anything 
about Mac OS Classic.

>
> Should ESC exit a menu too?  It seems to me that would
> be a coherent interface.  Is that easy to do?

Yes, and I've done that also.  C-g also exits a menu now (just exits, 
it does not quit).  The same comment about OSX and W32 applies here.

>
>     Any key pressed when the focus is on the Emacs frame and not the 
> dialog
>     pops down the Lucid and Lesstif/Motif dialog, to be compatible with
>     21.3.
>
> I don't think we need to be backwards-compatible in that regard.  If
> only-ESC-exits is a better policy, let's switch to that in all cases
> if we can.

Ok, I'll remove that code.  ESC is good because it is the default for 
many toolkits and C-g is the Emacs way.  I think that is all that is 
needed.

	Jan D.

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: undo in loaddefs.el buffer
  2004-12-27  2:40             ` Luc Teirlinck
@ 2004-12-27 20:16               ` Juri Linkov
  2004-12-28  4:57                 ` Richard Stallman
  0 siblings, 1 reply; 60+ messages in thread
From: Juri Linkov @ 2004-12-27 20:16 UTC (permalink / raw)
  Cc: yamaoka, rms, emacs-devel

Luc Teirlinck <teirllm@dms.auburn.edu> writes:
> What do you mean with "I don't use popup menus"?  Do you have
> `use-dialog-box' set to nil?  Then you should not see a pop-up-menu and
> it would be very difficult to understand why you do, since yes-or-no-p
> explicitly checks `use-dialog-box'.

No, I have `use-dialog-box' set to t (i.e. haven't changed the default).
But the problem is the following: undo asks the question in the minibuffer,
and after I type C-g in the minibuffer, it repeats the same question
with a pop-up menu.

I expected that if it's really not allowed to quit during asking the
question and leave the question unanswered, then at least after C-g it
should repeat the same question in the minibuffer, not in a pop-up menu.

-- 
Juri Linkov
http://www.jurta.org/emacs/

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: undo in loaddefs.el buffer
  2004-12-27  5:29           ` Luc Teirlinck
@ 2004-12-27 22:35             ` Richard Stallman
  0 siblings, 0 replies; 60+ messages in thread
From: Richard Stallman @ 2004-12-27 22:35 UTC (permalink / raw)
  Cc: juri, yamaoka, joakim, emacs-devel

Since most timers don't insert text in buffers, maybe the right thing is
simply that Auto Revert and any other packages that have timer
functions that modify a buffer should do what's necessary regarding
undo boundaries.

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: undo in loaddefs.el buffer
  2004-12-27 10:21               ` Jan D.
  2004-12-27 11:05                 ` Jan D.
@ 2004-12-27 22:35                 ` Richard Stallman
  2004-12-28 13:16                   ` Jan D.
  2004-12-28  5:03                 ` Luc Teirlinck
  2 siblings, 1 reply; 60+ messages in thread
From: Richard Stallman @ 2004-12-27 22:35 UTC (permalink / raw)
  Cc: juri, yamaoka, teirllm, emacs-devel

    For the original case (quitting out of the undo question), that would be 
    an improvement as you could continue to hit Ctrl-g until all questions 
    are gone :-).  It is a strange case.  I have to hit Ctrl-g three times 
    for the yes-or-no question in the minibuffer to be canceled, but then a 
    yes-or-no dialog pops up.

I don't follow.  If you type C-g, that should quit the command that is
asking the question, so it won't produce any more undo info and it
won't ask any more questions.

If something other than that happens for you, why does it happen?
Is it a bug?

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: undo in loaddefs.el buffer
  2004-12-27 19:33               ` Jan D.
@ 2004-12-28  4:57                 ` Richard Stallman
  2004-12-28  8:11                   ` Jan D.
  2004-12-28 21:05                 ` Jason Rumney
  1 sibling, 1 reply; 60+ messages in thread
From: Richard Stallman @ 2004-12-28  4:57 UTC (permalink / raw)
  Cc: juri, yamaoka, teirllm, emacs-devel

    I've implemented ESC and C-g to do a quit for the X window versions.  
    I'll try to do it for OSX, and perhaps W32, but if someone has the time 
    to do at least W32, that would be great.  I really don't know anything 
    about Mac OS Classic.

    >
    > Should ESC exit a menu too?  It seems to me that would
    > be a coherent interface.  Is that easy to do?

    Yes, and I've done that also.  C-g also exits a menu now (just exits, 
    it does not quit).  The same comment about OSX and W32 applies here.

Thanks very much.

Can you mention this in etc/NEWS?

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: undo in loaddefs.el buffer
  2004-12-27 20:16               ` Juri Linkov
@ 2004-12-28  4:57                 ` Richard Stallman
  0 siblings, 0 replies; 60+ messages in thread
From: Richard Stallman @ 2004-12-28  4:57 UTC (permalink / raw)
  Cc: yamaoka, teirllm, emacs-devel

    I expected that if it's really not allowed to quit during asking the
    question and leave the question unanswered,

What a strange idea.  Why would this not be allowed?

Quitting from this question is supposed to work.  It is supposed
to quit the command, as usual.  If you have found a case where
this fails, can you debug it?

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: undo in loaddefs.el buffer
  2004-12-27 10:21               ` Jan D.
  2004-12-27 11:05                 ` Jan D.
  2004-12-27 22:35                 ` Richard Stallman
@ 2004-12-28  5:03                 ` Luc Teirlinck
  2004-12-28 17:25                   ` Richard Stallman
  2 siblings, 1 reply; 60+ messages in thread
From: Luc Teirlinck @ 2004-12-28  5:03 UTC (permalink / raw)
  Cc: juri, yamaoka, rms, emacs-devel

Jan D. wrote:

   It is a strange case.  I have to hit Ctrl-g three times 
   for the yes-or-no question in the minibuffer to be canceled, but then a 
   yes-or-no dialog pops up.  It is the same behaviour regardless of toolkit.

Juri Linkov wrote:

   No, I have `use-dialog-box' set to t (i.e. haven't changed the default).
   But the problem is the following: undo asks the question in the minibuffer,
   and after I type C-g in the minibuffer, it repeats the same question
   with a pop-up menu.

   I expected that if it's really not allowed to quit during asking the
   question and leave the question unanswered, then at least after C-g it
   should repeat the same question in the minibuffer, not in a pop-up menu.

Richard Stallman wrote:

   I don't follow.  If you type C-g, that should quit the command that is
   asking the question, so it won't produce any more undo info and it
   won't ask any more questions.

   If something other than that happens for you, why does it happen?
   Is it a bug?

If, for instance, a timer is involved that runs once every five
seconds, or even more frequently, then, after the quit, the timer will
run again, make the undo entry even larger without adding an undo
boundary and ask the question again.  And again, until something
creates an undo boundary.  I do not _know_ whether something like this
is happening in the situations described above, but until I committed
a patch yesterday evening, the described behavior was exactly what would
happen (with up to a five second delay) if you auto-reverted the
Buffer Menu every five seconds.

The popup menu could be explained by any intervening mouse click.

Sincerely,

Luc.

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: undo in loaddefs.el buffer
  2004-12-28  4:57                 ` Richard Stallman
@ 2004-12-28  8:11                   ` Jan D.
  0 siblings, 0 replies; 60+ messages in thread
From: Jan D. @ 2004-12-28  8:11 UTC (permalink / raw)
  Cc: juri, yamaoka, teirllm, emacs-devel


>>
>> Should ESC exit a menu too?  It seems to me that would
>> be a coherent interface.  Is that easy to do?
>
>     Yes, and I've done that also.  C-g also exits a menu now (just 
> exits,
>     it does not quit).  The same comment about OSX and W32 applies 
> here.
>
> Thanks very much.
>
> Can you mention this in etc/NEWS?

Done.

	Jan D.

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: undo in loaddefs.el buffer
  2004-12-27 22:35                 ` Richard Stallman
@ 2004-12-28 13:16                   ` Jan D.
  2004-12-28 20:57                     ` Richard Stallman
  0 siblings, 1 reply; 60+ messages in thread
From: Jan D. @ 2004-12-28 13:16 UTC (permalink / raw)
  Cc: juri, yamaoka, teirllm, emacs-devel

Luc Teirlinck wrote:


>If, for instance, a timer is involved that runs once every five
>seconds, or even more frequently, then, after the quit, the timer will
>run again, make the undo entry even larger without adding an undo
>boundary and ask the question again.  And again, until something
>creates an undo boundary.  I do not _know_ whether something like this
>is happening in the situations described above, but until I committed
>a patch yesterday evening, the described behavior was exactly what would
>happen (with up to a five second delay) if you auto-reverted the
>Buffer Menu every five seconds.
>
>The popup menu could be explained by any intervening mouse click.
>

There is no timer, and there is no mouse click.  Just C-g, no mouse 
movement, or anything else.

Richard Stallman wrote:

>    For the original case (quitting out of the undo question), that would be 
>    an improvement as you could continue to hit Ctrl-g until all questions 
>    are gone :-).  It is a strange case.  I have to hit Ctrl-g three times 
>    for the yes-or-no question in the minibuffer to be canceled, but then a 
>    yes-or-no dialog pops up.
>
>I don't follow.  If you type C-g, that should quit the command that is
>asking the question, so it won't produce any more undo info and it
>won't ask any more questions.
>
>If something other than that happens for you, why does it happen?
>Is it a bug?
>

Here is what I found.

The first time the question to discard is asked, it is asked by kill-region:


#0  Fyes_or_no_p (prompt=141235155) at fns.c:3279
#1  0x081c238e in Ffuncall (nargs=2, args=0xbfffe150) at eval.c:2775
#2  0x081f6065 in Fbyte_code (bytestr=137004643, vector=137004684,
    maxdepth=40) at bytecode.c:686
#3  0x081c2b84 in funcall_lambda (fun=137004612, nargs=1,
    arg_vector=0xbfffe374) at eval.c:2962
#4  0x081c25ab in Ffuncall (nargs=2, args=0xbfffe370) at eval.c:2823
#5  0x081c1fc5 in call1 (fn=138840169, arg1=61097120) at eval.c:2569
#6  0x081a3a86 in truncate_undo_list (b=0x83931e0) at undo.c:379
#7  0x081a829e in Fgarbage_collect () at alloc.c:4687
#8  0x081f5cbc in Fbyte_code (bytestr=137012651, vector=137012724,
    maxdepth=40) at bytecode.c:523
#9  0x081c15fa in Feval (form=137012637) at eval.c:2136
#10 0x081c00b7 in Fcondition_case (args=140356805) at eval.c:1332
#11 0x081f6814 in Fbyte_code (bytestr=137012587, vector=137012612,
    maxdepth=24) at bytecode.c:864
#12 0x081c2b84 in funcall_lambda (fun=137012524, nargs=2,
    arg_vector=0xbfffe9e4) at eval.c:2962
#13 0x081c25ab in Ffuncall (nargs=3, args=0xbfffe9e0) at eval.c:2823
#14 0x081be2e3 in Fcall_interactively (function=138212161,
    record_flag=137916553, keys=137975548) at callint.c:877
#15 0x08155340 in Fcommand_execute (cmd=138212161, record_flag=137916553,
    keys=137916553, special=137916553) at keyboard.c:9712
#16 0x081486e2 in command_loop_1 () at keyboard.c:1785
#17 0x081c01ca in internal_condition_case (bfun=0x81472f1 <command_loop_1>,
    handlers=137979985, hfun=0x8146e2e <cmd_error>) at eval.c:1385
#18 0x08147173 in command_loop_2 () at keyboard.c:1312
#19 0x081bfca9 in internal_catch (tag=137973201,
    func=0x8147150 <command_loop_2>, arg=137916553) at eval.c:1144
#20 0x08147129 in command_loop () at keyboard.c:1291
#21 0x08146bb0 in recursive_edit_1 () at keyboard.c:984
#22 0x08146cf5 in Frecursive_edit () at keyboard.c:1045
#23 0x0814565b in main (argc=2, argv=0xbffff3d4) at emacs.c:1763
(gdb) xbacktrace
"yes-or-no-p"
"undo-outer-limit-truncate"
"byte-code"
"kill-region"
"call-interactively"

But when I hit C-g, Emacs does redisplay, and that in turn invokes a GC, 
which asks the question again:

#0  Fyes_or_no_p (prompt=141235011) at fns.c:3279
#1  0x081c238e in Ffuncall (nargs=2, args=0xbfffdd30) at eval.c:2775
#2  0x081f6065 in Fbyte_code (bytestr=137004643, vector=137004684,
    maxdepth=40) at bytecode.c:686
#3  0x081c2b84 in funcall_lambda (fun=137004612, nargs=1,
    arg_vector=0xbfffdf54) at eval.c:2962
#4  0x081c25ab in Ffuncall (nargs=2, args=0xbfffdf50) at eval.c:2823
#5  0x081c1fc5 in call1 (fn=138840169, arg1=61097120) at eval.c:2569
#6  0x081a3a86 in truncate_undo_list (b=0x83931e0) at undo.c:379
#7  0x081a829e in Fgarbage_collect () at alloc.c:4687
#8  0x081c2119 in Ffuncall (nargs=2, args=0xbfffe0e0) at eval.c:2715
#9  0x081c1fc5 in call1 (fn=138013281, arg1=137972113) at eval.c:2569
#10 0x08149427 in safe_run_hooks_1 (hook=-1073749696) at keyboard.c:2037
#11 0x081c01ca in internal_condition_case (bfun=0x814940b 
<safe_run_hooks_1>,
    handlers=137916601, hfun=0x8149429 <safe_run_hooks_error>) at 
eval.c:1385
#12 0x081494c1 in safe_run_hooks (hook=137972113) at keyboard.c:2065
#13 0x080a57df in update_menu_bar (f=0x85a4e00, save_match_data=0)
    at xdisp.c:8305
#14 0x080a557f in prepare_menu_bars () at xdisp.c:8204
#15 0x080a826f in redisplay_internal (preserve_echo_area=0) at xdisp.c:9881
#16 0x080a73f4 in redisplay () at xdisp.c:9482
#17 0x08149cb9 in read_char (commandflag=1, nmaps=2, maps=0xbfffea90,
    prev_event=137916553, used_mouse_menu=0xbfffeb8c) at keyboard.c:2537
#18 0x081533f3 in read_key_sequence (keybuf=0xbfffecf0, bufsize=30,
    prompt=137916553, dont_downcase_last=0, can_return_switch_frame=1,
    fix_current_buffer=1) at keyboard.c:8818
#19 0x08147690 in command_loop_1 () at keyboard.c:1531
#20 0x081c01ca in internal_condition_case (bfun=0x81472f1 <command_loop_1>,
    handlers=137979985, hfun=0x8146e2e <cmd_error>) at eval.c:1385
#21 0x08147173 in command_loop_2 () at keyboard.c:1312
#22 0x081bfca9 in internal_catch (tag=137973201,
    func=0x8147150 <command_loop_2>, arg=137916553) at eval.c:1144
#23 0x08147129 in command_loop () at keyboard.c:1291
#24 0x08146bb0 in recursive_edit_1 () at keyboard.c:984
#25 0x08146cf5 in Frecursive_edit () at keyboard.c:1045
#26 0x0814565b in main (argc=2, argv=0xbffff3d4) at emacs.c:1763
(gdb) xbacktrace
"yes-or-no-p"
"undo-outer-limit-truncate"

(gdb) l alloc.c:4687
4682        /* If a buffer's undo list is Qt, that means that undo is
4683           turned off in that buffer.  Calling truncate_undo_list on
4684           Qt tends to return NULL, which effectively turns undo 
back on.
4685           So don't call truncate_undo_list if undo_list is Qt.  */
4686        if (! EQ (nextb->undo_list, Qt))
4687          truncate_undo_list (nextb);
4688   
4689        /* Shrink buffer gaps, but skip indirect and dead buffers.  */
4690        if (nextb->base_buffer == 0 && !NILP (nextb->name))
4691          {
(gdb)


And from that point on every C-g leads to a redisplay and a GC, and the 
same place in alloc.c again, until I answer Yes or No on the question.

As for the dialog popping up, I can only assume that read_key_sequence 
gets interrupted by the C-g after it has set last_nonmenu_event to Qnil, 
but before it has set it to the event.  This is however just 
speculation, I haven't been able to actually catch that in the 
debugger.  Running inside the debugger has the strange side effect of 
never popping up a dialog, so there might be some timing involved.

    Jan D.

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: undo in loaddefs.el buffer
  2004-12-28  5:03                 ` Luc Teirlinck
@ 2004-12-28 17:25                   ` Richard Stallman
  2004-12-29  2:07                     ` Luc Teirlinck
  2004-12-30  5:06                     ` Luc Teirlinck
  0 siblings, 2 replies; 60+ messages in thread
From: Richard Stallman @ 2004-12-28 17:25 UTC (permalink / raw)
  Cc: juri, yamaoka, jan.h.d, emacs-devel

    If, for instance, a timer is involved that runs once every five
    seconds, or even more frequently, then, after the quit, the timer will
    run again, make the undo entry even larger without adding an undo
    boundary and ask the question again.

A timer that modifies the buffer should always create an undo
boundary.  Can people fix these timers to do so?

Which programs are these timers in, anyway?
We need to look at these issues in their specifics
to be able to think about them.

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: undo in loaddefs.el buffer
  2004-12-28 13:16                   ` Jan D.
@ 2004-12-28 20:57                     ` Richard Stallman
  2004-12-29 12:59                       ` Jan D.
  0 siblings, 1 reply; 60+ messages in thread
From: Richard Stallman @ 2004-12-28 20:57 UTC (permalink / raw)
  Cc: juri, yamaoka, teirllm, emacs-devel

Now I understand the problem.  Does this fix it?

*** simple.el	27 Dec 2004 20:52:25 -0500	1.676
--- simple.el	28 Dec 2004 13:49:15 -0500	
***************
*** 1524,1540 ****
  	     '(0 . 0)))
      '(0 . 0)))
  
  ;; When the first undo batch in an undo list is longer than undo-outer-limit,
  ;; this function gets called to ask the user what to do.
  ;; Garbage collection is inhibited around the call,
  ;; so it had better not do a lot of consing.
  (setq undo-outer-limit-function 'undo-outer-limit-truncate)
  (defun undo-outer-limit-truncate (size)
!   (if (let (use-dialog-box)
! 	(yes-or-no-p (format "Buffer %s undo info is %d bytes long; discard it? "
! 			     (buffer-name) size)))
!       (progn (setq buffer-undo-list nil) t)
!     nil))
  \f
  (defvar shell-command-history nil
    "History list for some commands that read shell commands.")
--- 1524,1556 ----
  	     '(0 . 0)))
      '(0 . 0)))
  
+ (defvar undo-extra-outer-limit nil
+   "If non-nil, an extra level of size that's ok in an undo item.
+ We don't ask the user about truncating the undo list until the
+ current item gets bigger than this amount.")
+ (make-variable-buffer-local 'undo-extra-outer-limit)
+ 
  ;; When the first undo batch in an undo list is longer than undo-outer-limit,
  ;; this function gets called to ask the user what to do.
  ;; Garbage collection is inhibited around the call,
  ;; so it had better not do a lot of consing.
  (setq undo-outer-limit-function 'undo-outer-limit-truncate)
  (defun undo-outer-limit-truncate (size)
!   (when (or (null undo-extra-outer-limit)
! 	    (> size undo-extra-outer-limit))
!     ;; Don't ask the question again unless it gets even bigger.
!     ;; This applies, in particular, if the user quits from the question.
!     ;; Such a quit quits out of GC, but something else will call GC
!     ;; again momentarily.  It will call this function again,
!     ;; but we don't want to ask the question again.
!     (setq undo-extra-outer-limit (+ size 50000))
!     (if (let (use-dialog-box)
! 	  (yes-or-no-p (format "Buffer %s undo info is %d bytes long; discard it? "
! 			       (buffer-name) size)))
! 	(progn (setq buffer-undo-list nil)
! 	       (setq undo-extra-outer-limit nil)
! 	       t)
!       nil)))
  \f
  (defvar shell-command-history nil
    "History list for some commands that read shell commands.")

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: undo in loaddefs.el buffer
  2004-12-27 19:33               ` Jan D.
  2004-12-28  4:57                 ` Richard Stallman
@ 2004-12-28 21:05                 ` Jason Rumney
  2004-12-29 23:22                   ` Jan D.
  1 sibling, 1 reply; 60+ messages in thread
From: Jason Rumney @ 2004-12-28 21:05 UTC (permalink / raw)
  Cc: emacs-devel

"Jan D." <jan.h.d@swipnet.se> writes:

> I've implemented ESC and C-g to do a quit for the X window versions.
> I'll try to do it for OSX, and perhaps W32, but if someone has the
> time to do at least W32, that would be great.

If someone could implement dialogs on W32 it would also be
great. Currently W32 uses menus, like the non-toolkit X version.

>> Should ESC exit a menu too?  It seems to me that would
>> be a coherent interface.  Is that easy to do?
>
> Yes, and I've done that also.  C-g also exits a menu now (just exits,
> it does not quit).  The same comment about OSX and W32 applies here.

ESC already works for exiting W32 menus. I don't know what would be
involved in making C-g work the same way, and don't have time to look
at it myself.

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: undo in loaddefs.el buffer
  2004-12-28 17:25                   ` Richard Stallman
@ 2004-12-29  2:07                     ` Luc Teirlinck
  2004-12-29 20:46                       ` Richard Stallman
  2004-12-30  5:06                     ` Luc Teirlinck
  1 sibling, 1 reply; 60+ messages in thread
From: Luc Teirlinck @ 2004-12-29  2:07 UTC (permalink / raw)
  Cc: juri, yamaoka, jan.h.d, emacs-devel

Richard Stallman wrote:

   A timer that modifies the buffer should always create an undo
   boundary.  Can people fix these timers to do so?

If they think about it.  Maybe we should add something to
`(elisp)Timers' about this, if we are sure that we definitely do not
want timers do make undo boundaries automatically.  I could do this,
if desired.

   Which programs are these timers in, anyway?
   We need to look at these issues in their specifics
   to be able to think about them.

The one I _know_ about is autorevert.  However, autorevert currently
only autoreverts file visiting buffers, Dired and the Buffer Menu.  I
took care of the only one that gave problems, the Buffer Menu.

Should we decide that we want to take care of potential further types
of autoreverted non-file buffers individually as they get added, then
I still would have to look at the new  Auto Revert Tail mode, because
there could still be a problem there.

While autorevert is the only concrete example I know, I would be very
surprised if it were the only example of a timer modifying buffers. 

Sincerely,

Luc.

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: undo in loaddefs.el buffer
  2004-12-28 20:57                     ` Richard Stallman
@ 2004-12-29 12:59                       ` Jan D.
  0 siblings, 0 replies; 60+ messages in thread
From: Jan D. @ 2004-12-29 12:59 UTC (permalink / raw)
  Cc: juri, yamaoka, teirllm, emacs-devel


> Now I understand the problem.  Does this fix it?

Yes it does.

	Jan D.

>
> *** simple.el	27 Dec 2004 20:52:25 -0500	1.676
> --- simple.el	28 Dec 2004 13:49:15 -0500	
> ***************
> *** 1524,1540 ****
>   	     '(0 . 0)))
>       '(0 . 0)))
>
>   ;; When the first undo batch in an undo list is longer than 
> undo-outer-limit,
>   ;; this function gets called to ask the user what to do.
>   ;; Garbage collection is inhibited around the call,
>   ;; so it had better not do a lot of consing.
>   (setq undo-outer-limit-function 'undo-outer-limit-truncate)
>   (defun undo-outer-limit-truncate (size)
> !   (if (let (use-dialog-box)
> ! 	(yes-or-no-p (format "Buffer %s undo info is %d bytes long; discard 
> it? "
> ! 			     (buffer-name) size)))
> !       (progn (setq buffer-undo-list nil) t)
> !     nil))
>   \f
>   (defvar shell-command-history nil
>     "History list for some commands that read shell commands.")
> --- 1524,1556 ----
>   	     '(0 . 0)))
>       '(0 . 0)))
>
> + (defvar undo-extra-outer-limit nil
> +   "If non-nil, an extra level of size that's ok in an undo item.
> + We don't ask the user about truncating the undo list until the
> + current item gets bigger than this amount.")
> + (make-variable-buffer-local 'undo-extra-outer-limit)
> +
>   ;; When the first undo batch in an undo list is longer than 
> undo-outer-limit,
>   ;; this function gets called to ask the user what to do.
>   ;; Garbage collection is inhibited around the call,
>   ;; so it had better not do a lot of consing.
>   (setq undo-outer-limit-function 'undo-outer-limit-truncate)
>   (defun undo-outer-limit-truncate (size)
> !   (when (or (null undo-extra-outer-limit)
> ! 	    (> size undo-extra-outer-limit))
> !     ;; Don't ask the question again unless it gets even bigger.
> !     ;; This applies, in particular, if the user quits from the 
> question.
> !     ;; Such a quit quits out of GC, but something else will call GC
> !     ;; again momentarily.  It will call this function again,
> !     ;; but we don't want to ask the question again.
> !     (setq undo-extra-outer-limit (+ size 50000))
> !     (if (let (use-dialog-box)
> ! 	  (yes-or-no-p (format "Buffer %s undo info is %d bytes long; 
> discard it? "
> ! 			       (buffer-name) size)))
> ! 	(progn (setq buffer-undo-list nil)
> ! 	       (setq undo-extra-outer-limit nil)
> ! 	       t)
> !       nil)))
>   \f
>   (defvar shell-command-history nil
>     "History list for some commands that read shell commands.")
>
>
> _______________________________________________
> Emacs-devel mailing list
> Emacs-devel@gnu.org
> http://lists.gnu.org/mailman/listinfo/emacs-devel

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: undo in loaddefs.el buffer
  2004-12-29  2:07                     ` Luc Teirlinck
@ 2004-12-29 20:46                       ` Richard Stallman
  2004-12-30  1:14                         ` Luc Teirlinck
  0 siblings, 1 reply; 60+ messages in thread
From: Richard Stallman @ 2004-12-29 20:46 UTC (permalink / raw)
  Cc: juri, yamaoka, jan.h.d, emacs-devel

    If they think about it.  Maybe we should add something to
    `(elisp)Timers' about this, if we are sure that we definitely do not
    want timers do make undo boundaries automatically.  I could do this,
    if desired.

I think it is to change the timer functions rather than the timer
mechanism.  This is because not many timers will need to do it, and it
will take some experimenting to determine just what they should do.

I updated the manual.

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: undo in loaddefs.el buffer
  2004-12-28 21:05                 ` Jason Rumney
@ 2004-12-29 23:22                   ` Jan D.
  0 siblings, 0 replies; 60+ messages in thread
From: Jan D. @ 2004-12-29 23:22 UTC (permalink / raw)
  Cc: emacs-devel


2004-12-28 kl. 22.05 skrev Jason Rumney:

> "Jan D." <jan.h.d@swipnet.se> writes:
>
>> I've implemented ESC and C-g to do a quit for the X window versions.
>> I'll try to do it for OSX, and perhaps W32, but if someone has the
>> time to do at least W32, that would be great.
>
> If someone could implement dialogs on W32 it would also be
> great. Currently W32 uses menus, like the non-toolkit X version.

It is the same on OSX.

>
>>> Should ESC exit a menu too?  It seems to me that would
>>> be a coherent interface.  Is that easy to do?
>>
>> Yes, and I've done that also.  C-g also exits a menu now (just exits,
>> it does not quit).  The same comment about OSX and W32 applies here.
>
> ESC already works for exiting W32 menus. I don't know what would be
> involved in making C-g work the same way, and don't have time to look
> at it myself.

I may very well be impossible on OSX and/or W32, I haven't looked at it 
in detail.

	Jan D.

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: undo in loaddefs.el buffer
  2004-12-29 20:46                       ` Richard Stallman
@ 2004-12-30  1:14                         ` Luc Teirlinck
  2004-12-30 16:43                           ` Richard Stallman
  0 siblings, 1 reply; 60+ messages in thread
From: Luc Teirlinck @ 2004-12-30  1:14 UTC (permalink / raw)
  Cc: juri, yamaoka, jan.h.d, emacs-devel

Richard Stallman wrote:

       If they think about it.  Maybe we should add something to
       `(elisp)Timers' about this, if we are sure that we definitely do not
       want timers do make undo boundaries automatically.  I could do this,
       if desired.

   I think it is to change the timer functions rather than the timer
   mechanism.  This is because not many timers will need to do it, and it
   will take some experimenting to determine just what they should do.

   I updated the manual.

The change you made to the manual says that timers (as opposed to idle
timers) should not edit user buffers.  But this is exactly what Auto
Revert mode and Auto Revert Tail mode do.  They have to use timers,
because idle timers only run once after a period of idleness and Auto
Revert has to be able to continuously update the buffer.

I suppose the remark was meant to prevent timers from interrupting
user input.  But Auto Revert takes special steps to prevent that and
so could other timers.

What about the following?  I could install if desired.

===File ~/os.texi-diff======================================
*** os.texi	29 Dec 2004 15:49:18 -0600	1.67
--- os.texi	29 Dec 2004 17:42:40 -0600	
***************
*** 1368,1377 ****
  timer to call a function that takes substantial time to run is likely
  to be annoying.
  
!   Timer functions should normally not alter the current buffer
! contents, but it may be ok to alter some other buffer that exists for
! special purposes.  A general guideline is that if a buffer has undo
! enabled, timers should not write in it.
  
  @deffn Command run-at-time time repeat function &rest args
  This sets up a timer that calls the function @var{function} with
--- 1368,1380 ----
  timer to call a function that takes substantial time to run is likely
  to be annoying.
  
!   When a timer edits a buffer in which undo is enabled, it normally
! should explicitly call @code{undo-boundary} once at the beginning and
! once just before exiting, since Emacs won't do that automatically
! (@pxref{Undo}).  In addition, a timer which edits a buffer that the
! user also might want to edit, should take special steps to avoid
! interrupting user input.  Using an idle timer (see below) is one way
! to avoid the latter problem.
  
  @deffn Command run-at-time time repeat function &rest args
  This sets up a timer that calls the function @var{function} with
***************
*** 1486,1496 ****
  input.  Then it becomes idle again, and all the idle timers that are
  set up to repeat will subsequently run another time, one by one.
  
-   It is legitimate for an idle timer to edit the current buffer.  If
- it does, it should explicitly call @code{undo-boundary} once at the
- beginning and once just before exiting, since Emacs won't do that
- automatically for an idle timer.
- 
  @defun cancel-timer timer
  Cancel the requested action for @var{timer}, which should be a value
  previously returned by @code{run-at-time} or @code{run-with-idle-timer}.
--- 1489,1494 ----
============================================================

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: undo in loaddefs.el buffer
  2004-12-28 17:25                   ` Richard Stallman
  2004-12-29  2:07                     ` Luc Teirlinck
@ 2004-12-30  5:06                     ` Luc Teirlinck
  2004-12-30 20:58                       ` Richard Stallman
  1 sibling, 1 reply; 60+ messages in thread
From: Luc Teirlinck @ 2004-12-30  5:06 UTC (permalink / raw)
  Cc: juri, yamaoka, jan.h.d, emacs-devel

I believe that Auto Revert Tail mode needs two undo boundaries.  I
checked that without them it keeps accumulating one big undo entry.
The patch below does puts in the undo boundaries.  I can install if
desired.

I do not believe that Auto Revert Mode itself needs any undo
boundaries.  All currently reverted buffers now clear out all undo
info as a part of reverting, so the problem is handled by the revert
functions.

The problem with Auto Revert Tail mode is that it does not use a
"real" revert.

I do not know whether there are any circumstances where timers that do
fontification could accumulate big single undo entries.

Here is the autorevert patch:

===File ~/autorevert-diff===================================
*** autorevert.el	29 Dec 2004 20:37:00 -0600	1.41
--- autorevert.el	29 Dec 2004 21:08:55 -0600	
***************
*** 444,454 ****
--- 444,456 ----
  	(file buffer-file-name)
  	buffer-file-name)		; ignore that file has changed
      (when (> size auto-revert-tail-pos)
+       (undo-boundary)
        (save-restriction
  	(widen)
  	(save-excursion
  	  (goto-char (point-max))
  	  (insert-file-contents file nil auto-revert-tail-pos size)))
+       (undo-boundary)
        (setq auto-revert-tail-pos size)
        (set-buffer-modified-p modified)))
    (set-visited-file-modtime))
============================================================

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: undo in loaddefs.el buffer
  2004-12-30  1:14                         ` Luc Teirlinck
@ 2004-12-30 16:43                           ` Richard Stallman
  2004-12-31  1:54                             ` Luc Teirlinck
  2004-12-31  2:14                             ` Luc Teirlinck
  0 siblings, 2 replies; 60+ messages in thread
From: Richard Stallman @ 2004-12-30 16:43 UTC (permalink / raw)
  Cc: juri, yamaoka, jan.h.d, emacs-devel

    The change you made to the manual says that timers (as opposed to idle
    timers) should not edit user buffers.

Here is what it says:

      Timer functions should normally not alter the current buffer
    contents,

That is correct; I don't see a reason to change it.

The manual is not supposed to describe every possible exception to the
rules that could be made to work.  That would make the manual too
big, too complicated, and too hard to read for ordinary purposes.

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: undo in loaddefs.el buffer
  2004-12-30  5:06                     ` Luc Teirlinck
@ 2004-12-30 20:58                       ` Richard Stallman
  0 siblings, 0 replies; 60+ messages in thread
From: Richard Stallman @ 2004-12-30 20:58 UTC (permalink / raw)
  Cc: juri, yamaoka, jan.h.d, emacs-devel

    I believe that Auto Revert Tail mode needs two undo boundaries.  I
    checked that without them it keeps accumulating one big undo entry.
    The patch below does puts in the undo boundaries.  I can install if
    desired.

Please do.

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: undo in loaddefs.el buffer
  2004-12-30 16:43                           ` Richard Stallman
@ 2004-12-31  1:54                             ` Luc Teirlinck
  2004-12-31  9:22                               ` David Kastrup
  2004-12-31  2:14                             ` Luc Teirlinck
  1 sibling, 1 reply; 60+ messages in thread
From: Luc Teirlinck @ 2004-12-31  1:54 UTC (permalink / raw)
  Cc: juri, yamaoka, jan.h.d, emacs-devel

Richard Stallman wrote:

   The manual is not supposed to describe every possible exception to the
   rules that could be made to work.  That would make the manual too
   big, too complicated, and too hard to read for ordinary purposes.

But 100% of the known examples (Auto Revert and Auto Revert Tail)
contradict the rules.  So it would seem better not to mention these
rules to begin with.  There is no need to distinguish between timers
and idle timers in as far as the undo problem is concerned.  All cases
where we had to worry about were timers, not idle timers.

There are several problems with:

      It is legitimate for an idle timer to edit the current buffer.  If
    it does, it should explicitly call @code{undo-boundary} once at the
    beginning and once just before exiting, since Emacs won't do that
    automatically for an idle timer.

It should be discussed in the common introduction to timers and idle
timers and not distinguish between them.  Remember that we arrived at
the above conclusion by looking exclusively at timers.  We never
looked at one single instance of the problem that involved idle timers.

Secondly, the correct solution is not always to make two undo
boundaries.  Sometimes it is to disable undo, sometimes it is to clear
out all undo info, as we saw with autorevert.  It sometimes might be
unnecessary for a timer that runs only once.  I believe that we should
explicitly mention the problem we want to avoid.  The person writing
the timer function is best placed to decide what the best solution is.
Also, it would make clear that the problem is serious.  I believe that
there is no need to explicitly mention disabling undo and clearing out
undo info, since these are obvious solutions to the problem.  The
double undo boundary solution is less obvious and should be mentioned,
especially since the programmer might have the false impression that
Emacs does this automatically anyway.

I propose the following alternative patch, which is rather different
from the one proposed yesterday.  I believe that it says all that
needs to be said.  It replaces the current two four line paragraphs
with one six line paragraph and describes the actual problem.

===File ~/os.texi-diff======================================
*** os.texi	29 Dec 2004 15:49:18 -0600	1.67
--- os.texi	30 Dec 2004 14:20:31 -0600	
***************
*** 1368,1377 ****
  timer to call a function that takes substantial time to run is likely
  to be annoying.
  
!   Timer functions should normally not alter the current buffer
! contents, but it may be ok to alter some other buffer that exists for
! special purposes.  A general guideline is that if a buffer has undo
! enabled, timers should not write in it.
  
  @deffn Command run-at-time time repeat function &rest args
  This sets up a timer that calls the function @var{function} with
--- 1368,1379 ----
  timer to call a function that takes substantial time to run is likely
  to be annoying.
  
!   A timer that edits a buffer in which undo is enabled, should be
! careful not to accumulate one huge undo entry over time, since that
! could yield memory problems.  To avoid this, it is usually necessary
! for the timer to explicitly call @code{undo-boundary} once at the
! beginning and once just before exiting.  Emacs won't do that
! automatically (@pxref{Undo}).
  
  @deffn Command run-at-time time repeat function &rest args
  This sets up a timer that calls the function @var{function} with
***************
*** 1486,1496 ****
  input.  Then it becomes idle again, and all the idle timers that are
  set up to repeat will subsequently run another time, one by one.
  
-   It is legitimate for an idle timer to edit the current buffer.  If
- it does, it should explicitly call @code{undo-boundary} once at the
- beginning and once just before exiting, since Emacs won't do that
- automatically for an idle timer.
- 
  @defun cancel-timer timer
  Cancel the requested action for @var{timer}, which should be a value
  previously returned by @code{run-at-time} or @code{run-with-idle-timer}.
--- 1488,1493 ----
============================================================

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: undo in loaddefs.el buffer
  2004-12-30 16:43                           ` Richard Stallman
  2004-12-31  1:54                             ` Luc Teirlinck
@ 2004-12-31  2:14                             ` Luc Teirlinck
  1 sibling, 0 replies; 60+ messages in thread
From: Luc Teirlinck @ 2004-12-31  2:14 UTC (permalink / raw)
  Cc: juri, yamaoka, jan.h.d, emacs-devel

Maybe there is one difference between timers and idle timers that is
relevant to the problem.  Many timers only run once.  There is no
problem for them.  Theoretically, idle timers can also only run once,
but that happens rarely in practice.  The following slightly changed
version of my latest patch makes clear that we are talking about
repeatedly running timers:

===File ~/os.texi-diff======================================
*** os.texi	29 Dec 2004 15:49:18 -0600	1.67
--- os.texi	30 Dec 2004 19:54:02 -0600	
***************
*** 1368,1377 ****
  timer to call a function that takes substantial time to run is likely
  to be annoying.
  
!   Timer functions should normally not alter the current buffer
! contents, but it may be ok to alter some other buffer that exists for
! special purposes.  A general guideline is that if a buffer has undo
! enabled, timers should not write in it.
  
  @deffn Command run-at-time time repeat function &rest args
  This sets up a timer that calls the function @var{function} with
--- 1368,1379 ----
  timer to call a function that takes substantial time to run is likely
  to be annoying.
  
!   A timer that runs at regular intervals and edits a buffer in which
! undo is enabled, should be careful not to accumulate one huge undo
! entry over time, since that could yield memory problems.  To avoid
! this, it is usually necessary for the timer to explicitly call
! @code{undo-boundary} once at the beginning and once just before
! exiting.  Emacs won't do that automatically (@pxref{Undo}).
  
  @deffn Command run-at-time time repeat function &rest args
  This sets up a timer that calls the function @var{function} with
***************
*** 1486,1496 ****
  input.  Then it becomes idle again, and all the idle timers that are
  set up to repeat will subsequently run another time, one by one.
  
-   It is legitimate for an idle timer to edit the current buffer.  If
- it does, it should explicitly call @code{undo-boundary} once at the
- beginning and once just before exiting, since Emacs won't do that
- automatically for an idle timer.
- 
  @defun cancel-timer timer
  Cancel the requested action for @var{timer}, which should be a value
  previously returned by @code{run-at-time} or @code{run-with-idle-timer}.
--- 1488,1493 ----
============================================================

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: undo in loaddefs.el buffer
  2004-12-31  1:54                             ` Luc Teirlinck
@ 2004-12-31  9:22                               ` David Kastrup
  2004-12-31 15:04                                 ` Luc Teirlinck
  0 siblings, 1 reply; 60+ messages in thread
From: David Kastrup @ 2004-12-31  9:22 UTC (permalink / raw)
  Cc: juri, yamaoka, jan.h.d, rms, emacs-devel

Luc Teirlinck <teirllm@dms.auburn.edu> writes:

> Richard Stallman wrote:
>
>    The manual is not supposed to describe every possible exception to the
>    rules that could be made to work.  That would make the manual too
>    big, too complicated, and too hard to read for ordinary purposes.
>
> But 100% of the known examples (Auto Revert and Auto Revert Tail)
> contradict the rules.

If the rule is "you should not ...", of course 100% of all relevant
examples are exceptions.

And they have to take special measures to deal with the consequences
of violating the rule.

-- 
David Kastrup, Kriemhildstr. 15, 44793 Bochum

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: undo in loaddefs.el buffer
  2004-12-31  9:22                               ` David Kastrup
@ 2004-12-31 15:04                                 ` Luc Teirlinck
  2005-01-01  5:25                                   ` Richard Stallman
  0 siblings, 1 reply; 60+ messages in thread
From: Luc Teirlinck @ 2004-12-31 15:04 UTC (permalink / raw)
  Cc: juri, yamaoka, jan.h.d, rms, emacs-devel

David Kastrup wrote:

   > But 100% of the known examples (Auto Revert and Auto Revert Tail)
   > contradict the rules.

   If the rule is "you should not ...", of course 100% of all relevant
   examples are exceptions.

The stated rules are:

    Timer functions should normally not alter the current buffer contents,
    but it may be ok to alter some other buffer that exists for special
    purposes.  A general guideline is that if a buffer has undo enabled,
    timers should not write in it.

The three guidelines given are that the buffer written into should not
be current (but that guideline seems so strange that it is probably
just a misformulation), that the buffer should only exist for special
purposes and, most importantly, that it should not have undo enabled.
All known examples write into buffers that are current when they alter
it and, more importantly, into buffers that have (by default) undo
enabled.  Most buffers they alter are normal file visiting buffers
that do not exist for special purposes.  Dired and the Buffer Menu
exist for special purposes, but their main purpose is not to be
autoreverted.

But the one important thing is that they operate on buffers that have
undo enabled.  The rest is side stuff.

   And they have to take special measures to deal with the consequences
   of violating the rule.

Some of which are obvious and some of which are non-obvious.  My
proposal is to point out the latter.  There is no need to point out
that you should not blindly overwrite user editing, it is obvious.
There is a need to point out that Emacs will not automatically put in
undo boundaries and that, consequently, one might accumulate one big
undo entry, unless one does something about it.  The correct solution
is not always to disable undo.  It was not the solution we decided on
in any of cases we looked at.  All these cases involved timers, not
idle timers.

Sincerely,

Luc.

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: undo in loaddefs.el buffer
  2004-12-31 15:04                                 ` Luc Teirlinck
@ 2005-01-01  5:25                                   ` Richard Stallman
  2005-01-02 16:02                                     ` Luc Teirlinck
  0 siblings, 1 reply; 60+ messages in thread
From: Richard Stallman @ 2005-01-01  5:25 UTC (permalink / raw)
  Cc: juri, yamaoka, jan.h.d, emacs-devel

    All known examples write into buffers that are current

No, most timers do not.  I found about 40 places in Emacs that create
timers, and these are just two of them.

There is no need for the manual to explain all the ways of writing
code that could possibly be made to work.  That is not the manual's job.
However, I found a simple way to improve the text.

It is normal that there is code in Emacs that does things the manual
says users shouldn't do.  Writing the manual in such a way that no code
in Emacs ever goes against its recommendations is not the goal.
       And they have to take special measures to deal with the consequences
       of violating the rule.

    Some of which are obvious and some of which are non-obvious.  My
    proposal is to point out the latter.

Could you please explain these special requirements in the comments in
autorevert.el, if that isn't already done.

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: undo in loaddefs.el buffer
  2005-01-01  5:25                                   ` Richard Stallman
@ 2005-01-02 16:02                                     ` Luc Teirlinck
  2005-01-03  0:58                                       ` Richard Stallman
  0 siblings, 1 reply; 60+ messages in thread
From: Luc Teirlinck @ 2005-01-02 16:02 UTC (permalink / raw)
  Cc: juri, yamaoka, jan.h.d, emacs-devel

       Some of which are obvious and some of which are non-obvious.  My
       proposal is to point out the latter.

   Could you please explain these special requirements in the comments in
   autorevert.el, if that isn't already done.

As I already pointed out, the only non-obvious requirement is that one
way or the other they have to take care of undo correctly.

In as far as autorevert is concerned, all problems with currently
reverted buffers have been taken care of.  If additional non-file
buffers get autoreverted, there _theoretically_ should be no problem.
I believe that we decided that reverting any buffer should clear out
all undo info.  In practice, some `revert-buffer-function's may not do
this, as we saw with the Buffer Menu.  I guess that the correct
solution in such cases would be to fix the `revert-buffer-function'.

Sincerely,

Luc.

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: undo in loaddefs.el buffer
  2005-01-02 16:02                                     ` Luc Teirlinck
@ 2005-01-03  0:58                                       ` Richard Stallman
  2005-01-04  3:07                                         ` Luc Teirlinck
  0 siblings, 1 reply; 60+ messages in thread
From: Richard Stallman @ 2005-01-03  0:58 UTC (permalink / raw)
  Cc: juri, yamaoka, jan.h.d, emacs-devel

    As I already pointed out, the only non-obvious requirement is that one
    way or the other they have to take care of undo correctly.

Yes.  If you could make sure that this issue is clearly explained
in comments in the code, that would be a good thing.
It has been explained clearly in mail on this list,
but the explanation needs to be in the code to ensure people see it.

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: undo in loaddefs.el buffer
  2005-01-03  0:58                                       ` Richard Stallman
@ 2005-01-04  3:07                                         ` Luc Teirlinck
  2005-01-04 17:00                                           ` Richard Stallman
  0 siblings, 1 reply; 60+ messages in thread
From: Luc Teirlinck @ 2005-01-04  3:07 UTC (permalink / raw)
  Cc: juri, yamaoka, jan.h.d, emacs-devel

Richard Stallman wrote:

       As I already pointed out, the only non-obvious requirement is that one
       way or the other they have to take care of undo correctly.

   Yes.  If you could make sure that this issue is clearly explained
   in comments in the code, that would be a good thing.

There is one obvious requirement, but two issues.  The first issue is
the general question of what it means to timers and idle timers in
general, whether they write into user buffers or into non-user buffers.
The second question is the way more specialized question of what it
means to autoreverting non-file buffers.  Actually, there might be the
third question of whether the general problem is really limited to
timers or applies in exactly the same way to asynchronous processes
that might write their output repeatedly into a buffer.

Before going into the autorevert specific problem, let me state what I
believe what our conclusion to the _general_ problem was.

I believe it was that the person writing a timer function that writes
at regular time intervals into a buffer needs to know that there is
the danger of accumulating one huge single undo entry and running out
of memory.  Something needs to be done about it, which could be
disabling undo, clearing out the undo info or putting in two undo
boundaries.  These points have to be made clear in `(elisp)Timers'
which currently says:

       It is usually a bad idea for timer functions to alter buffer
    contents.  When they do, they usually should call `undo-boundary' both
    before and after changing the buffer, to separate the timer's changes
    from user commands' changes.

I believe that there still are problems with this.

Although this was not the point of our discussion, it indeed would
usually seem better to put in two undo boundaries even if the timer
only runs once (in which case there are no memory problems), for the
reason given above.  But running out of memory is not mentioned and
the memory problem occurs _regardless_ of whether the buffer is a buffer
the user might want to write into.  (Several buffers in which the user
usually does not write have undo enabled, say Dired, Buffer Menu...)

I would replace the above quote with:

      If a timer function alters buffer contents, it usually should call
    `undo-boundary' both before and after changing the buffer, to separate
    the timer's changes from user commands' changes.  If the timer runs
    repeatedly, this also avoids accumulating one huge undo entry, which
    can cause memory problems.

The line " It is usually a bad idea for timer functions to alter
buffer contents.", could be left in, but it really serves no purpose
whatsoever.  Nobody is going to be tempted to make a timer alter
buffer contents without having good reasons to do so.

In as far as the autorevert issue is concerned, there is no problem
with autoreverting file buffers, or with the two currently
autoreverted non-file buffers.  Auto Revert Tail is an isolated case
and has been taken care of.

Which leaves autoreverting additional non-file buffers.  There I
understood that the revert-buffer-function was supposed to clear out
all undo info and that if it did not, the revert-buffer-function
should be changed to do that.  Did I understand this correctly?  If
yes, should that not actually be pointed out in the Elisp manual and
docstring documentation of `revert-buffer-function'?

I gave an overview of the various difficulties in autoreverting
non-file buffers in emacs-xtra.  (There is a link to this in the
docstring of `global-auto-revert-non-file-buffers'.)  I could add to
that list the need to check whether the revert-buffer-function really
sets the undo info to nil and to change that function if it does not.

Sincerely,

Luc.


I 

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: undo in loaddefs.el buffer
  2004-12-22  4:31   ` Katsumi Yamaoka
                       ` (2 preceding siblings ...)
  2004-12-24  1:45     ` Juri Linkov
@ 2005-01-04  9:05     ` Juri Linkov
  3 siblings, 0 replies; 60+ messages in thread
From: Juri Linkov @ 2005-01-04  9:05 UTC (permalink / raw)


There are two more cases where asking the question about undo info
is inappropriate:

1. Visiting large files inside a tar archive in tar mode
(with auto-compression-mode=t).  The backtrace is below:

Debugger entered--Lisp error: (quit)
  yes-or-no-p("Buffer file.ext (archive.tar.bz2) undo info is 331154 bytes long; discard it? ")
  undo-outer-limit-truncate(331154)
  tar-extract()
  call-interactively(tar-extract)

2. Running `man' with large man pages.

Debugger entered--Lisp error: (quit)
  yes-or-no-p("Buffer *Man xdvi* undo info is 334507 bytes long; discard it? ")
  undo-outer-limit-truncate(334507)
  Man-fontify-manpage()
  Man-bgproc-sentinel(#<process man> "finished\n")

-- 
Juri Linkov
http://www.jurta.org/emacs/

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: undo in loaddefs.el buffer
  2005-01-04  3:07                                         ` Luc Teirlinck
@ 2005-01-04 17:00                                           ` Richard Stallman
  0 siblings, 0 replies; 60+ messages in thread
From: Richard Stallman @ 2005-01-04 17:00 UTC (permalink / raw)
  Cc: juri, yamaoka, jan.h.d, emacs-devel

    The line " It is usually a bad idea for timer functions to alter
    buffer contents.", could be left in, but it really serves no purpose
    whatsoever.  Nobody is going to be tempted to make a timer alter
    buffer contents without having good reasons to do so.

That's clearly not true.  People will surely sometimes consider
"let's make a timer do the editing" as a possible solution.

^ permalink raw reply	[flat|nested] 60+ messages in thread

end of thread, other threads:[~2005-01-04 17:00 UTC | newest]

Thread overview: 60+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-12-21 14:14 undo in loaddefs.el buffer Luc Teirlinck
2004-12-21 15:41 ` Luc Teirlinck
2004-12-22  4:31   ` Katsumi Yamaoka
2004-12-22  4:58     ` Katsumi Yamaoka
2004-12-23  0:01     ` Richard Stallman
2004-12-23  0:26       ` David Kastrup
2004-12-25 15:13         ` Richard Stallman
2004-12-24  1:45     ` Juri Linkov
2004-12-24 21:39       ` Luc Teirlinck
2004-12-26  9:14         ` Richard Stallman
2004-12-27  5:29           ` Luc Teirlinck
2004-12-27 22:35             ` Richard Stallman
2004-12-24 23:59       ` Luc Teirlinck
2004-12-25 15:12       ` Richard Stallman
2004-12-26  2:06         ` Luc Teirlinck
2004-12-26  2:32           ` Juri Linkov
2004-12-26  3:59             ` Luc Teirlinck
2004-12-27  2:40             ` Luc Teirlinck
2004-12-27 20:16               ` Juri Linkov
2004-12-28  4:57                 ` Richard Stallman
2004-12-27  4:09             ` Richard Stallman
2004-12-26 16:15           ` Jan D.
2004-12-27  2:31             ` Luc Teirlinck
2004-12-27 10:21               ` Jan D.
2004-12-27 11:05                 ` Jan D.
2004-12-27 22:35                 ` Richard Stallman
2004-12-28 13:16                   ` Jan D.
2004-12-28 20:57                     ` Richard Stallman
2004-12-29 12:59                       ` Jan D.
2004-12-28  5:03                 ` Luc Teirlinck
2004-12-28 17:25                   ` Richard Stallman
2004-12-29  2:07                     ` Luc Teirlinck
2004-12-29 20:46                       ` Richard Stallman
2004-12-30  1:14                         ` Luc Teirlinck
2004-12-30 16:43                           ` Richard Stallman
2004-12-31  1:54                             ` Luc Teirlinck
2004-12-31  9:22                               ` David Kastrup
2004-12-31 15:04                                 ` Luc Teirlinck
2005-01-01  5:25                                   ` Richard Stallman
2005-01-02 16:02                                     ` Luc Teirlinck
2005-01-03  0:58                                       ` Richard Stallman
2005-01-04  3:07                                         ` Luc Teirlinck
2005-01-04 17:00                                           ` Richard Stallman
2004-12-31  2:14                             ` Luc Teirlinck
2004-12-30  5:06                     ` Luc Teirlinck
2004-12-30 20:58                       ` Richard Stallman
2004-12-27 18:05             ` Richard Stallman
2004-12-27 19:33               ` Jan D.
2004-12-28  4:57                 ` Richard Stallman
2004-12-28  8:11                   ` Jan D.
2004-12-28 21:05                 ` Jason Rumney
2004-12-29 23:22                   ` Jan D.
2004-12-27  4:09           ` Richard Stallman
2004-12-27  4:42             ` Luc Teirlinck
2004-12-26  2:43         ` Juri Linkov
2004-12-27  4:09           ` Richard Stallman
2005-01-04  9:05     ` Juri Linkov
2004-12-21 21:57 ` Kevin Rodgers
2004-12-22  0:17   ` Luc Teirlinck
2004-12-22  0:17 ` Richard Stallman

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).