branch: elpa/bash-completion
commit 5cb435eee866f4428e33162aed7a8971092e3b60
Author: Stephane Zermatten <szerm...@gmx.net>
Commit: Stephane Zermatten <szerm...@gmx.net>

    Simplify complete -p output parsing.
    
    Before this change, bash-completion-build-alist would parse the complete
    ouptut of "complete -p" into an alist. This is, however, not necessary
    anymore since bash-completion--customize now makes sure that there will
    only ever be at most one entry in the output of complete -p.
    
    This change simplifies bash-completion-build-alist, renamed
    bash-completion--parse-complete-options, to extract the arguments from a
    single "complete" command, as output by "complete -p".
---
 bash-completion.el           | 69 +++++++++++++++++++-------------------------
 test/bash-completion-test.el | 45 +++++++++++++++--------------
 2 files changed, 52 insertions(+), 62 deletions(-)

diff --git a/bash-completion.el b/bash-completion.el
index 7bb375e262..cad451f28b 100644
--- a/bash-completion.el
+++ b/bash-completion.el
@@ -1238,42 +1238,6 @@ Return a bash command-line for going to 
`default-directory' or \"\"."
                 " && ")
       "")))
 
-(defun bash-completion-build-alist (buffer)
-  "Parse the content of BUFFER into an alist.
-
-BUFFER should contains the output of:
-  complete -p
-
-The returned alist is a slightly parsed version of the output of
-\"complete -p\"."
-  (let ((alist (list)))
-    (with-current-buffer buffer
-      (save-excursion
-        (goto-char (point-min))
-        (when (search-forward-regexp "^complete" nil 'noerror)
-          (let ((tokens (bash-completion-strings-from-tokens
-                         (bash-completion-tokenize
-                          (match-beginning 0) (point-max)))))
-            (while tokens
-              (let ((command tokens)
-                    (command-end (member "\n" tokens)))
-                (setq tokens (cdr command-end))
-                (when command-end
-                  (setcdr command-end nil))
-                (when (string= "complete" (car command))
-                  (setq command (nreverse (cdr command)))
-                  (when (equal "\n" (car command))
-                    (setq command (cdr command)))
-                  (if (member "-D" command)
-                      ;; default completion
-                      (push (cons nil (nreverse (delete "-D" command))) alist)
-                    ;; normal completion
-                    (let ((command-name (car command))
-                          (options (nreverse (cdr command))))
-                      (when (and command-name options)
-                        (push (cons command-name options) alist)))))))))))
-    (nreverse alist)))
-
 (defun bash-completion--customize (process comp &optional forced)
   "Initialize current shell in PROCESS and fetch compgen args for COMP."
   (when (and (not (eq 'command (bash-completion--type comp)))
@@ -1281,10 +1245,35 @@ The returned alist is a slightly parsed version of the 
output of
     (bash-completion-send
      (concat "complete -p "
              (bash-completion-quote (bash-completion--command comp))
-             " 2>/dev/null || complete -p -D") process)
-    (setf (bash-completion--compgen-args comp)
-          (cdr (car (bash-completion-build-alist
-                     (bash-completion--get-buffer process)))))))
+             " 2>/dev/null || complete -p -D 2>/dev/null") process)
+    (setf
+     (bash-completion--compgen-args comp)
+     (with-current-buffer (bash-completion--get-buffer process)
+       (bash-completion--parse-complete-options)))))
+
+(defun bash-completion--parse-complete-options ()
+  "Parse options from a complete command, output by complete-p.
+
+The output is parsed from the current buffer. If more than one
+complete command is available, the options of the first one is
+returned.
+
+Returns the option as a list of strings."
+  (save-excursion
+    (goto-char (point-min))
+    (when (search-forward-regexp "^complete *" nil 'noerror)
+      (let ((args (bash-completion-strings-from-tokens
+                   (bash-completion-tokenize
+                    (match-end 0) (point-max)))))
+        ;; stop at the first newline token (not necessary the first
+        ;; newline)
+        (when-let ((end (member "\n" args)))
+          (setcdr end nil)
+          (setq args (butlast args)))
+        ;; remove the command name or the -D
+        (if (member "-D" args)
+            (delete "-D" args)
+          (butlast args))))))
 
 (defun bash-completion-generate-line (comp)
   "Generate a bash command to call \"compgen\" for COMP.
diff --git a/test/bash-completion-test.el b/test/bash-completion-test.el
index d0d5759c2b..dc9a1f0a71 100644
--- a/test/bash-completion-test.el
+++ b/test/bash-completion-test.el
@@ -344,28 +344,29 @@ The return value is the one returned by BODY."
             " "
             (bash-completion--parse (point-min) 2 wordbreaks))))))
 
-(ert-deftest bash-completion-build-alist ()
-  (should (equal
-          '(("cdb" "-F" "_cdargs_aliases")
-            ("project" "-F" "complete_projects")
-            ("pro" "-F" "complete_projects")
-             ("scp" "-o" "default" "-W" "home\nhome.lan")
-            ("cv" "-F" "_cdargs_aliases")
-            ("cb" "-F" "_cdargs_aliases")
-            (nil "-F" "_completion_loader"))
-          (bash-completion-test-with-buffer
-           "
-complete -F _cdargs_aliases cdb
-complete -F complete_projects project
-complete -F complete_projects pro
-complete -o default -W 'home
-home.lan' scp
-complete -F _cdargs_aliases cv
-complete -F _cdargs_aliases cb
-complete -F _completion_loader -D
-garbage
-"
-            (bash-completion-build-alist (current-buffer))))))
+(ert-deftest bash-completion-parse-complete-options ()
+  (bash-completion-test-with-buffer
+   "complete -F _cdargs_aliases cdb"
+   (should (equal '("-F" "_cdargs_aliases")
+                  (bash-completion--parse-complete-options))))
+  (bash-completion-test-with-buffer
+   "complete -F complete_projects pro"
+   (should (equal '("-F" "complete_projects")
+                  (bash-completion--parse-complete-options))))
+  (bash-completion-test-with-buffer
+   "complete -o plusdir -o default -F complete_projects pro"
+   (should (equal '("-o" "plusdir" "-o" "default" "-F" "complete_projects")
+                  (bash-completion--parse-complete-options))))
+  (bash-completion-test-with-buffer
+   "complete -F _first first
+    complete -F _second second"
+   (should (equal '("-F" "_first")
+                  (bash-completion--parse-complete-options))))
+  (bash-completion-test-with-buffer
+   "complete -o default -W 'home
+home.lan' scp"
+   (should (equal '("-o" "default" "-W" "home\nhome.lan")
+                  (bash-completion--parse-complete-options)))))
 
 (ert-deftest bash-completion-generate-line-test ()
   ;; no custom completion

Reply via email to