Use completion boundaries in 'pcomplete-long-option-completion-table'

This indicates that the current completion field is complete when the
string is, e.g. "--option=".  The option value is a subsequent field and
is handled by other parts of Pcomplete (bug#81792).

* lisp/pcomplete.el (pcomplete-long-option-completion-table): Set
boundary for completed options that take values.

* test/lisp/pcomplete-tests.el (pcomplete-shell-completion): Convert to
macro and accept BODY arguments.
(pcomplete-test-long-options/with-value/multiple)
(pcomplete-test-long-options/without-value/multiple): New tests.
This commit is contained in:
Jim Porter 2026-09-05 10:42:46 -07:00
parent 194587e0ef
commit 6b53a6f9e4
2 changed files with 48 additions and 16 deletions

View file

@ -1376,7 +1376,7 @@ OPTIONS should be a list of option strings; if a string ends in
\"=\", it's an option that accepts a value."
(lambda (string pred action)
(pcase action
('nil ; try-completion
('nil ; try-completion
(let ((result (try-completion string options pred)))
;; If the completion ends in "=", then it's not really
;; complete yet: we expect a value after the "=". Return the
@ -1385,10 +1385,22 @@ OPTIONS should be a list of option strings; if a string ends in
(if (and (eq result t) (string-suffix-p "=" string))
string
result)))
('t ; all-completions
(all-completions string options pred))
('lambda ; test-completion
(test-completion string options pred)))))
('t ; all-completions
;; Don't list completions when the boundary starts after an "=".
(unless (and (string-suffix-p "=" string)
(member string options))
(all-completions string options pred)))
('lambda ; test-completion
(test-completion string options pred))
(`(boundaries . ,suffix) ; completion-boundaries
;; As above, if the completion ends in "=", then it's not
;; complete yet. The completion's boundary should start after
;; the "=" to indicate that that's where subsequent completions
;; will occur.
(if (and (string-suffix-p "=" string)
(member string options))
`(boundaries ,(length string) . ,(length suffix))
(completion-boundaries string options pred suffix))))))
;;; Parsing help messages

View file

@ -96,17 +96,21 @@ usage: git [-v | --version] [-h | --help] [-C <path>] [-c <name>=<value>]
#("--super-prefix=" 0 1 (pcomplete-annotation "<path>"))
#("--config-env=" 0 1 (pcomplete-annotation "<name>")))))))
(defun pcomplete-shell-completion (input)
"Insert INPUT into shell mode, run completion, and return the result."
(with-temp-buffer
(shell (current-buffer))
(unwind-protect
(let ((start (point)))
(insert input)
(completion-at-point)
(buffer-substring start (point)))
(let (kill-buffer-query-functions)
(kill-buffer (current-buffer))))))
(defmacro pcomplete-shell-completion (input &rest body)
"Insert INPUT into shell mode, run completion, and return the result.
BODY is a list of extra forms to call after completion (e.g. to choose a
completion from the minibuffer)."
(declare (indent 1))
`(with-temp-buffer
(shell (current-buffer))
(unwind-protect
(let ((start (point)))
(insert ,input)
(completion-at-point)
,@body
(buffer-substring start (point)))
(let (kill-buffer-query-functions)
(kill-buffer (current-buffer))))))
(defun pcomplete/pcmpl-option-test ()
"Completion for a test command taking long options."
@ -124,5 +128,21 @@ usage: git [-v | --version] [-h | --help] [-C <path>] [-c <name>=<value>]
(should (string= (pcomplete-shell-completion "pcmpl-option-test --ver")
"pcmpl-option-test --version ")))
(ert-deftest pcomplete-test-long-options/with-value/multiple ()
"Test that completing long options taking values doesn't insert a space.
This tests completing when there are multiple possibilities."
(should (string= (pcomplete-shell-completion "pcmpl-option-test --"
(minibuffer-next-completion 1)
(minibuffer-choose-completion))
"pcmpl-option-test --owner=")))
(ert-deftest pcomplete-test-long-options/without-value/multiple ()
"Test that completing long options without values inserts a space.
This tests completing when there are multiple possibilities."
(should (string= (pcomplete-shell-completion "pcmpl-option-test --"
(minibuffer-next-completion 2)
(minibuffer-choose-completion))
"pcmpl-option-test --version ")))
(provide 'pcomplete-tests)
;;; pcomplete-tests.el ends here