Super User is a question and answer site for computer enthusiasts and power users. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I was wondering if there is a way to mark certain frames in a split window emacs session as inviolate to changing. I normally have 4 frames for sources files and 2-3 frames for other views such as compilation/grep-find/etc.
I would like to mark the latter frames somehow so that they will never be split or have their contents changed by emacs. This way if I click on a search result I don't have my compilation window splitting and a source file inserted.
I want any source files to go in my source windows and to stay out of my misc-view windows. Is there a way to do this?

share|improve this question
up vote 1 down vote accepted

Yes, there is a way to do this, but I don't think it will be easy. A quick look through frame-related functions and variables confirmed my belief that there's no easy fix here. The problem is that Emacs would not know what to do once these frames are the only remaining frames, and something needed to be done to/with them.

I think it would be possible to code up a package that advised all of the low-level frame manipulation functions such that some frames would remain untouched by any operation, but that would require identifying and interpreting each of those low-level functions. I think a better approach (unless you're an elisp wizard) would be to identify the functions that you use that annoy you in this manner, and see if there's a common function or group of functions that they use to determine which frame to display their output in, and then set out to change that behavior.

I would probably use a frame parameter (frame-parameter and modify-frame-parameters) to store whether or not a given frame was inviolate. This could be set manually by you, or perhaps at the end of the function that populates the frame with whatever data (through the use of a wrapper function or (more likely) defadvice). Then find a function that changes one of them and look at its source. What function(s) did it call to determine which frame to use? Modify and/or advise those functions (or maybe something called by those functions) to not consider frames with this certain parameter set. As a special case, if there are no other frames available, make a new frame and return that.

You could also have several classes of frames (e.g. source frame, compilation/errors frame) and allow some of these to be re-used by certain functions but not others. How complex you make it, really, is up to you and your imagination.

Anyhow, it looks at first blush to be very doable but non-trivial.

Now, having said all of that, there is a package out there that may help you get closer to what you want: One-on-One Emacs. It don't know if it protects frames the way you want to, though. And from the description it seems like it re-defines a lot of core functions, rather than advising them, which could make it extremely version-specific (that's just a feeling I got reading his description; I didn't look at the code to see if that is what actually is happening).

Good luck!

share|improve this answer
Thanks for the advice Joe. After I looked through the emacs frame functions and didn't find anything I was afraid something like this would be necessary but I didn't know where to start. I'll check out one-on-one emacs as well. – Andrew Myers Jan 25 '10 at 14:26
pop-to-buffer is the function that makes a window split and a new file show in the other half. If you redefine pop-to-buffer (first save the original pop-to-buffer so you can recover it internally), you can make a version to refuses to split windows in certain frames. – Justin Smith Jan 30 '10 at 1:54
On further research, (set-window-dedicated-p (selected-window) t) will make a window inviolable, so pop-to-buffer, or even an explicit buffer change command will not change the buffer displayed. You can bind this to a keybinding or run it via M-: – Justin Smith Jan 30 '10 at 2:03

One option could be looking into how gdb-many-windows works - this mode is very aggressive about preserving a specific window layout.

Also, it is possible to save a frame / window configuration to a register, and to retrieve that configuration from the register later.

Third option: here is a solution in elisp (you could just evaluate it in the scratch buffer to try it, and add it to your .emacs if you like it)

(define-key global-map "\C-cs"
  (lambda ()
    (message "saving current frame and window layout")
    (setq my-favorite-frame-setup (current-frame-configuration))))
(define-key global-map "\C-cf"
  (lambda ()
    (message "restoring frame and window layout")
    (set-frame-configuration my-favorite-frame-setup))))
Set up all your frame and window sizes and positions the way you like it, and type Control-c s, and your layout is stored. Then type Control-c f to recover it if the layout gets changed. This includes all window sizes, number of window splits, and what buffer is in each window, and where each window is on your desktop.

I made these key bindings just to reply to this question just now, but I like them enough I am actually going to be keeping them in my .emacs now, thanks for the great question.

share|improve this answer
Granted this does not do the specific thing you asked for - as Joe said above that may be non-trivial, but this is a workaround. – Justin Smith Jan 30 '10 at 1:52

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .