[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] externals/eglot a4441c6 37/69: Merge master into jsonrpc-refactor
From: |
João Távora |
Subject: |
[elpa] externals/eglot a4441c6 37/69: Merge master into jsonrpc-refactor (using imerge) |
Date: |
Fri, 22 Jun 2018 11:55:00 -0400 (EDT) |
branch: externals/eglot
commit a4441c656df1206b60a7df1f57b5ea4db9efc828
Merge: f594dd7 327119e
Author: João Távora <address@hidden>
Commit: João Távora <address@hidden>
Merge master into jsonrpc-refactor (using imerge)
---
README.md | 46 +++++--
eglot-tests.el | 2 +-
eglot.el | 194 +++++++++++++++++++++-------
gif-examples/eglot-code-actions.gif | Bin 0 -> 24977 bytes
gif-examples/eglot-completions.gif | Bin 0 -> 63910 bytes
gif-examples/eglot-diagnostics.gif | Bin 0 -> 30912 bytes
gif-examples/eglot-hover-on-symbol.gif | Bin 0 -> 26701 bytes
gif-examples/eglot-rename.gif | Bin 0 -> 17781 bytes
gif-examples/eglot-xref-find-definition.gif | Bin 0 -> 31143 bytes
gif-examples/eglot-xref-find-references.gif | Bin 0 -> 46140 bytes
10 files changed, 186 insertions(+), 56 deletions(-)
diff --git a/README.md b/README.md
index c88f804..2ced833 100644
--- a/README.md
+++ b/README.md
@@ -1,10 +1,17 @@
[![Build
Status](https://travis-ci.org/joaotavora/eglot.png)](https://travis-ci.org/joaotavora/eglot)
+[![MELPA](http://melpa.org/packages/eglot-badge.svg)](http://melpa.org/#/eglot)
+
Eglot
-----
-*E*macs Poly*glot*. An Emacs client to [Language Server Protocol][lsp] servers.
+*E*macs Poly*glot*. Emacs client to [Language Server Protocol][lsp]
+servers. Scroll down this README for some
+[pretty gifs](#animated_gifs).
+
+# Installation and usage
-Eglot is [in ELPA][gnuelpa]. Installation is straightforward:
+Eglot is in both [ELPA][gnuelpa] and [MELPA][melpa]. Installation is
+straightforward:
```
(package-install 'eglot) ; Requires Emacs 26!
@@ -24,7 +31,6 @@ for the language of your choice. Otherwise, it prompts you to
enter one:
* PHP's [php-language-server][php-language-server]
* [cquery][cquery] for C/C++
-
I'll add to this list as I test more servers. In the meantime you can
customize `eglot-server-programs`:
@@ -48,6 +54,11 @@ Here's a summary of available commands:
- `M-x eglot-rename` asks the server to rename the symbol at point;
+- `M-x eglot-code-actions` asks the server for any code actions at
+ point. These may tipically be simple fixes, like deleting an unused
+ variable, or fixing an import. Left click on diagnostics to check if
+ there are any there;
+
- `M-x eglot-help-at-point` asks the server for help for symbol at
point. Currently this is what `eldoc-mode` displays in the echo
area;
@@ -111,7 +122,8 @@ eglot-shutdown`.
- [ ] workspace/didChangeConfiguration
- [ ] workspace/configuration (3.6.0)
- [x] workspace/didChangeWatchedFiles
-- [x] workspace/symbol is
+- [x] workspace/symbol
+- [x] workspace/executeCommand
- [x] workspace/applyEdit
## Text Synchronization
@@ -136,7 +148,7 @@ eglot-shutdown`.
- [x] textDocument/references
- [x] textDocument/documentHighlight
- [x] textDocument/documentSymbol
-- [ ] textDocument/codeAction
+- [x] textDocument/codeAction
- [ ] textDocument/codeLens
- [ ] codeLens/resolve
- [ ] textDocument/documentLink
@@ -148,6 +160,17 @@ eglot-shutdown`.
- [ ] textDocument/onTypeFormatting
- [x] textDocument/rename
+<a name="animated_gifs"></a>
+# _Obligatory animated gif section_
+
+![eglot-code-actions](./gif-examples/eglot-code-actions.gif)
+![eglot-completions](./gif-examples/eglot-completions.gif)
+![eglot-diagnostics](./gif-examples/eglot-diagnostics.gif)
+![eglot-hover-on-symbol](./gif-examples/eglot-hover-on-symbol.gif)
+![eglot-rename](./gif-examples/eglot-rename.gif)
+![eglot-xref-find-definition](./gif-examples/eglot-xref-find-definition.gif)
+![eglot-xref-find-references](./gif-examples/eglot-xref-find-references.gif)
+
# Differences to lsp-mode.el
Eglot is **beta**. It may currently underperform
@@ -179,22 +202,23 @@ Under the hood:
- Message parser is much simpler.
- Defers signature requests like `textDocument/hover` until server is
- ready. Also sends `textDocument/didChange` for groups of edits, not
+ ready.
+- Sends `textDocument/didChange` for groups of edits, not
one per each tiny change.
- Easier to read and maintain elisp. Yeah I know, *very subjective*,
so judge for yourself.
-- About 1k LOC lighter.
-- Development doesn't require Cask, just Emacs.
-- Project support doesn't need `projectile.el`, uses Emacs's `project.el`
-- Requires the upcoming Emacs 26
+- Doesn't *require* anything other than Emacs 26, but will
+ automatically upgrade to work with stuff outside Emacs, like
+ `company`, `markdown-mode`, if you happen to have these installed.
- Contained in one file
- Has automated tests that check against actual LSP servers
-
+
[lsp]: https://microsoft.github.io/language-server-protocol/
[rls]: https://github.com/rust-lang-nursery/rls
[pyls]: https://github.com/palantir/python-language-server
[gnuelpa]: https://elpa.gnu.org/packages/eglot.html
+[melpa]: http://melpa.org/#/eglot
[javascript-typescript-langserver]:
https://github.com/sourcegraph/javascript-typescript-langserver
[emacs-lsp]: https://github.com/emacs-lsp/lsp-mode
[emacs-lsp-plugins]: https://github.com/emacs-lsp
diff --git a/eglot-tests.el b/eglot-tests.el
index c9cc3fd..af8cc37 100644
--- a/eglot-tests.el
+++ b/eglot-tests.el
@@ -281,7 +281,7 @@ Pass TIMEOUT to `eglot--with-timeout'."
(string= method "textDocument/publishDiagnostics"))
(flymake-start)
(goto-char (point-min))
- (flymake-goto-next-error)
+ (flymake-goto-next-error 1 '() t)
(should (eq 'flymake-error (face-at-point))))))))
(ert-deftest rls-hover-after-edit ()
diff --git a/eglot.el b/eglot.el
index 3f82c89..d5498f9 100644
--- a/eglot.el
+++ b/eglot.el
@@ -2,7 +2,7 @@
;; Copyright (C) 2018 Free Software Foundation, Inc.
-;; Version: 0.7
+;; Version: 0.8
;; Author: João Távora <address@hidden>
;; Maintainer: João Távora <address@hidden>
;; URL: https://github.com/joaotavora/eglot
@@ -86,15 +86,15 @@ mode symbol. SPEC is
PROGRAM is called with ARGS and is expected to serve LSP requests
over the standard input/output channels.
-* A list (HOST PORT [ARGS...]) where HOST is a string and PORT is a
-positive integer number for connecting to a server via TCP.
+* A list (HOST PORT [ARGS...]) where HOST is a string and PORT is
+a positive integer number for connecting to a server via TCP.
Remaining ARGS are passed to `open-network-stream' for upgrading
-the connection with encryption, etc...
+the connection with encryption or other capabilities.
* A function of no arguments returning a connected process.
* A cons (CLASS-NAME . SPEC) where CLASS-NAME is a symbol
-designating a subclass of `eglot-lsp-server', for
+designating a subclass of symbol `eglot-lsp-server', for
representing experimental LSP servers. In this case SPEC is
interpreted as described above this point.")
@@ -120,13 +120,6 @@ lasted more than that many seconds."
(let ((b (cl-gensym)))
`(let ((,b ,buf)) (if (buffer-live-p ,b) (with-current-buffer ,b
,@body)))))
-(cl-defmacro eglot--lambda (cl-lambda-list &body body)
- "Make a unary function of ARG, a plist-like JSON object.
-CL-LAMBDA-LIST destructures ARGS before running BODY."
- (declare (indent 1) (debug (sexp &rest form)))
- (let ((e (gensym "eglot--lambda-elem")))
- `(lambda (,e) (apply (cl-function (lambda ,cl-lambda-list ,@body)) ,e))))
-
(cl-defmacro eglot--widening (&rest body)
"Save excursion and restriction. Widen. Then run BODY." (declare (debug t))
`(save-excursion (save-restriction (widen) ,@body)))
@@ -147,6 +140,8 @@ CL-LAMBDA-LIST destructures ARGS before running BODY."
(list
:workspace (list
:applyEdit t
+ :executeCommand `(:dynamicRegistration :json-false)
+ :codeAction `(:dynamicRegistration :json-false)
:workspaceEdit `(:documentChanges :json-false)
:didChangeWatchesFiles `(:dynamicRegistration t)
:symbol `(:dynamicRegistration :json-false))
@@ -250,7 +245,7 @@ function with the server still running."
(eglot--warn "Not auto-reconnecting, last one didn't last long."))))
(defun eglot--all-major-modes ()
- "Return all know major modes."
+ "Return all known major modes."
(let ((retval))
(mapatoms (lambda (sym)
(when (plist-member (symbol-plist sym) 'derived-mode-parent)
@@ -501,16 +496,26 @@ If optional MARKER, return a marker instead"
(ignore-errors (funcall mode))
(insert string) (font-lock-ensure) (buffer-string))))
+(defcustom eglot-ignored-server-capabilites (list)
+ "LSP server capabilities that Eglot could use, but won't.
+You could add, for instance, the symbol
+`:documentHighlightProvider' to prevent automatic highlighting
+under cursor."
+ :type '(repeat symbol))
+
(defun eglot--server-capable (&rest feats)
"Determine if current server is capable of FEATS."
- (cl-loop for caps = (eglot--capabilities
(jsonrpc-current-connection-or-lose))
- then (cadr probe)
- for feat in feats
- for probe = (plist-member caps feat)
- if (not probe) do (cl-return nil)
- if (eq (cadr probe) t) do (cl-return t)
- if (eq (cadr probe) :json-false) do (cl-return nil)
- finally (cl-return (or probe t))))
+ (unless (cl-some (lambda (feat)
+ (memq feat eglot-ignored-server-capabilites))
+ feats)
+ (cl-loop for caps = (eglot--capabilities
(jsonrpc-current-connection-or-lose))
+ then (cadr probe)
+ for feat in feats
+ for probe = (plist-member caps feat)
+ if (not probe) do (cl-return nil)
+ if (eq (cadr probe) t) do (cl-return t)
+ if (eq (cadr probe) :json-false) do (cl-return nil)
+ finally (cl-return (or probe t)))))
(defun eglot--range-region (range &optional markers)
"Return region (BEG . END) that represents LSP RANGE.
@@ -603,13 +608,16 @@ that case, also signal textDocument/didOpen."
(put 'eglot--mode-line-format 'risky-local-variable t)
-(defun eglot--mode-line-call (what)
+(defun eglot--mouse-call (what)
"Make an interactive lambda for calling WHAT from mode-line."
(lambda (event)
(interactive "e")
- (with-selected-window (posn-window (event-start event))
- (call-interactively what)
- (force-mode-line-update t))))
+ (let ((start (event-start event))) (with-selected-window (posn-window
start)
+ (save-excursion
+ (goto-char (or (posn-point start)
+ (point)))
+ (call-interactively what)
+ (force-mode-line-update t))))))
(defun eglot--mode-line-props (thing face defs &optional prepend)
"Helper for function `eglot--mode-line-format'.
@@ -617,7 +625,7 @@ Uses THING, FACE, DEFS and PREPEND."
(cl-loop with map = (make-sparse-keymap)
for (elem . rest) on defs
for (key def help) = elem
- do (define-key map `[mode-line ,key] (eglot--mode-line-call def))
+ do (define-key map `[mode-line ,key] (eglot--mouse-call def))
concat (format "%s: %s" key help) into blurb
when rest concat "\n" into blurb
finally (return `(:propertize ,thing
@@ -661,6 +669,21 @@ Uses THING, FACE, DEFS and PREPEND."
(add-to-list 'mode-line-misc-info
`(eglot--managed-mode (" [" eglot--mode-line-format "] ")))
+(put 'eglot-note 'flymake-category 'flymake-note)
+(put 'eglot-warning 'flymake-category 'flymake-warning)
+(put 'eglot-error 'flymake-category 'flymake-error)
+
+(defalias 'eglot--make-diag 'flymake-make-diagnostic)
+(defalias 'eglot--diag-data 'flymake-diagnostic-data)
+
+(dolist (type '(eglot-error eglot-warning eglot-note))
+ (put type 'flymake-overlay-control
+ `((mouse-face . highlight)
+ (keymap . ,(let ((map (make-sparse-keymap)))
+ (define-key map [mouse-1]
+ (eglot--mouse-call 'eglot-code-actions))
+ map)))))
+
;;; Protocol implementation (Requests, notifications, etc)
;;;
@@ -709,16 +732,16 @@ Uses THING, FACE, DEFS and PREPEND."
(with-current-buffer buffer
(cl-loop
for diag-spec across diagnostics
- collect (cl-destructuring-bind (&key range severity _group
+ collect (cl-destructuring-bind (&key range ((:severity sev)) _group
_code source message)
diag-spec
+ (setq message (concat source ": " message))
(pcase-let ((`(,beg . ,end) (eglot--range-region range)))
- (flymake-make-diagnostic (current-buffer)
- beg end
- (cond ((<= severity 1) :error)
- ((= severity 2) :warning)
- (t :note))
- (concat source ": " message))))
+ (eglot--make-diag (current-buffer) beg end
+ (cond ((<= sev 1) 'eglot-error)
+ ((= sev 2) 'eglot-warning)
+ (t 'eglot-note))
+ message `((eglot-lsp-diag .
,diag-spec)))))
into diags
finally (cond (eglot--current-flymake-report-fn
(funcall eglot--current-flymake-report-fn diags)
@@ -913,7 +936,7 @@ Calls REPORT-FN maybe if server publishes diagnostics in
time."
(defun eglot--xref-reset-known-symbols (&rest _dummy)
"Reset `eglot--xref-reset-known-symbols'.
-DUMMY is ignored"
+DUMMY is ignored."
(setq eglot--xref-known-symbols nil))
(advice-add 'xref-find-definitions :after #'eglot--xref-reset-known-symbols)
@@ -1018,7 +1041,9 @@ DUMMY is ignored"
(mapcar
(jsonrpc-lambda (&rest all &key label insertText
&allow-other-keys)
(let ((insert (or insertText label)))
- (add-text-properties 0 1 all insert) insert))
+ (add-text-properties 0 1 all insert)
+ (put-text-property 0 1 'eglot--lsp-completion all insert)
+ insert))
items))))
:annotation-function
(lambda (obj)
@@ -1037,13 +1062,15 @@ DUMMY is ignored"
(or (get-text-property 0 :sortText b) "")))))
:company-doc-buffer
(lambda (obj)
- (let ((documentation
- (or (get-text-property 0 :documentation obj)
- (and (eglot--server-capable :completionProvider
- :resolveProvider)
- (plist-get (jsonrpc-request server
:completionItem/resolve
- (text-properties-at 0
obj))
- :documentation)))))
+ (let* ((documentation
+ (or (get-text-property 0 :documentation obj)
+ (and (eglot--server-capable :completionProvider
+ :resolveProvider)
+ (plist-get
+ (jsonrpc-request server :completionItem/resolve
+ (get-text-property
+ 0 'eglot--lsp-completion obj))
+ :documentation)))))
(when documentation
(with-current-buffer (get-buffer-create " *eglot doc*")
(insert (eglot--format-markup documentation))
@@ -1205,6 +1232,7 @@ If SKIP-SIGNATURE, don't try to send
textDocument/signatureHelp."
(pop prepared))))
(if prepared (eglot--warn "Caution: edits of files %s failed."
(mapcar #'car prepared))
+ (eglot-eldoc-function)
(eglot--message "Edit successful!"))))))
(defun eglot-rename (newname)
@@ -1219,6 +1247,50 @@ If SKIP-SIGNATURE, don't try to send
textDocument/signatureHelp."
:newName ,newname))
current-prefix-arg))
+
+(defun eglot-code-actions (&optional beg end)
+ "Get and offer to execute code actions between BEG and END."
+ (interactive
+ (let (diags)
+ (cond ((region-active-p) (list (region-beginning) (region-end)))
+ ((setq diags (flymake-diagnostics (point)))
+ (list (cl-reduce #'min (mapcar #'flymake-diagnostic-beg diags))
+ (cl-reduce #'max (mapcar #'flymake-diagnostic-end diags))))
+ (t (list (point-min) (point-max))))))
+ (unless (eglot--server-capable :codeActionProvider)
+ (eglot--error "Server can't execute code actions!"))
+ (let* ((server (jsonrpc-current-connection-or-lose))
+ (actions (jsonrpc-request
+ server
+ :textDocument/codeAction
+ (list :textDocument (eglot--TextDocumentIdentifier)
+ :range (list :start (eglot--pos-to-lsp-position beg)
+ :end (eglot--pos-to-lsp-position end))
+ :context
+ `(:diagnostics
+ [,@(mapcar (lambda (diag)
+ (cdr (assoc 'eglot-lsp-diag
+ (eglot--diag-data diag))))
+ (flymake-diagnostics beg end))]))))
+ (menu-items (mapcar (jsonrpc-lambda (&key title command arguments)
+ `(,title . (:command ,command :arguments
,arguments)))
+ actions))
+ (menu (and menu-items `("Eglot code actions:" ("dummy"
,@menu-items))))
+ (command-and-args
+ (and menu
+ (if (listp last-nonmenu-event)
+ (x-popup-menu last-nonmenu-event menu)
+ (let ((never-mind (gensym)) retval)
+ (setcdr (cadr menu)
+ (cons `("never mind..." . ,never-mind) (cdadr
menu)))
+ (if (eq (setq retval (tmm-prompt menu)) never-mind)
+ (keyboard-quit)
+ retval))))))
+ (if command-and-args
+ (jsonrpc-request server :workspace/executeCommand command-and-args)
+ (eglot--message "No code actions here"))))
+
+
;;; Dynamic registration
;;;
@@ -1291,8 +1363,8 @@ If SKIP-SIGNATURE, don't try to send
textDocument/signatureHelp."
"Passes through required cquery initialization options"
(let* ((root (car (project-roots (eglot--project server))))
(cache (expand-file-name ".cquery_cached_index/" root)))
- (vector :cacheDirectory (file-name-as-directory cache)
- :progressReportFrequencyMs -1)))
+ (list :cacheDirectory (file-name-as-directory cache)
+ :progressReportFrequencyMs -1)))
(cl-defmethod eglot-handle-notification
((_server eglot-cquery) (_method (eql :$cquery/progress))
@@ -1309,6 +1381,40 @@ If SKIP-SIGNATURE, don't try to send
textDocument/signatureHelp."
&key _uri _symbols &allow-other-keys)
"No-op for unsupported $cquery/publishSemanticHighlighting extension")
+
+;; FIXME: A horrible hack of Flymake's insufficient API that must go
+;; into Emacs master, or better, 26.2
+(when (version< emacs-version "27.0")
+ (cl-defstruct (eglot--diag (:include flymake--diag)
+ (:constructor eglot--make-diag-1))
+ data-1)
+ (defsubst eglot--make-diag (buffer beg end type text data)
+ (let ((sym (alist-get type eglot--diag-error-types-to-old-types)))
+ (eglot--make-diag-1 :buffer buffer :beg beg :end end :type sym
+ :text text :data-1 data)))
+ (defsubst eglot--diag-data (diag)
+ (and (eglot--diag-p diag) (eglot--diag-data-1 diag)))
+ (defvar eglot--diag-error-types-to-old-types
+ '((eglot-error . :error)
+ (eglot-warning . :warning)
+ (eglot-note . :note)))
+ (advice-add
+ 'flymake--highlight-line :after
+ (lambda (diag)
+ (when (eglot--diag-p diag)
+ (let ((ov (cl-find diag
+ (overlays-at (flymake-diagnostic-beg diag))
+ :key (lambda (ov)
+ (overlay-get ov 'flymake-diagnostic))))
+ (overlay-properties
+ (get (car (rassoc (flymake-diagnostic-type diag)
+ eglot--diag-error-types-to-old-types))
+ 'flymake-overlay-control)))
+ (cl-loop for (k . v) in overlay-properties
+ do (overlay-put ov k v)))))
+ '((name . eglot-hacking-in-some-per-diag-overlay-properties))))
+
+
(provide 'eglot)
;;; eglot.el ends here
diff --git a/gif-examples/eglot-code-actions.gif
b/gif-examples/eglot-code-actions.gif
new file mode 100644
index 0000000..c5b002d
Binary files /dev/null and b/gif-examples/eglot-code-actions.gif differ
diff --git a/gif-examples/eglot-completions.gif
b/gif-examples/eglot-completions.gif
new file mode 100644
index 0000000..53e5a56
Binary files /dev/null and b/gif-examples/eglot-completions.gif differ
diff --git a/gif-examples/eglot-diagnostics.gif
b/gif-examples/eglot-diagnostics.gif
new file mode 100644
index 0000000..5822a4b
Binary files /dev/null and b/gif-examples/eglot-diagnostics.gif differ
diff --git a/gif-examples/eglot-hover-on-symbol.gif
b/gif-examples/eglot-hover-on-symbol.gif
new file mode 100644
index 0000000..360255e
Binary files /dev/null and b/gif-examples/eglot-hover-on-symbol.gif differ
diff --git a/gif-examples/eglot-rename.gif b/gif-examples/eglot-rename.gif
new file mode 100644
index 0000000..9d59946
Binary files /dev/null and b/gif-examples/eglot-rename.gif differ
diff --git a/gif-examples/eglot-xref-find-definition.gif
b/gif-examples/eglot-xref-find-definition.gif
new file mode 100644
index 0000000..92833fb
Binary files /dev/null and b/gif-examples/eglot-xref-find-definition.gif differ
diff --git a/gif-examples/eglot-xref-find-references.gif
b/gif-examples/eglot-xref-find-references.gif
new file mode 100644
index 0000000..1679cf5
Binary files /dev/null and b/gif-examples/eglot-xref-find-references.gif differ
- [elpa] externals/eglot 9e9dc57 30/69: Merge branch 'master' into jsonrpc-refactor (using regular merge), (continued)
- [elpa] externals/eglot 9e9dc57 30/69: Merge branch 'master' into jsonrpc-refactor (using regular merge), João Távora, 2018/06/22
- [elpa] externals/eglot 6c9d41e 38/69: Add reasonably sophisticated deferred action tests, João Távora, 2018/06/22
- [elpa] externals/eglot 2da7d92 50/69: Simplify JSONRPC status setting, João Távora, 2018/06/22
- [elpa] externals/eglot 69a622a 64/69: Fix some typos, João Távora, 2018/06/22
- [elpa] externals/eglot 7371f68 57/69: * jsonrpc.el: Rewrite commentary., João Távora, 2018/06/22
- [elpa] externals/eglot 6531c8b 58/69: Merge branch 'master' into jsonrpc-refactor, João Távora, 2018/06/22
- [elpa] externals/eglot 59cc3fb 61/69: jsonrpc-connection-receive is now a public convenience function, João Távora, 2018/06/22
- [elpa] externals/eglot d371f05 49/69: Request dispatcher's return value determines response, João Távora, 2018/06/22
- [elpa] externals/eglot 0f20fdf 68/69: Tiny README.md change, João Távora, 2018/06/22
- [elpa] externals/eglot cef3c29 22/69: Heroically merge master into jsonrpc-refactor (using imerge), João Távora, 2018/06/22
- [elpa] externals/eglot a4441c6 37/69: Merge master into jsonrpc-refactor (using imerge),
João Távora <=
- [elpa] externals/eglot 0e44b27 27/69: jsonrpc.el uses classes and generic functions, João Távora, 2018/06/22
- [elpa] externals/eglot 856a224 62/69: Simplify jsonrpc-connection-send, João Távora, 2018/06/22
- [elpa] externals/eglot 1f09fd3 59/69: Review commentary section before another review cycle, João Távora, 2018/06/22
- [elpa] externals/eglot 8fda30c 67/69: Merge master into jsonrpc-refactor (using imerge), João Távora, 2018/06/22
- [elpa] externals/eglot 7f4e273 31/69: Merge master into jsonrpc-refactor (using imerge), João Távora, 2018/06/22
- [elpa] externals/eglot 4525eca 43/69: Support json.c. API purely based on classes, João Távora, 2018/06/22
- [elpa] externals/eglot bb60c0c 21/69: Rename jrpc.el to jsonrpc.el, João Távora, 2018/06/22
- [elpa] externals/eglot 46e6107 54/69: Reshuffle definitions inside jsonrpc.el, João Távora, 2018/06/22
- [elpa] externals/eglot 6f1ecc6 28/69: Merge branch use-eieio-server-defclass into jsonrpc-refactor, João Távora, 2018/06/22
- [elpa] externals/eglot 10559a5 56/69: Shuffle definitions around again, João Távora, 2018/06/22