forked from ChasManRors/ecb
-
Notifications
You must be signed in to change notification settings - Fork 20
/
ecb-compilation.el
312 lines (255 loc) · 13.2 KB
/
ecb-compilation.el
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
;;; 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 <[email protected]>
;; Klaus Berndl <[email protected]>
;; Kevin A. Burton <[email protected]>
;; Maintainer: Klaus Berndl <[email protected]>
;; 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 <[email protected]>: 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 <[email protected]>: 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