[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] externals/company e8a9d38e53 3/3: Merge pull request #1497 from c
From: |
ELPA Syncer |
Subject: |
[elpa] externals/company e8a9d38e53 3/3: Merge pull request #1497 from company-mode/completion_restart_in_new_field |
Date: |
Tue, 5 Nov 2024 12:57:43 -0500 (EST) |
branch: externals/company
commit e8a9d38e5332912433712947bab28af5adb27d7c
Merge: 9c273fc7c1 c625b2ccc7
Author: Dmitry Gutov <dmitry@gutov.dev>
Commit: GitHub <noreply@github.com>
Merge pull request #1497 from company-mode/completion_restart_in_new_field
company-finish: Restart completion if entered a new field
---
NEWS.md | 7 +++++++
company-capf.el | 5 ++---
company-files.el | 14 -------------
company.el | 25 ++++++++++++++++++----
doc/company.texi | 1 +
test/core-tests.el | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
6 files changed, 92 insertions(+), 21 deletions(-)
diff --git a/NEWS.md b/NEWS.md
index d1e28f99dd..e19eebbb5d 100644
--- a/NEWS.md
+++ b/NEWS.md
@@ -2,6 +2,13 @@
# Next
+* Completion is restarted if it enters a new "field" at the end, as indicated
by
+ the `adjust-boundaries` backend action
+ (#[1497](https://github.com/company-mode/company-mode/pull/1497)). This
+ benefits file name (and directory) completion. The user option
+ `company-files-chop-trailing-slash` has been removed, and the
+ `post-completion` handler in `company-files` has been removed as well.
+
* Handle the case when the current c-a-p-f function changes mid-session
(#[1494](https://github.com/company-mode/company-mode/pull/1494)).
diff --git a/company-capf.el b/company-capf.el
index 5295ecdd80..baeacaa283 100644
--- a/company-capf.el
+++ b/company-capf.el
@@ -240,8 +240,7 @@ so we can't just use the preceding variable instead.")
(exit-function (plist-get (nthcdr 4 res) :exit-function))
(table (nth 3 res)))
(if exit-function
- ;; We can more or less know when the user is done with completion,
- ;; so we do something different than `completion--done'.
+ ;; Follow the example of `completion--done'.
(funcall exit-function arg
;; FIXME: Should probably use an additional heuristic:
;; completion-at-point doesn't know when the user picked a
@@ -250,7 +249,7 @@ so we can't just use the preceding variable instead.")
;; RET (or use implicit completion with company-tng).
(if (= (car (completion-boundaries arg table nil ""))
(length arg))
- 'sole
+ 'exact
'finished)))))
(provide 'company-capf)
diff --git a/company-files.el b/company-files.el
index 61e8490467..738809606b 100644
--- a/company-files.el
+++ b/company-files.el
@@ -38,14 +38,6 @@ The values should use the same format as
`completion-ignored-extensions'."
:type '(repeat (string :tag "File extension or directory name"))
:package-version '(company . "0.9.1"))
-(defcustom company-files-chop-trailing-slash t
- "Non-nil to remove the trailing slash after inserting directory name.
-
-This way it's easy to continue completion by typing `/' again.
-
-Set this to nil to disable that behavior."
- :type 'boolean)
-
(defun company-files--directory-files (dir prefix)
;; Don't use directory-files. It produces directories without trailing /.
(condition-case _err
@@ -137,11 +129,6 @@ Set this to nil to disable that behavior."
(and (equal (cdr old) (cdr new))
(string-prefix-p (car old) (car new))))
-(defun company-files--post-completion (arg)
- (when (and company-files-chop-trailing-slash
- (company-files--trailing-slash-p arg))
- (delete-char -1)))
-
(defun company-files--adjust-boundaries (_file prefix suffix)
(cons
(file-name-nondirectory prefix)
@@ -162,7 +149,6 @@ File paths with spaces are only supported inside strings."
(company-files--adjust-boundaries arg (nth 0 rest) (nth 1 rest)))
(location (cons (dired-noselect
(file-name-directory (directory-file-name arg))) 1))
- (post-completion (company-files--post-completion arg))
(kind (if (string-suffix-p "/" arg) 'folder 'file))
(sorted t)
(no-cache t)))
diff --git a/company.el b/company.el
index a579a1de46..3023da6068 100644
--- a/company.el
+++ b/company.el
@@ -2491,7 +2491,6 @@ For more details see `company-insertion-on-trigger' and
(defun company--begin-new ()
(let ((min-prefix (company--prefix-min-length))
entity c)
- (company-cache-expire)
(cl-dolist (backend (if company-backend
;; prefer manual override
(list company-backend)
@@ -2545,6 +2544,7 @@ For more details see `company-insertion-on-trigger' and
(company-candidates
(company--continue))
((company--should-complete)
+ (company-cache-expire)
(company--begin-new)))
(if (not company-candidates)
(setq company-backend nil)
@@ -2595,8 +2595,21 @@ For more details see `company-insertion-on-trigger' and
(pcase-let ((`(,prefix . ,suffix) (company--boundaries result)))
(company--insert-candidate result (or prefix company-prefix))
(and (> (length suffix) 0)
- (delete-region (point) (+ (point) (length suffix)))))
- (company-cancel result))
+ (delete-region (point) (+ (point) (length suffix))))
+ (let ((tick (buffer-chars-modified-tick))
+ (backend company-backend))
+ ;; Call backend's `post-completion' and run other hooks, then exit.
+ (company-cancel result)
+ ;; Try restarting completion, to see if we moved into a new field.
+ ;; Most commonly, this would be after entering a dir in file completion.
+ (when (= (buffer-chars-modified-tick) tick)
+ (let (company-require-match)
+ (setq company-backend backend
+ company--manual-prefix 0)
+ (company--begin-new))
+ (unless (and company-candidates
+ (equal (company--boundaries) '("" . "")))
+ (company-cancel))))))
(defsubst company-keep (command)
(and (symbolp command) (get command 'company-keep)))
@@ -3075,7 +3088,11 @@ For use in the `select-mouse' frontend action.
`let'-bound.")
(company-complete-selection)))
(defun company-complete-selection ()
- "Insert the selected candidate."
+ "Insert the selected candidate.
+
+Restart completion if a new field is entered. A field is indicated by
+`adjust-boundaries' as implemented in the backend. If both adjusted prefix
+and adjusted suffix are empty strings, that means a new field."
(interactive)
(when (and (company-manual-begin) company-selection)
(let ((result (nth company-selection company-candidates)))
diff --git a/doc/company.texi b/doc/company.texi
index 020075a173..9b9eb02397 100644
--- a/doc/company.texi
+++ b/doc/company.texi
@@ -332,6 +332,7 @@ Select the previous candidate
@cindex complete
@findex company-complete-selection
Insert the selected candidate (@code{company-complete-selection}).
+Restart completion if a new field is entered.
@item TAB
@itemx <tab>
diff --git a/test/core-tests.el b/test/core-tests.el
index 152e94c5a2..c33eb3b79c 100644
--- a/test/core-tests.el
+++ b/test/core-tests.el
@@ -706,6 +706,67 @@
(company-complete-selection)
(should (string= "tea-cup" (buffer-string))))))
+(ert-deftest company-complete-restarts-in-new-field ()
+ (with-temp-buffer
+ (insert "foo")
+ (company-mode)
+ (let (company-frontends
+ (company-backends
+ (list (lambda (command &optional _arg &rest rest)
+ (cl-case command
+ (prefix (buffer-substring (point-min) (point)))
+ (adjust-boundaries
+ (if (string-suffix-p "/" (car rest))
+ (cons "" (nth 1 rest))
+ (cons (car rest) (nth 1 rest))))
+ (candidates '("cc/" "aa1" "bb2"))
+ (sorted t))))))
+ (let (this-command)
+ (company-complete))
+ (should (string= "foo" (buffer-string)))
+ (company-complete-selection)
+ (should (string= "cc/" (buffer-string)))
+ (should (equal company-candidates '("cc/" "aa1" "bb2"))))))
+
+(ert-deftest company-complete-no-restart-in-old-field ()
+ (with-temp-buffer
+ (insert "foo")
+ (company-mode)
+ (let (company-frontends
+ (company-backends
+ (list (lambda (command &rest _rest)
+ (cl-case command
+ (prefix (buffer-substring (point-min) (point)))
+ (candidates '("cc/" "aa1" "bb2"))
+ (sorted t))))))
+ (let (this-command)
+ (company-complete))
+ (company-complete-selection)
+ (should (string= "cc/" (buffer-string)))
+ (should (null company-candidates)))))
+
+(ert-deftest company-complete-no-restart-after-post-completion-change ()
+ (with-temp-buffer
+ (insert "foo")
+ (company-mode)
+ (let (company-frontends
+ (company-backends
+ (list (lambda (command &optional _arg &rest rest)
+ (cl-case command
+ (prefix (buffer-substring (point-min) (point)))
+ (candidates '("cc/" "aa1" "bb2"))
+ (adjust-boundaries
+ (if (string-suffix-p "/" (car rest))
+ (cons "" (nth 1 rest))
+ (cons (car rest) (nth 1 rest))))
+ (post-completion (insert "bar/"))
+ (sorted t))))))
+ (let (this-command)
+ (company-complete))
+ (company-complete-selection)
+ (should (string= "cc/bar/" (buffer-string)))
+ (should (null company-candidates)))))
+
(defvar ct-sorted nil)
;; FIXME: When Emacs 29+ only: just replace with equal-including-properties.