branch: externals/gtags-mode
commit 1aaac5fead13dcfd19b56a8108502f6d5ce1b5c8
Author: Jimmy Aguilar Mena <kratsbinov...@gmail.com>
Commit: Jimmy Aguilar Mena <kratsbinov...@gmail.com>

    Simplify code to so only the needed.
    
    (global-xref--exec-sync) :
    (global-xref--exec-async) : Separate sync from async calls in different
    functions.
    (global-xref--buffer-to-list) : Removed because sync call always return
    a list.
    (global-xref--find-root) : Use car.
    (global-xref--filter-find-symbol) : Change the arguments order.
    (global-xref--output-format-regex) :
    (global-xref--output-format-options) : New cons.
---
 global-xref.el | 179 +++++++++++++++++++++++++++++----------------------------
 1 file changed, 91 insertions(+), 88 deletions(-)

diff --git a/global-xref.el b/global-xref.el
index 54f491f4a2..e75a84bb01 100644
--- a/global-xref.el
+++ b/global-xref.el
@@ -48,126 +48,130 @@
   "Gtags executable."
   :type 'string)
 
-(defun global-xref--buffer-to-list ()
-  "Return lines in current buffer in a list."
-  (let ((lines))
-    (goto-char (point-min))
-    (while (not (eobp))
-      (push (buffer-substring-no-properties
-            (line-beginning-position) (line-end-position))
-           lines)
-      (forward-line 1))
-    (nreverse lines)))
-
-(defvar global-xref--roots-list nil)
+(defvar global-xref--roots-list nil
+  "Full list of project Global root.
+The address is absolute on remote hsts.")
 (put 'global-xref--roots-list 'risky-local-variable t)
 
 (defvar-local global-xref--global (executable-find global-xref-global))
 (defvar-local global-xref--gtags (executable-find global-xref-gtags))
 (defvar-local global-xref--project-root nil
-  "Project Global root for this buffer.")
-
-(defun global-xref--exec (command args async &optional postfunction)
-  "Run COMMAND-SYM with and ARGS, in ASYNC way.
-When ASYNC is 'nil' executes command synchronously; returns the
-output of the command as a string or calls POSTFUNCTION in the
-command's buffer and returns the result.  returns nil if an error
-occurred.
-When ASYNC is non-nil starts an async process and executes the
-ignores.  Returns the process handler."
+  "Project Global root for this buffer.
+the address is relative on remote hosts.")
+
+(defconst global-xref--output-format-regex
+  "^\\([^ \t]+\\)[ \t]+\\([0-9]+\\)[ \t]+\\([^ \t\]+\\)[ \t]+\\(.*\\)"
+  "Regex to filter the output with `global-xref--output-format-options'.")
+
+(defconst global-xref--output-format-options
+  '("--result=ctags-x" "--path-style=absolute")
+  "Command line options to use with `global-xref--output-format-regex'.")
+
+(defun global-xref--exec-async (command args)
+  "Run COMMAND with ARGS asynchronously.
+Starts an async process and sets an informative process sentinel.
+Returns the process handler."
   (with-connection-local-variables
-   (when-let (cmd (symbol-value command))
-     (if async ;; When async
-        (let ((process (apply #'start-file-process
+   (when-let* ((cmd (symbol-value command))
+              (process (apply #'start-file-process
                               (format "%s-async" cmd)
                               (generate-new-buffer " *temp*" t) cmd args)))
-          (set-process-sentinel
-           process
-           (lambda (process event)
-             (let ((temp-buffer (process-buffer process)))
-               (while (accept-process-output process))
-               (if (eq (process-status process) 'exit)
-                   (and (buffer-name temp-buffer)
-                        (kill-buffer temp-buffer))
-                 (with-current-buffer temp-buffer
-                   (message "global error output:\n%s" (buffer-string)))))
-             (message "Async %s: %s" (process-command process) event)))
-          process)
-       (with-temp-buffer ;; When sync
-        (let ((status (apply #'process-file cmd nil (current-buffer) nil 
args)))
-          (if (eq status 0)
-              (if (functionp postfunction)
-                  (funcall postfunction)
-                (string-trim (buffer-substring-no-properties (point-min) 
(point-max))))
-            (message "global error output:\n%s" (buffer-string))
-            (error "Sync %s %s: exited abnormally with code %s" cmd args 
status)
-            nil)))))))
-
-(defsubst global-xref--to-list (args)
-  "Run GLOBAL with `process-file' and ARGS; return a list."
-  (global-xref--exec 'global-xref--global args nil 
#'global-xref--buffer-to-list))
+     (set-process-sentinel
+      process
+      (lambda (process event)
+       (let ((temp-buffer (process-buffer process)))
+         (while (accept-process-output process))
+         (if (eq (process-status process) 'exit)
+             (and (buffer-name temp-buffer)
+                  (kill-buffer temp-buffer))
+           (with-current-buffer temp-buffer
+             (message "global error output:\n%s" (buffer-string)))))
+       (message "Async %s: %s" (process-command process) event)))
+     process)))
+
+(defun global-xref--exec-sync (command args)
+  "Run COMMAND with ARGS synchronously.
+Starts a sync process returns the output of the command as a list
+of strings or nil if any error occurred."
+  (with-connection-local-variables
+   (when-let ((cmd (symbol-value command)))
+     (with-temp-buffer ;; When sync
+       (let ((status (apply #'process-file cmd nil (current-buffer) nil args)))
+        (if (eq status 0)
+            (let (lines substring)
+              (goto-char (point-min))
+              (while (not (eobp))
+                (when (not (string-blank-p
+                            (setq substring (buffer-substring-no-properties
+                                             (line-beginning-position)
+                                             (line-end-position)))))
+                  (push substring lines))
+                (forward-line 1))
+              (nreverse lines))
+          (message "global error output:\n%s" (buffer-string))
+          (error "Sync %s %s: exited abnormally with code %s" cmd args status)
+          nil))))))
 
 (defun global-xref--set-connection-locals ()
   "Set GLOBAL connection local variables when possible."
-  (when-let ((host (file-remote-p default-directory 'host)))
-    (let ((symvars (intern (concat "global-xref-" host "-vars")))
-         (criteria `(:machine ,host))
-         connection-local-variables-alist)
-      (hack-connection-local-variables criteria)
-      (unless (alist-get 'global-xref--global connection-local-variables-alist)
-       (connection-local-set-profile-variables
-        symvars
-        `((global-xref--global . ,(executable-find (file-name-base 
global-xref-global) t))
-          (global-xref--gtags . ,(executable-find (file-name-base 
global-xref-gtags) t))))
-       (connection-local-set-profiles criteria symvars)))))
+  (when-let* ((host (file-remote-p default-directory 'host))
+             (symvars (intern (concat "global-xref-" host "-vars")))
+             ((not (alist-get symvars connection-local-profile-alist)))
+             (criteria `(:machine ,host)))
+    (connection-local-set-profile-variables
+     symvars
+     `((global-xref--global . ,(executable-find (file-name-base 
global-xref-global) t))
+       (global-xref--gtags . ,(executable-find (file-name-base 
global-xref-gtags) t))))
+    (connection-local-set-profiles criteria symvars)))
 
 (defun global-xref--find-root ()
   "Return the GLOBAL project root.  Return nil if none."
-  (let ((root (global-xref--exec 'global-xref--global '("--print-dbpath") 
nil)))
+  (let ((root (car (global-xref--exec-sync 'global-xref--global 
'("--print-dbpath")))))
     (when root
       (add-to-list 'global-xref--roots-list
                   (concat (file-remote-p default-directory)
                           (file-truename root)))
       root)))
 
-(defun global-xref--filter-find-symbol (creator args symbol)
-  "Run GNU Global and apply CREATOR to global-xref--to-list output.
-Return the results as a list."
+(defun global-xref--filter-find-symbol (args symbol creator)
+  "Run global-xref--exec-sync with ARGS on SYMBOL and filter output with 
CREATOR.
+Returns the results as a list of CREATORS outputs similar to
+mapcar.  Creator should be a function with 4 input arguments:
+name, code, file, line."
   (remove
    nil
-   (mapcar (lambda (line)
-            (when (string-match
-                   "^\\([^ \t]+\\)[ \t]+\\([0-9]+\\)[ \t]+\\([^ \t\]+\\)[ 
\t]+\\(.*\\)"
-                   line)
-              (funcall creator
-                       (match-string 1 line)   ;; name
-                       (match-string 4 line)   ;; code
-                       (match-string 3 line)   ;; file
-                       (string-to-number (match-string 2 line)) ;; line
-                       )))
-          (global-xref--to-list
-           (append args (list "--result=ctags-x" "--path-style=absolute"
-                              (shell-quote-argument symbol)))))))
+   (mapcar
+    (lambda (line)
+      (when (string-match global-xref--output-format-regex line)
+       (funcall creator
+                (match-string 1 line)   ;; name
+                (match-string 4 line)   ;; code
+                (match-string 3 line)   ;; file
+                (string-to-number (match-string 2 line))))) ;; line
+    (global-xref--exec-sync
+     'global-xref--global
+     (append args global-xref--output-format-options
+            (list (shell-quote-argument symbol)))))))
 
 ;; Interactive commands.
 (defun global-xref-create-db (root-dir)
   "Create a GLOBAL database in ROOT-DIR asynchronously."
   (interactive "DCreate db in directory: ")
   (let ((default-directory root-dir))
-    (global-xref--exec 'global-xref--gtags nil t)))
+    (global-xref--exec-async 'global-xref--gtags nil)))
 
 (defun global-xref-update ()
   "Update GLOBAL project database."
   (interactive)
   (if global-xref--project-root
-      (global-xref--exec 'global-xref--global '("--update") t)
+      (global-xref--exec-async 'global-xref--global '("--update"))
     (error "Not under a GLOBAL project")))
 
 (defun global-xref--after-save-hook ()
   "After save hook to update GLOBAL database with changed data."
   (when (and buffer-file-name global-xref--project-root)
-    (global-xref--exec
-     'global-xref--global `("--single-update" ,buffer-file-name) t)))
+    (global-xref--exec-async
+     'global-xref--global `("--single-update" ,buffer-file-name))))
 
 (defun global-xref--find-file-hook ()
   "Try to enable `global-xref' when opening a file.
@@ -188,11 +192,11 @@ one of them."
 Return the results as a list of xref location objects.  ARGS are
 any additional command line arguments to pass to GNU Global."
   (global-xref--filter-find-symbol
+   args symbol
    (lambda (_name code file line)
      (xref-make code (xref-make-file-location
                      (concat (file-remote-p default-directory) file)
-                     line 0)))
-   args symbol))
+                     line 0)))))
 
 (defun global-xref-xref-backend ()
   "Global-Xref backend for Xref."
@@ -200,7 +204,7 @@ any additional command line arguments to pass to GNU 
Global."
 
 (cl-defmethod xref-backend-identifier-completion-table ((_backend (eql 
global-xref)))
   "List all symbols."
-  (global-xref--to-list '("--completion")))
+  (global-xref--exec-sync 'global-xref--global '("--completion")))
 
 (cl-defmethod xref-backend-definitions ((_backend (eql global-xref)) symbol)
   "List all definitions for SYMBOL."
@@ -225,10 +229,9 @@ any additional command line arguments to pass to GNU 
Global."
   "Make imenu use Global."
   (when buffer-file-name
     (global-xref--filter-find-symbol
+     '("--file") (file-name-nondirectory buffer-file-name)
      (lambda (name _code _file line)
-       (list name line #'global-xref--imenu-goto-function))
-     '("--file")
-     (file-name-nondirectory buffer-file-name))))
+       (list name line #'global-xref--imenu-goto-function)))))
 
 ;;;###autoload
 (define-minor-mode global-xref-mode

Reply via email to