Before this change, running a dired operation on many files displayed
a pop-up window *below* the dired buffer and immediately *above* the
minibuffer. This is the most convenient place to display a list of
file names, because it is near the minibuffer where the user types more
input for the command (a shell command or a directory to copy files to).
But now this list of files is displayed somewhere else - on the top of the
side window. Thus now this list is as far for minibuffer as possible.
This is because `dired-pop-to-buffer' doesn't call `split-window' anymore
that used to split windows vertically even on a wide-screen display.
This is the same problem as I reported in
http://thread.gmane.org/gmane.emacs.devel/93011/focus=94236
i.e. we need a special option to split windows vertically
where necessary.
--
Juri Linkov
http://www.jurta.org/emacs/
But that's what `split-width-threshold' is meant for. Does
`dired-pop-to-buffer' DTRT when you set this to nil?
martin
Yes, it works perfectly for Dired when `split-width-threshold' is nil.
But the problem is that I prefer a wide-screen configuration with
horizontally split windows, so I can't set `split-width-threshold' to nil.
There are a few exceptions where obeying non-nil `split-width-threshold'
is not desirable. One exception is displaying a list of files in Dired,
and another is displaying the Calendar window. Maybe there are a few
of others.
Fine.
> But the problem is that I prefer a wide-screen configuration with
> horizontally split windows, so I can't set `split-width-threshold' to nil.
>
> There are a few exceptions where obeying non-nil `split-width-threshold'
> is not desirable. One exception is displaying a list of files in Dired,
> and another is displaying the Calendar window. Maybe there are a few
> of others.
So the only thing we have to decide is whether we want to hardcode this
in `dired-pop-to-buffer' (and for the Calendar window and others) or
make it optional.
martin
I can't image a situation when someone will want to display a narrow
window on a full-height side window. At least I think currently we should
restore the old behavior when these commands displayed a narrow window
below the original window instead of a side window.
I think a general rule of thumb for finding all such cases should be the
following: when there is a call to `fit-window-to-buffer' after calling
`pop-to-buffer' then split windows vertically because otherwise
`fit-window-to-buffer' makes no sense since it adjusts the window height
and can't do this on a full-height horizontally split window.
For buffers showing information directly linked to the minibuffer (such
as Dired's file list, and maybe also *Completions*), it might make sense
to make an exception, indeed.
OTOH, I don't understand why you feel the same way for the Calendar window.
Stefan
The Calendar window has a fixed height of 7 lines, and when
`split-width-threshold' is nil or the current frame is not wide,
it creates a nice small window with the height exactly fit
into these 7 lines.
But Calendar in a horizontally split window is currently very ugly:
there is small text part at the beginning of the window with almost
70 empty lines below.
And if the frame is wide and you set split-width-threshold to nil you
get a silly window with only 75 columns used and the rest is empty.
Looks just as ugly to me. The advantage of the "side window" layout is
that when I then pop up the diary buffer (as I always end up doing), it
makes good use of those 70 lines, whereas with your layout, the diary
buffer doesn't make use of those extra columns.
I'm not saying you're wrong, but just that this is not as clear cut as
the "dired files list".
Stefan
I did this for `dired-pop-to-buffer'.
> I think a general rule of thumb for finding all such cases should be the
> following: when there is a call to `fit-window-to-buffer' after calling
> `pop-to-buffer' then split windows vertically because otherwise
> `fit-window-to-buffer' makes no sense since it adjusts the window height
> and can't do this on a full-height horizontally split window.
Good suggestion. I found the following candidates:
`Electric-pop-up-window', `ibuffer-confirm-operation-on',
`disabled-command-function', `proced-send-signal',
`fancy-startup-screen', `display-time-world', `widget-choose'.
Can someone comment on these? We might also have to consider windows
affected by `temp-buffer-resize-mode'. I'll leave it to Carsten to
figure out what's best for `org-mode'.
As for `calendar' I share Stefan's POV ...
martin
Thanks, it now works for the one-window configuration.
However, when windows are already split horizontally,
it still doesn't work like it always worked by displaying
a small window below. As you can see in the code removed
from `dired-pop-to-buffer' it used to call `split-window'
explicitly:
(setq w2 (split-window window
(max window-min-height
(- (window-height window)
(1+ (max window-min-height target-lines))))))
We need a new special function in window.el that will do something
similar.
>> I think a general rule of thumb for finding all such cases should be the
>> following: when there is a call to `fit-window-to-buffer' after calling
>> `pop-to-buffer' then split windows vertically because otherwise
>> `fit-window-to-buffer' makes no sense since it adjusts the window height
>> and can't do this on a full-height horizontally split window.
>
> Good suggestion. I found the following candidates:
>
> `Electric-pop-up-window', `ibuffer-confirm-operation-on',
> `disabled-command-function', `proced-send-signal',
> `fancy-startup-screen', `display-time-world', `widget-choose'.
>
> Can someone comment on these?
`proced-send-signal' is a recent change:
2009-01-03 Roland Winkler <Roland....@physik.uni-erlangen.de>
* proced.el (proced-send-signal):
Use fit-window-to-buffer instead of dired-pop-to-buffer.
Roland, maybe we need a general function for both Proced and Dired?
> We might also have to consider windows affected by
> `temp-buffer-resize-mode'. I'll leave it to Carsten to figure out
> what's best for `org-mode'.
>
> As for `calendar' I share Stefan's POV ...
Sorry, as a user of a wide-screen configuration I can't use
such layout. Every time I run `calendar' I need manually fix
the layout by typing something like `C-x o C-x 2 C-x o C-x left C-x -'.
This is a real hassle! For users who don't want a silly tall
mostly empty 70-line window we should have an option like
`dired-shrink-to-fit' to always show a 7-line window.
This layout also works well with the diary buffer:
+------------+------------+
| | |
| | |
| diary | |
| | |
| | |
| | |
| | |
| | |
+------------+ |
| | |
| calendar | |
| | |
+------------+------------+
Please see the code in calendar.el that creates such standard layout
for non-wide-screen configurations (i.e. when there is no right window).
I think we should keep exactly the same logic for wide-screen configurations,
i.e. treating the creation of such small low windows as if there is no
existing side window.
Usually this worked correctly due to the fact that directory buffers
were sufficiently high. But for `pop-up-frames' non-nil addicts this
was not necessarily the right behavior.
Anyway, I suppose you mean something like
(defun dired-pop-to-buffer (buf)
(let* ((split-height-threshold 8)
split-width-threshold
(buffer (get-buffer-create buf))
(window (window--try-to-split-window (selected-window))))
(if window
(progn
(select-window window)
(set-window-buffer window buffer))
(pop-to-buffer buffer))
(when dired-shrink-to-fit
(fit-window-to-buffer nil nil 1))))
> Please see the code in calendar.el that creates such standard layout
> for non-wide-screen configurations (i.e. when there is no right window).
> I think we should keep exactly the same logic for wide-screen configurations,
> i.e. treating the creation of such small low windows as if there is no
> existing side window.
Would the above code handle that?
martin
Thank you, this works almost ideally. The only problem I've encountered
is that sometimes it resizes existing windows:
+------------+------------+ +------------+------------+
| | | | | |
| | | | | |
| dired | other2 | | dired | other2 |
| | | | | |
| | | +------------+ |
| | | | file list | |
| | | ===> +------------+ |
+------------+ | | | |
| | | | | |
| other1 | | | other1 | |
| | | | | |
| | | | | |
+------------+------------+ +------------+------------+
Please notice how the upper border of the lower window (other1)
was moved up. I think it should keep the existing configuration
and create a new window at the cost of space from the original
dired buffer like this:
+------------+------------+ +------------+------------+
| | | | | |
| | | | | |
| dired | other | | dired | other |
| | | | | |
| | | | | |
| | | +------------+ |
| | | | file list | |
+------------+ | ===> +------------+ |
| | | | | |
| other | | | other | |
| | | | | |
| | | | | |
+------------+------------+ +------------+------------+
As I can see currently `fit-window-to-buffer' always takes space
from the bottom window, but we need it from the top window.
>> Please see the code in calendar.el that creates such standard layout
>> for non-wide-screen configurations (i.e. when there is no right window).
>> I think we should keep exactly the same logic for wide-screen configurations,
>> i.e. treating the creation of such small low windows as if there is no
>> existing side window.
>
> Would the above code handle that?
I believe it would handle these cases. Maybe it is possible to create
a single function e.g. `pop-to-buffer-below' that will display a new window
below from the current window taking its space.
Not really. `fit-window-to-buffer' uses `enlarge-window' which is our
idea of Robin Hood - stealing from the large, giving to the small.
An impractical solution is to make all other windows fixed-height and do
the fit. This will almost certainly fail since deleting the window may
give its space to _any_ of its siblings.
A more practical solution would be to implement something like the
following: When a new window is created, remember the OLD _and_ the NEW
window configuration in the window's parameters. When the window is
eventually deleted and the actual configuration "sufficiently" resembles
the NEW configuration, restore the OLD configuration.
martin
Looking at this again, I believe what you want is to invert the order of
stealing and giving as in the attached patch. Might have side-effects
elsewhere.
martin
When I changed proced to use fit-window-to-buffer, this change was
inspired by the changed code of dired-pop-to-buffer. Later I
realized that this doesn't always give the old behavior of
dired-pop-to-buffer which in my opinion was more appropriate than
the new code (but I hadn't found time yet to look into this more
carefully). So yes, I agree that probably it would be best to have a
function that gives the old behavior which can be used by both dired
and proced. And maybe the new function will be useful for other
packages, too.
Roland
> I can't image a situation when someone will want to display a narrow
> window on a full-height side window. At least I think currently we should
> restore the old behavior when these commands displayed a narrow window
> below the original window instead of a side window.
I did this for `dired-pop-to-buffer'.
> I think a general rule of thumb for finding all such cases should be the
> following: when there is a call to `fit-window-to-buffer' after calling
> `pop-to-buffer' then split windows vertically because otherwise
> `fit-window-to-buffer' makes no sense since it adjusts the window height
> and can't do this on a full-height horizontally split window.
Good suggestion. I found the following candidates:
`Electric-pop-up-window', `ibuffer-confirm-operation-on',
`disabled-command-function', `proced-send-signal',
`fancy-startup-screen', `display-time-world', `widget-choose'.
Can someone comment on these? We might also have to consider windows
affected by `temp-buffer-resize-mode'. I'll leave it to Carsten to
figure out what's best for `org-mode'.
As for `calendar' I share Stefan's POV ...
martin
... you mean the `other-window' argument ...
> This should be
> generalized so as to be able to say "preferably in the selected-window"
> (to provide basically the behavior of switch-to-buffer), or "preferably
> in selected-frame", or "preferably close to the minibuffer". The first
> 2 are available *to the user* via the `same-window' and `same-frame'
> attribute that they can set in special-display-buffer-names, but they
> should also be available to the program (and overridable by the user).
But none of these provide the behavior wanted by Juri. He wants to
split the selected window which runs counter to the `pop-up-frames'
non-nil ideology. So I suppose we need a "preferably splitting the
selected window" value which can be overridden by `pop-up-frames'.
martin
It might be better to use (not (window-full-width-p window)) here.
Comparing `frame-width' and `window-width' is not always reliable.
> If the current window is not the full frame width, I do not adjust its
> size because it would shink other windows along with it.
IIUC you mostly use a
(delete-other-windows)
(split-window-vertically)
(org-switch-to-buffer-other-window ...)
paradigm which avoids most of the pitfalls raised by Juri. So I think
you are not really bothered by the problems discussed here.
martin
The preferred location of the window can be expressed by the new parameter
proposed by Stefan: in addition to `same-window' and `same-frame' it
could also support a parameter like `fit-below' with the meaning
of creating a new window below from the current window with calling
`fit-window-to-buffer' on it.
Maybe a simpler solution is to change `fit-window-to-buffer'
so in such configurations when windows are split vertically
(the correct treating of horizontally split windows
is already provided in dired-pop-to-buffer you sent recently)
it will temporarily switch the current window to the upper window
and call `enlarge-window' from the upper window, thus resizing
the right border.
The change of `enlarge-window' _is_ simple - only the diff appears
complicated. But we'd have to decide whether it's OK to steal from/give
to the previous window when enlarging a window. (It makes a difference
only when we have at least three windows in a row or column.)
> is to change `fit-window-to-buffer'
> so in such configurations when windows are split vertically
We cannot change `fit-window-to-buffer' - it's used, for example, by
`resize-temp-buffer-window', not necessarily connected to splitting
windows at all.
> (the correct treating of horizontally split windows
> is already provided in dired-pop-to-buffer you sent recently)
> it will temporarily switch the current window to the upper window
> and call `enlarge-window' from the upper window, thus resizing
> the right border.
We'd have to do this within the function that splits the Dired window.
I recently rewrote `fit-window-to-buffer' but still don't understand it
completely - in particular the (enlarge-window 1) loop. Within that
loop we'd have to continuously switch to the Dired window in order too
enlarge it. I'd rather avoid such hairy switches.
martin
That's not what I meant. The old `dired-pop-to-buffer' did split the
window regardless of what `pop-up-frames' was set to and Juri wants to
get the old behavior back. The question is whether we want
`pop-up-frames' non-nil override that. Currently, `pop-up-frames'
non-nil does bring up a separate frame.
martin
I think either behavior is acceptable as long as it can be overridden by
the user (via special-display-buffer-names). Reproducing the previous
behavior (of ignoring pop-up-frames) is probably the safer option, and
it at least would suit my use-pattern better as well (I do have
pop-up-frames set to t but would rather not have a new frame created for
those dired-lists unless I explicitly set one up in
special-display-buffer-names with a specific geometry).
Stefan
I've just looked at the old behavior from the December CVS state,
and noticed that it behaved more conveniently than we are currently
discussing. It displayed a list of files immediately above the
minibuffer. This is convenient because when the minibuffer says:
! on * [5 files]:
then a list of these 5 files is very near above, so there is no need
to search for this list elsewhere on the current frame. Maybe we
should have a special function to display a buffer above the minibuffer
(e.g. `pop-to-buffer-above-minibuffer')?
But when you have vertically-split windows and the *dired* buffer
appears on top of the frame, there may be another window between the
*dired* window and the *Marked files* window.
martin
Maybe we should have `special-display-popup-frame' handle yet another
phony parameter, say 'split-window, making it split the selected window
if that is set.
martin
Not sure if `split-window' is really what we want. I thought in this
case, we want `near-minibuffer'. But, yes, I basically agree.
Note that the parameter should be passed from the code, not from
special-display-buffer-names (which is a config variable).
Stefan
And that's good: the list should be close to the question, not close to
the dired buffer.
Stefan
The list of files closer to the minibuffer is better than closer to the
dired buffer because the minibuffer is the place that the user looks at
while typing command's arguments for these files.
Unless our user uses a separate minibuffer-only frame.
martin
If the dired buffer were not needed while asking the question, dired
could temporarily display that list in the dired window itself and
switch back to the dired buffer afterwards. But I never use dired.
What about putting this in `pop-up-windows'? Possible values are:
nil do not allow popping up windows
'this selected window
'below below selected window
'below-split split selected window vertically
'right right of selected window
'right-split split selected window horizontally
'bottom use window near bottom of frame
'bottom-split split window near bottom of frame
t allow popping up windows
If an application (like dired) sees that this variable is t (the
default) it may ask to pop up the window wherever it's most suitable.
Otherwise, it has to respect the value chosen by the user. Like
(let ((pop-up-windows (if (eq pop-up-windows t)
'bottom-split
pop-up-windows)))
(display-buffer ...))
martin
> nil do not allow popping up windows
> 'this selected window
> 'below below selected window
> 'below-split split selected window vertically
> 'right right of selected window
> 'right-split split selected window horizontally
> 'bottom use window near bottom of frame
> 'bottom-split split window near bottom of frame
> t allow popping up windows
> If an application (like dired) sees that this variable is t (the
> default) it may ask to pop up the window wherever it's most suitable.
> Otherwise, it has to respect the value chosen by the user. Like
> (let ((pop-up-windows (if (eq pop-up-windows t)
> 'bottom-split
> pop-up-windows)))
> (display-buffer ...))
But how would the user override this behavior in a way that can depend
on the buffer being shown (i.e. via special-display-buffer-names)?
Stefan
In that case the right behavior depends on many things (e.g. depends on
where the minibuffer frame is located w.r.t to selected frame). To get
this right most of time will require a lot of heuristic code, so we may
as well punt on it and decide that any behavior that's OK for
non-minibuffer-only situations is OK for minibuffer-only situations
as well.
Stefan
Actually Dired already displays that list in the Dired window itself
when the list is too large and fills the whole window. But it would be
bad to replace the Dired buffer with a small list with 2-3 filename lines
and a lot of empty lines. So it is better to display a separate window
near the minibuffer without empty lines using `fit-window-to-buffer'.
Reasonable. I suppose we should try to stay in the same "column" when
frames are divided horizontally. Any fallback we should use when a
bottom window can't be split? Split the selected one?
martin
Customizing `pop-up-windows' would give (1) a general preference where
and how `display-buffer' should pop up windows, and (2) a possibility to
override decisions made by applications like dired on where and how to
pop up windows.
`special-display-buffer-names' and `special-display-regexps' would be
handled as usually, before checking `pop-up-windows'. If we want, we
can provide things like 'window-below or 'window-at-bottom as phony
parameters as suggested earlier.
All this is also a question of where and how to document behavior best.
I tried to understand and document the special-display stuff but am
pretty sure that I still haven't got it right yet. I strongly doubt
that anyone but you really knows how this is supposed to work.
OTOH `pop-up-windows' has a one line doc-string, so I thought we could
try that first.
martin
> Customizing `pop-up-windows' would give (1) a general preference where
> and how `display-buffer' should pop up windows, and (2) a possibility to
> override decisions made by applications like dired on where and how to
> pop up windows.
> `special-display-buffer-names' and `special-display-regexps' would be
> handled as usually, before checking `pop-up-windows'. If we want, we
> can provide things like 'window-below or 'window-at-bottom as phony
> parameters as suggested earlier.
Actually, those phony params aren't right. Now that you made me think
some more about it, they're all mutually exclusive, so we really only
want one such param whose value could be `same-frame', `same-window',
or `near-minibuffer'. Those same values could be used for
pop-up-windows.
Stefan
While at this topic, could you also suggest a good parameter for the
name of the current buffer to define where to display a new buffer.
What I mean is that, for example, after clicking a link to the source file
from the *Help* buffer, I want the source code (c. or .el) buffer to be
displayed in the same window replacing the *Help* buffer. Since the name
of the source code buffer can be anything, the only definite parameter is
the name of the last buffer displayed in the current window ("*Help*").
Creating a full-width window would fit more information, and the
window width will be the same as the width of the minibuffer's window.
This will more logically connect a new window to the minibuffer
that is necessary for dired files and completions:
+------------+------------+
| | |
| | |
| dired | other |
| | |
| | |
+------------+ |
| other | |
| | |
+------------+------------+
| file1.ext file2.ext |
| file3.ext file4.ext |
+-------------------------+
| Prompt: command |
+-------------------------+
I think this would be the best layout, but not sure is it possible
to create it using splitting from the initial configuration?
+------------+------------+
| | |
| | |
| dired | other |
| | |
| | |
+------------+ |
| other | |
| | |
| | |
| | |
| | |
+------------+------------+
| Prompt: command |
+-------------------------+
Not sure 'bout that. Probably special-display-buffer-names is not the
bext place to use for that kind of information.
Stefan
Not really. Creating windows anew breaks the 'window property of
overlays. ISTR that Lennart has some code to fix that, but the overhead
may be considerable since you have to investigate all overlays and most
of them usually don't have the 'window property. Here I simply split
the root window to get the effect you mean. In any case, restoring the
previous configuration when the window is no more needed is not entirely
trivial either.
I suppose, for the moment we have to split the "other" window below
instead. That is, check if there is a window with the same left edge as
the dired window and the maximum bottom edge of all windows on this
frame. If that window cannot be split because it's too small or fixed
height, try to split the selected window (the dired window) instead.
martin
`display-buffer' and `pop-to-buffer' behave "as usual" as long as the
default values for `pop-up-windows', NOT-THIS-WINDOW, and OTHER-WINDOW
are used. An application calling `display-buffer' or `pop-to-buffer'
can specify the preferable window to split by setting NOT-THIS-WINDOW or
OTHER-WINDOW appropriately. Users can specify their preferences (and
override the application) by setting `pop-up-windows' appropriately.
martin
I think this is post-23.1.
Stefan
This might be good for post-23.1, but the reported annoyance is still here,
so we need just to restore the old 22.1 behavior of `dired-pop-to-buffer'.
Martin, do you think this is possible without reverting `dired-pop-to-buffer'
to pre-December 2008 state, and making necessary changes in window.el
thus providing the same behavior that was in `dired-pop-to-buffer'?
`dired-pop-to-buffer' could bind `split-window-preferred-function' to a
function that tries to always split the selected window instead of
whatever window was chosen by `display-buffer' but that would override
any user customizations of `split-window-preferred-function'.
We could also provide a variable `split-window-preferred-window', nil by
default, which the window choosing mechanism of `display-buffer' would
respect if bound to some live window. And we could turn this variable
into an option (now or later).
martin
We could compare `split-window-preferred-function' with its default value
and override it in dired only when it has the default value.
Otherwise we could define a new option `dired-split-window-preferred-function'.
> We could also provide a variable `split-window-preferred-window', nil by
> default, which the window choosing mechanism of `display-buffer' would
> respect if bound to some live window. And we could turn this variable
> into an option (now or later).
Do you mean `split-window-preferred-window' as a user-defined value
that replaces the `window' argument of `split-window-preferred-function'?
It would be more difficult to document such behavior than to implement it.
> Otherwise we could define a new option `dired-split-window-preferred-function'.
Didn't you cite some other package that wanted such a thing?
>> We could also provide a variable `split-window-preferred-window', nil by
>> default, which the window choosing mechanism of `display-buffer' would
>> respect if bound to some live window. And we could turn this variable
>> into an option (now or later).
>
> Do you mean `split-window-preferred-window' as a user-defined value
> that replaces the `window' argument of `split-window-preferred-function'?
Yes, provided `split-window-preferred-function' then still wants such an
argument. I'd simply check whether `split-window-preferred-window' is a
live window that can be split by `split-window-preferred-function'. If
not, I'd proceed in the usual way. Later on, we could allow as value of
`split-window-preferred-window' also a function that computes such a
window on-the-fly.
martin
Why would it override it? It would of course bind
split-window-preferred-function to a function that selects the right
window and then calls the previous value.
Stefan
Maybe you can come up with some advanced technique to do that but here I
would have to define a variable to save the current (user provided)
`split-window-preferred-function' and call the function I save there
within the body of the function provided by dired. Hence an extra
variable would be needed anyway and I suppose it's easier to define that
in window.el rather than in all packages that want to change the window
to split (IIRC Calendar was one of these).
martin
Yes, Proced, Calendar, etc. I believe it is possible to define
one common splitting function (that finds the right window to split
and splits it vertically) for all these packages in window.el,
but I still think even this common function should be customizable.
> Maybe you can come up with some advanced technique to do that but here I
> would have to define a variable to save the current (user provided)
> `split-window-preferred-function' and call the function I save there
> within the body of the function provided by dired.
I'd use something like
(lexical-let ((oldfun split-window-preferred-function))
(let ((split-window-preferred-function
(lambda () (with-selected-window TOTO (funcall oldfun)))))
BLABLA))
> Hence an extra variable would be needed anyway and I suppose it's
> easier to define that in window.el rather than in all packages that
> want to change the window to split (IIRC Calendar was one of these).
The above coding should be close to "standard practice" for locally
rebinding a *-function variable. The "extra variable" doesn't matter,
it's not like we count variables.
Maybe what you're getting at is that we should make a hook to influence
the window-choice. Maybe so. But it doesn't seem urgent.
Stefan
We probably need something like in the attached patch but my knowledge
of closures within Elisp is very limited.
> The above coding should be close to "standard practice" for locally
> rebinding a *-function variable. The "extra variable" doesn't matter,
> it's not like we count variables.
>
> Maybe what you're getting at is that we should make a hook to influence
> the window-choice. Maybe so. But it doesn't seem urgent.
I was aiming at an extra variable to work around "advanced techniques"
like closures. `lexical-let' doesn't even indent reasonably :-(
martin
That looks fine.
> I was aiming at an extra variable to work around "advanced techniques"
> like closures.
Closures are (should be) bread&butter; not "advanced".
> `lexical-let' doesn't even indent reasonably :-(
I don't know of any such bug, so please give details.
Stefan
It won't indent correctly from scratch. I do have to load the CL
library first which hardly qualifies as bread&butter ;-)
martin
Is your patch intended to fix a problem I reported? I tried it and
it makes the current state worse. It works incorrectly even in the
one-window configuration - it splits it horizontally and displays
a list of files in a side window.
However, when I replaced
(funcall old-fun)
with
(funcall 'split-window-vertically)
in your patch, it works perfectly in all configurations I tried.
Hopefully.
> I tried it and
> it makes the current state worse. It works incorrectly even in the
> one-window configuration - it splits it horizontally and displays
> a list of files in a side window.
Did you try it after applying my patch for window.el?
martin
Yes, with your patch for window.el and in a frame wider than 160 columns.
My bad. Does the attached patch give better results?
martin
It is no much better than your previous patch - when windows are already
split horizontally, it displays a list of files in the side window instead
of vertically splitting the dired buffer's window and creating a new
window below it.
I still think `split-window-vertically' is more appropriate because
in a dired buffer it should unconditionally split the original window
vertically. In such situations `split-window-sensibly' is
the wrong method
with the wrong technique
It displays a new window
in the wrong place
at the wrong time
For the wrong reason and
the wrong rhyme
On the wrong day of
the wrong week
Wrong
Wrong
Kto-to majskij prazdnik otmechajet ;-)
BTW, here we call a bridge day "Fenstertag" (window day) and since we
didn't have any bridge day this week it _was_ the wrong day of the wrong
week indeed ...
I don't have any problems hard-coding `split-window-vertically' in
`dired-pop-to-buffer' but:
(1) `split-window-sensibly' with `split-width-threshold' nil _should_ do
`split-window-vertically' in the first place. If it doesn't, I have
a bug somewhere and must fix that.
(2) Someone might want `split-window-sensibly' do something special for
dired buffers.
So please try to debug this and tell me why it doesn't split the window
vertically with a dired-window-only-frame configuration in the first
attempt. It DTRT here for me.
martin
PS: It does not DTRT when there's another window below because it does
not restore the original window layout when the temporary window is
closed. But that's another story ...
:-)
> I don't have any problems hard-coding `split-window-vertically' in
> `dired-pop-to-buffer' but:
>
> (1) `split-window-sensibly' with `split-width-threshold' nil _should_ do
> `split-window-vertically' in the first place. If it doesn't, I have
> a bug somewhere and must fix that.
>
> (2) Someone might want `split-window-sensibly' do something special for
> dired buffers.
>
> So please try to debug this and tell me why it doesn't split the window
> vertically with a dired-window-only-frame configuration in the first
> attempt. It DTRT here for me.
I tried to debug this. With your latest patch it works correctly
with a dired-window-only-frame configuration, but fails when
there are two horizontally split side-by-side windows with a dired
buffer in one of them. It displays a list of dired files at the top
of another side window.
split-window-sensibly has three `or' branches:
1. Split window vertically.
In my case this branch is not selected because my window-height (79)
is less than split-height-threshold (80).
2. Split window horizontally.
This branch is not selected since dired-pop-to-buffer sets
split-width-threshold to nil (this is ok).
3. If the selected window is the only window on its frame and is
not the minibuffer window, try to split it vertically.
This branch is not selected since the dired buffer's window is
not the only window on its frame.
So display-buffer displays a list of dired files in the existing
side window.
I see one way to fix this - it is necessary to force
the first branch to be selected. It works when I tried
the following lambda in dired-pop-to-buffer:
(lambda ()
(let ((split-height-threshold 0)
(split-width-threshold nil))
(with-selected-window old-window (funcall old-fun))))
Setting split-height-threshold to 0 forces the vertical splitting.
Setting split-width-threshold to nil prevents the horizontal splitting
when the vertical splitting is not possible (the window is not splittable).
On my display this amounts to setting `split-height-threshold' nil.
> So display-buffer displays a list of dired files in the existing
> side window.
>
> I see one way to fix this - it is necessary to force
> the first branch to be selected. It works when I tried
> the following lambda in dired-pop-to-buffer:
>
> (lambda ()
> (let ((split-height-threshold 0)
> (split-width-threshold nil))
> (with-selected-window old-window (funcall old-fun))))
>
> Setting split-height-threshold to 0 forces the vertical splitting.
> Setting split-width-threshold to nil prevents the horizontal splitting
> when the vertical splitting is not possible (the window is not splittable).
You convinced me.
Thanks, martin.
`lexical-let' is specific to Emacs. Closures are not.
`lexical-let' is a hack. Closures are not.
Stefan
That's precisely what I had in mind but was afraid to say.
martin
As a matter of fact, we do have to override the users' customizations
here just as Juri suggested earlier. Suppose a user has set
`split-window-preferred-function' to the standard option "horizontally"
which always splits a window horizontally. Then `dired-pop-to-buffer'
simply cannot get a vertical split when it calls the original
`split-window-preferred-function'. So we probably have to do this as in
the attached patch :-(
martin
Thank you! Could you also fix Proced and Calendar?
I attached a similar patch for `proced-send-signal'. I don't know what
to do about `proced' itself. Roland what do you think?
martin
I suppose you mean the call in `calendar-basic-setup' here. In this
case you probably want to split the largest or LRU window vertically
even if your customized settings would imply a horizontal split. But
you don't insist on splitting the selected window. Right?
Any opinions, Glenn?
martin
What do you mean by "proced itself"? Only proced-send-signal should
behave analogous to dired-pop-to-buffer.
Roland
I meant whether `proced' which uses `pop-to-buffer' has any preferences
about where and how to pop up that buffer.
martin
I see. I have never much thought about that. If anyone has some
argument why it might be better that Proced used something else
instead of a simple call of pop-to-buffer, I'd be happy to use some
appropriate code. Otherwise I suggest to keep it the way it is now
(or wait till after the next release). Certainly, Proced is
different from Dired in the sense that normally one will have only
one such buffer.
Roland
> I suppose you mean the call in `calendar-basic-setup' here. In this
> case you probably want to split the largest or LRU window vertically
> even if your customized settings would imply a horizontal split. But
> you don't insist on splitting the selected window. Right?
>
> Any opinions, Glenn?
Hi; I haven't been following this, but after a quick skim of the
(long) thread, I think neither the current nor the proposed behaviour
is ideal (it seems to be a choice between getting the height wrong or
the width wrong), but I prefer the current one. I'd rather leave it as
is for now, and look to improve it after 23.1. Thanks.
We should refrain from using anything else than just a plain
`pop-to-buffer', except for those cases where it is clearly problematic.
Stefan
It is unfortunate that no one yet paid attention to the Calendar's
treatment of the wide-screen configuration. Since now we have
a new smart window splitting, it produces very bad results on such
configurations - `M-x calendar' displays an ugly 70-line window
instead of a narrow 7-line window that fits nicely to the contents
of the Calendar buffer. That's because assumptions about the
behaviour of `display-buffer' in `calendar-basic-setup' and
`calendar-generate-window' are now invalid.
It seems a fix is not as simple. The function `calendar-generate-window'
comes into play and doesn't adjust the window to fit the displayed calendar
in horizontally split windows. The condition (not (window-full-width-p))
prevents calling `fit-window-to-buffer':
(if (or (one-window-p t) (not (window-full-width-p)))
;; Don't mess with the window size, but ensure that the first
;; line is fully visible.
(set-window-vscroll nil 0)
;; Adjust the window to exactly fit the displayed calendar.
(fit-window-to-buffer nil nil calendar-minimum-window-height))
Removing (not (window-full-width-p)) fixes this, but I don't know if this
change has some side effect.
Indeed, with its Dired-like keybindings it is still different from Dired
in regard to displaying a Proced window itself where it is more like
a Buffer List (`C-x C-b'). So e.g. as it's easy to add "*Buffer List*"
to `same-window-buffer-names', it's easy to add "*Proced*" as well
and to do other standard customizations allowed by `pop-to-buffer'.
This is unlike a non-standard treatment of displaying a window with
a list of selected items to process. I think no change is needed
for `pop-to-buffer' that displays a Proced window.
> Removing (not (window-full-width-p)) fixes this, but I don't know if this
> change has some side effect.
Often (not (window-full-width-p)) is used as a round-about and confusing
way to check whether resizing is safe (in the sense that it doesn't
risk deleting other windows along the way). In such cases, it is
preferable to use window-safely-shrinkable-p, which is also
less conservative.
Stefan
> Hi; I haven't been following this, but after a quick skim of the
> (long) thread, I think neither the current nor the proposed behaviour
> is ideal (it seems to be a choice between getting the height wrong or
> the width wrong), but I prefer the current one. I'd rather leave it as
> is for now, and look to improve it after 23.1.
I believe the behaviour of the calendar is now fixed in this regard.
I don't know if there is anything else left to do for this lengthy
bug, or if it can be closed now.
The only remaining calendar issue I can see is that one might prefer
the diary to always appear directly above (or below) the calendar,
rather than to one side. This could be achieved by the use of
windmove. I might install something along those lines, or I might not
bother.
Thank you. I wonder how did you test your change. In emacs -Q
I see a strange window configuration after `M-x calendar RET'
in a single wide window:
+-------------------------+ +------------+------------+
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | ===> | | |
| | | | |
| | | | *Messages* |
| | | +------------+
| | | | |
| *scratch* | | *scratch* | *Calendar* |
+-------------------------+ +------------+------------+
I believe it was supposed to do rather:
+-------------------------+ +-------------------------+
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | ===> | |
| | | |
| | | *scratch* |
| | +-------------------------+
| | | |
| *scratch* | | *Calendar* |
+-------------------------+ +-------------------------+
i.e. the calendar to always appear directly below from the current window.
I also see this. What's more, I have things configured so that calling
Calendar also pops up the fancy diary display, and starting with a
single (screen-) wide window, the result is similar to the above, namely:
+-------------------------+ +------------+------------+
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | ===> | | |
| | | | |
| | | | *Messages* |
| | | +------------+
| | | | |
| *scratch* | | Diary | *Calendar* |
+-------------------------+ +------------+------------+
(Note that in the result *scratch* is not displayed in the frame, but
instead the previous buffer *Messages*.)
Steve Berman
> What's more, I have things configured so that calling Calendar also
> pops up the fancy diary display, and starting with a single
> (screen-) wide window, the result is similar to the above, namely:
>
> +-------------------------+ +------------+------------+
> | | | | |
> | | | | |
> | | | | |
> | | | | |
> | | | | |
> | | | | |
> | | ===> | | |
> | | | | |
> | | | | *Messages* |
> | | | +------------+
> | | | | |
> | *scratch* | | Diary | *Calendar* |
> +-------------------------+ +------------+------------+
> In emacs -Q I see a strange window configuration after `M-x calendar
> RET' in a single wide window:
>
> +-------------------------+ +------------+------------+
> | | | | |
> | | | | |
> | | | | |
> | | | | |
> | | | | |
> | | | | |
> | | ===> | | |
> | | | | |
> | | | | *Messages* |
> | | | +------------+
> | | | | |
> | *scratch* | | *scratch* | *Calendar* |
> +-------------------------+ +------------+------------+
That was the intended behaviour. If the frame is wide enough to split
horizontally, it is split horizontally. This both makes sense and
looks correct to me.
> I believe it was supposed to do rather:
>
> +-------------------------+ +-------------------------+
> | | | |
> | | | |
> | | | |
> | | | |
> | | | |
> | | | |
> | | ===> | |
> | | | |
> | | | *scratch* |
> | | +-------------------------+
> | | | |
> | *scratch* | | *Calendar* |
> +-------------------------+ +-------------------------+
It will do this if the frame is not wider than split-width-threshold.
> That was the intended behaviour. If the frame is wide enough to split
> horizontally, it is split horizontally. This both makes sense and
> looks correct to me.
Showing *Messages* out of the blue is definitely not a feature.
IOW It doesn't look correct to me.
Stefan
> Showing *Messages* out of the blue is definitely not a feature.
> IOW It doesn't look correct to me.
It's because:
-----------
| scratch |
| |
| |
-----------
goes to :
------------------
| scratch | other |
| | ------
| | cal |
------------------
where `other' is whatever other-buffer returns. It's not choosing
messages specially, but obviously in emacs -Q there are no other
buffers available.
Then if you show the diary, it may happen to put it in the leftmost
window, replacing scratch.
AFAIK there are no general Emacs window-handling features to do any of
this in any more sophisticated fashion.
> It's bécasse:
[..]
> AFAIK there are no general Emacs window-handling features to do any of
> this in any more sophisticated fashion.
I know why the code gives this result. But still, result is not good.
I think it's better to end up with
+----------------------------------------------------------+
| |
| |
| *scratch* |
| |
+----------------------------------------------------------+
| |
| |
| *calendar* |
| |
+----------------------------------------------------------+
It may be suboptimal, but at least it doesn't end up with a weird window
arrangement displaying some randomly chosen old buffer. It's easy for
the user to hit C-x 3 before running calendar, if she doesn't like
this behavior; much easier than trying to fix the mess of the
current code, when you're not happy with its choices.
Stefan
> Stephen Berman wrote:
>
>> What's more, I have things configured so that calling Calendar also
>> pops up the fancy diary display, and starting with a single
>> (screen-) wide window, the result is similar to the above, namely:
>>
>> +-------------------------+ +------------+------------+
>> | | | | |
>> | | | | |
>> | | | | |
>> | | | | |
>> | | | | |
>> | | | | |
>> | | ===> | | |
>> | | | | |
>> | | | | *Messages* |
>> | | | +------------+
>> | | | | |
>> | *scratch* | | Diary | *Calendar* |
>> +-------------------------+ +------------+------------+
>
> As I wrote:
>
> The only remaining calendar issue I can see is that one might
> prefer the diary to always appear directly above (or below) the
> calendar, rather than to one side. This could be achieved by the
> use of windmove. I might install something along those lines, or I
> might not bother.
Oh yeah, sorry, I forgot about that.
Steve Berman
It could show *scratch* twice. Ideally, the "other" window would not be
created but a "vertical" calendar layout used instead ;-) Or show all
months of the respective year (maybe in some dimmed face) to make use of
the available space. With the current layout I don't see much sense
doing a horizontal split at all.
> Then if you show the diary, it may happen to put it in the leftmost
> window, replacing scratch.
>
> AFAIK there are no general Emacs window-handling features to do any of
> this in any more sophisticated fashion.
We could supply a command to show diary and cal simultaneously in two
windows above each other. Otherwise, we could remember in a separate
variable which "other" window was created when the calendar window was
split off and, if that other window is still alive and the calendar
window is below or on the right of it, use it for displaying the diary.
martin
> It could show *scratch* twice.
Yes, it could, easily.
> Ideally, the "other" window would not be created but a "vertical"
> calendar layout used instead ;-) Or show all months of the
> respective year (maybe in some dimmed face) to make use of the
> available space.
This is something I would like to see, but it is a lot of work.
> With the current layout I don't see much sense doing a horizontal
> split at all.
Because it makes zero sense to have a calendar wider than 80 columns.
The space is always wasted.
But it doesn't harm either.
> The space is always wasted.
But it can be recovered by a simple C-x 2.
Stefan
> We could supply a command to show diary and cal simultaneously in two
> windows above each other.
(setq calendar-setup 'one-frame)
Exactly. When `calendar-setup' is configured to display the calendar
in a separate frame and the frame is wide, we don't try filling the
available space with random buffers. A single-frame configuration
should not be different from this.
A wide-screen single-frame configuration is a special case. At least,
I perceive `C-x 3' as a way to create a virtual two-frame configuration
with two side-by-side frame-like windows. Consequently, I expect
`M-x calendar' respecting my choice: either keeping the single frame
and displaying the calendar below the current buffer, or when I create
a virtual two-frame configuration with `C-x 3' then keeping this
configuration intact and displaying the calendar below the current buffer.
Please don't duplicate buffers without users' consent.
>> Ideally, the "other" window would not be created but a "vertical"
>> calendar layout used instead ;-) Or show all months of the
>> respective year (maybe in some dimmed face) to make use of the
>> available space.
>
> This is something I would like to see, but it is a lot of work.
Yes, this would be ideal by either displaying the full year:
+-------------------------+-------------------------+
| | Jan2009 Feb2009 Mar2009 |
| | |
| | |
| | Apr2009 May2009 Jun2009 |
| | |
| | |
| | Jul2009 Aug2009 Sep2009 |
| | |
| | |
| | Oct2009 Nov2009 Dec2009 |
| | |
| *scratch* | *Calendar* |
+-------------------------+-------------------------+
or a long stripe for as much months will fit to the window's width:
+---------------------------------------------------+
| |
| |
| |
| |
| |
| |
| |
| *scratch* |
+---------------------------------------------------+
| May2009 Jun2009 Jul2009 Aug2009 Sep2009 Oct2009 |
| |
| *Calendar* |
+---------------------------------------------------+
I guess the latter would be easier to implement?
I think the most expected way would be to display the calendar window
below the current buffer, and to display the diary above the calendar
(effectively what `d' does when invoked from the calendar) that replaces
the original buffer (*scratch* in this case) with the diary buffer:
+-------------------------+ +-------------------------+
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | ===> | |
| | | |
| | | *Diary* |
| | +-------------------------+
| | | |
| *scratch* | | *Calendar* |
+-------------------------+ +-------------------------+
--
Juri Linkov
http://www.jurta.org/emacs/
> Please don't duplicate buffers without users' consent.
So I can't win. They won't accept Messages (or whatever), you won't
accept another Scratch (or whatever).
> I guess the latter would be easier to implement?
No. Please let's not conflate these two separate issues.
> It may be suboptimal,
What is the optimal behaviour in your opinion?
> but at least it doesn't end up with a weird window arrangement
> displaying some randomly chosen old buffer.
The buffer is no longer randomly chosen. But now I see that Juri
objects to the result of that, sigh.
I don't agree that the window arrangement is "weird". I suppose if the
whole world continues to disagree with me, I will add
`calendar-split-width-threshold', default nil.
This whole exercise seems to have been a waste of time.
The optimal behavior depends on the user's intention, here.
Calendar can't know it. So it should just strive to make it easy for
the user to get what she wants.
> This whole exercise seems to have been a waste of time.
Yes, I'm sorry about it, but clearly the new "automatic double split" is
not a good idea: sometimes it may correspond to what the user wanted,
but I expect it'll be rare, and as mentioned, it's a lot easy for those
users to hit C-x 3 before invoking calendar, than for the rest of them
to undo the damage. KISS.
Stefan
+------------+------------+ +------------+------------+
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | ===> | | |
| | | | | |
| current | | | | *scratch* |
| buffer | | | +------------+
| | | | | |
| *scratch* | *Messages* | | *scratch* | *Calendar* |
+------------+------------+ +------------+------------+
> I noticed another case with weird behaviour. Please confirm is this
> intentional or not.
Well, not so much intentional, as just, this is what pop-to-buffer
does. But, this is no longer the default behaviour - please try the
current CVS.
Hmm, tried the current CVS and see no improvement. I mean I still see
this default behaviour:
+------------+------------+ +------------+------------+
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | ===> | | |
| | | | | |
| current | | | | *scratch* |
| buffer | | | +------------+
| | | | | |
| *scratch* | *Messages* | | *scratch* | *Calendar* |
+------------+------------+ +------------+------------+
I expected it to be rather:
+------------+------------+ +------------+------------+
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | ===> | | |
| | | | | |
| current | | | *scratch* | |
| buffer | | +------------+ |
| | | | | |
| *scratch* | *Messages* | | *Calendar* | *Messages* |