[gnu.emacs.bug] GNU Emacs 18.52 "bug"

garyo) (12/06/88)

WARNING:  Although this drives me up a wall, it's not truly a bug.

When deleting windows with delete-window, it is not always desirable
to spread the old window's space around among the remaining windows
and select the next window.

Often I'd rather just select the window ABOVE, and absorb the space
from the deleted window into that one.  This more closely parallels
what split-window does, and prevents delete-window from having
unwanted global effects on other windows.

I see this a lot with compilation windows; I compile something (using
a very small 5- or 6-line window on a 60-line screen), then close some
other window elsewhere on the screen and my compilation window changes
size!  Then I have to readjust ALL the windows on the screen (a
non-trivial task for windows in the middle, but that's another story)
to get them back to their state before deleting the window.

I consider a window configuration a vital part of the user interface;
the program (emacs) should not fool with it unless it has to.
Locality concerns would seem to require that the smallest number of
windows be changed arbitrarily on a user event (such as split or
delete).  Do you agree?

I can't see any way to fix this from elisp, since there's no way to
fool with the raw window data structures.  I expect it can be done
from within window.c, but I don't understand it well enough to fix it.
I may get to that point eventually, and if I do I'll send in my code;
if you have any hints I'd love to hear them.

					As always,

					Gary Oberbrunner

----------------------------------------------------------------------------
Remember,			Truth is not beauty;      (508)692-6200x2445
Information is not knowledge;	Beauty is not love;	  Gary   Oberbrunner
Knowledge is not wisdom;	Love is not music;	  ...!masscomp!garyo
Wisdom is not truth;		Music is the best. - FZ   ....garyo@masscomp

heiser@iis.UUCP (Gernot Heiser) (12/14/88)

In article <8812052005.AA07568@prep.ai.mit.edu> garyo%playroom@HARVARD.HARVARD.EDU (Gary Oberbrunner, ...{uunet,harvard}!masscomp!garyo) writes:
>
>WARNING:  Although this drives me up a wall, it's not truly a bug.
>
>When deleting windows with delete-window, it is not always desirable
>to spread the old window's space around among the remaining windows
>and select the next window.
>
>Often I'd rather just select the window ABOVE, and absorb the space
>from the deleted window into that one.

The following function my-delete-window probably does what you want. Also
enclosed is a split-window that messes much less with the screen. This not only
saves redrawing (the original stuff is a pain in the neck when using large
windows over slow lines) but generally produces less disturbtion to the current
window setup.

Gernot

---------------------------- cut here ---------------------------
;; GNU Emacs window commands aside from those written in C.
;; Copyright (C) 1985 Free Software Foundation, Inc.

;; This file is part of GNU Emacs.

;; GNU Emacs is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY.  No author or distributor
;; accepts responsibility to anyone for the consequences of using it
;; or for whether it serves any particular purpose or works at all,
;; unless he says so in writing.  Refer to the GNU Emacs General Public
;; License for full details.

;; Everyone is granted permission to copy, modify and redistribute
;; GNU Emacs, but only under the conditions described in the
;; GNU Emacs General Public License.   A copy of this license is
;; supposed to have been given to you along with GNU Emacs so you
;; can know your rights and responsibilities.  It should be in a
;; file named COPYING.  Among other things, the copyright notice
;; and this notice must be preserved on all copies.

;; Current version Gernot Heiser (heiser@iis.uucp)
;;   1988-08-15   split windows with minimum redrawing


(defun split-window-fast (wind size &optional hor-flag)
  "Split WINDOW, putting SIZE lines in the first of the pair.
The new windows are positioned such that a minimum of redrawing
is necessary.
WINDOW defaults to selected one and SIZE to half its size.
If optional third arg HOR-FLAG is non-nil, split side by side
and put SIZE columns in the first of the pair."
  (interactive)
  (if hor-flag
      (split-window wind size hor-flag)   ; default action for hor. windows
    (let ((current-window (selected-window))
          (old-size (window-height wind))
          (select-new nil)
          old-point new-top new-bottom new-point-1 new-point-2)
      (if (not size)
          (setq size (/ old-size 2)))     ; default size is half old size
      (cond
        ((>= old-size (* 2 window-min-height))   ; wind is big enough to split
         (setq size (min (max size window-min-height)
                         (- old-size window-min-height))) ; adjust size
         (if wind
             (select-window (wind)))
         (setq old-point (point))
         (setq new-point-1 old-point)     ; where point is to be in new upper
         (setq new-point-2 old-point)     ; where point is to be in new lower
         (setq new-top (save-excursion
                         (move-to-window-line 0)
                            (point)))     ; new upper to start with
                                          ; same line as old
         (setq new-bottom (save-excursion
                            (move-to-window-line -1)
                            (point)))     ; new lower to end with
                                          ; same line as old
         (save-excursion
           (move-to-window-line (- size 1))  ; the split line (new mode line)
           (let (bol-point eol-point)
             (beginning-of-line nil)
             (setq bol-point (point))
             (end-of-line nil)
             (setq eol-point (point))
             (cond
               ((> bol-point old-point)           ; cursor was in upper part
                (setq new-point-2 (save-excursion
                                    (move-to-window-line size)
                                    (point))))    ; lower curs to top
               ((< eol-point old-point)           ; cursor was in lower part
                (setq new-point-1 (save-excursion
                                    (move-to-window-line (- size 2))
                                    (point)))     ; upper curs to bottom
                (setq select-new (eq current-window
                                     (selected-window))))
               (t                                 ; cursor was on split line
                 (setq new-top (save-excursion
                                 (move-to-window-line 1)
                                 (point)))        ; scroll down upper by 1
                 (setq new-bottom (save-excursion
                                    (move-to-window-line -2)
                                    (point))))))) ; scroll up lower by 1
         (split-window nil size nil)
         (goto-char new-top)
         (recenter 0)                        ; position upper window ...
         (goto-char new-point-1)             ;  ... and point
         (other-window 1)
         (goto-char new-bottom)
         (recenter -1)                       ; position lower window ...
         (goto-char new-point-2)             ;  ... and point
         (if (not select-new)
             (select-window current-window)))))))

(defun split-window-vertically (arg)
  "Split current window into two windows, one above the other.
This window becomes the uppermost of the two, and gets
ARG lines.  No arg means split equally."
  (interactive "P")
  (split-window-fast nil (and arg (prefix-numeric-value arg))))

(defun my-delete-window (&optional window)
  "Delete window WINDOW while not changing any other windows except the
one immediately below (or above if WIND is the bottommost window"
  (interactive)
  (let ((current-window (selected-window)))
    (if window
        (select-window window))
    (enlarge-window (- window-min-height (window-height window)))
    (select-window current-window)
    (delete-window window)))
-- 
Gernot Heiser                   Phone:       +41 1/256 23 48
Integrated Systems Laboratory   CSNET/ARPA:  heiser%iis.ethz.ch@relay.cs.net
ETH Zuerich                     UUCP (new):  heiser@iis.uucp
CH-8092 Zuerich, Switzerland    UUCP (old):  {uunet,mcvax,...}!iis!heiser