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