;; ada-xref.el --- for lookup and completion in Ada mode
-;; Copyright (C) 1994-2011 Free Software Foundation, Inc.
+;; Copyright (C) 1994-2014 Free Software Foundation, Inc.
;; Author: Markus Heritsch <Markus.Heritsch@studbox.uni-stuttgart.de>
;; Rolf Ebert <ebert@inf.enst.fr>
;;; for lookup and completion in Ada mode.
;;;
;;; If a file *.`adp' exists in the ada-file directory, then it is
-;;; read for configuration informations. It is read only the first
+;;; read for configuration information. It is read only the first
;;; time a cross-reference is asked for, and is not read later.
;;; You need Emacs >= 20.2 to run this package
;; ------ User variables
(defcustom ada-xref-other-buffer t
- "*If nil, always display the cross-references in the same buffer.
+ "If nil, always display the cross-references in the same buffer.
Otherwise create either a new buffer or a new frame."
:type 'boolean :group 'ada)
(defcustom ada-xref-create-ali nil
- "*If non-nil, run gcc whenever the cross-references are not up-to-date.
+ "If non-nil, run gcc whenever the cross-references are not up-to-date.
If nil, the cross-reference mode never runs gcc."
:type 'boolean :group 'ada)
(defcustom ada-xref-confirm-compile nil
- "*If non-nil, ask for confirmation before compiling or running the application."
+ "If non-nil, ask for confirmation before compiling or running the application."
:type 'boolean :group 'ada)
(defcustom ada-krunch-args "0"
- "*Maximum number of characters for filenames created by `gnatkr'.
+ "Maximum number of characters for filenames created by `gnatkr'.
Set to 0, if you don't use crunched filenames. This should be a string."
:type 'string :group 'ada)
:type 'string :group 'ada)
(defcustom ada-gnatls-args '("-v")
- "*Arguments to pass to `gnatls' to find location of the runtime.
+ "Arguments to pass to `gnatls' to find location of the runtime.
Typical use is to pass `--RTS=soft-floats' on some systems that support it.
You can also add `-I-' if you do not want the current directory to be included.
(defcustom ada-prj-default-check-cmd
(concat "${cross_prefix}gnatmake -u -c -gnatc ${gnatmake_opt} ${full_current}"
" -cargs ${comp_opt}")
- "*Default command to be used to compile a single file.
+ "Default command to be used to compile a single file.
Emacs will substitute the current filename for ${full_current}, or add
the filename at the end. This is the same syntax as in the project file."
:type 'string :group 'ada)
(defcustom ada-prj-default-comp-cmd
(concat "${cross_prefix}gnatmake -u -c ${gnatmake_opt} ${full_current} -cargs"
" ${comp_opt}")
- "*Default command to be used to compile a single file.
+ "Default command to be used to compile a single file.
Emacs will substitute the current filename for ${full_current}, or add
the filename at the end. This is the same syntax as in the project file."
:type 'string :group 'ada)
(defcustom ada-prj-default-debugger "${cross_prefix}gdb"
- "*Default name of the debugger."
+ "Default name of the debugger."
:type 'string :group 'ada)
(defcustom ada-prj-default-make-cmd
(concat "${cross_prefix}gnatmake -o ${main} ${main} ${gnatmake_opt} "
"-cargs ${comp_opt} -bargs ${bind_opt} -largs ${link_opt}")
- "*Default command to be used to compile the application.
+ "Default command to be used to compile the application.
This is the same syntax as in the project file."
:type 'string :group 'ada)
(defcustom ada-prj-default-project-file ""
- "*Name of the current project file.
+ "Name of the current project file.
Emacs will not try to use the search algorithm to find the project file if
this string is not empty. It is set whenever a project file is found."
:type '(file :must-match t) :group 'ada)
(defcustom ada-gnatstub-opts "-q -I${src_dir}"
- "*Options to pass to `gnatsub' to generate the body of a package.
+ "Options to pass to `gnatsub' to generate the body of a package.
This has the same syntax as in the project file (with variable substitution)."
:type 'string :group 'ada)
(defcustom ada-always-ask-project nil
- "*If nil, use default values when no project file was found.
+ "If nil, use default values when no project file was found.
Otherwise, ask the user for the name of the project file to use."
:type 'boolean :group 'ada)
"True if we are running on Windows.")
(defcustom ada-tight-gvd-integration nil
- "*If non-nil, a new Emacs frame will be swallowed in GVD when debugging.
+ "If non-nil, a new Emacs frame will be swallowed in GVD when debugging.
If GVD is not the debugger used, nothing happens."
:type 'boolean :group 'ada)
(defcustom ada-xref-search-with-egrep t
- "*If non-nil, use egrep to find the possible declarations for an entity.
+ "If non-nil, use egrep to find the possible declarations for an entity.
This alternate method is used when the exact location was not found in the
information provided by GNAT. However, it might be expensive if you have a lot
of sources, since it will search in all the files in your project."
)
(kill-buffer nil))))
- (set 'ada-xref-runtime-library-specs-path
+ (setq ada-xref-runtime-library-specs-path
(reverse ada-xref-runtime-library-specs-path))
- (set 'ada-xref-runtime-library-ali-path
+ (setq ada-xref-runtime-library-ali-path
(reverse ada-xref-runtime-library-ali-path))
))
(while dirs
(if (file-directory-p (car dirs))
- (set 'list (append list (file-name-all-completions string (car dirs)))))
- (set 'dirs (cdr dirs)))
+ (setq list (append list (file-name-all-completions string (car dirs)))))
+ (setq dirs (cdr dirs)))
(cond ((equal flag 'lambda)
(assoc string list))
(flag
((file-exists-p first-choice)
;; filename.adp
- (set 'selected first-choice))
+ (setq selected first-choice))
((= (length prj-files) 1)
;; Exactly one project file was found in the current directory
- (set 'selected (car prj-files)))
+ (setq selected (car prj-files)))
((and (> (length prj-files) 1) (not no-user-question))
;; multiple project files in current directory, ask the user
(> choice (length prj-files)))
(setq choice (string-to-number
(read-from-minibuffer "Enter No. of your choice: "))))
- (set 'selected (nth (1- choice) prj-files))))
+ (setq selected (nth (1- choice) prj-files))))
((= (length prj-files) 0)
;; No project file in the current directory; ask user
(concat "project file [" ada-last-prj-file "]:")
nil ada-last-prj-file))
(unless (string= ada-last-prj-file "")
- (set 'selected ada-last-prj-file))))
+ (setq selected ada-last-prj-file))))
)))
(or selected "default.adp")
(setq prj-file (expand-file-name prj-file))
(if (string= (file-name-extension prj-file) "gpr")
- (set 'project (ada-gnat-parse-gpr project prj-file))
+ (setq project (ada-gnat-parse-gpr project prj-file))
- (set 'project (ada-parse-prj-file-1 prj-file project))
+ (setq project (ada-parse-prj-file-1 prj-file project))
)
;; Store the project properties
(substitute-in-file-name (match-string 2)))))
((string= (match-string 1) "build_dir")
- (set 'project
+ (setq project
(plist-put project 'build_dir
(file-name-as-directory (match-string 2)))))
(t
;; any other field in the file is just copied
- (set 'project (plist-put project
+ (setq project (plist-put project
(intern (match-string 1))
(match-string 2))))))
(let ((sep (plist-get project 'ada_project_path_sep)))
(setq ada_project_path (reverse ada_project_path))
(setq ada_project_path (mapconcat 'identity ada_project_path sep))
- (set 'project (plist-put project 'ada_project_path ada_project_path))
+ (setq project (plist-put project 'ada_project_path ada_project_path))
;; env var needed now for ada-gnat-parse-gpr
(setenv "ADA_PROJECT_PATH" ada_project_path)))
- (if debug_post_cmd (set 'project (plist-put project 'debug_post_cmd (reverse debug_post_cmd))))
- (if debug_pre_cmd (set 'project (plist-put project 'debug_pre_cmd (reverse debug_pre_cmd))))
- (if casing (set 'project (plist-put project 'casing (reverse casing))))
- (if check_cmd (set 'project (plist-put project 'check_cmd (reverse check_cmd))))
- (if comp_cmd (set 'project (plist-put project 'comp_cmd (reverse comp_cmd))))
- (if make_cmd (set 'project (plist-put project 'make_cmd (reverse make_cmd))))
- (if run_cmd (set 'project (plist-put project 'run_cmd (reverse run_cmd))))
+ (if debug_post_cmd (setq project (plist-put project 'debug_post_cmd (reverse debug_post_cmd))))
+ (if debug_pre_cmd (setq project (plist-put project 'debug_pre_cmd (reverse debug_pre_cmd))))
+ (if casing (setq project (plist-put project 'casing (reverse casing))))
+ (if check_cmd (setq project (plist-put project 'check_cmd (reverse check_cmd))))
+ (if comp_cmd (setq project (plist-put project 'comp_cmd (reverse comp_cmd))))
+ (if make_cmd (setq project (plist-put project 'make_cmd (reverse make_cmd))))
+ (if run_cmd (setq project (plist-put project 'run_cmd (reverse run_cmd))))
(if gpr_file
(progn
- (set 'project (ada-gnat-parse-gpr project gpr_file))
+ (setq project (ada-gnat-parse-gpr project gpr_file))
;; append Ada source and object directories to others from Emacs project file
(setq src_dir (append (plist-get project 'src_dir) src_dir))
(setq obj_dir (append (plist-get project 'obj_dir) obj_dir))
(ada-initialize-runtime-library (or (ada-xref-get-project-field 'cross_prefix) ""))
;;)
- (if obj_dir (set 'project (plist-put project 'obj_dir (reverse obj_dir))))
- (if src_dir (set 'project (plist-put project 'src_dir (reverse src_dir))))
+ (if obj_dir (setq project (plist-put project 'obj_dir (reverse obj_dir))))
+ (if src_dir (setq project (plist-put project 'src_dir (reverse src_dir))))
project
))
(if old-contents
(progn
(goto-char 1)
- (set 'buffer-read-only nil)
+ (setq buffer-read-only nil)
(insert old-contents)
- (set 'buffer-read-only t)
+ (setq buffer-read-only t)
(goto-char (point-max)))))
)
)
(condition-case err
(ada-find-in-ali identlist other-frame)
;; File not found: print explicit error message
- (error-file-not-found
+ (ada-error-file-not-found
(message (concat (error-message-string err)
(nthcdr 1 err))))
(defun ada-goto-declaration-other-frame (pos)
"Display the declaration of the identifier around POS.
-The declation is shown in another frame if `ada-xref-other-buffer' is non-nil."
+The declaration is shown in another frame if `ada-xref-other-buffer' is
+non-nil."
(interactive "d")
(ada-goto-declaration pos t))
(objects (getenv "ADA_OBJECTS_PATH"))
(build-dir (ada-xref-get-project-field 'build_dir)))
(if include
- (set 'include (concat path-separator include)))
+ (setq include (concat path-separator include)))
(if objects
- (set 'objects (concat path-separator objects)))
+ (setq objects (concat path-separator objects)))
(cons
(concat "ADA_INCLUDE_PATH="
(mapconcat (lambda(x) (expand-file-name x build-dir))
;; Guess the command if it wasn't specified
(if (not command)
- (set 'command (list (file-name-sans-extension (buffer-name)))))
+ (setq command (list (file-name-sans-extension (buffer-name)))))
;; Modify the command to run remotely
(setq command (ada-remote (mapconcat 'identity command
;; Run the command
(with-current-buffer (get-buffer-create "*run*")
- (set 'buffer-read-only nil)
+ (setq buffer-read-only nil)
(erase-buffer)
(start-process "run" (current-buffer) shell-file-name
;; If the command was not given in the project file, start a bare gdb
(if (not cmd)
- (set 'cmd (concat ada-prj-default-debugger
+ (setq cmd (concat ada-prj-default-debugger
" "
(or executable-name
(file-name-sans-extension (buffer-file-name))))))
- ;; For gvd, add an extra switch so that the Emacs window is completly
+ ;; For gvd, add an extra switch so that the Emacs window is completely
;; swallowed inside the Gvd one
(if (and ada-tight-gvd-integration
(string-match "^[^ \t]*gvd" cmd))
;; chance to fully manage it. Then it works fine with Enlightenment
;; as well
(let ((frame (make-frame '((visibility . nil)))))
- (set 'cmd (concat
+ (setq cmd (concat
cmd " --editor-window="
(cdr (assoc 'outer-window-id (frame-parameters frame)))))
(select-frame frame)))
;; Add a -fullname switch
;; Use the remote machine
- (set 'cmd (ada-remote (concat cmd " -fullname ")))
+ (setq cmd (ada-remote (concat cmd " -fullname ")))
;; Ask for confirmation if required
(if (or arg ada-xref-confirm-compile)
- (set 'cmd (read-from-minibuffer "enter command to debug: " cmd)))
+ (setq cmd (read-from-minibuffer "enter command to debug: " cmd)))
(let ((old-comint-exec (symbol-function 'comint-exec)))
;; FIXME: This is evil but luckily a nop under Emacs-21.3.50 ! -stef
(fset 'gud-gdb-massage-args (lambda (_file args) args))
- (set 'pre-cmd (mapconcat 'identity pre-cmd ada-command-separator))
+ (setq pre-cmd (mapconcat 'identity pre-cmd ada-command-separator))
(if (not (equal pre-cmd ""))
(setq pre-cmd (concat pre-cmd ada-command-separator)))
- (set 'post-cmd (mapconcat 'identity post-cmd "\n"))
+ (setq post-cmd (mapconcat 'identity post-cmd "\n"))
(if post-cmd
- (set 'post-cmd (concat post-cmd "\n")))
+ (setq post-cmd (concat post-cmd "\n")))
;; Temporarily replaces the definition of `comint-exec' so that we
`(lambda (buffer name command startfile switches)
(let (compilation-buffer-name-function)
(save-excursion
- (set 'compilation-buffer-name-function
+ (setq compilation-buffer-name-function
(lambda(x) (buffer-name buffer)))
(compile (ada-quote-cmd
(concat ,pre-cmd
;; is going to have some relevant information.
(if (or (not (string-match "gvd" (comint-arguments cmd 0 0)))
(string-match "--tty" cmd))
- (split-window-vertically))
+ (split-window-below))
(switch-to-buffer buffer)
)))
"Search for FILE in DIR-LIST."
(let (found)
(while (and (not found) dir-list)
- (set 'found (concat (file-name-as-directory (car dir-list))
+ (setq found (concat (file-name-as-directory (car dir-list))
(file-name-nondirectory file)))
(unless (file-exists-p found)
- (set 'found nil))
- (set 'dir-list (cdr dir-list)))
+ (setq found nil))
+ (setq dir-list (cdr dir-list)))
found))
(defun ada-find-ali-file-in-dir (file)
;; .ali file for a spec file. If we are, go to step 3.
;; 3- If the file is not found or step 2 failed:
;; find the name of the "other file", ie the body, and look
- ;; for its associated .ali file by subtituing the extension
+ ;; for its associated .ali file by substituting the extension
;;
;; We must also handle the case of separate packages and subprograms:
;; 4- If no ali file was found, we try to modify the file name by removing
;; also a separate.
(with-current-buffer (get-file-buffer file)
- (let ((short-ali-file-name
- (concat (file-name-sans-extension (file-name-nondirectory file))
- ".ali"))
+ (let ((short-ali-file-name (concat (file-name-base file) ".ali"))
ali-file-name
is-spec)
(while specs
(if (string-match (concat (regexp-quote (car specs)) "$")
file)
- (set 'is-spec t))
- (set 'specs (cdr specs)))))
+ (setq is-spec t))
+ (setq specs (cdr specs)))))
(if is-spec
- (set 'ali-file-name
+ (setq ali-file-name
(ada-find-ali-file-in-dir
- (concat (file-name-sans-extension
- (file-name-nondirectory
- (ada-other-file-name)))
- ".ali"))))
+ (concat (file-name-base (ada-other-file-name)) ".ali"))))
(setq ali-file-name
;; file_s.ada and file_b.ada), try to go to the other file
;; and look for its ali file
(ada-find-ali-file-in-dir
- (concat (file-name-sans-extension
- (file-name-nondirectory (ada-other-file-name)))
- ".ali"))
+ (concat (file-name-base (ada-other-file-name)) ".ali"))
;; If we still don't have an ali file, try to get the one
;; from the parent unit, in case we have a separate entity.
- (let ((parent-name (file-name-sans-extension
- (file-name-nondirectory file))))
+ (let ((parent-name (file-name-base file)))
(while (and (not ali-file-name)
(string-match "^\\(.*\\)[.-][^.-]*" parent-name))
- (set 'parent-name (match-string 1 parent-name))
- (set 'ali-file-name (ada-find-ali-file-in-dir
+ (setq parent-name (match-string 1 parent-name))
+ (setq ali-file-name (ada-find-ali-file-in-dir
(concat parent-name ".ali")))
)
ali-file-name)))
(let ((filename (ada-find-src-file-in-dir file)))
(if filename
(expand-file-name filename)
- (signal 'error-file-not-found (file-name-nondirectory file)))
+ (signal 'ada-error-file-not-found (file-name-nondirectory file)))
)))
(defun ada-find-file-number-in-ali (file)
(if (and (= (char-before) ?\")
(= (char-after (+ (length (match-string 0)) (point))) ?\"))
(forward-char -1))
- (set 'identifier (regexp-quote (concat "\"" (match-string 0) "\""))))
+ (setq identifier (regexp-quote (concat "\"" (match-string 0) "\""))))
(if (ada-in-string-p)
(error "Inside string or character constant"))
(if (looking-at (concat ada-keywords "[^a-zA-Z_]"))
(error "No cross-reference available for reserved keyword"))
(if (looking-at "[a-zA-Z0-9_]+")
- (set 'identifier (match-string 0))
+ (setq identifier (match-string 0))
(error "No identifier around")))
;; Build the identlist
- (set 'identlist (ada-make-identlist))
+ (setq identlist (ada-make-identlist))
(ada-set-name identlist (downcase identifier))
(ada-set-line identlist
(number-to-string (count-lines 1 (point))))
(concat "^X [0-9]+ " (file-name-nondirectory (ada-file-of identlist)))
nil t)
(let ((bound (save-excursion (re-search-forward "^X " nil t))))
- (set 'declaration-found
+ (setq declaration-found
(re-search-forward
(concat "^" (ada-line-of identlist)
"." (ada-column-of identlist)
(unless declaration-found
- ;; Since we alread know the number of the file, search for a direct
+ ;; Since we already know the number of the file, search for a direct
;; reference to it
(goto-char (point-min))
- (set 'declaration-found t)
+ (setq declaration-found t)
(ada-set-ali-index
identlist
(number-to-string (ada-find-file-number-in-ali
;; If still not found, then either the declaration is unknown
;; or the source file has been modified since the ali file was
;; created
- (set 'declaration-found nil)
+ (setq declaration-found nil)
)
)
- ;; Last check to be completly sure we have found the correct line (the
+ ;; Last check to be completely sure we have found the correct line (the
;; ali might not be up to date for instance)
(if declaration-found
(progn
(beginning-of-line))
(unless (looking-at (concat "[0-9]+.[0-9]+[ *]"
(ada-name-of identlist) "[ <{=\(\[]"))
- (set 'declaration-found nil))))
+ (setq declaration-found nil))))
;; Still no success ! The ali file must be too old, and we need to
;; use a basic algorithm based on guesses. Note that this only happens
;; automatically
(unless declaration-found
(if (ada-xref-find-in-modified-ali identlist)
- (set 'declaration-found t)
+ (setq declaration-found t)
;; No more idea to find the declaration. Give up
(progn
(kill-buffer ali-buffer)
(forward-line 1)
(beginning-of-line)
(while (looking-at "^\\.\\(.*\\)")
- (set 'current-line (concat current-line (match-string 1)))
+ (setq current-line (concat current-line (match-string 1)))
(forward-line 1))
)
(ada-file-of identlist)))
;; Else clean up the ali file
- (error-file-not-found
+ (ada-error-file-not-found
(signal (car err) (cdr err)))
(error
(kill-buffer ali-buffer)
(goto-char (point-max))
(while (re-search-backward my-regexp nil t)
(save-excursion
- (set 'line-ali (count-lines 1 (point)))
+ (setq line-ali (count-lines 1 (point)))
(beginning-of-line)
;; have a look at the line and column numbers
(if (looking-at "^\\([0-9]+\\).\\([0-9]+\\)[ *]")
;; Get all the possible locations
(string-match "^\\([0-9]+\\)[a-zA-Z+*]\\([0-9]+\\)[ *]" ali-line)
- (set 'locations (list (list (match-string 1 ali-line) ;; line
+ (setq locations (list (list (match-string 1 ali-line) ;; line
(match-string 2 ali-line) ;; column
(ada-declare-file-of identlist))))
(while (string-match "\\([0-9]+\\)[bc]\\(<[^>]+>\\)?\\([0-9]+\\)"
(goto-char (point-min))
(re-search-forward "^D \\([a-zA-Z0-9_.-]+\\)" nil t
(string-to-number file-number))
- (set 'file (match-string 1))
+ (setq file (match-string 1))
)
;; Else get the nearest file
- (set 'file (ada-declare-file-of identlist)))
+ (setq file (ada-declare-file-of identlist)))
- (set 'locations (append locations (list (list line col file)))))
+ (setq locations (append locations (list (list line col file)))))
;; Add the specs at the end again, so that from the last body we go to
;; the specs
- (set 'locations (append locations (list (car locations))))
+ (setq locations (append locations (list (car locations))))
;; Find the new location we want to go to.
;; If we are on none of the locations listed, we simply go to the specs.
col (nth 1 locations)
file (nth 2 locations)
locations nil)
- (set 'locations (cdr locations))))
+ (setq locations (cdr locations))))
;; Find the file in the source path
- (set 'file (ada-get-ada-file-name file (ada-file-of identlist)))
+ (setq file (ada-get-ada-file-name file (ada-file-of identlist)))
;; Kill the .ali buffer
(kill-buffer (current-buffer))
" "
(shell-quote-argument (file-name-as-directory (car dirs)))
"*.ali")))
- (set 'dirs (cdr dirs)))
+ (setq dirs (cdr dirs)))
;; Now parse the output
- (set 'case-fold-search t)
+ (setq case-fold-search t)
(goto-char (point-min))
(while (re-search-forward regexp nil t)
(save-excursion
(setq line (match-string 1)
column (match-string 2))
(re-search-backward "^X [0-9]+ \\(.*\\)$")
- (set 'file (list (match-string 1) line column))
+ (setq file (list (match-string 1) line column))
;; There could be duplicate choices, because of the structure
;; of the .ali files
(unless (member file list)
- (set 'list (append list (list file))))))))
+ (setq list (append list (list file))))))))
;; Current buffer is still "*grep*"
(kill-buffer "*grep*")
;; Only one choice => Do the cross-reference
((= (length list) 1)
- (set 'file (ada-find-src-file-in-dir (caar list)))
+ (setq file (ada-find-src-file-in-dir (caar list)))
(if file
(ada-xref-change-buffer file
(string-to-number (nth 1 (car list)))
(string-to-number
(read-from-minibuffer "Enter No. of your choice: "))))
)
- (set 'choice (1- choice))
+ (setq choice (1- choice))
(kill-buffer "*choice list*")
- (set 'file (ada-find-src-file-in-dir (car (nth choice list))))
+ (setq file (ada-find-src-file-in-dir (car (nth choice list))))
(if file
(ada-xref-change-buffer file
(string-to-number (nth 1 (nth choice list)))
(string-to-number (nth 2 (nth choice list)))
identlist
other-frame)
- (signal 'error-file-not-found (car (nth choice list))))
+ (signal 'ada-error-file-not-found (car (nth choice list))))
(message "This is only a (good) guess at the cross-reference.")
))))
(if ada-xref-other-buffer
(if other-frame
(find-file-other-frame file)
- (set 'declaration-buffer (find-file-noselect file))
+ (setq declaration-buffer (find-file-noselect file))
(set-buffer declaration-buffer)
(switch-to-buffer-other-window declaration-buffer)
)
(add-hook 'ada-mode-hook 'ada-xref-initialize)
;; Define a new error type
-(put 'error-file-not-found
- 'error-conditions
- '(error ada-mode-errors error-file-not-found))
-(put 'error-file-not-found
- 'error-message
- "File not found in src-dir (check project file): ")
+(define-error 'ada-error-file-not-found
+ "File not found in src-dir (check project file): " 'ada-mode-errors)
(provide 'ada-xref)