summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Mendler <mail@daniel-mendler.de>2024-01-30 17:28:12 +0100
committerDaniel Mendler <mail@daniel-mendler.de>2024-01-30 19:59:39 +0100
commit2032acea9b5aaa40bffa06cfced7da51675896ea (patch)
treeb77759860d762cbc0a23b1ba92ea2125f7e6081f
parente60773ec02e82140dda5a36df71aab052cfde02a (diff)
Relax the completion table recomputation condition
The completion table will be recomputed when the input prefix changes, even if there is trailing Orderless filter input. Affected are cape--dynamic-table (cape-dict, cape-company-to-capf): and cape-capf-buster. See the discussion at https://github.com/minad/cape/discussions/106 for details.
-rw-r--r--CHANGELOG.org2
-rw-r--r--cape.el39
2 files changed, 25 insertions, 16 deletions
diff --git a/CHANGELOG.org b/CHANGELOG.org
index 51ac1db..98c9bf7 100644
--- a/CHANGELOG.org
+++ b/CHANGELOG.org
@@ -5,6 +5,8 @@
* Development
- Add =cape-wrap-inside-code= and =cape-capf-inside-code=.
+=- =cape--dynamic-table=, =cape-capf-buster=: Recompute the completion table when the
+ input prefix changes, even in the presence of trailing Orderless input.
* Version 1.2 (2024-01-23)
diff --git a/cape.el b/cape.el
index d231794..a196c68 100644
--- a/cape.el
+++ b/cape.el
@@ -158,16 +158,19 @@ The buffers are scanned for completion candidates by `cape-line'."
(replace-match str nil nil input))))
str))
-(defun cape--separator-p (str)
- "Return non-nil if input STR has a separator character.
+(defun cape--input-string (beg end)
+ "Return input string between BEG and END up to a separator character.
Separator characters are used by completion styles like Orderless
to split filter words. In Corfu, the separator is configurable
via the variable `corfu-separator'."
- (string-search (string ;; Support `corfu-separator' and Orderless
- (or (and (bound-and-true-p corfu-mode)
- (bound-and-true-p corfu-separator))
- ?\s))
- str))
+ (save-excursion
+ (goto-char beg)
+ (if (search-forward (string (or (and (bound-and-true-p corfu-mode)
+ (bound-and-true-p corfu-separator))
+ ?\s))
+ end t)
+ (buffer-substring-no-properties beg (1- (point)))
+ (buffer-substring-no-properties beg end))))
(defmacro cape--silent (&rest body)
"Silence BODY."
@@ -324,10 +327,8 @@ string as first argument to the completion table."
;; `all-completions' must surely be most expensive, so nobody will suspect
;; a thing.
(unless (or (eq action 'metadata) (eq (car-safe action) 'boundaries))
- (let ((input (buffer-substring-no-properties beg end)))
- (unless (and valid
- (or (cape--separator-p input)
- (funcall valid input)))
+ (let ((input (cape--input-string beg end)))
+ (unless (and valid (funcall valid input))
(let* (;; Reset in case `all-completions' is used inside FUN
completion-ignore-case completion-regexp-list
;; Retrieve new state by calling FUN
@@ -1005,16 +1006,22 @@ completion table is refreshed on every input change."
(end (copy-marker end t))
(input (buffer-substring-no-properties beg end)))
(lambda (str pred action)
- (let ((new-input (buffer-substring-no-properties beg end)))
- (unless (or (not (eq action t))
- (cape--separator-p new-input)
- (funcall valid input new-input))
+ (let ((new-input (cape--input-string beg end)))
+ (when (and
+ ;; Only refresh table for the `all-completions' action.
+ (eq action t)
+ ;; Point must be inside the input string. It could lie
+ ;; outside if the Orderless completion style is used.
+ (<= beg (point) (+ beg (length new-input)))
+ ;; Current input is not valid.
+ (not (funcall valid input new-input)))
(pcase
;; Reset in case `all-completions' is used inside CAPF
(let (completion-ignore-case completion-regexp-list)
(funcall capf))
((and `(,new-beg ,new-end ,new-table . ,new-plist)
- (guard (and (= beg new-beg) (= end new-end))))
+ ;; new-end can be before end for Orderless completion.
+ (guard (and (= new-beg beg) (<= new-end end))))
(let (throw-on-input) ;; No interrupt during state update
(setf table new-table
input new-input