gnu-emacs-sources
[Top][All Lists]
Advanced

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

ewm v0.2


From: grischka
Subject: ewm v0.2
Date: Tue, 07 Dec 2010 02:39:46 +0100
User-agent: Thunderbird 2.0.0.23 (Windows/20090812)

Update for ewm with experimental support for GUD and ediff.

See also:
http://lists.gnu.org/archive/html/gnu-emacs-sources/2010-05/msg00026.html


;; -------------------------------------------------------------
;; ewm.el - emacs window manager
;;
;; An experimental proof-of-concept for an emacs window manager
;; with strict content->window association
;;
;; Copyright (C) 2010 grischka
;;
;;
;; This file 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.

;; v 0.1 published Thu, 20 May 2010 01:02:57 +0200 at:
;; http://lists.gnu.org/archive/html/gnu-emacs-sources/2010-05/msg00026.html
;; v 0.2 published Mo, 06 Dec 2010

;; Quick Start:
;; ------------
;;   Visit ewm.el and type 'M-x eval-buffer RET'
;;
;;
;; Key Summary:
;; ------------
;;   Ctrl-1 - toggle sidebar-1
;;   Ctrl-2 - toggle sidebar-2
;;   Ctrl-3 - toggle sidebar-3
;;   Ctrl-4 - toggle compile window
;;   Ctrl-5 - toggle top left window
;;   Ctrl-6 - toggle top right window
;;   Ctrl-7 - toggle primary edit window
;;   Ctrl-8 - toggle secondary edit window
;;   Ctrl-9 - toggle info window
;;
;;   Ctrl-0 - refresh layout
;;   Ctrl-F4 - kill active buffer
;;
;;   F1 - info
;;   F2 - switch window
;;   F3 - switch frame
;;   F7 - save and reload ewm.el
;;   F9 - compilation
;;
;;
;; Example layout:
;; ---------------
;;   The example layout (below) and bindings are ment to give the
;;   following behaviour:
;;
;;   A speedbar is created in the sidebar
;;
;;   "*compilation*" is shown in a full-width bottom pane
;;   "*Help* and "Buffer List" are shown in top panes
;;
;;   "*info*" and "*grep*"  are shown on a second frame
;;   "*About GNU Emacs*" is shown on a third frame
;;
;;   Other buffers are shown in the 'edit' window on the main frame
;;
;;
;; How it works:
;; -------------
;;   ewm provide two main interfaces:
;;    - ewm-display-buffer
;;    - ewm-hide-buffer
;;
;;   emacs own functions such as 'display-buffer',  'switch-to-window'
;;   'kill/bury-buffer' are advised to use the two interfaces above.
;;
;;   When asked to display some buffer, ewm looks for a suitable window
;;   in 'ewm-window-bindings.  This window is then marked as active
;;   and the buffer is added on top of the window's buffer stack.
;;
;;   To hide some buffer, ewm removes ot from the window's buffer
;;   stack.  If the stack is empty, the window is marked not active.
;;
;;   After any change, an emacs window-tree with the active windows
;;   is built accordingly to the layout in 'ewm-window-layout'.
;;   Frames are created if necessary.  Frames without active windows
;;   are deleted.
;;
;;   ewm is based on the thought that on a shared, tiled screen only
;;   a central instance is able to coordinate the display for packages
;;   and features and to decide where to display what.
;;
;;   ewm is experimental because any calls to the emacs window
;;   interface ('split-window', 'set-window-buffer', etc). from
;;   code other than ewm itself is contraproductive to the concept.


;; Not implemented:
;; ----------------
;;   Manual resize or layout changes by the user are not recorded.


;; -------------------------------------------------------------
;; Layout definition - Welcome to play with this.

