[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[nongnu] elpa/bash-completion fc3f762d16 177/313: Track and support opti
From: |
ELPA Syncer |
Subject: |
[nongnu] elpa/bash-completion fc3f762d16 177/313: Track and support options -o default, filenames and nospace. |
Date: |
Sat, 3 Dec 2022 10:59:28 -0500 (EST) |
branch: elpa/bash-completion
commit fc3f762d1647c69aab120ca2ad4e173fa11d28fa
Author: Stephane Zermatten <szermatt@gmx.net>
Commit: Stephane Zermatten <szermatt@gmx.net>
Track and support options -o default, filenames and nospace.
This commit introduces a struct to keep track of the state needed to
handle and apply options at different steps of the completion and
then use it to support default, filenames and nospace in a generic
way.
Issue #19
---
bash-completion.el | 393 ++++++++++++++++++++-----------
test/bash-completion-integration-test.el | 143 +++++------
test/bash-completion-test.el | 386 ++++++++++++++++++------------
3 files changed, 553 insertions(+), 369 deletions(-)
diff --git a/bash-completion.el b/bash-completion.el
index cb262173d3..33cccc6584 100644
--- a/bash-completion.el
+++ b/bash-completion.el
@@ -121,6 +121,7 @@
;; https://github.com/szermatt/emacs-bash-completion
(require 'comint)
+(eval-when-compile (require 'cl))
;;; Code:
@@ -183,7 +184,7 @@ which typically takes a long time."
:type '(float)
:group 'bash-completion)
-(defcustom bash-completion-nospace nil
+(defcustom bash-completion-nospace 'as-configured
"Never let bash add a final space at the end of a completion.
When there is only one completion candidate, bash sometimes adds
@@ -196,10 +197,25 @@ to remove the extra space bash adds after a completion."
:type '(boolean)
:group 'bash-completion)
-(defcustom bash-completion-default-completion t
- "Use Readline’s default filename completion if a compspec
- generates no matches."
- :type 'boolean
+(defcustom bash-completion-default 'as-configured
+ "Use default filename completion if a compspec
+ generates no matches. Normally configured function by function
+ using compgen."
+ :type '(choice
+ (:tag "As configured" 'as-configured)
+ (:tag "Always" t)
+ (:tag "Never"))
+ :group 'bash-completion)
+
+(defcustom bash-completion-filenames 'as-configured
+ "Perform filenames-specific processing on the candidates, such
+ as adding a slash to directories or supressing trailing
+ characters. Normally configured function by function using
+ compgen."
+ :type '(choice
+ (:tag "As configured" 'as-configured)
+ (:tag "Always" t)
+ (:tag "Never"))
:group 'bash-completion)
(if (fboundp 'completion-table-with-cache)
@@ -255,6 +271,13 @@ completion in colon-separated values.")
(append bash-completion-wordbreaks-str nil)
"`bash-completion-wordbreaks-str' as a list of characters.")
+(defconst bash-completion--default-option-strings
+ '("filenames")
+ "Compgen for command, default and wordbreak completions.
+
+`bash-completion--parse-options' is applied to it at runtime, to
+allow customization of these options.")
+
(defconst bash-completion-special-chars "[^-0-9a-zA-Z_./\n=]"
"Regexp of characters that must be escaped or quoted.")
@@ -274,6 +297,51 @@ to be included into a completion output.")
"Download emacs-bash-completion version 2.1 to run on older Emacs "
"versions, from 22 to 24."))))
+;;; ---------- Struct
+
+;; The main, completion structure, keeping track of the definition and
+;; state of the current completion.
+(defstruct (completion (:constructor bash-completion--make)
+ (:conc-name bash-completion--)
+ (:copier nil))
+ line ; the relevant command (string)
+ point ; 0-based position of the cursor in line (number)
+ words ; line split into words, unescaped (list of strings)
+ cword ; 0-based index of the word to be completed in words (number)
+ stub-start ; start position of the thing we are completing
+ unparsed-stub ; unparsed version of (nth cword words)
+ open-quote ; quote open at stub end: nil, ?' or ?\""
+ compgen-args ; compgen arguments, if custom (list of strings)
+)
+
+(defsubst bash-completion--stub (comp)
+ "Returns the stub being completed for COMP."
+ (nth (bash-completion--cword comp) (bash-completion--words comp)))
+
+(defun bash-completion--type (comp)
+ "Returns the type of COMP.
+
+Completion type is 'command, if completing a command (cword = 0),
+'custom if there's a custom completion for the current command or
+'default if there isn't or if the completion hasn't been
+customized, usually by `bash-completion--customize'.
+"
+ (cond
+ ((zerop (bash-completion--cword comp)) 'command)
+ ((bash-completion--compgen-args comp) 'custom)
+ (t 'default)))
+
+(defun bash-completion--options (comp)
+ "Returns options for comp, either default or customized.
+
+See options definition in
+`bash-completion--extract-compgen-options'"
+ (bash-completion--parse-options
+ (if (eq (bash-completion--type comp) 'custom)
+ (bash-completion--extract-compgen-options
+ (bash-completion--compgen-args comp))
+ bash-completion--default-option-strings)))
+
;;; ---------- Inline functions
(defsubst bash-completion-tokenize-get-range (token)
@@ -363,24 +431,19 @@ Returns (list stub-start stub-end completions) with
- completions, a possibly empty list of completion candidates or a function if
`bash-completion-enable-caching' is non-nil"
(when bash-completion-enabled
- (let* ((tokens (bash-completion-tokenize comp-start comp-pos))
- (open-quote (bash-completion-tokenize-open-quote tokens))
- (parsed (bash-completion-process-tokens tokens comp-pos open-quote))
- (line (cdr (assq 'line parsed)))
- (point (cdr (assq 'point parsed)))
- (cword (cdr (assq 'cword parsed)))
- (words (cdr (assq 'words parsed)))
- (stub-start (cdr (assq 'stub-start parsed)))
- (stub (nth cword words))
- (unparsed-stub (buffer-substring-no-properties stub-start
comp-pos)))
+ (let* ((comp (bash-completion--parse comp-start comp-pos))
+ (open-quote (bash-completion--open-quote comp))
+ (stub-start (bash-completion--stub-start comp))
+ (stub (bash-completion--stub comp))
+ (unparsed-stub (bash-completion--unparsed-stub comp)))
(if bash-completion-enable-caching
(list
stub-start
comp-pos
(bash-completion--completion-table-with-cache
(lambda (_)
- (or (bash-completion-comm line point words cword open-quote
- unparsed-stub)
+ (bash-completion--customize comp)
+ (or (bash-completion-comm comp)
(pcase-let ((`(,wordbreak-start _ ,wordbreak-collection)
(bash-completion--try-wordbreak-complete
stub unparsed-stub stub-start comp-pos
@@ -393,8 +456,8 @@ Returns (list stub-start stub-end completions) with
(- wordbreak-start stub-start))))
(mapcar (lambda (c) (concat before-wordbreak c))
wordbreak-collection))))))))
- (let ((completions (bash-completion-comm line point words cword
- open-quote unparsed-stub)))
+ (bash-completion--customize comp)
+ (let ((completions (bash-completion-comm comp)))
(if completions
(list stub-start comp-pos completions)
(bash-completion--try-wordbreak-complete
@@ -429,7 +492,8 @@ This function is not meant to be called outside of
pos
(bash-completion--default-completion
after-wordbreak unparsed-after-wordbreak
- open-quote 'wordbreak)))))
+ open-quote (bash-completion--parse-options
+ bash-completion--default-option-strings))))))
(defun bash-completion--find-last (elt array)
"Return the position of the last intance of ELT in array or nil."
@@ -441,19 +505,18 @@ This function is not meant to be called outside of
nil))
(defun bash-completion--default-completion
- (stub unparsed-stub open-quote completion-type)
+ (stub unparsed-stub open-quote options)
"Do default completion on the given STUB.
Return the extracted candidate, with STUB replaced with
-UNPARSED-STUB, taking OPEN-QUOTE into account. COMPLETION-TYPE is
-passed, eventually, to `bash-completion-fix'"
+UNPARSED-STUB, taking OPEN-QUOTE into account."
(when (eq 0 (bash-completion-send (concat
(bash-completion-cd-command-prefix)
"compgen -o default -- "
(bash-completion-quote stub))))
(bash-completion-extract-candidates
stub unparsed-stub open-quote
- (or completion-type 'default))))
+ options)))
;;; ---------- Functions: parsing and tokenizing
@@ -482,7 +545,7 @@ functions adds single quotes around it and return the
result."
(replace-regexp-in-string "'" "'\\''" word nil t)
"'")))
-(defun bash-completion-process-tokens (tokens pos open-quote)
+(defun bash-completion--parse (comp-start comp-pos)
"Process a command line split into TOKENS that end at POS.
If stub is quoted, the quote character should be passed as
@@ -497,35 +560,32 @@ Return an association list with the current symbol as
keys:
point - 0-based position of the cursor in line (number)
cword - 0-based index of the word to be completed in words (number)
words - line split into words, unescaped (list of strings)
- stub-start - start position of the thing we are completing"
- (bash-completion-parse-line-postprocess
- (bash-completion-parse-current-command tokens) pos open-quote))
-
-(defun bash-completion-parse-line-postprocess (tokens pos open-quote)
- "Extract from TOKENS the data needed by compgen functions.
-
-This function takes a list of TOKENS created by
-`bash-completion-tokenize' for the current buffer and generate
-the data needed by compgen functions given the cursor position
-POS and the quote character OPEN-QUOTE, if any."
- (let* ((first-token (car tokens))
- (last-token (car (last tokens)))
- (start (or (car (bash-completion-tokenize-get-range first-token)) pos))
- (end (or (cdr (bash-completion-tokenize-get-range last-token)) pos))
- (words (bash-completion-strings-from-tokens tokens))
- (stub-empty (or (> pos end) (= start end)))
+ stub-start - start position of the thing we are completing
+ unparsed-stub - unparsed version of (nth cword words)
+ open-quote - quote open at stub end: nil, ?' or ?\""
+ (let* ((all-tokens (bash-completion-tokenize comp-start comp-pos))
+ (line-tokens (bash-completion-parse-current-command all-tokens))
+ (first-token (car line-tokens))
+ (last-token (car (last line-tokens)))
+ (open-quote (bash-completion-tokenize-open-quote line-tokens))
+ (start (or (car (bash-completion-tokenize-get-range first-token))
comp-pos))
+ (end (or (cdr (bash-completion-tokenize-get-range last-token))
comp-pos))
+ (words (bash-completion-strings-from-tokens line-tokens))
+ (stub-empty (or (> comp-pos end) (= start end)))
(stub-start
(if stub-empty
- pos
+ comp-pos
(+ (car (bash-completion-tokenize-get-range last-token))
(if open-quote 1 0)))))
(when stub-empty (setq words (append words '(""))))
- (list
- (cons 'line (buffer-substring-no-properties start pos))
- (cons 'point (- pos start))
- (cons 'cword (- (length words) 1))
- (cons 'words words)
- (cons 'stub-start stub-start))))
+ (bash-completion--make
+ :line (buffer-substring-no-properties start comp-pos)
+ :point (- comp-pos start)
+ :cword (- (length words) 1)
+ :words words
+ :stub-start stub-start
+ :unparsed-stub (buffer-substring-no-properties stub-start comp-pos)
+ :open-quote open-quote)))
(defun bash-completion-parse-current-command (tokens)
"Extract from TOKENS the tokens forming the current command.
@@ -725,53 +785,54 @@ QUOTE should be nil, ?' or ?\"."
;;; ---------- Functions: getting candidates from bash
-(defun bash-completion-comm (line pos words cword open-quote unparsed-stub)
- "Set LINE, POS, WORDS and CWORD, call compgen, return the result.
+(defun bash-completion-comm (comp)
+ "Call compgen on COMP return the result.
+
+COMP should be a struct returned by `bash-completion--parse'
This function starts a separate bash process if necessary, sets
up the completion environment (COMP_LINE, COMP_POINT, COMP_WORDS,
COMP_CWORD) and calls compgen.
-OPEN-QUOTE should be the quote, a character, that's still open in
-the last word or nil.
-
-UNPARSED-STUB is a raw, unparsed version of COMP_WORDS[CWORD] as
-it appears in the original buffer. Returned candidates The
-returned set of candidates start with UNPARSED-STUB.
-
The result is a list of candidates, which might be empty."
;; start process now, to make sure bash-completion-alist is
;; set before we run bash-completion-generate-line
(let* ((entry (bash-completion-require-process))
(process (car entry))
- (bash-completion-alist (cdr entry))
- (cmdline)
(candidates)
- (completion-status))
- (setq cmdline (bash-completion-generate-line line pos words cword t))
- (setq completion-status (bash-completion-send (cdr cmdline) process))
+ (completion-status)
+ (options))
+ (setq completion-status (bash-completion-send
(bash-completion-generate-line comp) process))
(when (eq 124 completion-status)
;; Special 'retry-completion' exit status, typically returned by
;; functions bound by complete -D. Presumably, the function has
;; just setup completion for the current command and is asking
- ;; us to retry once with the new configuration.
- (bash-completion-send "complete -p" process)
- (bash-completion-build-alist (process-buffer process))
- (setcdr entry bash-completion-alist)
- (setq cmdline (bash-completion-generate-line line pos words cword nil))
- (setq completion-status (bash-completion-send (cdr cmdline) process)))
+ ;; us to retry once with the new configuration.
+ (let ((bash-completion-alist nil))
+ (bash-completion-send "complete -p" process)
+ (bash-completion-build-alist (process-buffer process))
+ (setcdr entry bash-completion-alist))
+ (bash-completion--customize comp 'nodefault)
+ (setq completion-status (bash-completion-send
(bash-completion-generate-line comp) process)))
+ (setq options (bash-completion--options comp))
(setq candidates
(when (eq 0 completion-status)
(bash-completion-extract-candidates
- (nth cword words) unparsed-stub open-quote (car cmdline))))
- (if (and bash-completion-default-completion (not candidates) (eq 'custom
(car cmdline)))
+ (bash-completion--stub comp)
+ (bash-completion--unparsed-stub comp)
+ (bash-completion--open-quote comp)
+ options)))
+ (if (and (not candidates) (memq 'default options))
(bash-completion--default-completion
- (nth cword words) unparsed-stub open-quote 'default)
+ (bash-completion--stub comp)
+ (bash-completion--unparsed-stub comp)
+ (bash-completion--open-quote comp)
+ options)
candidates)))
(defun bash-completion-extract-candidates
- (parsed-stub unparsed-stub open-quote completion-type)
+ (parsed-stub unparsed-stub open-quote options)
"Extract the completion candidates from the process buffer for PARSED-STUB.
This command takes the content of the completion process buffer,
@@ -790,20 +851,20 @@ Post-processing includes escaping special characters,
adding a /
to directory names, replacing STUB with UNPARSED-STUB in the
result. See `bash-completion-fix' for more details."
(let ((candidates) (result (list)))
- (setq candidates (with-current-buffer (bash-completion-buffer)
- (split-string (buffer-string) "\n" t)))
+ (setq candidates (delete-dups (with-current-buffer (bash-completion-buffer)
+ (split-string (buffer-string) "\n" t))))
(if (eq 1 (length candidates))
(list (bash-completion-fix
(car candidates) parsed-stub unparsed-stub
- open-quote completion-type t))
+ open-quote options t))
(dolist (completion candidates)
(push (bash-completion-fix
- completion parsed-stub unparsed-stub open-quote completion-type
nil)
+ completion parsed-stub unparsed-stub open-quote options nil)
result))
(delete-dups (nreverse result)))))
(defun bash-completion-fix
- (str parsed-prefix unparsed-prefix open-quote completion-type single)
+ (str parsed-prefix unparsed-prefix open-quote options single)
"Fix completion candidate in STR if PREFIX is the current prefix.
STR is the completion candidate to modify.
@@ -818,9 +879,10 @@ of candidates.
OPEN-QUOTE should be the quote that's still open in prefix. A
character (' or \") or nil.
-COMPLETION-TYPE describes the type of completion that was
-executed: 'default, 'custom, 'command or 'wordbreak. It is used
-to choose whether to add a space and detect directories.
+OPTIONS configrues some behaviors:
+ 'nospace to not add a space after a single completion
+ 'filenames to post-process candidates as filenames and detect
+ directories
If SINGLE is non-nil, this is the single completion candidate.
@@ -871,7 +933,7 @@ for directory name detection to work."
;; build suffix
(let ((last-char (bash-completion-last-char rest))
(close-quote-str (if open-quote (char-to-string open-quote) ""))
- (final-space-str (if bash-completion-nospace "" " ")))
+ (final-space-str (if (memq 'nospace options) "" " ")))
(cond
((eq ?\ last-char)
(setq rest (substring rest 0 -1))
@@ -880,14 +942,12 @@ for directory name detection to work."
(eq ?/ last-char))
(setq suffix ""))
((and
- (memq completion-type '(command default wordbreak custom))
+ (memq 'filenames options)
(file-accessible-directory-p
(bash-completion--expand-file-name (bash-completion-unescape
open-quote (concat parsed-prefix
rest)))))
(setq suffix "/"))
- ((or (eq completion-type 'command)
- (and (memq completion-type '(default wordbreak custom))
- single))
+ (single
(setq suffix (concat close-quote-str final-space-str)))
(t (setq suffix close-quote-str))))
@@ -1140,76 +1200,69 @@ Return `bash-completion-alist'."
(push (cons command options) bash-completion-alist)))))
bash-completion-alist)
-(defun bash-completion-generate-line (line pos words cword allowdefault)
- "Generate a command-line that calls compgen.
+(defun bash-completion--customize (comp &optional nodefault)
+ (unless (eq 'command (bash-completion--type comp))
+ (let ((bash-completion-alist (cdr (bash-completion-require-process))))
+ (let ((command-name (file-name-nondirectory (car (bash-completion--words
comp)))))
+ (setf (bash-completion--compgen-args comp)
+ (or (cdr (assoc command-name bash-completion-alist))
+ (and (not nodefault) (cdr (assoc nil
bash-completion-alist)))))))))
-This function looks into `bash-completion-alist' for a matching compgen
-argument set. If it finds one, it executes it. Otherwise, it executes the
-default bash completion (compgen -o default)
-LINE is the command-line to complete.
-POS is the position of the cursor on LINE
-WORDS is the content of LINE split by words and unescaped
-CWORD is the word 0-based index of the word to complete in WORDS
-ALLOWDEFAULT controls whether to fallback on a possible -D completion
+(defun bash-completion-generate-line (comp)
+ "Generate a command-line that calls compgen for COMP.
+
+COMP is a struct returned by `bash-completion--parse'. It is
+normally configured using `bash-completion--customize' before
+calling this command.
If the compgen argument set specifies a custom function or command, the
arguments will be passed to this function or command as:
- COMP_LINE, taken from LINE
- COMP_POINT, taken from POS
- COMP_WORDS, taken from WORDS (a bash array)
- COMP_CWORD, taken for CWORD
+ COMP_LINE, taken from (bash-completion--line COMP)
+ COMP_POINT, taken from (bash-completion--point COMP)
+ COMP_WORDS, taken from (bash-completion--words COMP) (a bash array)
+ COMP_CWORD, taken for (bash-completion--cword COMP)
Return a cons containing the completion type (command default or
custom) and a bash command-line that calls compgen to get the
completion candidates."
- (let* ( (command-name (file-name-nondirectory (car words)))
- (compgen-args
- (or (cdr (assoc command-name bash-completion-alist))
- (and allowdefault (cdr (assoc nil bash-completion-alist)))))
- (quoted-stub (bash-completion-quote (nth cword words)))
- (completion-type)
- (commandline) )
- (cond
- ((= cword 0)
- ;; a command. let bash expand builtins, aliases and functions
- (setq completion-type 'command)
- (setq commandline (concat "compgen -b -c -a -A function -- "
quoted-stub)))
-
- ((not compgen-args)
- ;; no completion configured for this command
- (setq completion-type 'default)
- (setq commandline (concat "compgen -o default -- " quoted-stub)))
-
- ((or (member "-F" compgen-args) (member "-C" compgen-args))
+ (let ((quoted-stub (bash-completion-quote (bash-completion--stub comp)))
+ (completion-type (bash-completion--type comp))
+ (compgen-args (bash-completion--compgen-args comp)))
+ (concat
+ (bash-completion-cd-command-prefix)
+ (cond
+ ((eq 'command completion-type)
+ (concat "compgen -b -c -a -A function -- " quoted-stub))
+
+ ((eq 'default completion-type)
+ (concat "compgen -o default -- " quoted-stub))
+
+ ((and (eq 'custom completion-type) (or (member "-F" compgen-args)
+ (member "-C" compgen-args)))
;; custom completion with a function of command
(let* ((args (copy-tree compgen-args))
- (function (or (member "-F" args) (member "-C" args)))
- (function-name (car (cdr function))) )
- (setcar function "-F")
- (setcar (cdr function) "__bash_complete_wrapper")
- (setq completion-type 'custom)
- (setq commandline
- (format "__BASH_COMPLETE_WRAPPER=%s compgen %s -- %s"
- (bash-completion-quote
- (format "COMP_LINE=%s; COMP_POINT=%s; COMP_CWORD=%s;
COMP_WORDS=( %s ); %s \"${COMP_WORDS[@]}\""
- (bash-completion-quote line)
- pos
- cword
- (bash-completion-join words)
- (bash-completion-quote function-name)))
- (bash-completion-join args)
- quoted-stub))))
- (t
+ (function (or (member "-F" args) (member "-C" args)))
+ (function-name (car (cdr function))) )
+ (setcar function "-F")
+ (setcar (cdr function) "__bash_complete_wrapper")
+ (format "__BASH_COMPLETE_WRAPPER=%s compgen %s -- %s"
+ (bash-completion-quote
+ (format "COMP_LINE=%s; COMP_POINT=%s; COMP_CWORD=%s;
COMP_WORDS=( %s ); %s \"${COMP_WORDS[@]}\""
+ (bash-completion-quote (bash-completion--line comp))
+ (bash-completion--point comp)
+ (bash-completion--cword comp)
+ (bash-completion-join (bash-completion--words comp))
+ (bash-completion-quote function-name)))
+ (bash-completion-join args)
+ quoted-stub)))
+ ((eq 'custom completion-type)
;; simple custom completion
- (setq completion-type 'custom)
- (setq commandline (format "compgen %s -- %s" (bash-completion-join
compgen-args)
- quoted-stub))))
- (cons completion-type
- (concat
- (bash-completion-cd-command-prefix)
- commandline
- " 2>/dev/null"))))
+ (format "compgen %s -- %s"
+ (bash-completion-join compgen-args)
+ quoted-stub))
+ (t (error "Unsupported completion type: %s" completion-type)))
+ " 2>/dev/null")))
;;;###autoload
(defun bash-completion-reset ()
@@ -1313,5 +1366,57 @@ Return the status code of the command, as a number."
(file-remote-p expanded 'localname)
expanded)))
+(defun bash-completion--extract-compgen-options (compgen-args)
+ "Extract from COMPGEN-ARGS the -o option strings."
+ (let ((rest compgen-args)
+ (options (list)))
+ (while (setq rest (cdr (member "-o" rest)))
+ (push (car rest) options)
+ (setq rest (cdr rest)))
+ options))
+
+(defun bash-completion--parse-options (option-strings)
+ "Parse OPTIONS-STRINGS for compgen into a list of symbols.
+
+Supported options and compgen option equivalent:
+ 'default: -o default or -o bashdefault
+ 'nospace: -o nospace
+ 'filenames: -o filenames"
+ (let ((options))
+ (if (bash-completion--check-option
+ option-strings
+ '("default" "bashdefault") bash-completion-default)
+ (push 'default options))
+ (if (bash-completion--check-option
+ option-strings
+ "nospace" bash-completion-nospace)
+ (push 'nospace options))
+ (if (bash-completion--check-option
+ option-strings
+ "filenames" bash-completion-filenames)
+ (push 'filenames options))
+ options))
+
+(defun bash-completion--check-option
+ (option-strings option-name-or-names customize-option)
+ "Return t if the option should be enabled.
+
+OPTION-STRINGS is a list of compgen option strings, often
+generated by `bash-completion--extract-compgen-options'
+
+OPTION-NAME-OR-NAMES is one or more strings that correspond
+to the option to check.
+
+CUSTOMIZE-OPTION is a customized value, which is either
+'as-configured, to take the option from OPTION-STRINGS, t, to
+force it to be always enabled, or nil, to force it to be always
+disabled."
+ (if (eq 'as-configured customize-option)
+ (if (listp option-name-or-names)
+ (delete nil (mapcar (lambda (name) (member name option-strings))
+ option-name-or-names))
+ (member option-name-or-names option-strings))
+ customize-option))
+
(provide 'bash-completion)
;;; bash-completion.el ends here
diff --git a/test/bash-completion-integration-test.el
b/test/bash-completion-integration-test.el
index f43232edd7..2f858f5b33 100644
--- a/test/bash-completion-integration-test.el
+++ b/test/bash-completion-integration-test.el
@@ -34,11 +34,13 @@
(require 'ert)
(defmacro bash-completion_test-harness (&rest body)
- `(progn
+ `(if (file-executable-p bash-completion-prog)
(let ((test-env-dir (bash-completion_test-setup-env)))
(let ((bash-completion-processes nil)
(bash-completion-alist nil)
(bash-completion-nospace nil)
+ (bash-completion-default 'as-configured)
+ (bash-completion-enable-caching nil)
(bash-completion-start-files nil)
(bash-completion-args
(list "--noediting"
@@ -55,7 +57,7 @@
(bash-completion_test-teardown-env test-env-dir)
(bash-completion-reset-all)))))))
-(defmacro bash-completion_test-with-shell (complete-me)
+(defmacro bash-completion_test-with-shell-harness (&rest body)
`(bash-completion_test-harness
(let ((shell-buffer))
(unwind-protect
@@ -66,15 +68,21 @@
(while (accept-process-output nil 0.6))
;; do a completion and return the result
(with-current-buffer shell-buffer
- (insert ,complete-me)
(let ((comint-dynamic-complete-functions
'(bash-completion-dynamic-complete)))
- (completion-at-point))
- (buffer-substring-no-properties
- (comint-line-beginning-position) (point))))
- ;; finally
- (when (and shell-buffer (buffer-live-p shell-buffer))
- (kill-process (get-buffer-process shell-buffer))
- (kill-buffer shell-buffer))))))
+ (progn ,@body))))
+ (progn ;; finally
+ (when (and shell-buffer (buffer-live-p shell-buffer))
+ (kill-process (get-buffer-process shell-buffer)))
+ (when shell-buffer
+ (kill-buffer shell-buffer)))))))
+
+(defun bash-completion_test-complete (complete-me)
+ (goto-char (point-max))
+ (comint-delete-input)
+ (insert complete-me)
+ (completion-at-point)
+ (buffer-substring-no-properties
+ (comint-line-beginning-position) (point)))
(defun bash-completion_test-setup-env ()
"Sets up a directory that contains a bashrc file other files
@@ -88,7 +96,13 @@ for testing completion."
test-env-dir
(with-temp-file (expand-file-name "bashrc" test-env-dir)
(insert (format "cd '%s'\n" test-env-dir))
- (insert "function somefunction { echo ok; }\n"))
+ (insert "function somefunction { echo ok; }\n")
+ (insert "function someotherfunction { echo ok; }\n")
+ (insert "function _dummy_complete {\n")
+ (insert " if [[ ${COMP_WORDS[COMP_CWORD]} == du ]]; then
COMPREPLY=(dummy); fi\n")
+ (insert "}\n")
+ (insert "complete -F _dummy_complete -o filenames somefunction\n")
+ (insert "complete -F _dummy_complete -o default -o filenames
someotherfunction\n"))
(let ((default-directory test-env-dir))
(make-directory "some/directory" 'parents)
(make-directory "some/other/directory" 'parents)))))
@@ -101,67 +115,54 @@ for testing completion."
(dired-delete-file test-env-dir 'always))))
(ert-deftest bash-completion-integration-test ()
- (let ((bash-completion-enable-caching nil))
- (bash-completion_test-integration)))
-
-(ert-deftest bash-completion-integration-test-with-caching ()
- (let ((bash-completion-enable-caching t))
- (bash-completion_test-integration)))
-
-(defun bash-completion_test-integration ()
- (if (file-executable-p bash-completion-prog)
- (bash-completion_test-harness
- (should-not (bash-completion-is-running))
- (should (buffer-live-p (bash-completion-buffer)))
- (should (bash-completion-is-running))
- (should-not (null (member
- "help "
- (let ((bash-completion-nospace nil))
- (bash-completion-comm "hel" 4 '("hel") 0 nil
"hel")))))
- (bash-completion-reset)
- (should-not (bash-completion-is-running)))))
+ (bash-completion_test-harness
+ (should-not (bash-completion-is-running))
+ (should (buffer-live-p (bash-completion-buffer)))
+ (should (bash-completion-is-running))
+ (should-not (null (member
+ "help "
+ (let ((bash-completion-nospace nil))
+ (bash-completion-comm
+ (bash-completion--make
+ :line "hel"
+ :point 4
+ :words '("hel")
+ :cword 0
+ :unparsed-stub "hel"))))))
+ (bash-completion-reset)
+ (should-not (bash-completion-is-running))))
(ert-deftest bash-completion-integration-setenv-test ()
- (let ((bash-completion-enable-caching nil))
- (bash-completion_test-integration-setenv-test)))
-
-(ert-deftest bash-completion-integration-setenv-test-with-caching ()
- (let ((bash-completion-enable-caching t))
- (bash-completion_test-integration-setenv-test)))
-
-(defun bash-completion_test-integration-setenv-test ()
- (if (file-executable-p bash-completion-prog)
- (bash-completion_test-harness
- (bash-completion-send "echo $EMACS_BASH_COMPLETE")
- (with-current-buffer (bash-completion-buffer)
- (should (equal "t\n" (buffer-string)))))))
-
-(ert-deftest bash-completion-integration-one-completion-test ()
- (let ((bash-completion-enable-caching nil))
- (bash-completion_test-integration-one-completion-test)))
-
-(ert-deftest bash-completion-integration-one-completion-test-with-caching ()
- (let ((bash-completion-enable-caching t))
- (bash-completion_test-integration-one-completion-test)))
-
-(defun bash-completion_test-integration-one-completion-test ()
- (if (file-executable-p bash-completion-prog)
- (should (equal "somefunction "
- (bash-completion_test-with-shell "somef")))))
-
-(ert-deftest bash-completion-integration-wordbreak-completion-test ()
- (let ((bash-completion-enable-caching nil))
- (bash-completion_test-integration-wordbreak-completion-test)))
-
-(ert-deftest
bash-completion-integration-wordbreak-completion-test-with-caching ()
- (let ((bash-completion-enable-caching t))
- (bash-completion_test-integration-wordbreak-completion-test)))
-
-(defun bash-completion_test-integration-wordbreak-completion-test ()
- (if (file-executable-p bash-completion-prog)
- (should (equal "export SOMEPATH=some/directory:some/other/"
- (bash-completion_test-with-shell
- "export SOMEPATH=some/directory:some/oth")))))
-
+ (bash-completion_test-harness
+ (bash-completion-send "echo $EMACS_BASH_COMPLETE")
+ (with-current-buffer (bash-completion-buffer)
+ (should (equal "t\n" (buffer-string))))))
+
+(ert-deftest bash-completion-integration-completion-test ()
+ (bash-completion_test-with-shell-harness
+ (bash-completion-integration-test-complete)))
+
+(ert-deftest bash-completion-integration-completion-test-with-caching ()
+ (bash-completion_test-with-shell-harness
+ (setq bash-completion-enable-caching t)
+ (bash-completion-integration-test-complete)))
+
+(defun bash-completion-integration-test-complete ()
+ ;; complete command
+ (should (equal "somefunction "
+ (bash-completion_test-complete "somef")))
+ ;; custom completion
+ (should (equal "somefunction dummy "
+ (bash-completion_test-complete "somefunction du")))
+ ;; failed completion, no -o default
+ (should (equal "somefunction so"
+ (bash-completion_test-complete "somefunction so")))
+ ;; failed completion, with -o default
+ (should (equal "someotherfunction some/"
+ (bash-completion_test-complete "someotherfunction so")))
+ ;; wordbreak completion
+ (should (equal "export SOMEPATH=some/directory:some/other/"
+ (bash-completion_test-complete
+ "export SOMEPATH=some/directory:some/oth"))))
;;; bash-completion-integration-test.el ends here
diff --git a/test/bash-completion-test.el b/test/bash-completion-test.el
index be5706e645..4d71e2b761 100644
--- a/test/bash-completion-test.el
+++ b/test/bash-completion-test.el
@@ -146,102 +146,138 @@ The return value is the one returned by BODY."
(bash-completion-strings-from-tokens
(bash-completion-tokenize 1 (line-end-position)))))))
-(ert-deftest bash-completion-process-tokens-test ()
+(ert-deftest bash-completion--parse-test ()
;; cursor at end of word
(should (equal
- '((line . "a hello world")
- (point . 13)
- (cword . 2)
- (words . ("a" "hello" "world"))
- (stub-start . 9))
+ (bash-completion--make
+ :line "a hello world"
+ :point 13
+ :cword 2
+ :words '("a" "hello" "world")
+ :stub-start 9
+ :unparsed-stub "world")
(bash-completion-test-with-buffer
"a hello world"
- (bash-completion-process-tokens
- (bash-completion-tokenize (point-min) (point-max)) 14 nil))))
+ (bash-completion--parse (point-min) 14))))
;; just one space, cursor after it
(should (equal
- '((line . "")
- (point . 0)
- (cword . 0)
- (words . (""))
- (stub-start . 2))
- (bash-completion-test-with-buffer
- " "
- (bash-completion-process-tokens
- (bash-completion-tokenize (point-min) (point-max)) 2 nil))))
+ (bash-completion--make
+ :line ""
+ :point 0
+ :cword 0
+ :words '("")
+ :stub-start 2
+ :unparsed-stub "")
+ (bash-completion-test-with-buffer
+ " "
+ (bash-completion--parse (point-min) 2))))
;; some words separated by spaces, cursor after the last space
(should (equal
- '((line . "a hello ")
- (point . 8)
- (cword . 2)
- (words . ("a" "hello" ""))
- (stub-start . 9))
- (bash-completion-test-with-buffer
- "a hello "
- (bash-completion-process-tokens
- (bash-completion-tokenize (point-min) (point-max)) 9 nil))))
-
+ (bash-completion--make
+ :line "a hello "
+ :point 8
+ :cword 2
+ :words '("a" "hello" "")
+ :stub-start 9
+ :unparsed-stub "")
+ (bash-completion-test-with-buffer
+ "a hello "
+ (bash-completion--parse (point-min) 9))))
+
;; complex multi-command line
- (should (equal
- '((line . "make -")
- (point . 6)
- (cword . 1)
- (words . ("make" "-"))
- (stub-start . 27))
- (bash-completion-test-with-buffer
- "cd /var/tmp ; ZORG=t make -"
- (bash-completion-process-tokens
- (bash-completion-tokenize (point-min) (point-max)) 28 nil))))
+ (should (equal
+ (bash-completion--make
+ :line "make -"
+ :point 6
+ :cword 1
+ :words '("make" "-")
+ :stub-start 27
+ :unparsed-stub "-")
+ (bash-completion-test-with-buffer
+ "cd /var/tmp ; ZORG=t make -"
+ (bash-completion--parse (point-min) 28))))
;; pipe
- (should (equal
- '((line . "sort -")
- (point . 6)
- (cword . 1)
- (words . ("sort" "-"))
- (stub-start . 20))
- (bash-completion-test-with-buffer
- "ls /var/tmp | sort -"
- (bash-completion-process-tokens
- (bash-completion-tokenize (point-min) (point-max)) 21 nil))))
+ (should (equal
+ (bash-completion--make
+ :line "sort -"
+ :point 6
+ :cword 1
+ :words '("sort" "-")
+ :stub-start 20
+ :unparsed-stub "-")
+ (bash-completion-test-with-buffer
+ "ls /var/tmp | sort -"
+ (bash-completion--parse (point-min) 21))))
;; escaped semicolon
- (should (equal
- '((line . "find -name '*.txt' -exec echo {} ';' -")
- (point . 38)
- (cword . 7)
- (words . ("find" "-name" "*.txt" "-exec" "echo" "{}" ";" "-"))
- (stub-start . 38))
- (bash-completion-test-with-buffer
- "find -name '*.txt' -exec echo {} ';' -"
- (bash-completion-process-tokens
- (bash-completion-tokenize (point-min) (point-max)) 39 nil))))
+ (should (equal
+ (bash-completion--make
+ :line "find -name '*.txt' -exec echo {} ';' -"
+ :point 38
+ :cword 7
+ :words '("find" "-name" "*.txt" "-exec" "echo" "{}" ";" "-")
+ :stub-start 38
+ :unparsed-stub "-")
+ (bash-completion-test-with-buffer
+ "find -name '*.txt' -exec echo {} ';' -"
+ (bash-completion--parse (point-min) 39))))
;; at var assignment
- (should (equal
- '((line . "ZORG=t")
- (point . 6)
- (cword . 0)
- (words . ("ZORG=t"))
- (stub-start . 19))
- (bash-completion-test-with-buffer
- "cd /var/tmp ; A=f ZORG=t"
- (bash-completion-process-tokens
- (bash-completion-tokenize (point-min) (point-max)) 25 nil))))
+ (should (equal
+ (bash-completion--make
+ :line "ZORG=t"
+ :point 6
+ :cword 0
+ :words '("ZORG=t")
+ :stub-start 19
+ :unparsed-stub "ZORG=t")
+ (bash-completion-test-with-buffer
+ "cd /var/tmp ; A=f ZORG=t"
+ (bash-completion--parse (point-min) 25))))
;; with escaped quote
- (should (equal
- '((line . "cd /vcr/shows/Dexter\\'s")
- (point . 23)
- (cword . 1)
- (words . ("cd" "/vcr/shows/Dexter's"))
- (stub-start . 4))
- (bash-completion-test-with-buffer
- "cd /vcr/shows/Dexter\\'s"
- (bash-completion-process-tokens
- (bash-completion-tokenize (point-min) (point-max)) 24 nil)))))
+ (should (equal
+ (bash-completion--make
+ :line "cd /vcr/shows/Dexter\\'s"
+ :point 23
+ :cword 1
+ :words '("cd" "/vcr/shows/Dexter's")
+ :stub-start 4
+ :unparsed-stub "/vcr/shows/Dexter\\'s")
+ (bash-completion-test-with-buffer
+ "cd /vcr/shows/Dexter\\'s"
+ (bash-completion--parse (point-min) 24))))
+
+ ;; with double quote
+ (should (equal
+ (bash-completion--make
+ :line "cd \"/vcr/shows/Dexter's"
+ :point 23
+ :cword 1
+ :words '("cd" "/vcr/shows/Dexter's")
+ :stub-start 5
+ :unparsed-stub "/vcr/shows/Dexter's"
+ :open-quote ?\")
+ (bash-completion-test-with-buffer
+ "cd \"/vcr/shows/Dexter's"
+ (bash-completion--parse (point-min) 24))))
+
+ ;; with single quote
+ (should (equal
+ (bash-completion--make
+ :line "cd '/vcr/shows/Dexter'\\''s"
+ :point 26
+ :cword 1
+ :words '("cd" "/vcr/shows/Dexter's")
+ :stub-start 5
+ :unparsed-stub "/vcr/shows/Dexter'\\''s"
+ :open-quote ?')
+ (bash-completion-test-with-buffer
+ "cd '/vcr/shows/Dexter'\\''s"
+ (bash-completion--parse (point-min) 27)))))
(ert-deftest bash-completion-add-to-alist-test ()
;; garbage
@@ -306,72 +342,82 @@ garbage
(ert-deftest bash-completion-generate-line-test ()
;; no custom completion
(should
- (equal (cons 'default
- (concat "cd >/dev/null 2>&1 " (expand-file-name "~/test")
- " ; compgen -o default -- worl 2>/dev/null"))
+ (equal (concat "cd >/dev/null 2>&1 " (expand-file-name "~/test")
+ " ; compgen -o default -- worl 2>/dev/null")
(let ((bash-completion-alist nil)
(default-directory "~/test"))
- (bash-completion-generate-line "hello worl" 7 '("hello" "worl") 1
nil))))
+ (bash-completion-generate-line
+ (bash-completion--make
+ :line "hello worl"
+ :point 7
+ :words '("hello" "worl")
+ :cword 1)))))
;; custom completion no function or command
(should (equal
- (cons 'custom
- "cd >/dev/null 2>&1 /test ; compgen -A -G '*.txt' -- worl
2>/dev/null")
- (let ((bash-completion-alist '(("zorg" . ("-A" "-G" "*.txt"))))
- (default-directory "/test"))
- (bash-completion-generate-line "zorg worl" 7 '("zorg" "worl") 1
nil))))
+ "cd >/dev/null 2>&1 /test ; compgen -A -G '*.txt' -- worl
2>/dev/null"
+ (let ((default-directory "/test"))
+ (bash-completion-generate-line
+ (bash-completion--make
+ :line "zorg worl"
+ :point 7
+ :words '("zorg" "worl")
+ :cword 1
+ :compgen-args '("-A" "-G" "*.txt"))))))
;; custom completion function
(should (equal
- (cons 'custom
- (concat
- "cd >/dev/null 2>&1 /test ; "
- "__BASH_COMPLETE_WRAPPER='COMP_LINE='\\''zorg worl'\\''; "
- "COMP_POINT=7; COMP_CWORD=1; "
- "COMP_WORDS=( zorg worl ); "
- "__zorg \"${COMP_WORDS[@]}\"' "
- "compgen -F __bash_complete_wrapper -- worl 2>/dev/null"))
- (let ((bash-completion-alist '(("zorg" . ("-F" "__zorg"))))
- (default-directory "/test"))
- (bash-completion-generate-line "zorg worl" 7 '("zorg" "worl") 1
nil))))
+ (concat
+ "cd >/dev/null 2>&1 /test ; "
+ "__BASH_COMPLETE_WRAPPER='COMP_LINE='\\''zorg worl'\\''; "
+ "COMP_POINT=7; COMP_CWORD=1; "
+ "COMP_WORDS=( zorg worl ); "
+ "__zorg \"${COMP_WORDS[@]}\"' "
+ "compgen -F __bash_complete_wrapper -- worl 2>/dev/null")
+ (let ((default-directory "/test"))
+ (bash-completion-generate-line
+ (bash-completion--make
+ :line "zorg worl"
+ :point 7
+ :words '("zorg" "worl")
+ :cword 1
+ :compgen-args '("-F" "__zorg"))))))
;; custom completion command
(should (equal
- (cons 'custom
- (concat
- "cd >/dev/null 2>&1 /test ; "
- "__BASH_COMPLETE_WRAPPER='COMP_LINE='\\''zorg worl'\\''; "
- "COMP_POINT=7; "
- "COMP_CWORD=1; "
- "COMP_WORDS=( zorg worl ); "
- "__zorg \"${COMP_WORDS[@]}\"' "
- "compgen -F __bash_complete_wrapper -- worl 2>/dev/null"))
- (let ((bash-completion-alist '(("zorg" . ("-C" "__zorg"))))
- (default-directory "/test"))
- (bash-completion-generate-line "zorg worl" 7 '("zorg" "worl") 1
nil))))
-
- ;; default completion function
- (should (equal
- (cons 'custom
- (concat
- "cd >/dev/null 2>&1 /test ; "
- "__BASH_COMPLETE_WRAPPER='COMP_LINE='\\''zorg worl'\\''; "
- "COMP_POINT=7; "
- "COMP_CWORD=1; "
- "COMP_WORDS=( zorg worl ); "
- "__zorg \"${COMP_WORDS[@]}\"' "
- "compgen -F __bash_complete_wrapper -- worl 2>/dev/null"))
- (let ((bash-completion-alist '((nil . ("-F" "__zorg"))))
- (default-directory "/test"))
- (bash-completion-generate-line "zorg worl" 7 '("zorg" "worl") 1
t))))
-
- ;; ignore completion function
- (should (equal
- (cons 'default
- "cd >/dev/null 2>&1 /test ; compgen -o default -- worl
2>/dev/null")
- (let ((bash-completion-alist '((nil . ("-F" "__zorg"))))
- (default-directory "/test"))
- (bash-completion-generate-line "zorg worl" 7 '("zorg" "worl") 1
nil)))))
+ (concat
+ "cd >/dev/null 2>&1 /test ; "
+ "__BASH_COMPLETE_WRAPPER='COMP_LINE='\\''zorg worl'\\''; "
+ "COMP_POINT=7; "
+ "COMP_CWORD=1; "
+ "COMP_WORDS=( zorg worl ); "
+ "__zorg \"${COMP_WORDS[@]}\"' "
+ "compgen -F __bash_complete_wrapper -- worl 2>/dev/null")
+ (let ((default-directory "/test"))
+ (bash-completion-generate-line
+ (bash-completion--make
+ :line "zorg worl"
+ :point 7
+ :words '("zorg" "worl")
+ :cword 1
+ :compgen-args '("-C" "__zorg")))))))
+
+(ert-deftest bash-completion-customize-test ()
+ (cl-letf (((symbol-function 'bash-completion-require-process)
+ (lambda () '(nil
+ (nil "-F" "__default")
+ ("zorg" "-F" "__zorg")))))
+ (let ((comp (bash-completion--make :cword 1)))
+ (setf (bash-completion--words comp) '("zorg" "world"))
+ (bash-completion--customize comp)
+ (should (equal '("-F" "__zorg") (bash-completion--compgen-args comp)))
+
+ (setf (bash-completion--words comp) '("notzorg" "world"))
+ (bash-completion--customize comp)
+ (should (equal '("-F" "__default") (bash-completion--compgen-args comp)))
+
+ (bash-completion--customize comp 'nodefault)
+ (should (null (bash-completion--compgen-args comp))))))
(ert-deftest bash-completion--find-last-test ()
(should (equal nil (bash-completion--find-last ?a "xxxxx")))
@@ -506,13 +552,11 @@ Return (const return-value new-buffer-content)"
;; do not escape final space
(should (equal "ab "
- (let ((bash-completion-nospace nil))
- (bash-completion-fix "ab " "a" "a" nil nil nil))))
+ (bash-completion-fix "ab " "a" "a" nil nil nil)))
- ;; remove final space
+ ;; remove final space with option nospace
(should (equal "ab"
- (let ((bash-completion-nospace t))
- (bash-completion-fix "ab " "a" "a" nil nil nil))))
+ (bash-completion-fix "ab " "a" "a" nil '(nospace) nil)))
;; unexpand home and escape
(should (equal "~/a/hello\\ world"
@@ -528,10 +572,13 @@ Return (const return-value new-buffer-content)"
(should (equal "hello\\ world"
(bash-completion-fix " world" "hello" "hello" nil nil nil)))
- ;; append / for home
+ ;; append / for home, with option filenames
(should (equal "~/"
(bash-completion-fix (expand-file-name "~")
- "~" "~" nil 'default nil)))
+ "~" "~" nil '(filenames) nil)))
+ (should (equal "~"
+ (bash-completion-fix (expand-file-name "~")
+ "~" "~" nil nil nil)))
(cl-letf (((symbol-function 'file-accessible-directory-p)
(lambda (d) (equal d "/tmp/somedir"))))
@@ -539,35 +586,31 @@ Return (const return-value new-buffer-content)"
;; append / for directory
(should (equal "somedir/"
(bash-completion-fix "somedir" "some" "some"
- nil 'default nil)))
- ;; append / for initial command that is a directory
- (should (equal "somedir/"
- (bash-completion-fix "somedir" "some" "some"
- nil 'command nil)))))
+ nil '(filenames) nil)))))
;; append a space for initial command that is not a directory
(should (let ((bash-completion-nospace nil))
(equal "somecmd "
(bash-completion-fix "somecmd" "some" "some"
- nil 'command nil))))
+ nil nil 'single))))
- ;; ... but not if nospace is t.
+ ;; ... but not if nospace option is set
(should (let ((bash-completion-nospace t))
(equal "somecmd"
(bash-completion-fix "somecmd" "some" "some"
- nil 'command nil))))
+ nil '(nospace) nil))))
- ;; append a space for a single default completion
+ ;; append a space for a single completion
(should (let ((bash-completion-nospace nil))
(equal "somecmd "
(bash-completion-fix "somecmd" "some" "some"
- nil 'default 'single))))
+ nil nil 'single))))
;; but only for a single completion
(should (let ((bash-completion-nospace nil))
(equal "somecmd"
(bash-completion-fix "somecmd" "some" "some"
- nil 'default nil))))
+ nil nil nil))))
;; subset of the prefix"
(should (equal "Dexter"
@@ -862,7 +905,7 @@ before calling `bash-completion-dynamic-complete-nocomint'.
(push "bin\nbind\n" --send-results)
(insert "$ b")
(should (equal
- '("bin/" "bind ")
+ '("bin/" "bind")
(nth 2 (bash-completion-dynamic-complete-nocomint 3 (point)))))
(should (equal (concat "cd >/dev/null 2>&1 /tmp/test ; "
"compgen -b -c -a -A function -- b 2>/dev/null")
@@ -934,9 +977,9 @@ before calling `bash-completion-dynamic-complete-nocomint'.
'("somedir/")
(nth 2 (bash-completion-dynamic-complete-nocomint 3
(point))))))))
-(ert-deftest bash-completion-single-custom-completion-as-directory-implicit ()
+(ert-deftest bash-completion-single-custom-completion-as-directory-with-option
()
(--with-fake-bash-completion-send
- (setq bash-completion-alist '(("ls" "compgen" "args")))
+ (setq bash-completion-alist '(("ls" "compgen" "args" "-o" "filenames")))
;; note that adding a / after a completion is not always the right thing
;; to do. See github issue #19.
(push "/tmp/test/somedir" --directories)
@@ -949,7 +992,7 @@ before calling `bash-completion-dynamic-complete-nocomint'.
(ert-deftest bash-completion-custom-completion-with-fallback ()
(--with-fake-bash-completion-send
- (setq bash-completion-alist '(("ls" "compgen" "args")))
+ (setq bash-completion-alist '(("ls" "compgen" "args" "-o" "default")))
(setq --send-results '("" "foo\nfoobar\n"))
(insert "$ ls fo")
(let ((bash-completion-nospace nil))
@@ -957,5 +1000,40 @@ before calling
`bash-completion-dynamic-complete-nocomint'.
'("foo" "foobar")
(nth 2 (bash-completion-dynamic-complete-nocomint 3
(point))))))))
+(ert-deftest bash-completion--extract-compgen-options-test ()
+ (should (equal '("filenames" "default")
+ (bash-completion--extract-compgen-options
+ '("-a" "-o" "default" "-F" "fun" "-o" "filenames"))))
+ (should (equal '()
+ (bash-completion--extract-compgen-options
+ '("-a" "-F" "fun"))))
+ (should (equal '()
+ (bash-completion--extract-compgen-options
+ '("-a" "-F" "fun" "-o")))))
+
+(ert-deftest bash-completion--parse-options ()
+ (let ((bash-completion-default 'as-configured)
+ (bash-completion-nospace 'as-configured)
+ (bash-completion-filenames 'as-configured))
+ (should (equal nil (bash-completion--parse-options nil)))
+ (should (equal '(filenames nospace default)
+ (bash-completion--parse-options
+ '("filenames" "nospace" "default"))))
+ (should (equal '(filenames)
+ (bash-completion--parse-options
+ '("filenames"))))
+ (should (equal '(default)
+ (bash-completion--parse-options
+ '("bashdefault"))))
+ (setq bash-completion-default nil)
+ (setq bash-completion-nospace nil)
+ (setq bash-completion-filenames nil)
+ (should (equal '() (bash-completion--parse-options
+ '("filenames" "nospace" "default"))))
+ (setq bash-completion-default t)
+ (setq bash-completion-nospace t)
+ (setq bash-completion-filenames t)
+ (should (equal '(filenames nospace default)
+ (bash-completion--parse-options nil)))))
;;; bash-completion_test.el ends here
- [nongnu] elpa/bash-completion abe93ae2f6 308/313: Fix whitespace (#47), (continued)
- [nongnu] elpa/bash-completion abe93ae2f6 308/313: Fix whitespace (#47), ELPA Syncer, 2022/12/03
- [nongnu] elpa/bash-completion df635e79fd 310/313: Replace deprecated `cl` package with `cl-lib` (#50), ELPA Syncer, 2022/12/03
- [nongnu] elpa/bash-completion 8e9c20dbfe 313/313: Replace or quote certain single quotes in docstrings (#55), ELPA Syncer, 2022/12/03
- [nongnu] elpa/bash-completion aa9bea48ba 022/313: fix position, ELPA Syncer, 2022/12/03
- [nongnu] elpa/bash-completion 6aedd69000 164/313: Delete duplicates when extracting candidates. fixes #26, ELPA Syncer, 2022/12/03
- [nongnu] elpa/bash-completion 58447c67bf 206/313: Merge the send functions, ELPA Syncer, 2022/12/03
- [nongnu] elpa/bash-completion d6c28d3132 302/313: Add a troubleshooting section to README.md, ELPA Syncer, 2022/12/03
- [nongnu] elpa/bash-completion d550256e3f 306/313: Disable flakey test for now., ELPA Syncer, 2022/12/03
- [nongnu] elpa/bash-completion a8f7de1e91 173/313: Merge remote-tracking branch 'montag451/remote-shell-support-rebase', ELPA Syncer, 2022/12/03
- [nongnu] elpa/bash-completion 9521f79b33 176/313: Display the emacs command run by the tests., ELPA Syncer, 2022/12/03
- [nongnu] elpa/bash-completion fc3f762d16 177/313: Track and support options -o default, filenames and nospace.,
ELPA Syncer <=
- [nongnu] elpa/bash-completion c6df9be78d 182/313: Store the alist as process property., ELPA Syncer, 2022/12/03
- [nongnu] elpa/bash-completion fefe5ae88e 191/313: Introduce bash-completion-remote-prog., ELPA Syncer, 2022/12/03
- [nongnu] elpa/bash-completion d99ad71050 199/313: Add a new option to disable the use of separate processes to perform completion, ELPA Syncer, 2022/12/03
- [nongnu] elpa/bash-completion ce59fb017a 202/313: Fallback to the use of a separate process if an error occurs, ELPA Syncer, 2022/12/03
- [nongnu] elpa/bash-completion 24f78df106 203/313: Improve output handling, ELPA Syncer, 2022/12/03
- [nongnu] elpa/bash-completion cc9a3dcab4 204/313: Stop cluttering the Bash history, ELPA Syncer, 2022/12/03
- [nongnu] elpa/bash-completion 0a6fa499ad 207/313: Fix one parameter name of bash-completion--wait-for-prompt, ELPA Syncer, 2022/12/03
- [nongnu] elpa/bash-completion 3bd30eea3f 208/313: Use the correct function to send string to completion process, ELPA Syncer, 2022/12/03
- [nongnu] elpa/bash-completion fd2f8e277e 211/313: Improve prompt detection, ELPA Syncer, 2022/12/03
- [nongnu] elpa/bash-completion ac3bd404e8 220/313: Fix typos (#40), ELPA Syncer, 2022/12/03