]> code.delx.au - gnu-emacs-elpa/blob - packages/ada-mode/ada-wisi.el
Add ada-mode, wisi packages
[gnu-emacs-elpa] / packages / ada-mode / ada-wisi.el
1 ;;; An indentation engine for Ada mode, using the wisi generalized LALR parser
2 ;;
3 ;; [1] ISO/IEC 8652:2012(E); Ada 2012 reference manual
4 ;;
5 ;; Copyright (C) 2012, 2013 Free Software Foundation, Inc.
6 ;;
7 ;; Author: Stephen Leake <stephen_leake@member.fsf.org>
8 ;;
9 ;; This file is part of GNU Emacs.
10 ;;
11 ;; GNU Emacs is free software: you can redistribute it and/or modify
12 ;; it under the terms of the GNU General Public License as published by
13 ;; the Free Software Foundation, either version 3 of the License, or
14 ;; (at your option) any later version.
15 ;;
16 ;; GNU Emacs is distributed in the hope that it will be useful,
17 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 ;; GNU General Public License for more details.
20 ;;
21 ;; You should have received a copy of the GNU General Public License
22 ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
23 ;;
24 ;;; History:
25 ;;
26 ;; implementation started Jan 2013
27 ;;
28 ;;; code style
29 ;;
30 ;; not using lexical-binding or cl-lib because we support Emacs 23
31 ;;
32 ;;;;
33
34 (require 'ada-fix-error)
35 (require 'ada-grammar-wy)
36 (require 'ada-indent-user-options)
37 (require 'wisi)
38
39 (eval-when-compile (require 'cl-macs))
40
41 (defconst ada-wisi-class-list
42 '(
43 block-end
44 block-middle ;; not start of statement
45 block-start ;; start of block is start of statement
46 close-paren
47 list-break
48 name
49 name-paren ;; anything that looks like a procedure call, since the grammar can't distinguish most of them
50 open-paren
51 return
52 return-1
53 return-2
54 statement-end
55 statement-other
56 statement-start
57 type
58 ))
59
60 ;;;; indentation
61
62 (defun ada-wisi-indent-cache (offset cache)
63 "Return indentation of OFFSET plus indentation of line containing point. Point must be at CACHE."
64 (let ((indent (current-indentation)))
65 (cond
66 ;; special cases
67 ;;
68 ((eq 'LEFT_PAREN (wisi-cache-token cache))
69 ;; test/ada_mode-long_paren.adb
70 ;; (RT => RT,
71 ;; Monitor => True,
72 ;; RX_Enable =>
73 ;; (RX_Torque_Subaddress |
74 ;; indenting '(RX_'
75 ;;
76 ;; test/ada_mode-parens.adb
77 ;; return Float (
78 ;; Integer'Value
79 ;; (Local_6));
80 ;; indenting '(local_6)'; 'offset' = ada-indent - 1
81 (+ (current-column) 1 offset))
82
83 ((save-excursion
84 (let ((containing (wisi-goto-containing-paren cache)))
85 (and containing
86 ;; test/ada_mode-conditional_expressions.adb
87 ;; K2 : Integer := (if J > 42
88 ;; then -1
89 ;; indenting 'then'; offset = 0
90 ;;
91 ;; need get-start, not just get-containing, because of:
92 ;; L1 : Integer := (case J is
93 ;; when 42 => -1,
94 ;;
95 ;; _not_ (ada-in-paren-p), because of:
96 ;; test/indent.ads
97 ;; C_S_Controls : constant
98 ;; CSCL_Type :=
99 ;; CSCL_Type'
100 ;; (
101 ;; 1 => -- Used to be aligned on "CSCL_Type'"
102 ;; -- aligned with previous comment.
103 ;; IO_CPU_Control_State_S_Pkg.CPU2_Fault_Status_Type'
104 ;; (Unused2 => 10, -- Used to be aligned on "1 =>"
105 ;; indenting '(Unused2'
106 (+ (current-column) offset)))))
107
108 ;; all other structures
109 (t
110 ;; current cache may be preceded by something on same
111 ;; line. Handle common cases nicely.
112 (while (and cache
113 (or
114 (not (= (current-column) indent))
115 (eq 'EQUAL_GREATER (wisi-cache-token cache))))
116 (when (and
117 (eq 'WHEN (wisi-cache-token cache))
118 (not (eq 'exit_statement (wisi-cache-nonterm cache))))
119 (setq offset (+ offset ada-indent-when)))
120 (setq cache (wisi-goto-containing cache))
121 (setq indent (current-indentation)))
122
123 (cond
124 ((null cache)
125 ;; test/ada_mode-opentoken.ads
126 ;; private package GDS.Commands.Add_Statement is
127 ;; type Instance is new Nonterminal.Instance with null record;
128 offset)
129
130 ((eq 'label_opt (wisi-cache-token cache))
131 (+ indent (- ada-indent-label) offset))
132
133 (t
134 ;; test/ada_mode-generic_instantiation.ads
135 ;; function Function_1 is new Instance.Generic_Function
136 ;; (Param_Type => Integer,
137 ;;
138 ;; test/ada_mode-nested_packages.adb
139 ;; function Create (Model : in Integer;
140 ;; Context : in String) return String is
141 ;; ...
142 ;; Cache : array (1 .. 10) of Boolean := (True, False, others => False);
143 (+ indent offset))
144 ))
145 )))
146
147 (defun ada-wisi-indent-containing (offset cache &optional before)
148 "Return indentation of OFFSET plus indentation of token containing CACHE.
149 BEFORE should be t when called from ada-wisi-before-cache, nil otherwise."
150 (save-excursion
151 (cond
152 ((markerp (wisi-cache-containing cache))
153 (ada-wisi-indent-cache offset (wisi-goto-containing cache)))
154
155 (t
156 (cond
157 ((ada-in-paren-p)
158 (ada-goto-open-paren 1)
159 (+ (current-column) offset))
160
161 (t
162 ;; at outermost containing statement. If called from
163 ;; ada-wisi-before-cache, we want to ignore OFFSET (indenting
164 ;; 'package' in a package spec). If called from
165 ;; ada-wisi-after-cache, we want to include offset (indenting
166 ;; first declaration in the package).
167 (if before 0 offset))
168 ))
169 )))
170
171 (defun ada-wisi-before-cache ()
172 "Point is at indentation, before a cached token. Return new indentation for point."
173 (let ((pos-0 (point))
174 (cache (wisi-get-cache (point))))
175 (when cache
176 (cl-ecase (wisi-cache-class cache)
177 (block-start
178 (cl-case (wisi-cache-token cache)
179 (IS ;; subprogram body
180 (ada-wisi-indent-containing 0 cache t))
181
182 (RECORD
183 (ada-wisi-indent-containing ada-indent-record-rel-type cache t))
184
185 (t ;; other
186 (ada-wisi-indent-containing ada-indent cache t))))
187
188 (block-end
189 (cl-case (wisi-cache-nonterm cache)
190 (record_definition
191 (save-excursion
192 (wisi-goto-containing cache);; now on 'record'
193 (current-indentation)))
194
195 (t
196 (ada-wisi-indent-containing 0 cache t))
197 ))
198
199 (block-middle
200 (cl-case (wisi-cache-token cache)
201 (WHEN
202 (ada-wisi-indent-containing ada-indent-when cache t))
203
204 (t
205 (ada-wisi-indent-containing 0 cache t))
206 ))
207
208 (close-paren (wisi-indent-paren 0))
209
210 (name
211 (ada-wisi-indent-containing ada-indent-broken cache t))
212
213 (name-paren
214 (let ((containing (wisi-goto-containing cache)))
215 (cl-case (wisi-cache-class containing)
216 (open-paren
217 ;; test/ada_mode-slices.adb
218 ;; Put_Line(Day'Image(D1) & " - " & Day'Image(D2) & " = " &
219 ;; Integer'Image(N));
220 ;;
221 ;; test/ada_mode-parens.adb
222 ;; return Float (
223 ;; Integer'Value
224 ;; indenting 'Integer'
225 ;;
226 ;; We distinguish the two cases by going to the first token,
227 ;; and comparing point to pos-0.
228 (let ((paren-column (current-column)))
229 (wisi-forward-token t); "("
230 (forward-comment (point-max))
231 (if (= (point) pos-0)
232 ;; 2)
233 (1+ paren-column)
234 ;; 1)
235 (+ paren-column 1 ada-indent-broken))))
236
237 (list-break
238 ;; test/parent.adb
239 ;; Append_To (Formals,
240 ;; Make_Parameter_Specification (Loc,
241 (wisi-indent-paren 1))
242
243 (t
244 ;; test/ada_mode-generic_instantiation.ads
245 ;; procedure Procedure_6 is new
246 ;; Instance.Generic_Procedure (Integer, Function_1);
247 ;; indenting 'Instance'; containing is 'new'
248 (ada-wisi-indent-cache ada-indent-broken containing))
249 )))
250
251 (open-paren
252 (let ((containing (wisi-goto-containing cache)))
253 (cl-case (wisi-cache-token containing)
254 (COMMA
255 ;; test/ada_mode-parens.adb
256 ;; A : Matrix_Type :=
257 ;; ((1, 2, 3),
258 ;; (4, 5, 6),
259 ;; indenting (4
260 (ada-wisi-indent-containing 0 containing))
261
262 (EQUAL_GREATER
263 (setq containing (wisi-goto-containing containing))
264 (cl-ecase (wisi-cache-token containing)
265 (COMMA
266 ;; test/ada_mode-long_paren.adb
267 ;; (RT => RT,
268 ;; Monitor => True,
269 ;; RX_Enable =>
270 ;; (RX_Torque_Subaddress |
271 ;; indenting (RX_Torque
272 (ada-wisi-indent-containing (1- ada-indent) containing t))
273 (LEFT_PAREN
274 ;; test/ada_mode-parens.adb
275 ;; (1 =>
276 ;; (1 => 12,
277 ;; indenting '(1 => 12'; containing is '=>'
278 (ada-wisi-indent-cache (1- ada-indent) containing))
279 (WHEN
280 ;; test/ada_mode-conditional_expressions.adb
281 ;; when 1 =>
282 ;; (if J > 42
283 ;; indenting '(if'; containing is '=>'
284 (+ (current-column) -1 ada-indent))
285 ))
286
287 ((FUNCTION PROCEDURE)
288 ;; test/ada_mode-nominal.adb
289 ;; function Function_Access_11
290 ;; (A_Param : in Float)
291 ;; -- EMACSCMD:(test-face "function" font-lock-keyword-face)
292 ;; return access function
293 ;; (A_Param : in Float)
294 ;; return
295 ;; Standard.Float -- Ada mode 4.01, GPS do this differently
296 ;; indenting second '(A_Param)
297 (+ (current-indentation) -1 ada-indent))
298
299 (LEFT_PAREN
300 ;; test/ada_mode-parens.adb
301 ;; or else ((B.all
302 ;; and then C)
303 ;; or else
304 ;; (D
305 ;; indenting (D
306 (+ (current-column) 1 ada-indent-broken))
307
308 (name
309 ;; test/indent.ads
310 ;; CSCL_Type'
311 ;; (
312 ;; identing (
313 ;;
314 ;; test/ada_mode-parens.adb
315 ;; Check
316 ;; ("foo bar",
317 ;; A
318 ;; (1),
319 ;; A(2));
320 ;; indenting (1)
321 (+ (current-indentation) ada-indent-broken))
322
323 (t
324 (cond
325 ((memq (wisi-cache-class containing) '(block-start statement-start))
326 ;; test/ada_mode-nominal.adb
327 ;; entry E2
328 ;; (X : Integer)
329 ;; indenting (X
330 (ada-wisi-indent-cache ada-indent-broken containing))
331
332 ((and
333 (eq (wisi-cache-nonterm containing) 'entry_body)
334 (eq (wisi-cache-token containing) 'WHEN))
335 ;; test/ada_mode-nominal.adb
336 ;; when Local_1 = 0 and not
337 ;; (Local_2 = 1)
338 ;; indenting (Local_2
339 (+ (current-column) ada-indent-broken))
340
341 (t
342 ;; Open paren in an expression.
343 ;;
344 ;; test/ada_mode-conditional_expressions.adb
345 ;; L0 : Integer :=
346 ;; (case J is when 42 => -1, when Integer'First .. 41 => 0, when others => 1);
347 ;; indenting (case
348 (ada-wisi-indent-containing ada-indent-broken containing t))
349 ))
350 )))
351
352 (return-1;; parameter list
353 (let ((return-pos (point)))
354 (wisi-goto-containing cache nil) ;; matching 'function'
355 (cond
356 ((<= ada-indent-return 0)
357 ;; indent relative to "("
358 (wisi-forward-find-class 'open-paren return-pos)
359 (+ (current-column) (- ada-indent-return)))
360
361 (t
362 (+ (current-column) ada-indent-return))
363 )))
364
365 (return-2;; no parameter list
366 (wisi-goto-containing cache nil) ;; matching 'function'
367 (+ (current-column) ada-indent-broken))
368
369 (statement-end
370 (ada-wisi-indent-containing ada-indent-broken cache t))
371
372 (statement-other
373 (let ((containing (wisi-goto-containing cache nil)))
374 (cl-case (wisi-cache-token cache)
375 (EQUAL_GREATER
376 (+ (current-column) ada-indent-broken))
377
378 (ELSIF
379 ;; test/g-comlin.adb
380 ;; elsif Current_Argument < CL.Argument_Count then
381 (ada-wisi-indent-cache 0 containing))
382
383 (RENAMES
384 (cl-ecase (wisi-cache-nonterm containing)
385 ((generic_renaming_declaration subprogram_renaming_declaration)
386 (wisi-forward-find-token '(FUNCTION PROCEDURE) pos-0)
387 (let ((pos-subprogram (point))
388 (has-params
389 ;; this is wrong for one return access
390 ;; function case: overriding function Foo
391 ;; return access Bar (...) renames ...;
392 (wisi-forward-find-token 'LEFT_PAREN pos-0 t)))
393 (if has-params
394 (if (<= ada-indent-renames 0)
395 ;; indent relative to paren
396 (+ (current-column) (- ada-indent-renames))
397 ;; else relative to line containing keyword
398 (goto-char pos-subprogram)
399 (+ (current-indentation) ada-indent-renames))
400
401 ;; no params
402 (goto-char pos-subprogram)
403 (+ (current-indentation) ada-indent-broken))
404 ))
405
406 (object_renaming_declaration
407 (+ (current-indentation) ada-indent-broken))
408 ))
409
410 (t
411 (while (not (wisi-cache-nonterm containing))
412 (setq containing (wisi-goto-containing containing)))
413
414 (cl-ecase (wisi-cache-nonterm containing)
415 (aggregate
416 ;; indenting 'with'
417 (+ (current-column) 1))
418
419 (association_opt
420 ;; test/indent.ads
421 ;; 1 => -- Used to be aligned on "CSCL_Type'"
422 ;; -- aligned with previous comment.
423 ;; IO_CPU_Control_State_S_Pkg.CPU2_Fault_Status_Type'
424 (ada-wisi-indent-cache ada-indent-broken containing))
425
426 (asynchronous_select
427 ;; indenting 'abort'
428 (+ (current-column) ada-indent-broken))
429
430 (component_declaration
431 ;; test/ada_mode-nominal.ads record_type_3
432 (+ (current-column) ada-indent-broken))
433
434 (entry_body
435 ;; indenting 'when'
436 (+ (current-column) ada-indent-broken))
437
438 (formal_package_declaration
439 ;; test/ada_mode-generic_package.ads
440 ;; with package A_Package_7 is
441 ;; new Ada.Text_IO.Integer_IO (Num => Formal_Signed_Integer_Type);
442 ;; indenting 'new'
443 (+ (current-column) ada-indent-broken))
444
445 (full_type_declaration
446 ;; test/ada_mode-nominal.ads
447 ;; type Unconstrained_Array_Type_3 is array (Integer range <>, Standard.Character range <>)
448 ;; of Object_Access_Type_1;
449 ;; indenting 'of'
450 ;;
451 ;; type Object_Access_Type_7
452 ;; is access all Integer;
453 ;; indenting 'is'
454 (while (not (eq 'TYPE (wisi-cache-token containing)))
455 (setq containing (wisi-goto-containing containing)))
456 (+ (current-column) ada-indent-broken))
457
458 (generic_instantiation
459 ;; test/ada_mode-generic_instantiation.ads
460 ;; procedure Procedure_7 is
461 ;; new Instance.Generic_Procedure (Integer, Function_1);
462 ;; indenting 'new'
463 (+ (current-column) ada-indent-broken))
464
465 (generic_renaming_declaration
466 ;; indenting keyword following 'generic'
467 (current-column))
468
469 (object_declaration
470 (cl-ecase (wisi-cache-token containing)
471 (COLON
472 ;; test/ada_mode-nominal.ads
473 ;; Anon_Array_3 : array (1 .. 10)
474 ;; of Integer;
475 ;; indenting 'of'
476 (+ (current-indentation) ada-indent-broken))
477
478 (COLON_EQUAL
479 ;; test/indent.ads
480 ;; C_S_Controls : constant
481 ;; CSCL_Type :=
482 ;; CSCL_Type'
483 ;; indenting 'CSCL_Type'
484 (+ (current-indentation) ada-indent-broken))
485
486 (identifier_list
487 ;; test/ada_mode-nominal.adb
488 ;; Local_2 : constant Float
489 ;; := Local_1;
490 (+ (current-indentation) ada-indent-broken))
491 ))
492
493 (qualified_expression
494 ;; test/ada_mode-nominal-child.ads
495 ;; Child_Obj_5 : constant Child_Type_1 :=
496 ;; (Parent_Type_1'
497 ;; (Parent_Element_1 => 1,
498 (ada-wisi-indent-cache ada-indent-broken containing))
499
500 (statement
501 (cl-case (wisi-cache-token containing)
502 (label_opt
503 (- (current-column) ada-indent-label))
504
505 (t
506 ;; test/ada_mode-nominal.adb
507 ;; select
508 ;; delay 1.0;
509 ;; then
510 ;; -- ...
511 ;; abort
512 (ada-wisi-indent-cache ada-indent-broken cache))
513 ))
514
515 ((subprogram_body subprogram_declaration subprogram_specification null_procedure_declaration)
516 (cl-ecase (wisi-cache-token cache)
517 (OVERRIDING
518 ;; indenting 'overriding' following 'not'
519 (current-column))
520
521 ((PROCEDURE FUNCTION)
522 ;; indenting 'procedure' or 'function following 'overriding'
523 (current-column))
524 ))
525
526 (subtype_declaration
527 ;; test/adacore_9717_001.ads A_Long_Name
528 (+ (current-column) ada-indent-broken))
529
530 ))))) ;; end statement-other
531
532 (statement-start
533 (cond
534 ((eq 'label_opt (wisi-cache-token cache))
535 (ada-wisi-indent-containing (+ ada-indent-label ada-indent) cache t))
536
537 (t
538 (let ((containing-cache (wisi-get-containing-cache cache)))
539 (if (not containing-cache)
540 ;; at bob
541 0
542 ;; not at bob
543 (cl-case (wisi-cache-class containing-cache)
544 ((block-start block-middle)
545 (wisi-goto-containing cache)
546 (cl-case (wisi-cache-nonterm containing-cache)
547 (record_definition
548 (+ (current-indentation) ada-indent))
549
550 (t
551 (ada-wisi-indent-cache ada-indent containing-cache))
552 ))
553
554 (list-break
555 ;; test/ada_mode-generic_instantiation.ads
556 ;; function Function_1 is new Instance.Generic_Function
557 ;; (Param_Type => Integer,
558 ;; Result_Type => Boolean,
559 ;; Threshold => 2);
560 ;; indenting 'Result_Type'
561 (wisi-indent-paren 1))
562
563 (statement-other
564 (cl-case (wisi-cache-token containing-cache)
565 (LEFT_PAREN
566 ;; test/ada_mode-parens.adb
567 ;; return Float (
568 ;; Integer'Value
569 ;; indenting 'Integer'
570 (wisi-indent-paren 1))
571
572 (EQUAL_GREATER
573 ;; test/ada_mode-nested_packages.adb
574 ;; exception
575 ;; when Io.Name_Error =>
576 ;; null;
577 (ada-wisi-indent-containing ada-indent containing-cache t))
578
579 (t
580 ;; test/ada_mode-generic_instantiation.ads
581 ;; procedure Procedure_6 is new
582 ;; Instance.Generic_Procedure (Integer, Function_1);
583 ;; indenting 'Instance'
584 (ada-wisi-indent-containing ada-indent-broken cache t))
585 ))
586 ))))
587 ))
588
589 (type
590 (ada-wisi-indent-containing ada-indent-broken cache t))
591 ))
592 ))
593
594 (defun ada-wisi-after-cache ()
595 "Point is at indentation, not before a cached token. Find previous
596 cached token, return new indentation for point."
597 (let ((start (point))
598 (prev-token (save-excursion (wisi-backward-token)))
599 (cache (wisi-backward-cache)))
600
601 (cond
602 ((not cache) ;; bob
603 0)
604
605 (t
606 (while (memq (wisi-cache-class cache) '(name name-paren type))
607 ;; not useful for indenting
608 (setq cache (wisi-backward-cache)))
609
610 (cl-ecase (wisi-cache-class cache)
611 (block-end
612 ;; indenting block/subprogram name after 'end'
613 (wisi-indent-current ada-indent-broken))
614
615 (block-middle
616 (cl-case (wisi-cache-token cache)
617 (IS
618 (cl-case (wisi-cache-nonterm cache)
619 (case_statement
620 ;; between 'case .. is' and first 'when'; most likely a comment
621 (ada-wisi-indent-containing 0 cache t))
622
623 (t
624 (+ (ada-wisi-indent-containing ada-indent cache t)))
625 ))
626
627 ((THEN ELSE)
628 (let ((indent
629 (cl-ecase (wisi-cache-nonterm (wisi-get-containing-cache cache))
630 ((statement if_statement elsif_statement_item) ada-indent)
631 ((if_expression elsif_expression_item) ada-indent-broken))))
632 (ada-wisi-indent-containing indent cache t)))
633
634 (WHEN
635 ;; between 'when' and '=>'
636 (+ (current-column) ada-indent-broken))
637
638 (t
639 ;; block-middle keyword may not be on separate line:
640 ;; function Create (Model : in Integer;
641 ;; Context : in String) return String is
642 (ada-wisi-indent-containing ada-indent cache nil))
643 ))
644
645 (block-start
646 (cl-case (wisi-cache-nonterm cache)
647 (exception_handler
648 ;; between 'when' and '=>'
649 (+ (current-column) ada-indent-broken))
650
651 (if_expression
652 (ada-wisi-indent-containing ada-indent-broken cache nil))
653
654 (select_alternative
655 (ada-wisi-indent-containing (+ ada-indent-when ada-indent-broken) cache nil))
656
657 (t ;; other; normal block statement
658 (ada-wisi-indent-cache ada-indent cache))
659 ))
660
661 (close-paren
662 ;; actual_parameter_part: test/ada_mode-nominal.adb
663 ;; return 1.0 +
664 ;; Foo (Bar) + -- multi-line expression that happens to have a cache at a line start
665 ;; 12;
666 ;; indenting '12'; don't indent relative to containing function name
667 ;;
668 ;; attribute_designator: test/ada_mode-nominal.adb
669 ;; raise Constraint_Error with Count'Image (Line (File)) &
670 ;; "foo";
671 ;; indenting '"foo"'; relative to raise
672 (when (memq (wisi-cache-nonterm cache)
673 '(actual_parameter_part attribute_designator))
674 (setq cache (wisi-goto-containing cache)))
675 (ada-wisi-indent-containing ada-indent-broken cache nil))
676
677 (list-break
678 (save-excursion
679 (let ((break-point (point))
680 (containing (wisi-goto-containing cache)))
681 (cl-ecase (wisi-cache-token containing)
682 (LEFT_PAREN
683 (let*
684 ((list-element-token (wisi-cache-token (save-excursion (wisi-forward-cache))))
685 (indent
686 (cl-case list-element-token
687 (WHEN ada-indent-when)
688 (t 0))))
689 (if (equal break-point (cl-caddr prev-token))
690 ;; we are indenting the first token after the list-break; not hanging.
691 (+ (current-column) 1 indent)
692 ;; else hanging
693 (+ (current-column) 1 ada-indent-broken indent))))
694
695 (IS
696 ;; ada_mode-conditional_expressions.adb
697 ;; L1 : Integer := (case J is
698 ;; when 42 => -1,
699 ;; -- comment aligned with 'when'
700 ;; indenting '-- comment'
701 (wisi-indent-paren (+ 1 ada-indent-when)))
702
703 (WITH
704 (cl-ecase (wisi-cache-nonterm containing)
705 (aggregate
706 ;; ada_mode-nominal-child.ads
707 ;; (Default_Parent with
708 ;; Child_Element_1 => 10,
709 ;; Child_Element_2 => 12.0,
710 (wisi-indent-paren 1))
711 ))
712 ))))
713
714 (open-paren
715 ;; 1) A parenthesized expression, or the first item in an aggregate:
716 ;;
717 ;; (foo +
718 ;; bar)
719 ;; (foo =>
720 ;; bar)
721 ;;
722 ;; we are indenting 'bar'
723 ;;
724 ;; 2) A parenthesized expression, or the first item in an
725 ;; aggregate, and there is whitespace between
726 ;; ( and the first token:
727 ;;
728 ;; test/ada_mode-parens.adb
729 ;; Local_9 : String := (
730 ;; "123"
731 ;;
732 ;; 3) A parenthesized expression, or the first item in an
733 ;; aggregate, and there is a comment between
734 ;; ( and the first token:
735 ;;
736 ;; test/ada_mode-nominal.adb
737 ;; A :=
738 ;; (
739 ;; -- a comment between paren and first association
740 ;; 1 =>
741 ;;
742 (let ((paren-column (current-column))
743 (start-is-comment (save-excursion (goto-char start) (looking-at comment-start-skip))))
744 (wisi-forward-token t); point is now after paren
745 (if start-is-comment
746 (skip-syntax-forward " >"); point is now on comment
747 (forward-comment (point-max)); point is now on first token
748 )
749 (if (= (point) start)
750 ;; case 2) or 3)
751 (1+ paren-column)
752 ;; 1)
753 (+ paren-column 1 ada-indent-broken))))
754
755 ((return-1 return-2)
756 ;; hanging. Intent relative to line containing matching 'function'
757 (ada-prev-statement-keyword)
758 (back-to-indentation)
759 (+ (current-column) ada-indent-broken))
760
761 (statement-end
762 (ada-wisi-indent-containing 0 cache nil))
763
764 (statement-other
765 (cl-ecase (wisi-cache-token cache)
766 (ABORT
767 ;; select
768 ;; Please_Abort;
769 ;; then
770 ;; abort
771 ;; -- 'abort' indented with ada-broken-indent, since this is part
772 ;; Titi;
773 (ada-wisi-indent-containing ada-indent cache))
774
775 ;; test/subdir/ada_mode-separate_task_body.adb
776 ((COLON COLON_EQUAL)
777 ;; Local_3 : constant Float :=
778 ;; Local_2;
779 (ada-wisi-indent-cache ada-indent-broken cache))
780
781 (COMMA
782 (cl-ecase (wisi-cache-nonterm cache)
783 (name_list
784 (cl-ecase (wisi-cache-nonterm (wisi-get-containing-cache cache))
785 (use_clause
786 ;; test/with_use1.adb
787 (ada-wisi-indent-containing ada-indent-use cache))
788
789 (with_clause
790 ;; test/ada_mode-nominal.ads
791 ;; limited private with Ada.Strings.Bounded,
792 ;; --EMACSCMD:(test-face "Ada.Containers" 'default)
793 ;; Ada.Containers;
794 ;;
795 ;; test/with_use1.adb
796 (ada-wisi-indent-containing ada-indent-with cache))
797 ))
798 ))
799
800 (ELSIF
801 ;; test/g-comlin.adb
802 ;; elsif Index_Switches + Max_Length <= Switches'Last
803 ;; and then Switches (Index_Switches + Max_Length) = '?'
804 (ada-wisi-indent-cache ada-indent-broken cache))
805
806 (EQUAL_GREATER
807 (cl-ecase (wisi-cache-nonterm (wisi-goto-containing cache nil))
808 (actual_parameter_part
809 ;; ada_mode-generic_package.ads
810 ;; with package A_Package_2 is new Ada.Text_IO.Integer_IO (Num =>
811 ;; Formal_Signed_Integer_Type);
812 ;; indenting 'Formal_Signed_...', point on '(Num'
813 (+ (current-column) 1 ada-indent-broken))
814
815 (association_list
816 ;; test/ada_mode-parens.adb
817 ;; (1 => 1,
818 ;; 2 =>
819 ;; 1 + 2 * 3,
820 ;; point is on ','
821 (wisi-indent-paren (1+ ada-indent-broken)))
822
823 ((case_expression_alternative case_statement_alternative exception_handler)
824 ;; containing is 'when'
825 (+ (current-column) ada-indent))
826
827 (generic_renaming_declaration
828 ;; not indenting keyword following 'generic'
829 (+ (current-column) ada-indent-broken))
830
831 (primary
832 ;; test/ada_mode-quantified_expressions.adb
833 ;; if (for some J in 1 .. 10 =>
834 ;; J/2 = 0)
835 (ada-wisi-indent-containing ada-indent-broken cache))
836
837 ))
838
839 (IS
840 (setq cache (wisi-goto-containing cache))
841 (cl-ecase (wisi-cache-nonterm cache)
842 (full_type_declaration
843 ;; ada_mode/nominal.ads
844 ;; type Limited_Derived_Type_1a is abstract limited new
845 ;; Private_Type_1 with record
846 ;; Component_1 : Integer;
847 ;; indenting 'Private_Type_1'; look for 'record'
848 (let ((type-column (current-column)))
849 (goto-char start)
850 (if (wisi-forward-find-token 'RECORD (line-end-position) t)
851 ;; 'record' on line being indented
852 (+ type-column ada-indent-record-rel-type)
853 ;; 'record' on later line
854 (+ type-column ada-indent-broken))))
855
856 ((formal_type_declaration
857 ;; test/ada_mode-generic_package.ads
858 ;; type Synchronized_Formal_Derived_Type is abstract synchronized new Formal_Private_Type and Interface_Type
859 ;; with private;
860
861 subtype_declaration)
862 ;; test/ada_mode-nominal.ads
863 ;; subtype Subtype_2 is Signed_Integer_Type range 10 ..
864 ;; 20;
865
866 (+ (current-column) ada-indent-broken))
867 ))
868
869 (LEFT_PAREN
870 ;; test/indent.ads
871 ;; C_S_Controls : constant
872 ;; CSCL_Type :=
873 ;; CSCL_Type'
874 ;; (
875 ;; 1 =>
876 (+ (current-column) 1))
877
878 (OF
879 ;; ada_mode-nominal.ads
880 ;; Anon_Array_2 : array (1 .. 10) of
881 ;; Integer;
882 (ada-wisi-indent-containing ada-indent-broken cache))
883
884 (NEW
885 ;; ada_mode-nominal.ads
886 ;; type Limited_Derived_Type_2 is abstract limited new Private_Type_1 with
887 ;; private;
888 (ada-wisi-indent-containing ada-indent-broken cache))
889
890 (WHEN
891 ;; test/ada_mode-parens.adb
892 ;; exit when A.all
893 ;; or else B.all
894 (ada-wisi-indent-containing ada-indent-broken cache))
895
896 (WITH
897 ;; extension aggregate: test/ada_mode-nominal-child.ads
898 ;; (Default_Parent with
899 ;; 10, 12.0, True);
900 ;; indenting '10'; containing is '('
901 ;;
902 ;; raise_statement: test/ada_mode-nominal.adb
903 ;; raise Constraint_Error with
904 ;; "help!";
905 (cl-case (wisi-cache-nonterm cache)
906 (aggregate
907 (ada-wisi-indent-containing 0 cache nil))
908 (raise_statement
909 (ada-wisi-indent-containing ada-indent-broken cache nil))
910 ))
911
912 ;; otherwise just hanging
913 ((ACCEPT FUNCTION PROCEDURE RENAMES)
914 (back-to-indentation)
915 (+ (current-column) ada-indent-broken))
916
917 ))
918
919 (statement-start
920 (cl-case (wisi-cache-token cache)
921 (WITH ;; with_clause
922 (+ (current-column) ada-indent-with))
923
924 (label_opt
925 ;; comment after label
926 (+ (current-column) (- ada-indent-label)))
927
928 (t
929 ;; procedure Procedure_8
930 ;; is new Instance.Generic_Procedure (Integer, Function_1);
931 ;; indenting 'is'; hanging
932 ;; (+ (current-column) ada-indent-broken))
933 (ada-wisi-indent-cache ada-indent-broken cache))
934 ))
935 )))
936 ))
937
938 (defun ada-wisi-comment ()
939 "Compute indentation of a comment. For `wisi-indent-functions'."
940 ;; We know we are at the first token on a line. We check for comment
941 ;; syntax, not comment-start, to accomodate gnatprep, skeleton
942 ;; placeholders, etc.
943 (when (= 11 (syntax-class (syntax-after (point))))
944
945 ;; We are at a comment; indent to previous code or comment.
946 (cond
947 ((and ada-indent-comment-col-0
948 (= 0 (current-column)))
949 0)
950
951 ((or
952 (save-excursion (forward-line -1) (looking-at "\\s *$"))
953 (save-excursion (forward-comment -1)(not (looking-at comment-start))))
954 ;; comment is after a blank line or code; indent as if code
955 ;;
956 ;; ada-wisi-before-cache will find the keyword _after_ the
957 ;; comment, which could be a block-middle or block-end, and that
958 ;; would align the comment with the block-middle, which is wrong. So
959 ;; we only call ada-wisi-after-cache.
960
961 ;; FIXME: need option to match gnat style check; change indentation to match (ie mod 3)
962 (ada-wisi-after-cache))
963
964 (t
965 ;; comment is after a comment
966 (forward-comment -1)
967 (current-column))
968 )))
969
970 (defun ada-wisi-post-parse-fail ()
971 "For `wisi-post-parse-fail-hook'."
972 (save-excursion
973 (let ((start-cache (wisi-goto-start (or (wisi-get-cache (point)) (wisi-backward-cache)))))
974 (when start-cache
975 ;; nil when in a comment at point-min
976 (indent-region (point) (wisi-cache-end start-cache)))
977 ))
978 (back-to-indentation))
979
980 ;;;; ada-mode functions (alphabetical)
981
982 (defun ada-wisi-declarative-region-start-p (cache)
983 "Return t if cache is a keyword starting a declarative region."
984 (cl-case (wisi-cache-token cache)
985 (DECLARE t)
986 (IS
987 (memq (wisi-cache-class cache) '(block-start block-middle)))
988 (t nil)
989 ))
990
991 (defun ada-wisi-context-clause ()
992 "For `ada-fix-context-clause'."
993 (wisi-validate-cache (point-max))
994 (save-excursion
995 (goto-char (point-min))
996 (let ((begin nil)
997 (end nil)
998 cache)
999
1000 (while (not end)
1001 (setq cache (wisi-forward-cache))
1002 (cl-case (wisi-cache-nonterm cache)
1003 (pragma nil)
1004 (use_clause nil)
1005 (with_clause
1006 (when (not begin)
1007 (setq begin (point-at-bol))))
1008 (t
1009 ;; start of compilation unit
1010 (setq end (point-at-bol))
1011 (unless begin
1012 (setq begin end)))
1013 ))
1014 (cons begin end)
1015 )))
1016
1017 (defun ada-wisi-goto-declaration-start ()
1018 "For `ada-goto-declaration-start', which see.
1019 Also return cache at start."
1020 (wisi-validate-cache (point))
1021 (let ((cache (wisi-get-cache (point)))
1022 (done nil))
1023 (unless cache
1024 (setq cache (wisi-backward-cache)))
1025 ;; cache is null at bob
1026 (while (not done)
1027 (if cache
1028 (progn
1029 (setq done
1030 (cl-case (wisi-cache-nonterm cache)
1031 ((generic_package_declaration generic_subprogram_declaration)
1032 (eq (wisi-cache-token cache) 'GENERIC))
1033
1034 ((package_body package_declaration)
1035 (eq (wisi-cache-token cache) 'PACKAGE))
1036
1037 ((protected_body protected_type_declaration single_protected_declaration)
1038 (eq (wisi-cache-token cache) 'PROTECTED))
1039
1040 ((subprogram_body subprogram_declaration null_procedure_declaration)
1041 (memq (wisi-cache-token cache) '(NOT OVERRIDING FUNCTION PROCEDURE)))
1042
1043 (task_type_declaration
1044 (eq (wisi-cache-token cache) 'TASK))
1045
1046 ))
1047 (unless done
1048 (setq cache (wisi-goto-containing cache nil))))
1049 (setq done t))
1050 )
1051 cache))
1052
1053 (defun ada-wisi-goto-declarative-region-start ()
1054 "For `ada-goto-declarative-region-start', which see."
1055 (wisi-validate-cache (point))
1056 (let ((done nil)
1057 (first t)
1058 (cache
1059 (or
1060 (wisi-get-cache (point))
1061 ;; we use forward-cache here, to handle the case where point is after a subprogram declaration:
1062 ;; declare
1063 ;; ...
1064 ;; function ... is ... end;
1065 ;; <point>
1066 ;; function ... is ... end;
1067 (wisi-forward-cache))))
1068 (while (not done)
1069 (if (ada-wisi-declarative-region-start-p cache)
1070 (progn
1071 (wisi-forward-token t)
1072 (setq done t))
1073 (cl-case (wisi-cache-class cache)
1074 ((block-middle block-end)
1075 (setq cache (wisi-prev-statement-cache cache)))
1076
1077 (statement-start
1078 ;; 1) test/ada_mode-nominal.adb
1079 ;; protected body Protected_1 is -- target 2
1080 ;; <point>
1081 ;; want target 2
1082 ;;
1083 ;; 2) test/ada_mode-nominal.adb
1084 ;; function Function_Access_1
1085 ;; (A_Param <point> : in Float)
1086 ;; return
1087 ;; Standard.Float
1088 ;; is -- target 1
1089 ;; want target 1
1090 ;;
1091 ;; 3) test/ada_mode-nominal-child.adb
1092 ;; overriding <point> function Function_2c (Param : in Child_Type_1)
1093 ;; return Float
1094 ;; is -- target Function_2c
1095 ;; want target
1096
1097 (if first
1098 ;; case 1
1099 (setq cache (wisi-goto-containing cache t))
1100 ;; case 2, 3
1101 (cl-case (wisi-cache-nonterm cache)
1102 (subprogram_body
1103 (while (not (eq 'IS (wisi-cache-token cache)))
1104 (setq cache (wisi-next-statement-cache cache))))
1105 (t
1106 (setq cache (wisi-goto-containing cache t)))
1107 )))
1108 (t
1109 (setq cache (wisi-goto-containing cache t)))
1110 ))
1111 (when first (setq first nil)))
1112 ))
1113
1114 (defun ada-wisi-in-paramlist-p ()
1115 "For `ada-in-paramlist-p'."
1116 (wisi-validate-cache (point))
1117 ;; (info "(elisp)Parser State" "*syntax-ppss*")
1118 (let* ((parse-result (syntax-ppss))
1119 cache)
1120 (and (> (nth 0 parse-result) 0)
1121 ;; cache is nil if the parse failed
1122 (setq cache (wisi-get-cache (nth 1 parse-result)))
1123 (eq 'formal_part (wisi-cache-nonterm cache)))
1124 ))
1125
1126 (defun ada-wisi-make-subprogram-body ()
1127 "For `ada-make-subprogram-body'."
1128 (wisi-validate-cache (point))
1129 (when wisi-parse-failed
1130 (error "syntax parse failed; cannot create body"))
1131
1132 (let* ((begin (point))
1133 (end (save-excursion (wisi-forward-find-class 'statement-end (point-max)) (point)))
1134 (cache (wisi-forward-find-class 'name end))
1135 (name (buffer-substring-no-properties
1136 (point)
1137 (+ (point) (wisi-cache-last cache)))))
1138 (goto-char end)
1139 (newline)
1140 (insert " is begin\nnull;\nend ");; legal syntax; parse does not fail
1141 (insert name)
1142 (forward-char 1)
1143
1144 ;; newline after body to separate from next body
1145 (newline-and-indent)
1146 (indent-region begin (point))
1147 (forward-line -2)
1148 (back-to-indentation); before 'null;'
1149 ))
1150
1151 (defun ada-wisi-scan-paramlist (begin end)
1152 "For `ada-scan-paramlist'."
1153 (wisi-validate-cache end)
1154 (goto-char begin)
1155 (let (token
1156 text
1157 identifiers
1158 (in-p nil)
1159 (out-p nil)
1160 (not-null-p nil)
1161 (access-p nil)
1162 (constant-p nil)
1163 (protected-p nil)
1164 (type nil)
1165 type-begin
1166 type-end
1167 (default nil)
1168 (default-begin nil)
1169 param
1170 paramlist
1171 (done nil))
1172 (while (not done)
1173 (let ((token-text (wisi-forward-token)))
1174 (setq token (nth 0 token-text))
1175 (setq text (nth 1 token-text)))
1176 (cond
1177 ((equal token 'COMMA) nil);; multiple identifiers
1178
1179 ((equal token 'COLON)
1180 ;; identifiers done. find type-begin; there may be no mode
1181 (skip-syntax-forward " ")
1182 (setq type-begin (point))
1183 (save-excursion
1184 (while (member (car (wisi-forward-token)) '(IN OUT NOT NULL ACCESS CONSTANT PROTECTED))
1185 (skip-syntax-forward " ")
1186 (setq type-begin (point)))))
1187
1188 ((equal token 'IN) (setq in-p t))
1189 ((equal token 'OUT) (setq out-p t))
1190 ((and (not type-end)
1191 (member token '(NOT NULL)))
1192 ;; "not", "null" could be part of the default expression
1193 (setq not-null-p t))
1194 ((equal token 'ACCESS) (setq access-p t))
1195 ((equal token 'CONSTANT) (setq constant-p t))
1196 ((equal token 'PROTECTED) (setq protected-p t))
1197
1198 ((equal token 'COLON_EQUAL)
1199 (setq type-end (save-excursion (backward-char 2) (skip-syntax-backward " ") (point)))
1200 (skip-syntax-forward " ")
1201 (setq default-begin (point))
1202 (wisi-forward-find-token 'SEMICOLON end t))
1203
1204 ((member token '(SEMICOLON RIGHT_PAREN))
1205 (if (equal token 'RIGHT_PAREN)
1206 ;; all done
1207 (progn
1208 (setq done t)
1209 (when (not type-end) (setq type-end (1- (point))))
1210 (when default-begin (setq default (buffer-substring-no-properties default-begin (1- (point)))))
1211 )
1212 ;; else semicolon - one param done
1213 (when (not type-end) (setq type-end (1- (point))))
1214 (when default-begin (setq default (buffer-substring-no-properties default-begin (1- (point)))))
1215 )
1216
1217 (setq type (buffer-substring-no-properties type-begin type-end))
1218 (setq param (list (reverse identifiers)
1219 in-p out-p not-null-p access-p constant-p protected-p
1220 type default))
1221 (if paramlist
1222 (add-to-list 'paramlist param)
1223 (setq paramlist (list param)))
1224 (setq identifiers nil
1225 in-p nil
1226 out-p nil
1227 not-null-p nil
1228 access-p nil
1229 constant-p nil
1230 protected-p nil
1231 type nil
1232 type-begin nil
1233 type-end nil
1234 default nil
1235 default-begin nil))
1236
1237 (t
1238 (when (not type-begin)
1239 (if identifiers
1240 (add-to-list 'identifiers text)
1241 (setq identifiers (list text)))))
1242 ))
1243 paramlist))
1244
1245 (defun ada-wisi-which-function-1 (keyword add-body)
1246 "used in `ada-wisi-which-function'."
1247 (let (region
1248 result
1249 (cache (wisi-forward-find-class 'name (point-max))))
1250
1251 (setq result (wisi-cache-text cache))
1252
1253 (when (not ff-function-name)
1254 (setq ff-function-name
1255 (concat
1256 keyword
1257 (when add-body "\\s-+body")
1258 "\\s-+"
1259 result
1260 ada-symbol-end)))
1261 result))
1262
1263 (defun ada-wisi-which-function ()
1264 "For `ada-which-function'."
1265 (wisi-validate-cache (point))
1266 (save-excursion
1267 (let ((result nil)
1268 (cache (ada-wisi-goto-declaration-start)))
1269 (if (null cache)
1270 ;; bob
1271 (setq result "")
1272
1273 (cl-case (wisi-cache-nonterm cache)
1274 ((generic_package_declaration generic_subprogram_declaration)
1275 ;; name is after next statement keyword
1276 (wisi-next-statement-cache cache)
1277 (setq cache (wisi-get-cache (point))))
1278 )
1279
1280 ;; add or delete 'body' as needed
1281 (cl-ecase (wisi-cache-nonterm cache)
1282 (package_body
1283 (setq result (ada-wisi-which-function-1 "package" nil)))
1284
1285 ((package_declaration
1286 generic_package_declaration) ;; after 'generic'
1287 (setq result (ada-wisi-which-function-1 "package" t)))
1288
1289 (protected_body
1290 (setq result (ada-wisi-which-function-1 "protected" nil)))
1291
1292 ((protected_type_declaration single_protected_declaration)
1293 (setq result (ada-wisi-which-function-1 "protected" t)))
1294
1295 ((subprogram_declaration
1296 subprogram_specification ;; after 'generic'
1297 null_procedure_declaration)
1298 (setq result (ada-wisi-which-function-1
1299 (wisi-cache-text (wisi-forward-find-token '(FUNCTION PROCEDURE) (point-max)))
1300 nil))) ;; no 'body' keyword in subprogram bodies
1301
1302 (subprogram_body
1303 (setq result (ada-wisi-which-function-1
1304 (wisi-cache-text (wisi-forward-find-token '(FUNCTION PROCEDURE) (point-max)))
1305 nil)))
1306
1307 (task_type_declaration
1308 (setq result (ada-wisi-which-function-1 "task" t)))
1309
1310 ))
1311 result)))
1312
1313 ;;;; debugging
1314 (defun ada-wisi-debug-keys ()
1315 "Add debug key definitions to `ada-mode-map'."
1316 (interactive)
1317 (define-key ada-mode-map "\M-e" 'wisi-show-parse-error)
1318 (define-key ada-mode-map "\M-h" 'wisi-show-containing-or-previous-cache)
1319 (define-key ada-mode-map "\M-i" 'wisi-goto-end)
1320 (define-key ada-mode-map "\M-j" 'wisi-show-cache)
1321 (define-key ada-mode-map "\M-k" 'wisi-show-token)
1322 )
1323
1324 ;;;###autoload
1325 (defun ada-wisi-setup ()
1326 "Set up a buffer for parsing Ada files with wisi."
1327 (wisi-setup '(ada-wisi-comment
1328 ada-wisi-before-cache
1329 ada-wisi-after-cache)
1330 'ada-wisi-post-parse-fail
1331 ada-wisi-class-list
1332 ada-grammar-wy--keyword-table
1333 ada-grammar-wy--token-table
1334 ada-grammar-wy--parse-table)
1335 (setq wisi-string-quote-escape-doubled t)
1336
1337 (set (make-local-variable 'comment-indent-function) 'wisi-comment-indent)
1338
1339 (add-hook 'hack-local-variables-hook 'ada-wisi-post-local-vars nil t)
1340 )
1341
1342 (defun ada-wisi-post-local-vars ()
1343 ;; run after file local variables are read because font-lock-add-keywords
1344 ;; evaluates font-lock-defaults, which depends on ada-language-version.
1345 (font-lock-add-keywords 'ada-mode
1346 ;; use keyword cache to distinguish between 'function ... return <type>;' and 'return ...;'
1347 (list
1348 (list
1349 (concat
1350 "\\<\\("
1351 "return[ \t]+access[ \t]+constant\\|"
1352 "return[ \t]+access\\|"
1353 "return"
1354 "\\)\\>[ \t]*"
1355 ada-name-regexp "?")
1356 '(1 font-lock-keyword-face)
1357 '(2 (if (eq (when (not (ada-in-string-or-comment-p))
1358 (wisi-validate-cache (match-end 2))
1359 (and (wisi-get-cache (match-beginning 2))
1360 (wisi-cache-class (wisi-get-cache (match-beginning 2)))))
1361 'type)
1362 font-lock-type-face
1363 'default)
1364 nil t)
1365 )))
1366
1367 (when global-font-lock-mode
1368 ;; ensure the modified keywords are applied
1369 (font-lock-refresh-defaults))
1370 )
1371
1372 (add-hook 'ada-mode-hook 'ada-wisi-setup)
1373
1374 (setq ada-fix-context-clause 'ada-wisi-context-clause)
1375 (setq ada-goto-declaration-start 'ada-wisi-goto-declaration-start)
1376 (setq ada-goto-declarative-region-start 'ada-wisi-goto-declarative-region-start)
1377 (setq ada-goto-end 'wisi-goto-end)
1378 (setq ada-in-paramlist-p 'ada-wisi-in-paramlist-p)
1379 (setq ada-indent-statement 'wisi-indent-statement)
1380 (setq ada-make-subprogram-body 'ada-wisi-make-subprogram-body)
1381 (setq ada-next-statement-keyword 'wisi-forward-statement-keyword)
1382 (setq ada-prev-statement-keyword 'wisi-backward-statement-keyword)
1383 (setq ada-scan-paramlist 'ada-wisi-scan-paramlist)
1384 (setq ada-show-parse-error 'wisi-show-parse-error)
1385 (setq ada-which-function 'ada-wisi-which-function)
1386
1387 (provide 'ada-wisi)
1388 (provide 'ada-indent-engine)
1389
1390 ;; end of file