nil comp)
finally (cl-return comp)))
-(defun eglot--dumb-allc (pat table pred _point) (funcall table pat pred t))
+(defun eglot--dumb-allc (pat table pred point)
+ (funcall table (substring pat 0 point) pred t))
+
(defun eglot--dumb-tryc (pat table pred point)
- (let ((probe (funcall table pat pred nil)))
- (cond ((eq probe t) t)
- (probe
- (if (and (not (equal probe pat))
- (cl-every
- (lambda (s) (string-prefix-p probe s completion-ignore-case))
- (funcall table pat pred t)))
- (cons probe (length probe))
- (cons pat point)))
- (t
- ;; Match ignoring suffix: if there are any completions for
- ;; the current prefix at least, keep the current input.
- (and (funcall table (substring pat 0 point) pred t)
- (cons pat point))))))
+ (let* ((probe (funcall table (substring pat 0 point) pred t)))
+ (cond ((and probe (null (cdr probe)))
+ (cons (car probe) (length (car probe))))
+ (t (cons pat point)))))
(add-to-list 'completion-category-defaults '(eglot-capf (styles eglot--dumb-flex)))
(add-to-list 'completion-styles-alist '(eglot--dumb-flex eglot--dumb-tryc eglot--dumb-allc))
(eglot--wait-for (s-notifs 20) (&key method params &allow-other-keys)
(and
(string= method "$/progress")
- "rustAnalyzer/Indexing"
- (equal params
- '(:token "rustAnalyzer/Indexing" :value
- ;; Could wait for :kind "end" instead, but it's 2 more seconds.
- (:kind "begin" :title "Indexing" :cancellable :json-false :percentage 0)))))))
+ (equal (plist-get params :token) "rustAnalyzer/Roots Scanned")
+ (equal (plist-get (plist-get params :value) :kind) "end")))
+ ;; Annoyingly, waiting for that special progress report is still not
+ ;; enough to make sure the server is ready to provide completions,
+ ;; so here's two extra seconds.
+ (sit-for 2)))
(ert-deftest eglot-test-basic-completions ()
"Test basic autocompletion in a clangd LSP."
(message (buffer-string))
(should (looking-back "fprintf.?")))))
-(ert-deftest eglot-test-common-prefix-completion ()
- "Test completion appending the common prefix."
- (skip-unless (executable-find "clangd"))
- (eglot--with-fixture
- `(("project" . (("coiso.c" .
- ,(concat "int foo_bar; int foo_bar_baz;"
- "int main() {foo")))))
- (with-current-buffer
- (eglot--find-file-noselect "project/coiso.c")
- (eglot--wait-for-clangd)
- (goto-char (point-max))
- (completion-at-point)
- (should (looking-back "{foo_bar")))))
-
(ert-deftest eglot-test-non-unique-completions ()
"Test completion resulting in 'Complete, but not unique'."
(skip-unless (executable-find "clangd"))
(completion-at-point)
(should (looking-back "foo")))))
+(defun eglot--kill-completions-buffer ()
+ (when (buffer-live-p (get-buffer "*Completions*"))
+ (kill-buffer "*Completions*")))
+
(ert-deftest eglot-test-try-completion-nomatch ()
"Test completion table with non-matching input, returning nil."
(skip-unless (executable-find "clangd"))
(with-current-buffer
(eglot--find-file-noselect "project/coiso.c")
(eglot--wait-for-clangd)
+ (eglot--kill-completions-buffer)
(goto-char (point-max))
- (should
- (null
- (completion-try-completion
- "abc"
- (nth 2 (eglot-completion-at-point)) nil 3))))))
+ (completion-at-point)
+ (should (looking-back "abc"))
+ (should-not (get-buffer "*Completions*")))))
(ert-deftest eglot-test-try-completion-inside-symbol ()
"Test completion table inside symbol, with only prefix matching."
`(("project" . (("coiso.c" .
,(concat
"int foobar;"
+ "int foobarbaz;"
"int main() {foo123")))))
(with-current-buffer
(eglot--find-file-noselect "project/coiso.c")
(eglot--wait-for-clangd)
(goto-char (- (point-max) 3))
- (when (buffer-live-p "*Completions*")
- (kill-buffer "*Completions*"))
+ (eglot--kill-completions-buffer)
(completion-at-point)
(should (looking-back "foo"))
(should (looking-at "123"))
- (should (get-buffer "*Completions*"))
- )))
+ (should (get-buffer "*Completions*")))))
+
+(ert-deftest eglot-test-try-completion-inside-symbol-2 ()
+ "Test completion table inside symbol, with only prefix matching."
+ (skip-unless (executable-find "clangd"))
+ (eglot--with-fixture
+ `(("project" . (("coiso.c" .
+ ,(concat
+ "int foobar;"
+ "int main() {foo123")))))
+ (with-current-buffer
+ (eglot--find-file-noselect "project/coiso.c")
+ (eglot--wait-for-clangd)
+ (goto-char (- (point-max) 3))
+ (completion-at-point)
+ (should (looking-back "foobar"))
+ (should (looking-at "123")))))
(ert-deftest eglot-test-rust-completion-exit-function ()
- "Ensure that the rust-analyzer exit function creates the expected contents."
+ "Ensure rust-analyzer exit function creates the expected contents."
+ :tags '(:expensive-test)
+ ;; This originally appeared in github#1339
(skip-unless (executable-find "rust-analyzer"))
(skip-unless (executable-find "cargo"))
(eglot--with-fixture
(with-current-buffer
(eglot--find-file-noselect "cmpl-project/main.rs")
(should (zerop (shell-command "cargo init")))
- (eglot--tests-connect)
- (goto-char (point-min))
(search-forward "v.count_on")
- (let ((minibuffer-message-timeout 0)
- ;; Fail at (ding) if completion fails.
- (executing-kbd-macro t))
- (when (buffer-live-p "*Completions*")
- (kill-buffer "*Completions*"))
- ;; The design is pretty brittle, we'll need to monitor the
- ;; language server for changes in behavior.
- (eglot--wait-for-rust-analyzer)
- (completion-at-point)
- (should (looking-back "\\.count_on"))
- (should (get-buffer "*Completions*"))
- (minibuffer-next-completion 1)
- (minibuffer-choose-completion t))
+ (eglot--wait-for-rust-analyzer)
+ (completion-at-point)
(should
(equal
- "fn test() -> i32 { let v: usize = 1; v.count_ones.1234567890;"
+ (if (bound-and-true-p yas-minor-mode)
+ "fn test() -> i32 { let v: usize = 1; v.count_ones().1234567890;"
+ "fn test() -> i32 { let v: usize = 1; v.count_ones.1234567890;")
(buffer-string))))))
(ert-deftest eglot-test-basic-xref ()