emacs-devel
[Top][All Lists]
Advanced

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

Re: gdb-ui, dedicated windows


From: Tom Tromey
Subject: Re: gdb-ui, dedicated windows
Date: Sat, 05 Jul 2008 10:11:06 -0600
User-agent: Gnus/5.11 (Gnus v5.11) Emacs/22.1 (gnu/linux)

>> Another smaller annoyance: IMHO the separate IO buffer shouldn't be in a
>> dedicated window even if `gdb-many-windows' is t.  It just takes to much
>> space and makes it hard to look at two source files at the same time.

Nick> If it takes up too much room why use a separate buffer?  If you need a
Nick> separate buffer, why not put it in another frame?

The effect I would like is to have a single, screen-filling "gdb UI"
frame show up when I start debugging, and have it go away when I
finish debugging.  And, I'd like to be able to arrange the windows in
this frame the way I like.

The "one frame" approach is vaguely reminiscent of an Eclipse
perspective.  FWIW I think it is reasonable for some people to want
multiple frames and some to want a single frame.

To achieve this, a few changes are needed.  First, Emacs needs a new
way to maximize a frame so it doesn't overshadow the panel.  Second,
gdb-ui needs some window layout code.

>> BTW, how about some key bindings to move around / display the gdb-ui
>> windows?

Nick> It would be nice to be able to move the buffers around like
Nick> views in Eclipse but that would be a substantial task.  Emacs 23
Nick> has tabs in the header line of some buffers.  Do you have any
Nick> concrete ideas?

A while back I wrote the appended.  It isn't perfect, but the idea is
that you can rearrange the windows by hand, then save the state.
Then, next time, M-x gdb-frame-restore-windows will use this window
layout instead of the built-in one.

A few unimplemented refinements: have gdb-ui do this automatically,
save the window configuration, and allow multiple "source" windows w/
LRU replacement.

Tom

;;; gdb-frame.el --- new frame for gdb

;; Copyright (C) 2007 Tom Tromey <address@hidden>

;; Author: Tom Tromey <address@hidden>
;; Created: 15 Sep 2007
;; Version: 0.1
;; Keywords: tools

;; This file is not (yet) part of GNU Emacs.
;; However, it is distributed under the same license.

;; 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., 51 Franklin Street, Fifth Floor,
;; Boston, MA 02110-1301, USA.

;;; Commentary:

;;; Code:

(defvar gdb-application-frame nil)

(defun gdb-get-application-frame ()
  (unless (frame-live-p gdb-application-frame)
    (setq gdb-application-frame
          (make-frame '((title . "Emacs - GDB")
                        (tool-bar-lines . 1)
                        (height . 55)
                        (width . 183)))))
  (raise-frame gdb-application-frame)
  (select-frame-set-input-focus gdb-application-frame)
  gdb-application-frame)

(defun tjt-gdba (command-line)
  (interactive (list (gud-query-cmdline 'gdba)))
  (when (and (eq window-system 'x) gdb-many-windows)
    (gdb-get-application-frame))
  (gdba command-line))

(defvar gdb-frame-saved-windows nil)

(defun gdb--restore-windows-mapper (window-symbol window)
  (if (eq window-symbol 'gdb-source-window)
      ;; Assumes just one source window in the tree.
      (setq gdb-source-window window)
    (set-window-buffer window (gdb-get-buffer window-symbol))))

(defun gdb--restore-windows (parent-window tree map-fn)
  (let* ((vertical (nth 0 tree))
         (edges (nth 1 tree))
         (window-spec (nthcdr 2 tree)))
    (while window-spec
      (let* ((elt (car window-spec))
             next-window)
        (if (cdr window-spec)
            (setq next-window
                  ;; 'elt' here works for both the vector children and
                  ;; the list children.
                  (split-window parent-window (elt elt 1) (not vertical))))
        (if (vectorp elt)
            (funcall map-fn (elt elt 0) parent-window)
          (gdb--restore-windows parent-window elt map-fn))
        (setq parent-window next-window)
        (setq window-spec (cdr window-spec))))))

(defun gdb-frame-restore-windows ()
  (interactive)
  ;; Don't bother if we just had a single window.
  (delete-other-windows)
  (unless (symbolp gdb-frame-saved-windows)
    (gdb--restore-windows (selected-window) gdb-frame-saved-windows
                          #'gdb--restore-windows-mapper)))

(defun gdb--save-window-mapper (alist window)
  (if (eq window gdb-source-window)
      'gdb-source-window
    (or (cdr (assq (window-buffer window) alist))
        'gdb-source-window)))

(defun gdb--rewrite-window-tree (tree horizontal map-fn)
  (if (windowp tree)
      ;; Rewrite the window according to the mapper.
      ;; Also check for the source window.
      ;; If we don't understand what we have, assume it is the source.
      (let ((size (if horizontal
                      (window-height tree)
                    (window-width tree))))
        (vector (funcall map-fn tree) size))
    (append (list (nth 0 tree)
                  (let ((sizes (nth 1 tree)))
                    (if (nth 0 tree)
                        (- (nth 2 sizes) (nth 0 sizes))
                      (- (nth 3 sizes) (nth 1 sizes)))))
            (mapcar (lambda (item)
                      (gdb--rewrite-window-tree item (nth 0 tree) map-fn))
                    (nthcdr 2 tree)))))

(defun gdb-frame-save-windows ()
  (interactive)
  (let ((buffer-map
         ;; Map buffers to symbolic buffer names.
         (delq nil
               (mapcar (lambda (elt)
                         (let ((buffer (gdb-get-buffer (car elt))))
                           (if buffer
                               (cons buffer (car elt))
                             nil)))
                       gdb-buffer-rules-assoc)))
        ;; Use 'car' to avoid the minibuffer window here.
        (tree (car (window-tree))))
    (setq gdb-frame-saved-windows
          (gdb--rewrite-window-tree tree
                                    (if (consp tree) (nth 0 tree) nil)
                                    (lambda (window)
                                      (gdb--save-window-mapper buffer-map
                                                               window))))))

;;; gdb-frame.el ends here




reply via email to

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