emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RE: patch for optional inhibit of delete-other-windows(IDE feature)


From: klaus.berndl
Subject: RE: patch for optional inhibit of delete-other-windows(IDE feature)
Date: Tue, 29 Apr 2008 16:27:55 +0200

martin rudalics wrote:
>  > The compile-window is used to display all stuff like help-buffers,
>  compile- > grep-buffer etc...
> 
> Do you mean that C-h ... are not allowed to display the help buffer in
> the edit-area?  How do you achieve that?

By setting `temp-buffer-show-function' to the following ecb-function
which does this.
You see that it uses at the end the adviced `display-buffer' of ECB which
does the final trick, i.e. using the compile-window for all buffers
an ECB user has to customized being displayed in the compile window
(default is all help-buffers, the compile, grep and some others...)

-------
(defun ecb-temp-buffer-show-function-emacs (buf)
  ;; cause of running the hooks in `temp-buffer-show-hook' we must use
  ;; save-selected-window (s.b.). But maybe `display-buffer' calls
  ;; `ecb-toggle-compile-window' which completely destroy all windows and
  ;; redraw the layout. This conflicts with the save-selected-window.
  ;; Therefore we toggle the compile-window before the save-selected-window!
  (when (ecb-compilation-buffer-p buf)
    (ecb-layout-debug-error "ecb-temp-buffer-show-function-emacs: comp-buffer: 
%s"
                            buf)
    (when (and (equal (selected-frame) ecb-frame)
               (equal 'hidden (ecb-compile-window-state))
               ;; calling this from minibuffer (e.g. completions)
               ;; seems to cause problems
               (not (equal (minibuffer-window ecb-frame) (selected-window))))
      (ecb-layout-debug-error "ecb-temp-buffer-show-function-emacs: comp-win 
will toggled")
      (ecb-toggle-compile-window 1)))
  (save-selected-window
    (save-excursion
      ;; this call to `display-buffer' runs the adviced version of ECB which
      ;; always handles all the compile-window stuff if buf is a
      ;; compile-buffer in the sense of `ecb-compilation-buffer-p'.
      (let ((win (display-buffer buf)))
        (ecb-layout-debug-error "ecb-temp-buffer-show-function-emacs: win: %s, 
buf: %s"
                                win buf)
        (select-window win)
        (setq minibuffer-scroll-window win)
        (set-buffer buf)
        (run-hooks 'temp-buffer-show-hook)))))
-------

maybe you now get an impression how it works: ECB has its own display-buffer
version and this one is used in all places where necessary to display
the right buffer in the right window...

some years ago one of my problem was, that not all builtin functions
of Emacs which do displaying buffers seem to have used `display-buffer'
internaly - so probably ECB had the need to advice more functions as
necessary...

To make a long story short: It would be very very great if there is
a commitment that *each* command or function which has to display 
a buffer in a window uses internaly `display-buffer', because then
it would probably sufficient for ECB to patch this machanism (either
by adding a full featured display-buffer-function or by advicing
display-buffer itself).

What is the current state with this respect?


> 
>  > is customizable by mode and regexp which buffers should
>  > be automatically alwasy being displayed in the compile-buffer -
>  example: > When you do switch-to-buffer in one of the edit-windows
>  and you insert a > buffer which is customized to be displayed in the
>  compile-window then > ECB will switch to this buffer in the
>  compile-window (if it is displayed > in the current layout) - in
>  generell the advices of switch-to-buffer and > pop-to-buffer are one
>  of the most important ones currently because > the do all the needed
>  smartness to display the right buffer in the right > window...
> 
> Did you ever try to tackle these problems with `same-window-regexps'
> or `same-window-buffer-names'?  Though I suppose they are too fuzzy
> for 
> your purposes.

Indeed - i tried it a long long time ago but i gave up (i must admit
to understand this stuff in deep is not easy)

> 
>  > Redraw the ECB screen according to the layout set in
> `ecb-layout-name'. 
> 
> How do you get the structure needed for splitting windows into a
> layout - do you use the `window-tree' function?

No because the window-tree function is too young - ECB exists already
when Emacs 20 was used...

The basic mechanism is at follows:

ecb-redraw-layout-full performs all the layouting. For this it does
all the window-structure-independ stuff out-of-the-box and then it
calls a special layout-function `ecb-layout-function-<layoutname>'
which performs all the splits necessary for a certain layout...

the there is a macro `ecb-layout-define' which allows easily
programming new layouts, here is an example for using this macro:

-------
(ecb-layout-define "left4" left
  "This function creates the following layout:

   -------------------------------------------------------
   |              |                                      |
   |              |                                      |
   |              |                                      |
   |  Directories |                                      |
   |              |                                      |
   |              |                                      |
   |              |                                      |
   |--------------|                 Edit                 |
   |      |       |                                      |
   |      |       |                                      |
   |      |       |                                      |
   | Sour | Hist  |                                      |
   |      |       |                                      |
   |      |       |                                      |
   |      |       |                                      |
   -------------------------------------------------------
   |                                                     |
   |                    Compilation                      |
   |                                                     |
   -------------------------------------------------------

If you have not set a compilation-window in `ecb-compile-window-height' then
the layout contains no persistent compilation window and the other windows get a
little more place."
  (ecb-set-directories-buffer)
  (ecb-split-ver 0.5)
  (ecb-set-sources-buffer)
  (ecb-split-hor 0.5)
  (ecb-set-history-buffer)
  (select-window (next-window)))
