(defun truncate-command-history-for-gc ()
- (let ((tail (nthcdr 30 command-history)))
- (if tail (setcdr tail nil)))
- (let ((tail (nthcdr 30 values)))
- (if tail (setcdr tail nil)))
- )
+ ;; We should try to avoid accessing any bindings to speak of in this
+ ;; function; as this hook is called asynchronously, the search for
+ ;; those bindings might search local bindings from essentially
+ ;; arbitrary functions. We force the body of the function to run at
+ ;; command-loop level, where the danger of local bindings is much
+ ;; reduced; the code can still do its job because the command history
+ ;; and values list will not grow before then anyway.
+ ;;
+ ;; Nothing is done in batch mode, both because it is a waste of time
+ ;; (there is no command loop!) and because this any GCs during dumping
+ ;; will invoke this code, and if it were to enqueue an eval event,
+ ;; the portable dumper would try to dump it and fail.
+ (if (not (noninteractive))
+ (enqueue-eval-event
+ #'(lambda (arg)
+ (let ((tail (nthcdr 30 command-history)))
+ (if tail (setcdr tail nil)))
+ (let ((tail (nthcdr 30 values)))
+ (if tail (setcdr tail nil))))
+ nil)))
(add-hook 'pre-gc-hook 'truncate-command-history-for-gc)
; (call-interactively _command _record-flag)))))
\f
(defun y-or-n-p-minibuf (prompt)
- "Ask user a \"y or n\" question. Return t if answer is \"y\".
+ "Ask user a \"y or n\" question. Return t if answer is \"y\", nil if \"n\".
Takes one argument, which is the string to display to ask the question.
It should end in a space; `y-or-n-p' adds `(y or n) ' to it.
No confirmation of the answer is requested; a single character is enough.
(yes-or-no-p-minibuf prompt)))
(defun y-or-n-p (prompt)
- "Ask user a \"y or n\" question. Return t if answer is \"y\".
+ "Ask user a \"y or n\" question. Return t if answer is \"y\", nil if \"n\".
Takes one argument, which is the string to display to ask the question.
The question is asked with a dialog box or the minibuffer, as appropriate.
It should end in a space; `y-or-n-p' adds `(y or n) ' to it.