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

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

[elpa] externals/elpa d40f9ac 094/139: Half-decent imenu support via tex


From: João Távora
Subject: [elpa] externals/elpa d40f9ac 094/139: Half-decent imenu support via textDocument/documentSymbol
Date: Mon, 14 May 2018 09:53:43 -0400 (EDT)

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

    Half-decent imenu support via textDocument/documentSymbol
    
    * README.md: Update capability
    
    * eglot.el (eglot--lsp-position-to-point): New function.
    (eglot--managed-mode): Handle imenu-create-index-function.
    (eglot--server-textDocument/publishDiagnostics): Use
    eglot--lsp-position-to-point.
    (eglot-imenu): New function.
    (eglot--client-capabilities): Capable of documentSymbol.
---
 README.md |  2 +-
 eglot.el  | 96 ++++++++++++++++++++++++++++++++++++++++-----------------------
 2 files changed, 62 insertions(+), 36 deletions(-)

diff --git a/README.md b/README.md
index 611839b..fef2d16 100644
--- a/README.md
+++ b/README.md
@@ -35,7 +35,7 @@ server. To skip the guess and always be prompted use `C-u M-x 
eglot`.
 - [ ] completionItem/resolve
 - [x] textDocument/definition
 - [ ] textDocument/documentHighlight
-- [ ] textDocument/documentSymbol
+- [x] textDocument/documentSymbol
 - [ ] textDocument/executeCommand
 - [ ] textDocument/format
 - [x] textDocument/hover
diff --git a/eglot.el b/eglot.el
index 7cc3756..d7ea329 100644
--- a/eglot.el
+++ b/eglot.el
@@ -193,10 +193,11 @@ CONTACT is as `eglot--contact'.  Returns a process 
object."
                                     :willSave t
                                     :willSaveWaitUntil :json-false
                                     :didSave t)
-                  :completion `(:dynamicRegistration :json-false)
-                  :hover      `(:dynamicRegistration :json-false)
-                  :references `(:dynamicRegistration :json-false)
-                  :definition `(:dynamicRegistration :json-false)
+                  :completion     `(:dynamicRegistration :json-false)
+                  :hover          `(:dynamicRegistration :json-false)
+                  :references     `(:dynamicRegistration :json-false)
+                  :definition     `(:dynamicRegistration :json-false)
+                  :documentSymbol `(:dynamicRegistration :json-false)
                   :publishDiagnostics `(:relatedInformation :json-false))
    :experimental (eglot--obj)))
 
@@ -703,6 +704,17 @@ Meaning only return locally if successful, otherwise exit 
non-locally."
                 (- (goto-char (or pos (point)))
                    (line-beginning-position)))))
 
+(defun eglot--lsp-position-to-point (pos-plist)
+  "Convert LSP position POS-PLIST to Emacs point."
+  (save-excursion (goto-char (point-min))
+                  (forward-line (plist-get pos-plist :line))
+                  (forward-char
+                   (min (plist-get pos-plist :character)
+                        (- (line-end-position)
+                           (line-beginning-position))))
+                  (point)))
+
+
 (defun eglot--mapply (fun seq)
   "Apply FUN to every element of SEQ."
   (mapcar (lambda (e) (apply fun e)) seq))
@@ -766,6 +778,7 @@ Meaning only return locally if successful, otherwise exit 
non-locally."
     (add-hook 'completion-at-point-functions #'eglot-completion-at-point nil t)
     (add-function :before-until (local 'eldoc-documentation-function)
                   #'eglot-eldoc-function)
+    (advice-add imenu-create-index-function :around #'eglot-imenu)
     (flymake-mode 1)
     (eldoc-mode 1))
    (t
@@ -779,7 +792,8 @@ Meaning only return locally if successful, otherwise exit 
non-locally."
     (remove-hook 'xref-backend-functions 'eglot-xref-backend t)
     (remove-hook 'completion-at-point-functions #'eglot-completion-at-point t)
     (remove-function (local 'eldoc-documentation-function)
-                     #'eglot-eldoc-function))))
+                     #'eglot-eldoc-function)
+    (advice-remove imenu-create-index-function #'eglot-imenu))))
 
 (define-minor-mode eglot-mode
   "Minor mode for all buffers managed by EGLOT in some way."  nil
@@ -956,36 +970,28 @@ running.  INTERACTIVE is t if called interactively."
     (cond
      (buffer
       (with-current-buffer buffer
-        (cl-flet ((pos-at (pos-plist)
-                          (save-excursion (goto-char (point-min))
-                                          (forward-line (plist-get pos-plist 
:line))
-                                          (forward-char
-                                           (min (plist-get pos-plist 
:character)
-                                                (- (line-end-position)
-                                                   (line-beginning-position))))
-                                          (point))))
-          (cl-loop for diag-spec across diagnostics
-                   collect (cl-destructuring-bind (&key range severity _group
-                                                        _code source message)
-                               diag-spec
-                             (cl-destructuring-bind (&key start end)
-                                 range
-                               (let* ((begin-pos (pos-at start))
-                                      (end-pos (pos-at end)))
-                                 (flymake-make-diagnostic
-                                  (current-buffer)
-                                  begin-pos end-pos
-                                  (cond ((<= severity 1) :error)
-                                        ((= severity 2)  :warning)
-                                        (t               :note))
-                                  (concat source ": " message)))))
-                   into diags
-                   finally
-                   (if eglot--current-flymake-report-fn
-                       (funcall eglot--current-flymake-report-fn
-                                diags)
-                     (setq eglot--unreported-diagnostics
-                           diags))))))
+        (cl-loop
+         for diag-spec across diagnostics
+         collect (cl-destructuring-bind (&key range severity _group
+                                              _code source message)
+                     diag-spec
+                   (cl-destructuring-bind (&key start end)
+                       range
+                     (let* ((begin-pos (eglot--lsp-position-to-point start))
+                            (end-pos (eglot--lsp-position-to-point end)))
+                       (flymake-make-diagnostic
+                        (current-buffer)
+                        begin-pos end-pos
+                        (cond ((<= severity 1) :error)
+                              ((= severity 2)  :warning)
+                              (t               :note))
+                        (concat source ": " message)))))
+         into diags
+         finally (if eglot--current-flymake-report-fn
+                     (funcall eglot--current-flymake-report-fn
+                              diags)
+                   (setq eglot--unreported-diagnostics
+                         diags)))))
      (t
       (eglot--message "OK so %s isn't visited" filename)))))
 
@@ -1321,6 +1327,26 @@ DUMMY is ignored"
                                               "\n")))))
   nil)
 
+(defun eglot-imenu (oldfun)
+  "EGLOT's `imenu-create-index-function' overriding OLDFUN."
+  (if (eglot--server-capable :documentSymbolProvider)
+      (let ((entries
+             (eglot--mapply
+              (eglot--lambda (&key name kind location _containerName)
+                (cons (propertize name :kind (cdr (assoc kind 
eglot--kind-names)))
+                      (eglot--lsp-position-to-point
+                       (plist-get (plist-get location :range) :start))))
+              (eglot--sync-request
+               (eglot--current-process-or-lose)
+               :textDocument/documentSymbol
+               (eglot--obj
+                :textDocument 
(eglot--current-buffer-TextDocumentIdentifier))))))
+        (append
+         (seq-group-by (lambda (e) (get-text-property 0 :kind (car e)))
+                       entries)
+         entries))
+    (funcall oldfun)))
+
 
 ;;; Dynamic registration
 ;;;



reply via email to

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