I used gdb 7.6's undo feature in emacs 24.3, and got the following warnings. It suggests me to set `undo-outer-limit' to be a larger value. How should I set the variable to a correct value? How large can emacs support?
Warning (undo): Buffer `*gud-foo*' undo info was 13351087 bytes long.
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',
which is defined in the `warnings' library.
You can increase undo-outer-limit from the default value of 24,000,000 (see docs) by setting it in your .emacs or .emacs.d/init.el file:
;; increase undo-outer-limit to 72MB, 3x default value
(setq undo-outer-limit 72000000)
64-bit Emacs should be able to handle much larger values (see this discussion of supported file sizes) but as the warning says, very high undo memory usage may indicate a bug, so it's probably more sensible to set it as high as you find yourself needing it and not much farther.
Note that if you habitually work with files that would have been considered large in 2003 (i.e., files > 10MB), you may also want to increase large-file-warning-threshold:
;; increase large-file-warning-threshold to 30MB, 3x default value
(setq large-file-warning-threshold 30000000)
Related
I use (desktop-save-mode 1) in my .emacs. After some time of working with it my .emacs.desktop contains many (desktop-create-buffer...) entries which slow down startup terribly. Is it possible to limit the number of saved buffers to some arbitrary number?
For total control, you could advise the function desktop-save-buffer-p such that it returns nil for all the buffers you don't want to be saved.
By default that uses three user options:
desktop-buffers-not-to-save (regexp)
desktop-files-not-to-save (regexp)
desktop-modes-not-to-save (list)
Those don't directly help you cap the number of buffers saved to a specific limit, but they may prove useful regardless.
You might adapt code from midnight.el (e.g. a variant of clean-buffer-list which just returns a buffer list rather than killing buffers) to make use of existing code for identifying old/unnecessary buffers.
I am trying to execute when the active buffer has changed by either
Changing the buffer in the current window (e.g. C-x <left>).
Switching to another window (C-x o).
Switching to another frame.
Are their hooks suitable for detecting this?
What I figured out so far
Looking through the Standard Hooks I found the following options, none of which quite do what I want:
buffer-list-update-hook is called for both (1) and (2). It is however unsuitable, because it is run before the buffer is changed, while I want to know what the current-buffer after the change is.
window-configuration-change-hook can be used to detect a change of the buffer displayed in the current window, and it is run after the change, as needed. It is however not run for M-x other-window.
mouse-leave-buffer-hook seems viable for detecting mouse-based window switching, but it gets called a bit often (for me four times upon switching windows with the mouse, three times before and once after switching), which requires additional logical to prevent multiple execution.
post-command-hook would be viable but a bit heavy handed, risking significant slow-down of the editor by even minor bugs.
Since my action would need to use with-selected-window, which triggers these hooks, care has to be taken to avoid endless loops where the hook triggers itself.
Judging from the comments, the answer to this question is “No, there is no such hook.”
Additionally, some of the hooks mentioned in my question, are also triggered by changes, which are not user-visible, such as temporary changes due to with-current-buffer and with-selected-window.
However, using post-command-hook has proven to be a non-issue for performance, since the required state-check is cheap.
Alternative
Probably obvious, but stated for completeness.
Store state information in a global variable, in a frame-parameter, in a window-parameter or in a buffer-local variable, whichever is most applicable to the use-case. In my use-case, this necessary unique state is was defined by current-buffer, current-window, and in one case line-beginning-position.*
In post-command-hook, check if the state has changed, possibly skipping
even that, if this-command is self-insert-command.
If it has, perform the intended action and update the stored state.
* line-number-at-pos is unsuitable, because it counts lines by iterating over the buffer from point-min to point, making it generally cheap, but not cheap enough to be executed after every typed character.
Emacs27.1 introduce a new variable called `window-buffer-change-functions'
From time to time I get a "nesting exceeds `max-lisp-eval-depth'" error.
What does it mean?
When I get one, is there something I can do, other than "killall emacs"?
Edit:
You can get the error if you evaluate:
(defun func ()
(func))
(func)
However, in this case emacs remains responsive.
An immediate remedy can be to simply increase the maximum. Its default value is 500, but you could set it to, say, 10000 like this:
(setq max-lisp-eval-depth 10000)
But that's generally not a great idea, because the fact that you run into a nesting exceeds `max-lisp-eval-depth' error in the first place is a sign that some part of your code is taking up too much stack space. But at least increasing the maximum temporarily can help you analyze the problem without getting the same error message over and over again.
Basically, it means that some Lisp code used up more stack than Emacs was compiled to permit.
In practice, it's a sign of a bug in Lisp code. Correctly written code should avoid nesting this deeply, even if the algorithm and the input data were "correct"; but more frequently, it happens because of an unhandled corner case or unexpected input.
In other words, you have probably created an endless loop via recusion, or perhaps e.g. a regular expression with exponential backtracking.
If you are lucky, repeated control-G keypresses could get you out of the conundrum without killing Emacs.
If you are developing Emacs Lisp code, you might want to tweak down the value of max-lisp-eval-depth artificially to help find spots where your code might need hardening or bug fixing. And of course, having debug-on-error set to t should help by showing you a backtrace of the stack.
My clojure repl started throwing a "Variable binding depth exceeds max-specpdl-size" error and I've gotten thrown into the debugger.
I am currently accessing slime via clojure-jack-in and I am executing a reduce on a reasonable sized dataset. A bit of googling leads me to believe that the error is because I'm generating too many temporary variables, specifically:
User Option: max-specpdl-size
This variable defines the limit on the total number of local variable bindings and unwind-protect cleanups (see Cleaning Up from Nonlocal Exits) that are allowed before Emacs signals an error (with data "Variable binding depth exceeds max-specpdl-size").
This limit, with the associated error when it is exceeded, is one way that Lisp avoids infinite recursion on an ill-defined function. max-lisp-eval-depth provides another limit on depth of nesting. See Eval.
The default value is 1000. Entry to the Lisp debugger increases the value, if there is little room left, to make sure the debugger itself has room to execute.
found here.
I have little experience with debugging clojure-swank/slime so I hope someone can help.
EDIT:
I'm using clojure-mode 1.11.4 with emacs 24 and clojure 1.3.0, I've not installed swank-clojure, I'm using the one that comes bundled with clojure-mode via clojure-jack-in as I explained earlier.
Just in case someone is looking for a possible answer to this questions....
This error, as outlined, does often mean a problem, but not always. You can legitimately exceed the default depth setting in situations where you have large data structures or where you are usiing some emacs features, such as defadvice, which can result in deep bindings etc. You can increase the depth and see if that helps (for example, double it), but in this case it probably is an error.
One of the problems with swank-clojure is that it is tightly coupled with an old version of slime. This means improvements and bug fixes in slime are not available. It is because of this tight binding that the coljure community has moved away from using slime to using cider and I'd strongly recommend switching to using cider rather than slime and swank-clojure.
I had just lost most of the content of my notes in a text file, when I used emacs, and there was a bug, but I ignored the error message, and forced a file save. After a few hours, I found that my newly saved file had only a few bytes left! Most of my notes in the file had gone.
I wish that I had set up warning of file size change significantly, when saving a file in emacs. I saw such message before from emacs before, but I don't know how I can set it up now? Please share with m me any pointer to a solution. Worst come to worst, it should be possibe to add some checking in the hook for file save to implement it.
Thanks in advance!
Yu Shen
Depending on what kind of warning you want, this solves your problem. The current delta is 8M, obviously you can customize this how you want. If you want a more intrusive warning, you can uncomment the call to 'y-or-n-p, and get rid of the message.
(defvar check-buffer-size-delta (* 8 1024 1024)
"Delta in size over which the user will be warned when saving.")
(defun check-buffer-size-on-save ()
"Warn user if buffer has changed by more than CHECK-BUFFER-SIZE-DELTA since last save"
(let ((delta (abs (- (buffer-size) buffer-saved-size))))
(when (> delta check-buffer-size-delta)
(beep)
;; (y-or-n-p "WARNING: Buffer has changed by %d bytes since last save. Do you know what you're doing? "
(message "WARNING: Buffer has changed by %d bytes since last save." delta))))
(add-hook 'before-save-hook 'check-buffer-size-on-save)
This is not specific to Emacs, but if you want to avoid losing work in the future, committing your work to a version control system is very helpful. I generally use Git, but some people find Mercurial a bit simpler to use (there are lots of others, like Subversion, Bazaar, and so on, but Git and Mercurial are the most popular distributed revision control systems, which make it easier to just version control a directory on your disk without setting up a server). A version control system allows you to record the history of your work as you go, so if you make some sort of big mistake you can just revert back to an older version.