branch: elpa/bash-completion
commit 5cb435eee866f4428e33162aed7a8971092e3b60
Author: Stephane Zermatten <[email protected]>
Commit: Stephane Zermatten <[email protected]>
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