(defun ewm-set-layout ()

  ;; the layout tree (frames and windows) -- sizes in percent
  (setq ewm-window-layout '(
    (frame-1
     (div-rows
      (25 div-cols
          (40 top-1)
          (30 top-2)
          (30 top-3)
          )
      (55 div-cols
          (25 div-rows
              (40 side-1)
              (30 side-2)
              (30 side-3)
              )
          (75 div-cols
              (50 div-rows
                  (50 edit-1)
                  (50 edit-2)
                  )
              (50 edit-3)
              )
          )
      (20 div-cols
          (50 tools)
          (50 tools-2)
          )
      ))
    (frame-2
     (info)
     )
    (frame-3
     (about)
     )
   ))

  ;; frame layout
  (setq ewm-frame-layout '(
    (frame-1
     :params ((left . 10) (top . 26) (width . 90) (height . 64))
     :default t
     )
    (frame-2
     :params ((left . 710) (top . 26) (width . 66) (height . 40))
     )
    (frame-3
     :params ((left . 250) (top . 150) (width . 72) (height . 42))
     )
    ))

  ;; buffer to window association
  (setq ewm-window-bindings (copy-tree '(
    (side-1
     :classes ("*side-1*" "*SPEEDBAR*" "^\\*registers of .*")
     )
    (side-2
     :classes ("*side-2*" " *undo-tree*" "^\\*locals of .*")
     ;; -> http://www.emacswiki.org/emacs/UndoTree
     )
    (side-3
     :classes ("*side-3*" "^\\*threads of .*")
     )
    (edit-1 ;; primary general purpose window
     :classes ("*scratch*" * ediff-A)
     )
    (edit-2 ;; secondary general purpose window
     :classes ("*scratch*" * "!Dired" "^\\*magit" "^\\*disassembly of .*" 
ediff-B)
     ;; strings starting witn ! are matched against buffer's mode-name
     )
    (edit-3 ;; vertical secondary general purpose window
     :classes ("*scratch*")
     )
    (top-1
     :classes ("*eproject*" "!Debugger")
     ;; -> http://www.emacswiki.org/emacs/eproject
     )
    (top-2
     :classes ("*Help*" "*Buffer List*" "^\\*breakpoints of .*")
     )
    (top-3
     :classes ("*top-3" "!Inferior I/O")
     )
    (tools
     :classes ("*compilation*" "*Completions*" "*Messages*" "^\\*stack frames 
of .*")
     )
    (tools-2
     :classes ("*tools-2*" "^\\*memory of .*" ediff-H)
     )
    (info
     :classes ("*info*" "*grep*")
     )
    (about
     :classes ("*GNU Emacs*" "*About GNU Emacs*" "^.*THE-GNU-PROJECT")
     ;; strings starting witn ^ are matched as regular expression
     )
   )))
)

;; "Debugger" "Locals: " "Inferior I/O" "Frames" "Breakpoints"
;; "Registers" "Disassembly: " "Memory" "Threads"

