emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[elpa] externals/eglot c4ffabc 083/139: Half-decent completion support


From: João Távora
Subject: [elpa] externals/eglot c4ffabc 083/139: Half-decent completion support
Date: Mon, 14 May 2018 09:54:58 -0400 (EDT)

branch: externals/eglot
commit c4ffabcb5f95d8d2a3676006641362e188df52f8
Author: João Távora <address@hidden>
Commit: João Távora <address@hidden>

    Half-decent completion support
    
    * README.md: Update.
    
    * eglot.el (eglot--kind-names): New variable.
    (eglot--managed-mode): Handle completion-at-point-functions.
    (eglot-completion-at-point): New function.
---
 README.md |  3 ++-
 eglot.el  | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 55 insertions(+), 3 deletions(-)

diff --git a/README.md b/README.md
index 955ef54..f70d15f 100644
--- a/README.md
+++ b/README.md
@@ -31,7 +31,8 @@ server. To skip the guess and always be prompted use `C-u M-x 
eglot`.
 - [x] textDocument/didSave
 
 - [ ] textDocument/codeAction
-- [ ] textDocument/completion (incl. completion/resolve)
+- [x] textDocument/completion
+- [ ] completionItem/resolve
 - [x] textDocument/definition
 - [ ] textDocument/documentHighlight
 - [ ] textDocument/documentSymbol
diff --git a/eglot.el b/eglot.el
index f6bf010..2ab4781 100644
--- a/eglot.el
+++ b/eglot.el
@@ -757,6 +757,13 @@ Meaning only return locally if successful, otherwise exit 
non-locally."
   "Convert URI to a file path."
   (url-filename (url-generic-parse-url (url-unhex-string uri))))
 
+(defconst eglot--kind-names
+  `((1 . "Text") (2 . "Method") (3 . "Function") (4 . "Constructor")
+    (5 . "Field") (6 . "Variable") (7 . "Class") (8 . "Interface")
+    (9 . "Module") (10 . "Property") (11 . "Unit") (12 . "Value")
+    (13 . "Enum") (14 . "Keyword") (15 . "Snippet") (16 . "Color")
+    (17 . "File") (18 . "Reference")))
+
 
 ;;; Minor modes
 ;;;
@@ -777,10 +784,11 @@ Meaning only return locally if successful, otherwise exit 
non-locally."
     (add-hook 'flymake-diagnostic-functions 'eglot-flymake-backend nil t)
     (add-hook 'kill-buffer-hook 'eglot--signal-textDocument/didClose nil t)
     (add-hook 'before-revert-hook 'eglot--signal-textDocument/didClose nil t)
-    ;; (add-hook 'after-revert-hook 'eglot--signal-textDocument/didOpen nil t)
+    ;;(add-hook 'after-revert-hook 'eglot--signal-textDocument/didOpen nil t)
     (add-hook 'before-save-hook 'eglot--signal-textDocument/willSave nil t)
     (add-hook 'after-save-hook 'eglot--signal-textDocument/didSave nil t)
     (add-hook 'xref-backend-functions 'eglot-xref-backend nil t)
+    (add-hook 'completion-at-point-functions #'eglot-completion-at-point nil t)
     (flymake-mode 1))
    (t
     (remove-hook 'flymake-diagnostic-functions 'eglot-flymake-backend t)
@@ -791,7 +799,8 @@ Meaning only return locally if successful, otherwise exit 
non-locally."
     ;; (remove-hook 'after-revert-hook 'eglot--signal-textDocument/didOpen t)
     (remove-hook 'before-save-hook 'eglot--signal-textDocument/willSave t)
     (remove-hook 'after-save-hook 'eglot--signal-textDocument/didSave t)
-    (remove-hook 'xref-backend-functions 'eglot-xref-backend t))))
+    (remove-hook 'xref-backend-functions 'eglot-xref-backend t)
+    (remove-hook 'completion-at-point-functions #'eglot-completion-at-point 
t))))
 
 (define-minor-mode eglot-mode
   "Minor mode for all buffers managed by EGLOT in some way."  nil
@@ -1353,6 +1362,48 @@ DUMMY is ignored"
                         :workspace/symbol
                         (eglot--obj :query pattern))))
 
+(defun eglot-completion-at-point ()
+  "EGLOT's `completion-at-point' function."
+  (let ((bounds (bounds-of-thing-at-point 'sexp))
+        (proc (eglot--current-process-or-lose)))
+    (when (plist-get (eglot--capabilities proc)
+                     :completionProvider)
+      (list
+       (if bounds (car bounds) (point))
+       (if bounds (cdr bounds) (point))
+       (completion-table-dynamic
+        (lambda (_ignored)
+          (let* ((resp (eglot--sync-request
+                        proc
+                        :textDocument/completion
+                        (eglot--obj
+                         :textDocument 
(eglot--current-buffer-TextDocumentIdentifier)
+                         :position (eglot--pos-to-lsp-position))))
+                 (items (if (vectorp resp) resp
+                          (plist-get resp :items))))
+            (eglot--mapply
+             (eglot--lambda (&key insertText label kind detail
+                                  documentation sortText)
+               (propertize insertText
+                           :label label :kind kind :detail detail
+                           :documentation documentation :sortText sortText))
+             items))))
+       :annotation-function
+       (lambda (what)
+         (let ((detail (get-text-property 0 :detail what))
+               (kind (get-text-property 0 :kind what)))
+           (format "%s%s"
+                   detail
+                   (if kind
+                       (format " (%s)" (cdr (assoc kind eglot--kind-names)))
+                     ""))))
+       :display-sort-function
+       (lambda (items)
+         (sort items (lambda (a b)
+                       (string-lessp
+                        (get-text-property 0 :sortText a)
+                        (get-text-property 0 :sortText b)))))))))
+
 
 ;;; Dynamic registration
 ;;;



reply via email to

[Prev in Thread] Current Thread [Next in Thread]