313 lines
13 KiB
EmacsLisp
313 lines
13 KiB
EmacsLisp
;;; ecb-compilation.el --- code for buffers displayed in compile-window
|
|
|
|
;; Copyright (C) 2000 - 2005 Jesper Nordenberg,
|
|
;; Klaus Berndl,
|
|
;; Kevin A. Burton,
|
|
;; Free Software Foundation, Inc.
|
|
|
|
;; Author: Jesper Nordenberg <mayhem@home.se>
|
|
;; Klaus Berndl <klaus.berndl@sdm.de>
|
|
;; Kevin A. Burton <burton@openprivacy.org>
|
|
;; Maintainer: Klaus Berndl <klaus.berndl@sdm.de>
|
|
;; Keywords: browser, code, programming, tools
|
|
;; Created: 2001
|
|
|
|
;; 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:
|
|
|
|
;; NOTE: If you enjoy this software, please consider a donation to the EFF
|
|
;; (http://www.eff.org)
|
|
|
|
;;; History
|
|
;;
|
|
;; For the ChangeLog of this file see the CVS-repository. For a complete
|
|
;; history of the ECB-package see the file NEWS.
|
|
|
|
|
|
|
|
;;; Code:
|
|
|
|
(eval-when-compile
|
|
(require 'silentcomp))
|
|
|
|
(silentcomp-defun comint-check-proc)
|
|
|
|
(require 'ecb-util)
|
|
|
|
(defcustom ecb-compilation-buffer-names `(("*Calculator*" . nil)
|
|
("*vc*" . nil)
|
|
("*vc-diff*" . nil)
|
|
,(if ecb-running-xemacs
|
|
'("\\*Apropos.*\\*" . t)
|
|
'("*Apropos*" . nil))
|
|
("*Occur*" . nil)
|
|
("*shell*" . nil)
|
|
("\\*[cC]ompilation.*\\*" . t)
|
|
("\\*i?grep.*\\*" . t)
|
|
("*JDEE Compile Server*" . nil)
|
|
,(if ecb-running-xemacs
|
|
'("\\*Help.*\\*" . t)
|
|
'("*Help*" . nil))
|
|
("*Completions*" . nil)
|
|
("*Backtrace*" . nil)
|
|
("*Compile-log*" . nil)
|
|
("*bsh*" . nil)
|
|
(,(if ecb-running-xemacs
|
|
" *Message-Log*"
|
|
"*Messages*") . nil))
|
|
"*Additional buffer names that should be displayed in the compile-window.
|
|
Buffer names can either be defined as strings or as regexps. If the
|
|
buffer-name of a buffer matches one of the defined string or regexp then it
|
|
will be displayed in the compile-window of ECB even if `compilation-buffer-p'
|
|
says nil for this buffer.
|
|
|
|
It is not recommended to add the name of eshell-buffers to this list because
|
|
ECB already handles the eshell-integration as best as possible.
|
|
|
|
See also the options `ecb-compilation-major-modes' and
|
|
`ecb-compilation-predicates'."
|
|
:group 'ecb-compilation
|
|
:group 'ecb-most-important
|
|
:type '(repeat (cons (string :tag "Buffer name")
|
|
(boolean :tag "Handled as regexp"))))
|
|
|
|
(defvar ecb-compilation-buffer-names-internal nil
|
|
"This variable is for ECB internal use and can be used by ECB to add
|
|
buffer-names to the set specified in `ecb-compilation-buffer-names'. Type is
|
|
the same as of option `ecb-compilation-buffer-names'")
|
|
|
|
(defun ecb-compilation-buffer-names ()
|
|
"Return the set of buffer names which should be displayed in the
|
|
compile-window of ECB. This is a list combined of
|
|
`ecb-compilation-buffer-names' and `ecb-compilation-buffer-names-internal'."
|
|
(append ecb-compilation-buffer-names
|
|
ecb-compilation-buffer-names-internal))
|
|
|
|
(defun ecb-compilation-registered-buffer-p (name)
|
|
"Check if name belongs to the set of buffers returned by
|
|
`ecb-compilation-buffer-names'. If yes returns NAME."
|
|
(catch 'exit
|
|
(dolist (b (ecb-compilation-buffer-names))
|
|
(if (null (cdr b))
|
|
(if (ecb-string= name (car b))
|
|
(throw 'exit name))
|
|
(save-match-data
|
|
(if (string-match (car b) name)
|
|
(throw 'exit name))))
|
|
nil)))
|
|
|
|
(defcustom ecb-compilation-major-modes '(compilation-mode)
|
|
"*Additional major-mode that should be displayed in the compile-window.
|
|
All buffers of a major-mode contained in this list are displayed in the
|
|
compile-window even if `compilation-buffer-p' says nil for such a buffer.
|
|
|
|
It is not recommended to add `eshell-mode' to this list because ECB already
|
|
handles the eshell-integration as best as possible."
|
|
:group 'ecb-compilation
|
|
:type '(repeat (symbol :tag "major-mode name")))
|
|
|
|
(defvar ecb-compilation-major-modes-internal nil
|
|
"This variable is for ECB internal use and can be used by ECB to add
|
|
major-mode symbols to the set specified in `ecb-compilation-major-modes'.")
|
|
|
|
(defun ecb-compilation-major-modes ()
|
|
"Return all major-mode symbols which should be displayed in the
|
|
compile-window. This is a list combined of `ecb-compilation-major-modes' and
|
|
`ecb-compilation-major-modes-internal'."
|
|
(append ecb-compilation-major-modes
|
|
ecb-compilation-major-modes-internal))
|
|
|
|
|
|
(defcustom ecb-compilation-predicates '(comint-check-proc)
|
|
"*Predicates when a buffer should be treated as compilation-buffer.
|
|
Every element of this list has to be a function or lambda-expression which
|
|
gets as argument a buffer-object and which has to return not nil when this
|
|
buffer should be treated as compilation-buffer \(even if
|
|
`compilation-buffer-p' says nil) and therefore be displayed in the
|
|
compile-window of ECB \(if there is any).
|
|
|
|
In combination with the values of `ecb-compilation-buffer-names' and
|
|
`ecb-compilation-major-modes' ECB decides when a buffer is displayed in the
|
|
compile-window.
|
|
|
|
Default value is the function `comint-check-proc' which returns not nil when
|
|
the buffer is related to a living process."
|
|
:group 'ecb-compilation
|
|
:type '(repeat (symbol :tag "Compilation predicate")))
|
|
|
|
(defvar ecb-compilation-predicates-internal nil
|
|
"This variable is for ECB internal use and can be used by ECB to add
|
|
predicates to the set defined in `ecb-compilation-predicates'.")
|
|
|
|
(defun ecb-compilation-predicates ()
|
|
"Return all predicates which should be used to test if a buffer should be
|
|
displayed in the compile-window. This is a list combined of
|
|
`ecb-compilation-predicates' and `ecb-compilation-predicates-internal'."
|
|
(append ecb-compilation-predicates
|
|
ecb-compilation-predicates-internal))
|
|
|
|
|
|
|
|
(defun ecb-compilation-get-buffers()
|
|
"Get all known compilation buffer names. See `ecb-compilation-buffer-p'."
|
|
|
|
(let((buffer-names '())
|
|
(buffer-list (buffer-list ecb-frame))
|
|
(index 0))
|
|
|
|
(setq buffer-list (sort buffer-list (lambda(first second)
|
|
(ecb-string< (buffer-name first)
|
|
(buffer-name second)))))
|
|
(dolist(buffer buffer-list)
|
|
(when (ecb-compilation-buffer-p buffer)
|
|
(setq buffer-names
|
|
(append buffer-names
|
|
(list (cons (buffer-name buffer) index))))
|
|
(setq index (1+ index))))
|
|
|
|
buffer-names))
|
|
|
|
|
|
(defun ecb-compilation-buffer-p (buffer-or-name)
|
|
"Test if the given buffer BUFFER-OR-NAME should be treated as a compilation
|
|
buffer. Note that in this case we define \"compilation buffer\" as a buffer
|
|
that should ideally be displayed in the compile-window of ECB \(see
|
|
`ecb-compile-window-height'). This means that in some situations this might
|
|
not be the result of a real `compile-internal'. A good example would be the
|
|
*Help* buffer.
|
|
|
|
BUFFER-OR-NAME can be the name of a living\(!) buffer or a buffer-object.
|
|
|
|
This function returns the buffer-object of BUFFER-OR-NAME - i.e.
|
|
BUFFER-OR-NAME will be treated as compilation-buffer - if:
|
|
|
|
- The name of the buffer is contained in the list returned by the function
|
|
`ecb-compilation-buffer-names' or
|
|
- the `major-mode' of the buffer is contained in the list returned by the
|
|
function `ecb-compilation-major-modes' or
|
|
- if `compilation-buffer-p' returns true or
|
|
- one of the predicates returned by `ecb-compilation-predicates' returns not
|
|
nil for the buffer.
|
|
|
|
Otherwise nil is returned.
|
|
|
|
Summary for ECB-end-users: A buffer will be treated as compilation-buffer if
|
|
either
|
|
- `compilation-buffer-p' returns not nil, i.e. if a real compilation-buffer or
|
|
- if at least one of the options `ecb-compilation-buffer-names',
|
|
`ecb-compilation-major-modes' or `ecb-compilation-predicates' define the
|
|
buffer as compilation-buffer."
|
|
;;determine the best valid for the buffer.
|
|
(let ((buffer (ecb-buffer-obj buffer-or-name))
|
|
(ecb-comp-predicates (ecb-compilation-predicates)))
|
|
(when buffer
|
|
|
|
;;test if this is a valid buffer by name.
|
|
(if (ecb-compilation-registered-buffer-p (buffer-name buffer))
|
|
buffer
|
|
;;else test if this is a valid buffer by mode
|
|
(if (with-current-buffer buffer
|
|
(member major-mode (ecb-compilation-major-modes)))
|
|
buffer
|
|
;;else test if this is a regular compilation buffer
|
|
(if (compilation-buffer-p buffer)
|
|
buffer
|
|
;; we do not use run-hook-with-args-until-success because we have
|
|
;; to check if the functions are bound!!
|
|
(if (dolist (p ecb-comp-predicates)
|
|
(if (and (fboundp p) (funcall p buffer))
|
|
(return t)))
|
|
buffer
|
|
nil)))))))
|
|
|
|
;; Klaus Berndl <klaus.berndl@sdm.de>: The following mechanism is necessary to
|
|
;; avoid eating up whole CPU for updating the menu-entries for the
|
|
;; compilation-buffers. Especially if you have opened a lot of buffers this
|
|
;; can slow down Emacs/ECB dramatically. Now we add an idle-times
|
|
;; check-function `ecb-compilation-buffer-list-changed-p' which checks if the
|
|
;; buffer-list has changed. If yes, then the variable
|
|
;; `ecb-compilation-update-menu-p' is set to t. Only if this variable is not
|
|
;; nil the menu-bar-update-hook `ecb-compilation-update-menu' updates the
|
|
;; ECB-menu.
|
|
|
|
(defvar ecb-compilation-update-menu-p nil)
|
|
(defvar ecb-compilation-buffer-list-cache nil)
|
|
(defvar ecb-compilation-update-idle-time 0.25)
|
|
|
|
(defun ecb-compilation-buffer-list-init ()
|
|
"Initialize the compilation buffer list cache."
|
|
(setq ecb-compilation-update-menu-p nil)
|
|
(setq ecb-compilation-buffer-list-cache nil)
|
|
(ecb-compilation-buffer-list-changed-p))
|
|
|
|
(defecb-autocontrol/sync-function ecb-compilation-buffer-list-changed-p nil nil nil
|
|
"Check if current active buffer list has changed - i.e. if a new buffer has
|
|
been created or a buffer has been deleted. If yes then
|
|
`ecb-compilation-update-menu-p' is set to not nil and the cache is updated."
|
|
(let ((new-buffer-list (buffer-list)))
|
|
(when (not (equal new-buffer-list
|
|
ecb-compilation-buffer-list-cache))
|
|
(ecb-bodytrace-autocontrol/sync-fcn-error
|
|
'ecb-compilation-buffer-list-changed-p
|
|
"New buffer list not equal with cached buffer list.")
|
|
(setq ecb-compilation-buffer-list-cache new-buffer-list)
|
|
;; Nowhere else this variable will be set to t.
|
|
(setq ecb-compilation-update-menu-p t))))
|
|
|
|
|
|
(defun ecb-compilation-update-menu()
|
|
"Create an install a menu that allows the user to navigate buffers that are
|
|
valid ECB compilation buffers. This is only done if
|
|
`ecb-compilation-update-menu-p' is not nil; see
|
|
`ecb-compilation-buffer-list-changed-p'. For more information about
|
|
compilation buffers see `ecb-compilation-buffer-p'."
|
|
|
|
(when ecb-compilation-update-menu-p
|
|
(let ((submenu nil)
|
|
(buffers (ecb-compilation-get-buffers)))
|
|
(condition-case nil
|
|
(progn
|
|
(setq ecb-compilation-update-menu-p nil)
|
|
(dolist(buffer buffers)
|
|
(setq submenu
|
|
(append submenu
|
|
(list (vector (car buffer)
|
|
;; switch-to-buffer-other-window is
|
|
;; ok for all situations because if
|
|
;; no compile-window it uses another
|
|
;; edit-window otherwise it uses the
|
|
;; compile-window.
|
|
`(funcall 'switch-to-buffer-other-window
|
|
,(car buffer))
|
|
:active t)))))
|
|
|
|
;;Klaus Berndl <klaus.berndl@sdm.de>: Seems not to work with
|
|
;;Emacs 20.X, but who cares, 20.x is outdated and not supported
|
|
;;anymore by ECB
|
|
(easy-menu-change (list ecb-menu-name)
|
|
"Compilation Buffers"
|
|
submenu
|
|
"Navigate")
|
|
t)
|
|
(error nil)))))
|
|
|
|
|
|
|
|
(silentcomp-provide 'ecb-compilation)
|
|
|
|
;;; ecb-compilation.el ends here
|