(defgroup ewm-group '() "ewm custom stuff")

(defcustom ewm-stuff
  '((a . 1) (b . 2)(c . 3))
  "stuff in ewm"
  :group 'ewm-group
  )

(defun ewm-csa ()
  (let ((new-value (cons '(x . 0) ewm-stuff)))
    (customize-save-variable 'ewm-stuff new-value)
    ))

;; -------------------------------------------------------------
;; bind some keys for testing

(dolist (k '(

  ;; toggle some windows
  ([?\C-1]  (ewm-toggle 'side-1))
  ([?\C-2]  (ewm-toggle 'side-2))
  ([?\C-3]  (ewm-toggle 'side-3))
  ([?\C-4]  (ewm-toggle 'tools))
  ([?\C-5]  (ewm-toggle 'top-1))
  ([?\C-6]  (ewm-toggle 'top-2))
  ([?\C-7]  (ewm-toggle 'edit-1))
  ([?\C-8]  (ewm-toggle 'edit-2))
  ([?\C-9]  (ewm-toggle 'info))

  ;; for convenience and demonstration
  ([?\C-0]  (ewm-update)) ;; refresh layout
  ([C-f4]   (kill-buffer nil)) ;; kill active buffer
  ([f7]     (ewm-reload)) ;; save and reload this file

  ([f1]     (info "(elisp)Top")) ;; show info
  ([f9]     (compile "echo \"hello world\"")) ;; show compilation

  ;; switch focus
  ([f2]     (other-window 1)) ;; focus next window
  ([S-f2]   (other-window -1)) ;; focus previous window
  ([f3]     (other-frame 1)) ;; focus next frame
  ([S-f3]   (other-frame -1)) ;; focus previous frame
  ))

  (global-set-key (car k) `(lambda () (interactive) ,@(cdr k)))
  )

;; -------------------------------------------------------------

;; -------------------------------------------------------------
;; implementation

;; make div or window
(defun ewm-make-elem (w e c)
  (let (a b)
    (cond ((eq (car e) 'div-cols)
           (ewm-make-div w t (cdr e) c)
           )
          ((eq (car e) 'div-rows)
           (ewm-make-div w nil (cdr e) c)
           )
          ((setq a (assoc (car e) c))
           (push (cons (car a) w) ewm-window-handles)
           (setq b (ewm-get-buffer (cdr a) t))
           (set-window-buffer w b)
           ))))

;; check if element is activated
(defun ewm-elem-active (e c)
  (let (a)
    (cond ((memq (car e) '(div-rows div-cols))
           (while (and (setq e (cdr e))
                       (null (ewm-elem-active (cdar e) c))
                       ))
           (consp e)
           )
          ((setq a (assoc (car e) c))
           (plist-get (cdr a) :active)
           ))))

;; make all elements in a div
(defun ewm-make-div (w h l c)
  (let (size w2 l2 e (ref 100) (n 0) (x 0) (s 0))
    (dolist (e l)
      (if (eq (car e) '*)
        (setq x (1+ x))
        (setq n (+ n (car e)))
        ))
    (when (> x 0)
      (setq s (/ (- ref n) x))
      )
    (setq ref (+ n (* x s)))
    (dolist (e l)
      (setq x (if (eq (car e) '*) s (car e)))
      (if (ewm-elem-active (cdr e) c)
        (push (cons x (cdr e)) l2)
        (setq ref (- ref x))
        ))
    (setq l2 (nreverse l2))
    (setq size (if h (window-width w) (window-height w)))
    (while (and l2 w)
      (setq e (car l2))
      (when (setq l2 (cdr l2))
        (setq x (/ (+ (* (car e) size) (/ ref 2)) ref))
        (setq w2 (split-window w x h))
        )
      (ewm-make-elem w (cdr e) c)
      (setq w w2)
      )))

;; generate entire layout
(defun ewm-make-layout (layout bindings)
  (let (f h p a d bl (ewm-making-layout t))
    (setq bl (buffer-list))
    (setq ewm-window-handles nil)
    (dolist (e layout)
      (when (setq f (cdr (assoc (car e) ewm-frame-layout)))
        (unless (setq a (assoc (car e) ewm-frame-handles))
          (push (setq a (list (car e))) ewm-frame-handles)
          )
        (setq d (plist-get f :default))
        (setq p (cons '(user-position . t) (plist-get f :params)))
        (setq h (cdr a))
        (setq e (cadr e))
        (and d
             (null (frame-live-p h))
             (setq h (car (last (frame-list))))
             )
        (cond ((or d (ewm-elem-active e bindings))
               (cond ((frame-live-p h)
                      (when ewm-init-frames
                        (modify-frame-parameters h p)
                        (sit-for 0.1)
                        ))
                     (t
                      (setq h (make-frame p))
                      (sit-for 0.1)
                      ))
               (let ((w (frame-first-window h)))
                 ;; delete all windows
                 (set-window-dedicated-p w nil)
                 (delete-other-windows w)
                 (setq w (split-window w nil t))
                 (delete-other-windows w)
                 ;; recreate window structure
                 (ewm-make-elem w e bindings)
                 ))
              ((frame-live-p h)
               (delete-frame h)
               (setq h nil)
               ))
        (setcdr a h)
        ))
    ;; restore original buffer order
    (while bl (bury-buffer (pop bl)))
    (setq ewm-init-frames nil)
    ))

;; -------------------------------------------------------------
;; functions for buffer-to-window association

;; get window id from elisp 'window'
(defun ewm-window-id (w)
  (car (rassoc w ewm-window-handles))
  )

;; get elisp window from window-id
(defun ewm-get-window (i)
  (cdr (assoc i ewm-window-handles))
  )

(defun ewm-get-binding (i)
  (cdr (assoc i ewm-window-bindings))
  )

(defun ewm-put (i p v)
  (let ((e (ewm-get-binding i)))
    (and e (plist-put e p v))
    ))

(defun ewm-get (i p)
  (let ((e (ewm-get-binding i)))
    (and e (plist-get e p))
    ))

;; remove buffer from the window's buffer-stack
(defun ewm-del-buffer (e b)
  (let ((bl (plist-get e :buffers)))
    (plist-put e :buffers (delete b bl))
    ))

;; add buffer on top of the window's buffer-stack
(defun ewm-add-buffer (e b)
  (let ((bl (plist-get e :buffers)))
    (plist-put e :buffers (cons b (delete b bl)))
    bl
    ))

;; cleanup and return buffer-stack
(defun ewm-buffer-list (e prop)
  (let (l)
    (dolist (b (plist-get e prop))
      (when (buffer-live-p b)
        (push b l)
        ))
    (setq l (nreverse l))
    (plist-put e prop l)
    l
    ))

;; get buffer to display in a window
(defun ewm-get-buffer (e force)
  (let ((bl (ewm-buffer-list e :buffers)))
    (when (and (null bl) force)
      (setq bl
            (list
             (or
              (car (ewm-buffer-list e :buffers-old))
              (get-buffer-create
               (or (car (plist-get e :classes)) "*scratch*")
               ))))
      (plist-put e :buffers bl)
      )
    (car bl)
    ))

;; select window and the frame where it's on
(defun ewm-select-window (w)
  (when (window-live-p w)
    (let (focus-follows-mouse)
      (select-window w)
      (select-frame-set-input-focus (window-frame w))
      w
      )))


(defun ewm-get-window-start ()
  (mapcar (lambda (e) (cons (car e) (window-start (cdr e))))
          ewm-window-handles))

(defun ewm-set-window-start (l)
  (dolist (x l)
    ((lambda (a) (and a (set-window-start (cdr a) (cdr x))))
     (assoc (car x) ewm-window-handles)
     )))
        
;; update layout and focus window 'i' or the previously focussed
(defun ewm-update (&optional i)
  (let ((w0 (selected-window)) i0 p)
    (setq i0 (or i (ewm-window-id w0)))
    ;;(setq p (ewm-get-window-start))
    (ewm-make-layout ewm-window-layout ewm-window-bindings)
    ;;(ewm-set-window-start p)
    (ewm-select-window (or (ewm-get-window i0) w0))
    ))

;; -------------------------------------------------------------
;; show/hide/toggle window

(defun ewm-show-window (i sel)
  (ewm-put i :active t)
  (ewm-update (and sel i))
  )

;; mark window as inactive and clear its buffer-stack (but keep a copy)
(defun ewm-hide-window (i)
  (let ((e (ewm-get-binding i)) b1 b2 sel)
    (when e
      (setq b1 (ewm-buffer-list e :buffers))
      (setq b2 (ewm-buffer-list e :buffers-old))
      (dolist (b (reverse b1)) (setq b2 (cons b (delete b b2))))
      (plist-put e :buffers-old b2)
      )
    (ewm-put i :buffers nil)
    (ewm-put i :active nil)
    (setq ewm-focus-stack (delete i ewm-focus-stack))
    (if (eq (selected-window) (ewm-get-window i))
        (setq sel (or (car ewm-focus-stack) 'edit-1))
      )
    (ewm-update sel)
    ))

(defun ewm-toggle (i &optional a)
  (if (if a (> a 0) (not (ewm-get i :active)))
    (ewm-show-window i nil)
    (ewm-hide-window i)
    )
  )

;; -------------------------------------------------------------
;; figure out the preferred window to display buffer

(defun ewm-get-buffer-class (buffer class)
  (let ((wb ewm-window-bindings)
        (name (buffer-name buffer))
        (mode (with-current-buffer buffer mode-name))
        a c e r d
        )
    (when (consp mode)
      (setq mode (symbol-name (car mode)))
      )
    (while (and wb (null r))
      (setq a (pop wb))
      (setq c (plist-get (cdr a) :classes))
      (while (and c (null r))
        (setq e (pop c))
        (when
          (cond ((eq e '*)
                 (progn (push a d) nil)
                 )
                ((symbolp e)
                 (eq e class)
                 )
                ((equal (substring e 0 1) "^")
                 (string-match e name)
                 )
                ((equal (substring e 0 1) "!")
                 (string-match (substring e 1) mode)
                 )
                (t
                 (equal e name)
                 ))
          (setq r a)
          )))
    (or r (ewm-get-buffer-class-default buffer (nreverse d)))
    ))

;; emulate (very) basic "other-window" logic
(defun ewm-get-buffer-class-default (buffer d)
  (cond ((cdr d)
         (let ((d1 (car d))
               (d2 (car (cdr d)))
               (w (selected-window))
               w1 w2
               )
           (setq w1 (ewm-get-window (car d1)))
           (setq w2 (ewm-get-window (car d2)))
           ;;(b1 (plist-get (cdr d1) :buffers))
           ;;(b2 (plist-get (cdr d2) :buffers))
           (cond (ewm-other-window
                  (if (eq w w1) d2 d1)
                  )
                 (t
                  (if (eq w w2) d2 d1)
                  )))
         )
        (t
         (car d)
         )))

;; return binding if any where buffer 'b' is currently displayed
(defun ewm-lookup-buffer (b)
  (let ((l ewm-window-bindings) bl c e)
    (while (and l (null c))
      (setq e (car l) l (cdr l))
      (when (plist-get (cdr e) :active)
        (setq bl (plist-get (cdr e) :buffers))
        (when (eq (car bl) b)
          (setq c e)
          )))
    c))

;; -------------------------------------------------------------
;; ewm interface : display & hide buffer

(defun ewm-display-buffer (b &optional sel lbl)
  (let (c e i w (ewm-making-layout t))
    (setq b (get-buffer-create (or b (current-buffer))))
    ;;(message "ewm-display-buffer %s" b)

    (unless lbl
      (setq c (ewm-lookup-buffer b))
      )
    (unless c
      (setq c (ewm-get-buffer-class b lbl))
      )
    (when c
      (setq i (car c))
      (setq e (cdr c))
      (ewm-add-buffer e b)
      (setq w (ewm-get-window i))
      (cond ((and (plist-get e :active) (window-live-p w))
             (set-window-buffer w b)
             (if sel (ewm-select-window w))
             w
             )
            (t
             (ewm-show-window i sel)
             (ewm-get-window i)
             )))))

(defun ewm-hide-buffer (w b)
  (let (i e (ewm-making-layout t))
    (setq i (ewm-window-id w))
    (setq e (ewm-get-binding i))
    (when e
      (ewm-del-buffer e b)
      ;; get previously displayed buffer
      (setq b (ewm-get-buffer e nil))
      (cond (b
             (set-window-buffer w b)
             )
            (t
             (ewm-hide-window i)
             )))))

(defun ewm-display-multi-buffers (bsl)
  (mapcar
   'ewm-get-window
   (mapcar
    (lambda (b)
      (and (car b)
           (ewm-window-id
            (ewm-display-buffer (car b) nil (cdr b))
            )))
    bsl)))

;; -------------------------------------------------------------
;; focus-change-hook replacement

(defun ewm-post-command-hook ()
  (unless ewm-making-layout
    (let ((w1 (selected-window)) i1 i2)
      (setq i1 (ewm-window-id w1))
      (setq i2 ewm-focus)
      (when (and i1 (null (eq i1 i2)))
        (unless (window-live-p (ewm-get-window i2))
          (setq ewm-focus-stack (delete i2 ewm-focus-stack))
          )
        (setq ewm-focus-stack (cons i1 (delete i1 ewm-focus-stack)))
        (setq ewm-focus i1)
        ;;(message "focus: %s -> %s" i2 i1)
        )
      )))

;; -------------------------------------------------------------
;; redirect emacs core functions to the ewm interface

(defun ewm-advise (f)
  (when (fboundp 'ad-unadvise)
    (ad-unadvise 'display-buffer)
    (ad-unadvise 'switch-to-buffer)
    (ad-unadvise 'switch-to-buffer-other-window)
    (ad-unadvise 'pop-to-buffer)
    (ad-unadvise 'kill-buffer)
    (ad-unadvise 'bury-buffer)
    (ad-unadvise 'delete-window)
    (ad-unadvise 'delete-frame)
    (ad-unadvise 'set-window-buffer)
    (ad-unadvise 'split-window)
    (ad-unadvise 'set-window-dedicated-p)
    (when (boundp 'display-buffer-regexps)
      (ad-unadvise 'switch-to-prev-buffer)
      (ad-unadvise 'replace-buffer-in-windows)
      )
    (remove-hook 'post-command-hook 'ewm-post-command-hook)
    (setq ewm-focus-stack nil)
    (setq display-buffer-function nil)
    )

  (when f
    (add-hook 'post-command-hook 'ewm-post-command-hook)

    (defadvice set-window-dedicated-p (around ewm activate)
      (if ewm-making-layout
          ad-do-it
        (let ((w (or (ad-get-arg 0) (selected-window)))
              (f (ad-get-arg 1))
              )
          (unless f ad-do-it)
          (setq ad-return-value f)
          )))

    (defadvice set-window-buffer (around ewm activate)
      (if ewm-making-layout
          ad-do-it
        (let ((w (or (ad-get-arg 0) (selected-window)))
              (b (ad-get-arg 1))
              )
          ;;(message "set")
          (ewm-display-buffer b)
          (setq ad-return-value nil)
          )))

    (defadvice split-window (around ewm activate)
      (if ewm-making-layout
          ad-do-it
        (let (w)
          ;;(message "split")
          (setq w (frame-first-window (car (last (frame-list)))))
          (setq ad-return-value w)
          )))

    ;; (setq display-buffer-function
    ;;   (lambda (b &optional ntw f)
    ;;     (let ((ewm-other-window ntw))
    ;;       ;;(message "display")
    ;;       (ewm-display-buffer b)
    ;;       )))

    (defadvice display-buffer (around ewm activate)
      (let ((b (ad-get-arg 0))
            (ewm-other-window (ad-get-arg 1))
            w)
        ;;(message "display")
        (setq w (ewm-display-buffer b))
        (setq ad-return-value w)
        ))

    (when (boundp 'display-buffer-regexps)
      (defadvice switch-to-prev-buffer (around ewm activate)
        (let ((w (or (ad-get-arg 0) (selected-window))) b)
          (setq b (window-buffer w))
          (ewm-hide-buffer w b)
          ))
      (defadvice replace-buffer-in-windows (around ewm activate))
      )

    (defadvice switch-to-buffer (around ewm activate)
      (let ((b (or (ad-get-arg 0) (other-buffer))) w)
        ;;(message "switch")
        (unless ewm-ignore
          (setq w (ewm-display-buffer b t))
          ;;ad-do-it
          (setq b (set-buffer (window-buffer w)))
          (setq ad-return-value b)
          )))

    (defadvice switch-to-buffer-other-window (around ewm activate)
      (let ((ewm-other-window t) b)
        (setq b (switch-to-buffer (ad-get-arg 0) (ad-get-arg 1)))
        (setq ad-return-value b)
        ))

    (defadvice pop-to-buffer (around ewm activate)
      (let ((b (or (ad-get-arg 0) (other-buffer))))
        ;;(message "pop")
        (ewm-display-buffer b t)
        (ad-set-arg 1 nil)
        ;;ad-do-it
        (setq b (set-buffer b))
        (setq ad-return-value b)
        ))

    (defadvice kill-buffer (around ewm activate)
      (let ((b (or (ad-get-arg 0) (current-buffer)))
            (ewm-ignore t)
            w)
        ;;(message "kill")
        (setq w (get-buffer-window b))
        ad-do-it
        (ewm-hide-buffer w b)
        ))

    (defadvice bury-buffer (around ewm activate)
      (if ewm-making-layout
          ad-do-it
        (let ((a (ad-get-arg 0)) (b (current-buffer))
              (ewm-ignore t)
              w)
          ;;(message "bury")
          (setq w (get-buffer-window b))
          ad-do-it
          (unless a (ewm-hide-buffer w b))
          )))

    (defadvice delete-window (around ewm activate)
      (if ewm-making-layout
          ad-do-it
        (let ((w (or (ad-get-arg 0) (selected-window))))
          ad-do-it
          (ewm-hide-window (ewm-window-id w))
          )))

    (defadvice delete-frame (around ewm activate)
      (if ewm-making-layout
          ad-do-it
        (let ((f (or (ad-get-arg 0) (selected-frame))) wl)
          (when (frame-live-p f)
            (setq wl (window-list f))
            ad-do-it
            (dolist (w wl) (ewm-hide-window (ewm-window-id w)))
            ))))
    ))

;; -------------------------------------------------------------
;; speedbar integration

(defun ewm-speedbar ()
  (require 'speedbar)
  ;; speedbar would not update if it thinks that it's
  ;; on the same frame
  (defadvice speedbar-timer-fn (around ewm activate)
    (defadvice selected-frame (around ewm activate) nil)
    (defadvice select-frame (around ewm activate) nil)
    ad-do-it
    (ad-unadvise 'select-frame)
    (ad-unadvise 'selected-frame)
    )
  (setq speedbar-frame (selected-frame))
  (with-current-buffer
      (setq speedbar-buffer (get-buffer-create "*SPEEDBAR*"))
    (speedbar-mode)
    )
  (speedbar-frame-mode 1)
  (buffer-disable-undo speedbar-buffer)
  (display-buffer speedbar-buffer)
  )

;; -------------------------------------------------------------
;; ediff hook

(setq ediff-window-setup-function
      (lambda (A B C H) ;; buffers
        (apply (lambda (WA WB WC WH) ;; windows
                 (ediff-with-current-buffer control-buffer
                   (setq ediff-window-A WA
                         ediff-window-B WB
                         ediff-window-C WC
                         )
                   (when ediff-windows-job
                     (set-window-start WA
                       (ediff-overlay-start
                         (ediff-get-value-according-to-buffer-type
                           'A ediff-narrow-bounds)))
                     (set-window-start WB
                       (ediff-overlay-start
                         (ediff-get-value-according-to-buffer-type
                           'B ediff-narrow-bounds)))
                     ))
                 (ewm-select-window WH)
                 (ediff-setup-control-buffer control-buffer)
                 )
               (ewm-display-multi-buffers
                `((,A . ediff-A)
                  (,B . ediff-B)
                  (,C . ediff-C)
                  (,H . ediff-H)
                  ))
               )))

;; -------------------------------------------------------------
;; initialization

;; global variables
(defvar ewm-frame-layout nil)
(defvar ewm-window-layout nil)
(defvar ewm-window-bindings nil)
(defvar ewm-window-handles nil)
(defvar ewm-frame-handles nil)
(defvar ewm-init-frames nil)
(defvar ewm-making-layout nil)
(defvar ewm-focus nil)
(defvar ewm-ignore nil)
(defvar ewm-focus-stack nil)
(defvar ewm-other-window nil)

(defun ewm-init ()
  (let ((b (current-buffer)))
    (ewm-set-layout)
    (ewm-advise t)
    (ewm-speedbar)
    (switch-to-buffer b)
    ))

(defun ewm-exit ()
  (setq speedbar-frame nil)
  (kill-buffer speedbar-buffer)
  (ewm-advise nil)
  )

(defun ewm-reload ()
  (let ((f (symbol-file 'ewm-reload)) b)
    (if (setq b (get-file-buffer f))
        (with-current-buffer b (save-buffer 0))
        )
    (load-file f)
    ))

;; -------------------------------------------------------------
;; start the thing

(provide 'ewm)
(ewm-init)

reply via email to

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