]> code.delx.au - gnu-emacs-elpa/blobdiff - packages/ada-mode/gpr-query.el
Merge commit '60d4c09c982a1c562a70cd6aa705f47ab3badcfb' from company
[gnu-emacs-elpa] / packages / ada-mode / gpr-query.el
old mode 100755 (executable)
new mode 100644 (file)
index 36cbd33..ae4ed8e
@@ -31,6 +31,7 @@
 ;; M-x gpr-query
 
 (require 'ada-mode) ;; for ada-prj-*, some other things
+(require 'gnat-core)
 (require 'cl-lib)
 (require 'compile)
 
@@ -46,9 +47,7 @@
 
 (cl-defstruct (gpr-query--session)
   (process nil) ;; running gpr_query
-  (buffer nil)  ;; receives output of gpr_query
-  (sent-kill-p nil)
-  (closed-p nil))
+  (buffer nil)) ;; receives output of gpr_query
 
 (defconst gpr-query-buffer-name-prefix " *gpr_query-")
 
   (with-current-buffer (gpr-query--session-buffer session)
     (let ((process-environment (ada-prj-get 'proc_env)) ;; for GPR_PROJECT_PATH
 
-         ;; WORKAROUND: gnatcoll-1.6 can't handle aggregate projects; M910-032
-         ;; gpr_query can handle some aggregate projects, but not all
-         (project-file (file-name-nondirectory
-                        (or (ada-prj-get 'gpr_query_file)
-                            (ada-prj-get 'gpr_file)))))
+         (project-file (file-name-nondirectory (ada-prj-get 'gpr_file))))
       (erase-buffer); delete any previous messages, prompt
       (setf (gpr-query--session-process session)
+           ;; gnatcoll-1.6 can't handle aggregate projects; M910-032
+           ;; gpr_query can handle some aggregate projects, but not all
            ;; FIXME: need good error message on bad project file:
-           ;;          "can't handle aggregate projects? - set gpr_query_file")
+           ;;          "can't handle aggregate projects?")
            (start-process (concat "gpr_query " (buffer-name))
                           (gpr-query--session-buffer session)
                           "gpr_query"
@@ -80,7 +77,6 @@
       ;; check for warnings about invalid directories etc
       (goto-char (point-min))
       (when (search-forward "warning:" nil t)
-       (pop-to-buffer (current-buffer))
        (error "gpr_query warnings"))
       )))
 
 
 (defun gpr-query-session-wait (session)
   "Wait for the current command to complete."
+  (unless (process-live-p (gpr-query--session-process session))
+    (gpr-query-show-buffer session)
+    (error "gpr-query process died"))
+
   (with-current-buffer (gpr-query--session-buffer session)
     (let ((process (gpr-query--session-process session))
          (search-start (point-min))
        (setq wait-count (1+ wait-count)))
       (if (process-live-p process)
          (message (concat "running gpr_query ... done"))
-       (pop-to-buffer (current-buffer))
+       (gpr-query-show-buffer session)
        (error "gpr_query process died"))
       )))
 
@@ -148,8 +148,10 @@ If WAIT is non-nil, wait for command to complete.
 Return buffer that holds output."
   (gpr-require-prj)
   (let ((session (gpr-query-cached-session)))
+    ;; always wait for previous command to complete; also checks for
+    ;; dead process.
+    (gpr-query-session-wait session)
     (with-current-buffer (gpr-query--session-buffer session)
-      ;; FIXME: Check prev command complete (might not have waited); look for prompt at EOB
       (erase-buffer)
       (process-send-string (gpr-query--session-process session)
                           (concat cmd "\n"))
@@ -158,6 +160,14 @@ Return buffer that holds output."
       (current-buffer)
       )))
 
+(defun gpr-query-kill-session (session)
+  (let ((process (gpr-query--session-process session)))
+    (when (process-live-p process)
+      (process-send-string (gpr-query--session-process session) "exit\n")
+      (while (process-live-p process)
+       (accept-process-output process 1.0)))
+    ))
+
 (defun gpr-query-kill-all-sessions ()
   (interactive)
   (let ((count 0))
@@ -171,6 +181,11 @@ Return buffer that holds output."
     (message "Killed %d sessions" count)
     ))
 
+(defun gpr-query-show-buffer (&optional session)
+  "For `ada-show-xref-tool-buffer'; show gpr-query buffer for current project."
+  (interactive)
+  (pop-to-buffer (gpr-query--session-buffer (or session (gpr-query-cached-session)))))
+
 ;;;;; utils
 
 (defun gpr-query-get-src-dirs (src-dirs)
@@ -363,6 +378,7 @@ buffer in another window."
     ["Find and select project ..."   ada-build-prompt-select-prj-file t]
     ["Select project ..."            ada-prj-select                   t]
     ["Show current project"          ada-prj-show                     t]
+    ["Show gpr-query buffer"         gpr-query-show-buffer            t]
     ["Next compilation error"        next-error                       t]
     ["Show secondary error"          ada-show-secondary-error         t]
     ["Goto declaration/body"         gpr-query-goto-declaration       t]
@@ -387,7 +403,10 @@ Enable mode if ARG is positive"
 (defun gpr-query-refresh ()
   "For `ada-xref-refresh-function', using gpr_query."
   (interactive)
-  (with-current-buffer (gpr-query-session-send "refresh" t)))
+  ;; need to kill session to get changed env vars etc
+  (let ((session (gpr-query-cached-session)))
+    (gpr-query-kill-session session)
+    (gpr-query--start-process session)))
 
 (defun gpr-query-other (identifier file line col)
   "For `ada-xref-other-function', using gpr_query."
@@ -397,6 +416,11 @@ Enable mode if ARG is positive"
     (setq identifier (substring identifier 1 (1- (length identifier))))
     )
 
+  (when (eq system-type 'windows-nt)
+    ;; Since Windows file system is case insensitive, GNAT and Emacs
+    ;; can disagree on the case, so convert all to lowercase.
+    (setq file (downcase file)))
+
   (let ((cmd (format "refs %s:%s:%d:%d" identifier (file-name-nondirectory file) line col))
        (decl-loc nil)
        (body-loc nil)
@@ -442,6 +466,13 @@ Enable mode if ARG is positive"
                 (dist       (gpr-query-dist found-line line found-col col))
                 )
 
+           (when (eq system-type 'windows-nt)
+             ;; 'expand-file-name' converts Windows directory
+             ;; separators to normal Emacs.  Since Windows file
+             ;; system is case insensitive, GNAT and Emacs can
+             ;; disagree on the case, so convert all to lowercase.
+             (setq found-file (downcase (expand-file-name found-file))))
+
            (when (string-equal found-type "declaration")
              (setq decl-loc (list found-file found-line (1- found-col))))
 
@@ -490,7 +521,6 @@ Enable mode if ARG is positive"
        )
 
       (when (null result)
-       (pop-to-buffer (current-buffer))
        (error "gpr_query did not return other item; refresh?"))
 
       (message "parsing result ... done")
@@ -529,7 +559,6 @@ Enable mode if ARG is positive"
               (string-to-number (match-string 3)))))
 
       (when (null result)
-       (pop-to-buffer (current-buffer))
        (error "gpr_query did not return a result; refresh?"))
 
       (message "parsing result ... done")
@@ -553,6 +582,7 @@ Enable mode if ARG is positive"
   (setq ada-xref-all-function        'gpr-query-all)
   (setq ada-xref-overriding-function 'gpr-query-overriding)
   (setq ada-xref-overridden-function 'gpr-query-overridden-1)
+  (setq ada-show-xref-tool-buffer    'gpr-query-show-buffer)
 
   (add-to-list 'completion-ignored-extensions ".ali") ;; gnat library files, used for cross reference
   )
@@ -570,6 +600,7 @@ Enable mode if ARG is positive"
   (setq ada-xref-all-function        nil)
   (setq ada-xref-overriding-function nil)
   (setq ada-xref-overridden-function nil)
+  (setq ada-show-xref-tool-buffer    nil)
 
   (setq completion-ignored-extensions (delete ".ali" completion-ignored-extensions))
   )