0

I understand that when a window is split, the original window and the new window become children under a new "parent window".

I would like the option to somehow register these windows such that when either child window is deleted, the other child and the parent are also automatically deleted.

Here's why I want this ...

I'm using a complicated 3rd-party package that has a number of ways to create buffers and windows. Under certain isolated conditions (usually during a conditional operation within a hook function), I split certain windows.

If I use the standard facilities of this package to delete the original window (which is now one of the two children), the other, newly created child window remains.

I know that I can write code to determine the parent of a window being deleted and to write more code to delete its parent and sibling windows. However, this involves manually modifying functions within this complicated 3rd-party package, and I'd like to avoid this.

Ideally, I'd like to somehow register the children and the parent at the time that the window is initially split, so that whenever one of the three windows is deleted, the other two are also automatically deleted. This way, when the existing 3rd-party code deletes the original window as part of its normal processing, the parent and the other child will also automatically be deleted.

I have not been able to find any such facility in emacs nor in any searches. Does such a thing exist, by any chance?

One idea which occurs to me is to write wrapper functions for delete-window and split-window and install them via emacs' advice mechanism. But is there perhaps another mechanism for my desired functionality which might already exist?

Thank you very much for any suggestions.

NOTE: In digging through the emacs source code, I notice something called an "atomic window" or an "atom window". I can't find many docs for this, but it seems like it might give me what I want. For example, look at the final paragraph of the doc string for delete-window ...

(delete-window &optional WINDOW)

Delete WINDOW. WINDOW must be a valid window and defaults to the selected one. Return nil.

If the variable ‘ignore-window-parameters’ is non-nil or the ‘delete-window’ parameter of WINDOW equals t, do not process any parameters of WINDOW. Otherwise, if the ‘delete-window’ parameter of WINDOW specifies a function, call that function with WINDOW as its sole argument and return the value returned by that function.

Otherwise, if WINDOW is part of an atomic window, call ‘delete-window’ with the root of the atomic window as its argument. Signal an error if WINDOW is either the only window on its frame, the last non-side window, or part of an atomic window that is its frame’s root window.

... and here's the doc string for a function I found called display-buffer-in-atom-window ...

(display-buffer-in-atom-window BUFFER ALIST)

Display BUFFER in an atomic window. This function displays BUFFER in a new window that will be combined with an existing window to form an atomic window. If the existing window is already part of an atomic window, add the new window to that atomic window. Operations like ‘split-window’ or ‘delete-window’, when applied to a constituent of an atomic window, are applied atomically to the root of that atomic window.

ALIST is an association list of symbols and values. The following symbols can be used.

‘window’ specifies the existing window the new window shall be
combined with. Use ‘window-atom-root’ to make the new window a
sibling of an atomic window’s root. If an internal window is
specified here, all children of that window become part of the
atomic window too. If no window is specified, the new window
becomes a sibling of the selected window. By default, the
‘window-atom’ parameter of the existing window is set to ‘main’
provided it is live and was not set before.

‘side’ denotes the side of the existing window where the new window shall be located. Valid values are ‘below’, ‘right’, ‘above’ and ‘left’. The default is ‘below’. By default, the ‘window-atom’ parameter of the new window is set to this value.

The return value is the new window, nil when creating that window failed.

I'll be investigating this atom(ic) window thing, and I'll report back.

4
  • Instead of fiddling with core functions that every library relies upon, I would recommend you run a test when closing the selected-window for other windows containing a particular buffer and then delete those windows using the optional argument in delete-window. For example, you can set up the letter q to call your custom quit window function in the selected-window to handle deleting any other windows matching your specified criteria. You could get fancy and record prior windows in a variable or a window-config -- buffers inside windows can change . . . .
    – lawlist
    Apr 11, 2017 at 16:57
  • Thank you. Yes, I can do that, but it would involve re-writing parts of the 3rd-party package that I'm using, and I'm trying to avoid that. I don't delete the window "manually"; rather, the 3rd-party software deletes it during its own processing. That's why I'm thinking that I might have to override some core functions. But perhaps there are as-yet-undiscovered hooks within the 3rd-party package that I could use for this purpose. I'm continuing to investigate.
    – HippoMan
    Apr 12, 2017 at 10:59
  • I just discovered something in emacs called an "atom window" or an "atomic window" which might give me what I want. I added text to my question, above, discussing this.
    – HippoMan
    Apr 12, 2017 at 11:23
  • ... and atom(-ic) windows indeed do the trick! See my Answer.
    – HippoMan
    Apr 12, 2017 at 13:44

1 Answer 1

1

It turns out that atom(ic) windows are indeed exactly what I want. Consider this code ...

;; Instead of split-window, do this ...
(let ((subwin (display-buffer-in-atom-window
               (current-buffer)
               `((window . ,(get-buffer-window (current-buffer)))
                 (side . below)))))
  (with-selected-window subwin
    ;; do whatever you want with subwin
    )
  )

When the original window is deleted via a generic call to (delete-window), the subwindow also gets deleted.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.