]> code.delx.au - gnu-emacs-elpa/blob - packages/ada-mode/gpr-query.el
2ec07717af2f3febce9109be9125f64cf2c78066
[gnu-emacs-elpa] / packages / ada-mode / gpr-query.el
1 ;;; gpr-query.el --- minor-mode for navigating sources using the
2 ;;; custom gpr_query tool, based on AdaCore cross reference tool
3 ;;; gnatinspect.
4 ;;;
5 ;;; gpr-query supports Ada and any gcc language that supports the
6 ;;; AdaCore -fdump-xref switch (which includes C, C++).
7 ;;
8 ;;; Copyright (C) 2013, 2014 Free Software Foundation, Inc.
9
10 ;; Author: Stephen Leake <stephen_leake@member.fsf.org>
11 ;; Maintainer: Stephen Leake <stephen_leake@member.fsf.org>
12 ;; Version: 1.0
13
14 ;; This file is part of GNU Emacs.
15
16 ;; GNU Emacs is free software: you can redistribute it and/or modify
17 ;; it under the terms of the GNU General Public License as published by
18 ;; the Free Software Foundation, either version 3 of the License, or
19 ;; (at your option) any later version.
20
21 ;; GNU Emacs is distributed in the hope that it will be useful,
22 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
23 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 ;; GNU General Public License for more details.
25
26 ;; You should have received a copy of the GNU General Public License
27 ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
28
29 ;;; Usage:
30 ;;
31 ;; M-x gpr-query
32
33 (require 'ada-mode) ;; for ada-prj-*, some other things
34 (require 'gnat-core)
35 (require 'cl-lib)
36 (require 'compile)
37
38 ;;;;; sessions
39
40 ;; gpr_query reads the project files and the database at startup,
41 ;; which is noticeably slow for a reasonably sized project. But
42 ;; running queries after startup is fast. So we leave gpr_query
43 ;; running, and send it new queries via stdin, getting responses via
44 ;; stdout.
45 ;;
46 ;; We maintain a cache of active sessions, one per gnat project.
47
48 (cl-defstruct (gpr-query--session)
49 (process nil) ;; running gpr_query
50 (buffer nil)) ;; receives output of gpr_query
51
52 (defconst gpr-query-buffer-name-prefix " *gpr_query-")
53
54 (defun gpr-query--start-process (session)
55 "Start the session process running gpr_query."
56 (unless (buffer-live-p (gpr-query--session-buffer session))
57 ;; user may have killed buffer
58 (setf (gpr-query--session-buffer session) (gnat-run-buffer gpr-query-buffer-name-prefix)))
59
60 (with-current-buffer (gpr-query--session-buffer session)
61 (let ((process-environment (ada-prj-get 'proc_env)) ;; for GPR_PROJECT_PATH
62
63 (project-file (file-name-nondirectory (ada-prj-get 'gpr_file))))
64 (erase-buffer); delete any previous messages, prompt
65 (setf (gpr-query--session-process session)
66 ;; gnatcoll-1.6 can't handle aggregate projects; M910-032
67 ;; gpr_query can handle some aggregate projects, but not all
68 ;; FIXME: need good error message on bad project file:
69 ;; "can't handle aggregate projects?")
70 (start-process (concat "gpr_query " (buffer-name))
71 (gpr-query--session-buffer session)
72 "gpr_query"
73 (concat "--project=" project-file)))
74 (set-process-query-on-exit-flag (gpr-query--session-process session) nil)
75 (gpr-query-session-wait session)
76
77 ;; check for warnings about invalid directories etc
78 (goto-char (point-min))
79 (when (search-forward "warning:" nil t)
80 (error "gpr_query warnings"))
81 )))
82
83 (defun gpr-query--make-session ()
84 "Create and return a session for the current project file."
85 (let ((session
86 (make-gpr-query--session
87 :buffer (gnat-run-buffer gpr-query-buffer-name-prefix))))
88 (gpr-query--start-process session)
89 session))
90
91 (defvar gpr-query--sessions '()
92 "Assoc list of sessions, indexed by absolute GNAT project file name.")
93
94 (defun gpr-query-cached-session ()
95 "Return a session for the current project file, creating it if necessary."
96 (let* ((session (cdr (assoc ada-prj-current-file gpr-query--sessions))))
97 (if session
98 (progn
99 (unless (process-live-p (gpr-query--session-process session))
100 (gpr-query--start-process session))
101 session)
102 ;; else
103 (prog1
104 (setq session (gpr-query--make-session))
105 (setq gpr-query--sessions
106 (cl-acons ada-prj-current-file session gpr-query--sessions))))
107 ))
108
109 (defconst gpr-query-prompt "^>>> $"
110 ;; gpr_query output ends with this
111 "Regexp matching gpr_query prompt; indicates previous command is complete.")
112
113 (defun gpr-query-session-wait (session)
114 "Wait for the current command to complete."
115 (unless (process-live-p (gpr-query--session-process session))
116 (gpr-query-show-buffer session)
117 (error "gpr-query process died"))
118
119 (with-current-buffer (gpr-query--session-buffer session)
120 (let ((process (gpr-query--session-process session))
121 (search-start (point-min))
122 (wait-count 0))
123 (while (and (process-live-p process)
124 (progn
125 ;; process output is inserted before point, so move back over it to search it
126 (goto-char search-start)
127 (not (re-search-forward gpr-query-prompt (point-max) 1))))
128 (setq search-start (point));; don't search same text again
129 (message (concat "running gpr_query ..." (make-string wait-count ?.)))
130 ;; FIXME: use --display-progress
131 (accept-process-output process 1.0)
132 (setq wait-count (1+ wait-count)))
133 (if (process-live-p process)
134 (message (concat "running gpr_query ... done"))
135 (gpr-query-show-buffer session)
136 (error "gpr_query process died"))
137 )))
138
139 (defun gpr-require-prj ()
140 "Throw error if no project file defined."
141 (unless (or (ada-prj-get 'gpr_file)
142 (ada-prj-get 'gpr_query_file))
143 (error "no gpr project file defined.")))
144
145 (defun gpr-query-session-send (cmd wait)
146 "Send CMD to gpr_query session for current project.
147 If WAIT is non-nil, wait for command to complete.
148 Return buffer that holds output."
149 (gpr-require-prj)
150 (let ((session (gpr-query-cached-session)))
151 ;; always wait for previous command to complete; also checks for
152 ;; dead process.
153 (gpr-query-session-wait session)
154 (with-current-buffer (gpr-query--session-buffer session)
155 (erase-buffer)
156 (process-send-string (gpr-query--session-process session)
157 (concat cmd "\n"))
158 (when wait
159 (gpr-query-session-wait session))
160 (current-buffer)
161 )))
162
163 (defun gpr-query-kill-session (session)
164 (let ((process (gpr-query--session-process session)))
165 (when (process-live-p process)
166 (process-send-string (gpr-query--session-process session) "exit\n")
167 (while (process-live-p process)
168 (accept-process-output process 1.0)))
169 ))
170
171 (defun gpr-query-kill-all-sessions ()
172 (interactive)
173 (let ((count 0))
174 (mapc (lambda (assoc)
175 (let ((session (cdr assoc)))
176 (when (process-live-p (gpr-query--session-process session))
177 (setq count (1+ count))
178 (process-send-string (gpr-query--session-process session) "exit\n")
179 )))
180 gpr-query--sessions)
181 (message "Killed %d sessions" count)
182 ))
183
184 (defun gpr-query-show-buffer (&optional session)
185 "For `ada-show-xref-tool-buffer'; show gpr-query buffer for current project."
186 (interactive)
187 (pop-to-buffer (gpr-query--session-buffer (or session (gpr-query-cached-session)))))
188
189 ;;;;; utils
190
191 (defun gpr-query-get-src-dirs (src-dirs)
192 "Append list of source dirs in current gpr project to SRC-DIRS.
193 Uses 'gpr_query'. Returns new list."
194
195 (with-current-buffer (gpr-query--session-buffer (gpr-query-cached-session))
196 (gpr-query-session-send "source_dirs" t)
197 (goto-char (point-min))
198 (while (not (looking-at gpr-query-prompt))
199 (cl-pushnew (directory-file-name
200 (buffer-substring-no-properties (point) (point-at-eol)))
201 src-dirs :test #'equal)
202 (forward-line 1))
203 )
204 src-dirs)
205
206 (defun gpr-query-get-prj-dirs (prj-dirs)
207 "Append list of source dirs in current gpr project to PRJ-DIRS.
208 Uses 'gpr_query'. Returns new list."
209
210 (with-current-buffer (gpr-query--session-buffer (gpr-query-cached-session))
211 (gpr-query-session-send "project_path" t)
212 (goto-char (point-min))
213 (while (not (looking-at gpr-query-prompt))
214 (cl-pushnew (directory-file-name
215 (buffer-substring-no-properties (point) (point-at-eol)))
216 prj-dirs :test #'equal)
217 (forward-line 1))
218 )
219 prj-dirs)
220
221 (defconst gpr-query-ident-file-regexp
222 ;; C:\Projects\GDS\work_dscovr_release\common\1553\gds-mil_std_1553-utf.ads:252:25
223 ;; /Projects/GDS/work_dscovr_release/common/1553/gds-mil_std_1553-utf.ads:252:25
224 "\\(\\(?:.:\\\|/\\)[^:]*\\):\\([0123456789]+\\):\\([0123456789]+\\)"
225 ;; 1 2 3
226 "Regexp matching <file>:<line>:<column>")
227
228 (defconst gpr-query-ident-file-regexp-alist
229 (list (concat "^" gpr-query-ident-file-regexp) 1 2 3)
230 "For compilation-error-regexp-alist, matching gpr_query output")
231
232 (defconst gpr-query-ident-file-type-regexp
233 (concat gpr-query-ident-file-regexp " (\\(.*\\))")
234 "Regexp matching <file>:<line>:<column> (<type>)")
235
236 ;; debugging:
237 ;; in *compilation-gpr_query-refs*, run
238 ;; (progn (set-text-properties (point-min)(point-max) nil)(compilation-parse-errors (point-min)(point-max) gpr-query-ident-file-regexp-alist))
239
240 (defun gpr-query-compilation (identifier file line col cmd comp-err)
241 "Run gpr_query IDENTIFIER:FILE:LINE:COL CMD,
242 set compilation-mode with compilation-error-regexp-alist set to COMP-ERR."
243 ;; Useful when gpr_query will return a list of references; we use
244 ;; `compilation-start' to run gpr_query, so the user can navigate
245 ;; to each result in turn via `next-error'.
246 (let ((cmd-1 (format "%s %s:%s:%d:%d" cmd identifier file line col))
247 (result-count 0)
248 file line column)
249 ;; FIXME: Code duplication with gnat-inspect-compilation!
250 (with-current-buffer (gpr-query--session-buffer (gpr-query-cached-session))
251 (compilation-mode)
252 (setq buffer-read-only nil)
253 (set (make-local-variable 'compilation-error-regexp-alist) (list comp-err))
254 (gpr-query-session-send cmd-1 t)
255 ;; point is at EOB. gpr_query returns one line per result plus prompt
256 (setq result-count (- (line-number-at-pos) 1))
257 ;; Won't be needed in 24.5 any more.
258 (if (fboundp 'font-lock-ensure)
259 (font-lock-ensure)
260 (font-lock-fontify-buffer))
261 ;; font-lock-fontify-buffer applies compilation-message text properties
262 ;; NOTE: Won't be needed in 24.5 any more, since compilation-next-error
263 ;; will apply compilation-message text properties on the fly.
264 ;; IMPROVEME: for some reason, next-error works, but the font
265 ;; colors are not right (no koolaid!)
266 (goto-char (point-min))
267
268 (cl-case result-count
269 (0
270 (error "gpr_query returned no results"))
271 (1
272 (when (looking-at "^Error: entity not found")
273 (error (buffer-substring-no-properties (line-beginning-position) (line-end-position))))
274
275 ;; just go there, don't display session-buffer. We have to
276 ;; fetch the compilation-message while in the session-buffer.
277 (let* ((msg (compilation-next-error 0 nil (point-min)))
278 ;; FIXME: Woah! This is messing with very internal details!
279 (loc (compilation--message->loc msg)))
280 (setq file (caar (compilation--loc->file-struct loc))
281 line (caar (cddr (compilation--loc->file-struct loc)))
282 column (1- (compilation--loc->col loc)))
283 ))
284
285 (t
286 ;; for next-error, below
287 (setq next-error-last-buffer (current-buffer)))
288
289 ));; case, with-currrent-buffer
290
291 (if (> result-count 1)
292 ;; more than one result; display session buffer, goto first ref
293 ;;
294 ;; compilation-next-error-function assumes there is not an error
295 ;; at point-min; work around that by moving forward 0 errors for
296 ;; the first one. Unless the first line contains "warning: ".
297 (if (looking-at "^warning: ")
298 (next-error)
299 (next-error 0 t))
300
301 ;; just one result; go there
302 (ada-goto-source file line column nil))
303 ))
304
305 (defun gpr-query-dist (found-line line found-col col)
306 "Return distance between FOUND-LINE FOUND-COL and LINE COL."
307 (+ (abs (- found-col col))
308 (* (abs (- found-line line)) 250)))
309
310 ;;;;; user interface functions
311
312 (defun gpr-query-show-references ()
313 "Show all references of identifier at point."
314 (interactive)
315 (gpr-query-all
316 (thing-at-point 'symbol)
317 (file-name-nondirectory (buffer-file-name))
318 (line-number-at-pos)
319 (1+ (current-column)))
320 )
321
322 (defun gpr-query-overridden (other-window)
323 "Move to the overridden declaration of the identifier around point.
324 If OTHER-WINDOW (set by interactive prefix) is non-nil, show the
325 buffer in another window."
326 (interactive "P")
327
328 (let ((target
329 (gpr-query-overridden-1
330 (thing-at-point 'symbol)
331 (buffer-file-name)
332 (line-number-at-pos)
333 (save-excursion
334 (goto-char (car (bounds-of-thing-at-point 'symbol)))
335 (1+ (current-column)))
336 )))
337
338 (ada-goto-source (nth 0 target)
339 (nth 1 target)
340 (nth 2 target)
341 other-window)
342 ))
343
344 (defun gpr-query-goto-declaration (other-window)
345 "Move to the declaration or body of the identifier around point.
346 If at the declaration, go to the body, and vice versa. If at a
347 reference, goto the declaration.
348
349 If OTHER-WINDOW (set by interactive prefix) is non-nil, show the
350 buffer in another window."
351 (interactive "P")
352
353 (let ((target
354 (gpr-query-other
355 (thing-at-point 'symbol)
356 (buffer-file-name)
357 (line-number-at-pos)
358 (save-excursion
359 (goto-char (car (bounds-of-thing-at-point 'symbol)))
360 (1+ (current-column)))
361 )))
362
363 (ada-goto-source (nth 0 target)
364 (nth 1 target)
365 (nth 2 target)
366 other-window)
367 ))
368
369 (defvar gpr-query-map
370 (let ((map (make-sparse-keymap)))
371 ;; C-c C-i prefix for gpr-query minor mode
372
373 (define-key map "\C-c\C-i\C-d" 'gpr-query-goto-declaration)
374 (define-key map "\C-c\C-i\C-p" 'ada-build-prompt-select-prj-file)
375 (define-key map "\C-c\C-i\C-q" 'gpr-query-refresh)
376 (define-key map "\C-c\C-i\C-r" 'gpr-query-show-references)
377 ;; FIXME: (define-key map "\C-c\M-d" 'gpr-query-parents)
378 ;; FIXME: overriding
379 map
380 ) "Local keymap used for GNAT inspect minor mode.")
381
382 (defvar gpr-query-menu (make-sparse-keymap "gpr-query"))
383 (easy-menu-define gpr-query-menu gpr-query-map "Menu keymap for gpr-query minor mode"
384 '("gpr-query"
385 ["Find and select project ..." ada-build-prompt-select-prj-file t]
386 ["Select project ..." ada-prj-select t]
387 ["Show current project" ada-prj-show t]
388 ["Show gpr-query buffer" gpr-query-show-buffer t]
389 ["Next compilation error" next-error t]
390 ["Show secondary error" ada-show-secondary-error t]
391 ["Goto declaration/body" gpr-query-goto-declaration t]
392 ["Show parent declarations" ada-show-declaration-parents t]
393 ["Show references" gpr-query-show-references t]
394 ;; ["Show overriding" gpr-query-show-overriding t]
395 ;; ["Show overridden" gpr-query-show-overridden t]
396 ["Refresh cross reference cache" gpr-query-refresh t]
397 ))
398
399 (define-minor-mode gpr-query
400 "Minor mode for navigating sources using GNAT cross reference tool.
401 Enable mode if ARG is positive"
402 :initial-value t
403 :lighter " gpr-query" ;; mode line
404
405 ;; just enable the menu and keymap
406 )
407
408 ;;;;; support for Ada mode
409
410 (defun gpr-query-refresh ()
411 "For `ada-xref-refresh-function', using gpr_query."
412 (interactive)
413 ;; need to kill session to get changed env vars etc
414 (let ((session (gpr-query-cached-session)))
415 (gpr-query-kill-session session)
416 (gpr-query--start-process session)))
417
418 (defun gpr-query-other (identifier file line col)
419 "For `ada-xref-other-function', using gpr_query."
420 (when (eq ?\" (aref identifier 0))
421 ;; gpr_query wants the quotes stripped
422 (setq col (+ 1 col))
423 (setq identifier (substring identifier 1 (1- (length identifier))))
424 )
425
426 (when (eq system-type 'windows-nt)
427 ;; Since Windows file system is case insensitive, GNAT and Emacs
428 ;; can disagree on the case, so convert all to lowercase.
429 (setq file (downcase file)))
430
431 (let ((cmd (format "refs %s:%s:%d:%d" identifier (file-name-nondirectory file) line col))
432 (decl-loc nil)
433 (body-loc nil)
434 (search-type nil)
435 (min-distance (1- (expt 2 29)))
436 (result nil))
437
438 (with-current-buffer (gpr-query-session-send cmd t)
439 ;; 'gpr_query refs' returns a list containing the declaration,
440 ;; the body, and all the references, in no particular order.
441 ;;
442 ;; We search the list, looking for the input location,
443 ;; declaration and body, then return the declaration or body as
444 ;; appropriate.
445 ;;
446 ;; the format of each line is file:line:column (type)
447 ;; 1 2 3 4
448 ;;
449 ;; 'type' can be:
450 ;; body
451 ;; declaration
452 ;; full declaration (for a private type)
453 ;; implicit reference
454 ;; reference
455 ;; static call
456 ;;
457 ;; Module_Type:/home/Projects/GDS/work_stephe_2/common/1553/gds-hardware-bus_1553-wrapper.ads:171:9 (full declaration)
458 ;;
459 ;; itc_assert:/home/Projects/GDS/work_stephe_2/common/itc/opsim/itc_dscovr_gdsi/Gds1553/src/Gds1553.cpp:830:9 (reference)
460
461 (message "parsing result ...")
462
463 (goto-char (point-min))
464
465 (while (not (eobp))
466 (cond
467 ((looking-at gpr-query-ident-file-type-regexp)
468 ;; process line
469 (let* ((found-file (match-string 1))
470 (found-line (string-to-number (match-string 2)))
471 (found-col (string-to-number (match-string 3)))
472 (found-type (match-string 4))
473 (dist (gpr-query-dist found-line line found-col col))
474 )
475
476 (when (eq system-type 'windows-nt)
477 ;; 'expand-file-name' converts Windows directory
478 ;; separators to normal Emacs. Since Windows file
479 ;; system is case insensitive, GNAT and Emacs can
480 ;; disagree on the case, so convert all to lowercase.
481 (setq found-file (downcase (expand-file-name found-file))))
482
483 (when (string-equal found-type "declaration")
484 (setq decl-loc (list found-file found-line (1- found-col))))
485
486 (when (or
487 (string-equal found-type "body")
488 (string-equal found-type "full declaration"))
489 (setq body-loc (list found-file found-line (1- found-col))))
490
491 (when
492 ;; The source may have changed since the xref database
493 ;; was computed, so allow for fuzzy matches.
494 (and (equal found-file file)
495 (< dist min-distance))
496 (setq min-distance dist)
497 (setq search-type found-type))
498 ))
499
500 (t ;; ignore line
501 ;;
502 ;; This skips GPR_PROJECT_PATH and echoed command at start of buffer.
503 ;;
504 ;; It also skips warning lines. For example,
505 ;; gnatcoll-1.6w-20130902 can't handle the Auto_Text_IO
506 ;; language, because it doesn't use the gprconfig
507 ;; configuration project. That gives lines like:
508 ;;
509 ;; common_text_io.gpr:15:07: language unknown for "gds-hardware-bus_1553-time_tone.ads"
510 ;;
511 ;; There are probably other warnings that might be reported as well.
512 )
513 )
514 (forward-line 1)
515 )
516
517 (cond
518 ((null search-type)
519 nil)
520
521 ((and
522 (string-equal search-type "declaration")
523 body-loc)
524 (setq result body-loc))
525
526 (decl-loc
527 (setq result decl-loc))
528 )
529
530 (when (null result)
531 (error "gpr_query did not return other item; refresh?"))
532
533 (message "parsing result ... done")
534 result)))
535
536 (defun gpr-query-all (identifier file line col)
537 "For `ada-xref-all-function', using gpr_query."
538 (gpr-query-compilation identifier file line col "refs" 'gpr-query-ident-file))
539
540 (defun gpr-query-parents (identifier file line col)
541 "For `ada-xref-parent-function', using gpr_query."
542 (gpr-query-compilation identifier file line col "parent_types" 'gpr-query-ident-file))
543
544 (defun gpr-query-overriding (identifier file line col)
545 "For `ada-xref-overriding-function', using gpr_query."
546 (gpr-query-compilation identifier file line col "overriding" 'gpr-query-ident-file))
547
548 (defun gpr-query-overridden-1 (identifier file line col)
549 "For `ada-xref-overridden-function', using gpr_query."
550 (when (eq ?\" (aref identifier 0))
551 ;; gpr_query wants the quotes stripped
552 (setq col (+ 1 col))
553 (setq identifier (substring identifier 1 (1- (length identifier))))
554 )
555
556 (let ((cmd (format "overridden %s:%s:%d:%d" identifier (file-name-nondirectory file) line col))
557 result)
558 (with-current-buffer (gpr-query-session-send cmd t)
559
560 (goto-char (point-min))
561 (when (looking-at gpr-query-ident-file-regexp)
562 (setq result
563 (list
564 (match-string 1)
565 (string-to-number (match-string 2))
566 (string-to-number (match-string 3)))))
567
568 (when (null result)
569 (error "gpr_query did not return a result; refresh?"))
570
571 (message "parsing result ... done")
572 result)))
573
574 (defun ada-gpr-query-select-prj ()
575 (setq ada-file-name-from-ada-name 'ada-gnat-file-name-from-ada-name)
576 (setq ada-ada-name-from-file-name 'ada-gnat-ada-name-from-file-name)
577 (setq ada-make-package-body 'ada-gnat-make-package-body)
578
579 (add-hook 'ada-syntax-propertize-hook 'gnatprep-syntax-propertize)
580
581 ;; must be after indentation engine setup, because that resets the
582 ;; indent function list.
583 (add-hook 'ada-mode-hook 'ada-gpr-query-setup t)
584
585 (setq ada-xref-refresh-function 'gpr-query-refresh)
586 (setq ada-xref-all-function 'gpr-query-all)
587 (setq ada-xref-other-function 'gpr-query-other)
588 (setq ada-xref-parent-function 'gpr-query-parents)
589 (setq ada-xref-all-function 'gpr-query-all)
590 (setq ada-xref-overriding-function 'gpr-query-overriding)
591 (setq ada-xref-overridden-function 'gpr-query-overridden-1)
592 (setq ada-show-xref-tool-buffer 'gpr-query-show-buffer)
593
594 (add-to-list 'completion-ignored-extensions ".ali") ;; gnat library files, used for cross reference
595 )
596
597 (defun ada-gpr-query-deselect-prj ()
598 (setq ada-file-name-from-ada-name nil)
599 (setq ada-ada-name-from-file-name nil)
600 (setq ada-make-package-body nil)
601
602 (setq ada-syntax-propertize-hook (delq 'gnatprep-syntax-propertize ada-syntax-propertize-hook))
603 (setq ada-mode-hook (delq 'ada-gpr-query-setup ada-mode-hook))
604
605 (setq ada-xref-other-function nil)
606 (setq ada-xref-parent-function nil)
607 (setq ada-xref-all-function nil)
608 (setq ada-xref-overriding-function nil)
609 (setq ada-xref-overridden-function nil)
610 (setq ada-show-xref-tool-buffer nil)
611
612 (setq completion-ignored-extensions (delete ".ali" completion-ignored-extensions))
613 )
614
615 (defun ada-gpr-query-setup ()
616 (when (boundp 'wisi-indent-calculate-functions)
617 (add-to-list 'wisi-indent-calculate-functions 'gnatprep-indent))
618 )
619
620 (defun ada-gpr-query ()
621 "Set Ada mode global vars to use gpr_query."
622 (add-to-list 'ada-prj-parser-alist '("gpr" . gnat-parse-gpr))
623 (add-to-list 'ada-select-prj-xref-tool '(gpr_query . ada-gpr-query-select-prj))
624 (add-to-list 'ada-deselect-prj-xref-tool '(gpr_query . ada-gpr-query-deselect-prj))
625
626 ;; no parse-*-xref
627
628 (font-lock-add-keywords 'ada-mode
629 ;; gnatprep preprocessor line
630 (list (list "^[ \t]*\\(#.*\n\\)" '(1 font-lock-type-face t))))
631 )
632
633 (provide 'gpr-query)
634 (provide 'ada-xref-tool)
635
636 (add-to-list 'compilation-error-regexp-alist-alist
637 (cons 'gpr-query-ident-file gpr-query-ident-file-regexp-alist))
638
639 (unless (and (boundp 'ada-xref-tool)
640 (default-value 'ada-xref-tool))
641 (setq ada-xref-tool 'gpr_query))
642
643 (ada-gpr-query)
644
645 ;;; end of file