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: Thu, 27 Jan 2005 21:31:02 -0600 (CST)

Richard Stallman wrote:

   I like your new option of displaying a warning, but please keep the
   option of asking the question.  At least we need to use it for
   testing purposes.

The patches below to simple.el and (purely doc changes) undo.c
implement this.  I will update the manuals and NEWS if they look OK.

Everything seems to work right, including keyboard macros, except for
one detail, which however looks like a bug in `yes-or-no-p' or related
functions rather than a bug in the `undo-outer-limit' related code.
That detail is the following.  If we set `undo-ask-before-discard' to
t and the question gets asked, then everything works as expected,
except that after answering the question (with yes _or_ no) and
waiting for a while 
RET-
appears in the echo area.

Is this for some reason normal?  Are there other situations where
yes-or-no-p is known to behave like this?

The above phenomenon is _not_ due to my patch.  It _already_ occurs in
the present version of `undo-outer-limit-truncate'.  I never noticed
it before, because I did not wait long enough before providing extra
input after asking the question.  

===File ~/simple.el-diff====================================
*** simple.el   23 Jan 2005 09:35:35 -0600      1.686
--- simple.el   27 Jan 2005 19:49:52 -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,1596 ----
             '(0 . 0)))
      '(0 . 0)))
  
+ (defcustom undo-ask-before-discard nil
+   "If non-nil ask about discarding undo info for the current command.
+ Normally, Emacs discards the undo info for the current command if
+ it exceeds `undo-outer-limit'.  But if you set this option
+ non-nil, it asks in the echo area whether to discard the info.
+ If you answer no, there a slight risk that Emacs might crash, so
+ only do it if you really want to undo the command.
+ 
+ This option is mainly intended for debugging.  You have to be
+ careful if you use it for other purposes.  Garbage collection is
+ inhibited while the question is asked, meaning that Emacs might
+ leak memory.  So you should make sure that you do not wait
+ excessively long before answering the question."
+   :type 'boolean
+   :group 'undo
+   :version "21.4")
+ 
  (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.
! 
! This variable only matters if `undo-ask-before-discard' is non-nil.")
  (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 warn the user that
! ;; the undo info for the current 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)
!   (if undo-ask-before-discard
!       (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 track-mouse executing-kbd-macro )
!             (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))
!     (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.")
============================================================

===File ~/undo.c-diff=======================================
*** undo.c      22 Dec 2004 18:50:07 -0600      1.63
--- undo.c      27 Jan 2005 20:35:12 -0600      
***************
*** 627,637 ****
    DEFVAR_LISP ("undo-outer-limit", &Vundo_outer_limit,
              doc: /* Outer limit on size of undo information for one command.
  At garbage collection time, if the current command has produced
! more than this much undo information, it asks you whether to delete
! the information.  This is a last-ditch limit to prevent memory overflow.
  
! The size is counted as the number of bytes occupied,
! which includes both saved text and other data.
  
  In fact, this calls the function which is the value of
  `undo-outer-limit-function' with one argument, the size.
--- 627,639 ----
    DEFVAR_LISP ("undo-outer-limit", &Vundo_outer_limit,
              doc: /* Outer limit on size of undo information for one command.
  At garbage collection time, if the current command has produced
! more than this much undo information, it discards the info and displays
! a warning.  This is a last-ditch limit to prevent memory overflow.
  
! The size is counted as the number of bytes occupied, which includes
! both saved text and other data.  A value of nil means no limit.  In
! this case, accumulating one huge undo entry could make Emacs crash as
! a result of memory overflow.
  
  In fact, this calls the function which is the value of
  `undo-outer-limit-function' with one argument, the size.
============================================================




reply via email to

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