0
|
1 ;;; $Id: eiffel3.el,v 1.1.1.1 1996/12/18 03:30:45 steve Exp $
|
|
2 ;;;--------------------------------------------------------------------------
|
|
3 ;;; TowerEiffel -- Copyright (c) 1993,1994 Tower Technology Corporation.
|
|
4 ;;; All Rights Reserved.
|
|
5 ;;;
|
|
6 ;;; Use, duplication, or disclosure is subject to restrictions as set forth
|
|
7 ;;; in subdivision (c)(1)(ii) of the Rights in Technical Data and Computer
|
|
8 ;;; Software clause at DFARS 252.227-7013.
|
|
9 ;;;
|
|
10 ;;; This file is made available for use and distribution under the same terms
|
|
11 ;;; as GNU Emacs. Such availability of this elisp file should not be construed
|
|
12 ;;; as granting such availability to the rest of TowerEiffel.
|
|
13 ;;;--------------------------------------------------------------------------
|
|
14 ;;; Portions of the file, as indicated below, were derived from "eiffel.el"
|
|
15 ;;; and "eif-mult-fmt.el
|
|
16 ;;; Copyright (C) 1989, 1990 Free Software Foundation, Inc. and Bob Weiner
|
|
17 ;;; Available for use and distribution under the same terms as GNU Emacs.
|
|
18
|
|
19 ;;; Synched up with: Not in FSF.
|
|
20
|
|
21 ;;;--------------------------------------------------------------------------
|
|
22 ;;; Adapted the file for the XEmacs 19.12 distribution. -- jasa (1995/03/11)
|
|
23 ;;;--------------------------------------------------------------------------
|
|
24 ;;;
|
|
25 ;;; EIFFEL3 : GNU Emacs mode for Eiffel Version 3
|
|
26 ;;;
|
|
27 ;;; INSTALLATION
|
|
28 ;;; To install, simply copy this file into a directory in your
|
|
29 ;;; load-path and add the following two commands in your .emacs file:
|
|
30 ;;;
|
|
31 ;;; (setq auto-mode-alist (cons '("\\.e$" . eiffel-mode)
|
|
32 ;;; auto-mode-alist))
|
|
33 ;;; (autoload 'eiffel-mode "eiffel3" "Mode for Eiffel programs" t)
|
|
34 ;;;
|
|
35 ;;; TowerEiffel users should do the following instead: See the file
|
|
36 ;;; dot-emacs that comes with the TowerEiffel distribution for a sample
|
|
37 ;;; ".emacs" file. If all Tower elisp files are already in your
|
|
38 ;;; load-path, then simply add the following line to your .emacs file:
|
|
39 ;;;
|
|
40 ;;; (load "tinstall")
|
|
41 ;;;
|
|
42 ;;; TOWER EIFFEL
|
|
43 ;;; TowerEiffel provides additional Emacs support for Eiffel
|
|
44 ;;; programming that integrates Emacs with Tower's Eiffel compiler,
|
|
45 ;;; documentation, and browsing tools. For more information on
|
|
46 ;;; these tools and their Emacs interface contact:
|
|
47 ;;;
|
|
48 ;;; Tower Technology Corporation
|
|
49 ;;; 1501 Koenig Dr.
|
|
50 ;;; Austin TX, 78756
|
|
51 ;;;
|
|
52 ;;; tower@twr.com (to reach a human being)
|
|
53 ;;; info@twr.com (automated file server)
|
|
54 ;;; (512)452-1721 (FAX)
|
|
55 ;;; (512)452-9455 (phone)
|
|
56 ;;;
|
|
57 ;;; SUPPORT
|
|
58 ;;; Please send bug reports, fixes or enhancements to:
|
|
59 ;;; elisp@atlanta.twr.com
|
|
60 ;;;
|
|
61 ;;; COMPATIBILITY:
|
|
62 ;;; This file has been tested with XEmacs 19.11. Syntax highlighting is
|
|
63 ;;; primarily supported with font-lock.el.
|
|
64 ;;;
|
|
65 ;;; COMMANDS
|
|
66 ;;; eif-backward-sexp
|
|
67 ;;; eif-feature-quote
|
|
68 ;;; eif-forward-sexp
|
|
69 ;;; eif-goto-matching-line
|
|
70 ;;; eif-indent-region
|
|
71 ;;; eif-indent-construct
|
|
72 ;;; eif-indent-line
|
|
73 ;;; eif-newline
|
|
74 ;;; eiffel-mode
|
|
75 ;;;
|
|
76 ;;; PUBLIC VARIABLES
|
|
77 ;;; eif-body-comment-indent
|
|
78 ;;; eif-check-keyword-indent
|
|
79 ;;; eif-class-level-comment-indent
|
|
80 ;;; eif-class-level-kw-indent
|
|
81 ;;; eif-extra-body-comment-indent
|
|
82 ;;; eif-extra-check-keyword-indent
|
|
83 ;;; eif-extra-class-level-comment-indent
|
|
84 ;;; eif-extra-class-level-kw-indent
|
|
85 ;;; eif-extra-feature-level-comment-indent
|
|
86 ;;; eif-extra-feature-level-indent
|
|
87 ;;; eif-extra-feature-level-kw-indent
|
|
88 ;;; eif-extra-inherit-level-kw-indent
|
|
89 ;;; eif-extra-then-indent
|
|
90 ;;; eif-feature-level-comment-indent
|
|
91 ;;; eif-feature-level-indent
|
|
92 ;;; eif-feature-level-kw-indent
|
|
93 ;;; eif-indent-increment
|
|
94 ;;; eif-inherit-level-kw-indent
|
|
95 ;;; eif-rescue-keyword-indent
|
|
96 ;;; eif-then-indent
|
|
97 ;;; eiffel-mode-abbrev-table
|
|
98 ;;; eiffel-mode-hook
|
|
99 ;;; eiffel-mode-map
|
|
100 ;;; eiffel-mode-syntax-table
|
|
101 ;;;
|
|
102 ;;; PUBLIC FUNCTIONS
|
|
103 ;;; None.
|
|
104 ;;;
|
|
105 ;;; HISTORY
|
|
106 ;;; Fred Hart - Jul 31, 1992: Created.
|
|
107
|
|
108 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
109 ;;; Indentation Amount Variables. ;;;
|
|
110 ;;; ;;;
|
|
111 ;;; The default values correspond to style used in ``Eiffel: The ;;;
|
|
112 ;;; Language''. Note: for TowerEiffel users the values below ;;;
|
|
113 ;;; will be superceded by the values in either tcustom.el or ;;;
|
|
114 ;;; ~/.tcustom.el if it is present. ;;;
|
|
115 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
116
|
|
117 (defvar eif-indent-increment 3
|
|
118 "Default indentation interval (in spaces)")
|
|
119
|
|
120 (defvar eif-class-level-kw-indent 0
|
|
121 "Indentation amount for Class level keywords (in number of
|
|
122 eif-indent-increments) (see eif-class-level-keywords variable).")
|
|
123 (defvar eif-extra-class-level-kw-indent 0
|
|
124 "Number of SPACES to add to eif-class-level-kw-indent to get the
|
|
125 actual indentation of a class level keyword. Can be negative.")
|
|
126
|
|
127 (defvar eif-class-level-comment-indent 0
|
|
128 "Indentation of comments at the beginning of the class (in number of
|
|
129 eif-indent-increments)")
|
|
130 (defvar eif-extra-class-level-comment-indent 0
|
|
131 "Number of SPACES to add to eif-class-level-comment-indent to get the
|
|
132 actual indentation of a class level comment. Can be negative.")
|
|
133
|
|
134 (defvar eif-inherit-level-kw-indent 2
|
|
135 "Indentation of keywords falling under the Inherit clause (in number of
|
|
136 eif-indent-increments) (see eif-inherit-level-keywords variable.")
|
|
137 (defvar eif-extra-inherit-level-kw-indent 0
|
|
138 "Number of SPACES to add to eif-inherit-level-kw-indent to get the
|
|
139 actual indentation of an inherit level keyword. Can be negative.")
|
|
140
|
|
141 (defvar eif-feature-level-indent 1
|
|
142 "Indentation amount of features. (in number of eif-indent-increments)")
|
|
143 (defvar eif-extra-feature-level-indent 0
|
|
144 "Number of SPACES to add to eif-feature-level-indent to get the
|
|
145 actual indentation of a feature. Can be negative.")
|
|
146
|
|
147 (defvar eif-feature-level-kw-indent 2
|
|
148 "Indentation of keywords belonging to individual features. (in number of
|
|
149 eif-indent-increments) (see eif-feature-level-keywords variable)")
|
|
150 (defvar eif-extra-feature-level-kw-indent 0
|
|
151 "Number of SPACES to add to eif-feature-level-kw-indent to get the
|
|
152 actual indentation of a feature level keyword. Can be negative.")
|
|
153
|
|
154 (defvar eif-feature-level-comment-indent 3
|
|
155 "Indentation of comments at the beginning of a feature. (in number of
|
|
156 eif-indent-increments)")
|
|
157 (defvar eif-extra-feature-level-comment-indent 0
|
|
158 "Number of SPACES to add to eif-feature-level-comment-indent to get the
|
|
159 actual indentation of a feature level comment. Can be negative.")
|
|
160
|
|
161 (defvar eif-body-comment-indent 0
|
|
162 "Indentation of comments in the body of a routine. (in number of
|
|
163 eif-indent-increments)")
|
|
164 (defvar eif-extra-body-comment-indent 0
|
|
165 "Number of SPACES to add to eif-body-comment-indent to get the
|
|
166 actual indentation of a routine body comment. Can be negative.")
|
|
167
|
|
168 (defvar eif-check-keyword-indent 0
|
|
169 "Extra indentation for the check clause as described in ETL. (in number of
|
|
170 eif-indent-increments). Default is 0, which is different than in ETL's 1.")
|
|
171 (defvar eif-extra-check-keyword-indent 0
|
|
172 "Number of SPACES to add to eif-check-keyword-indent to get the
|
|
173 actual indentation of a check keyword. Can be negative.")
|
|
174
|
|
175 (defvar eif-rescue-keyword-indent -1
|
|
176 "Extra indentation for the rescue clause as described in ETL. (in number of
|
|
177 eif-indent-increments). Default is -1.")
|
|
178 (defvar eif-extra-rescue-keyword-indent 0
|
|
179 "Number of SPACES to add to eif-rescue-keyword-indent to get the
|
|
180 actual indentation of a rescue keyword. Can be negative.")
|
|
181
|
|
182 (defvar eif-then-indent 0
|
|
183 "Indentation for a `then' appearing on a line by itself rather
|
|
184 than on the same line as an `if'. (in number of eif-indent-increments)")
|
|
185 (defvar eif-extra-then-indent 1
|
|
186 "Number of SPACES to add to eif-then-indent to get the
|
|
187 actual indentation of a `then' appearing on a line by itself. Can be
|
|
188 negative.")
|
|
189
|
|
190 (defvar eif-continuation-indent 1
|
|
191 "Extra indentation for a continued statement line. (in number of eif-indent-increments)")
|
|
192 (defvar eif-extra-continuation-indent 0
|
|
193 "Number of SPACES to add to eif-continuation-indent to get the
|
|
194 actual indentation of a continued statement line. Can be
|
|
195 negative.")
|
|
196
|
|
197 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
198 ;;; font-lock, lhilit, and hilit19 support ;;;
|
|
199 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
200
|
|
201 ;; The value for a font variable must either be a string
|
|
202 ;; specifying a valid font, the symbol 'default meaning the
|
|
203 ;; default font, or the symbol 'context meaning the font of the
|
|
204 ;; surrounding text.
|
|
205 ;;
|
|
206 ;; Simlarly, the value for a color variable must either be a string
|
|
207 ;; specifying a valid color, the symbol 'default meaning the
|
|
208 ;; default foreground color, or the symbol 'context meaning the
|
|
209 ;; foregound color of the surrounding text.
|
|
210
|
|
211 (if (or (featurep 'font-lock) (featurep 'lhilit) (featurep 'hilit19)) (progn
|
|
212
|
|
213 (cond ((eq window-system 'pm)
|
|
214 (defvar eif-comment-font 'default
|
|
215 "The font in which to display comments in Eiffel and Ace files (either a font name string or 'default or 'context)")
|
|
216 (defvar eif-comment-color "firebrick"
|
|
217 "Color of comments in Eiffel and Ace files (either a color name string or 'default or 'context)")
|
|
218
|
|
219 (defvar eif-hidden-comment-font 'default
|
|
220 "The font in which to display hidden comments in Eiffel and Ace files (either a font name string or 'default or 'context)")
|
|
221 (defvar eif-hidden-comment-color "os2darkgreen"
|
|
222 "Color of hidden comments in Eiffel and Ace files (either a color name string or 'default or 'context)")
|
|
223
|
|
224 (defvar eif-major-keyword-font 'default
|
|
225 "The font in which to display major keywords in Eiffel and Ace files (either a font name string or 'default or 'context)")
|
|
226 (defvar eif-major-keyword-color 'default
|
|
227 "Color of major keywords in Eiffel and Ace files (either a color name string or 'default or 'context)")
|
|
228
|
|
229 (defvar eif-assertion-keyword-font 'default
|
|
230 "The font in which to display assertion keywords in Eiffel and Ace files (either a font name string or 'default or 'context)")
|
|
231 (defvar eif-assertion-keyword-color "os2darkblue"
|
|
232 "Color of assertion keywords in Eiffel and Ace files (either a color name string or 'default or 'context)")
|
|
233
|
|
234 (defvar eif-minor-keyword-font 'default
|
|
235 "The font in which to display minor keywords in Eiffel and Ace files (either a font name string or 'default or 'context)")
|
|
236 (defvar eif-minor-keyword-color 'default
|
|
237 "Color of minor-keywords in Eiffel and Ace files (either a color name string or 'default or 'context)")
|
|
238
|
|
239 (defvar eif-string-font 'default
|
|
240 "The font in which to display literal strings in Eiffel and Ace files (either a font name string or 'default or 'context)")
|
|
241 (defvar eif-string-color "os2darkcyan"
|
|
242 "Color of literal strings in Eiffel and Ace files (either a color name string or 'default or 'context)")
|
|
243
|
|
244 (defvar eif-quoted-feature-font 'default
|
|
245 "The font in which to display features names enclosed in `'s in Eiffel and Ace file comments (either a font name string or 'default or 'context)")
|
|
246 (defvar eif-quoted-feature-color 'context
|
|
247 "Color of features names enclosed in `'s in Eiffel and Ace file comments (either a color name string or 'default or 'context)")
|
|
248 )
|
|
249
|
|
250 ((eq window-system 'ns)
|
|
251 (defvar eif-comment-font 'default
|
|
252 "The font in which to display comments in Eiffel and Ace files (either a font name string or 'default or 'context)")
|
|
253 (defvar eif-comment-color "red3"
|
|
254 "Color of comments in Eiffel and Ace files (either a color name string or 'default or 'context)")
|
|
255
|
|
256 (defvar eif-hidden-comment-font 'default
|
|
257 "The font in which to display hidden comments in Eiffel and Ace files (either a font name string or 'default or 'context)")
|
|
258 (defvar eif-hidden-comment-color "ForestGreen"
|
|
259 "Color of hidden comments in Eiffel and Ace files (either a color name string or 'default or 'context)")
|
|
260
|
|
261 (defvar eif-major-keyword-font "Courier-Bold"
|
|
262 "The font in which to display major keywords in Eiffel and Ace files (either a font name string or 'default or 'context)")
|
|
263 (defvar eif-major-keyword-color 'default
|
|
264 "Color of major keywords in Eiffel and Ace files (either a color name string or 'default or 'context)")
|
|
265
|
|
266 (defvar eif-assertion-keyword-font "Courier-Bold"
|
|
267 "The font in which to display assertion keywords in Eiffel and Ace files (either a font name string or 'default or 'context)")
|
|
268 (defvar eif-assertion-keyword-color "slate blue"
|
|
269 "Color of assertion keywords in Eiffel and Ace files (either a color name string or 'default or 'context)")
|
|
270
|
|
271 (defvar eif-minor-keyword-font "Courier-Bold"
|
|
272 "The font in which to display minor keywords in Eiffel and Ace files (either a font name string or 'default or 'context)")
|
|
273 (defvar eif-minor-keyword-color 'default
|
|
274 "Color of minor-keywords in Eiffel and Ace files (either a color name string or 'default or 'context)")
|
|
275
|
|
276 (defvar eif-string-font 'default
|
|
277 "The font in which to display literal strings in Eiffel and Ace files (either a font name string or 'default or 'context)")
|
|
278 (defvar eif-string-color "sienna"
|
|
279 "Color of literal strings in Eiffel and Ace files (either a color name string or 'default or 'context)")
|
|
280
|
|
281 (defvar eif-quoted-feature-font 'default
|
|
282 "The font in which to display features names enclosed in `'s in Eiffel and Ace file comments (either a font name string or 'default or 'context)")
|
|
283 (defvar eif-quoted-feature-color 'context
|
|
284 "Color of features names enclosed in `'s in Eiffel and Ace file comments (either a color name string or 'default or 'context)")
|
|
285 )
|
|
286
|
|
287 ((eq window-system 'x)
|
|
288 (defvar eif-comment-font 'default
|
|
289 "The font in which to display comments in Eiffel and Ace files (either a font name string or 'default or 'context)")
|
|
290 (defvar eif-comment-color "red3"
|
|
291 "Color of comments in Eiffel and Ace files (either a color name string or 'default or 'context)")
|
|
292
|
|
293 (defvar eif-hidden-comment-font 'default
|
|
294 "The font in which to display hidden comments in Eiffel and Ace files (either a font name string or 'default or 'context)")
|
|
295 (defvar eif-hidden-comment-color "ForestGreen"
|
|
296 "Color of hidden comments in Eiffel and Ace files (either a color name string or 'default or 'context)")
|
|
297
|
|
298 (defvar eif-major-keyword-font "-*-fixed-bold-*-*-*-*-100-*-*-*-*-*-*"
|
|
299 "The font in which to display major keywords in Eiffel and Ace files (either a font name string or 'default or 'context)")
|
|
300 (defvar eif-major-keyword-color 'default
|
|
301 "Color of major keywords in Eiffel and Ace files (either a color name string or 'default or 'context)")
|
|
302
|
|
303 (defvar eif-assertion-keyword-font "-*-fixed-bold-*-*-*-*-100-*-*-*-*-*-*"
|
|
304 "The font in which to display assertion keywords in Eiffel and Ace files (either a font name string or 'default or 'context)")
|
|
305 (defvar eif-assertion-keyword-color "slate blue"
|
|
306 "Color of assertion keywords in Eiffel and Ace files (either a color name string or 'default or 'context)")
|
|
307
|
|
308 (defvar eif-minor-keyword-font "-*-fixed-bold-*-*-*-*-100-*-*-*-*-*-*"
|
|
309 "The font in which to display minor keywords in Eiffel and Ace files (either a font name string or 'default or 'context)")
|
|
310 (defvar eif-minor-keyword-color 'default
|
|
311 "Color of minor-keywords in Eiffel and Ace files (either a color name string or 'default or 'context)")
|
|
312
|
|
313 (defvar eif-string-font 'default
|
|
314 "The font in which to display literal strings in Eiffel and Ace files (either a font name string or 'default or 'context)")
|
|
315 (defvar eif-string-color "sienna"
|
|
316 "Color of literal strings in Eiffel and Ace files (either a color name string or 'default or 'context)")
|
|
317
|
|
318 (defvar eif-quoted-feature-font "-*-times-medium-i-*-*-*-120-*-*-*-*-*-*"
|
|
319 "The font in which to display features names enclosed in `'s in Eiffel and Ace file comments (either a font name string or 'default or 'context)")
|
|
320 (defvar eif-quoted-feature-color 'context
|
|
321 "Color of features names enclosed in `'s in Eiffel and Ace file comments (either a color name string or 'default or 'context)")
|
|
322 )
|
|
323 )
|
|
324
|
|
325 (defvar default-foreground-color 'default
|
|
326 "Default text color in Eiffel and Ace files (either a color name string or 'default or 'context)")
|
|
327
|
|
328 (defvar disable-color nil "Should hilighting not use colors")
|
|
329
|
|
330
|
|
331 (defun eif-set-foreground (face color)
|
|
332 "Set the FACE's foreground color to COLOR if COLOR is a string, to the default foreground color if COLOR is 'default, or to the color of the surrounding text if COLOR is 'context"
|
|
333 (cond ((stringp color)
|
|
334 ;; If the specified color is not useable, use 'default:
|
|
335 (condition-case error
|
|
336 (set-face-foreground face color)
|
|
337 (error
|
|
338 (progn
|
|
339 (message "eif-set-foreground failed for face %s and color %s. Setting to 'default" face color)
|
|
340 (eif-set-foreground face 'default)))
|
|
341 )
|
|
342 )
|
|
343 ((eq color 'context)
|
|
344 (remove-face-property face 'foreground)
|
|
345 )
|
|
346 ((eq color 'default)
|
|
347 (set-face-foreground face (face-foreground 'default))
|
|
348 )
|
|
349 )
|
|
350 )
|
|
351
|
|
352 (defun eif-set-font (face font)
|
|
353 "Set the FACE's font to FONT if FONT is a string, to the default font if FONT is 'default, or to the font of the surrounding text if FONT is 'context"
|
|
354 (cond ((stringp font)
|
|
355 ;; If the specified font is not useable, use 'default:
|
|
356 (condition-case error
|
|
357 (set-face-font face font)
|
|
358 (error
|
|
359 (progn
|
|
360 (message "eif-set-font failed for face %s and font %s. Setting to 'default" face font)
|
|
361 (eif-set-font face 'default)))
|
|
362 )
|
|
363 )
|
|
364 ((eq font 'context)
|
|
365 (set-face-font face nil)
|
|
366 )
|
|
367 ((eq font 'default)
|
|
368 (set-face-font face (face-font 'default))
|
|
369 )
|
|
370 )
|
|
371 )
|
|
372
|
|
373 (defun eif-supports-color-p ()
|
|
374 (and (not disable-color)
|
|
375 (or (and (fboundp 'display-color-p)
|
|
376 (display-color-p))
|
|
377 (and (fboundp 'x-display-color-p)
|
|
378 (x-display-color-p))
|
|
379 (and (fboundp 'x-color-display-p)
|
|
380 (x-color-display-p))
|
|
381 )
|
|
382 )
|
|
383 )
|
|
384
|
|
385 (defun eif-init-color ()
|
|
386 "Reset the Eiffel fonts and faces from the values of their repective variables"
|
|
387 (make-face 'eif-comment)
|
|
388 (make-face 'eif-hidden-comment)
|
|
389 (make-face 'eif-major-keyword)
|
|
390 (make-face 'eif-minor-keyword)
|
|
391 (make-face 'eif-quoted-feature)
|
|
392 (make-face 'eif-assertion)
|
|
393 (make-face 'eif-string)
|
|
394
|
|
395 (if (eif-supports-color-p)
|
|
396 (progn
|
|
397 (eif-set-foreground 'eif-comment eif-comment-color)
|
|
398 (eif-set-font 'eif-comment eif-comment-font)
|
|
399 (eif-set-foreground 'eif-hidden-comment eif-hidden-comment-color)
|
|
400 (eif-set-font 'eif-hidden-comment eif-hidden-comment-font)
|
|
401 (eif-set-foreground 'eif-quoted-feature eif-quoted-feature-color)
|
|
402 (eif-set-font 'eif-quoted-feature eif-quoted-feature-font)
|
|
403 (eif-set-foreground 'eif-major-keyword eif-major-keyword-color)
|
|
404 (eif-set-font 'eif-major-keyword eif-major-keyword-font)
|
|
405 (eif-set-foreground 'eif-minor-keyword eif-minor-keyword-color)
|
|
406 (eif-set-font 'eif-minor-keyword eif-minor-keyword-font)
|
|
407 (eif-set-foreground 'eif-assertion eif-assertion-keyword-color)
|
|
408 (eif-set-font 'eif-assertion eif-assertion-keyword-font)
|
|
409 (eif-set-foreground 'eif-string eif-string-color)
|
|
410 (eif-set-font 'eif-string eif-string-font)
|
|
411 )
|
|
412 (eif-set-foreground 'eif-comment default-foreground-color)
|
|
413 (eif-set-font 'eif-comment eif-comment-font)
|
|
414 (eif-set-foreground 'eif-hidden-comment default-foreground-color)
|
|
415 (eif-set-font 'eif-hidden-comment eif-hidden-comment-font)
|
|
416 (eif-set-foreground 'eif-quoted-feature default-foreground-color)
|
|
417 (eif-set-font 'eif-quoted-feature eif-quoted-feature-font)
|
|
418 (eif-set-foreground 'eif-major-keyword default-foreground-color)
|
|
419 (eif-set-font 'eif-major-keyword eif-major-keyword-font)
|
|
420 (eif-set-foreground 'eif-minor-keyword default-foreground-color)
|
|
421 (eif-set-font 'eif-minor-keyword eif-minor-keyword-font)
|
|
422 (eif-set-foreground 'eif-assertion default-foreground-color)
|
|
423 (eif-set-font 'eif-assertion eif-assertion-keyword-font)
|
|
424 (eif-set-foreground 'eif-string default-foreground-color)
|
|
425 (eif-set-font 'eif-string eif-string-font)
|
|
426 )
|
|
427
|
|
428 (cond ((featurep 'font-lock)
|
|
429 (copy-face 'eif-comment 'font-lock-comment-face)
|
|
430 (copy-face 'eif-string 'font-lock-string-face)
|
|
431 )
|
|
432 ((and (featurep 'hilit19)
|
|
433 (not (eq 'eif-comment (car hilit-predefined-face-list)))
|
|
434 )
|
|
435 (setq hilit-predefined-face-list
|
|
436 (append '(eif-comment
|
|
437 eif-hidden-comment
|
|
438 eif-major-keyword
|
|
439 eif-minor-keyword
|
|
440 eif-quoted-feature
|
|
441 eif-assertion
|
|
442 eif-string
|
|
443 )
|
|
444 hilit-predefined-face-list
|
|
445 )
|
|
446 )
|
|
447 )
|
|
448 )
|
|
449 )
|
|
450
|
|
451 (eif-init-color)
|
|
452
|
|
453 )) ;; matches "(if () (progn" above that checks for a highlighting package
|
|
454
|
|
455 (cond ((featurep 'font-lock)
|
|
456 (copy-face 'eif-comment 'font-lock-comment-face)
|
|
457 (copy-face 'eif-string 'font-lock-string-face)
|
|
458 (defconst eiffel-font-lock-keywords
|
|
459 (purecopy
|
|
460 '(;; major keywords
|
|
461 ("\\(^[ \t]*\\|[ \t]+\\)creation\\|^deferred[ \t]+class\\|^expanded[ \t]+class\\|^class\\|^feature\\|^indexing\\|\\(^[ \t]*\\|[ \t]+\\)inherit\\|^obsolete" 0 eif-major-keyword nil)
|
|
462 ;; assertions
|
|
463 ("\\(^\\|[^_\n]\\<\\)\\(check\\|ensure then\\|ensure\\|invariant\\|require else\\|require\\|variant\\)\\($\\|\\>[^_\n]\\)" 2 eif-assertion nil)
|
|
464 ;; minor keywords
|
|
465 ("\\(^\\|[^_\n]\\<\\)\\(alias\\|all\\|and not\\|and then\\|and\\|as\\|debug\\|deferred\\|do\\|else\\|elseif\\|end\\|export\\|external\\|from\\|frozen\\|if not\\|if\\|implies not\\|implies\\|infix\\|inspect\\|is deferred\\|is unique\\|is\\|like\\|local\\|loop\\|not\\|obsolete\\|old\\|once\\|or else\\|or not\\|or\\|prefix\\|redefine\\|rename\\|rescue\\|retry\\|select\\|strip\\|then\\|undefine\\|unique\\|until\\|when\\|xor\\)\\($\\|\\>[^_\n]\\)" 2 eif-minor-keyword nil)
|
|
466 ;; hidden comments
|
|
467 ("--|.*" 0 eif-hidden-comment t)
|
|
468 ;; quoted expr's in comments
|
|
469 ("`[^`'\n]*'" 0 eif-quoted-feature t)
|
|
470 )
|
|
471 )
|
|
472 "Regular expressions to use with font-lock mode.")
|
|
473 (defconst ace-font-lock-keywords
|
|
474 (purecopy
|
|
475 '(;; major keywords
|
|
476 ("^system\\|^default\\|^root\\|^cluster\\|^external\\|[ \t\n]end\\($\\|\\>[^_\n]\\)" 0 eif-major-keyword nil)
|
|
477 ;; hidden comments
|
|
478 ("--|.*" 0 eif-hidden-comment t)
|
|
479 ;; quoted expr's in comments
|
|
480 ("`[^`'\n]*'" 0 eif-quoted-feature t)
|
|
481 )
|
|
482 )
|
|
483 "Ace regular expressions to use with font-lock mode.")
|
|
484 )
|
|
485 ((featurep 'lhilit)
|
|
486
|
|
487 ;; ---- Eiffel mode -----
|
|
488 ;; NOTE: The order of keywords below is generally alphabetical except
|
|
489 ;; when one keyword is the prefix of another (e.g. "and" & "and then")
|
|
490 ;; In such cases, the prefix keyword MUST be the last one.
|
|
491 (defvar eiffel-mode-hilit
|
|
492 '(
|
|
493 ("--|.*" nil eif-hidden-comment 4);; hidden comments
|
|
494 ("--[^\n|].*\\|--$" nil eif-comment 3);; comments
|
|
495 ("`[^`'\n]*'" nil eif-quoted-feature 5);; quoted expr's in comments
|
|
496 ("^creation\\|^deferred[ \t]*class\\|^expanded[ \t]*class\\|^class\\|^feature\\|^indexing\\|^inherit\\|^obsolete" nil eif-major-keyword 1);; major keywords
|
|
497 ("\\(^\\|[^_\n]\\<\\)\\(alias\\|all\\|and not\\|and then\\|and\\|as\\|debug\\|deferred\\|do\\|else\\|elseif\\|end\\|export\\|external\\|from\\|frozen\\|if not\\|if\\|implies not\\|implies\\|infix\\|inspect\\|is deferred\\|is unique\\|is\\|like\\|local\\|loop\\|not\\|obsolete\\|old\\|once\\|or else\\|or not\\|or\\|prefix\\|redefine\\|rename\\|rescue\\|retry\\|select\\|strip\\|then\\|undefine\\|unique\\|until\\|when\\|xor\\)\\($\\|\\>[^_\n]\\)" nil eif-minor-keyword 0 2) ;; minor keywords
|
|
498 ("\\(^\\|[^_\n]\\<\\)\\(check\\|ensure then\\|ensure\\|invariant\\|require else\\|require\\|variant\\)\\($\\|\\>[^_\n]\\)" nil eif-assertion 2 2) ;; assertions
|
|
499 ("\\(\"\"\\)\\|\\(\"\\([^\"%]\\|%.\\|%\n\\)+\"\\)" nil eif-string 2);; strings
|
|
500 ))
|
|
501 (hilit::mode-list-update "Eiffel" eiffel-mode-hilit)
|
|
502 ;; ---- Ace mode -----
|
|
503 (defvar ace-mode-hilit
|
|
504 '(
|
|
505 ("--|.*" nil eif-hidden-comment 2);; hidden comments
|
|
506 ("--[^\n|].*\\|--$" nil eif-comment 1);; comments
|
|
507 ("`[^`'\n]*'" nil eif-quoted-feature 3);; quoted expr's in comments
|
|
508 ("^system\\|^default\\|^root\\|^cluster\\|^external\\|[ \t\n]end\\($\\|\\>[^_\n]\\)" nil eif-major-keyword);; major keywords
|
|
509
|
|
510 ))
|
|
511 (hilit::mode-list-update "Ace" ace-mode-hilit)
|
|
512 )
|
|
513 ;;
|
|
514 ;; NOTE: The hilit19 colors and fonts are _not_ set via the eif-*
|
|
515 ;; faces, fonts, and foreground variables defined above. They
|
|
516 ;; use their own face names which describe the colors and fonts
|
|
517 ;; to use. See hilit19.el for more info.
|
|
518 ((featurep 'hilit19)
|
|
519
|
|
520 ;; ---- Eiffel mode -----
|
|
521 ;; NOTE: The order of keywords below is generally alphabetical except
|
|
522 ;; when one keyword is the prefix of another (e.g. "and" & "and then")
|
|
523 ;; In such cases, the prefix keyword MUST be the last one.
|
|
524 (hilit-set-mode-patterns
|
|
525 'eiffel-mode
|
|
526 '(
|
|
527 ("--|.*" nil eif-hidden-comment 4);; hidden comments
|
|
528 ("--[^\n|].*\\|--$" nil eif-comment 3);; comments
|
|
529 ("`[^`'\n]*'" nil eif-quoted-feature 5);; quoted expr's in comments
|
|
530 ("^creation\\|^deferred[ \t]*class\\|^expanded[ \t]*class\\|^class\\|^feature\\|^indexing\\|^inherit\\|^obsolete" nil eif-major-keyword 1);; major keywords
|
|
531 ("\\(^\\|[^_\n]\\<\\)\\(alias\\|all\\|and not\\|and then\\|and\\|as\\|debug\\|deferred\\|do\\|else\\|elseif\\|end\\|export\\|external\\|from\\|frozen\\|if not\\|if\\|implies not\\|implies\\|infix\\|inspect\\|is deferred\\|is unique\\|is\\|like\\|local\\|loop\\|not\\|obsolete\\|old\\|once\\|or else\\|or not\\|or\\|prefix\\|redefine\\|rename\\|rescue\\|retry\\|select\\|strip\\|then\\|undefine\\|unique\\|until\\|when\\|xor\\)\\($\\|\\>[^_\n]\\)" 2 eif-minor-keyword 0) ;; minor keywords
|
|
532 ("\\(^\\|[^_\n]\\<\\)\\(check\\|ensure then\\|ensure\\|invariant\\|require else\\|require\\|variant\\)\\($\\|\\>[^_\n]\\)" 2 eif-assertion 2) ;; assertions
|
|
533 ("\\(\"\"\\)\\|\\(\"\\([^\"%]\\|%.\\|%\n\\)+\"\\)" nil eif-string 2);; strings
|
|
534 )
|
|
535 )
|
|
536 ;; ---- Ace mode -----
|
|
537 (hilit-set-mode-patterns
|
|
538 'ace-mode
|
|
539 '(
|
|
540 ("--|.*" nil eif-hidden-comment 2);; hidden comments
|
|
541 ("--[^\n|].*\\|--$" nil eif-comment 1);; comments
|
|
542 ("`[^`'\n]*'" nil eif-quoted-feature 3);; quoted expr's in comments
|
|
543 ("^system\\|^default\\|^root\\|^cluster\\|^external\\|[ \t\n]end\\($\\|\\>[^_\n]\\)" nil eif-major-keyword);; major keywords
|
|
544
|
|
545 )
|
|
546 )
|
|
547 )
|
|
548 )
|
|
549 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
550 ;;; No user-customizable definitions below this point. ;;;
|
|
551 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
552
|
|
553 (defmacro eif-class-level-kw-indent-m ()
|
|
554 "Indentation amount for Class level keywords (in number of spaces)."
|
|
555 '(+ (* eif-class-level-kw-indent eif-indent-increment)
|
|
556 eif-extra-class-level-kw-indent)
|
|
557 )
|
|
558
|
|
559 (defmacro eif-class-level-comment-indent-m ()
|
|
560 "Indentation amount for Class level comments (in number of spaces)."
|
|
561 '(+ (* eif-class-level-comment-indent eif-indent-increment)
|
|
562 eif-extra-class-level-comment-indent)
|
|
563 )
|
|
564
|
|
565 (defmacro eif-inherit-level-kw-indent-m ()
|
|
566 "Indentation amount for Inherit level keywords (in number of spaces)."
|
|
567 '(+ (* eif-inherit-level-kw-indent eif-indent-increment)
|
|
568 eif-extra-inherit-level-kw-indent)
|
|
569 )
|
|
570
|
|
571 (defmacro eif-feature-level-indent-m ()
|
|
572 "Indentation amount for features (in number of spaces)."
|
|
573 '(+ (* eif-feature-level-indent eif-indent-increment)
|
|
574 eif-extra-feature-level-indent)
|
|
575 )
|
|
576
|
|
577 (defmacro eif-feature-level-kw-indent-m ()
|
|
578 "Indentation amount for Feature level keywords (in number of spaces)."
|
|
579 '(+ (* eif-feature-level-kw-indent eif-indent-increment)
|
|
580 eif-extra-feature-level-kw-indent)
|
|
581 )
|
|
582
|
|
583 (defmacro eif-body-comment-indent-m ()
|
|
584 "Indentation amount for comments in routine bodies (in number of spaces)."
|
|
585 '(+ (* eif-body-comment-indent eif-indent-increment)
|
|
586 eif-extra-body-comment-indent)
|
|
587 )
|
|
588
|
|
589 (defmacro eif-feature-level-comment-indent-m ()
|
|
590 "Indentation amount for Feature level comments (in number of spaces)."
|
|
591 '(+ (* eif-feature-level-comment-indent eif-indent-increment)
|
|
592 eif-extra-feature-level-comment-indent)
|
|
593 )
|
|
594
|
|
595 (defmacro eif-check-keyword-indent-m ()
|
|
596 "Indentation amount for Check keyword (in number of spaces)."
|
|
597 '(+ (* eif-check-keyword-indent eif-indent-increment)
|
|
598 eif-extra-check-keyword-indent)
|
|
599 )
|
|
600
|
|
601 (defmacro eif-rescue-keyword-indent-m ()
|
|
602 "Indentation amount for Rescue keyword (in number of spaces)."
|
|
603 '(+ (* eif-rescue-keyword-indent eif-indent-increment)
|
|
604 eif-extra-rescue-keyword-indent)
|
|
605 )
|
|
606
|
|
607 (defmacro eif-then-indent-m ()
|
|
608 "Indentation amount for `then' appearing on a line by itself (in number of spaces)."
|
|
609 '(+ (* eif-then-indent eif-indent-increment)
|
|
610 eif-extra-then-indent)
|
|
611 )
|
|
612
|
|
613 (defmacro eif-continuation-indent-m ()
|
|
614 "Indentation amount for a statement continuation line (in number of spaces)."
|
|
615 '(+ (* eif-continuation-indent eif-indent-increment)
|
|
616 eif-extra-continuation-indent)
|
|
617 )
|
|
618 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
619 ;;; Keyword Regular Expression Variables. ;;;
|
|
620 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
621
|
|
622 (defvar eif-all-keywords-regexp
|
|
623 "\\(indexing\\|class\\|inherit\\|creation\\|feature\\|invariant\\|rename\
|
|
624 \\|redefine\\|undefine\\|select\\|export\\|require\\|local\\|deferred\
|
|
625 \\|do\\|once\\|ensure\\|alias\\|external\\|check\\|rescue\\|debug\\|if\
|
|
626 \\|inspect\\|from\\|else\\|elseif\\|when\\|until\\|variant\\|loop\\|then\
|
|
627 \\|obsolete\\|end\\)[^a-z0-9_]"
|
|
628 "Regular Expression to identify the presence of any eiffel keyword in a line.
|
|
629 Does not include `is'."
|
|
630 )
|
|
631
|
|
632 ;; Note invariant is handled as a special case since it is both a
|
|
633 ;; class-level and a from-level keyword
|
|
634 ;; Note obsolete is handled as a special case since it is both a
|
|
635 ;; class-level and a feature-level keyword
|
|
636 (defvar eif-class-level-keywords
|
|
637 "\\(indexing\\|class\\|deferred[ \t]*class\\|expanded[ \t]*class\\|inherit\\|creation\\|feature\\)[^a-z0-9_]"
|
|
638 "Those keywords introducing class-level clauses. Note that `invariant'
|
|
639 and `obsolete' are not included here since can function as more than one type of keyword. "
|
|
640 )
|
|
641
|
|
642 (defvar eif-inherit-level-keywords
|
|
643 "\\(rename\\|redefine\\|undefine\\|select\\|export\\)"
|
|
644 "Those keywords which introduce subclauses of the inherit clause."
|
|
645 )
|
|
646
|
|
647 (defvar eif-feature-level-keywords
|
|
648 "\\(require\\|local\\|deferred\\|do\\|once\\|ensure\\|alias\\|external\\)[^a-z0-9_]"
|
|
649 "Those keywords which are internal to features (in particular, routines)."
|
|
650 )
|
|
651
|
|
652 (defvar eif-end-keyword "end" "The `end' keyword.")
|
|
653
|
|
654 (defvar eif-end-on-current-line ".*[ \t]end[ \t]*;?[ \t]*\\(--.*\\)?$"
|
|
655 "Regular expression to identify lines ending with the `end' keyword")
|
|
656
|
|
657 (defvar eif-non-id-char-regexp "[^a-z0-9_]"
|
|
658 "The characters that are not part of identifiers.")
|
|
659
|
|
660 (defvar eif-end-keyword-regexp "[^a-z0-9_]end[^a-z0-9_]"
|
|
661 "The `end' keyword with context.")
|
|
662
|
|
663 (defvar eif-end-matching-keywords
|
|
664 "\\(check\\|class\\|feature\\|rename\\|redefine\\|undefine\\|select\\|export\\|do\\|once\\|deferred\\|external\\|alias\\|if\\|inspect\\|from\\|debug\\)[^a-z0-9_]"
|
|
665 "Those keywords whose clause is terminated by an `end' keyword."
|
|
666 )
|
|
667
|
|
668 (defvar eif-control-flow-keywords
|
|
669 "\\(if\\|inspect\\|from\\|debug\\)"
|
|
670 "Keywords which introduce control-flow constructs."
|
|
671 )
|
|
672
|
|
673 (defvar eif-control-flow-matching-keywords
|
|
674 "\\(deferred\\|do\\|once\\|if\\|inspect\\|from\\|debug\\)[^a-z0-9_]"
|
|
675 "Keywords whose occurrence prior to a control-flow-keyword causes the
|
|
676 indentation of the control-flow-keyword. Note that technically,
|
|
677 `end' is part of this list but it is handled separately in the
|
|
678 functions: eif-matching-indent and eif-matching-kw."
|
|
679 )
|
|
680
|
|
681 (defvar eif-check-keyword "check" "The `check' keyword.")
|
|
682
|
|
683 (defvar eif-check-keywords "\\(check\\)[^a-z0-9_]"
|
|
684 "The `check' keyword (with trailing context).")
|
|
685
|
|
686 (defvar eif-check-matching-keywords
|
|
687 "\\(deferred\\|do\\|once\\|if\\|inspect\\|from\\|debug\\)[^a-z0-9_]"
|
|
688 "Keywords whose occurrence prior to a check-keyword causes the
|
|
689 indentation of the check-keyword. Note that technically, `end' is
|
|
690 part of this list but it is handled separately in the functions:
|
|
691 eif-matching-indent and eif-matching-kw. (see also
|
|
692 eif-control-flow-matching-keywords)"
|
|
693 )
|
|
694
|
|
695 (defvar eif-rescue-keyword "rescue" "The `rescue' keyword.")
|
|
696
|
|
697 (defvar eif-obsolete-keyword "obsolete" "The `obsolete' keyword.")
|
|
698
|
|
699 (defvar eif-rescue-keywords "\\(rescue\\)[^a-z0-9_]"
|
|
700 "The `rescue' keyword (with trailing context).")
|
|
701
|
|
702 (defvar eif-rescue-matching-keywords
|
|
703 "\\(deferred\\|do\\|once\\)[^a-z0-9_]"
|
|
704 "Keywords whose occurrence prior to a rescue-keyword causes the
|
|
705 indentation of the rescue-keyword. Note that technically, `end' is
|
|
706 part of this list but it is handled separately in the functions:
|
|
707 eif-matching-indent and eif-matching-kw. (see also
|
|
708 eif-control-flow-matching-keywords)"
|
|
709 )
|
|
710
|
|
711 (defvar eif-from-level-keywords
|
|
712 "\\(until\\|variant\\|loop\\)[^a-z0-9_]"
|
|
713 "Keywords occuring inside of a from clause."
|
|
714 )
|
|
715
|
|
716 (defvar eif-from-keyword "from" "The keyword `from'.")
|
|
717
|
|
718 (defvar eif-if-or-inspect-level-keywords "\\(elseif\\|else\\|when\\)[^a-z0-9_]"
|
|
719 "Keywords occuring inside of an if or inspect clause."
|
|
720 )
|
|
721
|
|
722 (defvar eif-if-or-inspect-keyword "\\(if\\|inspect\\)[^a-z0-9_]"
|
|
723 "The `if' or `inspect' keywords."
|
|
724 )
|
|
725
|
|
726 (defvar eif-then-keyword ".*[ \t)]then[ \t]*$"
|
|
727 "The keyword `then' with possible leading text.")
|
|
728
|
|
729 (defvar eif-solitary-then-keyword "then" "The keyword `then'.")
|
|
730
|
|
731 (defvar eif-then-matching-keywords "\\(if\\|elseif\\|when\\)"
|
|
732 "Keywords whose occurrence prior to a then-keyword sets the
|
|
733 indentation of the then-keyword. Note that technically, `end' is
|
|
734 part of this list but it is handled separately in the functions:
|
|
735 eif-matching-indent and eif-matching-kw. (see also
|
|
736 eif-control-flow-matching-keywords)"
|
|
737 )
|
|
738
|
|
739 (defvar eif-invariant-keyword "invariant" "The `invariant' keyword.")
|
|
740
|
|
741 (defvar eif-invariant-matching-keywords
|
|
742 "\\(from\\|feature\\)"
|
|
743 "Keywords whose occurrence prior to an invariant-keyword causes the
|
|
744 indentation of the invariant-keyword. Note that technically, `end'
|
|
745 is part of this list but it is handled separately in the functions:
|
|
746 eif-matching-indent and eif-matching-kw. (see also
|
|
747 eif-control-flow-matching-keywords)"
|
|
748 )
|
|
749
|
|
750 (defvar eif-obsolete-matching-keywords
|
|
751 "\\(is\\|class\\)"
|
|
752 "Keywords whose occurrence prior to an obsolete-keyword causes the
|
|
753 indentation of the obsolete-keyword."
|
|
754 )
|
|
755
|
|
756 (defvar eif-white-space-regexp "[ ]*"
|
|
757 "RE to locate whitespace.")
|
|
758
|
|
759 (defvar eif-comment-line-regexp "[ ]*\\(--.*\\)$"
|
|
760 "RE to match a line with a comment on it.")
|
|
761
|
|
762 (defvar eif-non-source-line "[ ]*\\(--.*\\)?$"
|
|
763 "RE to match a line with a only a comment or whitespace.")
|
|
764
|
|
765 (defvar eif-variable-or-const-regexp "[^()\n]*:[^=].*"
|
|
766 "RE to match a variable or constant declaration.")
|
|
767
|
|
768 (defvar eif-indentation-keywords-regexp
|
|
769 "\\(indexing\\|class\\|check\\|rescue\\|inherit\\|creation\\|feature\\|invariant\\|rename\\|redefine\\|undefine\\|select\\|export\\|require\\|local\\|deferred\\|do\\|once\\|ensure\\|alias\\|external\\|if\\|inspect\\|from\\|debug\\|else\\|elseif\\|when\\|until\\|variant\\|invariant\\|loop\\|obsolete\\)[^a-z0-9_]"
|
|
770 "RE to identify the presence of any eiffel keyword triggering indentation"
|
|
771 )
|
|
772
|
|
773 (defvar eif-feature-indentation-keywords-regexp
|
|
774 "\\(creation\\|feature\\)[^a-z0-9_]"
|
|
775 "Keywords which denote the presence of features following them."
|
|
776 )
|
|
777
|
|
778 (defvar eif-is-keyword-regexp "\\(.*[ )]\\)?is[ ]*\\(--.*\\)?$"
|
|
779 "The `is' keyword (with some context)."
|
|
780 )
|
|
781
|
|
782 (defvar eif-multiline-routine-is-keyword-regexp
|
|
783 ".*([^)]*)\\([ \t\n]*\\|[ \t\n]*:[][ \t\nA-Za-x0-9_,]*\\)is[ ]*\\(--.*\\)?$"
|
|
784 "The `is' keyword (with some context)."
|
|
785 )
|
|
786
|
|
787 (defvar eif-operator-regexp
|
|
788 "[ ]*\\([@*/+]\\|-[^-]\\|\\<and[ (]\\|\\<or[ (]\\)"
|
|
789 "Eiffel operators - used to identify continuation lines"
|
|
790 )
|
|
791
|
|
792 (defvar eif-operator-eol-regexp
|
|
793 ".*\\([@*/+-]\\|\\<and\\|\\<or\\|:=\\)[ ]*$"
|
|
794 "Eiffel operators - used to identify continuation lines"
|
|
795 )
|
|
796
|
|
797 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
798
|
|
799 (defvar eif-matching-indent -1
|
|
800 "The indentation of the keyword found on the last call to eif-matching-kw.
|
|
801 -1 if no match was found."
|
|
802 )
|
|
803
|
|
804 (defvar eif-matching-kw-for-end nil)
|
|
805
|
|
806 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
807 ;;; Indentation Functions. ;;;
|
|
808 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
809
|
|
810 (defun eif-calc-indent ()
|
|
811 "Calculate the indentation of the current line of eiffel code. This
|
|
812 function generally assumes that the preceding line of code is
|
|
813 indented properly, although lines containing certain class-level
|
|
814 constructs do not require correct indentation of the preceding line."
|
|
815 (let ((indent 0)
|
|
816 (line-end 0)
|
|
817 (originally-looking-at-comment nil)
|
|
818 (kw-match nil)
|
|
819 (continuation)
|
|
820 (id-colon)
|
|
821 )
|
|
822
|
|
823 (save-excursion
|
|
824
|
|
825 ;; Save location of line-end and skip past leading white space.
|
|
826 (end-of-line)
|
|
827 (setq line-end (point))
|
|
828 (beginning-of-line)
|
|
829 (re-search-forward eif-white-space-regexp line-end t)
|
|
830
|
|
831 ;; Is the line we are trying to indent a comment line?
|
|
832 (setq originally-looking-at-comment (looking-at eif-comment-line-regexp))
|
|
833
|
|
834 ;; Look for a keyword on the current line
|
|
835 (if (looking-at eif-all-keywords-regexp)
|
|
836
|
|
837 ;; Then we are looking at a keyword
|
|
838 (cond ((looking-at eif-class-level-keywords)
|
|
839 ;; File level keywords (indent defaults to 0)
|
|
840 (setq indent (eif-class-level-kw-indent-m))
|
|
841 )
|
|
842 ((looking-at eif-inherit-level-keywords)
|
|
843 ;; Inherit level keywords (indent defaults to
|
|
844 ;; 2*eif-indent-increment)
|
|
845 (setq indent (eif-inherit-level-kw-indent-m))
|
|
846 )
|
|
847 ((looking-at eif-feature-level-keywords)
|
|
848 ;; Feature level keywords (indent defaults to
|
|
849 ;; (eif-feature-level-indent-m) + eif-indent-increment)
|
|
850 (setq indent (eif-feature-level-kw-indent-m))
|
|
851 )
|
|
852 ((looking-at eif-end-keyword)
|
|
853 ;; End keyword (indent to level of matching keyword)
|
|
854 (if (string-match "end"
|
|
855 (eif-matching-kw eif-end-matching-keywords))
|
|
856 ;; Then
|
|
857 (if (= eif-matching-indent
|
|
858 (eif-feature-level-kw-indent-m))
|
|
859 ;; Then
|
|
860 (setq indent (eif-class-level-kw-indent-m))
|
|
861 ;; Else
|
|
862 (setq indent
|
|
863 (- eif-matching-indent eif-indent-increment))
|
|
864 )
|
|
865 ;; Else
|
|
866 (setq indent eif-matching-indent)
|
|
867 )
|
|
868 (if (<= indent (eif-feature-level-indent-m))
|
|
869 (save-excursion
|
|
870 (end-of-line)
|
|
871 (while (and (< (point) (point-max))
|
|
872 (or (forward-char 1) t)
|
|
873 (looking-at eif-non-source-line)
|
|
874 )
|
|
875 (end-of-line)
|
|
876 )
|
|
877 (if (not (looking-at eif-non-source-line))
|
|
878 (setq indent (eif-inherit-level-kw-indent-m))
|
|
879 (setq indent (eif-class-level-kw-indent-m))
|
|
880 )
|
|
881 )
|
|
882 )
|
|
883 )
|
|
884 ((looking-at eif-control-flow-keywords)
|
|
885 ;; Control flow keywords
|
|
886 ;; Indent to same level as a preceding "end" or
|
|
887 ;; if no preceding "end" is found, indent to the level
|
|
888 ;; of the preceding "do" plus the value of
|
|
889 ;; eif-indent-increment
|
|
890 (setq kw-match
|
|
891 (eif-matching-kw eif-control-flow-matching-keywords))
|
|
892 (cond ((string-match "end" kw-match)
|
|
893 (setq indent eif-matching-indent)
|
|
894 )
|
|
895 (t
|
|
896 (setq indent
|
|
897 (+ eif-matching-indent eif-indent-increment)
|
|
898 )
|
|
899 )
|
|
900 )
|
|
901 )
|
|
902 ((looking-at eif-check-keywords)
|
|
903 ;; Check keyword
|
|
904 ;; Indent to level of preceding "end"+eif-indent-increment or
|
|
905 ;; if no preceding "end" is found, indent to the level
|
|
906 ;; of the preceding eif-check-matching-keywords plus the
|
|
907 ;; value (eif-indent-increment + eif-check-keyword-indent).
|
|
908 (setq kw-match (eif-matching-kw eif-check-matching-keywords))
|
|
909 (cond ((string-match "end" kw-match)
|
|
910 (setq indent (+ eif-matching-indent
|
|
911 (eif-check-keyword-indent-m)
|
|
912 )
|
|
913 )
|
|
914 )
|
|
915 (t
|
|
916 (setq indent
|
|
917 (+ eif-matching-indent
|
|
918 (+ eif-indent-increment
|
|
919 (eif-check-keyword-indent-m)
|
|
920 )
|
|
921 )
|
|
922 )
|
|
923 )
|
|
924 )
|
|
925 )
|
|
926 ((looking-at eif-rescue-keywords)
|
|
927 ;; Rescue keyword
|
|
928 ;; Indent to level of preceding "end"+eif-indent-increment or
|
|
929 ;; if no preceding "end" is found, indent to the level
|
|
930 ;; of the preceding eif-rescue-matching-keywords plus the
|
|
931 ;; value (eif-indent-increment + eif-rescue-keyword-indent).
|
|
932 (setq kw-match (eif-matching-kw eif-rescue-matching-keywords))
|
|
933 (cond ((string-match "end" kw-match)
|
|
934 (setq indent (+ eif-matching-indent
|
|
935 (eif-rescue-keyword-indent-m)
|
|
936 )
|
|
937 )
|
|
938 )
|
|
939 (t
|
|
940 (setq indent eif-matching-indent)
|
|
941 )
|
|
942 )
|
|
943 )
|
|
944 ((looking-at eif-from-level-keywords)
|
|
945 ;; From level keywords (indent to level of matching "From")
|
|
946 (if (string-match "end" (eif-matching-kw eif-from-keyword))
|
|
947 ;; Closest matching KW is `end'.
|
|
948 (setq indent (- eif-matching-indent eif-indent-increment))
|
|
949 ;; Closest matching KW is one of `eif-from-keyword'.
|
|
950 (setq indent eif-matching-indent)
|
|
951 )
|
|
952 )
|
|
953 ((looking-at eif-if-or-inspect-level-keywords)
|
|
954 ;; If level keywords (indent to level of matching
|
|
955 ;; "If" or "Inspect")
|
|
956 (if (string-match "end"
|
|
957 (eif-matching-kw eif-if-or-inspect-keyword)
|
|
958 )
|
|
959 ;; Closest matching KW is `end'.
|
|
960 (setq indent (- eif-matching-indent eif-indent-increment))
|
|
961 ;; Closest matching KW is one of `eif-if-or-inspect-keyword'.
|
|
962 (setq indent eif-matching-indent)
|
|
963 )
|
|
964 )
|
|
965 ((looking-at eif-solitary-then-keyword)
|
|
966 ;; Handles case where "then" appears on a line by itself
|
|
967 ;; (Indented to the level of the matching if, elseif or when)
|
|
968 (setq indent (+ (eif-matching-indent eif-then-matching-keywords)
|
|
969 (eif-then-indent-m)
|
|
970 )
|
|
971 )
|
|
972 )
|
|
973 ((looking-at eif-invariant-keyword)
|
|
974 ;; Invariant keyword
|
|
975 ;; (Indented to the level of the matching from or feature)
|
|
976 (if (string-match "from"
|
|
977 (eif-matching-kw eif-invariant-matching-keywords)
|
|
978 )
|
|
979 ;; Then - loop invariant
|
|
980 (setq indent eif-matching-indent)
|
|
981 ;; Else - class invariant
|
|
982 (setq indent (eif-class-level-kw-indent-m))
|
|
983 )
|
|
984 )
|
|
985 ((looking-at eif-obsolete-keyword)
|
|
986 ;; Obsolete keyword
|
|
987 ;; (Indented to the level of the matching from or feature)
|
|
988 (if (string-match "is"
|
|
989 (eif-matching-kw eif-obsolete-matching-keywords)
|
|
990 )
|
|
991 ;; Then - feature obsolete
|
|
992 (setq indent (eif-feature-level-kw-indent-m))
|
|
993 ;; Else - class obsolete
|
|
994 (setq indent (eif-class-level-kw-indent-m))
|
|
995 )
|
|
996 ) ;; end of cond
|
|
997 )
|
|
998
|
|
999 ;; Else no keyword on current line,
|
|
1000 ;; are we in a multi-line parenthesis expression
|
|
1001
|
|
1002 (if (or (and (> (eif-in-paren-expression) 0)
|
|
1003 (> (setq indent (eif-indent-multi-line)) -1)
|
|
1004 )
|
|
1005 (setq indent (eif-manifest-array-indent))
|
|
1006 )
|
|
1007
|
|
1008 ;; multi-line parenthesis expression
|
|
1009 ;; Move string continuation lines one column to the left
|
|
1010 (if (looking-at "%")
|
|
1011 (setq indent (1- indent))
|
|
1012 )
|
|
1013
|
|
1014 ;; Else Find the first preceding line with non-comment source on it
|
|
1015 ;; that is not a continuation line of a multi-line parnethesized
|
|
1016 ;; expression.
|
|
1017
|
|
1018 ;; Record whether this line begins with an operator. We assume
|
|
1019 ;; that the line is a continuation line if it begins with an operator
|
|
1020 (beginning-of-line)
|
|
1021 (if (looking-at eif-operator-regexp)
|
|
1022 (setq continuation t)
|
|
1023 (setq continuation nil)
|
|
1024 )
|
|
1025 ;; Record whether the line being indented begins with an "<id> :"
|
|
1026 ;; This is used in indenting assertion tag expressions.
|
|
1027 (if (looking-at "[ ]*[a-zA-Z0-9_]+[ ]*:")
|
|
1028 (setq id-colon t)
|
|
1029 (setq id-colon nil)
|
|
1030 )
|
|
1031
|
|
1032 (forward-line -1)
|
|
1033 (beginning-of-line)
|
|
1034 (while (and (looking-at eif-non-source-line) (not (= (point) 1)))
|
|
1035 (previous-line 1)
|
|
1036 (beginning-of-line)
|
|
1037 )
|
|
1038 (if (eif-line-contains-close-paren)
|
|
1039 (backward-sexp)
|
|
1040 )
|
|
1041 (end-of-line)
|
|
1042 (setq line-end (point))
|
|
1043 (beginning-of-line)
|
|
1044 (re-search-forward eif-white-space-regexp line-end t)
|
|
1045
|
|
1046 (cond ((and (= (point) 1)
|
|
1047 originally-looking-at-comment
|
|
1048 (setq indent (eif-class-level-comment-indent-m))
|
|
1049 )
|
|
1050 )
|
|
1051 ;; 'eif-is-keyword-regexp' case must precede
|
|
1052 ;; '(not eif-all-keywords-regexp)' case since "is" is not
|
|
1053 ;; part of 'eif-all-keywords-regexp'
|
|
1054 ((or (looking-at eif-is-keyword-regexp)
|
|
1055 (looking-at eif-multiline-routine-is-keyword-regexp)
|
|
1056 (looking-at eif-obsolete-keyword)
|
|
1057 )
|
|
1058 (if originally-looking-at-comment
|
|
1059 ;; Then the line we are trying to indent is a comment
|
|
1060 (setq indent (eif-feature-level-comment-indent-m))
|
|
1061 ;; Else the line being indented is not a comment
|
|
1062 (setq indent (eif-feature-level-kw-indent-m))
|
|
1063 )
|
|
1064 )
|
|
1065 ((looking-at eif-feature-indentation-keywords-regexp)
|
|
1066 (setq indent (eif-feature-level-indent-m))
|
|
1067 )
|
|
1068 ((looking-at eif-indentation-keywords-regexp)
|
|
1069 (if (looking-at eif-end-on-current-line)
|
|
1070 (setq indent (eif-current-line-indent))
|
|
1071 (setq indent
|
|
1072 (+ (eif-current-line-indent) eif-indent-increment))
|
|
1073 )
|
|
1074 )
|
|
1075 ((looking-at eif-solitary-then-keyword)
|
|
1076 (setq indent (- (+ (eif-current-line-indent) eif-indent-increment)
|
|
1077 (eif-then-indent-m)
|
|
1078 )
|
|
1079 )
|
|
1080 )
|
|
1081 ((looking-at eif-then-keyword)
|
|
1082 (setq indent (eif-current-line-indent))
|
|
1083 )
|
|
1084 ((looking-at (concat eif-end-keyword eif-non-id-char-regexp))
|
|
1085 (if (= (setq indent (eif-current-line-indent))
|
|
1086 (eif-feature-level-kw-indent-m)
|
|
1087 )
|
|
1088 (setq indent (eif-feature-level-indent-m))
|
|
1089 (eif-matching-line)
|
|
1090 (if (string-match eif-check-keyword eif-matching-kw-for-end)
|
|
1091 (setq indent (- indent (eif-check-keyword-indent-m)))
|
|
1092 )
|
|
1093 )
|
|
1094 )
|
|
1095 ((looking-at eif-variable-or-const-regexp)
|
|
1096 ;;Either a variable declaration or a pre or post condition tag
|
|
1097 (if originally-looking-at-comment
|
|
1098 ;; Then the line we are trying to indent is a comment
|
|
1099 (if (= (setq indent (eif-current-line-indent))
|
|
1100 (eif-feature-level-indent-m)
|
|
1101 )
|
|
1102 ;; Then - a feature level comment
|
|
1103 (setq indent (eif-feature-level-comment-indent-m))
|
|
1104 ;; Else - some other kind of comment
|
|
1105 (setq indent (+ indent (eif-body-comment-indent-m)))
|
|
1106 )
|
|
1107 ;; Else the line being indented is not a comment
|
|
1108 (if (setq indent (eif-indent-assertion-continuation id-colon))
|
|
1109 indent
|
|
1110 (setq indent (eif-current-line-indent))
|
|
1111 )
|
|
1112 )
|
|
1113 )
|
|
1114 ((setq indent (eif-manifest-array-start))
|
|
1115 indent
|
|
1116 )
|
|
1117 ((not (looking-at eif-all-keywords-regexp))
|
|
1118 (if originally-looking-at-comment
|
|
1119 ;; Then the line we are trying to indent is a comment
|
|
1120 (cond ((eif-continuation-line)
|
|
1121 (setq indent
|
|
1122 (+ (- (eif-current-line-indent)
|
|
1123 eif-indent-increment
|
|
1124 )
|
|
1125 (eif-body-comment-indent-m)
|
|
1126 )
|
|
1127 )
|
|
1128 )
|
|
1129 ;; preceding line is at eif-feature-level-indent -
|
|
1130 ;; assume that the preceding line is a parent
|
|
1131 ;; class in an inherit clause
|
|
1132 ((= (eif-current-line-indent)
|
|
1133 (eif-feature-level-indent-m)
|
|
1134 )
|
|
1135 (setq indent
|
|
1136 (+ (eif-inherit-level-kw-indent-m)
|
|
1137 (eif-body-comment-indent-m)
|
|
1138 )
|
|
1139 )
|
|
1140 )
|
|
1141 (t
|
|
1142 (setq indent
|
|
1143 (+ (eif-current-line-indent)
|
|
1144 (eif-body-comment-indent-m)
|
|
1145 )
|
|
1146 )
|
|
1147 )
|
|
1148 )
|
|
1149 ;; Else line being indented is not a comment
|
|
1150
|
|
1151 ;; The line the point is on is the one above the line being
|
|
1152 ;; indented
|
|
1153 (beginning-of-line)
|
|
1154 (if (or continuation (looking-at eif-operator-eol-regexp))
|
|
1155 ;; Then the line being indented is a continuation line
|
|
1156 (if (eif-continuation-line)
|
|
1157 ;; The line preceding the line being indented is
|
|
1158 ;; also a continuation line. Indent to the current
|
|
1159 ;; line indentation.
|
|
1160 (setq indent (eif-current-line-indent))
|
|
1161 ;; Else The line preceding the line being indented is
|
|
1162 ;; not a continuation line. Indent an extra
|
|
1163 ;; eif-continuation-indent
|
|
1164 (setq indent (+ (eif-current-line-indent)
|
|
1165 (eif-continuation-indent-m)))
|
|
1166 )
|
|
1167 ;; Else the line being indented is not a continuation line.
|
|
1168 (if (eif-continuation-line)
|
|
1169 (if id-colon
|
|
1170 ;; Then the line preceding the one being indented
|
|
1171 ;; is an assertion continuation. Indent the current
|
|
1172 ;; line to the same level as the preceding assertion
|
|
1173 ;; tag.
|
|
1174 (setq indent (eif-indent-assertion-tag))
|
|
1175 ;; Then the line preceding the one being indented is
|
|
1176 ;; a continuation line. Un-indent by an
|
|
1177 ;; eif-continuation-indent.
|
|
1178 (setq indent (- (eif-current-line-indent)
|
|
1179 eif-indent-increment
|
|
1180 )
|
|
1181 )
|
|
1182 )
|
|
1183 ;; Else the line preceding the line being indented is
|
|
1184 ;; also not a continuation line. Use the current indent.
|
|
1185 (setq indent (eif-current-line-indent))
|
|
1186 )
|
|
1187 )
|
|
1188 )
|
|
1189 )
|
|
1190 ) ;; cond
|
|
1191 ) ;; if
|
|
1192 ) ;; if
|
|
1193 ) ;; save-excursion
|
|
1194 indent
|
|
1195 ) ;; let
|
|
1196 )
|
|
1197
|
|
1198 (defun eif-continuation-line ()
|
|
1199 (or (looking-at eif-operator-regexp)
|
|
1200 (save-excursion
|
|
1201 (forward-line -1)
|
|
1202 (beginning-of-line)
|
|
1203 (looking-at eif-operator-eol-regexp)
|
|
1204 )
|
|
1205 )
|
|
1206 )
|
|
1207
|
|
1208 (defun eif-indent-assertion-continuation (id-colon)
|
|
1209 "Are we inside a pre or a post condition clause on a line that is a
|
|
1210 continuation of a multi-line assertion beginning with a tag? If so, return
|
|
1211 the indentation of the continuation line."
|
|
1212 (let ((limit (point)))
|
|
1213 (if (save-excursion
|
|
1214 (if (re-search-backward (concat eif-feature-level-keywords "\\|"
|
|
1215 eif-end-keyword-regexp) nil t)
|
|
1216 (if (looking-at "ensure\\|require")
|
|
1217 (setq limit (point))
|
|
1218 nil
|
|
1219 )
|
|
1220 nil
|
|
1221 )
|
|
1222 )
|
|
1223 (save-excursion
|
|
1224 (end-of-line)
|
|
1225 (if (and (not id-colon) (re-search-backward ": *" limit t))
|
|
1226 (progn
|
|
1227 (goto-char (match-end 0))
|
|
1228 (current-column)
|
|
1229 )
|
|
1230 nil
|
|
1231 )
|
|
1232 )
|
|
1233 nil
|
|
1234 )
|
|
1235 )
|
|
1236 )
|
|
1237
|
|
1238 (defun eif-indent-assertion-tag ()
|
|
1239 "Are we inside a pre or a post condition clause on a line that is a
|
|
1240 continuation of a multi-line assertion beginning with a tag? If so, return
|
|
1241 the indentation of the continuation line."
|
|
1242 (let (indent)
|
|
1243 (save-excursion
|
|
1244 (if (re-search-backward "ensure\\|require\\|variant\\|invariant" nil t)
|
|
1245 (setq indent (+ (eif-current-line-indent) eif-indent-increment))
|
|
1246 ;; This option should not occur
|
|
1247 (error "Could not find assertion tag.")
|
|
1248 )
|
|
1249 )
|
|
1250 )
|
|
1251 )
|
|
1252
|
|
1253 (defun eif-matching-indent (matching-keyword-regexp)
|
|
1254 "Search backward from the point looking for one of the keywords
|
|
1255 in the MATCHING-KEYWORD-REGEXP. Return the indentation of the
|
|
1256 keyword found. If an `end' keyword occurs prior to finding one of
|
|
1257 the keywords in MATCHING-KEYWORD-REGEXP and it terminates a check
|
|
1258 clause, return the indentation of the `end' minus the value of
|
|
1259 eif-check-keyword-indent."
|
|
1260 (let ((search-regexp (concat "[^a-z0-9A-Z_]"
|
|
1261 eif-end-keyword
|
|
1262 "[^a-z0-9A-Z_]\\|[^a-z0-9A-Z_]"
|
|
1263 matching-keyword-regexp
|
|
1264 )
|
|
1265 )
|
|
1266 (indent 0)
|
|
1267 (continue t)
|
|
1268 )
|
|
1269 (save-excursion
|
|
1270 (while (and (re-search-backward search-regexp 1 t)
|
|
1271 (or (eif-in-quoted-string-p)
|
|
1272 (eif-in-comment-p)
|
|
1273 )
|
|
1274 )
|
|
1275 )
|
|
1276 (if (looking-at search-regexp)
|
|
1277 ;; Then
|
|
1278 (if (and (looking-at eif-end-keyword-regexp)
|
|
1279 (eif-matching-line)
|
|
1280 (string-match eif-check-keyword eif-matching-kw-for-end)
|
|
1281 )
|
|
1282 ;; The keyword "end" was found that terminated a "check" clause
|
|
1283 (setq indent (- (eif-current-line-indent) (eif-check-keyword-indent-m)))
|
|
1284 ;; Else a keyword in "matching-keyword-regexp" or a normal
|
|
1285 ;; "end"was found
|
|
1286 (setq indent (eif-current-line-indent))
|
|
1287 )
|
|
1288 ;; Else
|
|
1289 (message "No matching indent keyword was found")
|
|
1290 )
|
|
1291 indent
|
|
1292
|
|
1293 )
|
|
1294 )
|
|
1295 )
|
|
1296
|
|
1297 (defun eif-matching-kw (matching-keyword-regexp)
|
|
1298 "Search backward from the point looking for one of the keywords in
|
|
1299 the MATCHING-KEYWORD-REGEXP. Return the keyword found. Also set the
|
|
1300 value of eif-matching-indent to the indentation of the keyword
|
|
1301 found. If an `end' keyword occurs prior to finding one of the
|
|
1302 keywords in MATCHING-KEYWORD-REGEXP and it terminates a check
|
|
1303 clause, set the value of eif-matching-indent to the indentation of
|
|
1304 the `end' minus the value of eif-check-keyword-indent."
|
|
1305 (let ((search-regexp (concat "[^a-z0-9A-Z_.]"
|
|
1306 eif-end-keyword
|
|
1307 "[^a-z0-9A-Z_.]\\|[^a-z0-9A-Z_.]"
|
|
1308 matching-keyword-regexp
|
|
1309 )
|
|
1310 )
|
|
1311 (keyword "")
|
|
1312 )
|
|
1313 (save-excursion
|
|
1314 ;; Search backward for a matching keyword.
|
|
1315 (while (and (re-search-backward search-regexp 1 t)
|
|
1316 (or (eif-in-quoted-string-p)
|
|
1317 (eif-in-comment-p)
|
|
1318 )
|
|
1319 )
|
|
1320 )
|
|
1321 (if (looking-at search-regexp)
|
|
1322 ;; Then - a keyword was found
|
|
1323 (progn
|
|
1324 (setq keyword
|
|
1325 (buffer-substring (match-beginning 0) (match-end 0))
|
|
1326 )
|
|
1327 (if (and (looking-at eif-end-keyword-regexp)
|
|
1328 (eif-matching-line)
|
|
1329 (string-match eif-check-keyword eif-matching-kw-for-end)
|
|
1330 )
|
|
1331 ;; Then
|
|
1332 (setq eif-matching-indent
|
|
1333 (- (eif-current-line-indent) (eif-check-keyword-indent-m))
|
|
1334 )
|
|
1335 ;; Else
|
|
1336 (setq eif-matching-indent (eif-current-line-indent))
|
|
1337 )
|
|
1338 )
|
|
1339 ;; Else no keyword was found. I think this is an error
|
|
1340 (setq eif-matching-indent 0)
|
|
1341 (message "No matching indent keyword was found")
|
|
1342 )
|
|
1343 keyword
|
|
1344 )
|
|
1345 )
|
|
1346 )
|
|
1347
|
|
1348 (defun eif-current-line-indent ()
|
|
1349 "Return the indentation of the line containing the point."
|
|
1350 (save-excursion
|
|
1351 (let ((line-end 0)
|
|
1352 (indent 0)
|
|
1353 )
|
|
1354 (end-of-line)
|
|
1355 (setq line-end (point))
|
|
1356 (beginning-of-line)
|
|
1357 (re-search-forward eif-white-space-regexp line-end t)
|
|
1358 (setq indent (current-column))
|
|
1359 )
|
|
1360 )
|
|
1361 )
|
|
1362
|
|
1363 (defun eif-line-contains-close-paren ()
|
|
1364 "This function returns t if the current line contains a close paren and
|
|
1365 nil otherwise. If a close paren is found, the point is placed immediately
|
|
1366 after the last close paren on the line. If no paren is found, the point is
|
|
1367 placed at the beginning of the line."
|
|
1368 (let ((search-min 0))
|
|
1369 (beginning-of-line)
|
|
1370 (setq search-min (point))
|
|
1371 (end-of-line)
|
|
1372 (if (search-backward ")" search-min t)
|
|
1373 ;; Then
|
|
1374 (progn
|
|
1375 (forward-char 1)
|
|
1376 t
|
|
1377 )
|
|
1378 ;; Else
|
|
1379 (beginning-of-line)
|
|
1380 nil
|
|
1381 )
|
|
1382 )
|
|
1383 )
|
|
1384
|
|
1385 ;;;; Not Currently Used
|
|
1386 ;;;(defun eif-quoted-string-on-line-p ()
|
|
1387 ;;; "t if an Eiffel quoted string begins, ends, or is continued
|
|
1388 ;;; on current line."
|
|
1389 ;;; (save-excursion
|
|
1390 ;;; (beginning-of-line)
|
|
1391 ;;; ;; Line must either start with optional whitespace immediately followed
|
|
1392 ;;; ;; by a '%' or include a '\"'. It must either end with a '%' character
|
|
1393 ;;; ;; or must include a second '\"' character.
|
|
1394 ;;; (looking-at "^\\([ \t]*%\\|[^\"\n]*\"\\)[^\"\n]*\\(%$\\|\"\\)")
|
|
1395 ;;; )
|
|
1396 ;;;)
|
|
1397
|
|
1398 (defun eif-in-quoted-string-p (&optional non-strict-p)
|
|
1399 "t if point is in a quoted string. Optional argument NON-STRICT-P if true
|
|
1400 causes the function to return true even if the point is located in leading
|
|
1401 white space on a continuation line. Normally leading white space is not
|
|
1402 considered part of the string."
|
|
1403 (let ((initial-regexp "^[ \t]*%\\|[^%]\"\\|%[ \t]*$")
|
|
1404 (search-limit (point))
|
|
1405 (count 0)
|
|
1406 )
|
|
1407 (save-excursion
|
|
1408 ;; Line must either start with optional whitespace immediately followed
|
|
1409 ;; by a '%' or include a '\"' before the search-limit.
|
|
1410 (beginning-of-line)
|
|
1411 (while (re-search-forward initial-regexp search-limit t)
|
|
1412 (setq count (1+ count))
|
|
1413 (if (= count 1) (setq search-limit (1+ search-limit)))
|
|
1414 )
|
|
1415 ;; If the number of quotes (including continuation line markers) is odd,
|
|
1416 ;; then we are inside of a string. Also if non-strict-p and we are in
|
|
1417 ;; the leading white space of a continuation line, then we are in a quote.
|
|
1418 (if (= (% count 2) 1)
|
|
1419 t
|
|
1420 (beginning-of-line)
|
|
1421 (if non-strict-p
|
|
1422 (if (looking-at "^[ \t]*%")
|
|
1423 t
|
|
1424 nil
|
|
1425 )
|
|
1426 nil
|
|
1427 );; if
|
|
1428 );; if
|
|
1429 );; save-excursion
|
|
1430 );; let
|
|
1431 );; e-in-quoted-string
|
|
1432
|
|
1433 (defvar eif-opening-regexp
|
|
1434 "\\<\\(external\\|check\\|deferred\\|do\\|once\\|from\\|if\\|inspect\\)\\>"
|
|
1435 "Keywords that open eiffel nesting constructs."
|
|
1436 )
|
|
1437 (defvar eif-closing-regexp "\\<end\\>"
|
|
1438 "Keywords that close eiffel nesting constructs."
|
|
1439 )
|
|
1440 (defvar eif-do-regexp "\\<do\\|once\\|external\\>"
|
|
1441 "Keyword that opens eiffel routine body."
|
|
1442 )
|
|
1443 (defvar eif-opening-or-closing-regexp
|
|
1444 (concat "\\(" eif-opening-regexp "\\|" eif-closing-regexp "\\)")
|
|
1445 "Keywords that open or close eiffel nesting constructs."
|
|
1446 )
|
|
1447
|
|
1448 ;;;
|
|
1449 ;;; Code to allow indenting whole eiffel blocks
|
|
1450 ;;;
|
|
1451
|
|
1452 (defun eif-matching-line (&optional return-line-break direction)
|
|
1453 "Return the character position of the keyword matching the eiffel
|
|
1454 keyword on the current line. (e.g. a line containing the keyword
|
|
1455 'do' is matched by a line containing the keyword 'end' and a line
|
|
1456 containing 'end' may be matched by a number of opening keywords.
|
|
1457 If the optional parameter 'return-line-break' is not nil, the
|
|
1458 character position returned is the beginning (or end) of the line
|
|
1459 containing the matching keyword instead of the position of the
|
|
1460 keyword itself. If the second optional parameter, direction, is
|
|
1461 non-null, the current line is not searched for a keyword. Instead,
|
|
1462 if the value of direction is 'forward, the function acts as if
|
|
1463 an eif-opening-regexp is on the current line. If the value of direction
|
|
1464 is 'backward, the function acts as if a eif-closing-regexp is on the
|
|
1465 current line. The effect of using the direction parameter is to
|
|
1466 locate either the opening or closing keyword of the syntactic
|
|
1467 construct containing the point."
|
|
1468 (let ((nesting-level 0)
|
|
1469 (matching-point nil)
|
|
1470 (search-end 0)
|
|
1471 (opening-keyword nil)
|
|
1472 (match-start nil)
|
|
1473 (match-end nil)
|
|
1474 (success nil)
|
|
1475 (start-point nil)
|
|
1476 )
|
|
1477 (unwind-protect
|
|
1478 (save-excursion
|
|
1479 (modify-syntax-entry ?_ "w ")
|
|
1480 (setq eif-matching-kw-for-end "");; public variable set by this function
|
|
1481 (setq start-point (point))
|
|
1482 (end-of-line)
|
|
1483 (setq search-end (point))
|
|
1484 (beginning-of-line)
|
|
1485 ;; Set starting state: If direction was specified use it.
|
|
1486 ;; If direction is nil, search for a keyword on the current line
|
|
1487 ;; If the keyword in in eif-opening-regexp, set the search
|
|
1488 ;; direction to 'forward, if the keyword on the current line is `end'
|
|
1489 ;; set the search direction to 'backward.
|
|
1490 (cond ((eq direction 'forward)
|
|
1491 (end-of-line);; So we wont see any keywords on the current line
|
|
1492 (setq nesting-level 1)
|
|
1493 )
|
|
1494 ((eq direction 'backward)
|
|
1495 (beginning-of-line);; So we wont see any keywords on the current line
|
|
1496 (setq nesting-level -1)
|
|
1497 )
|
|
1498 ((and (re-search-forward eif-opening-regexp search-end t)
|
|
1499 (not (or (eif-in-quoted-string-p)
|
|
1500 (eif-in-comment-p)
|
|
1501 )
|
|
1502 )
|
|
1503 )
|
|
1504 (setq match-start (match-beginning 0))
|
|
1505 (goto-char match-start)
|
|
1506 (if (not (or (eif-in-quoted-string-p) (eif-in-comment-p)))
|
|
1507 (setq nesting-level 1)
|
|
1508 )
|
|
1509 (setq opening-keyword
|
|
1510 (cons (buffer-substring match-start (match-end 0))
|
|
1511 opening-keyword
|
|
1512 )
|
|
1513 )
|
|
1514 (goto-char (match-end 0))
|
|
1515 )
|
|
1516 ((and (progn (beginning-of-line) t)
|
|
1517 (re-search-forward eif-closing-regexp search-end t)
|
|
1518 (not (or (eif-in-quoted-string-p)
|
|
1519 (eif-in-comment-p)
|
|
1520 )
|
|
1521 )
|
|
1522 )
|
|
1523 (goto-char (match-beginning 0))
|
|
1524 (if (not (or (eif-in-quoted-string-p) (eif-in-comment-p)))
|
|
1525 (setq nesting-level -1)
|
|
1526 )
|
|
1527 )
|
|
1528 )
|
|
1529 ;; Perform the search
|
|
1530 (while (not (= nesting-level 0))
|
|
1531 (if (> nesting-level 0)
|
|
1532 ;; Then search forward for the next keyword not in a comment
|
|
1533 (while (and (re-search-forward eif-opening-or-closing-regexp nil 1)
|
|
1534 (goto-char (setq match-start (match-beginning 0)))
|
|
1535 (setq match-end (match-end 0))
|
|
1536 (setq success t)
|
|
1537 (or (eif-in-quoted-string-p) (eif-in-comment-p))
|
|
1538 )
|
|
1539 (goto-char match-end)
|
|
1540 (setq success nil)
|
|
1541 )
|
|
1542 ;; Else search backward for the next keyword not in a comment
|
|
1543 (while (and (re-search-backward eif-opening-or-closing-regexp nil 1)
|
|
1544 (goto-char (setq match-start (match-beginning 0)))
|
|
1545 (setq success t)
|
|
1546 (or (eif-in-quoted-string-p) (eif-in-comment-p))
|
|
1547 )
|
|
1548 (setq success nil)
|
|
1549 )
|
|
1550 )
|
|
1551 (cond ((and (looking-at eif-opening-regexp) success)
|
|
1552 ;; Found an opening keyword
|
|
1553 (if (> nesting-level 0)
|
|
1554 ;; Then
|
|
1555 (if (looking-at eif-do-regexp)
|
|
1556 ;; Then
|
|
1557 (setq nesting-level -1)
|
|
1558 ;; Else
|
|
1559 (setq opening-keyword
|
|
1560 (cons (buffer-substring match-start (match-end 0))
|
|
1561 opening-keyword
|
|
1562 )
|
|
1563 )
|
|
1564 (goto-char (match-end 0))
|
|
1565 )
|
|
1566 ;; Else
|
|
1567 (if (= nesting-level -1)
|
|
1568 ;; Then
|
|
1569 (progn
|
|
1570 (setq eif-matching-kw-for-end
|
|
1571 (buffer-substring match-start (match-end 0))
|
|
1572 )
|
|
1573 (if (looking-at "[ \t\n]+") (goto-char (match-end 0)))
|
|
1574 )
|
|
1575 ;; Else
|
|
1576 (if (looking-at eif-do-regexp)
|
|
1577 ;; Then
|
|
1578 (progn
|
|
1579 (goto-char (eif-matching-line nil 'forward))
|
|
1580 (setq nesting-level -1)
|
|
1581 )
|
|
1582 )
|
|
1583 )
|
|
1584 (setq opening-keyword (cdr opening-keyword))
|
|
1585 (if return-line-break
|
|
1586 (beginning-of-line)
|
|
1587 )
|
|
1588 )
|
|
1589 (setq nesting-level (1+ nesting-level))
|
|
1590 )
|
|
1591 ((and (looking-at eif-closing-regexp) success)
|
|
1592 ;; Found an opening keyword
|
|
1593 (if (> nesting-level 0)
|
|
1594 ;; Then
|
|
1595 (progn
|
|
1596 (setq opening-keyword (cdr opening-keyword))
|
|
1597 (if return-line-break
|
|
1598 (end-of-line)
|
|
1599 )
|
|
1600 (goto-char (match-end 0))
|
|
1601 )
|
|
1602 ;; Else
|
|
1603 (setq opening-keyword
|
|
1604 (cons (buffer-substring (match-beginning 0)
|
|
1605 (match-end 0)
|
|
1606 )
|
|
1607 opening-keyword
|
|
1608 )
|
|
1609 )
|
|
1610 )
|
|
1611 (setq nesting-level (1- nesting-level))
|
|
1612 )
|
|
1613 (t (message (concat "Could not find match"
|
|
1614 (if (car opening-keyword)
|
|
1615 (concat " for: " (car opening-keyword))
|
|
1616 )
|
|
1617 )
|
|
1618 )
|
|
1619 (goto-char start-point)
|
|
1620 (setq nesting-level 0)
|
|
1621 )
|
|
1622 );; cond
|
|
1623 );; while
|
|
1624 (setq matching-point (point))
|
|
1625 );; save-excursion
|
|
1626 (modify-syntax-entry ?_ "_ ")
|
|
1627 );; unwind-protect
|
|
1628 (set-mark matching-point)
|
|
1629 );; let
|
|
1630 );; eif-matching-line
|
|
1631
|
|
1632 ;;; ENHANCEME: Make this function correctly indent more than just routine
|
|
1633 ;;; bodies and their sub-constructs. At the least it should
|
|
1634 ;;; handle whole routines also.
|
|
1635 (defun eif-indent-construct ()
|
|
1636 "Indents an entire eiffel syntactic construct. It is assumed that
|
|
1637 the point is within a nesting construct ('do', `once', 'check', 'if',
|
|
1638 'from', or 'inspect'). The whole construct is indented up to the
|
|
1639 matching end. If the point is not within such a construct, then
|
|
1640 only that line is indented"
|
|
1641 (interactive)
|
|
1642 (let ((end-point 0))
|
|
1643 (save-excursion
|
|
1644 (end-of-line)
|
|
1645 (if (not (= (point) (point-max))) (forward-char 1))
|
|
1646 (goto-char (eif-matching-line t 'backward))
|
|
1647 (setq end-point (eif-matching-line t 'forward))
|
|
1648 (while (< (point) end-point)
|
|
1649 (eif-indent-line)
|
|
1650 (next-line 1)
|
|
1651 (beginning-of-line)
|
|
1652 )
|
|
1653 )
|
|
1654 )
|
|
1655 )
|
|
1656
|
|
1657 (defun eif-indent-region (&optional start end)
|
|
1658 "Indents the lines in the current region"
|
|
1659 (interactive)
|
|
1660 (let ((start-point (or start (region-beginning)))
|
|
1661 (end-point (copy-marker (or end (region-end))))
|
|
1662 )
|
|
1663 (save-excursion
|
|
1664 (goto-char start-point)
|
|
1665 (cond ((eq major-mode 'ace-mode)
|
|
1666 (while (< (point) end-point)
|
|
1667 (if (not (looking-at "[ ]*$"))
|
|
1668 (ace-indent-line)
|
|
1669 )
|
|
1670 (next-line 1)
|
|
1671 (beginning-of-line)
|
|
1672 )
|
|
1673 )
|
|
1674 ((eq major-mode 'eiffel-mode)
|
|
1675 (while (< (point) end-point)
|
|
1676 (if (not (looking-at "[ ]*$"))
|
|
1677 (eif-indent-line)
|
|
1678 )
|
|
1679 (next-line 1)
|
|
1680 (beginning-of-line)
|
|
1681 )
|
|
1682 )
|
|
1683 (t (error "Buffer must be in eiffel or ace mode."))
|
|
1684 )
|
|
1685 )
|
|
1686 )
|
|
1687 )
|
|
1688
|
|
1689 ;;(defun eif-goto-matching-line (&optional direction)
|
|
1690 ;; "Place the cursor on the line which closes(opens) the current
|
|
1691 ;;opening(closing) syntactic construct. For example if the point
|
|
1692 ;;is on `from', executing goto-matching-line places the point
|
|
1693 ;;on the matching `end' and vice-versa."
|
|
1694 ;; (interactive)
|
|
1695 ;; (if (not direction)
|
|
1696 ;; (progn
|
|
1697 ;; (cond ((save-excursion (beginning-of-line) (looking-at "[ ]*end.*$"))
|
|
1698 ;; (goto-char (eif-matching-line nil 'backward))
|
|
1699 ;; )
|
|
1700 ;; ((looking-at "(")
|
|
1701 ;; (forward-sexp)
|
|
1702 ;; )
|
|
1703 ;; ((save-excursion (backward-char 1) (looking-at ")"))
|
|
1704 ;; (backward-sexp)
|
|
1705 ;; )
|
|
1706 ;; (t
|
|
1707 ;; (goto-char (eif-matching-line nil 'forward))
|
|
1708 ;; )
|
|
1709 ;; )
|
|
1710 ;; )
|
|
1711 ;; )
|
|
1712 ;; )
|
|
1713
|
|
1714 (defun eif-forward-sexp ()
|
|
1715 "Place the cursor on the line which closes the current opening syntactic construct. For example if the point is on `from', executing eif-forward-sexp places the point on the matching `end'. This also does matching of parens ala forward-sexp."
|
|
1716 (interactive)
|
|
1717 (cond ((looking-at "[[(]")
|
|
1718 (forward-sexp)
|
|
1719 )
|
|
1720 (t
|
|
1721 (goto-char (eif-matching-line nil 'forward))
|
|
1722 )
|
|
1723 )
|
|
1724 )
|
|
1725
|
|
1726 (defun eif-backward-sexp ()
|
|
1727 "Place the cursor on the line which opens the current closing syntactic construct. For example if the point is on the terminating `end' of an `if' statement, executing eif-backward-sexp places the point on the opening `if'. This also does matching of parens ala backward-sexp."
|
|
1728 (interactive)
|
|
1729 (cond ((save-excursion (backward-char 1) (looking-at "[])]"))
|
|
1730 (backward-sexp)
|
|
1731 )
|
|
1732 (t
|
|
1733 (goto-char (eif-matching-line nil 'backward))
|
|
1734 )
|
|
1735 )
|
|
1736 )
|
|
1737
|
|
1738 (defun eif-local-indent (amount)
|
|
1739 "Set the value of eif-indent-increment to amount and make the change local to this buffer."
|
|
1740 (interactive "NNumber of spaces for eif-indent-increment: ")
|
|
1741 (make-local-variable 'eif-indent-increment)
|
|
1742 (setq eif-indent-increment amount)
|
|
1743 )
|
|
1744
|
|
1745 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1746 ;;; Utility Functions. ;;;
|
|
1747 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1748
|
|
1749 (defun eif-feature-quote ()
|
|
1750 "Put a `' around the current feature name"
|
|
1751 (interactive)
|
|
1752 (save-excursion
|
|
1753 (backward-sexp)
|
|
1754 (insert "`")
|
|
1755 (forward-sexp)
|
|
1756 (insert "'")
|
|
1757 )
|
|
1758 (if (looking-at "'")
|
|
1759 (forward-char 1))
|
|
1760 )
|
|
1761
|
|
1762 (defvar eiffel-mode-abbrev-table nil)
|
|
1763 (define-abbrev-table 'eiffel-mode-abbrev-table ())
|
|
1764
|
|
1765 ;;; ----------------------------------------------------------------------
|
|
1766 ;;; This next portion of the file is derived from "eiffel.el"
|
|
1767 ;;; Copyright (C) 1989, 1990 Free Software Foundation, Inc. and Bob Weiner
|
|
1768 ;;; Available for use and distribution under the same terms as GNU Emacs.
|
|
1769 ;;; ----------------------------------------------------------------------
|
|
1770
|
|
1771 (defvar eiffel-mode-map nil
|
|
1772 "Keymap for Eiffel mode.")
|
|
1773
|
|
1774 (defvar eiffel-mode-syntax-table nil
|
|
1775 "Syntax table in use in Eiffel-mode buffers.")
|
|
1776
|
|
1777 (if eiffel-mode-syntax-table
|
|
1778 nil
|
|
1779 (let ((table (make-syntax-table))
|
|
1780 (i 0))
|
|
1781 (while (< i ?0)
|
|
1782 (modify-syntax-entry i "_ " table)
|
|
1783 (setq i (1+ i)))
|
|
1784 (setq i (1+ ?9))
|
|
1785 (while (< i ?A)
|
|
1786 (modify-syntax-entry i "_ " table)
|
|
1787 (setq i (1+ i)))
|
|
1788 (setq i (1+ ?Z))
|
|
1789 (while (< i ?a)
|
|
1790 (modify-syntax-entry i "_ " table)
|
|
1791 (setq i (1+ i)))
|
|
1792 (setq i (1+ ?z))
|
|
1793 (while (< i 128)
|
|
1794 (modify-syntax-entry i "_ " table)
|
|
1795 (setq i (1+ i)))
|
|
1796 (modify-syntax-entry ? " " table)
|
|
1797 (modify-syntax-entry ?- ". 12" table)
|
|
1798 (modify-syntax-entry ?_ "_ " table)
|
|
1799 (modify-syntax-entry ?\t " " table)
|
|
1800 (modify-syntax-entry ?\n "> " table)
|
|
1801 (modify-syntax-entry ?\f "> " table)
|
|
1802 (modify-syntax-entry ?\" "\" " table)
|
|
1803 (modify-syntax-entry ?\\ "." table)
|
|
1804 (modify-syntax-entry ?\( "() " table)
|
|
1805 (modify-syntax-entry ?\) ")( " table)
|
|
1806 (modify-syntax-entry ?\[ "(] " table)
|
|
1807 (modify-syntax-entry ?\] ")[ " table)
|
|
1808 (modify-syntax-entry ?\{ "(} " table)
|
|
1809 (modify-syntax-entry ?\} "){ " table)
|
|
1810 (modify-syntax-entry ?' "\"" table)
|
|
1811 (modify-syntax-entry ?` "." table)
|
|
1812 (modify-syntax-entry ?/ "." table)
|
|
1813 (modify-syntax-entry ?* "." table)
|
|
1814 (modify-syntax-entry ?+ "." table)
|
|
1815 (modify-syntax-entry ?= "." table)
|
|
1816 (modify-syntax-entry ?% "\\" table)
|
|
1817 (modify-syntax-entry ?< "." table)
|
|
1818 (modify-syntax-entry ?> "." table)
|
|
1819 (modify-syntax-entry ?& "." table)
|
|
1820 (modify-syntax-entry ?| "." table)
|
|
1821 (modify-syntax-entry ?; "." table)
|
|
1822 (modify-syntax-entry ?: "." table)
|
|
1823 (modify-syntax-entry ?! "." table)
|
|
1824 (modify-syntax-entry ?. "." table)
|
|
1825 (setq eiffel-mode-syntax-table table))
|
|
1826 )
|
|
1827
|
|
1828 (if eiffel-mode-map
|
|
1829 nil
|
|
1830 (setq eiffel-mode-map (make-sparse-keymap))
|
|
1831 (define-key eiffel-mode-map "\t" 'eif-indent-line)
|
|
1832 (define-key eiffel-mode-map "\C-j" 'eif-newline)
|
|
1833 (define-key eiffel-mode-map "\177" 'backward-delete-char-untabify)
|
|
1834 (define-key eiffel-mode-map "\M-\C-q" 'eif-indent-construct)
|
|
1835 (define-key eiffel-mode-map "\M-'" 'eif-feature-quote)
|
|
1836 (define-key eiffel-mode-map "\M-q" 'eif-fill-paragraph)
|
|
1837 )
|
|
1838
|
|
1839 ;;;###autoload
|
|
1840 (defun eiffel-mode ()
|
|
1841 "Major mode for editing Eiffel programs."
|
|
1842 (interactive)
|
|
1843 (setq major-mode 'eiffel-mode)
|
|
1844 (setq mode-name "Eiffel")
|
|
1845 (use-local-map eiffel-mode-map)
|
|
1846 (set-syntax-table eiffel-mode-syntax-table)
|
|
1847
|
|
1848 ;; Make local variables.
|
|
1849 (make-local-variable 'paragraph-start)
|
|
1850 (make-local-variable 'paragraph-separate)
|
|
1851 (make-local-variable 'paragraph-ignore-fill-prefix)
|
|
1852 (make-local-variable 'require-final-newline)
|
|
1853 (make-local-variable 'parse-sexp-ignore-comments)
|
|
1854 (make-local-variable 'indent-line-function)
|
|
1855 (make-local-variable 'indent-region-function)
|
|
1856 (make-local-variable 'comment-start)
|
|
1857 (make-local-variable 'comment-end)
|
|
1858 (make-local-variable 'comment-column)
|
|
1859 (make-local-variable 'comment-start-skip)
|
|
1860 ;; Now set their values.
|
|
1861 (setq paragraph-start (concat "^$\\|" page-delimiter)
|
|
1862 paragraph-separate paragraph-start
|
|
1863 paragraph-ignore-fill-prefix t
|
|
1864 require-final-newline 'ask
|
|
1865 parse-sexp-ignore-comments t
|
|
1866 indent-line-function 'eif-indent-line
|
|
1867 indent-region-function 'eif-indent-region
|
|
1868 comment-start "-- "
|
|
1869 comment-end ""
|
|
1870 comment-column 32
|
|
1871 comment-start-skip "--+ *")
|
|
1872
|
|
1873 (run-hooks 'eiffel-mode-hook)
|
|
1874 (setq local-abbrev-table eiffel-mode-abbrev-table)
|
|
1875 (setq auto-fill-function 'eif-auto-fill)
|
|
1876 )
|
|
1877
|
|
1878 (defun eif-in-comment-p ()
|
|
1879 "t if point is in a comment."
|
|
1880 (save-excursion
|
|
1881 (and (/= (point) (point-max)) (forward-char 1))
|
|
1882 (search-backward "--" (save-excursion (beginning-of-line) (point)) t)))
|
|
1883
|
|
1884
|
|
1885 (defun eif-comment-prefix ()
|
|
1886 "Prefix that starts a comment that begins a line.
|
|
1887 Comments that are not the only thing on a line return nil as their prefix."
|
|
1888 (save-excursion
|
|
1889 (end-of-line)
|
|
1890 (let ((limit (point)) len
|
|
1891 (in-string (eif-in-quoted-string-p))
|
|
1892 )
|
|
1893 (beginning-of-line)
|
|
1894 (cond ((re-search-forward "^[ \t]*--|?[ \t]*" limit t)
|
|
1895 (buffer-substring (match-beginning 0) (match-end 0))
|
|
1896 )
|
|
1897 ;; Handle string-literal continuation lines
|
|
1898 (in-string
|
|
1899 (end-of-line)
|
|
1900 (re-search-backward "^[ \t]*%\\|[^%]\"" nil t)
|
|
1901 (re-search-forward "%\\|\"" nil t)
|
|
1902 (setq len (1- (current-column)))
|
|
1903 (concat (make-string len ? ) "%")
|
|
1904 )
|
|
1905 (t nil)
|
|
1906 )
|
|
1907 )
|
|
1908 )
|
|
1909 )
|
|
1910
|
|
1911
|
|
1912 (defun eif-auto-fill ()
|
|
1913 (if (> (current-column) fill-column)
|
|
1914 (let ((fill-prefix (eif-comment-prefix)) (pm (point-marker)))
|
|
1915 (if fill-prefix
|
|
1916 (if (string-match "^[ \t]*%" fill-prefix)
|
|
1917 (progn
|
|
1918 (backward-char 1)
|
|
1919 (re-search-backward "[^][a-zA-Z0-9]" nil t)
|
|
1920 (forward-char 1)
|
|
1921 (insert "%\n")
|
|
1922 (insert fill-prefix)
|
|
1923 (goto-char pm)
|
|
1924 )
|
|
1925 ;; (do-auto-fill)
|
|
1926 (backward-char 1)
|
|
1927 (re-search-backward "\\s-" nil t)
|
|
1928 (forward-char 1)
|
|
1929 (insert "\n")
|
|
1930 (insert fill-prefix)
|
|
1931 (goto-char pm)
|
|
1932 )
|
|
1933 )
|
|
1934 )
|
|
1935 )
|
|
1936 )
|
|
1937
|
|
1938 (defun eif-fill-paragraph ()
|
|
1939 "Textually fills Eiffel comments ala fill-paragraph"
|
|
1940 (interactive)
|
|
1941 (save-excursion
|
|
1942 (let ((current-point (point))
|
|
1943 (last-point nil)
|
|
1944 (para-begin nil)
|
|
1945 (para-end nil)
|
|
1946 (fill-prefix (eif-comment-prefix))
|
|
1947 )
|
|
1948 (if fill-prefix
|
|
1949 (progn
|
|
1950 (setq last-point (point))
|
|
1951 (forward-line -1)
|
|
1952 (end-of-line)
|
|
1953 (while (and (not (= (point) last-point))
|
|
1954 (eif-comment-prefix)
|
|
1955 )
|
|
1956 (setq last-point (point))
|
|
1957 (forward-line -1)
|
|
1958 (end-of-line)
|
|
1959 )
|
|
1960 (if (= (point) last-point)
|
|
1961 (setq para-begin (save-excursion (beginning-of-line) (point)))
|
|
1962 (setq para-begin (1+ (point)))
|
|
1963 )
|
|
1964 (goto-char current-point)
|
|
1965 (setq last-point (point))
|
|
1966 (next-line 1)
|
|
1967 (end-of-line)
|
|
1968 (while (and (not (= (point) last-point))
|
|
1969 (eif-comment-prefix)
|
|
1970 )
|
|
1971 (setq last-point (point))
|
|
1972 (next-line 1)
|
|
1973 (end-of-line)
|
|
1974 )
|
|
1975 (if (= (point) last-point)
|
|
1976 (setq para-end (point))
|
|
1977 (beginning-of-line)
|
|
1978 (setq para-end (point))
|
|
1979 )
|
|
1980 (fill-region para-begin para-end)
|
|
1981 )
|
|
1982 )
|
|
1983 )
|
|
1984 )
|
|
1985 )
|
|
1986
|
|
1987 (defun eif-newline ()
|
|
1988 "Insert a newline and indent the new line."
|
|
1989 (interactive)
|
|
1990 (insert "\n")
|
|
1991 (eif-indent-line)
|
|
1992 )
|
|
1993
|
|
1994 (defun eif-indent-line (&optional whole-exp)
|
|
1995 "Indent the current line as Eiffel code.
|
|
1996 With argument, indent any additional lines of the same clause
|
|
1997 rigidly along with this one (not implemented yet)."
|
|
1998 (interactive "p")
|
|
1999 (save-excursion
|
|
2000 (beginning-of-line)
|
|
2001 (skip-chars-forward " \t")
|
|
2002 (let ((indent (eif-calc-indent)))
|
|
2003 (if (not (= indent (current-column)))
|
|
2004 (progn
|
|
2005 (delete-horizontal-space)
|
|
2006 (indent-to indent)
|
|
2007 )
|
|
2008 )
|
|
2009 )
|
|
2010 )
|
|
2011 (skip-chars-forward " \t"))
|
|
2012
|
|
2013 ;; ENHANCEME: Currently eif-beginning-of-feature only works for routines.
|
|
2014 ;; It should be made more general.
|
|
2015 ;;
|
|
2016
|
|
2017 (defun eif-beginning-of-feature (&optional arg)
|
|
2018 "Move backward to next feature beginning. With argument, do this that many
|
|
2019 times. Returns t unless search stops due to beginning of buffer."
|
|
2020 (interactive "p")
|
|
2021 (and arg (< arg 0) (forward-char 1))
|
|
2022 (if (or (re-search-backward eif-multiline-routine-is-keyword-regexp
|
|
2023 nil t (or arg 1))
|
|
2024 (re-search-backward eif-is-keyword-regexp
|
|
2025 nil 'move (or arg 1))
|
|
2026 )
|
|
2027 (progn
|
|
2028 (backward-sexp 1)
|
|
2029 (if (looking-at "(")
|
|
2030 (backward-word 1)
|
|
2031 )
|
|
2032 (beginning-of-line)
|
|
2033 )
|
|
2034 nil
|
|
2035 )
|
|
2036 )
|
|
2037
|
|
2038 (defun eif-move-to-prev-non-blank ()
|
|
2039 "Moves point to previous line excluding blank lines.
|
|
2040 Returns t if successful, nil if not."
|
|
2041 (beginning-of-line)
|
|
2042 (re-search-backward "^[ \t]*[^ \t\n]" nil t))
|
|
2043
|
|
2044 (defvar eif-last-feature-level-indent -1)
|
|
2045 (defvar eif-feature-level-indent-regexp nil)
|
|
2046 (defun eif-in-paren-expression ()
|
|
2047 "Determine if we are inside of a parenthesized expression"
|
|
2048 (interactive)
|
|
2049 (let ((paren-count 0) (limit 0))
|
|
2050 (save-excursion
|
|
2051 (if (= eif-last-feature-level-indent (eif-feature-level-indent-m))
|
|
2052 (setq limit
|
|
2053 (re-search-backward eif-feature-level-indent-regexp nil t))
|
|
2054 (setq eif-last-feature-level-indent (eif-feature-level-indent-m))
|
|
2055 (setq eif-feature-level-indent-regexp
|
|
2056 (concat "^" (make-string eif-last-feature-level-indent ? )
|
|
2057 "[^ \t\n]")
|
|
2058 )
|
|
2059 (setq limit
|
|
2060 (or (re-search-backward eif-feature-level-indent-regexp nil t)
|
|
2061 0)
|
|
2062 )
|
|
2063 )
|
|
2064 )
|
|
2065 (save-excursion
|
|
2066 (while (re-search-backward "[][()]" limit t)
|
|
2067 (if (looking-at "[[(]")
|
|
2068 (setq paren-count (1+ paren-count))
|
|
2069 (setq paren-count (1- paren-count))
|
|
2070 )
|
|
2071 )
|
|
2072 )
|
|
2073 paren-count
|
|
2074 )
|
|
2075 )
|
|
2076
|
|
2077 (defun eif-manifest-array-indent ()
|
|
2078 "Determine if we are inside of a manifest array"
|
|
2079 (interactive)
|
|
2080 (let ((paren-count 0) (indent nil)
|
|
2081 (limit 0))
|
|
2082 (save-excursion
|
|
2083 (if (= eif-last-feature-level-indent (eif-feature-level-indent-m))
|
|
2084 (setq limit
|
|
2085 (re-search-backward eif-feature-level-indent-regexp nil t))
|
|
2086 (setq eif-last-feature-level-indent (eif-feature-level-indent-m))
|
|
2087 (setq eif-feature-level-indent-regexp
|
|
2088 (concat "^" (make-string eif-last-feature-level-indent ? )
|
|
2089 "[^ \t\n]")
|
|
2090 )
|
|
2091 (setq limit
|
|
2092 (or (re-search-backward eif-feature-level-indent-regexp nil t)
|
|
2093 0)
|
|
2094 )
|
|
2095 )
|
|
2096 )
|
|
2097 (save-excursion
|
|
2098 (while (and (<= paren-count 0) (re-search-backward "<<\\|>>" nil t))
|
|
2099 (if (looking-at "<<")
|
|
2100 (setq paren-count (1+ paren-count))
|
|
2101 (setq paren-count (1- paren-count))
|
|
2102 )
|
|
2103 )
|
|
2104 (if (> paren-count 0)
|
|
2105 (let ((eol (save-excursion (end-of-line) (point))))
|
|
2106 (setq indent
|
|
2107 (or (and (re-search-forward "[^< \t]" eol t)
|
|
2108 (1- (current-column)))
|
|
2109 (+ (current-column) 2)
|
|
2110 )
|
|
2111 )
|
|
2112 )
|
|
2113 )
|
|
2114 )
|
|
2115 indent
|
|
2116 )
|
|
2117 )
|
|
2118
|
|
2119 (defun eif-manifest-array-start ()
|
|
2120 "Determine the indentation of the statement containing a manifest array"
|
|
2121 (interactive)
|
|
2122 (let ((paren-count 0) (indent nil)
|
|
2123 (limit 0))
|
|
2124 (save-excursion
|
|
2125 (if (= eif-last-feature-level-indent (eif-feature-level-indent-m))
|
|
2126 (setq limit
|
|
2127 (re-search-backward eif-feature-level-indent-regexp nil t))
|
|
2128 (setq eif-last-feature-level-indent (eif-feature-level-indent-m))
|
|
2129 (setq eif-feature-level-indent-regexp
|
|
2130 (concat "^" (make-string eif-last-feature-level-indent ? )
|
|
2131 "[^ \t\n]")
|
|
2132 )
|
|
2133 (setq limit
|
|
2134 (or (re-search-backward eif-feature-level-indent-regexp nil t)
|
|
2135 0)
|
|
2136 )
|
|
2137 )
|
|
2138 )
|
|
2139 (save-excursion
|
|
2140 (while (and (<= paren-count 0) (re-search-backward "<<\\|>>" nil t))
|
|
2141 (if (looking-at "<<")
|
|
2142 (setq paren-count (1+ paren-count))
|
|
2143 (setq paren-count (1- paren-count))
|
|
2144 )
|
|
2145 )
|
|
2146 (if (> paren-count 0)
|
|
2147 (let ((limit (progn (end-of-line) (point))))
|
|
2148 (beginning-of-line)
|
|
2149 (if (re-search-forward "^[ \t]*<<" limit t)
|
|
2150 (setq indent (- (current-column) 2 eif-indent-increment))
|
|
2151 (re-search-forward "^[ \t]*" limit t)
|
|
2152 (setq indent (current-column))
|
|
2153 )
|
|
2154 )
|
|
2155 )
|
|
2156 )
|
|
2157 indent
|
|
2158 )
|
|
2159 )
|
|
2160
|
|
2161 ;;; ----------------------------------------------------------------------
|
|
2162 ;;; The portion of the file below this point is derived from "eif-mult-fmt.el"
|
|
2163 ;;; Copyright (C) 1985 Free Software Foundation, Inc.
|
|
2164 ;;; Copyright (C) 1990 Bob Weiner, Motorola Inc.
|
|
2165 ;;; Available for use and distribution under the same terms as GNU Emacs.
|
|
2166 ;;; ----------------------------------------------------------------------
|
|
2167
|
|
2168 (defun eif-indent-multi-line (&optional parse-start)
|
|
2169 "Return integer giving appropriate indentation for current Eiffel code
|
|
2170 line between parentheses or double quotes, otherwise -1. Optional
|
|
2171 PARSE-START is buffer position at which to begin parsing, default is to begin
|
|
2172 at the feature enclosing or preceding point."
|
|
2173 (let ((eif-opoint (point))
|
|
2174 (indent-point (progn (beginning-of-line) (point)))
|
|
2175 (eif-ind-val -1)
|
|
2176 (eif-in-str nil)
|
|
2177 (eif-paren-depth 0)
|
|
2178 (retry t)
|
|
2179 state
|
|
2180 ;; setting this to a number inhibits calling hook
|
|
2181 last-sexp containing-sexp)
|
|
2182 (if parse-start
|
|
2183 (goto-char parse-start)
|
|
2184 (eif-beginning-of-feature))
|
|
2185 ;; Find outermost containing sexp
|
|
2186 (while (< (point) indent-point)
|
|
2187 (setq state (parse-partial-sexp (point) indent-point 0)))
|
|
2188 ;; Find innermost containing sexp
|
|
2189 (while (and retry
|
|
2190 state
|
|
2191 (> (setq eif-paren-depth (elt state 0)) 0))
|
|
2192 (setq retry nil)
|
|
2193 (setq last-sexp (elt state 2))
|
|
2194 (setq containing-sexp (elt state 1))
|
|
2195 ;; Position following last unclosed open.
|
|
2196 (goto-char (1+ containing-sexp))
|
|
2197 ;; Is there a complete sexp since then?
|
|
2198 (if (and last-sexp (> last-sexp (point)))
|
|
2199 ;; Yes, but is there a containing sexp after that?
|
|
2200 (let ((peek (parse-partial-sexp last-sexp indent-point 0)))
|
|
2201 (if (setq retry (car (cdr peek))) (setq state peek)))))
|
|
2202 (if retry
|
|
2203 nil
|
|
2204 ;; Innermost containing sexp found
|
|
2205 (goto-char (1+ containing-sexp))
|
|
2206 (if (not last-sexp)
|
|
2207 ;; indent-point immediately follows open paren.
|
|
2208 nil
|
|
2209 ;; Find the start of first element of containing sexp.
|
|
2210 (parse-partial-sexp (point) last-sexp 0 t)
|
|
2211 (cond ((looking-at "\\s(")
|
|
2212 ;; First element of containing sexp is a list.
|
|
2213 ;; Indent under that list.
|
|
2214 )
|
|
2215 ((> (save-excursion (forward-line 1) (point))
|
|
2216 last-sexp)
|
|
2217 ;; This is the first line to start within the containing sexp.
|
|
2218 (backward-prefix-chars))
|
|
2219 (t
|
|
2220 ;; Indent beneath first sexp on same line as last-sexp.
|
|
2221 ;; Again, it's almost certainly a routine call.
|
|
2222 (goto-char last-sexp)
|
|
2223 (beginning-of-line)
|
|
2224 (parse-partial-sexp (point) last-sexp 0 t)
|
|
2225 (backward-prefix-chars))))
|
|
2226 (setq eif-ind-val (current-column))
|
|
2227 )
|
|
2228 ;; Point is at the point to indent under unless we are inside a string.
|
|
2229 (setq eif-in-str (elt state 3))
|
|
2230 (goto-char eif-opoint)
|
|
2231 (if (not eif-in-str)
|
|
2232 nil
|
|
2233 ;; Inside a string, indent 1 past string start
|
|
2234 (setq eif-paren-depth 1);; To account for being inside string
|
|
2235 (save-excursion
|
|
2236 (if (re-search-backward "\"" nil t)
|
|
2237 (setq eif-ind-val (1+ (current-column)))
|
|
2238 (goto-char indent-point)
|
|
2239 (if (looking-at "^[ \t]*[^ \t\n]")
|
|
2240 (eif-move-to-prev-non-blank))
|
|
2241 (skip-chars-forward " \t")
|
|
2242 (setq eif-ind-val (current-column)))))
|
|
2243 (if (> eif-paren-depth 0) eif-ind-val -1)
|
|
2244 ))
|
|
2245
|
|
2246 (provide 'eiffel3)
|