-------

This results in a function ecb-layout-function-left4 which
is called from the `ecb-redraw-layout-full'-"framework".

ECB offers also an intercative layout-creation-engine where
a user can define own layouts with a specialized layout-creation-
frame - when the user is fine with its new layout he pressed
"save" and a new call to ecb-layout-define with all the necessary
splits etc. is stored in a file "user-layouts" which is loaded 
at starttime of ECB...

another topic: ECB automatically stores all split-window-* calls
and delete-window and delete-other-windows calls performed in the
edit-area (this is simply done by before-advices of these commands).
so after a full redraw ECB "replays" these stored split- and delete-
commands and voila: the edit-area has the same window-structure
as before... but it had cost me huge effort to implement this stable.

It would be very great if the object `save-window-configuration'
stores would be "readable" or "accessible" in a way so we could
restore only parts of a frame (in case of ECB the edit-area)...
Do not know the current state of Emacs with this respect?!

> 
>  > After
>  > this function the edit-window is selected which was current before
>  redrawing. > If no-buffer-sync is not nil then the ecb-buffers will
>  not be synchronized. If > ecb-windows-creator is not nil then it
>  will be used to draw the layout instead > of the standard layout. If
>  window-configuration-data is not nil it must be an > object returned
>  by `ecb-window-configuration-data' and will be used for > restoring
> the layout. 
> 
> Is `ecb-window-configuration-data' based on
> `current-window-configuration'?  In this case you always get
> edit-area, 
> special windows, and whatever have you in one big pot.  Do you trim
> away 
> windows you don't need then?

No, it return other informations but these informations are stored
extra in an after-advice of current-window-configuration in a
window-config-cache of ECB - and another aftre advice of
set-window-configuration uses this stored extra information...
To complex to describe all details here ;-)

Here is the docstring of ecb-window-configuration-data:

-------
Return current window configuration of the ecb-frame as a list with the
following structure:
1. The number of the edit-window if point is one of the edit-windows, nil
   otherwise
2. current point if one of the edit-windows is selected, nil otherwise.
3. Data of all edit-windows in form of a list: Everey listelement is a list
   again with first subelement is the buffer of an edit-window, second
   subelement is the `window-start' of this window, third is the
   `window-point' and fourth subelement is the result of `ecb-get-window-size'
   for this window. This data-list has the same ordering as
   `ecb-canonical-edit-windows-list'.
4. Data of the compile window or nil (if there is no compile-window visible):
   List with first elem is the buffer of the compile-window, second elem is
   current point of the compile-buffer if the compile-window is selected
   (otherwise nil) and third elem is the current height of the
   compile-window.
5. The window sizes of the ecb-windows as returned by
   `ecb-get-ecb-window-sizes'
-------

