370 lines
16 KiB
EmacsLisp
370 lines
16 KiB
EmacsLisp
;;; ecb-compatibility.el --- ECB-compatibility for other packages
|
|
|
|
;; Copyright (C) 2000 - 2005 Jesper Nordenberg,
|
|
;; Klaus Berndl,
|
|
;; Kevin A. Burton,
|
|
;; Free Software Foundation, Inc.
|
|
|
|
;; Author: Klaus Berndl <klaus.berndl@sdm.de>
|
|
;; Maintainer: Klaus Berndl <klaus.berndl@sdm.de>
|
|
;; Keywords: browser, code, programming, tools
|
|
;; Created: 2004
|
|
|
|
;; 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, 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
|
|
;; 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.
|
|
|
|
;; $Id$
|
|
|
|
;;; Commentary:
|
|
;;
|
|
;; Contains compatibility-code for other-packages.
|
|
;;
|
|
;; Whenever commands of other packages are not fully compatible with ECB then
|
|
;; this library should contain the necessary code to make it fully compatible
|
|
;; - or at least working acceptable.
|
|
;;
|
|
;; This file is part of the ECB package which can be found at:
|
|
;; http://ecb.sourceforge.net
|
|
|
|
(eval-when-compile
|
|
(require 'silentcomp))
|
|
|
|
|
|
(require 'ecb-util)
|
|
(require 'ecb-common-browser)
|
|
(require 'ecb-layout)
|
|
|
|
;; To add compatibilty code for packages just do:
|
|
;;
|
|
;; 1. Add the needed advice(s) to `ecb-compatibility-advices'
|
|
;; 2. Add the advice-code below.
|
|
;;
|
|
;; All advices of `ecb-compatibility-advices' will be autom. enabled when ECB
|
|
;; starts and autom. disabled when ECB shuts down. No advice is enabled just
|
|
;; by loading the ECB-library!
|
|
|
|
(defecb-advice-set ecb-compatibility-advices
|
|
"Contains all advices needed for package-compatibility.")
|
|
|
|
;; package bs.el ----------------------------------------------------------
|
|
|
|
(defecb-advice bs-show before ecb-compatibility-advices
|
|
"Ensures `bs-show' works well when called from another window as an
|
|
edit-window. Does nothing if called in another frame as the `ecb-frame'."
|
|
(when (equal (selected-frame) ecb-frame)
|
|
(unless (ecb-point-in-edit-window-number)
|
|
(ecb-select-edit-window))
|
|
;; now we handle if bs-show should always display in the compile-window
|
|
(let ((my-bs-buffer (get-buffer-create "*buffer-selection*")))
|
|
;; ecb-compilation-buffer-p needs a living buffer!
|
|
(when (and (ecb-compilation-buffer-p my-bs-buffer)
|
|
ecb-compile-window-height)
|
|
(display-buffer (buffer-name my-bs-buffer))))))
|
|
|
|
;; package electric.el ------------------------------------------------------
|
|
|
|
|
|
(defecb-advice one-window-p around ecb-always-disabled-advices
|
|
"If called for the `ecb-frame' it only returns not nil if there is exactly
|
|
one edit-window. Neither the ecb-windows nor the compile-window nor the
|
|
minibuffer-window are considered. This adviced version of `one-window-p' is
|
|
not for direct usage therefore it's added to `ecb-always-disabled-advices' and
|
|
therefore it's always disabled\; use the macro `ecb-with-ecb-advice' instead
|
|
if you need this adviced version of `one-window-p'!"
|
|
(if (and ecb-minor-mode
|
|
(equal (selected-frame) ecb-frame))
|
|
(setq ad-return-value
|
|
(= (length (ecb-canonical-edit-windows-list)) 1))
|
|
ad-do-it))
|
|
|
|
(defecb-advice Electric-pop-up-window around ecb-compatibility-advices
|
|
"Ensures that the electric-* commands \(e.g. `electric-buffer-list') work
|
|
well with ECB. If BUFFER is a \"compilation-buffer\" in the sense of
|
|
`ecb-compilation-buffer-p' then BUFFER will be displayed in the compile-window
|
|
of ECB - if there is any. If the compile-window is temporally hidden then the
|
|
BUFFER is displayed in an edit-window!"
|
|
(if (and ecb-minor-mode
|
|
(equal (selected-frame) ecb-frame))
|
|
(if (and (ecb-compilation-buffer-p (ad-get-arg 0))
|
|
(equal (ecb-compile-window-state) 'visible))
|
|
(pop-to-buffer (ad-get-arg 0))
|
|
(let ((ecb-compilation-buffer-names nil)
|
|
(ecb-compilation-major-modes nil)
|
|
(ecb-compilation-predicates nil))
|
|
(ecb-with-ecb-advice 'one-window-p 'around
|
|
ad-do-it)))
|
|
ad-do-it))
|
|
|
|
(defecb-advice electric-command-history before ecb-compatibility-advices
|
|
"Ensures that the electric-* commands work well with ECB."
|
|
(when (and ecb-minor-mode
|
|
(equal (selected-frame) ecb-frame)
|
|
(ecb-point-in-dedicated-special-buffer))
|
|
(ecb-select-edit-window)))
|
|
|
|
(defecb-advice electric-buffer-list before ecb-compatibility-advices
|
|
"Ensures that the electric-* commands work well with ECB."
|
|
(when (and ecb-minor-mode
|
|
(equal (selected-frame) ecb-frame)
|
|
(ecb-point-in-dedicated-special-buffer))
|
|
(ecb-select-edit-window)))
|
|
|
|
(defecb-advice electric-buffer-list after ecb-compatibility-advices
|
|
"Ensures that the electric-* commands work well with ECB."
|
|
(when (and ecb-minor-mode
|
|
(equal (selected-frame) ecb-frame))
|
|
(if (ecb-buffer-obj "*Buffer List*")
|
|
(bury-buffer (ecb-buffer-obj "*Buffer List*")))))
|
|
|
|
;; package master.el (only Emacs >= 22.X) ------------------------------------
|
|
|
|
;; The adviced version of switch-to-buffer-other-window can redraw the layout
|
|
;; (e.g. if the buffer in the compile-window is the slave and the
|
|
;; compile-window has been made visible), so <window> in the code below can be
|
|
;; a destroyed window-object! we have to prevent from this (e.g. by selecting
|
|
;; the window before by number).
|
|
(when-ecb-running-emacs
|
|
(defecb-advice master-says around ecb-compatibility-advices
|
|
"Makes the function compatible with ECB."
|
|
(if (or (not ecb-minor-mode)
|
|
(not (equal (selected-frame) ecb-frame)))
|
|
(ecb-with-original-basic-functions ad-do-it)
|
|
(if (null (buffer-live-p (ecb-buffer-obj master-of)))
|
|
(error "Slave buffer has disappeared")
|
|
(let ((window (selected-window))
|
|
(point-loc (ecb-where-is-point))
|
|
(p (point)))
|
|
(if (not (eq (window-buffer window) (ecb-buffer-obj master-of)))
|
|
(switch-to-buffer-other-window master-of))
|
|
(if (ad-get-arg 0)
|
|
(condition-case nil
|
|
(apply (ad-get-arg 0) (ad-get-arg 1))
|
|
(error nil)))
|
|
(select-window (case (car point-loc)
|
|
(ecb
|
|
(ecb-get-ecb-window-by-number (cdr point-loc)))
|
|
(edit
|
|
(ecb-get-edit-window-by-number (cdr point-loc)))
|
|
(compile
|
|
ecb-compile-window)
|
|
(minibuf
|
|
(minibuffer-window ecb-frame))
|
|
(other-dedicated
|
|
(ecb-get-window-by-number (cdr point-loc)))))
|
|
(goto-char (point))))))
|
|
)
|
|
|
|
;; package scroll-all.el --------------------------------------------------
|
|
|
|
(defecb-advice scroll-all-function-all around ecb-compatibility-advices
|
|
"Make it compatible with ECB."
|
|
(if (or (not ecb-minor-mode)
|
|
(not (equal (selected-frame) ecb-frame)))
|
|
(ecb-with-original-basic-functions ad-do-it)
|
|
(let (;; This runs the `other-window'-calls in the body in the right mode
|
|
(ecb-other-window-behavior 'only-edit))
|
|
;; return the current number of edit-windows if point is in an edit-window
|
|
;; and always return 1 if point is not in an edit-window.
|
|
(flet ((count-windows (&optional minibuf)
|
|
(if (ecb-point-in-edit-window-number)
|
|
(length (ecb-canonical-edit-windows-list))
|
|
1)))
|
|
ad-do-it))))
|
|
|
|
|
|
;; package tmm.el --------------------------------------------------------
|
|
|
|
;; Klaus Berndl <klaus.berndl@sdm.de>: We can not use our
|
|
;; Electric-pop-up-window advice instaed of this advice because otherwise
|
|
;; some commands of the popup-menus of the ecb-buffers would not work - this
|
|
;; comes from the save-window-excursion in the the tmm.
|
|
(when-ecb-running-emacs
|
|
(defecb-advice tmm-prompt around ecb-compatibility-advices
|
|
"Make it compatible with ECB."
|
|
(if (or (not ecb-minor-mode)
|
|
(not (equal (selected-frame) ecb-frame)))
|
|
(ecb-with-original-basic-functions ad-do-it)
|
|
;; we set temporally `ecb-other-window-behavior' to a function which
|
|
;; always selects the "next" window after the
|
|
;; `ecb-last-edit-window-with-point'
|
|
(let ((ecb-other-window-behavior
|
|
(lambda (win-list edit-win-list ecb-win-list comp-win
|
|
mini-win point-loc nth-win)
|
|
(ecb-next-listelem edit-win-list
|
|
ecb-last-edit-window-with-point)))
|
|
;; we must not handle the tmm-stuff as compilation-buffer
|
|
(ecb-compilation-buffer-names nil)
|
|
(ecb-compilation-major-modes nil)
|
|
(ecb-compilation-predicates nil))
|
|
ad-do-it)))
|
|
)
|
|
|
|
;; ediff-stuff ---------------------------------------------------------------
|
|
|
|
(silentcomp-defun ediff-cleanup-mess)
|
|
(silentcomp-defvar ediff-quit-hook)
|
|
|
|
;; (defecb-advice ediff-setup-windows around ecb-compatibility-advices
|
|
;; "Ediff can manage all its windows with deactivated ECB-advices.
|
|
|
|
;; This is possible because we have in the setup-hook cleared the whole ecb-frame."
|
|
;; (if (and (boundp 'ecb-minor-mode)
|
|
;; ecb-minor-mode
|
|
;; (eq (selected-frame) ecb-frame))
|
|
;; (ecb-with-original-basic-functions
|
|
;; ad-do-it)
|
|
;; ad-do-it))
|
|
|
|
(defvar ecb-before-ediff-window-config nil)
|
|
|
|
;; We must not add this function to `ediff-before-setup-windows-hook' because
|
|
;; this hook is called very often - see docu. The hook
|
|
;; `ediff-before-setup-hook' is called only once - so it can be used to store
|
|
;; window-configs!
|
|
(defun ecb-ediff-before-setup-hook ()
|
|
"Special ecb-setup before starting ediff."
|
|
(if (and ecb-minor-mode
|
|
(equal (selected-frame) ecb-frame))
|
|
(progn
|
|
(setq ecb-before-ediff-window-config (ecb-current-window-configuration))
|
|
(if ecb-run-ediff-in-ecb-frame
|
|
;; !!!! we must delete all ECB-windows and the compile-window so
|
|
;; ediff can manage the whole ecb-frame concerning its windows!
|
|
;; This is the reason why we can advice `ediff-setup-windows' so
|
|
;; it runs with all original layout basic functions (especially
|
|
;; delete-other-window is necessary!)
|
|
(progn
|
|
(ecb-toggle-ecb-windows -1)
|
|
(ecb-toggle-compile-window -1))
|
|
(if (not (ecb-windows-all-hidden))
|
|
(delete-other-windows (car (ecb-canonical-edit-windows-list))))))
|
|
(setq ecb-before-ediff-window-config nil)))
|
|
|
|
;; TODO: Klaus Berndl <klaus.berndl@sdm.de>: Should we add this function to
|
|
;; `ediff-suspend-hook' too?! We should add something but this functions is
|
|
;; not perfectly....in general suspending ediff need some work here...
|
|
(defun ecb-ediff-quit-hook ()
|
|
"Added to the end of `ediff-quit-hook' during ECB is activated. It
|
|
does all necessary after finishing ediff."
|
|
(when ecb-minor-mode
|
|
(if (and (not (equal (selected-frame) ecb-frame))
|
|
(y-or-n-p
|
|
"Ediff finished. Do you want to delete the extra ediff-frame? "))
|
|
(delete-frame (selected-frame) t))
|
|
(select-frame ecb-frame)
|
|
(when ecb-before-ediff-window-config
|
|
(ecb-set-window-configuration ecb-before-ediff-window-config)
|
|
(setq ecb-before-ediff-window-config nil))))
|
|
|
|
(defun ecb-activate-ediff-compatibility ()
|
|
(if (boundp 'ediff-quit-hook)
|
|
(put 'ediff-quit-hook 'ecb-ediff-quit-hook-value
|
|
ediff-quit-hook))
|
|
(add-hook 'ediff-quit-hook 'ediff-cleanup-mess)
|
|
(add-hook 'ediff-quit-hook 'ecb-ediff-quit-hook t)
|
|
;; TODO: Klaus Berndl <klaus.berndl@sdm.de>: suspending ediff and
|
|
;; especially reactivating does currently not really work well...
|
|
;; (add-hook 'ediff-suspend-hook 'ecb-ediff-quit-hook t)
|
|
(add-hook 'ediff-before-setup-hook
|
|
'ecb-ediff-before-setup-hook))
|
|
|
|
(defun ecb-deactivate-ediff-compatibility ()
|
|
(if (get 'ediff-quit-hook 'ecb-ediff-quit-hook-value)
|
|
(setq ediff-quit-hook (get 'ediff-quit-hook
|
|
'ecb-ediff-quit-hook-value))
|
|
(remove-hook 'ediff-quit-hook 'ecb-ediff-quit-hook))
|
|
(remove-hook 'ediff-before-setup-hook
|
|
'ecb-ediff-before-setup-hook))
|
|
|
|
|
|
;; view-stuff --------------------------------------------------------------------
|
|
|
|
;; The code of the view-package of GNU Emacs has to be advices when the
|
|
;; view-buffer is displayed in the compile-window of ECB.
|
|
;; The much simpler view-mechanism of XEmacs (view-less.el) should work out of
|
|
;; the box.
|
|
|
|
;; TODO: Klaus Berndl <klaus.berndl@sdm.de>: for Emacs 22 we need also a
|
|
;; workaround when no compile-window is active because the return-to-alist
|
|
;; stuff in Emacs 22 is not really smart and does not work with layout like
|
|
;; ECB - with Emacs 23 it works perfectly without a compile-window.
|
|
;; In Emacs 22 the return-to-alist contains in case of a window-layout with
|
|
;; more than two windows quit-window which switches the buffer after quiting
|
|
;; (which is not what we want); with deactivated ECB and more than 2 windows
|
|
;; the same dump behavior - but unfortunatelly ECB contains always more than
|
|
;; two windows (at least in by far most cases), so current view-mode-exit
|
|
;; stuff wil not work with Emacs 22 and ECB ==> we simplify the logic in the
|
|
;; following case:
|
|
;; - Emacs 22 is running and
|
|
;; - there is no compile-window:
|
|
;; - current buffer is in view-mode
|
|
;; then we just delete the current-window (for which view-mode-exit is called)
|
|
;; and select ecb-last-edit-window-with-point (hmm, is this possible - this
|
|
;; one will be the deleted one...how to go back to that window we have to go
|
|
;; back??
|
|
|
|
(when-ecb-running-emacs
|
|
(defecb-advice view-mode-exit around ecb-compatibility-advices
|
|
"Makes view-mode compatible with ECB.
|
|
|
|
If there is no compile-window \(i.e. the buffer with view-mode is not
|
|
displayed in the special compile-window of ECB) then nothing special is done
|
|
but the original `view-mode-exit' is performed.
|
|
|
|
If the view-buffer is displayed in the compile-window \(i.e. this function is
|
|
called from within the compile-window) then the whole window-management stuff
|
|
of view-mode is disabled only `view-no-disable-on-exit' is taken into acount.
|
|
|
|
The compile-window will be shrinked down with
|
|
`ecb-toggle-compile-window-height' and the last edit-window with point will be
|
|
selected afterwards."
|
|
(if (and (boundp 'ecb-minor-mode)
|
|
ecb-minor-mode
|
|
(eq (selected-frame) ecb-frame)
|
|
(eq (selected-window) ecb-compile-window))
|
|
(when view-mode
|
|
(or view-no-disable-on-exit
|
|
(view-mode-disable))
|
|
;; (when (ad-get-arg 1) ;; = exit-action
|
|
;; (setq view-exit-action nil)
|
|
;; (funcall (ad-get-arg 1) (current-buffer)))
|
|
(force-mode-line-update)
|
|
(ecb-toggle-compile-window-height -1)
|
|
(select-window ecb-last-edit-window-with-point))
|
|
ad-do-it))
|
|
)
|
|
|
|
|
|
;; not yet done ----------------------------------------------------------------
|
|
|
|
;; TODO: Klaus Berndl <klaus.berndl@sdm.de>:
|
|
;; *** The new package gdb-ui.el provides an enhanced graphical interface to
|
|
;; GDB. You can interact with GDB through the GUD buffer in the usual way, but
|
|
;; there are also further buffers which control the execution and describe the
|
|
;; state of your program. It separates the input/output of your program from
|
|
;; that of GDB and watches expressions in the speedbar. It also uses features
|
|
;; of Emacs 21 such as the display margin for breakpoints, and the toolbar.
|
|
;; This is new in Emacs 21.4 so maybe we have to make it compatible with ECB!
|
|
;; But maybe this could be hard because AFAIK gdb-ui.el uses dedicated
|
|
;; windows!
|
|
|
|
|
|
|
|
|
|
;; we disable the advices at load-time
|
|
(ecb-disable-advices 'ecb-compatibility-advices t)
|
|
|
|
(silentcomp-provide 'ecb-compatibility)
|
|
|
|
;;; ecb-compatibility.el ends here
|