diff options
| author | Daniel Mendler <mail@daniel-mendler.de> | 2024-01-30 17:28:12 +0100 |
|---|---|---|
| committer | Daniel Mendler <mail@daniel-mendler.de> | 2024-01-30 19:59:39 +0100 |
| commit | 2032acea9b5aaa40bffa06cfced7da51675896ea (patch) | |
| tree | b77759860d762cbc0a23b1ba92ea2125f7e6081f | |
| parent | e60773ec02e82140dda5a36df71aab052cfde02a (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.org | 2 | ||||
| -rw-r--r-- | cape.el | 39 |
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) @@ -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 |
