;;; mldrag.el --- mode line and vertical line dragging to resize windows;; Copyright (C) 1994 Free Software Foundation, Inc.;; Author: Kyle E. Jones <kyle@wonderworks.com>;; Keywords: mouse;; This file is part of GNU Emacs.;; GNU Emacs is free software; you can redistribute it and/or modify;; it under the terms of the GNU General Public License as published by;; the Free Software Foundation; either version 2, or (at your option);; any later version.;; GNU Emacs is distributed in the hope that it will be useful,;; but WITHOUT ANY WARRANTY; without even the implied warranty of;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the;; GNU General Public License for more details.;; You should have received a copy of the GNU General Public License;; along with GNU Emacs; see the file COPYING. If not, write to the;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,;; Boston, MA 02111-1307, USA.;;; Commentary:;; This package lets you drag the modeline, vertical bar and;; scrollbar to resize windows. Suggested bindings are:;;;; (global-set-key [mode-line down-mouse-1] 'mldrag-drag-mode-line);; (global-set-key [vertical-line down-mouse-1] 'mldrag-drag-vertical-line);; (global-set-key [vertical-scroll-bar S-down-mouse-1];; 'mldrag-drag-vertical-line);;;; Put the bindings and (require 'mldrag) in your .emacs file.;;; Code:(provide'mldrag)(defunmldrag-drag-mode-line(start-event)"Change the height of the current window with the mouse.This command should be bound to a down-mouse- event, and is mostusefully bound with the `mode-line' prefix. Holding down a mousebutton and moving the mouse up and down will make the clicked-onwindow taller or shorter."(interactive"e")(let((donenil)(echo-keystrokes0)(start-event-frame(window-frame(car(car(cdrstart-event)))))(start-event-window(car(car(cdrstart-event))))(start-nwindows(count-windowst))(old-selected-window(selected-window))should-enlarge-minibuffereventmouseminibufferytopbotedgeswconfigparamsgrowth)(setqparams(frame-parameters))(if(and(not(setqminibuffer(cdr(assq'minibufferparams))))(one-window-pt))(error"Attempt to resize sole window"))(unwind-protect(track-mouse(progn;; enlarge-window only works on the selected window, so;; we must select the window where the start event originated.;; unwind-protect will restore the old selected window later.(select-windowstart-event-window);; if this is the bottommost ordinary window, then to;; move its modeline the minibuffer must be enlarged.(setqshould-enlarge-minibuffer(andminibuffer(not(one-window-pt))(=(nth1(window-edgesminibuffer))(nth3(window-edges)))));; loop reading events and sampling the position of;; the mouse.(while(notdone)(setqevent(read-event)mouse(mouse-position));; do nothing if;; - there is a switch-frame event.;; - the mouse isn't in the frame that we started in;; - the mouse isn't in any Emacs frame;; drag if;; - there is a mouse-movement event;; - there is a scroll-bar-movement event;; (same as mouse movement for our purposes);; quit if;; - there is a keyboard event or some other unknown event;; unknown event.(cond((integerpevent)(setqdonet))((eq(carevent)'switch-frame)nil)((not(memq(carevent)'(mouse-movementscroll-bar-movement)))(setqdonet))((not(eq(carmouse)start-event-frame))nil)((null(car(cdrmouse)))nil)(t(setqy(cdr(cdrmouse))edges(window-edges)top(nth1edges)bot(nth3edges));; scale back a move that would make the;; window too short.(cond((<(-ytop-1)window-min-height)(setqy(+topwindow-min-height-1))));; compute size change needed(setqgrowth(-ybot-1)wconfig(current-window-configuration));; grow/shrink minibuffer?(ifshould-enlarge-minibuffer(progn;; yes. briefly select minibuffer so;; enlarge-window will affect the;; correct window.(select-windowminibuffer);; scale back shrinkage if it would;; make the minibuffer less than 1;; line tall.(if(and(>growth0)(<(-(window-heightminibuffer)growth)1))(setqgrowth(1-(window-heightminibuffer))))(enlarge-window(-growth))(select-windowstart-event-window));; no. grow/shrink the selected window(enlarge-windowgrowth));; if this window's growth caused another;; window to be deleted because it was too;; short, rescind the change.;;;; if size change caused space to be stolen;; from a window above this one, rescind the;; change, but only if we didn't grow/srhink;; the minibuffer. minibuffer size changes;; can cause all windows to shrink... no way;; around it.(if(or(/=start-nwindows(count-windowst))(and(notshould-enlarge-minibuffer)(/=top(nth1(window-edges)))))(set-window-configurationwconfig)))))));; restore the old selected window(select-windowold-selected-window))))(defunmldrag-drag-vertical-line(start-event)"Change the width of the current window with the mouse.This command should be bound to a down-mouse- event, and is mostusefully bound with the `vertical-line' or the `vertical-scroll-bar'prefix. Holding down a mouse button and moving the mouse left andright will make the clicked-on window thinner or wider."(interactive"e")(let*((donenil)(echo-keystrokes0)(start-event-frame(window-frame(car(car(cdrstart-event)))))(scroll-bar-left(eq(cdr(assq'vertical-scroll-bars(frame-parameters)))'left))(start-event-window(car(car(cdrstart-event))))(start-nwindows(count-windowst))(old-selected-window(selected-window))eventmousexleftrightedgeswconfiggrowth)(if(one-window-pt)(error"Attempt to resize sole ordinary window"))(ifscroll-bar-left(when(=(nth0(window-edgesstart-event-window))0)(error"Attempt to drag leftmost scrollbar"))(when(>=(nth2(window-edgesstart-event-window))(frame-widthstart-event-frame))(error"Attempt to drag rightmost scrollbar")))(unwind-protect(track-mouse(progn;; enlarge-window only works on the selected window, so;; we must select the window where the start event originated.;; unwind-protect will restore the old selected window later.(select-windowstart-event-window);; loop reading events and sampling the position of;; the mouse.(while(notdone)(setqevent(read-event)mouse(mouse-position));; do nothing if;; - there is a switch-frame event.;; - the mouse isn't in the frame that we started in;; - the mouse isn't in any Emacs frame;; drag if;; - there is a mouse-movement event;; - there is a scroll-bar-movement event;; (same as mouse movement for our purposes);; quit if;; - there is a keyboard event or some other unknown event;; unknown event.(cond((integerpevent)(setqdonet))((eq(carevent)'switch-frame)nil)((not(memq(carevent)'(mouse-movementscroll-bar-movement)))(setqdonet))((not(eq(carmouse)start-event-frame))nil)((null(car(cdrmouse)))nil)(t(setqx(car(cdrmouse))edges(window-edges)left(nth0edges)right(nth2edges));; scale back a move that would make the;; window too thin.(ifscroll-bar-left(cond((<(-rightx)window-min-width)(setqx(-rightwindow-min-width))))(cond((<(-xleft-1)window-min-width)(setqx(+leftwindow-min-width-1)))));; compute size change needed(setqgrowth(ifscroll-bar-left(-leftx)(-xright-1))wconfig(current-window-configuration))(enlarge-windowgrowtht);; if this window's growth caused another;; window to be deleted because it was too;; thin, rescind the change.;;;; if size change caused space to be stolen;; from a window to the left of this one,;; rescind the change.(if(or(/=start-nwindows(count-windowst))(ifscroll-bar-left(/=right(nth2(window-edges)))(/=left(nth0(window-edges)))))(set-window-configurationwconfig)))))));; restore the old selected window(select-windowold-selected-window))));; mldrag.el ends here