aboutsummaryrefslogtreecommitdiffstats
path: root/src/alloc.c
diff options
context:
space:
mode:
authorMartin Rudalics2024-08-01 09:37:50 +0200
committerMartin Rudalics2024-08-01 09:37:50 +0200
commit27381d71c65bd0ba93ed61f57011dbc66bd5bfab (patch)
treed0121e4ab000c95e49d5e4991d95aac388cebc02 /src/alloc.c
parentefbeefd17e3e8a3dcc02439805e42b9d9cedded9 (diff)
downloademacs-27381d71c65bd0ba93ed61f57011dbc66bd5bfab.tar.gz
emacs-27381d71c65bd0ba93ed61f57011dbc66bd5bfab.zip
Improve window/buffer handling code
The purpose of these changes is to improve the code handling the display of buffers in windows, switching to previous and next buffers in windows and restoring a previous state after quitting or killing buffers. In particular it does: - Add a new window parameter 'quit-restore-prev' so a window can keep its initial 'quit-restore' parameter and undoing a sequence of quit window operations becomes more reliable (Bug#59862). - Optionally have 'kill-buffer' call 'quit-restore-window' for all windows showing the argument buffer (Bug#59862). - Add a new hook so it's possible to avoid that a window gets deleted implicitly by functions like 'kill-buffer' (Bug#71386). - Add a new option to make 'quit-restore-window' delete windows more aggressively (Bug#59862). - Immediately remove killed buffers from all windows' previous and next buffers. For windows that are already dead, use a weak hash table to be used by 'kill-buffer'. This avoids any special handling of such windows by the garbage collector. - Immediately remove 'quit-restore' and 'quit-restore-prev' window parameters that reference killed buffers. These parameters have no more use once their buffers got killed. - Make sure that internal windows do not have any previous and next buffers. This fixes a silly memory leak. - Make sure that after set_window_buffer and some wset_buffer calls the buffer now shown in the window does not appear in the lists of that window's previous and next buffers. The old behavior could make functions investigating these lists erroneously believe that there still existed some other buffer to switch to. * src/alloc.c (mark_discard_killed_buffers): Remove function. (mark_window): No more filter previous and next buffer lists. * src/window.h (struct window): Move up prev_buffers and next-buffers in structure; they are now treated by the collector as usual. * src/window.c (window_discard_buffer_from_alist) (window_discard_buffer_from_list) (window_discard_buffer_from_window) (window_discard_buffer_from_dead_windows) (Fwindow_discard_buffer): New functions. (set_window_buffer): Discard BUFFER from WINDOW's previous and next buffers. (make_parent_window): Make sure internal windows have no previous and next buffers. (make_window): Don't initialize window's previous and next buffers, they are handled by allocate_window now. (Fdelete_window_internal): Add WINDOW to window_dead_windows_table. (Fset_window_configuration): Remove resurrected window from window_dead_windows_table. Make sure buffers set by wset_buffer calls are not recorded in window's previous and next buffers. (delete_all_child_windows): Add deleted windows to window_dead_windows_table. (window_dead_windows_table): New weak hash table to record dead windows that are stored in saved window configurations. * src/buffer.c (Fkill_buffer): Call new function 'window_discard_buffer_from_dead_windows'. * lisp/window.el (window-deletable-functions): New hook. (window-deletable-p): Update doc-string. Run 'window-deletable-functions' (Bug#71386). (unrecord-window-buffer): New argument ALL. Move body to 'window-discard-buffer-from-window' so that if ALL is non-nil, WINDOW's 'quit-restore' and 'quit-restore-prev' parameters get removed too. (switch-to-prev-buffer): Don't care about killed buffers here; 'replace-buffer-in-windows' should have done that already. Use 'unrecord-window-buffer'. (switch-to-next-buffer): Don't care about killed buffers here; 'replace-buffer-in-windows' should do that now. (kill-buffer-quit-windows): New option. (delete-windows-on): Update doc-string. Handle new option 'kill-buffer-quit-windows'. Update 'unrecord-window-buffer' calls. (replace-buffer-in-windows): Update doc-string. Handle new option 'kill-buffer-quit-windows' (Bug#59862). Update call to 'unrecord-window-buffer'. (quit-restore-window-no-switch): New option. (quit-restore-window): Update doc-string. Handle additional values of BURY-OR-KILL so to not kill a buffer about to be killed by the caller. Handle 'quit-restore-prev' parameter (Bug#59862). Handle new option 'quit-restore-window-no-switch' (Bug#59862). (quit-windows-on): Update doc-string. Call 'quit-window-hook' and call 'quit-restore-window' directly so that the buffer does not get buried or killed by the latter. Update 'unrecord-window-buffer' call. (display-buffer-record-window): Update doc-string. Handle new `quit-restore-prev' parameter (Bug#59862). (switch-to-buffer): Call 'display-buffer-record-window' so a latter 'quit-restore-window' can use its parameters. * doc/lispref/windows.texi (Deleting Windows): Describe implicit deletion of windows and new hook 'window-deletable-functions'. (Buffers and Windows): Update description of 'replace-buffer-in-windows'. Describe new option 'kill-buffer-quit-windows'. (Quitting Windows): Describe 'quit-restore-prev' parameter and new option 'quit-restore-window-no-switch'. Update description of 'quit-restore-window'. (Window Parameters): Mention 'quit-restore-prev' parameter. * etc/NEWS: Add entries for 'window-deletable-functions', 'kill-buffer-quit-windows', 'quit-restore-window-no-switch'. mention new parameter 'quit-restore-prev' and new argument values for 'quit-restore-window'.
Diffstat (limited to 'src/alloc.c')
-rw-r--r--src/alloc.c36
1 files changed, 0 insertions, 36 deletions
diff --git a/src/alloc.c b/src/alloc.c
index 48b170b866f..06fe12cff3d 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -7009,33 +7009,6 @@ mark_face_cache (struct face_cache *c)
7009 } 7009 }
7010} 7010}
7011 7011
7012/* Remove killed buffers or items whose car is a killed buffer from
7013 LIST, and mark other items. Return changed LIST, which is marked. */
7014
7015static Lisp_Object
7016mark_discard_killed_buffers (Lisp_Object list)
7017{
7018 Lisp_Object tail, *prev = &list;
7019
7020 for (tail = list; CONSP (tail) && !cons_marked_p (XCONS (tail));
7021 tail = XCDR (tail))
7022 {
7023 Lisp_Object tem = XCAR (tail);
7024 if (CONSP (tem))
7025 tem = XCAR (tem);
7026 if (BUFFERP (tem) && !BUFFER_LIVE_P (XBUFFER (tem)))
7027 *prev = XCDR (tail);
7028 else
7029 {
7030 set_cons_marked (XCONS (tail));
7031 mark_object (XCAR (tail));
7032 prev = xcdr_addr (tail);
7033 }
7034 }
7035 mark_object (tail);
7036 return list;
7037}
7038
7039static void 7012static void
7040mark_frame (struct Lisp_Vector *ptr) 7013mark_frame (struct Lisp_Vector *ptr)
7041{ 7014{
@@ -7090,15 +7063,6 @@ mark_window (struct Lisp_Vector *ptr)
7090 mark_glyph_matrix (w->current_matrix); 7063 mark_glyph_matrix (w->current_matrix);
7091 mark_glyph_matrix (w->desired_matrix); 7064 mark_glyph_matrix (w->desired_matrix);
7092 } 7065 }
7093
7094 /* Filter out killed buffers from both buffer lists
7095 in attempt to help GC to reclaim killed buffers faster.
7096 We can do it elsewhere for live windows, but this is the
7097 best place to do it for dead windows. */
7098 wset_prev_buffers
7099 (w, mark_discard_killed_buffers (w->prev_buffers));
7100 wset_next_buffers
7101 (w, mark_discard_killed_buffers (w->next_buffers));
7102} 7066}
7103 7067
7104/* Entry of the mark stack. */ 7068/* Entry of the mark stack. */