From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: pjb@informatimago.com (Pascal J. Bourguignon) Newsgroups: gmane.emacs.help Subject: Re: Creating a bottom window? Date: Fri, 23 Jul 2010 18:39:31 +0200 Organization: Informatimago Message-ID: <874ofqi24c.fsf@kuiper.lan.informatimago.com> References: <64e7785b-1dc5-45b6-b90f-8a87fc76783b@q22g2000yqm.googlegroups.com> NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Transfer-Encoding: 8bit X-Trace: dough.gmane.org 1291850120 5619 80.91.229.12 (8 Dec 2010 23:15:20 GMT) X-Complaints-To: usenet@dough.gmane.org NNTP-Posting-Date: Wed, 8 Dec 2010 23:15:20 +0000 (UTC) To: help-gnu-emacs@gnu.org Original-X-From: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Thu Dec 09 00:15:15 2010 Return-path: Envelope-to: geh-help-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([199.232.76.165]) by lo.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1PQTEB-0005yB-CS for geh-help-gnu-emacs@m.gmane.org; Thu, 09 Dec 2010 00:15:15 +0100 Original-Received: from localhost ([127.0.0.1]:45505 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PQTEA-0005GM-Fw for geh-help-gnu-emacs@m.gmane.org; Wed, 08 Dec 2010 18:15:14 -0500 Original-Path: usenet.stanford.edu!fu-berlin.de!uni-berlin.de!individual.net!not-for-mail Original-Newsgroups: gnu.emacs.help Original-Lines: 198 Original-X-Trace: individual.net d5AXDK+RJu6ePhGM4C2OOABJYoe46gZizep3+p4MG8Yge5T0Zq Cancel-Lock: sha1:NjgzYjk3OGI2Y2RiZDMxYTdmMWU4YmE3NTZhNTQ5YTQyMjNmZDdiYQ== sha1:gQNc66vemdBgZSrRpdThg0td2kw= Face: iVBORw0KGgoAAAANSUhEUgAAADAAAAAwAQMAAABtzGvEAAAABlBMVEUAAAD///+l2Z/dAAAA oElEQVR4nK3OsRHCMAwF0O8YQufUNIQRGIAja9CxSA55AxZgFO4coMgYrEDDQZWPIlNAjwq9 033pbOBPtbXuB6PKNBn5gZkhGa86Z4x2wE67O+06WxGD/HCOGR0deY3f9Ijwwt7rNGNf6Oac l/GuZTF1wFGKiYYHKSFAkjIo1b6sCYS1sVmFhhhahKQssRjRT90ITWUk6vvK3RsPGs+M1RuR mV+hO/VvFAAAAABJRU5ErkJggg== X-Accept-Language: fr, es, en X-Disabled: X-No-Archive: no User-Agent: Gnus/5.101 (Gnus v5.10.10) Emacs/23.2 (gnu/linux) Original-Xref: usenet.stanford.edu gnu.emacs.help:179987 X-BeenThere: help-gnu-emacs@gnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Users list for the GNU Emacs text editor List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Errors-To: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.help:76199 Archived-At: TheFlyingDutchman writes: > On Jul 22, 6:35 am, Elena wrote: >> Hello, >> >> how do you create a window as wide as its frame and positioned at the >> bottom, no matter how many windows are there at the moment? I mean, a >> window positioned like the `shrink-fit.el' in this picture:http://www.emacswiki.org/emacs/DrewsEmacsWindowCallouts >> >> I've checked the ELisp reference about windows, but it seems you can >> just split existing windows. >> > > I also don't see any other way to create a new window besides > splitting windows. > > This code doesn't satisfy "no matter how many windows are there" - it > only handles 1 or 2 windows, and also assumes equal sized windows, so > may not be of any value. It does allow the number of bottom window > lines and bottom window buffer to be spacified. Here is how I would do it. The following code gets the window-tree, and walks it to build a lisp expression that will delete and re-split windows so that a new window is created at the bottom. It would need to be completed with the saving and restoring of more window parameters, and to be more precise. For example, I note a shift in the position of the vertical splits which must be due to the difference between window-width and what split-window takes as size argument in this case. Also, before deleting and spliting windows, the size should be checked, and windows resized to accomodate the new one. ;;;; -*- mode:emacs-lisp;coding:utf-8 -*- ;;;;************************************************************************** ;;;;FILE: window-pane.el ;;;;LANGUAGE: emacs lisp ;;;;SYSTEM: POSIX ;;;;USER-INTERFACE: NONE ;;;;DESCRIPTION ;;;; ;;;; A sketch for split-bottom. ;;;; ;;;;AUTHORS ;;;; Pascal J. Bourguignon ;;;;MODIFICATIONS ;;;; 2010-07-23 Created. ;;;;BUGS ;;;;LEGAL ;;;; GPL ;;;; ;;;; Copyright Pascal J. Bourguignon 2010 - 2010 ;;;; ;;;; This program 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 of the License, or (at your option) any later version. ;;;; ;;;; This program 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 this program; if not, write to the Free ;;;; Software Foundation, Inc., 59 Temple Place, Suite 330, ;;;; Boston, MA 02111-1307 USA ;;;;************************************************************************** (require 'cl) (require 'eieio) (defclass pane () ((left :initform nil :initarg :left :accessor pane-left) (top :initform nil :initarg :top :accessor pane-top) (width :initform nil :initarg :width :accessor pane-width) (height :initform nil :initarg :height :accessor pane-height))) (defclass emacs-window (pane) ((window :initarg :window :accessor emacs-window-window))) (defclass horizontal-splits (pane) ((subpanes :initarg :subpanes :accessor pane-subpanes)) (:documentation "Subpanes are one above the other, the first topmost.")) (defclass frame-pane (horizontal-splits) () ;; TODO: what about frames without a mini-buffer? (:documentation "Contains only the main pane and the mini-buffer")) (defclass vertical-splits (pane) ((subpanes :initarg :subpanes :accessor pane-subpanes)) (:documentation "Subpanes are side by side, the first leftmost.")) (defun window-tree-to-pane (tree) "Convert a window tree into a pane tree." (if (windowp tree) (make-instance 'emacs-window :width (window-width tree) :height (window-height tree) :window tree) (destructuring-bind (horizontalp (left top width height) &rest subpanes) tree (make-instance (if horizontalp 'horizontal-splits 'vertical-splits) :left left :top top :width width :height height :subpanes (mapcar (function window-tree-to-pane) subpanes))))) (defun window-pane (&optional frame) (let* ((frame (or frame (selected-frame))) (tree (window-tree frame))) ;; TODO: see what window-tree returns for frames without a mini-buffer. (make-instance 'frame-pane :width (frame-width frame) :height (frame-height frame) :subpanes (list (window-tree-to-pane (first tree)) (window-tree-to-pane (second tree)))))) (defmethod split-bottom ((self frame-pane) size) "SIZE is the size of the bottom frame to be created." (split-bottom (first (pane-subpanes self)) size)) (defmethod split-bottom ((self horizontal-splits) size) (eval (split-bottom-command self size))) (defmethod split-bottom ((self vertical-splits) size) (eval (split-bottom-command self size))) (defmethod split-bottom ((self emacs-window) size) (eval (split-bottom-command self size))) (defmethod split-bottom-command ((self horizontal-splits) size) (split-bottom-command (first (last (pane-subpanes self))) size)) (defmethod split-bottom-command ((self vertical-splits) size) (let ((deletes (delete-subpane-command self))) `(progn ,@(cddr deletes) (split-window ,(second (second deletes)) ,(- (pane-height self) size) nil) ,(recreate-subpane-command self)))) (defmethod split-bottom-command ((self emacs-window) size) `(split-window ,(emacs-window-window self) ,(- (pane-height self) size) nil)) (defmethod delete-subpane-command ((self horizontal-splits)) `(progn ,@(mapcar (function delete-subpane-command) (pane-subpanes self)))) (defmethod delete-subpane-command ((self vertical-splits)) `(progn ,@(mapcar (function delete-subpane-command) (pane-subpanes self)))) (defmethod delete-subpane-command ((self emacs-window)) `(delete-window ,(emacs-window-window self))) (defmethod recreate-subpane-command ((self horizontal-splits)) (let ((height (reduce (function +) (pane-subpanes self) :key (function pane-height)))) `(progn ,@(mapcar (lambda (pane) `(progn ,@(when (plusp (decf height (pane-height pane))) `((split-window nil ,(pane-height pane) nil))) ,(recreate-subpane-command pane) (other-window 1))) (pane-subpanes self))))) (defmethod recreate-subpane-command ((self vertical-splits)) (let ((width (reduce (function +) (pane-subpanes self) :key (function pane-width)))) `(progn ,@(mapcar (lambda (pane) `(progn ,@(when (plusp (decf width (pane-width pane))) `((split-window nil ,(pane-width pane) t))) ,(recreate-subpane-command pane) (other-window 1))) (pane-subpanes self))))) (defmethod recreate-subpane-command ((self emacs-window)) `(progn (switch-to-buffer ,(window-buffer (emacs-window-window self))) ;; TODO: set other window parameters from the old window. )) ;; (split-bottom (window-pane) 10) ; makes a window 10 lines high at the bottom. ;; You may use C-x r w a to store the current window configuration in register 'a' ;; and C-x r j a to restore the saved window configuration. -- __Pascal Bourguignon__ http://www.informatimago.com/