On Mon, 11 Sep 2023 16:18:43 +0200 Stephen Berman wrote: > On Sun, 10 Sep 2023 07:11:07 -0700 Stefan Kangas wrote: > >> Stephen Berman writes: >> >>> 0. emacs -Q >>> 1. Type `M-x' and then TAB to pop up the *Completions* buffer, then type >>> `C-g'. >>> 2. Type `M-x ibuffer'. >>> 3. Type `d' on the lines for the buffers *scratch* and *Completions* to >>> flag them for deletion. >>> 4. Type `C-c C-a' to enable ibuffer-auto-mode. >>> 5. Type `x' and at the prompt "Really kill 2 buffers? (y or n)" type `y'. >>> => The *Ibuffer* lines for *scratch* and *Completions* are deleted and >>> the echo area displays this message: "Operation finished; killed 3 >>> buffers". >>> >>> If you change this recipe by omitting step 4, then after the buffer >>> lines are deleted the message displayed is "Operation finished; killed 2 >>> buffers". >>> >>> The unexpected message with ibuffer-auto-mode enabled is displayed in >>> Emacs 27-30 but not in Emacs 26. With Emacs 27+, on typing `x' at step >>> 5, the buffer *Ibuffer confirmation* pops up and a line for this buffer >>> immediately appears in the *Ibuffer* display, and this is counted by the >>> function `ibuffer-map-lines', and on typing `y' not only are the two >>> flagged buffers deleted, but also *Ibuffer confirmation*, hence "killed >>> 3 buffers". In contrast, in Emacs 26, the popped up buffer *Ibuffer >>> confirmation* does not get added to the *Ibuffer* display and thus is >>> not counted by `ibuffer-map-lines'. >>> >>> AFAICT, this difference is not due to any ibuffer code changes after >>> Emacs 26; rather, there appears to be a timing difference with respect >>> to when Emacs updates the *Ibuffer* display: when I instrument >>> `ibuffer-update' for Edebug and then type `x' (step 5 above), what >>> happens in Emacs 26 is that I can confirm with `y', then the flagged >>> lines are deleted, and only then does Edebug stop the execution so I can >>> step into `ibuffer-update'; while in Emacs 27+, as soon as I type `x', >>> Edebug stops execution, i.e., before the flagged lines are deleted. >>> >>> `ibuffer-update' is called in `ibuffer-auto-update-changed', which is >>> added to post-command-hook in `ibuffer-auto-mode'. So it seems that in >>> Emacs 26 post-command-hook runs or takes effect later than in Emacs 27+. >>> Whether this is really the case, and if so, what change it is due to, I >>> haven't determined, and I don't know how restore the Emacs 26 execution >>> order (or if that's even desirable). But even if the difference is due >>> to something else, the message displayed in Emacs 27+ after the deletion >>> of the *Ibuffer* lines is at least misleading, since it clearly is meant >>> to refer only to the flagged lines, as in Emacs 26. >>> >>> In lieu of a real fix, since it is, AFAICS, only the transient buffer >>> *Ibuffer confirmation* that results in the problematic message, a >>> workaround is simply to decrement the line count by one when >>> ibuffer-auto-mode is enabled, as in the the attached patch (which also >>> takes the opportunity to wrap an overlong line in `ibuffer-map-lines'). >> >> Your analysis and patch makes sense to me. Please install, but add a >> brief comment explaining why we do that decrement there. > > Done, and pushed as commit ca95e45f7e8. Thanks. Unfortunately, I didn't test that commit adequately before pushing it and have found two regressions it introduced: - If you delete exactly one buffer in Ibuffer with ibuffer-auto-mode enabled, it now emits the message "Operation finished; killed 0 buffers". - If you delete two buffers in Ibuffer with ibuffer-auto-mode enabled and with ibuffer-expert non-nil, it emits the message "Operation finished; killed 1 buffers" (in general, one less than the number of buffers deleted). The first attached patch fixes these regressions while retaining the improvement in ca95e45f7e8. While debugging I noticed two unrelated infelicities in the Ibuffer feedback: - The message reporting deletion of one buffer is grammatically incorrect: "killed 1 buffers". - If you type `x' in an Ibuffer buffer containing no marked buffer lines and with point not on one of the buffer lines (e.g. at (point-min) or (point-max)), you are prompted with "Really kill buffer *Ibuffer*? (y or n)" and if you type `y', the resulting message is "Operation finished; killed 0 buffers". This statement is correct, since no buffer was killed (without the first patch, the message is nonsensical: "killed -1 buffers"), but then Ibuffer appears to be ignoring the user's response to its prompt. However, I think the prompt itself is a mistake, and instead, Ibuffer should point out that there's no buffer on the current line and do nothing else (but again, only when there are no marked buffer lines.) The second attached patch fixes these problems (to see the effect I had to bootstrap; just regenerating ibuffer-loaddefs.el and loaddefs.el was insufficient). Should I install both patches? I've tested all combinations of deleting just one or more than buffer with ibuffer-auto-mode disabled and enabled and ibuffer-expert nil and non-nil, but perhaps I've again overlooked something, so I'll wait for a go-ahead. Also, since the second patch is strictly unrelated to the original bug report, a new bug report for it might be preferred. Steve Berman