emacs-pretest-bug
[Top][All Lists]
Advanced

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

Re: Undo discard prompt (was: [T. V. Raman] read-only modes should be us


From: Luc Teirlinck
Subject: Re: Undo discard prompt (was: [T. V. Raman] read-only modes should be using buffer-disable-undo?)
Date: Wed, 26 Jan 2005 21:31:59 -0600 (CST)

Actually, I misinterpreted the reason for the memory leak after the
undo question is asked.  The memory leak happens even if nothing is
accumulating a large single undo entry.  After reading a comment in
the code, the reason for the memory leak became obvious:

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

`undo-outer-limit' may not do a lot of consing, but from the moment
the question is asked, timers and/or asynchronous processes start
consing and eating up memory.  If the question gets asked while the
user is not working at his monitor, eventually all memory gets eaten
up.  (I notice the memory leak every time, it is not just something I
theoretically deduced.)

Moreover, most users will not have the slightest idea what is going
on, or have any idea of what to base their answer on when they get
asked:

"Buffer %s undo info is %d bytes long; discard it? "

The probability of the user wanting to undo any given individual
command is very small.  I suggest to increase the default value
of `undo-outer-limit' to 3M, as you suggested yourself.  That would
decrease the occurrence of the problem.  Then I suggest to replace the
current question with a warning, displayed in a buffer, providing
proper explanation.  It suggests to the user to increase the value of
`undo-outer-limit' even further if even 3M turned out not to be enough
for him (and if the large size appeared legitimate).  It also suggests
to file a bug report if the large undo size was unexpected.

The patch below would do this using `display-warning'.  If this would
only be appropriate for small (one or two line) warning messages, we
could use `with-output-to-temp-buffer' instead, although
`display-warning' has some advantages.

The patch below would require some supporting doc changes in other
files (which I would make if the patch would look acceptable), but the
patch makes the intent clear.  It would also automatically solve the
keyboard macro problem.

===File ~/simple.el-diff====================================
*** simple.el   23 Jan 2005 09:35:35 -0600      1.686
--- simple.el   26 Jan 2005 20:01:11 -0600      
***************
*** 1521,1553 ****
             '(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)))
  
  (defvar shell-command-history nil
    "History list for some commands that read shell commands.")
--- 1521,1556 ----
             '(0 . 0)))
      '(0 . 0)))
  
! ;; When the first undo batch in an undo list is longer than
! ;; undo-outer-limit, this function gets called to warn the user that
! ;; the undo info for the last command was discarded.  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)
!   (display-warning '(undo discard-info)
!                  (concat
!                   (format "Buffer %s undo info was %d bytes long.\n"
!                           (buffer-name) size)
!                   "The undo info was discarded because it exceeded \
! `undo-outer-limit'.
! 
! This is normal if you executed a command that made a huge change
! to the buffer.  In that case, to prevent similar problems in the
! future, set `undo-outer-limit' to a value that is large enough to
! cover the maximum size of normal changes you expect a single
! command to make, but not so large that it might exceed the
! maximum memory allotted to Emacs.
! 
! If you did not execute any such command, the situation is
! probably due to a bug and you should report it.
! 
! You can disable the popping up of this buffer by adding the entry
! \(undo discard-info) to the user option `warning-suppress-types'.\n")
!                  :warning)
!   (setq buffer-undo-list nil)
!   t)
! 
  
  (defvar shell-command-history nil
    "History list for some commands that read shell commands.")
============================================================




reply via email to

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