> 
>  > If emergency is not nil then all other args will be
>  > ignored and the layout will be redrawn like defined in the current
>  layout and > the edit-area will be unsplitted and will just contain
>  the buffer before the > emergency-redraw.
>  > ---
>  >
>  > Not important, you understand this function but what you see is,
>  there > are some parameter (e.g. NO-ECB-WINDOWS) which determine
>  what should be done. > This is quite long and compley function and
>  what it does is basically: It completely > cleans the whole
>  ECB-frame and then redraws exactly that window-layout which > is
> needed in the current context. 
> 
> IIUC the first thing we should provide is find a way to (i) squeeze an
> entire frame into a window and (ii) blow up an internal Emacs window
> to 
> a frame.  The only problems I see here are how to specify the internal
> window (saying the smallest internal window containing windows 10, 14
> and 17 seems tedious) and how to preserve identities of windows within
> such configurations (`set-window-configuration' is notorious for
> breaking the 'window overlay-property).

Ooops, sorry, but i haven't understand this paragraph..what do you 
want to say (maybe my english is to bad)?!

> 
>  >>I meant "select", for example, using `other-window'.  How do you
>  >>select
>  >>the compile-window or the other special ECB-windows when you're in
>  the >>edit-area?
>  >
>  > Ah, now i understand: I simple use `select-window' with right
>  window- > object...the window-object of the compile-window is always
>  stored > in a variable and the dedicated browsing windows are
>  selectable > by buffer-name...
> 
> ... and `other-window' always stays within one and the same group, I
> presume.  We then probably want a command `other-group' and bind it to
> C-x ... o.

other-window is adviced:

-------
(defecb-advice other-window around ecb-basic-adviced-functions
  "The ECB-version of `other-window'. Works exactly like the original function
with the following ECB-adjustment: The behavior depends on
`ecb-other-window-behavior'."
  (if (or (not ecb-minor-mode)
          (not (equal (selected-frame) ecb-frame)))
      (ecb-with-original-basic-functions
       ad-do-it)
    (let* ((count (if (ad-get-arg 0)
                      (ad-get-arg 0)
                    1))
           (o-w (ecb-get-other-window count)))
      (select-window o-w))))
-------

You see `ecb-get-other-window' computes the right other
window depending the context the user is. The behavior
of other-window is highly customizable by an option
`ecb-other-window-behavior' - here is the docstring:

-------
"*The behavior of ECB concerning getting an \"other window\".

The following settings are possible:

'all:

ECB will cycle through all windows of the ECB-frame or scroll simply
the next window in the ECB-frame, means it behaves like the original
`other-window' rsp. the original `other-window-for-scrolling'.

'only-edit:

ECB will only cycle through the edit-windows of ECB or only
scroll another edit-window. If the selected window is not an edit-window
then it behaves like with value 'all.

'edit-and-compile:

Like 'only-edit plus the compile window if any. If the
selected window is neither an edit-window nor the compile-window then it
behaves like with value 'all.

'smart:

With this setting ECB tries to choose the `other-window'-destination or the
\"other window\" to scroll in a smart and intuitive way: If point is in one of
the edit-windows and if the edit-area is splitted then always the \"next\"
edit-window is choosen \(whereas the next edit-window of the last edit-window
is the first edit-window)- if the edit-area is unsplitted then the
compile-window is used if there is one. In the context of an
`other-window'-call the ARG of `other-window' will be taken into account.

If one of the special ecb-windows is selected then always the \"next\"
ecb-window is choosen \(whereas the next ecb-window of the last ecb-window is
the first ecb-window). In the context of an `other-window'-call the ARG of
`other-window' will be taken into account. If there is only one ecb-window
then ECB considers also the edit-windows!

If the compile-window is selected then always the last selected edit-window
will be used unless `other-window' has been called with a prefix-argument
unequal 1.

If there is an active minibuffer:

Regardless of the allowed values above ECB handles the situation of an active
minibuffer during a call to `other-window' or `scroll-other-window' like
follows:

If the minibuffer-window is selected then ECB always chooses the window
`minibuffer-scroll-window' points to \(when this variable is set, otherwise
the compile-window or the last selected edit-window is choosen) when the
called command is called to choose the 1. next window \(always true for
scrolling another window or true when `other-window' called without prefix-arg
or with prefix-arg equal 1). Otherwise the window ARG steps away is choosen
\(in case of `other-window).

If there is an active minibuffer but the minibuffer-window is not selected
then `other-window' and `scroll-other-window' behave like the original
version.

In addition to the allowed values above the value of this option can also be a
function:

This function gets seven arguments:
1. A canonical list of all currently visible windows of the `ecb-frame'
2. A canonical list of all currently visible edit-windows
3. A canonical list of all currently visible ecb-windows
4. The window-object of the compile-window if there is any.
5. The minibuffer-window of the ECB-frame if there is an active minibuffer.
5. The result of the function `ecb-where-is-point' - see the documentation
   of this function for details.
6. An integer which indicates how many steps away from the current selected
   window the \"other-window\ is. Is nil when this function is called in
   another context then for `other-window'.
The function has to return a window-object which is then used as \"other
window\" for the command `other-window' or for scrolling another window
\(e.g. with `scroll-other-window').

This function has to handle all properly situations for itself.
`ecb-get-other-window-smart' is an example for such a function."
-------

Klaus




reply via email to

[Prev in Thread] Current Thread [Next in Thread]