[elpa] externals/eglot 3403f86 027/139: Correctly report what we currently are capable of

2018-05-14 Thread Jo�o T�vora
branch: externals/eglot
commit 3403f86ea50bc7562b02df86509f7ca70e14c22e
Author: João Távora 
Commit: João Távora 

Correctly report what we currently are capable of

Which is almost nothing.

* eglot.el (eglot--protocol-initialize): Clean up.
---
 eglot.el | 19 +++
 1 file changed, 11 insertions(+), 8 deletions(-)

diff --git a/eglot.el b/eglot.el
index db594f4..1f2737e 100644
--- a/eglot.el
+++ b/eglot.el
@@ -459,20 +459,23 @@ INTERACTIVE is t if caller was called interactively."
   (eglot--request
process
:initialize
-   `(:processId  ,(emacs-pid)
- :rootPath  ,(concat 
-  (expand-file-name (car (project-roots
-  (project-current)
- :initializationOptions  []
- :capabilities (:workspace (:executeCommand 
(:dynamicRegistration t))
-   :textDocument (:synchronization 
(:didSave t
+   (eglot--obj :processId  (emacs-pid)
+   :rootPath  (concat
+   (expand-file-name (car (project-roots
+   (project-current)
+   :initializationOptions  []
+   :capabilities
+   (eglot--obj
+:workspace (eglot--obj)
+:textDocument (eglot--obj
+   :publishDiagnostics `(:relatedInformation t
:success-fn (cl-function
 (lambda ( capabilities)
   (setf (eglot--capabilities process) capabilities)
   (when interactive
 (setf (eglot--status process) nil)
 (eglot--message
- "So yeah I got lots (%d) of capabilities"
+ "Server reports %d capabilities"
  (length capabilities)))
 
 (defun eglot-quit-server (process  sync interactive)



[elpa] externals/eglot c417eb4 009/139: Cancel timeouts when process dies unexpectedly

2018-05-14 Thread Jo�o T�vora
branch: externals/eglot
commit c417eb4343ff76c18d323dd2a9861526940551f0
Author: João Távora 
Commit: João Távora 

Cancel timeouts when process dies unexpectedly
---
 eglot.el | 53 -
 1 file changed, 32 insertions(+), 21 deletions(-)

diff --git a/eglot.el b/eglot.el
index e3b288b..5699775 100644
--- a/eglot.el
+++ b/eglot.el
@@ -153,9 +153,16 @@
   (with-current-buffer (process-buffer process)
 (eglot--debug "Process state changed to %s" change)
 (when (not (process-live-p process))
+  ;; Remember to cancel all timers
+  ;;
+  (maphash (lambda (id v) 
+ (cl-destructuring-bind (_success _error timeout) v
+   (eglot--message "Cancelling timer for continuation %s" id)
+   (cancel-timer timeout)))
+   (eglot--pending-continuations process))
   (cond ((process-get process 'eglot--moribund)
  (eglot--message "Process exited with status %s"
-  (process-exit-status process)))
+ (process-exit-status process)))
 (t
  (eglot--warn "Process unexpectedly changed to %s" change))
 
@@ -319,26 +326,30 @@
   :method  ,method
   :params  ,params))
 (catch catch-tag
-  (puthash id
-   (list (if async-p
- success-fn
-   (lambda ( args)
- (throw catch-tag (apply success-fn args
- (if async-p
- error-fn
-   (lambda ( args)
- (throw catch-tag (apply error-fn args
- (run-with-timer 5 nil
- (if async-p
- timeout-fn
-   (lambda ()
- (throw catch-tag (apply 
timeout-fn))
-   (eglot--pending-continuations process))
-  (unless async-p
-(while t
-  (unless (eq (process-status process) 'open)
-(eglot--error "Process %s died unexpectedly" process))
-  (accept-process-output nil 0.01))
+  (let ((timeout-timer
+ (run-with-timer 5 nil
+ (if async-p
+ timeout-fn
+   (lambda ()
+ (throw catch-tag (apply timeout-fn)))
+(puthash id
+ (list (if async-p
+   success-fn
+ (lambda ( args)
+   (throw catch-tag (apply success-fn args
+   (if async-p
+   error-fn
+ (lambda ( args)
+   (throw catch-tag (apply error-fn args
+   timeout-timer)
+ (eglot--pending-continuations process))
+(unless async-p
+  (unwind-protect
+  (while t
+(unless (process-live-p process)
+  (eglot--error "Process %s died unexpectedly" process))
+(accept-process-output nil 0.01))
+(cancel-timer timeout-timer)))
 
 
 ;;; Requests



[elpa] externals/eglot c948713 035/139: Auto-reconnect on unexpected connection loss

2018-05-14 Thread Jo�o T�vora
branch: externals/eglot
commit c948713b050fe209572b362799ae688d1c0629f6
Author: João Távora 
Commit: João Távora 

Auto-reconnect on unexpected connection loss

* eglot.el (eglot-reconnect): Only quit if indeed not quit
already.
(eglot-new-process): Burn the command in the bootstrap fn.
(eglot--process-sentinel): Automatically reconnect if closed
unexpectedly.
(eglot--warn): Also message to *Messages*
---
 eglot.el | 23 ++-
 1 file changed, 14 insertions(+), 9 deletions(-)

diff --git a/eglot.el b/eglot.el
index aa23252..71dab80 100644
--- a/eglot.el
+++ b/eglot.el
@@ -162,7 +162,8 @@ Call SUCCESS-FN with no args if all goes well."
   "Reconnect to PROCESS.
 INTERACTIVE is t if called interactively."
   (interactive (list (eglot--current-process-or-lose) t))
-  (eglot-quit-server process 'sync interactive)
+  (when (process-live-p process)
+(eglot-quit-server process 'sync interactive))
   (eglot--connect (eglot--short-name process)
   (eglot--bootstrap-fn process)
   (lambda ()
@@ -174,7 +175,12 @@ INTERACTIVE is t if called interactively."
   (interactive (list t))
   (let ((project (project-current)))
 (unless project (eglot--error "(new-process) Cannot work without a current 
project!"))
-(let ((current-process (eglot--current-process)))
+(let ((current-process (eglot--current-process))
+  (command (let ((probe (cdr (assoc major-mode eglot-executables
+ (unless probe
+   (eglot--error "Don't know how to start EGLOT for %s 
buffers"
+ major-mode))
+ probe)))
   (cond ((and current-process
   (process-live-p current-process))
  (eglot--message "(new-process) Reconnecting instead")
@@ -187,11 +193,7 @@ INTERACTIVE is t if called interactively."
   (lambda (name)
 (eglot-make-local-process
  name
- (let ((probe (cdr (assoc major-mode eglot-executables
-   (unless probe
- (eglot--error "Don't know how to start EGLOT for %s 
buffers"
-   major-mode))
-   probe)))
+ command))
   (lambda ()
 (eglot--message "Connected")
 (dolist (buffer (buffer-list))
@@ -221,8 +223,10 @@ INTERACTIVE is t if called interactively."
(eglot--message "(sentinel) Moribund process exited with status %s"
(process-exit-status process)))
   (t
-   (eglot--warn "(sentinel) Process unexpectedly changed to %s"
-change)))
+   (eglot--warn
+"(sentinel) Reconnecting after process unexpectedly changed to %s."
+change)
+   (eglot-reconnect process)))
 (delete-process process)))
 
 (defun eglot--process-filter (proc string)
@@ -633,6 +637,7 @@ running.  INTERACTIVE is t if called interactively."
 
 (defun eglot--warn (format  args)
   "Warning message with FORMAT and ARGS."
+  (apply #'eglot--message (concat "(warning) " format) args)
   (let ((warning-minimum-level :error))
 (display-warning 'eglot
  (apply #'format format args)



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

2018-05-14 Thread Jo�o T�vora
branch: externals/eglot
commit c4ffabcb5f95d8d2a3676006641362e188df52f8
Author: João Távora 
Commit: João Távora 

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 ( 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)
+ 

[elpa] externals/elpa c7b9002 116/139: Only call deferred actions after a full message has been received

2018-05-14 Thread Jo�o T�vora
branch: externals/elpa
commit c7b90028bcdc52001849da5355ce48e03caca0f7
Author: João Távora 
Commit: João Távora 

Only call deferred actions after a full message has been received

Otherwise it can be quite wasteful.

* eglot.el (eglot--process-filter): Don't eglot--call-deferred here.
(eglot--process-receive): Do it here.
---
 eglot.el | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/eglot.el b/eglot.el
index d49367b..8b8d712 100644
--- a/eglot.el
+++ b/eglot.el
@@ -380,6 +380,7 @@ INTERACTIVE is t if called interactively."
   "(sentinel) Not auto-reconnecting, last one didn't last long."
   change)))
   (delete-process proc
+
 (defun eglot--process-filter (proc string)
   "Called when new data STRING has arrived for PROC."
   (when (buffer-live-p (process-buffer proc))
@@ -441,8 +442,7 @@ INTERACTIVE is t if called interactively."
   (throw done 
:waiting-for-more-bytes-in-this-message
   ;; Saved parsing state for next visit to this filter
   ;;
-  (setf (eglot--expected-bytes proc) expected-bytes
-(eglot--call-deferred proc)))
+  (setf (eglot--expected-bytes proc) expected-bytes))
 
 (defun eglot-events-buffer (process  interactive)
   "Display events buffer for current LSP connection PROCESS.
@@ -522,6 +522,7 @@ is a symbol saying if this is a client or server 
originated."
  (funcall (cl-first continuations) res)
   (id
(eglot--warn "Ooops no continuation for id %s" id)))
+(eglot--call-deferred proc)
 (force-mode-line-update t)))
 
 (defvar eglot--expect-carriage-return nil)



[elpa] externals/eglot e9b5e54 077/139: ETOOMANYLAMBDAS

2018-05-14 Thread Jo�o T�vora
branch: externals/eglot
commit e9b5e548be6f49bc81b6499d247b56f8b02bd635
Author: João Távora 
Commit: João Távora 

ETOOMANYLAMBDAS

* eglot.el (eglot--sync-request): Remove a lambda.
---
 eglot.el | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/eglot.el b/eglot.el
index d6ecdfe..321307d 100644
--- a/eglot.el
+++ b/eglot.el
@@ -663,9 +663,8 @@ Meaning only return locally if successful, otherwise exit 
non-locally."
  (lambda ( code message )
(eglot--error "Oops: %s: %s" code message)))
   :timeout-fn (lambda ()
-(lambda ()
-  (eglot--error
-   "Tired of waiting for reply to sync 
request")))
+(eglot--error
+ "Tired of waiting for reply to sync request"))
   :async-p nil))
 
 (cl-defun eglot--notify (process method params)



[elpa] externals/eglot 1fb2bcb 132/139: Ask server for textDocument/signatureHelp if it supports it

2018-05-14 Thread Jo�o T�vora
branch: externals/eglot
commit 1fb2bcbde95d89edd9df638869d679e42b416b4c
Author: João Távora 
Commit: João Távora 

Ask server for textDocument/signatureHelp if it supports it

* eglot.el (eglot--client-capabilities): Capable of signature Help.
(eglot--sig-info): Helper for eglot-eldoc-function.
(eglot-eldoc-function): Send textDocument/signatureHelp

* README.md: Update to mention textDocument/signatureHelp
---
 README.md |  2 +-
 eglot.el  | 97 ---
 2 files changed, 69 insertions(+), 30 deletions(-)

diff --git a/README.md b/README.md
index 4dfe0a6..39ec752 100644
--- a/README.md
+++ b/README.md
@@ -103,7 +103,7 @@ either:
 - [x] textDocument/completion
 - [x] completionItem/resolve (works quite well with 
[company-mode][company-mode])
 - [x] textDocument/hover
-- [ ] textDocument/signatureHelp
+- [x] textDocument/signatureHelp (fancy stuff with Python's [pyls[pyls]])
 - [x] textDocument/definition
 - [ ] textDocument/typeDefinition (3.6.0)
 - [ ] textDocument/implementation (3.6.0)
diff --git a/eglot.el b/eglot.el
index f6eabe1..2e872dc 100644
--- a/eglot.el
+++ b/eglot.el
@@ -211,6 +211,7 @@ CONTACT is as `eglot--contact'.  Returns a process object."
 :didSave t)
   :completion `(:dynamicRegistration :json-false)
   :hover  `(:dynamicRegistration :json-false)
+  :signatureHelp  `(:dynamicRegistration :json-false)
   :references `(:dynamicRegistration :json-false)
   :definition `(:dynamicRegistration :json-false)
   :documentSymbol `(:dynamicRegistration :json-false)
@@ -1330,6 +1331,28 @@ DUMMY is ignored"
 (contents
  (list contents "\n")))
 
+(defun eglot--sig-info (sigs active-sig active-param)
+  (cl-loop
+   for (sig . moresigs) on (append sigs nil) for i from 0
+   concat (cl-destructuring-bind ( label _documentation parameters) sig
+(let (active-doc)
+  (concat
+   (propertize (replace-regexp-in-string "(.*$" "(" label)
+   'face 'font-lock-function-name-face)
+   (cl-loop
+for (param . moreparams) on (append parameters nil) for j from 0
+concat (cl-destructuring-bind ( label documentation) param
+ (when (and (eql j active-param) (eql i active-sig))
+   (setq label (propertize
+label
+'face 
'eldoc-highlight-function-argument))
+   (when documentation
+ (setq active-doc (concat label ": " 
documentation
+ label)
+if moreparams concat ", " else concat ")")
+   (when active-doc (concat "\n" active-doc)
+   when moresigs concat "\n"))
+
 (defun eglot-help-at-point ()
   "Request \"hover\" information for the thing at point."
   (interactive)
@@ -1342,35 +1365,51 @@ DUMMY is ignored"
 (insert (eglot--hover-info contents range))
 
 (defun eglot-eldoc-function ()
-  "EGLOT's `eldoc-documentation-function' function."
-  (let ((buffer (current-buffer))
-(proc (eglot--current-process-or-lose))
-(position-params (eglot--TextDocumentPositionParams)))
-(when (eglot--server-capable :hoverProvider)
-  (eglot--async-request
-   proc :textDocument/hover position-params
-   :success-fn (eglot--lambda ( contents range)
- (when (get-buffer-window buffer)
-   (with-current-buffer buffer
- (eldoc-message (eglot--hover-info contents range)
-   :deferred :textDocument/hover))
-(when (eglot--server-capable :documentHighlightProvider)
-  (eglot--async-request
-   proc :textDocument/documentHighlight position-params
-   :success-fn (lambda (highlights)
- (mapc #'delete-overlay eglot--highlights)
- (setq eglot--highlights
-   (when (get-buffer-window buffer)
- (with-current-buffer buffer
-   (eglot--mapply
-(eglot--lambda ( range _kind)
-  (eglot--with-lsp-range (beg end) range
-(let ((ov (make-overlay beg end)))
-  (overlay-put ov 'face 'highlight)
-  (overlay-put ov 'evaporate t)
-  ov)))
-highlights)
-   :deferred :textDocument/documentHighlight)))
+  "EGLOT's `eldoc-documentation-function' function.
+If SKIP-SIGNATURE, don't try 

[elpa] externals/eglot 1514e0f 052/139: Fix a couple of Rust-related edge cases

2018-05-14 Thread Jo�o T�vora
branch: externals/eglot
commit 1514e0f4709c915426748ca764900edfb38f8acc
Author: João Távora 
Commit: João Távora 

Fix a couple of Rust-related edge cases

* eglot.el (eglot--server-window/progress): Allow other keys.
(eglot--server-textDocument/publishDiagnostics): Allow :group in diagnostic
spec.
---
 eglot.el | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/eglot.el b/eglot.el
index 1bf0d56..e7fe18c 100644
--- a/eglot.el
+++ b/eglot.el
@@ -843,7 +843,7 @@ running.  INTERACTIVE is t if called interactively."
   (line-beginning-position
  (point
   (cl-loop for diag-spec across diagnostics
-   collect (cl-destructuring-bind ( range severity
+   collect (cl-destructuring-bind ( range severity _group
 _code _source message)
diag-spec
  (cl-destructuring-bind ( start end)
@@ -1002,7 +1002,7 @@ Calls REPORT-FN maybe if server publishes diagnostics in 
time."
 ;;; Rust-specific
 ;;;
 (cl-defun eglot--server-window/progress
-(process  id done title )
+(process  id done title )
   "Handle notification window/progress"
   (setf (eglot--spinner process) (list id title done)))
 



[elpa] externals/elpa bfd82b5 108/139: Fancier RLS spinner

2018-05-14 Thread Jo�o T�vora
branch: externals/elpa
commit bfd82b55d4ab7bb846f9f728e0b5693c487eb307
Author: João Távora 
Commit: João Távora 

Fancier RLS spinner

* eglot.el (eglot--mode-line-format): Use (nth 3) of
eglot--spinner.
(eglot--server-window/progress): Save detail message in spinner.
---
 eglot.el | 12 +++-
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/eglot.el b/eglot.el
index 9a0b824..4739cea 100644
--- a/eglot.el
+++ b/eglot.el
@@ -869,7 +869,7 @@ Uses THING, FACE, DEFS and PREPEND."
(name (and (process-live-p proc) (eglot--short-name proc)))
(pending (and proc (hash-table-count
(eglot--pending-continuations proc
-   (`(,_id ,doing ,done-p) (and proc (eglot--spinner proc)))
+   (`(,_id ,doing ,done-p ,detail) (and proc (eglot--spinner 
proc)))
(`(,status ,serious-p) (and proc (eglot--status proc
 (append
  `(,(eglot--mode-line-props "eglot" 'eglot-mode-line
@@ -888,7 +888,9 @@ Uses THING, FACE, DEFS and PREPEND."
  (format "An error occured: %s\n" status
  ,@(when (and doing (not done-p))
  `("/" ,(eglot--mode-line-props
- doing 'compilation-mode-line-run
+ (format "%s%s" doing
+ (if detail (format ":%s" detail) ""))
+ 'compilation-mode-line-run
  '((mouse-1 eglot-events-buffer "go to events buffer")
  ,@(when (cl-plusp pending)
  `("/" ,(eglot--mode-line-props
@@ -1460,7 +1462,7 @@ Proceed? "
   "Guess if the RLS running in PROC is ready for WHAT."
   (or (eq what :textDocument/completion) ; RLS normally ready for this
 ; one, even if building
-  (pcase-let ((`(,_id ,what ,done) (eglot--spinner proc)))
+  (pcase-let ((`(,_id ,what ,done ,_detail) (eglot--spinner proc)))
 (and (equal "Indexing" what) done
 
 (add-hook 'rust-mode-hook 'eglot--setup-rls-idiosyncrasies)
@@ -1470,9 +1472,9 @@ Proceed? "
   (add-hook 'eglot--ready-predicates 'eglot--rls-probably-ready-for-p t t))
 
 (cl-defun eglot--server-window/progress
-(process  id done title )
+(process  id done title message )
   "Handle notification window/progress"
-  (setf (eglot--spinner process) (list id title done)))
+  (setf (eglot--spinner process) (list id title done message)))
 
 (provide 'eglot)
 ;;; eglot.el ends here



[elpa] externals/eglot dfab9a0 011/139: Experimental diagnostic overlays

2018-05-14 Thread Jo�o T�vora
branch: externals/eglot
commit dfab9a08a6b6af099c21f9cd8a99f5a00d81cb4e
Author: João Távora 
Commit: João Távora 

Experimental diagnostic overlays
---
 eglot.el | 40 ++--
 1 file changed, 38 insertions(+), 2 deletions(-)

diff --git a/eglot.el b/eglot.el
index 479e87a..cd91d78 100644
--- a/eglot.el
+++ b/eglot.el
@@ -414,11 +414,47 @@
 
 ;;; Notifications
 ;;;
+(defvar-local eglot--diagnostic-overlays nil)
+
 (cl-defun eglot--textDocument/publishDiagnostics
 (_process  uri diagnostics)
   "Handle notification publishDiagnostics"
-  (eglot--message "So yeah I got %s for %s"
-  diagnostics uri))
+  (let* ((obj (url-generic-parse-url uri))
+(filename (car (url-path-and-query obj)))
+ (buffer (find-buffer-visiting filename)))
+(cond
+ (buffer
+  (with-current-buffer buffer
+(eglot--message "OK so add some %s diags" (length diagnostics))
+(mapc #'delete-overlay eglot--diagnostic-overlays)
+(setq eglot--diagnostic-overlays nil)
+(cl-flet ((pos-at (pos-plist)
+  (save-excursion
+(goto-char (point-min))
+(forward-line (plist-get pos-plist :line))
+(forward-char (plist-get pos-plist :character))
+(point
+  (loop for diag across diagnostics
+do (cl-destructuring-bind ( range severity
+_code _source message)
+   diag
+ (cl-destructuring-bind ( start end)
+ range
+   (let* ((begin-pos (pos-at start))
+  (end-pos (pos-at end))
+  (ov (make-overlay begin-pos
+end-pos
+buffer)))
+ (push ov eglot--diagnostic-overlays)
+ (overlay-put ov 'face
+  (case severity
+(1 'flymake-errline)
+(2 'flymake-warnline)))
+ (overlay-put ov 'help-echo
+  message)
+ (overlay-put ov 'eglot--diagnostic diag
+ (t
+  (eglot--message "OK so %s isn't visited" filename)
 
 
 ;;; Helpers



[elpa] externals/elpa ecd334f 101/139: Update README

2018-05-14 Thread Jo�o T�vora
branch: externals/elpa
commit ecd334f6466b0a1488735e4cb6d41ab4fa65660f
Author: João Távora 
Commit: João Távora 

Update README
---
 README.md | 115 +-
 1 file changed, 84 insertions(+), 31 deletions(-)

diff --git a/README.md b/README.md
index a8d1c8b..faf2dea 100644
--- a/README.md
+++ b/README.md
@@ -2,19 +2,21 @@
 Eglot
 -
 
-*E*macs Poly*glot*. An Emacs client to Language Server Protocol servers.
+*E*macs Poly*glot*. An Emacs client to [Language Server Protocol][lsp] servers.
 
 ```
 (add-to-list 'load-path "/path/to/eglot")
-(require 'eglot)
+(require 'eglot) ; Requires emacs 26!
 
+;; Now find some project file inside some Git-controlled dir
 M-x eglot
 ```
 
-*That's it*. Either this guesses the local LSP program to start for
-the language of your choice or it prompts you for such a
-thing. Currently, if you have these programs installed, it works
-out-of-the-box for:
+*That's it*. Either this guesses the LSP executable to start for the
+language of your choice, or it prompts you to enter the program.
+
+If you have these programs installed, `M-x eglot` works out-of-the-box
+with:
 
 * Javascript's [javascript-typescript-stdio][javascript-typescript-langserver]
 * Rust's [rls][rls]
@@ -25,60 +27,111 @@ server. To skip the guess and always be prompted use `C-u 
M-x eglot`.
 
 # Supported Protocol features
 
-- [x] textDocument/didChange (incremental)
-- [x] textDocument/didClose
+## General
+- [x] initialize
+- [x] initalized
+- [x] shutdown
+- [x] exit
+- [ ] $/cancelRequest
+
+## Window
+- [x] window/showMessage
+- [x] window/showMessageRequest
+- [x] window/logMessage
+- [x] telemetry/event
+
+## Client
+- [ ] client/registerCapability
+- [ ] client/unregisterCapability
+
+## Workspace
+- [ ] workspace/workspaceFolders (3.6.0)
+- [ ] workspace/didChangeWorkspaceFolders (3.6.0)
+- [ ] workspace/didChangeConfiguration
+- [ ] workspace/configuration (3.6.0)
+- [ ] workspace/didChangeWatchedFiles
+- [x] workspace/symbol
+- [x] workspace/applyEdit
+
+## Text Synchronization
 - [x] textDocument/didOpen
+- [x] textDocument/didChange (incremental or full)
+- [x] textDocument/willSave
+- [ ] textDocument/willSaveWaitUntil
 - [x] textDocument/didSave
+- [x] textDocument/didClose
 
-- [ ] textDocument/codeAction
+## Diagnostics
+- [x] textDocument/publishDiagnostics
+
+## Language features
 - [x] textDocument/completion
 - [ ] completionItem/resolve
+- [x] textDocument/hover
+- [ ] textDocument/signatureHelp
 - [x] textDocument/definition
+- [ ] textDocument/typeDefinition (3.6.0)
+- [ ] textDocument/implementation (3.6.0)
+- [x] textDocument/references
 - [x] textDocument/documentHighlight
 - [x] textDocument/documentSymbol
-- [ ] textDocument/executeCommand
-- [ ] textDocument/format
-- [x] textDocument/hover
+- [ ] textDocument/codeAction
+- [ ] textDocument/codeLens
+- [ ] codeLens/resolve
+- [ ] textDocument/documentLink
+- [ ] documentLink/resolve
+- [ ] textDocument/documentColor
+- [ ] textDocument/colorPresentation (3.6.0)
+- [ ] textDocument/formatting 
+- [ ] textDocument/rangeFormatting
+- [ ] textDocument/onTypeFormatting
 - [x] textDocument/rename
-- [x] textDocument/references
-- [ ] textDocument/signatureHelp
-- [x] workspace/symbol
 
 # Differences to lsp-mode.el
 
-This is really beta and currently does a little less than
-[lsp-mode.el][emacs-lsp] which is more mature. Though I think
-`eglot.el` will eventually beat it, you could be better served with
+Eglot is **really beta** and may currently underperform
+[lsp-mode.el][emacs-lsp], which is more mature and has a host of
+[plugins][emacs-lsp-plugins] for bells and whistles.  If you think the 
minimalist approach
+of `eglot.el` is not for you, you could be better served with
 `lsp-mode.el` for now.
 
 User-visible differences:
 
-- Single entry point, `M-x eglot` to enable LSP in a project.
-  Automatically detects current and future opened files under that
+- Single entry point `M-x eglot`, not `M-x eglot-`. Also no
+  `eglot-` extra packages.
+- No "whitelisting" or "blacklisting" directories to languages. `M-x
+  eglot` starts servers to handle major modes inside a specific
+  project. Uses Emacs's built-in `project.el` library to discover
+  projects. Automatically detects current and future opened files under that
   project and syncs with server.
 - Easy way to quit/restart a server, just middle/right click on the
   connection name.
 - Pretty interactive mode-line section for live tracking of server
   communication.
+- Automatically restarts frequently crashing servers (like RLS).
+- Server-initiated edits are confirmed with the user.
+- Diagnostics work out-of-the-box (no `flycheck.el` needed).

-Differences under the hood:
-
-- Message parser is much much simpler
-- Easier to read and maintain elisp. Yeah I know, subjective... But
-  judge for yourself.
-- No external dependencies apart from Emacs (no 

[elpa] externals/elpa 764347d 128/139: New command eglot-help-at-point and a README update

2018-05-14 Thread Jo�o T�vora
branch: externals/elpa
commit 764347d24c9894b0de3a7aca2a7ea5b2d691c4e2
Author: João Távora 
Commit: João Távora 

New command eglot-help-at-point and a README update

* README.md (Commands and keybindings): New section.

* eglot.el (eglot-eldoc-function): Use eglot--hover-info.
Don't care about kind in highlightSymbol
(eglot--hover-info): New helper.
(eglot-help-at-point): New command.
---
 README.md | 25 +
 eglot.el  | 41 -
 2 files changed, 53 insertions(+), 13 deletions(-)

diff --git a/README.md b/README.md
index 8a94466..a3789a4 100644
--- a/README.md
+++ b/README.md
@@ -33,6 +33,31 @@ Let me know how well it works and I'll add it to the list, 
or submit a
 PR.  You can also enter a `server:port` pattern to connect to an LSP
 server. To skip the guess and always be prompted use `C-u M-x eglot`.
 
+# Commands and keybindings
+
+Here's a summary of available commands:
+
+- `M-x eglot-reconnect` reconnects to the server
+
+- `M-x eglot-rename` asks the server to rename the symbol at point
+
+- `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.
+
+- `M-x eglot-events-buffer` jumps to the events buffer for debugging
+  communication with the server.
+
+There are *no keybindings* specific to Eglot, but you can bind stuff
+in `eglot-mode-map`, which is active as long as Eglot is managing a
+file in your project. The commands don't need to be eglot-specific,
+either:
+
+```
+(define-key eglot-mode-map (kbd "C-c h") 'eglot-help-at-point)
+(define-key eglot-mode-map (kbd "") 'xref-find-definitions)
+```
+
 # Supported Protocol features
 
 ## General
diff --git a/eglot.el b/eglot.el
index c8612cf..13f6f61 100644
--- a/eglot.el
+++ b/eglot.el
@@ -1314,6 +1314,28 @@ DUMMY is ignored"
 
 (defvar eglot--highlights nil "Overlays for textDocument/documentHighlight.")
 
+(defun eglot--hover-info (contents  range)
+  (concat (and range
+   (eglot--with-lsp-range (beg end) range
+ (concat (buffer-substring beg end)  ": ")))
+  (mapconcat #'eglot--format-markup
+ (append
+  (cond ((vectorp contents)
+ contents)
+(contents
+ (list contents "\n")))
+
+(defun eglot-help-at-point ()
+  "Request \"hover\" information for the thing at point."
+  (interactive)
+  (cl-destructuring-bind ( contents range)
+  (eglot--request (eglot--current-process-or-lose) :textDocument/hover
+  (eglot--TextDocumentPositionParams))
+(when (seq-empty-p contents) (eglot--error "No hover info here"))
+(with-help-window "*eglot help*"
+  (with-current-buffer standard-output
+(insert (eglot--hover-info contents range))
+
 (defun eglot-eldoc-function ()
   "EGLOT's `eldoc-documentation-function' function."
   (let ((buffer (current-buffer))
@@ -1325,17 +1347,7 @@ DUMMY is ignored"
:success-fn (eglot--lambda ( contents range)
  (when (get-buffer-window buffer)
(with-current-buffer buffer
- (eldoc-message
-  (concat
-   (and range
-(eglot--with-lsp-range (beg end) range
-  (concat (buffer-substring beg end)  ": ")))
-   (mapconcat #'eglot--format-markup
-  (append
-   (cond ((vectorp contents)
-  contents)
- (contents
-  (list contents "\n"))
+ (eldoc-message (eglot--hover-info contents range)
:deferred :textDocument/hover))
 (when (eglot--server-capable :documentHighlightProvider)
   (eglot--async-request
@@ -1346,12 +1358,11 @@ DUMMY is ignored"
(when (get-buffer-window buffer)
  (with-current-buffer buffer
(eglot--mapply
-(eglot--lambda ( range kind)
+(eglot--lambda ( range _kind)
   (eglot--with-lsp-range (beg end) range
 (let ((ov (make-overlay beg end)))
   (overlay-put ov 'face 'highlight)
   (overlay-put ov 'evaporate t)
-  (overlay-put ov :kind kind)
   ov)))
 highlights)
:deferred :textDocument/documentHighlight)))
@@ -1482,3 +1493,7 @@ Proceed? "
 
 

[elpa] externals/elpa 581608f 115/139: Resist server failure during synchronous requests

2018-05-14 Thread Jo�o T�vora
branch: externals/elpa
commit 581608fa8c3f319415a3476a949b53e209299bc8
Author: João Távora 
Commit: João Távora 

Resist server failure during synchronous requests

Calling the error handler unprotected could lead to the rest of the
sentinel not running at all. This defeated the auto-reconnection in
Rust, for example.

* eglot.el (eglot--process-sentinel): Rework.
---
 eglot.el | 81 +++-
 1 file changed, 39 insertions(+), 42 deletions(-)

diff --git a/eglot.el b/eglot.el
index bf0b9e9..d49367b 100644
--- a/eglot.el
+++ b/eglot.el
@@ -339,50 +339,47 @@ INTERACTIVE is t if called interactively."
 (defvar eglot--inhibit-auto-reconnect nil
   "If non-nil, don't autoreconnect on unexpected quit.")
 
-(defun eglot--process-sentinel (process change)
-  "Called with PROCESS undergoes CHANGE."
+(defun eglot--process-sentinel (proc change)
+  "Called when PROC undergoes CHANGE."
   (eglot--debug "(sentinel) Process state changed to %s" change)
-  (when (not (process-live-p process))
-;; Cancel timers and error any outstanding continuations
-;;
+  (when (not (process-live-p proc))
+;; Cancel outstanding timers
 (maphash (lambda (_id triplet)
-   (cl-destructuring-bind (_success error timeout) triplet
- (cancel-timer timeout)
- (funcall error :code -1 :message (format "Server died"
- (eglot--pending-continuations process))
-;; Turn off `eglot--managed-mode' where appropriate.
-;;
-(dolist (buffer (buffer-list))
-  (with-current-buffer buffer
-(when (eglot--buffer-managed-p process)
-  (eglot--managed-mode -1
-;; Forget about the process-project relationship
-;;
-(setf (gethash (eglot--project process) eglot--processes-by-project)
-  (delq process
-(gethash (eglot--project process) 
eglot--processes-by-project)))
-(cond ((eglot--moribund process)
-   (eglot--message "(sentinel) Moribund process exited with status %s"
-   (process-exit-status process)))
-  ((null eglot--inhibit-auto-reconnect)
-   (eglot--warn
-"(sentinel) Reconnecting after process unexpectedly changed to 
`%s'."
-change)
-   (condition-case-unless-debug err
-   (eglot-reconnect process)
- (error (eglot--warn "Auto-reconnect failed: %s " err) ))
-   (setq eglot--inhibit-auto-reconnect
- (run-with-timer
-  3 nil
-  (lambda ()
-(setq eglot--inhibit-auto-reconnect nil)
-  (t
-   (eglot--warn
-"(sentinel) Not auto-reconnecting, last one didn't last long."
-change)))
-(force-mode-line-update t)
-(delete-process process)))
-
+   (cl-destructuring-bind (_success _error timeout) triplet
+ (cancel-timer timeout)))
+ (eglot--pending-continuations proc))
+(unwind-protect
+;; Call all outstanding error handlers
+(maphash (lambda (_id triplet)
+   (cl-destructuring-bind (_success error _timeout) triplet
+ (funcall error :code -1 :message (format "Server died"
+ (eglot--pending-continuations proc))
+  ;; Turn off `eglot--managed-mode' where appropriate.
+  (dolist (buffer (buffer-list))
+(with-current-buffer buffer
+  (when (eglot--buffer-managed-p proc)
+(eglot--managed-mode -1
+  ;; Forget about the process-project relationship
+  (setf (gethash (eglot--project proc) eglot--processes-by-project)
+(delq proc
+  (gethash (eglot--project proc) eglot--processes-by-project)))
+  (cond ((eglot--moribund proc)
+ (eglot--message "(sentinel) Moribund process exited with status 
%s"
+ (process-exit-status proc)))
+((null eglot--inhibit-auto-reconnect)
+ (eglot--warn
+  "(sentinel) Reconnecting after process unexpectedly changed to 
`%s'."
+  change)
+ (setq eglot--inhibit-auto-reconnect
+   (run-with-timer 3 nil
+   (lambda ()
+ (setq eglot--inhibit-auto-reconnect 
nil
+ (eglot-reconnect proc))
+(t
+ (eglot--warn
+  "(sentinel) Not auto-reconnecting, last one didn't last long."
+  change)))
+  (delete-process proc
 (defun eglot--process-filter (proc string)
   "Called when new data STRING has arrived for PROC."
   (when (buffer-live-p (process-buffer proc))



[elpa] externals/eglot 0625b6c 123/139: (eglot--xref-make): Fix Use of cl-destructuring-bind.

2018-05-14 Thread Jo�o T�vora
branch: externals/eglot
commit 0625b6c639bac70da71e35c3870896e731c6ebc7
Author: João Távora 
Commit: João Távora 

(eglot--xref-make): Fix Use of cl-destructuring-bind.
---
 eglot.el | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/eglot.el b/eglot.el
index 4c5d53e..635ca26 100644
--- a/eglot.el
+++ b/eglot.el
@@ -1176,7 +1176,7 @@ DUMMY is ignored"
 
 (defun eglot--xref-make (name uri position)
   "Like `xref-make' but with LSP's NAME, URI and POSITION."
-  (cl-destructuring-bind (line character) position
+  (cl-destructuring-bind ( line character) position
 (xref-make name (xref-make-file-location
  (eglot--uri-to-path uri)
  ;; 

[elpa] externals/elpa e964abe 091/139: Get rid of eglot--buffer-open-count

2018-05-14 Thread Jo�o T�vora
branch: externals/elpa
commit e964abeba3e1f164fa05e9f7aaa79c4419ee1fe7
Author: João Távora 
Commit: João Távora 

Get rid of eglot--buffer-open-count

Hasn't really proved useful yet.

* eglot.el (eglot--buffer-open-count): Remove.
(eglot--signal-textDocument/didOpen)
(eglot--signal-textDocument/didClose): Simplify.
---
 eglot.el | 35 ---
 1 file changed, 8 insertions(+), 27 deletions(-)

diff --git a/eglot.el b/eglot.el
index 1318fee..a600f47 100644
--- a/eglot.el
+++ b/eglot.el
@@ -135,9 +135,6 @@ A list (WHAT SERIOUS-P)." t)
 Either a list of strings (a shell command and arguments), or a
 list of a single string of the form :")
 
-(eglot--define-process-var eglot--buffer-open-count (make-hash-table)
-  "Keeps track of didOpen/didClose notifs for each buffer.")
-
 (defun eglot--make-process (name managed-major-mode contact)
   "Make a process from CONTACT.
 NAME is a name to give the inferior process or connection.
@@ -1158,33 +1155,17 @@ Records START, END and PRE-CHANGE-LENGTH locally."
 
 (defun eglot--signal-textDocument/didOpen ()
   "Send textDocument/didOpen to server."
-  (let* ((proc (eglot--current-process-or-lose))
- (count (1+ (or (gethash (current-buffer)
- (eglot--buffer-open-count proc))
-0
-(when (> count 1)
-  (eglot--error "Too many textDocument/didOpen notifs for %s" 
(current-buffer)))
-(setf (gethash (current-buffer) (eglot--buffer-open-count proc))
-  count)
-(eglot--notify proc
-   :textDocument/didOpen
-   (eglot--obj :textDocument
-   (eglot--current-buffer-TextDocumentItem)
+  (eglot--notify (eglot--current-process-or-lose)
+ :textDocument/didOpen
+ (eglot--obj :textDocument
+ (eglot--current-buffer-TextDocumentItem
 
 (defun eglot--signal-textDocument/didClose ()
   "Send textDocument/didClose to server."
-  (let* ((proc (eglot--current-process-or-lose))
- (count (1- (or (gethash (current-buffer)
- (eglot--buffer-open-count proc))
-0
-(when (< count 0)
-  (eglot--error "Too many textDocument/didClose notifs for %s" 
(current-buffer)))
-(setf (gethash (current-buffer) (eglot--buffer-open-count proc))
-  count)
-(eglot--notify proc
-   :textDocument/didClose
-   (eglot--obj :textDocument
-   
(eglot--current-buffer-TextDocumentIdentifier)
+  (eglot--notify (eglot--current-process-or-lose)
+ :textDocument/didClose
+ (eglot--obj :textDocument
+ (eglot--current-buffer-TextDocumentIdentifier
 
 (defun eglot--signal-textDocument/willSave ()
   "Send textDocument/willSave to server."



[elpa] externals/eglot ef80455 121/139: Support :completionItem/resolve

2018-05-14 Thread Jo�o T�vora
branch: externals/eglot
commit ef80455416426fea7bd4e80797365c5ed18bd66f
Author: João Távora 
Commit: João Távora 

Support :completionItem/resolve

This is quite handy with company and company-quickhelp

* eglot.el (eglot-completion-at-point): Send
:completionItem/resolve

* README.md: Mention completionItem/resolve
---
 README.md |  3 ++-
 eglot.el  | 38 +-
 2 files changed, 27 insertions(+), 14 deletions(-)

diff --git a/README.md b/README.md
index c2931be..8a94466 100644
--- a/README.md
+++ b/README.md
@@ -74,7 +74,7 @@ server. To skip the guess and always be prompted use `C-u M-x 
eglot`.
 
 ## Language features
 - [x] textDocument/completion
-- [ ] completionItem/resolve
+- [x] completionItem/resolve (works quite well with 
[company-mode][company-mode])
 - [x] textDocument/hover
 - [ ] textDocument/signatureHelp
 - [x] textDocument/definition
@@ -144,5 +144,6 @@ Under the hood:
 [emacs-lsp]: https://github.com/emacs-lsp/lsp-mode
 [emacs-lsp-plugins]: https://github.com/emacs-lsp
 [bash-language-server]: https://github.com/mads-hartmann/bash-language-server
+[company-mode]: https://github.com/company-mode/company-mode
 

diff --git a/eglot.el b/eglot.el
index 58a2374..3557303 100644
--- a/eglot.el
+++ b/eglot.el
@@ -1278,23 +1278,35 @@ DUMMY is ignored"
:textDocument/completion))
  (items (if (vectorp resp) resp (plist-get resp :items
 (eglot--mapply
- (eglot--lambda ( insertText label kind detail
-  documentation sortText )
-   (propertize (or insertText label)
-   :kind-name (cdr (assoc kind eglot--kind-names))
-   :detail detail
-   :documentation documentation :sortText sortText))
+ (eglot--lambda ( all  label )
+   (add-text-properties 0 1 all label) label)
  items
:annotation-function
-   (lambda (what)
- (propertize (concat " " (or (get-text-property 0 :detail what)
- (get-text-property 0 :kind what)))
+   (lambda (obj)
+ (propertize (concat " " (or (get-text-property 0 :detail obj)
+ (cdr (assoc (get-text-property 0 :kind 
obj)
+ eglot--kind-names
  'face 'font-lock-function-name-face))
:display-sort-function
-   (lambda (items) (sort items (lambda (a b)
- (string-lessp
-  (get-text-property 0 :sortText a)
-  (get-text-property 0 :sortText b)
+   (lambda (items)
+ (sort items (lambda (a b)
+   (string-lessp
+(or (get-text-property 0 :sortText a) "")
+(or (get-text-property 0 :sortText b) "")
+   :company-doc-buffer
+   (lambda (obj)
+ (let ((documentation
+(or (get-text-property 0 :documentation obj)
+(plist-get (eglot--request proc :completionItem/resolve
+   (text-properties-at 0 obj))
+   :documentation
+   (when documentation
+ (with-current-buffer (get-buffer-create " *eglot doc*")
+   (erase-buffer)
+   (ignore-errors (funcall (intern "markdown-mode")))
+   (font-lock-ensure)
+   (insert documentation)
+   (current-buffer)
:exit-function
(lambda (_string _status) (eglot-eldoc-function))
 



[elpa] externals/eglot ab575d2 120/139: Rename functions. eglot--request is now the synchronous one

2018-05-14 Thread Jo�o T�vora
branch: externals/eglot
commit ab575d229c5a93916ffb33517f89bf75b27d5b33
Author: João Távora 
Commit: João Távora 

Rename functions. eglot--request is now the synchronous one

* eglot.el (eglot--connect, eglot-shutdown)
(xref-backend-identifier-completion-table)
(xref-backend-definitions, xref-backend-references)
(xref-backend-apropos, eglot-completion-at-point, eglot-rename):
Call eglot--request.
(eglot--async-request): Renamed from eglot--request.
(eglot--request): Renamed from eglot--sync-request.
(eglot--TextDocumentIdentifier)
(eglot--VersionedTextDocumentIdentifier)
(eglot--TextDocumentPositionParams, eglot--TextDocumentItem):
Renamed from the more verbose eglot--current-buffer-* variante.
(eglot-rename, eglot-imenu, eglot-eldoc-function)
(eglot-completion-at-point, xref-backend-definitions)
(xref-backend-identifier-at-point)
(eglot--signal-textDocument/didSave)
(xref-backend-identifier-completion-table)
(eglot--signal-textDocument/didClose)
(eglot--signal-textDocument/didOpen)
(eglot--signal-textDocument/didChange): Use new function names.
---
 eglot.el | 140 +++
 1 file changed, 68 insertions(+), 72 deletions(-)

diff --git a/eglot.el b/eglot.el
index 22799cc..58a2374 100644
--- a/eglot.el
+++ b/eglot.el
@@ -219,7 +219,7 @@ CONTACT is as `eglot--contact'.  Returns a process object."
 (erase-buffer)
 (read-only-mode t)
 (cl-destructuring-bind ( capabilities)
-(eglot--sync-request
+(eglot--request
  proc
  :initialize
  (eglot--obj :processId (unless (eq (process-type proc)
@@ -558,9 +558,9 @@ is a symbol saying if this is a client or server 
originated."
 
 (defvar eglot--ready-predicates '(eglot--server-ready-p)
   "Special hook of predicates controlling deferred actions.
-When one of these functions returns nil, a deferrable
-`eglot--request' will be deferred.  Each predicate is passed the
-an symbol for the request request and a process object.")
+If one of these returns nil, a deferrable `eglot--async-request'
+will be deferred.  Each predicate is passed the symbol for the
+request request and a process object.")
 
 (defun eglot--server-ready-p (_what _proc)
   "Tell if server of PROC ready for processing deferred WHAT."
@@ -570,13 +570,13 @@ an symbol for the request request and a process object.")
   (declare (indent 1) (debug (sexp  form)))
   `(cl-function (lambda ,cl-lambda-list ,@body)))
 
-(cl-defun eglot--request (proc
-  method
-  params
-   args
-   success-fn error-fn timeout-fn
-  (timeout eglot-request-timeout)
-  (deferred nil))
+(cl-defun eglot--async-request (proc
+method
+params
+ args
+ success-fn error-fn timeout-fn
+(timeout eglot-request-timeout)
+(deferred nil))
   "Make a request to PROCESS, expecting a reply.
 Return the ID of this request. Wait TIMEOUT seconds for response.
 If DEFERRED, maybe defer request to the future, or never at all,
@@ -610,11 +610,11 @@ timeout keeps counting."
   (when (buffer-live-p buf)
 (with-current-buffer buf
   (save-excursion (goto-char point)
-  (apply #'eglot--request proc
+  (apply #'eglot--async-request 
proc
  method params args)))
 (puthash (list deferred buf) (list later (funcall make-timeout))
  (eglot--deferred-actions proc))
-(cl-return-from eglot--request nil)
+(cl-return-from eglot--async-request nil)
 ;; Really run it
 ;;
 (puthash id
@@ -634,17 +634,17 @@ timeout keeps counting."
   :method method
   :params params
 
-(defun eglot--sync-request (proc method params  deferred)
-  "Like `eglot--request' for PROC, METHOD and PARAMS, but synchronous.
+(defun eglot--request (proc method params  deferred)
+  "Like `eglot--async-request' for PROC, METHOD and PARAMS, but synchronous.
 Meaning only return locally if successful, otherwise exit non-locally.
-DEFERRED is passed to `eglot--request', which see."
+DEFERRED is passed to `eglot--async-request', which see."
   ;; Launching a deferred sync request with outstanding changes is a
   ;; bad idea, since that might lead to the request never having a
   ;; chance to run, because `eglot--ready-predicates'.
   

[elpa] externals/elpa 49fb02f 135/139: Use RLS in Travis CI and add actual tests

2018-05-14 Thread Jo�o T�vora
branch: externals/elpa
commit 49fb02fc1c838da6c4764d498540115c85acbdff
Author: João Távora 
Commit: João Távora 

Use RLS in Travis CI and add actual tests

Also run a hook when connected

* eglot-tests.el (eglot--with-dirs-and-files)
(eglot--make-file-or-dirs, eglot--call-with-dirs-and-files)
(eglot--find-file-noselect): New helpers.
(auto-detect-running-server, auto-reconnect): New actual tests.

* eglot.el (eglot-connect): Run hook when connected
(eglot-connect-hook): New variable

* .travis.yml: Use rust stable and install rls

* README.md: Update mention of automated tests
---
 .travis.yml|   9 +++-
 README.md  |   3 +-
 eglot-tests.el | 128 +
 eglot.el   |   3 ++
 4 files changed, 140 insertions(+), 3 deletions(-)

diff --git a/.travis.yml b/.travis.yml
index 7a89327..2f0db4c 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,5 +1,7 @@
-language: generic
+language: rust
 sudo: false
+rust:
+  - stable
 
 env:
   global:
@@ -13,7 +15,10 @@ install:
   # Configure $PATH: Emacs installed to /tmp/emacs
   - export PATH=/tmp/emacs/bin:${PATH}
   - emacs --version
-
+  # Install RLS
+  - rustup update
+  - rustup component add rls-preview rust-analysis rust-src
+
 script:
   - make check
 
diff --git a/README.md b/README.md
index 4683951..e5a2394 100644
--- a/README.md
+++ b/README.md
@@ -162,7 +162,8 @@ Under the hood:
 - Project support doesn't need `projectile.el`, uses Emacs's `project.el`
 - Requires the upcoming Emacs 26
 - Contained in one file
-- Its missing tests! This is *not good*
+- 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
diff --git a/eglot-tests.el b/eglot-tests.el
index 0f29519..119d873 100644
--- a/eglot-tests.el
+++ b/eglot-tests.el
@@ -24,9 +24,137 @@
 
 ;;; Code:
 (require 'eglot)
+(require 'cl-lib)
 (require 'ert)
 
+;; Helpers
+
+(defmacro eglot--with-dirs-and-files (dirs  body)
+  (declare (indent defun) (debug t))
+  `(eglot--call-with-dirs-and-files
+,dirs #'(lambda () ,@body)))
+
+(defun eglot--make-file-or-dirs (ass)
+  (let ((file-or-dir-name (car ass))
+(content (cdr ass)))
+(cond ((listp content)
+   (make-directory file-or-dir-name 'parents)
+   (let ((default-directory (concat default-directory "/" 
file-or-dir-name)))
+ (mapc #'eglot--make-file-or-dirs content)))
+  ((stringp content)
+   (with-temp-buffer
+ (insert content)
+ (write-region nil nil file-or-dir-name nil 'nomessage)))
+  (t
+   (message "[yas] oops don't know this content")
+
+(defun eglot--call-with-dirs-and-files (dirs fn)
+  (let* ((default-directory (make-temp-file "eglot--fixture" t))
+ new-buffers new-processes)
+(with-temp-message ""
+  (unwind-protect
+  (let ((find-file-hook
+ (cons (lambda () (push (current-buffer) new-buffers))
+   find-file-hook))
+(eglot-connect-hook
+ (lambda (proc) (push proc new-processes
+(mapc #'eglot--make-file-or-dirs dirs)
+(funcall fn))
+(eglot--message "Killing buffers %s,  deleting %s, killing %s"
+(mapconcat #'buffer-name new-buffers ", ")
+default-directory
+new-processes)
+(delete-directory default-directory 'recursive)
+(let ((eglot-autoreconnect nil))
+  (mapc #'eglot-shutdown
+(cl-remove-if-not #'process-live-p new-processes)))
+(mapc #'kill-buffer new-buffers)
+
+(cl-defmacro eglot--with-test-timeout (timeout  body)
+  (declare (indent 1) (debug t))
+  `(eglot--call-with-test-timeout ,timeout (lambda () ,@body)))
+
+(defun eglot--call-with-test-timeout (timeout fn)
+  (let* ((tag (make-symbol "tag"))
+ (timed-out (make-symbol "timeout"))
+ (timer )
+ (eglot-request-timeout 1)
+ (retval))
+(unwind-protect
+(setq retval
+  (catch tag
+(setq timer
+  (run-with-timer timeout nil
+  (lambda () (throw tag timed-out
+(funcall fn)))
+  (cancel-timer timer)
+  (when (eq retval timed-out)
+(error "Test timeout!")
+
+(defun eglot--find-file-noselect (file  noerror)
+  (unless (or noerror
+  (file-readable-p file)) (error "%s does not exist" file))
+  (find-file-noselect file))
+
+
+;; `rust-mode' is not a part of emacs. So define these two shims which
+;; should be more than enough for testing
+(unless (functionp 'rust-mode)
+  (define-derived-mode rust-mode prog-mode "Rust"))
+(add-to-list 'auto-mode-alist '("\\.rs\\'" . rust-mode))
+
+
 

[elpa] externals/elpa 37b7329 098/139: Reasonable textDocument/documentHighlight support

2018-05-14 Thread Jo�o T�vora
branch: externals/elpa
commit 37b73290e881df071efb6fb44854b05d57d758bf
Author: João Távora 
Commit: João Távora 

Reasonable textDocument/documentHighlight support

* README.md: Update.

* eglot.el (eglot--current-buffer-TextDocumentPositionParams): New
helper.
(xref-backend-identifier-completion-table): Refactor a bit.
(xref-backend-identifier-at-point): Use when-let and
eglot--current-buffer-TextDocumentPositionParams
(xref-backend-definitions, xref-backend-references): Refactor a
bit.
(eglot-completion-at-point): Use
eglot--current-buffer-TextDocumentPositionParams
(eglot-eldoc-function): Rewrite to handle
textDocument/documentHighlight.
(eglot--highlights): New variable.
(eglot--client-capabilities): Update with support for documentHighlight.
---
 README.md |  13 +++
 eglot.el  | 117 +++---
 2 files changed, 74 insertions(+), 56 deletions(-)

diff --git a/README.md b/README.md
index fef2d16..5838bc5 100644
--- a/README.md
+++ b/README.md
@@ -34,7 +34,7 @@ server. To skip the guess and always be prompted use `C-u M-x 
eglot`.
 - [x] textDocument/completion
 - [ ] completionItem/resolve
 - [x] textDocument/definition
-- [ ] textDocument/documentHighlight
+- [x] textDocument/documentHighlight
 - [x] textDocument/documentSymbol
 - [ ] textDocument/executeCommand
 - [ ] textDocument/format
@@ -46,17 +46,18 @@ server. To skip the guess and always be prompted use `C-u 
M-x eglot`.
 
 # Differences to lsp-mode.el
 
-This is really beta and currently does less than
-[lsp-mode.el][emacs-lsp] which is more
-mature. Though I think `eglot.el` will eventually beat it, you could
-be better served with `lsp-mode.el` for now.
+This is really beta and currently does a little less than
+[lsp-mode.el][emacs-lsp] which is more mature. Though I think
+`eglot.el` will eventually beat it, you could be better served with
+`lsp-mode.el` for now.
 
 User-visible differences:
 
 - Single entry point, `M-x eglot` to enable LSP in a project.
   Automatically detects current and future opened files under that
   project and syncs with server.
-- Easy way to restart a server
+- Easy way to quit/restart a server, just middle/right click on the
+  connection name.
 - Pretty interactive mode-line section for live tracking of server
   communication.

diff --git a/eglot.el b/eglot.el
index 807df98..c5c99f2 100644
--- a/eglot.el
+++ b/eglot.el
@@ -193,11 +193,12 @@ 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)
-  :documentSymbol `(:dynamicRegistration :json-false)
+  :completion `(:dynamicRegistration :json-false)
+  :hover  `(:dynamicRegistration :json-false)
+  :references `(:dynamicRegistration :json-false)
+  :definition `(:dynamicRegistration :json-false)
+  :documentSymbol `(:dynamicRegistration :json-false)
+  :documentHighlight  `(:dynamicRegistration :json-false)
   :publishDiagnostics `(:relatedInformation :json-false))
:experimental (eglot--obj)))
 
@@ -1057,6 +1058,11 @@ running.  INTERACTIVE is t if called interactively."
  (widen)
  (buffer-substring-no-properties (point-min) (point-max))
 
+(defun eglot--current-buffer-TextDocumentPositionParams ()
+  "Compute TextDocumentPositionParams."
+  (eglot--obj :textDocument (eglot--current-buffer-TextDocumentIdentifier)
+  :position (eglot--pos-to-lsp-position)))
+
 (defun eglot--before-change (start end)
   "Hook onto `before-change-functions'.
 Records START and END, crucially convert them into
@@ -1206,11 +1212,12 @@ DUMMY is ignored"
(eglot--mapply
 (eglot--lambda ( name kind location containerName)
   (propertize name
-  :position (plist-get
- (plist-get location :range)
- :start)
+  :textDocumentPositionParams
+  (eglot--obj :textDocument text-id
+  :position (plist-get
+ (plist-get location 
:range)
+ :start))
   :locations (list location)
-

[elpa] externals/eglot 6f0a8df 008/139: Organize a bit

2018-05-14 Thread Jo�o T�vora
branch: externals/eglot
commit 6f0a8dffc75c053df1f4e952ee0826df5195c798
Author: João Távora 
Commit: João Távora 

Organize a bit
---
 eglot.el | 50 ++
 1 file changed, 30 insertions(+), 20 deletions(-)

diff --git a/eglot.el b/eglot.el
index c7f8774..e3b288b 100644
--- a/eglot.el
+++ b/eglot.el
@@ -148,25 +148,6 @@
(format "\n---\n"
   (eglot--protocol-initialize proc interactive))
 
-(defun eglot-quit-server (process  sync)
-  (interactive (list (eglot--current-process-or-lose)))
-  (eglot--message "Asking server to terminate")
-  (eglot--request
-  process
-  :shutdown
-  nil
-  (lambda ( _anything)
-(eglot--message "Now asking server to exit")
-(process-put process 'eglot--moribund t)
-(eglot--process-send process
-  `(:jsonrpc  "2.0"
-  :method  :exit)))
-  :async-p (not sync)
-  :timeout-fn (lambda ()
-(eglot--warn "Brutally deleting existing process %s"
-  process)
-(process-put process 'eglot--moribund t)
-(delete-process process
 
 (defun eglot--process-sentinel (process change)
   (with-current-buffer (process-buffer process)
@@ -359,6 +340,9 @@
 (eglot--error "Process %s died unexpectedly" process))
   (accept-process-output nil 0.01))
 
+
+;;; Requests
+;;; 
 
 (defun eglot--protocol-initialize (process interactive)
   (eglot--request
@@ -366,6 +350,7 @@
:initialize
`(:processId  ,(emacs-pid)
  :rootPath  ,(concat "" ;; FIXME RLS doesn't like "file://"
+ "file://"
  (expand-file-name (car (project-roots
  
(project-current)
  :initializationOptions  []
@@ -396,7 +381,26 @@
   "So yeah I got lots (%d) of capabilities"
   (length all)))
 
-(defun eglot--debug (format  args)
+(defun eglot-quit-server (process  sync)
+  (interactive (list (eglot--current-process-or-lose)))
+  (eglot--message "Asking server to terminate")
+  (eglot--request
+  process
+  :shutdown
+  nil
+  (lambda ( _anything)
+(eglot--message "Now asking server to exit")
+(process-put process 'eglot--moribund t)
+(eglot--process-send process
+  `(:jsonrpc  "2.0"
+  :method  :exit)))
+  :async-p (not sync)
+  :timeout-fn (lambda ()
+(eglot--warn "Brutally deleting existing process %s"
+  process)
+(process-put process 'eglot--moribund t)
+(delete-process process
+
 
 ;;; Notifications
 ;;;
@@ -405,6 +409,12 @@
   "Handle notification publishDiagnostics"
   (eglot--message "So yeah I got %s for %s"
   diagnostics uri))
+
+
+;;; Helpers
+;;;
+(defun
+eglot--debug (format  args)
   (display-warning 'eglot
  (apply #'format format args)
  :debug))



[elpa] externals/eglot 46bb1c0 049/139: Reorganize file

2018-05-14 Thread Jo�o T�vora
branch: externals/eglot
commit 46bb1c0e38e8f437f5ea490562413d0c51c0219b
Author: João Távora 
Commit: João Távora 

Reorganize file

* eglot.el (eglot-mode-line): Move up.
(eglot-make-local-process, eglot--all-major-modes, eglot--obj)
(eglot--project-short-name, eglot--all-major-modes)
(eglot-reconnect, eglot--maybe-activate-editing-mode)
(eglot--protocol-initialize)
(eglot--window/showMessage, eglot--current-flymake-report-fn)
(eglot--unreported-diagnostics)
(eglot--textDocument/publishDiagnostics, eglot--signalDidOpen)
(eglot--signalDidClose): Move around.
(eglot-quit-server): Renamed to eglot-shutdown.
(eglot-shutdown): New function
---
 eglot.el | 391 ---
 1 file changed, 198 insertions(+), 193 deletions(-)

diff --git a/eglot.el b/eglot.el
index f25c7bd..7d44e6d 100644
--- a/eglot.el
+++ b/eglot.el
@@ -34,6 +34,8 @@
 (require 'warnings)
 (require 'flymake)
 
+
+;;; User tweakable stuff
 (defgroup eglot nil
   "Interaction with Language Server Protocol servers"
   :prefix "eglot-"
@@ -43,6 +45,13 @@
 (python-mode . ("pyls")))
   "Alist mapping major modes to server executables.")
 
+(defface eglot-mode-line
+  '((t (:inherit font-lock-constant-face :weight bold)))
+  "Face for package-name in EGLOT's mode line."
+  :group 'eglot)
+
+
+;;; Process management
 (defvar eglot--processes-by-project (make-hash-table :test #'equal)
   "Keys are projects.  Values are lists of processes.")
 
@@ -129,20 +138,6 @@ A list (WHAT SERIOUS-P)." t)
 Must be a function of one arg, a name, returning a process
 object.")
 
-(defun eglot--project-short-name (project)
-  "Give PROJECT a short name."
-  (file-name-base
-   (directory-file-name
-(car (project-roots project)
-
-(defun eglot--all-major-modes ()
-  "Return all know major modes."
-  (let ((retval))
-(mapatoms (lambda (sym)
-(when (plist-member (symbol-plist sym) 'derived-mode-parent)
-  (push sym retval
-retval))
-
 (defun eglot-make-local-process (name command)
   "Make a local LSP process from COMMAND.
 NAME is a name to give the inferior process or connection.
@@ -161,6 +156,26 @@ Returns a process object."
   name)
 proc))
 
+(defmacro eglot--obj ( what)
+  "Make WHAT a suitable argument for `json-encode'."
+  ;; FIXME: maybe later actually do something, for now this just fixes
+  ;; the indenting of literal plists.
+  `(list ,@what))
+
+(defun eglot--project-short-name (project)
+  "Give PROJECT a short name."
+  (file-name-base
+   (directory-file-name
+(car (project-roots project)
+
+(defun eglot--all-major-modes ()
+  "Return all know major modes."
+  (let ((retval))
+(mapatoms (lambda (sym)
+(when (plist-member (symbol-plist sym) 'derived-mode-parent)
+  (push sym retval
+retval))
+
 (defun eglot--connect (project managed-major-mode
short-name bootstrap-fn  success-fn)
   "Make a connection for PROJECT, SHORT-NAME and MANAGED-MAJOR-MODE.
@@ -191,23 +206,6 @@ SUCCESS-FN with no args if all goes well."
 (setf (eglot--status proc) nil)
 (when success-fn (funcall success-fn proc)
 
-(defun eglot-reconnect (process  interactive)
-  "Reconnect to PROCESS.
-INTERACTIVE is t if called interactively."
-  (interactive (list (eglot--current-process-or-lose) t))
-  (when (process-live-p process)
-(eglot-quit-server process 'sync interactive))
-  (eglot--connect
-   (eglot--project process)
-   (eglot--major-mode process)
-   (eglot--short-name process)
-   (eglot--bootstrap-fn process)
-   (lambda (proc)
- (eglot--message "Reconnected!")
- (dolist (buffer (buffer-list))
-   (with-current-buffer buffer
- (eglot--maybe-activate-editing-mode proc))
-
 (defvar eglot--command-history nil
   "History of COMMAND arguments to `eglot'.")
 
@@ -285,6 +283,23 @@ buffers in project %s."
  (with-current-buffer buffer
(eglot--maybe-activate-editing-mode proc))
 
+(defun eglot-reconnect (process  interactive)
+  "Reconnect to PROCESS.
+INTERACTIVE is t if called interactively."
+  (interactive (list (eglot--current-process-or-lose) t))
+  (when (process-live-p process)
+(eglot-shutdown process 'sync interactive))
+  (eglot--connect
+   (eglot--project process)
+   (eglot--major-mode process)
+   (eglot--short-name process)
+   (eglot--bootstrap-fn process)
+   (lambda (proc)
+ (eglot--message "Reconnected!")
+ (dolist (buffer (buffer-list))
+   (with-current-buffer buffer
+ (eglot--maybe-activate-editing-mode proc))
+
 (defun eglot--process-sentinel (process change)
   "Called with PROCESS undergoes CHANGE."
   (eglot--debug "(sentinel) Process state changed to %s" change)
@@ -370,12 +385,6 

[elpa] externals/elpa dc08e8e 134/139: Fix automatic project creation

2018-05-14 Thread Jo�o T�vora
branch: externals/elpa
commit dc08e8e3c4bd2a907533ef0713552e17ec75cbe6
Author: João Távora 
Commit: João Távora 

Fix automatic project creation

* eglot.el (eglot): Take PROJECT arg. Return process.
(eglot--interactive): Returns a project.
---
 eglot.el | 11 +++
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/eglot.el b/eglot.el
index c1b63ea..3d5d492 100644
--- a/eglot.el
+++ b/eglot.el
@@ -292,6 +292,7 @@ INTERACTIVE is t if inside interactive call."
  "\n" base-prompt)
 (list
  managed-mode
+ (or (project-current) `(transient . default-directory))
  (if prompt
  (split-string-and-unquote
   (read-shell-command prompt
@@ -302,11 +303,13 @@ INTERACTIVE is t if inside interactive call."
  t)))
 
 ;;;###autoload
-(defun eglot (managed-major-mode command  interactive)
+(defun eglot (managed-major-mode project command  interactive)
   "Start a Language Server Protocol server.
 Server is started with COMMAND and manages buffers of
 MANAGED-MAJOR-MODE for the current project.
 
+PROJECT is a project instance as returned by `project-current'.
+
 COMMAND is a list of strings, an executable program and
 optionally its arguments.  If the first and only string in the
 list is of the form \":\" it is taken as an
@@ -323,8 +326,7 @@ MANAGED-MAJOR-MODE.
 
 INTERACTIVE is t if called interactively."
   (interactive (eglot--interactive))
-  (let* ((project (project-current 'maybe))
- (short-name (eglot--project-short-name project)))
+  (let* ((short-name (eglot--project-short-name project)))
 (let ((current-process (eglot--current-process)))
   (if (and (process-live-p current-process)
interactive
@@ -339,7 +341,8 @@ INTERACTIVE is t if called interactively."
 interactive)))
   (eglot--message "Connected! Process `%s' now \
 managing `%s' buffers in project `%s'."
-  proc managed-major-mode short-name))
+  proc managed-major-mode short-name)
+  proc)
 
 (defun eglot-reconnect (process  interactive)
   "Reconnect to PROCESS.



[elpa] externals/eglot 3dcbc30 109/139: Add minimal headers, commentary and autoloads

2018-05-14 Thread Jo�o T�vora
branch: externals/eglot
commit 3dcbc30ee2e56e1fdfb8de653de124f096f55f97
Author: João Távora 
Commit: João Távora 

Add minimal headers, commentary and autoloads
---
 eglot.el | 11 +--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/eglot.el b/eglot.el
index 4739cea..eba0e84 100644
--- a/eglot.el
+++ b/eglot.el
@@ -2,8 +2,11 @@
 
 ;; Copyright (C) 2017  João Távora
 
+;; Version: 0.1
 ;; Author: João Távora
-;; Keywords: extensions
+;; Url: https://github.com/joaotavora/eglot
+;; Keywords: convenience, languages
+;; Package-Requires: ((emacs "26.1"))
 
 ;; This program is free software; you can redistribute it and/or modify
 ;; it under the terms of the GNU General Public License as published by
@@ -20,7 +23,8 @@
 
 ;;; Commentary:
 
-;;
+;; M-x eglot in some file under some .git controlled dir should get
+;; you started, but see README.md.
 
 ;;; Code:
 
@@ -285,6 +289,7 @@ Enter program to execute (or :): "
  guessed-command))
  t)))
 
+;;;###autoload
 (defun eglot (managed-major-mode command  interactive)
   "Start a Language Server Protocol server.
 Server is started with COMMAND and manages buffers of
@@ -1465,8 +1470,10 @@ Proceed? "
   (pcase-let ((`(,_id ,what ,done ,_detail) (eglot--spinner proc)))
 (and (equal "Indexing" what) done
 
+;;;###autoload
 (add-hook 'rust-mode-hook 'eglot--setup-rls-idiosyncrasies)
 
+;;;###autoload
 (defun eglot--setup-rls-idiosyncrasies ()
   "RLS needs special treatment..."
   (add-hook 'eglot--ready-predicates 'eglot--rls-probably-ready-for-p t t))



[elpa] externals/eglot 4c0bfc3 139/139: Support didChangeWatchedFiles with dynamic registration

2018-05-14 Thread Jo�o T�vora
branch: externals/eglot
commit 4c0bfc335181a6d3d54141d4fb952cff887621e6
Author: João Távora 
Commit: João Távora 

Support didChangeWatchedFiles with dynamic registration

RLS uses this, presumaly for knowing about Cargo.toml changes and stuff.

* README.md: Update protocol compliance.

* eglot.el (filenotify): Require it.
(eglot--file-watches): New process-local var.
(eglot--process-sentinel): Kill all watches
(eglot--register-unregister): New helper.
(eglot--server-client/registerCapability): Simplify.
(eglot--server-client/unregisterCapability): New method.
(eglot--register-workspace/didChangeWatchedFiles)
(eglot--unregister-workspace/didChangeWatchedFiles): New
capability.
(eglot--client-capabilities): Update.
---
 README.md |   7 +++--
 eglot.el  | 102 --
 2 files changed, 76 insertions(+), 33 deletions(-)

diff --git a/README.md b/README.md
index 056065c..7550a30 100644
--- a/README.md
+++ b/README.md
@@ -76,15 +76,16 @@ either:
 - [x] telemetry/event
 
 ## Client
-- [ ] client/registerCapability
-- [ ] client/unregisterCapability
+- [x] client/registerCapability (but only
+  `workspace/didChangeWatchedFiles`, like RLS asks)
+- [x] client/unregisterCapability  (ditto)
 
 ## Workspace
 - [ ] workspace/workspaceFolders (3.6.0)
 - [ ] workspace/didChangeWorkspaceFolders (3.6.0)
 - [ ] workspace/didChangeConfiguration
 - [ ] workspace/configuration (3.6.0)
-- [ ] workspace/didChangeWatchedFiles
+- [x] workspace/didChangeWatchedFiles
 - [x] workspace/symbol is
 - [x] workspace/applyEdit
 
diff --git a/eglot.el b/eglot.el
index 9b0f290..85b2d89 100644
--- a/eglot.el
+++ b/eglot.el
@@ -39,6 +39,7 @@
 (require 'flymake)
 (require 'xref)
 (require 'subr-x)
+(require 'filenotify)
 
 
 ;;; User tweakable stuff
@@ -148,6 +149,9 @@ list of a single string of the form :")
 (make-hash-table :test #'equal)
   "Actions deferred to when server is thought to be ready.")
 
+(eglot--define-process-var eglot--file-watches (make-hash-table :test #'equal)
+  "File system watches for the didChangeWatchedfiles thingy.")
+
 (defun eglot--make-process (name managed-major-mode contact)
   "Make a process from CONTACT.
 NAME is a name to give the inferior process or connection.
@@ -199,6 +203,9 @@ CONTACT is as `eglot--contact'.  Returns a process object."
   "What the EGLOT LSP client supports."
   (eglot--obj
:workspace(eglot--obj
+  :applyEdit t
+  :workspaceEdit `(:documentChanges :json-false)
+  :didChangeWatchesFiles `(:dynamicRegistration t)
   :symbol `(:dynamicRegistration :json-false))
:textDocument (eglot--obj
   :synchronization (eglot--obj
@@ -365,11 +372,14 @@ INTERACTIVE is t if called interactively."
 (with-current-buffer (eglot-events-buffer proc)
   (let ((inhibit-read-only t))
 (insert "\n--b---y---e---b---y---e--\n")))
-;; Cancel outstanding timers
+;; Cancel outstanding timers and file system watches
 (maphash (lambda (_id triplet)
(cl-destructuring-bind (_success _error timeout) triplet
  (cancel-timer timeout)))
  (eglot--pending-continuations proc))
+(maphash (lambda (_id watches)
+   (mapcar #'file-notify-rm-watch watches))
+ (eglot--file-watches proc))
 (unwind-protect
 ;; Call all outstanding error handlers
 (maphash (lambda (_id triplet)
@@ -990,32 +1000,31 @@ called interactively."
  (t
   (eglot--message "OK so %s isn't visited" filename)
 
+(cl-defun eglot--register-unregister (proc jsonrpc-id things how)
+  "Helper for `eglot--server-client/registerCapability'.
+THINGS are either registrations or unregisterations."
+  (dolist (thing (cl-coerce things 'list))
+(cl-destructuring-bind ( id method registerOptions) thing
+  (let (retval)
+(unwind-protect
+(setq retval (apply (intern (format "eglot--%s-%s" how method))
+proc :id id registerOptions))
+  (unless (eq t (car retval))
+(cl-return-from eglot--register-unregister
+  (eglot--reply
+   proc jsonrpc-id
+   :error `(:code -32601 :message ,(or (cadr retval) 
"sorry")
+  (eglot--reply proc jsonrpc-id :result (eglot--obj :message "OK")))
+
 (cl-defun eglot--server-client/registerCapability
 (proc  id registrations)
-  "Handle notification client/registerCapability"
-  (let ((jsonrpc-id id)
-(done (make-symbol "done")))
-(catch done
-  (mapc
-   (lambda (reg)
- (apply
-  (cl-function
-   (lambda ( id method registerOptions)
- (pcase-let*
- ((handler-sym (intern (concat "eglot--register-"
-   method)))
- 

[elpa] externals/eglot 8448d9b 133/139: Work with any old directory, no formal project needed

2018-05-14 Thread Jo�o T�vora
branch: externals/eglot
commit 8448d9b03b2813971093fd8420e739ee0b1856dd
Author: João Távora 
Commit: João Távora 

Work with any old directory, no formal project needed

Actually, uses a "transient project" which project-current returns if
desperate.

* README.md: Update

* eglot.el (eglot--current-process)
(eglot--current-process-or-lose): Simplify.
(eglot): Maybe prompt user for project.
---
 README.md | 10 +-
 eglot.el  | 18 ++
 2 files changed, 11 insertions(+), 17 deletions(-)

diff --git a/README.md b/README.md
index 39ec752..4683951 100644
--- a/README.md
+++ b/README.md
@@ -8,12 +8,12 @@ Eglot
 (add-to-list 'load-path "/path/to/eglot")
 (require 'eglot) ; Requires emacs 26!
 
-;; Now find some project file inside some Git-controlled dir
+;; Now find some source file, any source file
 M-x eglot
 ```
 
 *That's it*. If you're lucky, this guesses the LSP executable to start
-for the language of your choice, or it prompts you to enter one:
+for the language of your choice. Otherwise, it prompts you to enter one:
 
 `M-x eglot` currently guesses and works out-of-the-box with:
 
@@ -29,9 +29,9 @@ customize `eglot-server-programs`:
 (add-to-list 'eglot-server-programs '(fancy-mode . ("fancy-language-server" 
"--args"")))
 ```
 
-Let me know how well it works and I'll add it to the list, or submit a
-PR.  You can also enter a `server:port` pattern to connect to an LSP
-server. To skip the guess and always be prompted use `C-u M-x eglot`.
+Let me know how well it works and we can add it to the list.  You can
+also enter a `server:port` pattern to connect to an LSP server. To
+skip the guess and always be prompted use `C-u M-x eglot`.
 
 # Commands and keybindings
 
diff --git a/eglot.el b/eglot.el
index 2e872dc..c1b63ea 100644
--- a/eglot.el
+++ b/eglot.el
@@ -24,8 +24,7 @@
 
 ;;; Commentary:
 
-;; M-x eglot in some file under some .git controlled dir should get
-;; you started, but see README.md.
+;; Simply M-x eglot should be enough to get you started, but see README.md.
 
 ;;; Code:
 
@@ -79,15 +78,13 @@ lasted more than that many seconds."
 
 (defun eglot--current-process ()
   "The current logical EGLOT process."
-  (let* ((cur (project-current))
- (processes (and cur (gethash cur eglot--processes-by-project
-(cl-find major-mode processes :key #'eglot--major-mode)))
+  (let* ((probe (or (project-current) (cons 'transient default-directory
+(cl-find major-mode (gethash probe eglot--processes-by-project)
+ :key #'eglot--major-mode)))
 
 (defun eglot--current-process-or-lose ()
   "Return the current EGLOT process or error."
-  (or (eglot--current-process)
-  (eglot--error "No current EGLOT process%s"
-(if (project-current) "" " (Also no current project)"
+  (or (eglot--current-process) (eglot--error "No current EGLOT process")))
 
 (defmacro eglot--define-process-var
 (var-sym initval  doc)
@@ -326,11 +323,8 @@ MANAGED-MAJOR-MODE.
 
 INTERACTIVE is t if called interactively."
   (interactive (eglot--interactive))
-  (let* ((project (project-current))
+  (let* ((project (project-current 'maybe))
  (short-name (eglot--project-short-name project)))
-(unless project (eglot--error "Cannot work without a current project!"))
-(unless command (eglot--error "Don't know how to start EGLOT for %s 
buffers"
-  major-mode))
 (let ((current-process (eglot--current-process)))
   (if (and (process-live-p current-process)
interactive



[elpa] externals/elpa 71e47d2 102/139: Fix odd bugs and tweak stuff

2018-05-14 Thread Jo�o T�vora
branch: externals/elpa
commit 71e47d2091005cc69d679c2b5f8cb4f436b57c54
Author: João Távora 
Commit: João Távora 

Fix odd bugs and tweak stuff

* eglot.el (eglot--log-event): Insert before markers.
(eglot--process-receive): Shave lines.
(xref-backend-references): Use cl-return-from.
(eglot--log-event): Simplify
(eglot-completion-at-point): Saner annotation
---
 eglot.el | 23 +++
 1 file changed, 11 insertions(+), 12 deletions(-)

diff --git a/eglot.el b/eglot.el
index 37ad616..546671e 100644
--- a/eglot.el
+++ b/eglot.el
@@ -462,7 +462,7 @@ INTERACTIVE is t if called interactively."
 (when interactive (display-buffer buffer))
 buffer))
 
-(defun eglot--log-event (proc message type)
+(defun eglot--log-event (proc message  type)
   "Log an eglot-related event.
 PROC is the current process.  MESSAGE is a JSON-like plist.  TYPE
 is a symbol saying if this is a client or server originated."
@@ -477,7 +477,7 @@ is a symbol saying if this is a client or server 
originated."
   ;; pyls keeps on sending these
   (t 'unexpected-thingy)))
(type
-(format "%s-%s" type subtype)))
+(format "%s-%s" (or type :internal) subtype)))
   (goto-char (point-max))
   (let ((msg (format "%s%s%s:\n%s\n"
  type
@@ -486,7 +486,7 @@ is a symbol saying if this is a client or server 
originated."
  (pp-to-string message
 (when error
   (setq msg (propertize msg 'face 'error)))
-(insert msg)
+(insert-before-markers msg)
 
 (defun eglot--process-receive (proc message)
   "Process MESSAGE from PROC."
@@ -500,14 +500,12 @@ is a symbol saying if this is a client or server 
originated."
 (when err (setf (eglot--status proc) `(,err t)))
 (cond (method
;; a server notification or a server request
-   (let* ((handler-sym (intern (concat "eglot--server-"
-   method
+   (let* ((handler-sym (intern (concat "eglot--server-" method
  (if (functionp handler-sym)
  (apply handler-sym proc (append
   (plist-get message :params)
   (if id `(:id ,id
-   (eglot--warn "No implementation of method %s yet"
-method)
+   (eglot--warn "No implementation of method %s yet" method)
(when id
  (eglot--reply
   proc id
@@ -1264,7 +1262,8 @@ DUMMY is ignored"
  location-or-locations)))
 
 (cl-defmethod xref-backend-references ((_backend (eql eglot)) identifier)
-  (unless (eglot--server-capable :referencesProvider) (cl-return nil))
+  (unless (eglot--server-capable :referencesProvider)
+(cl-return-from xref-backend-references nil))
   (let ((params
  (or (get-text-property 0 :textDocumentPositionParams identifier)
  (let ((rich (car (member identifier eglot--xref-known-symbols
@@ -1316,10 +1315,10 @@ DUMMY is ignored"
:documentation documentation :sortText sortText))
  items
:annotation-function
-   (lambda (what) (let ((detail (get-text-property 0 :detail what))
-(kind-name (get-text-property 0 :kind what)))
-(concat (if detail (format " %s" detail) "")
-(if kind-name (format " (%s)" kind-name) ""
+   (lambda (what)
+ (propertize (concat " " (or (get-text-property 0 :detail what)
+ (get-text-property 0 :kind what)))
+ 'face 'font-lock-function-name-face))
:display-sort-function
(lambda (items) (sort items (lambda (a b)
  (string-lessp



[elpa] externals/eglot d33a9b5 103/139: Simplify eglot--signal-textDocument/didChange

2018-05-14 Thread Jo�o T�vora
branch: externals/eglot
commit d33a9b5ad9245cb594eb16e927f19741c4ef6a92
Author: João Távora 
Commit: João Távora 

Simplify eglot--signal-textDocument/didChange

* eglot.el (eglot--recent-before-changes)
(eglot--recent-after-changes): Delete.
(eglot--recent-changes): New var.
(eglot--outstanding-edits-p, eglot--before-change)
(eglot--after-change): Rewrite.
(eglot--signal-textDocument/didChange): Rewrite.
(eglot--signal-textDocument/didOpen): Initialize
buffer-local eglot--recent-changes here.
---
 eglot.el | 108 +++
 1 file changed, 46 insertions(+), 62 deletions(-)

diff --git a/eglot.el b/eglot.el
index 546671e..3eb43ce 100644
--- a/eglot.el
+++ b/eglot.el
@@ -1043,17 +1043,12 @@ running.  INTERACTIVE is t if called interactively."
(eglot--obj :code -32001
:message (format "%s" err))
 
-(defvar eglot--recent-before-changes nil
-  "List of recent changes as collected by `eglot--before-change'.")
-(defvar eglot--recent-after-changes nil
-  "List of recent changes as collected by `eglot--after-change'.")
-
-(defvar-local eglot--versioned-identifier 0)
-
 (defun eglot--current-buffer-TextDocumentIdentifier ()
   "Compute TextDocumentIdentifier object for current buffer."
   (eglot--obj :uri (eglot--path-to-uri buffer-file-name)))
 
+(defvar-local eglot--versioned-identifier 0)
+
 (defun eglot--current-buffer-VersionedTextDocumentIdentifier ()
   "Compute VersionedTextDocumentIdentifier object for current buffer."
   (append (eglot--current-buffer-TextDocumentIdentifier)
@@ -1077,78 +1072,67 @@ running.  INTERACTIVE is t if called interactively."
   (eglot--obj :textDocument (eglot--current-buffer-TextDocumentIdentifier)
   :position (eglot--pos-to-lsp-position)))
 
+(defvar-local eglot--recent-changes nil
+  "Recent buffer changes as collected by `eglot--before-change'.")
+
+(defun eglot--outstanding-edits-p ()
+  "Non-nil if there are outstanding edits."
+  (cl-plusp (+ (length (car eglot--recent-changes))
+   (length (cdr eglot--recent-changes)
+
 (defun eglot--before-change (start end)
   "Hook onto `before-change-functions'.
 Records START and END, crucially convert them into
 LSP (line/char) positions before that information is
 lost (because the after-change thingy doesn't know if newlines
 were deleted/added)"
-  (push (list (eglot--pos-to-lsp-position start)
-  (eglot--pos-to-lsp-position end))
-eglot--recent-before-changes))
+  (setf (car eglot--recent-changes)
+(vconcat (car eglot--recent-changes)
+ `[(,(eglot--pos-to-lsp-position start)
+,(eglot--pos-to-lsp-position end))])))
 
 (defun eglot--after-change (start end pre-change-length)
   "Hook onto `after-change-functions'.
 Records START, END and PRE-CHANGE-LENGTH locally."
   (cl-incf eglot--versioned-identifier)
-  (push (list start end pre-change-length
-  (buffer-substring-no-properties start end))
-eglot--recent-after-changes))
+  (setf (cdr eglot--recent-changes)
+(vconcat (cdr eglot--recent-changes)
+ `[(,pre-change-length
+,(buffer-substring-no-properties start end))])))
 
 (defun eglot--signal-textDocument/didChange ()
   "Send textDocument/didChange to server."
-  (unwind-protect
-  (when (or eglot--recent-before-changes
-eglot--recent-after-changes)
-(let* ((proc (eglot--current-process-or-lose))
-   (sync-kind (plist-get (eglot--capabilities proc)
- :textDocumentSync))
-   (emacs-messup
-(/= (length eglot--recent-before-changes)
-(length eglot--recent-after-changes)))
-   (full-sync-p (or (eq sync-kind 1) emacs-messup)))
-  (when emacs-messup
-(unless (eq sync-kind 1)
-  (eglot--warn "Using full sync because before: %s and after: %s"
-   eglot--recent-before-changes
-   eglot--recent-after-changes)))
-  (save-restriction
-(widen)
-(unless (or (not sync-kind)
-(eq sync-kind 0))
-  (eglot--notify
-   proc
-   :textDocument/didChange
-   (eglot--obj
-:textDocument
-(eglot--current-buffer-VersionedTextDocumentIdentifier)
-:contentChanges
-(if full-sync-p
-(vector
- (eglot--obj
-  :text (buffer-substring-no-properties (point-min)
-(point-max
-  (apply
-   #'vector
-   (mapcar
-(pcase-lambda (`(,before-start-position
-   

[elpa] externals/elpa ef80455 121/139: Support :completionItem/resolve

2018-05-14 Thread Jo�o T�vora
branch: externals/elpa
commit ef80455416426fea7bd4e80797365c5ed18bd66f
Author: João Távora 
Commit: João Távora 

Support :completionItem/resolve

This is quite handy with company and company-quickhelp

* eglot.el (eglot-completion-at-point): Send
:completionItem/resolve

* README.md: Mention completionItem/resolve
---
 README.md |  3 ++-
 eglot.el  | 38 +-
 2 files changed, 27 insertions(+), 14 deletions(-)

diff --git a/README.md b/README.md
index c2931be..8a94466 100644
--- a/README.md
+++ b/README.md
@@ -74,7 +74,7 @@ server. To skip the guess and always be prompted use `C-u M-x 
eglot`.
 
 ## Language features
 - [x] textDocument/completion
-- [ ] completionItem/resolve
+- [x] completionItem/resolve (works quite well with 
[company-mode][company-mode])
 - [x] textDocument/hover
 - [ ] textDocument/signatureHelp
 - [x] textDocument/definition
@@ -144,5 +144,6 @@ Under the hood:
 [emacs-lsp]: https://github.com/emacs-lsp/lsp-mode
 [emacs-lsp-plugins]: https://github.com/emacs-lsp
 [bash-language-server]: https://github.com/mads-hartmann/bash-language-server
+[company-mode]: https://github.com/company-mode/company-mode
 

diff --git a/eglot.el b/eglot.el
index 58a2374..3557303 100644
--- a/eglot.el
+++ b/eglot.el
@@ -1278,23 +1278,35 @@ DUMMY is ignored"
:textDocument/completion))
  (items (if (vectorp resp) resp (plist-get resp :items
 (eglot--mapply
- (eglot--lambda ( insertText label kind detail
-  documentation sortText )
-   (propertize (or insertText label)
-   :kind-name (cdr (assoc kind eglot--kind-names))
-   :detail detail
-   :documentation documentation :sortText sortText))
+ (eglot--lambda ( all  label )
+   (add-text-properties 0 1 all label) label)
  items
:annotation-function
-   (lambda (what)
- (propertize (concat " " (or (get-text-property 0 :detail what)
- (get-text-property 0 :kind what)))
+   (lambda (obj)
+ (propertize (concat " " (or (get-text-property 0 :detail obj)
+ (cdr (assoc (get-text-property 0 :kind 
obj)
+ eglot--kind-names
  'face 'font-lock-function-name-face))
:display-sort-function
-   (lambda (items) (sort items (lambda (a b)
- (string-lessp
-  (get-text-property 0 :sortText a)
-  (get-text-property 0 :sortText b)
+   (lambda (items)
+ (sort items (lambda (a b)
+   (string-lessp
+(or (get-text-property 0 :sortText a) "")
+(or (get-text-property 0 :sortText b) "")
+   :company-doc-buffer
+   (lambda (obj)
+ (let ((documentation
+(or (get-text-property 0 :documentation obj)
+(plist-get (eglot--request proc :completionItem/resolve
+   (text-properties-at 0 obj))
+   :documentation
+   (when documentation
+ (with-current-buffer (get-buffer-create " *eglot doc*")
+   (erase-buffer)
+   (ignore-errors (funcall (intern "markdown-mode")))
+   (font-lock-ensure)
+   (insert documentation)
+   (current-buffer)
:exit-function
(lambda (_string _status) (eglot-eldoc-function))
 



[elpa] externals/eglot dda11dd 095/139: Try to fix some textDocument/completion bugs

2018-05-14 Thread Jo�o T�vora
branch: externals/eglot
commit dda11dde6db5c91cdede6a10e9609aad3826bf2a
Author: João Távora 
Commit: João Távora 

Try to fix some textDocument/completion bugs

* eglot.el (eglot-completion-at-point): Rework slightly.
---
 eglot.el | 20 +---
 1 file changed, 9 insertions(+), 11 deletions(-)

diff --git a/eglot.el b/eglot.el
index d7ea329..2e409ef 100644
--- a/eglot.el
+++ b/eglot.el
@@ -1274,13 +1274,13 @@ DUMMY is ignored"
 
 (defun eglot-completion-at-point ()
   "EGLOT's `completion-at-point' function."
-  (let ((bounds (bounds-of-thing-at-point 'sexp))
+  (let ((bounds (bounds-of-thing-at-point 'symbol))
 (proc (eglot--current-process-or-lose)))
 (when (eglot--server-capable :completionProvider)
   (list
(or (car bounds) (point))
(or (cdr bounds) (point))
-   (completion-table-dynamic
+   (completion-table-with-cache
 (lambda (_ignored)
   (let* ((resp (eglot--sync-request
 proc
@@ -1291,19 +1291,17 @@ DUMMY is ignored"
  (items (if (vectorp resp) resp (plist-get resp :items
 (eglot--mapply
  (eglot--lambda ( insertText label kind detail
-  documentation sortText)
-   (propertize insertText
-   :label label :kind kind :detail detail
+  documentation sortText )
+   (propertize (or insertText label)
+   :kind-name (cdr (assoc kind eglot--kind-names))
+   :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)))
-  ""
+(kind-name (get-text-property 0 :kind what)))
+(concat (if detail (format " %s" detail) "")
+(if kind-name (format " (%s)" kind-name) ""
:display-sort-function
(lambda (items) (sort items (lambda (a b)
  (string-lessp



[elpa] externals/eglot 3a6c637 099/139: Support textDocument/rename

2018-05-14 Thread Jo�o T�vora
branch: externals/eglot
commit 3a6c63723370e71b992d21019fbf863d569d024a
Author: João Távora 
Commit: João Távora 

Support textDocument/rename

* README.md: Mention rename support.

* eglot.el (eglot--uri-to-path): Handle uri hidden in keywords.
(eglot--apply-text-edits): New helper.
(eglot-rename): New interactive command.
(eglot--client-capabilities): Add rename capability.
---
 README.md |  2 +-
 eglot.el  | 58 ++
 2 files changed, 59 insertions(+), 1 deletion(-)

diff --git a/README.md b/README.md
index 5838bc5..a8d1c8b 100644
--- a/README.md
+++ b/README.md
@@ -39,7 +39,7 @@ server. To skip the guess and always be prompted use `C-u M-x 
eglot`.
 - [ ] textDocument/executeCommand
 - [ ] textDocument/format
 - [x] textDocument/hover
-- [ ] textDocument/rename
+- [x] textDocument/rename
 - [x] textDocument/references
 - [ ] textDocument/signatureHelp
 - [x] workspace/symbol
diff --git a/eglot.el b/eglot.el
index c5c99f2..9ba87ef 100644
--- a/eglot.el
+++ b/eglot.el
@@ -199,6 +199,7 @@ CONTACT is as `eglot--contact'.  Returns a process object."
   :definition `(:dynamicRegistration :json-false)
   :documentSymbol `(:dynamicRegistration :json-false)
   :documentHighlight  `(:dynamicRegistration :json-false)
+  :rename `(:dynamicRegistration :json-false)
   :publishDiagnostics `(:relatedInformation :json-false))
:experimental (eglot--obj)))
 
@@ -729,6 +730,7 @@ Meaning only return locally if successful, otherwise exit 
non-locally."
 
 (defun eglot--uri-to-path (uri)
   "Convert URI to a file path."
+  (when (keywordp uri) (setq uri (substring (symbol-name uri) 1)))
   (url-filename (url-generic-parse-url (url-unhex-string uri
 
 (defconst eglot--kind-names
@@ -1368,6 +1370,62 @@ DUMMY is ignored"
  entries))
 (funcall oldfun)))
 
+(defun eglot--apply-text-edits (uri edits proc  version)
+  "Apply the EDITS for buffer of URI and return it."
+  (let* ((path (eglot--uri-to-path uri))
+ (buffer (and path
+  (find-file-noselect path
+(unless buffer
+  (eglot--error "Can't find `%s' to perform server edits"))
+(with-current-buffer buffer
+  (unless (eq proc (eglot--current-process))
+(eglot--error "Buffer `%s' for `%s' isn't managed by %s"
+  (current-buffer) uri proc))
+  (unless (or (not version)
+  (equal version eglot--versioned-identifier))
+(eglot--error "Edits on `%s' require version %d, you have %d"
+  uri version eglot--versioned-identifier))
+  (eglot--mapply
+   (eglot--lambda ( range newText)
+ (save-restriction
+   (widen)
+   (save-excursion
+ (let ((start (eglot--lsp-position-to-point (plist-get range 
:start
+   (goto-char start)
+   (delete-region start
+  (eglot--lsp-position-to-point (plist-get range 
:end)))
+   (insert newText)
+   edits)
+  (eglot--message "%s: %s edits" (current-buffer) (length edits)))
+buffer))
+
+(defun eglot-rename (newname)
+  "Rename the current symbol to NEWNAME."
+  (interactive
+   (list
+(read-from-minibuffer (format "Rename `%s' to: " (symbol-at-point)
+  (unless (eglot--server-capable :renameProvider)
+(eglot--error "Server can't rename!"))
+  (let* ((proc (eglot--current-process-or-lose))
+ (workspace-edit
+  (eglot--sync-request proc
+   :textDocument/rename
+   (append
+
(eglot--current-buffer-TextDocumentPositionParams)
+(eglot--obj :newName newname
+ performed)
+(cl-destructuring-bind ( changes documentChanges)
+workspace-edit
+  (cl-loop for change on documentChanges
+   do (push
+   (cl-destructuring-bind ( textDocument edits) change
+ (cl-destructuring-bind ( uri version) textDocument
+   (eglot--apply-text-edits uri edits proc version)))
+   performed))
+  (cl-loop for (uri edits) on changes by #'cddr
+   do (push (eglot--apply-text-edits uri edits proc)
+performed)
+
 
 ;;; Dynamic registration
 ;;;



[elpa] externals/elpa 56cf02d 126/139: Rework autoreconnection logic

2018-05-14 Thread Jo�o T�vora
branch: externals/elpa
commit 56cf02da4e832e6f38ff9aa9a3fffb1002710b8b
Author: João Távora 
Commit: João Távora 

Rework autoreconnection logic

Can't be a global var, has to be a per process thing.

* eglot.el (eglot-autoreconnect): New defcustom
(eglot--inhibit-autoreconnect): Renamed from eglot--inhibit-autoreconnect
(eglot--connect): Run autoreconnect timer here.
(eglot--inhibit-auto-reconnect): Removed.
(eglot--process-sentinel): Don't run timer here. Rework.
(eglot, eglot-reconnect): Pass INTERACTIVE to eglot--connect.
---
 eglot.el | 57 +++--
 1 file changed, 35 insertions(+), 22 deletions(-)

diff --git a/eglot.el b/eglot.el
index 3b3aada..aabaf54 100644
--- a/eglot.el
+++ b/eglot.el
@@ -59,9 +59,19 @@
   "Face for package-name in EGLOT's mode line.")
 
 (defcustom eglot-request-timeout 10
-  "How many seconds to way for a reply from the server."
+  "How many seconds to wait for a reply from the server."
   :type :integer)
 
+(defcustom eglot-autoreconnect 3
+  "Control EGLOT's ability to reconnect automatically.
+If t, always reconnect automatically (not recommended).  If nil,
+never reconnect automatically after unexpected server shutdowns,
+crashes or network failures.  A positive integer number says to
+only autoreconnect if the previous successful connection attempt
+lasted more than that many seconds."
+  :type '(choice (boolean :tag "Whether to inhibit autoreconnection")
+ (integer :tag "Number of seconds")))
+
 
 ;;; Process management
 (defvar eglot--processes-by-project (make-hash-table :test #'equal)
@@ -129,6 +139,9 @@ A list (ID WHAT DONE-P).")
   "Status as declared by the server.
 A list (WHAT SERIOUS-P).")
 
+(eglot--define-process-var eglot--inhibit-autoreconnect eglot-autoreconnect
+  "If non-nil, don't autoreconnect on unexpected quit.")
+
 (eglot--define-process-var eglot--contact nil
   "Method used to contact a server.
 Either a list of strings (a shell command and arguments), or a
@@ -206,8 +219,9 @@ CONTACT is as `eglot--contact'.  Returns a process object."
   :publishDiagnostics `(:relatedInformation :json-false))
:experimental (eglot--obj)))
 
-(defun eglot--connect (project managed-major-mode short-name contact)
-  "Connect for PROJECT, MANAGED-MAJOR-MODE, SHORT-NAME and CONTACT."
+(defun eglot--connect (project managed-major-mode short-name contact 
interactive)
+  "Connect for PROJECT, MANAGED-MAJOR-MODE, SHORT-NAME and CONTACT.
+INTERACTIVE is t if inside interactive call."
   (let* ((proc (eglot--make-process short-name managed-major-mode contact))
  (buffer (process-buffer proc)))
 (setf (eglot--contact proc) contact
@@ -215,6 +229,15 @@ CONTACT is as `eglot--contact'.  Returns a process object."
   (eglot--major-mode proc) managed-major-mode)
 (with-current-buffer buffer
   (let ((inhibit-read-only t))
+(setf (eglot--inhibit-autoreconnect proc)
+  (cond
+   ((booleanp eglot-autoreconnect) (not eglot-autoreconnect))
+   (interactive nil)
+   ((cl-plusp eglot-autoreconnect)
+(run-with-timer eglot-autoreconnect nil
+(lambda ()
+  (setf (eglot--inhibit-autoreconnect proc)
+(null eglot-autoreconnect)))
 (setf (eglot--short-name proc) short-name)
 (push proc (gethash project eglot--processes-by-project))
 (erase-buffer)
@@ -317,7 +340,8 @@ INTERACTIVE is t if called interactively."
 (let ((proc (eglot--connect project
 managed-major-mode
 short-name
-command)))
+command
+interactive)))
   (eglot--message "Connected! Process `%s' now \
 managing `%s' buffers in project `%s'."
   proc managed-major-mode short-name))
@@ -331,12 +355,10 @@ INTERACTIVE is t if called interactively."
   (eglot--connect (eglot--project process)
   (eglot--major-mode process)
   (eglot--short-name process)
-  (eglot--contact process))
+  (eglot--contact process)
+  interactive)
   (eglot--message "Reconnected!"))
 
-(defvar eglot--inhibit-auto-reconnect nil
-  "If non-nil, don't autoreconnect on unexpected quit.")
-
 (defun eglot--process-sentinel (proc change)
   "Called when PROC undergoes CHANGE."
   (eglot--log-event proc `(:message "Process state changed" :change ,change))
@@ -364,22 +386,13 @@ INTERACTIVE is t if called interactively."
   (setf (gethash (eglot--project proc) eglot--processes-by-project)
 (delq proc
   (gethash (eglot--project proc) 

[elpa] externals/elpa d254f97 082/139: Solve another textDocument/didChange bug

2018-05-14 Thread Jo�o T�vora
branch: externals/elpa
commit d254f974e1991f3787da5c06a76da33ab1181548
Author: João Távora 
Commit: João Távora 

Solve another textDocument/didChange bug

* eglot.el (eglot--signal-textDocument/didChange): Rework a bit.
(eglot--after-change): Store the actual after-text in the
eglot--recent-after-changes.
---
 eglot.el | 99 
 1 file changed, 56 insertions(+), 43 deletions(-)

diff --git a/eglot.el b/eglot.el
index 045588d..f6bf010 100644
--- a/eglot.el
+++ b/eglot.el
@@ -1128,52 +1128,65 @@ were deleted/added)"
   "Hook onto `after-change-functions'.
 Records START, END and PRE-CHANGE-LENGTH locally."
   (cl-incf eglot--versioned-identifier)
-  (push (list start end pre-change-length) eglot--recent-after-changes))
+  (push (list start end pre-change-length
+  (buffer-substring-no-properties start end))
+eglot--recent-after-changes))
 
 (defun eglot--signal-textDocument/didChange ()
   "Send textDocument/didChange to server."
-  (when (and eglot--recent-before-changes
- eglot--recent-after-changes)
-(let* ((proc (eglot--current-process-or-lose))
-   (sync-kind (plist-get (eglot--capabilities proc) 
:textDocumentSync)))
-  (save-restriction
-(widen)
-(unless (or (not sync-kind)
-(eq sync-kind 0))
-  (eglot--notify
-   proc
-   :textDocument/didChange
-   (eglot--obj
-:textDocument
-(eglot--current-buffer-VersionedTextDocumentIdentifier)
-:contentChanges
-(if (or (eq sync-kind 1)
-(/= (length eglot--recent-before-changes)
-(length eglot--recent-after-changes)))
-(vector
- (eglot--obj
-  :text (buffer-substring-no-properties (point-min) 
(point-max
-  (apply
-   #'vector
-   (mapcar
-(pcase-lambda (`(,before-start-position
- ,before-end-position
- ,after-start
- ,after-end
- ,len))
-  (eglot--obj
-   :range
-   (eglot--obj
-:start before-start-position
-:end before-end-position)
-   :rangeLength len
-   :text (buffer-substring-no-properties after-start 
after-end)))
-(reverse
- (cl-mapcar 'append
-eglot--recent-before-changes
-eglot--recent-after-changes)))
-  (setq eglot--recent-before-changes nil
-eglot--recent-after-changes nil))
+  (unwind-protect
+  (when (or eglot--recent-before-changes
+eglot--recent-after-changes)
+(let* ((proc (eglot--current-process-or-lose))
+   (sync-kind (plist-get (eglot--capabilities proc)
+ :textDocumentSync))
+   (emacs-messup
+(/= (length eglot--recent-before-changes)
+(length eglot--recent-after-changes)))
+   (full-sync-p (or (eq sync-kind 1) emacs-messup)))
+  (when emacs-messup
+(unless (eq sync-kind 1)
+  (eglot--warn "Using full sync because before: %s and after: %s"
+   eglot--recent-before-changes
+   eglot--recent-after-changes)))
+  (save-restriction
+(widen)
+(unless (or (not sync-kind)
+(eq sync-kind 0))
+  (eglot--notify
+   proc
+   :textDocument/didChange
+   (eglot--obj
+:textDocument
+(eglot--current-buffer-VersionedTextDocumentIdentifier)
+:contentChanges
+(if full-sync-p
+(vector
+ (eglot--obj
+  :text (buffer-substring-no-properties (point-min)
+(point-max
+  (apply
+   #'vector
+   (mapcar
+(pcase-lambda (`(,before-start-position
+ ,before-end-position
+ ,_after-start
+ ,_after-end
+ ,len
+ ,after-text))
+  (eglot--obj
+   :range
+   (eglot--obj
+:start before-start-position
+:end before-end-position)
+   :rangeLength len
+   :text after-text))
+(reverse
+

[elpa] externals/elpa f89f859 114/139: Simplify mode-line updating logic

2018-05-14 Thread Jo�o T�vora
branch: externals/elpa
commit f89f859eb71597f4ba7327d8758c2e9c7afb67fe
Author: João Távora 
Commit: João Távora 

Simplify mode-line updating logic

* eglot.el (eglot--define-process-var): Simplify.
(eglot--short-name, eglot--spinner, eglot--status): Don't
auto-update mode-line.
(eglot--process-receive): Update it here.
---
 eglot.el | 24 +---
 1 file changed, 9 insertions(+), 15 deletions(-)

diff --git a/eglot.el b/eglot.el
index 1ba5324..bf0b9e9 100644
--- a/eglot.el
+++ b/eglot.el
@@ -78,11 +78,9 @@
 (if (project-current) "" " (Also no current project)"
 
 (defmacro eglot--define-process-var
-(var-sym initval  doc mode-line-update-p)
+(var-sym initval  doc)
   "Define VAR-SYM as a generalized process-local variable.
-INITVAL is the default value.  DOC is the documentation.
-MODE-LINE-UPDATE-P says to also force a mode line update
-after setting it."
+INITVAL is the default value.  DOC is the documentation."
   (declare (indent 2))
   `(progn
  (put ',var-sym 'function-documentation ,doc)
@@ -94,16 +92,11 @@ after setting it."
(let ((def ,initval))
  (process-put proc ',var-sym def)
  def
- (gv-define-setter ,var-sym (to-store  process)
-   (let* ((prop ',var-sym))
- ,(let ((form '(let ((proc (or ,process 
(eglot--current-process-or-lose
- (process-put proc ',prop ,to-store
-(if mode-line-update-p
-`(backquote (prog1 ,form (force-mode-line-update t)))
-  `(backquote ,form)))
+ (gv-define-setter ,var-sym (to-store process)
+   `(let ((once ,to-store)) (process-put ,process ',',var-sym once) 
once
 
 (eglot--define-process-var eglot--short-name nil
-  "A short name for the process" t)
+  "A short name for the process")
 
 (eglot--define-process-var eglot--major-mode nil
   "The major-mode this server is managing.")
@@ -128,11 +121,11 @@ after setting it."
 
 (eglot--define-process-var eglot--spinner `(nil nil t)
   "\"Spinner\" used by some servers.
-A list (ID WHAT DONE-P)." t)
+A list (ID WHAT DONE-P).")
 
 (eglot--define-process-var eglot--status `(:unknown nil)
   "Status as declared by the server.
-A list (WHAT SERIOUS-P)." t)
+A list (WHAT SERIOUS-P).")
 
 (eglot--define-process-var eglot--contact nil
   "Method used to contact a server.
@@ -531,7 +524,8 @@ is a symbol saying if this is a client or server 
originated."
(apply (cl-first continuations) res)
  (funcall (cl-first continuations) res)
   (id
-   (eglot--warn "Ooops no continuation for id %s" id)
+   (eglot--warn "Ooops no continuation for id %s" id)))
+(force-mode-line-update t)))
 
 (defvar eglot--expect-carriage-return nil)
 



[elpa] externals/eglot 193c57d 075/139: Half-decent xref support

2018-05-14 Thread Jo�o T�vora
branch: externals/eglot
commit 193c57d02872f8fd17b652514c553835d932d2e9
Author: João Távora 
Commit: João Távora 

Half-decent xref support

* eglot.el
(eglot--xref-known-symbols): New hacky var.
(eglot--xref-reset-known-symbols): New helper.
(xref-find-definitions, xref-find-references): Advise after to
call the new helper.
(xref-backend-identifier-completion-table): Rework.
(eglot--xref-make): New helper.
(xref-backend-definitions): Use it.
(xref-backend-references, xref-backend-apropos): Implement.
(eglot--obj): Add a debug spec.
(eglot--lambda): Add debug spec.
---
 eglot.el | 132 +++
 1 file changed, 90 insertions(+), 42 deletions(-)

diff --git a/eglot.el b/eglot.el
index ad9ad52..cb92361 100644
--- a/eglot.el
+++ b/eglot.el
@@ -33,6 +33,7 @@
 (require 'compile) ; for some faces
 (require 'warnings)
 (require 'flymake)
+(require 'xref)
 
 
 ;;; User tweakable stuff
@@ -171,6 +172,7 @@ CONTACT is as `eglot--contact'.  Returns a process object."
 
 (defmacro eglot--obj ( what)
   "Make WHAT a suitable argument for `json-encode'."
+  (declare (debug ( form)))
   ;; FIXME: maybe later actually do something, for now this just fixes
   ;; the indenting of literal plists.
   `(list ,@what))
@@ -736,7 +738,7 @@ Meaning only return locally if successful, otherwise exit 
non-locally."
   (mapcar (lambda (e) (apply fun e)) seq))
 
 (cl-defmacro eglot--lambda (cl-lambda-list  body)
-  (declare (indent 1))
+  (declare (indent 1) (debug (sexp  form)))
   `(cl-function
 (lambda ,cl-lambda-list
   ,@body)))
@@ -1232,16 +1234,46 @@ Calls REPORT-FN maybe if server publishes diagnostics 
in time."
 
 (defun eglot-xref-backend () "EGLOT xref backend." 'eglot)
 
+(defvar eglot--xref-known-symbols nil)
+
+(defun eglot--xref-reset-known-symbols ()
+  "Reset `eglot--xref-reset-known-symbols'."
+  (setq eglot--xref-known-symbols nil))
+
+(advice-add 'xref-find-definitions :after #'eglot--xref-reset-known-symbols)
+(advice-add 'xref-find-references :after #'eglot--xref-reset-known-symbols)
+
+(defun eglot--xref-make (name uri position)
+  "Like `xref-make' but with LSP's NAME, URI and POSITION."
+  (xref-make name
+ (xref-make-file-location
+  (eglot--uri-to-path uri)
+  ;; F!@(#*

[elpa] externals/eglot ff5a03d 074/139: Very basic xref support

2018-05-14 Thread Jo�o T�vora
branch: externals/eglot
commit ff5a03dd81d543847cee9679a20bdb39539f1a70
Author: João Távora 
Commit: João Távora 

Very basic xref support

* eglot.el (eglot--pos-to-lisp-position): Move up.
(eglot--mapply, eglot--lambda): New helpers.
(eglot--uri-to-path): New helper.
(eglot--managed-mode): Manage xref-backend-functions.
(eglot-xref-backend): New function.
(xref-backend-identifier-completion-table)
(xref-backend-identifier-at-point)
(xref-backend-definitions): New methods.
(xref-backend-references)
(xref-backend-apropos): New methods, still unimplemented.
---
 eglot.el | 93 
 1 file changed, 82 insertions(+), 11 deletions(-)

diff --git a/eglot.el b/eglot.el
index 34ce0f8..ad9ad52 100644
--- a/eglot.el
+++ b/eglot.el
@@ -721,12 +721,36 @@ Meaning only return locally if successful, otherwise exit 
non-locally."
  (apply #'format format args)
  :warning)))
 
+(defun eglot--pos-to-lsp-position ( pos)
+  "Convert point POS to LSP position."
+  (save-excursion
+(eglot--obj :line
+;; F!@(#*

[elpa] externals/elpa eebd32b 059/139: When user declines to reconnect, first quit existing server

2018-05-14 Thread Jo�o T�vora
branch: externals/elpa
commit eebd32ba393c2f2ca786241f376d218725d16270
Author: João Távora 
Commit: João Távora 

When user declines to reconnect, first quit existing server

* eglot.el (eglot): Rework reconnection logic.
---
 eglot.el | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/eglot.el b/eglot.el
index c5a0c0f..3d0c044 100644
--- a/eglot.el
+++ b/eglot.el
@@ -293,13 +293,15 @@ Execute program (or connect to :) "
   (y-or-n-p "[eglot] Live process found, reconnect instead? "))
  (eglot-reconnect current-process interactive))
 (t
+ (when (process-live-p current-process)
+   (eglot-shutdown current-process 'sync))
  (eglot--connect
   project
   managed-major-mode
   short-name
   command
   (lambda (proc)
-(eglot--message "Connected! Process `%s' now managing `%s'\
+(eglot--message "Connected! Process `%s' now managing `%s' \
 buffers in project %s."
 proc
 managed-major-mode



[elpa] externals/elpa 8a80fb7 105/139: Simplify `eglot-shutdown`

2018-05-14 Thread Jo�o T�vora
branch: externals/elpa
commit 8a80fb7d5b93c92591958e9b08caafc302521de0
Author: João Távora 
Commit: João Távora 

Simplify `eglot-shutdown`

* eglot.el (eglot, eglot-reconnect)
(eglot--managed-mode): Call new eglot-shutdown.
(eglot-shutdown): Simplify.
(eglot--process-sentinel): Also call error functions.
(eglot--process-filter): Reindent.
---
 eglot.el | 146 +--
 1 file changed, 66 insertions(+), 80 deletions(-)

diff --git a/eglot.el b/eglot.el
index bed98ed..0795bc3 100644
--- a/eglot.el
+++ b/eglot.el
@@ -310,7 +310,7 @@ INTERACTIVE is t if called interactively."
(y-or-n-p "[eglot] Live process found, reconnect instead? "))
   (eglot-reconnect current-process interactive)
 (when (process-live-p current-process)
-  (eglot-shutdown current-process 'sync))
+  (eglot-shutdown current-process))
 (eglot--connect project
 managed-major-mode
 short-name
@@ -327,7 +327,7 @@ managing `%s' buffers in project `%s'."
 INTERACTIVE is t if called interactively."
   (interactive (list (eglot--current-process-or-lose) t))
   (when (process-live-p process)
-(eglot-shutdown process 'sync interactive))
+(eglot-shutdown process interactive))
   (eglot--connect (eglot--project process)
   (eglot--major-mode process)
   (eglot--short-name process)
@@ -341,13 +341,12 @@ INTERACTIVE is t if called interactively."
   "Called with PROCESS undergoes CHANGE."
   (eglot--debug "(sentinel) Process state changed to %s" change)
   (when (not (process-live-p process))
-;; Remember to cancel all timers
+;; Cancel timers and error any outstanding continuations
 ;;
-(maphash (lambda (id triplet)
-   (cl-destructuring-bind (_success _error timeout) triplet
- (eglot--message
-  "(sentinel) Cancelling timer for continuation %s" id)
- (cancel-timer timeout)))
+(maphash (lambda (_id triplet)
+   (cl-destructuring-bind (_success error timeout) triplet
+ (cancel-timer timeout)
+ (funcall error :code -1 :message (format "Server died"
  (eglot--pending-continuations process))
 ;; Turn off `eglot--managed-mode' where appropriate.
 ;;
@@ -400,46 +399,47 @@ INTERACTIVE is t if called interactively."
 (unwind-protect
 (catch done
   (while t
-(cond ((not expected-bytes)
-   ;; Starting a new message
-   ;;
-   (setq expected-bytes
- (and (search-forward-regexp
-   "\\(?:.*: .*\r\n\\)*Content-Length: \
+(cond
+ ((not expected-bytes)
+  ;; Starting a new message
+  ;;
+  (setq expected-bytes
+(and (search-forward-regexp
+  "\\(?:.*: .*\r\n\\)*Content-Length: \
 *\\([[:digit:]]+\\)\r\n\\(?:.*: .*\r\n\\)*\r\n"
-   (+ (point) 100)
-   t)
-  (string-to-number (match-string 1
-   (unless expected-bytes
- (throw done :waiting-for-new-message)))
-  (t
-   ;; Attempt to complete a message body
-   ;;
-   (let ((available-bytes (- (position-bytes (process-mark 
proc))
- (position-bytes (point)
- (cond
-  ((>= available-bytes
-   expected-bytes)
-   (let* ((message-end (byte-to-position
-(+ (position-bytes (point))
-   expected-bytes
- (unwind-protect
- (save-restriction
-   (narrow-to-region (point) message-end)
-   (let* ((json-object-type 'plist)
-  (json-message (json-read)))
- ;; Process content in another buffer,
- ;; shielding buffer from tamper
- ;;
- (with-temp-buffer
-   (eglot--process-receive proc 
json-message
-   (goto-char message-end)
-   (delete-region (point-min) (point))
-   (setq expected-bytes nil
-  (t
-  

[elpa] externals/elpa 05c67ee 112/139: Adjust flymake integration

2018-05-14 Thread Jo�o T�vora
branch: externals/elpa
commit 05c67eece9a94cf9f8ee58b18fb4a1318b2425b3
Author: João Távora 
Commit: João Távora 

Adjust flymake integration

When opening a new file (signalling textDocument/didOpen) it makes
sense to call the flymake callback (if it exists) with no diagnostics,
just to get rid of that "Wait", since we don't know if later in this
callback cycle the server will ever report new diagnostics.

* eglot.el (eglot--managed-mode): Don't call flymake-mode or eldoc-mode
(eglot--managed-mode-hook): Add them here.
(eglot--maybe-activate-editing-mode): Call flymake callback.
(eglot--server-textDocument/publishDiagnostics): Set unreported
diagnostics to nil if invoking callback.
---
 eglot.el | 29 ++---
 1 file changed, 14 insertions(+), 15 deletions(-)

diff --git a/eglot.el b/eglot.el
index 21ec247..f865c22 100644
--- a/eglot.el
+++ b/eglot.el
@@ -798,9 +798,7 @@ DEFERRED is passed to `eglot--request', which see."
 (add-hook 'completion-at-point-functions #'eglot-completion-at-point nil t)
 (add-function :before-until (local 'eldoc-documentation-function)
   #'eglot-eldoc-function)
-(add-function :around (local imenu-create-index-function) #'eglot-imenu)
-(flymake-mode 1)
-(eldoc-mode 1))
+(add-function :around (local imenu-create-index-function) #'eglot-imenu))
(t
 (remove-hook 'flymake-diagnostic-functions 'eglot-flymake-backend t)
 (remove-hook 'after-change-functions 'eglot--after-change t)
@@ -818,6 +816,9 @@ DEFERRED is passed to `eglot--request', which see."
   (when (and (process-live-p proc) (y-or-n-p "[eglot] Kill server too? "))
 (eglot-shutdown proc t))
 
+(add-hook 'eglot--managed-mode-hook 'flymake-mode)
+(add-hook 'eglot--managed-mode-hook 'eldoc-mode)
+
 (defun eglot--buffer-managed-p ( proc)
   "Tell if current buffer is managed by PROC."
   (and buffer-file-name (let ((cur (eglot--current-process)))
@@ -832,7 +833,8 @@ that case, also signal textDocument/didOpen."
   (when (eglot--buffer-managed-p proc)
 (eglot--managed-mode 1)
 (eglot--signal-textDocument/didOpen)
-(flymake-start)))
+(flymake-start)
+(funcall (or eglot--current-flymake-report-fn #'ignore) nil)))
 
 (add-hook 'find-file-hook 'eglot--maybe-activate-editing-mode)
 
@@ -999,11 +1001,11 @@ called interactively."
   (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)
+ finally (cond (eglot--current-flymake-report-fn
+(funcall eglot--current-flymake-report-fn diags)
+(setq eglot--unreported-diagnostics nil))
+   (t
+(setq eglot--unreported-diagnostics diags))
  (t
   (eglot--message "OK so %s isn't visited" filename)
 
@@ -1174,15 +1176,12 @@ Records START, END and PRE-CHANGE-LENGTH locally."
 (defun eglot-flymake-backend (report-fn  _more)
   "An EGLOT Flymake backend.
 Calls REPORT-FN maybe if server publishes diagnostics in time."
-  ;; Maybe call immediately if anything unreported (this will clear
-  ;; any pending diags)
+  (setq eglot--current-flymake-report-fn report-fn)
+  ;; Report anything unreported
   (when eglot--unreported-diagnostics
 (funcall report-fn eglot--unreported-diagnostics)
 (setq eglot--unreported-diagnostics nil))
-  ;; Setup so maybe it's called later, too.
-  (setq eglot--current-flymake-report-fn report-fn)
-  ;; Take this opportunity to signal a didChange that might eventually
-  ;; make the server report new diagnostics.
+  ;; Signal a didChange that might eventually bring new diagnotics
   (eglot--signal-textDocument/didChange))
 
 (defun eglot-xref-backend ()



[elpa] externals/elpa ab575d2 120/139: Rename functions. eglot--request is now the synchronous one

2018-05-14 Thread Jo�o T�vora
branch: externals/elpa
commit ab575d229c5a93916ffb33517f89bf75b27d5b33
Author: João Távora 
Commit: João Távora 

Rename functions. eglot--request is now the synchronous one

* eglot.el (eglot--connect, eglot-shutdown)
(xref-backend-identifier-completion-table)
(xref-backend-definitions, xref-backend-references)
(xref-backend-apropos, eglot-completion-at-point, eglot-rename):
Call eglot--request.
(eglot--async-request): Renamed from eglot--request.
(eglot--request): Renamed from eglot--sync-request.
(eglot--TextDocumentIdentifier)
(eglot--VersionedTextDocumentIdentifier)
(eglot--TextDocumentPositionParams, eglot--TextDocumentItem):
Renamed from the more verbose eglot--current-buffer-* variante.
(eglot-rename, eglot-imenu, eglot-eldoc-function)
(eglot-completion-at-point, xref-backend-definitions)
(xref-backend-identifier-at-point)
(eglot--signal-textDocument/didSave)
(xref-backend-identifier-completion-table)
(eglot--signal-textDocument/didClose)
(eglot--signal-textDocument/didOpen)
(eglot--signal-textDocument/didChange): Use new function names.
---
 eglot.el | 140 +++
 1 file changed, 68 insertions(+), 72 deletions(-)

diff --git a/eglot.el b/eglot.el
index 22799cc..58a2374 100644
--- a/eglot.el
+++ b/eglot.el
@@ -219,7 +219,7 @@ CONTACT is as `eglot--contact'.  Returns a process object."
 (erase-buffer)
 (read-only-mode t)
 (cl-destructuring-bind ( capabilities)
-(eglot--sync-request
+(eglot--request
  proc
  :initialize
  (eglot--obj :processId (unless (eq (process-type proc)
@@ -558,9 +558,9 @@ is a symbol saying if this is a client or server 
originated."
 
 (defvar eglot--ready-predicates '(eglot--server-ready-p)
   "Special hook of predicates controlling deferred actions.
-When one of these functions returns nil, a deferrable
-`eglot--request' will be deferred.  Each predicate is passed the
-an symbol for the request request and a process object.")
+If one of these returns nil, a deferrable `eglot--async-request'
+will be deferred.  Each predicate is passed the symbol for the
+request request and a process object.")
 
 (defun eglot--server-ready-p (_what _proc)
   "Tell if server of PROC ready for processing deferred WHAT."
@@ -570,13 +570,13 @@ an symbol for the request request and a process object.")
   (declare (indent 1) (debug (sexp  form)))
   `(cl-function (lambda ,cl-lambda-list ,@body)))
 
-(cl-defun eglot--request (proc
-  method
-  params
-   args
-   success-fn error-fn timeout-fn
-  (timeout eglot-request-timeout)
-  (deferred nil))
+(cl-defun eglot--async-request (proc
+method
+params
+ args
+ success-fn error-fn timeout-fn
+(timeout eglot-request-timeout)
+(deferred nil))
   "Make a request to PROCESS, expecting a reply.
 Return the ID of this request. Wait TIMEOUT seconds for response.
 If DEFERRED, maybe defer request to the future, or never at all,
@@ -610,11 +610,11 @@ timeout keeps counting."
   (when (buffer-live-p buf)
 (with-current-buffer buf
   (save-excursion (goto-char point)
-  (apply #'eglot--request proc
+  (apply #'eglot--async-request 
proc
  method params args)))
 (puthash (list deferred buf) (list later (funcall make-timeout))
  (eglot--deferred-actions proc))
-(cl-return-from eglot--request nil)
+(cl-return-from eglot--async-request nil)
 ;; Really run it
 ;;
 (puthash id
@@ -634,17 +634,17 @@ timeout keeps counting."
   :method method
   :params params
 
-(defun eglot--sync-request (proc method params  deferred)
-  "Like `eglot--request' for PROC, METHOD and PARAMS, but synchronous.
+(defun eglot--request (proc method params  deferred)
+  "Like `eglot--async-request' for PROC, METHOD and PARAMS, but synchronous.
 Meaning only return locally if successful, otherwise exit non-locally.
-DEFERRED is passed to `eglot--request', which see."
+DEFERRED is passed to `eglot--async-request', which see."
   ;; Launching a deferred sync request with outstanding changes is a
   ;; bad idea, since that might lead to the request never having a
   ;; chance to run, because `eglot--ready-predicates'.
   

[elpa] externals/elpa ff5a03d 074/139: Very basic xref support

2018-05-14 Thread Jo�o T�vora
branch: externals/elpa
commit ff5a03dd81d543847cee9679a20bdb39539f1a70
Author: João Távora 
Commit: João Távora 

Very basic xref support

* eglot.el (eglot--pos-to-lisp-position): Move up.
(eglot--mapply, eglot--lambda): New helpers.
(eglot--uri-to-path): New helper.
(eglot--managed-mode): Manage xref-backend-functions.
(eglot-xref-backend): New function.
(xref-backend-identifier-completion-table)
(xref-backend-identifier-at-point)
(xref-backend-definitions): New methods.
(xref-backend-references)
(xref-backend-apropos): New methods, still unimplemented.
---
 eglot.el | 93 
 1 file changed, 82 insertions(+), 11 deletions(-)

diff --git a/eglot.el b/eglot.el
index 34ce0f8..ad9ad52 100644
--- a/eglot.el
+++ b/eglot.el
@@ -721,12 +721,36 @@ Meaning only return locally if successful, otherwise exit 
non-locally."
  (apply #'format format args)
  :warning)))
 
+(defun eglot--pos-to-lsp-position ( pos)
+  "Convert point POS to LSP position."
+  (save-excursion
+(eglot--obj :line
+;; F!@(#*

[elpa] externals/eglot d1cdcf1 119/139: Friendlier M-x eglot

2018-05-14 Thread Jo�o T�vora
branch: externals/eglot
commit d1cdcf163849ca1a7bfcbc3287f4e2c28cae77af
Author: João Távora 
Commit: João Távora 

Friendlier M-x eglot

* eglot.el (eglot-server-programs): Renamed from eglot-executables
(eglot--interactive): Redesign
(eglot): Docstring.
(eglot--connect): Now a synchronous gig.
(eglot--interactive): Friendlier.
(eglot): Improve docstring, rework a bit.
(eglot-reconnect): Rework a bit.
(eglot--process-sentinel): Insert "byebye" ruler here.

* README.md: Update
---
 README.md |  39 ++---
 eglot.el  | 140 +++---
 2 files changed, 94 insertions(+), 85 deletions(-)

diff --git a/README.md b/README.md
index 66f2131..c2931be 100644
--- a/README.md
+++ b/README.md
@@ -12,17 +12,25 @@ Eglot
 M-x eglot
 ```
 
-*That's it*. Either this guesses the LSP executable to start for the
-language of your choice, or it prompts you to enter the program.
+*That's it*. If you're lucky, this guesses the LSP executable to start
+for the language of your choice, or it prompts you to enter one:
 
-If you have these programs installed, `M-x eglot` works out-of-the-box
-with:
+`M-x eglot` currently guesses and works out-of-the-box with:
 
 * Javascript's [javascript-typescript-stdio][javascript-typescript-langserver]
 * Rust's [rls][rls]
 * Python's [pyls][pyls]
+* Bash's [bash-language-server][bash-language-server]
 
-You can also enter a `server:port` pattern to connect to an LSP
+I'll add more as I test more features. In the meantime you can
+customize `eglot-server-programs`:
+
+```lisp
+(add-to-list 'eglot-server-programs '(fancy-mode . ("fancy-language-server" 
"--args"")))
+```
+
+Let me know how well it works and I'll add it to the list, or submit a
+PR.  You can also enter a `server:port` pattern to connect to an LSP
 server. To skip the guess and always be prompted use `C-u M-x eglot`.
 
 # Supported Protocol features
@@ -89,21 +97,22 @@ server. To skip the guess and always be prompted use `C-u 
M-x eglot`.
 
 # Differences to lsp-mode.el
 
-Eglot is **really beta** and may currently underperform
-[lsp-mode.el][emacs-lsp], which is more mature and has a host of
-[plugins][emacs-lsp-plugins] for bells and whistles.  If you think the 
minimalist approach
-of `eglot.el` is not for you, you could be better served with
-`lsp-mode.el` for now.
+Eglot is **beta**. It may currently underperform
+[lsp-mode.el][emacs-lsp], both in functionality and correctness. That
+other extension is much more mature and has a host of
+[plugins][emacs-lsp-plugins] for bells and whistles.  If you don't
+like the minimalist approach of `eglot.el`, you could be better served
+with `lsp-mode.el` for now.
 
 User-visible differences:
 
-- Single entry point `M-x eglot`, not `M-x eglot-`. Also no
-  `eglot-` extra packages.
+- Single and friendly entry point `M-x eglot`, not `M-x
+  eglot-`. Also no `eglot-` extra packages.
 - No "whitelisting" or "blacklisting" directories to languages. `M-x
   eglot` starts servers to handle major modes inside a specific
   project. Uses Emacs's built-in `project.el` library to discover
-  projects. Automatically detects current and future opened files under that
-  project and syncs with server.
+  projects. Automatically detects current and future opened files
+  under that project and syncs with server.
 - Easy way to quit/restart a server, just middle/right click on the
   connection name.
 - Pretty interactive mode-line section for live tracking of server
@@ -134,6 +143,6 @@ Under the hood:
 [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
-
+[bash-language-server]: https://github.com/mads-hartmann/bash-language-server
 

diff --git a/eglot.el b/eglot.el
index b2709a6..22799cc 100644
--- a/eglot.el
+++ b/eglot.el
@@ -47,9 +47,10 @@
   :prefix "eglot-"
   :group 'applications)
 
-(defvar eglot-executables '((rust-mode . ("rls"))
-(python-mode . ("pyls"))
-(js-mode . ("javascript-typescript-stdio")))
+(defvar eglot-server-programs '((rust-mode . ("rls"))
+(python-mode . ("pyls"))
+(js-mode . ("javascript-typescript-stdio"))
+(sh-mode . ("bash-language-server" "start")))
   "Alist mapping major modes to server executables.")
 
 (defface eglot-mode-line
@@ -204,10 +205,8 @@ CONTACT is as `eglot--contact'.  Returns a process object."
   :publishDiagnostics `(:relatedInformation :json-false))
:experimental (eglot--obj)))
 
-(defun eglot--connect (project managed-major-mode
-   short-name contact  success-fn)
-  "Connect for PROJECT, MANAGED-MAJOR-MODE, SHORT-NAME and CONTACT.
-SUCCESS-FN with 

[elpa] externals/elpa 79a2a1e 069/139: Be quite explicit about our lack of capabilities right now

2018-05-14 Thread Jo�o T�vora
branch: externals/elpa
commit 79a2a1e12eb5ead6ee3419457607ab38647e1ac2
Author: João Távora 
Commit: João Távora 

Be quite explicit about our lack of capabilities right now

* eglot.el (eglot--client-capabilities): Spread out.
---
 eglot.el | 35 +--
 1 file changed, 33 insertions(+), 2 deletions(-)

diff --git a/eglot.el b/eglot.el
index 8e39591..5701422 100644
--- a/eglot.el
+++ b/eglot.el
@@ -192,9 +192,40 @@ CONTACT is as `eglot--contact'.  Returns a process object."
 (defun eglot--client-capabilities ()
   "What the EGLOT LSP client supports."
   (eglot--obj
-   :workspace (eglot--obj)
+   :workspace(eglot--obj
+  :applyEdit nil
+  :workspaceEdit nil
+  :didChangeConfiguration nil
+  :didChangeWatchedFiles nil
+  :symbol nil
+  :executeCommand nil
+  :workspaceFolders nil
+  :configuration nil)
:textDocument (eglot--obj
-  :publishDiagnostics `(:relatedInformation nil
+  :synchronization (eglot--obj
+:dynamicRegistration :json-false
+:willSave t
+:willSaveWaitUntil :json-false
+:didSave t)
+  :completion nil
+  :hover nil
+  :signatureHelp nil
+  :references nil
+  :documentHighlight nil
+  :documentSymbol nil
+  :formatting nil
+  :rangeFormatting nil
+  :onTypeFormatting nil
+  :definition nil
+  :typeDefinition nil
+  :implementation nil
+  :codeAction nil
+  :codeLens nil
+  :documentLink nil
+  :colorProvider nil
+  :rename nil
+  :publishDiagnostics `(:relatedInformation :json-false))
+   :experimental (eglot--obj)))
 
 (defun eglot--connect (project managed-major-mode
short-name contact  success-fn)



[elpa] externals/elpa c2862f4 063/139: Don't auto-reconnect if last attempt lasted less than 3 seconds

2018-05-14 Thread Jo�o T�vora
branch: externals/elpa
commit c2862f46c8330a0c0feaf871034166ed5d973894
Author: João Távora 
Commit: João Távora 

Don't auto-reconnect if last attempt lasted less than 3 seconds

* eglot.el (eglot--inhibit-auto-reconnect): New var.
(eglot--process-sentinel): Use it.
---
 eglot.el | 16 ++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/eglot.el b/eglot.el
index 8f371d2..df03d04 100644
--- a/eglot.el
+++ b/eglot.el
@@ -329,6 +329,9 @@ INTERACTIVE is t if called interactively."
(with-current-buffer buffer
  (eglot--maybe-activate-editing-mode proc))
 
+(defvar eglot--inhibit-auto-reconnect nil
+  "If non-nil, don't autoreconnect on unexpected quit.")
+
 (defun eglot--process-sentinel (process change)
   "Called with PROCESS undergoes CHANGE."
   (eglot--debug "(sentinel) Process state changed to %s" change)
@@ -355,11 +358,20 @@ INTERACTIVE is t if called interactively."
 (cond ((eglot--moribund process)
(eglot--message "(sentinel) Moribund process exited with status %s"
(process-exit-status process)))
-  (t
+  ((null eglot--inhibit-auto-reconnect)
(eglot--warn
 "(sentinel) Reconnecting after process unexpectedly changed to %s."
 change)
-   (eglot-reconnect process)))
+   (eglot-reconnect process)
+   (setq eglot--inhibit-auto-reconnect
+ (run-with-timer
+  3 nil
+  (lambda ()
+(setq eglot--inhibit-auto-reconnect nil)
+  (t
+   (eglot--warn
+"(sentinel) Not auto-reconnecting, last one didn't last long."
+change)))
 (force-mode-line-update t)
 (delete-process process)))
 



[elpa] externals/elpa dda11dd 095/139: Try to fix some textDocument/completion bugs

2018-05-14 Thread Jo�o T�vora
branch: externals/elpa
commit dda11dde6db5c91cdede6a10e9609aad3826bf2a
Author: João Távora 
Commit: João Távora 

Try to fix some textDocument/completion bugs

* eglot.el (eglot-completion-at-point): Rework slightly.
---
 eglot.el | 20 +---
 1 file changed, 9 insertions(+), 11 deletions(-)

diff --git a/eglot.el b/eglot.el
index d7ea329..2e409ef 100644
--- a/eglot.el
+++ b/eglot.el
@@ -1274,13 +1274,13 @@ DUMMY is ignored"
 
 (defun eglot-completion-at-point ()
   "EGLOT's `completion-at-point' function."
-  (let ((bounds (bounds-of-thing-at-point 'sexp))
+  (let ((bounds (bounds-of-thing-at-point 'symbol))
 (proc (eglot--current-process-or-lose)))
 (when (eglot--server-capable :completionProvider)
   (list
(or (car bounds) (point))
(or (cdr bounds) (point))
-   (completion-table-dynamic
+   (completion-table-with-cache
 (lambda (_ignored)
   (let* ((resp (eglot--sync-request
 proc
@@ -1291,19 +1291,17 @@ DUMMY is ignored"
  (items (if (vectorp resp) resp (plist-get resp :items
 (eglot--mapply
  (eglot--lambda ( insertText label kind detail
-  documentation sortText)
-   (propertize insertText
-   :label label :kind kind :detail detail
+  documentation sortText )
+   (propertize (or insertText label)
+   :kind-name (cdr (assoc kind eglot--kind-names))
+   :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)))
-  ""
+(kind-name (get-text-property 0 :kind what)))
+(concat (if detail (format " %s" detail) "")
+(if kind-name (format " (%s)" kind-name) ""
:display-sort-function
(lambda (items) (sort items (lambda (a b)
  (string-lessp



[elpa] externals/elpa 9665a3e 051/139: Fix textDocument/didChange

2018-05-14 Thread Jo�o T�vora
branch: externals/elpa
commit 9665a3eec28fcf1bc52542cbe5e99d16f4fbc03a
Author: João Távora 
Commit: João Távora 

Fix textDocument/didChange

* eglot.el (eglot-editing-mode): Manage before-change-functions.
(eglot--recent-changes): Deleted.
(eglot--recent-before-changes): New var.
(eglot--recent-after-changes): Renamed from eglot--recent-changes.
(eglot--pos-to-lsp-position, eglot--before-change): New helpers.
(eglot--after-change): Rework.
(eglot--signal-textDocument/didChange): Rework.
---
 eglot.el | 98 +++-
 1 file changed, 66 insertions(+), 32 deletions(-)

diff --git a/eglot.el b/eglot.el
index 469d3f7..1bf0d56 100644
--- a/eglot.el
+++ b/eglot.el
@@ -611,6 +611,7 @@ identifier.  ERROR is non-nil if this is an error."
(eglot-editing-mode
 (eglot-mode 1)
 (add-hook 'after-change-functions 'eglot--after-change nil t)
+(add-hook 'before-change-functions 'eglot--before-change nil t)
 (add-hook 'flymake-diagnostic-functions 'eglot-flymake-backend nil t)
 (add-hook 'kill-buffer-hook 'eglot--signal-textDocument/didClose nil t)
 (flymake-mode 1)
@@ -620,6 +621,7 @@ identifier.  ERROR is non-nil if this is an error."
(t
 (remove-hook 'flymake-diagnostic-functions 'eglot-flymake-backend t)
 (remove-hook 'after-change-functions 'eglot--after-change t)
+(remove-hook 'before-change-functions 'eglot--before-change t)
 (remove-hook 'kill-buffer-hook 'eglot--signal-textDocument/didClose t
 
 (define-minor-mode eglot-mode
@@ -868,7 +870,9 @@ running.  INTERACTIVE is t if called interactively."
  (t
   (eglot--message "OK so %s isn't visited" filename)
 
-(defvar eglot--recent-changes nil
+(defvar eglot--recent-before-changes nil
+  "List of recent changes as collected by `eglot--before-change'.")
+(defvar eglot--recent-after-changes nil
   "List of recent changes as collected by `eglot--after-change'.")
 
 (defvar-local eglot--versioned-identifier 0)
@@ -895,46 +899,76 @@ running.  INTERACTIVE is t if called interactively."
  (widen)
  (buffer-substring-no-properties (point-min) (point-max))
 
-(defun eglot--after-change (start end length)
+(defun eglot--pos-to-lsp-position (pos)
+  "Convert point POS to LSP position."
+  (save-excursion
+(eglot--obj :line
+;; F!@(#*

[elpa] externals/elpa 9bf3166 136/139: Don't define a menu if nothing to show there for now

2018-05-14 Thread Jo�o T�vora
branch: externals/elpa
commit 9bf31667f1d1a4dfea61a96e44f658e70d9ebd85
Author: João Távora 
Commit: João Távora 

Don't define a menu if nothing to show there for now

* eglot.el (eglot-menu): Remove it.
(eglot--mode-line-format): Don't define a menu.
---
 eglot.el | 7 +--
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/eglot.el b/eglot.el
index 4477242..6dc2213 100644
--- a/eglot.el
+++ b/eglot.el
@@ -843,10 +843,6 @@ that case, also signal textDocument/didOpen."
 
 ;;; Mode-line, menu and other sugar
 ;;;
-(defvar eglot-menu)
-
-(easy-menu-define eglot-menu eglot-mode-map "EGLOT" `("EGLOT" ))
-
 (defvar eglot--mode-line-format `(:eval (eglot--mode-line-format)))
 
 (put 'eglot--mode-line-format 'risky-local-variable t)
@@ -881,8 +877,7 @@ Uses THING, FACE, DEFS and PREPEND."
(`(,_id ,doing ,done-p ,detail) (and proc (eglot--spinner 
proc)))
(`(,status ,serious-p) (and proc (eglot--status proc
 (append
- `(,(eglot--mode-line-props "eglot" 'eglot-mode-line
-'((down-mouse-1 eglot-menu "pop up EGLOT 
menu"
+ `(,(eglot--mode-line-props "eglot" 'eglot-mode-line nil))
  (when name
`(":" ,(eglot--mode-line-props
name 'eglot-mode-line



[elpa] externals/elpa e63dad0 092/139: Simplify mode-line code with a helper.

2018-05-14 Thread Jo�o T�vora
branch: externals/elpa
commit e63dad0bc5ae5f1233907e1ae3c1dbd7c2a02d81
Author: João Távora 
Commit: João Távora 

Simplify mode-line code with a helper.

* eglot.el (eglot--mdoe-line-props): New helper.
(eglot--mode-line-format): Use it.
---
 eglot.el | 118 ---
 1 file changed, 38 insertions(+), 80 deletions(-)

diff --git a/eglot.el b/eglot.el
index a600f47..02439df 100644
--- a/eglot.el
+++ b/eglot.el
@@ -817,93 +817,51 @@ that case, also signal textDocument/didOpen."
 (with-selected-window (posn-window (event-start event))
   (call-interactively what
 
+(defun eglot--mode-line-props (thing face defs  prepend)
+  "Helper for function `eglot--mode-line-format'.
+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))
+   concat (format "%s: %s" key help) into blurb
+   when rest concat "\n" into blurb
+   finally (return `(:propertize ,thing
+ face ,face
+ keymap ,map help-echo ,(concat 
prepend blurb)
+ mouse-face mode-line-highlight
+
 (defun eglot--mode-line-format ()
-  "Compose the mode-line format spec."
+  "Compose the EGLOT's mode-line."
   (pcase-let* ((proc (eglot--current-process))
-   (name (and proc
-  (process-live-p proc)
-  (eglot--short-name proc)))
-   (pending (and proc
- (hash-table-count
-  (eglot--pending-continuations proc
-   (`(,_id ,doing ,done-p)
-(and proc
- (eglot--spinner proc)))
-   (`(,status ,serious-p)
-(and proc
- (eglot--status proc
+   (name (and (process-live-p proc) (eglot--short-name proc)))
+   (pending (and proc (hash-table-count
+   (eglot--pending-continuations proc
+   (`(,_id ,doing ,done-p) (and proc (eglot--spinner proc)))
+   (`(,status ,serious-p) (and proc (eglot--status proc
 (append
- `((:propertize "eglot"
-face eglot-mode-line
-keymap ,(let ((map (make-sparse-keymap)))
-  (define-key map [mode-line down-mouse-1]
-(eglot--mode-line-call 'eglot-menu))
-  map)
-mouse-face mode-line-highlight
-help-echo "mouse-1: pop-up EGLOT menu"
-))
+ `(,(eglot--mode-line-props "eglot" 'eglot-mode-line
+'((down-mouse-1 eglot-menu "pop up EGLOT 
menu"
  (when name
-   `(":"
- (:propertize
-  ,name
-  face eglot-mode-line
-  keymap ,(let ((map (make-sparse-keymap)))
-(define-key map [mode-line mouse-1]
-  (eglot--mode-line-call 'eglot-events-buffer))
-(define-key map [mode-line mouse-2]
-  (eglot--mode-line-call 'eglot-shutdown))
-(define-key map [mode-line mouse-3]
-  (eglot--mode-line-call 'eglot-reconnect))
-map)
-  mouse-face mode-line-highlight
-  help-echo ,(concat "mouse-1: go to events buffer\n"
- "mouse-2: quit server\n"
- "mouse-3: reconnect to server"))
+   `(":" ,(eglot--mode-line-props
+   name 'eglot-mode-line
+   '((mouse-1 eglot-events-buffer "go to events buffer")
+ (mouse-2 eglot-shutdown  "quit server")
+ (mouse-3 eglot-reconnect "reconnect to server")))
  ,@(when serious-p
- `("/"
-   (:propertize
-,status
-help-echo ,(concat "mouse-1: go to events buffer\n"
-   "mouse-3: clear this status")
-mouse-face mode-line-highlight
-face compilation-mode-line-fail
-keymap ,(let ((map (make-sparse-keymap)))
-  (define-key map [mode-line mouse-1]
-(eglot--mode-line-call 'eglot-events-buffer))
-  (define-key map [mode-line mouse-3]
-(eglot--mode-line-call 'eglot-clear-status))
-  map
+ `("/" ,(eglot--mode-line-props
+ status 'compilation-mode-line-fail
+ '((mouse-1 eglot-events-buffer "go to events buffer")
+   

[elpa] externals/eglot b657b32 068/139: Use rootUri instead of rootPath

2018-05-14 Thread Jo�o T�vora
branch: externals/eglot
commit b657b328692c1315754aa2246b456469cdc77107
Author: João Távora 
Commit: João Távora 

Use rootUri instead of rootPath

* eglot.el (eglot--connect)
(eglot--current-buffer-VersionedTextDocumentIdentifier): Use
eglot--uri.
(eglot--uri): New function.
---
 eglot.el | 16 +---
 1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/eglot.el b/eglot.el
index b305ca3..8e39591 100644
--- a/eglot.el
+++ b/eglot.el
@@ -221,9 +221,9 @@ SUCCESS-FN with no args if all goes well."
  proc
  :initialize
  (eglot--obj :processId  (emacs-pid)
- :rootPath  (concat
- (expand-file-name (car (project-roots
- (project-current)
+ :rootUri  (eglot--uri
+(expand-file-name (car (project-roots
+(project-current)
  :initializationOptions  []
  :capabilities (eglot--client-capabilities))
  :success-fn
@@ -666,6 +666,8 @@ identifier.  ERROR is non-nil if this is a JSON-RPC error."
  (apply #'format format args)
  :warning)))
 
+(defun eglot--uri (path) "Add file:// to PATH." (concat "file://" path))
+
 
 ;;; Minor modes
 ;;;
@@ -988,10 +990,10 @@ running.  INTERACTIVE is t if called interactively."
 (defun eglot--current-buffer-VersionedTextDocumentIdentifier ()
   "Compute VersionedTextDocumentIdentifier object for current buffer."
   (eglot--obj :uri
-  (concat "file://"
-  (url-hexify-string
-   (file-truename buffer-file-name)
-   url-path-allowed-chars))
+  (eglot--uri
+   (url-hexify-string
+(file-truename buffer-file-name)
+url-path-allowed-chars))
   ;; FIXME: later deal with workspaces
   :version eglot--versioned-identifier))
 



[elpa] externals/eglot e86f9b4 073/139: New helper eglot--sync-request

2018-05-14 Thread Jo�o T�vora
branch: externals/eglot
commit e86f9b41beab44bfa3ab7c75882baa7eb80be46b
Author: João Távora 
Commit: João Távora 

New helper eglot--sync-request

This should help with xref definitions

* eglot.el (eglot--request): Rework a bit. Continuation is always
cleared on timeout, regardless of user-supplied fn.
(eglot--sync-request): New function.
(eglot--process-receive): watch out for vector results.
---
 eglot.el | 39 +++
 1 file changed, 31 insertions(+), 8 deletions(-)

diff --git a/eglot.el b/eglot.el
index 2afb0e7..34ce0f8 100644
--- a/eglot.el
+++ b/eglot.el
@@ -546,7 +546,10 @@ identifier.  ERROR is non-nil if this is a JSON-RPC error."
(remhash id (eglot--pending-continuations proc))
(if err
(apply (cl-second continuations) err)
- (apply (cl-first continuations) (plist-get message :result
+ (let ((res (plist-get message :result)))
+   (if (listp res)
+   (apply (cl-first continuations) res)
+ (funcall (cl-first continuations) res)
   (id
(eglot--warn "Ooops no continuation for id %s" id)
 
@@ -592,8 +595,7 @@ identifier.  ERROR is non-nil if this is a JSON-RPC error."
   (or timeout-fn
   (lambda ()
 (eglot--warn
- "(request) Tired of waiting for reply to %s" id)
-(remhash id (eglot--pending-continuations process)
+ "(request) Tired of waiting for reply to %s" id
  (error-fn
   (or error-fn
   (cl-function
@@ -618,11 +620,15 @@ identifier.  ERROR is non-nil if this is a JSON-RPC 
error."
  :params params))
 (catch catch-tag
   (let ((timeout-timer
- (run-with-timer 5 nil
- (if async-p
- timeout-fn
-   (lambda ()
- (throw catch-tag (funcall timeout-fn)))
+ (run-with-timer
+  5 nil
+  (if async-p
+  (lambda ()
+(remhash id (eglot--pending-continuations process))
+(funcall timeout-fn))
+(lambda ()
+  (remhash id (eglot--pending-continuations process))
+  (throw catch-tag (funcall timeout-fn)))
 (puthash id
  (list (if async-p
success-fn
@@ -651,6 +657,23 @@ identifier.  ERROR is non-nil if this is a JSON-RPC error."
"(request) Last-change cancelling timer for continuation %s" id)
   (cancel-timer timeout-timer
 
+(defun eglot--sync-request (proc method params)
+  "Like `eglot--request' for PROC, METHOD and PARAMS, but synchronous.
+Meaning only return locally if successful, otherwise exit non-locally."
+  (eglot--request proc method params
+  :success-fn (lambda ( args)
+(if (vectorp (car args))
+(car args)
+  args))
+  :error-fn (cl-function
+ (lambda ( code message )
+   (eglot--error "Oops: %s: %s" code message)))
+  :timeout-fn (lambda ()
+(lambda ()
+  (eglot--error
+   "Tired of waiting for reply to sync 
request")))
+  :async-p nil))
+
 (cl-defun eglot--notify (process method params)
   "Notify PROCESS of something, don't expect a reply.e"
   (eglot--process-send nil



[elpa] externals/elpa c7bd095 118/139: Improve eglot-eldoc-function

2018-05-14 Thread Jo�o T�vora
branch: externals/elpa
commit c7bd0952335bab43667974f15672b9fa3c99913e
Author: João Távora 
Commit: João Távora 

Improve eglot-eldoc-function

Use the :range key if the server provided it. Also simplify code with
a new eglot--with-lsp-range macro.

* eglot.el (eglot--format-markup): Tweak comment.
(eglot--with-lsp-range): New helper macro.
(eglot--server-textDocument/publishDiagnostics)
(eglot--apply-text-edits): Use it.
(eglot-eldoc-function): Use range if server provides it.
---
 eglot.el | 69 +++-
 1 file changed, 38 insertions(+), 31 deletions(-)

diff --git a/eglot.el b/eglot.el
index d1e4d15..b2709a6 100644
--- a/eglot.el
+++ b/eglot.el
@@ -740,7 +740,7 @@ DEFERRED is passed to `eglot--request', which see."
   "Format MARKUP according to LSP's spec."
   (cond ((stringp markup)
  (with-temp-buffer
-   (ignore-errors (funcall (intern "markdown-mode"))) ;escape 
bytecompiler
+   (ignore-errors (funcall (intern "markdown-mode"))) ;escape bytecomp
(font-lock-ensure)
(insert markup)
(string-trim (buffer-string
@@ -757,6 +757,15 @@ DEFERRED is passed to `eglot--request', which see."
   "Determine if current server is capable of FEAT."
   (plist-get (eglot--capabilities (eglot--current-process-or-lose)) feat))
 
+(cl-defmacro eglot--with-lsp-range ((start end) range  body
+ (range-sym (cl-gensym)))
+  "Bind LSP RANGE to START and END. Evaluate BODY."
+  (declare (indent 2) (debug (sexp sexp  form)))
+  `(let* ((,range-sym ,range)
+  (,start (eglot--lsp-position-to-point (plist-get ,range-sym :start)))
+  (,end (eglot--lsp-position-to-point (plist-get ,range-sym :end
+ ,@body))
+
 
 ;;; Minor modes
 ;;;
@@ -965,17 +974,13 @@ called interactively."
  collect (cl-destructuring-bind ( range severity _group
   _code source message)
  diag-spec
-   (cl-destructuring-bind ( 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)
+   (eglot--with-lsp-range (beg end) range
+ (flymake-make-diagnostic (current-buffer)
+  beg end
+  (cond ((<= severity 1) :error)
+((= severity 2)  :warning)
+(t   :note))
+  (concat source ": " message
  into diags
  finally (cond (eglot--current-flymake-report-fn
 (funcall eglot--current-flymake-report-fn diags)
@@ -1302,15 +1307,23 @@ DUMMY is ignored"
 (proc (eglot--current-process-or-lose))
 (position-params (eglot--current-buffer-TextDocumentPositionParams)))
 (when (eglot--server-capable :hoverProvider)
-  (eglot--request proc :textDocument/hover position-params
-  :success-fn (eglot--lambda ( contents _range)
-(eldoc-message
- (mapconcat #'eglot--format-markup
-(if (vectorp contents)
-contents
-  (list contents))
-"\n")))
-  :deferred :textDocument/hover))
+  (eglot--request
+   proc :textDocument/hover position-params
+   :success-fn (eglot--lambda ( contents range)
+ (when (get-buffer-window buffer)
+   (with-current-buffer buffer
+ (eldoc-message
+  (concat
+   (and range
+(eglot--with-lsp-range (beg end) range
+  (concat (buffer-substring beg end)  ": ")))
+   (mapconcat #'eglot--format-markup
+  (append
+   (cond ((vectorp contents)
+  contents)
+ (contents
+  (list contents 

[elpa] externals/elpa 54fc885 113/139: More RLS-specifics: update Flymake diags when indexing done

2018-05-14 Thread Jo�o T�vora
branch: externals/elpa
commit 54fc8854b8e0782cb46c46b83af99ed6b65c2688
Author: João Távora 
Commit: João Távora 

More RLS-specifics: update Flymake diags when indexing done

RLS could/should report diagnostics for every opened file, even if
there aren't any problems. Because it doesn't, loop for every buffer
managed by the process and call eglot--current-flymake-report-fn

* eglot.el
(eglot--server-window/progress): Call eglot--current-flymake-report-fn
---
 eglot.el | 14 ++
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/eglot.el b/eglot.el
index f865c22..1ba5324 100644
--- a/eglot.el
+++ b/eglot.el
@@ -825,6 +825,9 @@ DEFERRED is passed to `eglot--request', which see."
   (or (and (null proc) cur)
   (and proc (eq proc cur))
 
+(defvar-local eglot--current-flymake-report-fn nil
+  "Current flymake report function for this buffer")
+
 (defun eglot--maybe-activate-editing-mode ( proc)
   "Maybe activate mode function `eglot--managed-mode'.
 If PROC is supplied, do it only if BUFFER is managed by it.  In
@@ -969,9 +972,6 @@ called interactively."
   "Handle notification telemetry/event"
   (eglot--log "Server telemetry: %s" any))
 
-(defvar-local eglot--current-flymake-report-fn nil
-  "Current flymake report function for this buffer")
-
 (defvar-local eglot--unreported-diagnostics nil
   "Unreported diagnostics for this buffer.")
 
@@ -1479,7 +1479,13 @@ Proceed? "
 (cl-defun eglot--server-window/progress
 (process  id done title message )
   "Handle notification window/progress"
-  (setf (eglot--spinner process) (list id title done message)))
+  (setf (eglot--spinner process) (list id title done message))
+  (when (and (equal "Indexing" title) done)
+(dolist (buffer (buffer-list))
+  (with-current-buffer buffer
+(when (eglot--buffer-managed-p process)
+  (funcall (or eglot--current-flymake-report-fn #'ignore)
+   eglot--unreported-diagnostics))
 
 (provide 'eglot)
 ;;; eglot.el ends here



[elpa] externals/eglot bbc64b4 087/139: Clean up client capabilities

2018-05-14 Thread Jo�o T�vora
branch: externals/eglot
commit bbc64b4530734f7837d050094b755706cd34aadd
Author: João Távora 
Commit: João Távora 

Clean up client capabilities

* eglot.el (eglot--client-capabilities): Clean up client
capabilities.
---
 eglot.el | 21 -
 1 file changed, 4 insertions(+), 17 deletions(-)

diff --git a/eglot.el b/eglot.el
index 2c97f2f..8e92725 100644
--- a/eglot.el
+++ b/eglot.el
@@ -215,23 +215,10 @@ CONTACT is as `eglot--contact'.  Returns a process 
object."
 :willSave t
 :willSaveWaitUntil :json-false
 :didSave t)
-  :completion nil
-  :hover nil
-  :signatureHelp nil
-  :references nil
-  :documentHighlight nil
-  :documentSymbol nil
-  :formatting nil
-  :rangeFormatting nil
-  :onTypeFormatting nil
-  :definition nil
-  :typeDefinition nil
-  :implementation nil
-  :codeAction nil
-  :codeLens nil
-  :documentLink nil
-  :colorProvider nil
-  :rename nil
+  :completion `(:dynamicRegistration :json-false)
+  :hover  `(:dynamicRegistration :json-false)
+  :references `(:dynamicRegistration :json-false)
+  :definition `(:dynamicRegistration :json-false)
   :publishDiagnostics `(:relatedInformation :json-false))
:experimental (eglot--obj)))
 



[elpa] externals/eglot 571b08f 076/139: Fix the odd bug here and there

2018-05-14 Thread Jo�o T�vora
branch: externals/eglot
commit 571b08f52bf8420a5e0bb3cfa727235048d94ba6
Author: João Távora 
Commit: João Távora 

Fix the odd bug here and there

* eglot.el (eglot--connect): Activate editing mode where
applicable here.
(eglot, eglot-reconnect): Not here or here.
(eglot--process-sentinel): Catch auto-reconnect errors.
(eglot--notify): Dont send 'id=null', it messes up js's lsp
(eglot--reply): Do send id here.
(eglot--log-event): Simplify protocol. Complexify implementation.
(eglot--process-receive, eglot--process-send): Simplify
eglot--log-event call.
(eglot--request, eglot--notify, eglot--reply): Simplify
eglot--process-send call
(eglot--server-client/registerCapability): Fix bug when replying
with wrong id.
(eglot--xref-reset-known-symbols): Take DUMMY arg.
---
 eglot.el | 131 +--
 1 file changed, 61 insertions(+), 70 deletions(-)

diff --git a/eglot.el b/eglot.el
index cb92361..d6ecdfe 100644
--- a/eglot.el
+++ b/eglot.el
@@ -265,6 +265,9 @@ SUCCESS-FN with no args if all goes well."
   (lambda ( capabilities)
 (setf (eglot--capabilities proc) capabilities)
 (setf (eglot--status proc) nil)
+(dolist (buffer (buffer-list))
+  (with-current-buffer buffer
+(eglot--maybe-activate-editing-mode proc)))
 (when success-fn (funcall success-fn proc))
 (eglot--notify proc :initialized (eglot--obj :__dummy__ t)
 
@@ -344,10 +347,7 @@ INTERACTIVE is t if called interactively."
 buffers in project %s."
proc
managed-major-mode
-   short-name)
-   (dolist (buffer (buffer-list))
- (with-current-buffer buffer
-   (eglot--maybe-activate-editing-mode proc)
+   short-name)))
 
 (defun eglot-reconnect (process  interactive)
   "Reconnect to PROCESS.
@@ -360,11 +360,7 @@ INTERACTIVE is t if called interactively."
(eglot--major-mode process)
(eglot--short-name process)
(eglot--contact process)
-   (lambda (proc)
- (eglot--message "Reconnected!")
- (dolist (buffer (buffer-list))
-   (with-current-buffer buffer
- (eglot--maybe-activate-editing-mode proc))
+   (lambda (_proc) (eglot--message "Reconnected!"
 
 (defvar eglot--inhibit-auto-reconnect nil
   "If non-nil, don't autoreconnect on unexpected quit.")
@@ -397,9 +393,11 @@ INTERACTIVE is t if called interactively."
(process-exit-status process)))
   ((null eglot--inhibit-auto-reconnect)
(eglot--warn
-"(sentinel) Reconnecting after process unexpectedly changed to %s."
+"(sentinel) Reconnecting after process unexpectedly changed to 
`%s'."
 change)
-   (eglot-reconnect process)
+   (condition-case-unless-debug err
+   (eglot-reconnect process)
+ (error (eglot--warn "Auto-reconnect failed: %s " err) ))
(setq eglot--inhibit-auto-reconnect
  (run-with-timer
   3 nil
@@ -493,13 +491,22 @@ INTERACTIVE is t if called interactively."
   (display-buffer buffer))
 buffer))
 
-(defun eglot--log-event (proc type message  id error)
+(defun eglot--log-event (proc message type)
   "Log an eglot-related event.
-PROC is the current process.  TYPE is an identifier.  MESSAGE is
-a JSON-like plist or anything else.  ID is a continuation
-identifier.  ERROR is non-nil if this is a JSON-RPC error."
+PROC is the current process.  MESSAGE is a JSON-like plist.  TYPE
+is a symbol saying if this is a client or server originated."
   (with-current-buffer (eglot-events-buffer proc)
-(let ((inhibit-read-only t))
+(let* ((inhibit-read-only t)
+   (id (plist-get message :id))
+   (error (plist-get message :error))
+   (method (plist-get message :method))
+   (subtype (cond ((and method id)   'request)
+  (method'notification)
+  (id'reply)
+  ;; pyls keeps on sending these
+  (t 'unexpected-thingy)))
+   (type
+(format "%s-%s" type subtype)))
   (goto-char (point-max))
   (let ((msg (format "%s%s%s:\n%s\n"
  type
@@ -518,15 +525,7 @@ identifier.  ERROR is non-nil if this is a JSON-RPC error."
  (continuations (and id
  (not method)
  (gethash id (eglot--pending-continuations 
proc)
-(eglot--log-event proc
-  (cond ((and method id)   'server-request)
-(method'server-notification)
-  

[elpa] externals/eglot 1356844 097/139: Fix odd bugs

2018-05-14 Thread Jo�o T�vora
branch: externals/eglot
commit 1356844979c82e7a1b62055314a6a4326fed1576
Author: João Távora 
Commit: João Távora 

Fix odd bugs

* eglot.el (eglot--process-receive, eglot--request): Set status to
actual error message.
(eglot--managed-mode): Manage imenu-create-index-function
correctly.
(eglot--mode-line-format): Print error status.
---
 eglot.el | 16 +---
 1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/eglot.el b/eglot.el
index 9ce7e26..807df98 100644
--- a/eglot.el
+++ b/eglot.el
@@ -495,7 +495,7 @@ is a symbol saying if this is a client or server 
originated."
  (not method)
  (gethash id (eglot--pending-continuations 
proc)
 (eglot--log-event proc message 'server)
-(when err (setf (eglot--status proc) '("error" t)))
+(when err (setf (eglot--status proc) `(,err t)))
 (cond (method
;; a server notification or a server request
(let* ((handler-sym (intern (concat "eglot--server-"
@@ -566,7 +566,7 @@ response."
  (error-fn (or error-fn
(cl-function
 (lambda ( code message )
-  (setf (eglot--status process) '("error" t))
+  (setf (eglot--status process) `(,message t))
   (eglot--warn
"(request) Request id=%s errored with code=%s: %s"
id code message)
@@ -780,7 +780,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)
+(add-function :around (local imenu-create-index-function) #'eglot-imenu)
 (flymake-mode 1)
 (eldoc-mode 1))
(t
@@ -795,7 +795,7 @@ Meaning only return locally if successful, otherwise exit 
non-locally."
 (remove-hook 'completion-at-point-functions #'eglot-completion-at-point t)
 (remove-function (local 'eldoc-documentation-function)
  #'eglot-eldoc-function)
-(advice-remove imenu-create-index-function #'eglot-imenu
+(remove-function (local imenu-create-index-function) #'eglot-imenu
 
 (define-minor-mode eglot-mode
   "Minor mode for all buffers managed by EGLOT in some way."  nil
@@ -870,9 +870,10 @@ Uses THING, FACE, DEFS and PREPEND."
  (mouse-3 eglot-reconnect "reconnect to server")))
  ,@(when serious-p
  `("/" ,(eglot--mode-line-props
- status 'compilation-mode-line-fail
+ "error" 'compilation-mode-line-fail
  '((mouse-1 eglot-events-buffer "go to events buffer")
-   (mouse-3 eglot-clear-status  "clear this status")
+   (mouse-3 eglot-clear-status  "clear this status"))
+ (format "An error occured: %s\n" status
  ,@(when (and doing (not done-p))
  `("/" ,(eglot--mode-line-props
  doing 'compilation-mode-line-run
@@ -881,7 +882,8 @@ Uses THING, FACE, DEFS and PREPEND."
  `("/" ,(eglot--mode-line-props
  (format "%d" pending) 'warning
  '((mouse-1 eglot-events-buffer "go to events buffer")
-   (mouse-3 eglot-clear-status  "clear this 
status"))
+   (mouse-3 eglot-clear-status  "clear this status"))
+ (format "%d pending requests\n" pending)
 
 (add-to-list 'mode-line-misc-info `(eglot-mode (" [" eglot--mode-line-format 
"] ")))
 



[elpa] externals/elpa 5ce9ab0 106/139: Call eglot-eldoc-function after completion finishes

2018-05-14 Thread Jo�o T�vora
branch: externals/elpa
commit 5ce9ab01d609aff1a5b3d90d0d772dbf709ca6c1
Author: João Távora 
Commit: João Távora 

Call eglot-eldoc-function after completion finishes

* eglot.el (eglot-completion-at-point): Call
eglot-eldoc-function after completion finishes.
---
 eglot.el | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/eglot.el b/eglot.el
index 0795bc3..d5eae03 100644
--- a/eglot.el
+++ b/eglot.el
@@ -1292,7 +1292,9 @@ DUMMY is ignored"
(lambda (items) (sort items (lambda (a b)
  (string-lessp
   (get-text-property 0 :sortText a)
-  (get-text-property 0 :sortText b)
+  (get-text-property 0 :sortText b)
+   :exit-function
+   (lambda (_string _status) (eglot-eldoc-function))
 
 (defvar eglot--highlights nil "Overlays for textDocument/documentHighlight.")
 



[elpa] externals/elpa 193c57d 075/139: Half-decent xref support

2018-05-14 Thread Jo�o T�vora
branch: externals/elpa
commit 193c57d02872f8fd17b652514c553835d932d2e9
Author: João Távora 
Commit: João Távora 

Half-decent xref support

* eglot.el
(eglot--xref-known-symbols): New hacky var.
(eglot--xref-reset-known-symbols): New helper.
(xref-find-definitions, xref-find-references): Advise after to
call the new helper.
(xref-backend-identifier-completion-table): Rework.
(eglot--xref-make): New helper.
(xref-backend-definitions): Use it.
(xref-backend-references, xref-backend-apropos): Implement.
(eglot--obj): Add a debug spec.
(eglot--lambda): Add debug spec.
---
 eglot.el | 132 +++
 1 file changed, 90 insertions(+), 42 deletions(-)

diff --git a/eglot.el b/eglot.el
index ad9ad52..cb92361 100644
--- a/eglot.el
+++ b/eglot.el
@@ -33,6 +33,7 @@
 (require 'compile) ; for some faces
 (require 'warnings)
 (require 'flymake)
+(require 'xref)
 
 
 ;;; User tweakable stuff
@@ -171,6 +172,7 @@ CONTACT is as `eglot--contact'.  Returns a process object."
 
 (defmacro eglot--obj ( what)
   "Make WHAT a suitable argument for `json-encode'."
+  (declare (debug ( form)))
   ;; FIXME: maybe later actually do something, for now this just fixes
   ;; the indenting of literal plists.
   `(list ,@what))
@@ -736,7 +738,7 @@ Meaning only return locally if successful, otherwise exit 
non-locally."
   (mapcar (lambda (e) (apply fun e)) seq))
 
 (cl-defmacro eglot--lambda (cl-lambda-list  body)
-  (declare (indent 1))
+  (declare (indent 1) (debug (sexp  form)))
   `(cl-function
 (lambda ,cl-lambda-list
   ,@body)))
@@ -1232,16 +1234,46 @@ Calls REPORT-FN maybe if server publishes diagnostics 
in time."
 
 (defun eglot-xref-backend () "EGLOT xref backend." 'eglot)
 
+(defvar eglot--xref-known-symbols nil)
+
+(defun eglot--xref-reset-known-symbols ()
+  "Reset `eglot--xref-reset-known-symbols'."
+  (setq eglot--xref-known-symbols nil))
+
+(advice-add 'xref-find-definitions :after #'eglot--xref-reset-known-symbols)
+(advice-add 'xref-find-references :after #'eglot--xref-reset-known-symbols)
+
+(defun eglot--xref-make (name uri position)
+  "Like `xref-make' but with LSP's NAME, URI and POSITION."
+  (xref-make name
+ (xref-make-file-location
+  (eglot--uri-to-path uri)
+  ;; F!@(#*

[elpa] externals/elpa 29d4103 056/139: Fix mode-line mouse-clicks from outside selected window

2018-05-14 Thread Jo�o T�vora
branch: externals/elpa
commit 29d4103a947c255361c600f9ed74381ad3f2ec6a
Author: João Távora 
Commit: João Távora 

Fix mode-line mouse-clicks from outside selected window

* eglot.el (eglot--mode-line-call): New helper.
(eglot--mode-line-format): Use it.
---
 eglot.el | 28 +++-
 1 file changed, 19 insertions(+), 9 deletions(-)

diff --git a/eglot.el b/eglot.el
index 693535a..bdd339d 100644
--- a/eglot.el
+++ b/eglot.el
@@ -695,6 +695,13 @@ that case, also signal textDocument/didOpen."
 
 (put 'eglot--mode-line-format 'risky-local-variable t)
 
+(defun eglot--mode-line-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
+
 (defun eglot--mode-line-format ()
   "Compose the mode-line format spec."
   (pcase-let* ((proc (eglot--current-process))
@@ -715,7 +722,7 @@ that case, also signal textDocument/didOpen."
 face eglot-mode-line
 keymap ,(let ((map (make-sparse-keymap)))
   (define-key map [mode-line down-mouse-1]
-eglot-menu)
+(eglot--mode-line-call 'eglot-menu))
   map)
 mouse-face mode-line-highlight
 help-echo "mouse-1: pop-up EGLOT menu"
@@ -726,9 +733,12 @@ that case, also signal textDocument/didOpen."
   ,name
   face eglot-mode-line
   keymap ,(let ((map (make-sparse-keymap)))
-(define-key map [mode-line mouse-1] 'eglot-events-buffer)
-(define-key map [mode-line mouse-2] 'eglot-shutdown)
-(define-key map [mode-line mouse-3] 'eglot-reconnect)
+(define-key map [mode-line mouse-1]
+  (eglot--mode-line-call 'eglot-events-buffer))
+(define-key map [mode-line mouse-2]
+  (eglot--mode-line-call 'eglot-shutdown))
+(define-key map [mode-line mouse-3]
+  (eglot--mode-line-call 'eglot-reconnect))
 map)
   mouse-face mode-line-highlight
   help-echo ,(concat "mouse-1: go to events buffer\n"
@@ -744,9 +754,9 @@ that case, also signal textDocument/didOpen."
 face compilation-mode-line-fail
 keymap ,(let ((map (make-sparse-keymap)))
   (define-key map [mode-line mouse-1]
-'eglot-events-buffer)
+(eglot--mode-line-call 'eglot-events-buffer))
   (define-key map [mode-line mouse-3]
-'eglot-clear-status)
+(eglot--mode-line-call 'eglot-clear-status))
   map
  ,@(when (and doing (not done-p))
  `("/"
@@ -757,7 +767,7 @@ that case, also signal textDocument/didOpen."
 face compilation-mode-line-run
 keymap ,(let ((map (make-sparse-keymap)))
   (define-key map [mode-line mouse-1]
-'eglot-events-buffer)
+(eglot--mode-line-call 'eglot-events-buffer))
   map
  ,@(when (cl-plusp pending)
  `("/"
@@ -775,9 +785,9 @@ that case, also signal textDocument/didOpen."
  'eglot-mode-line))
 keymap ,(let ((map (make-sparse-keymap)))
   (define-key map [mode-line mouse-1]
-'eglot-events-buffer)
+(eglot--mode-line-call 'eglot-events-buffer))
   (define-key map [mode-line mouse-3]
-'eglot-forget-pending-continuations)
+(eglot--mode-line-call 
'eglot-forget-pending-continuations))
   map)
 
 (add-to-list 'mode-line-misc-info



[elpa] externals/elpa f257d63 089/139: * eglot.el: Reformat to shave off some lines.

2018-05-14 Thread Jo�o T�vora
branch: externals/elpa
commit f257d63256bdefe184c916479ef88e76f7f7d396
Author: João Távora 
Commit: João Távora 

* eglot.el: Reformat to shave off some lines.
---
 eglot.el | 268 +--
 1 file changed, 108 insertions(+), 160 deletions(-)

diff --git a/eglot.el b/eglot.el
index 9d7b16d..ba3b5be 100644
--- a/eglot.el
+++ b/eglot.el
@@ -43,10 +43,9 @@
   :prefix "eglot-"
   :group 'applications)
 
-(defvar eglot-executables
-  '((rust-mode . ("rls"))
-(python-mode . ("pyls"))
-(js-mode . ("javascript-typescript-stdio")))
+(defvar eglot-executables '((rust-mode . ("rls"))
+(python-mode . ("pyls"))
+(js-mode . ("javascript-typescript-stdio")))
   "Alist mapping major modes to server executables.")
 
 (defface eglot-mode-line
@@ -80,8 +79,7 @@
   "Return the current EGLOT process or error."
   (or (eglot--current-process)
   (eglot--error "No current EGLOT process%s"
-(if (project-current) ""
-  " (Also no current project)"
+(if (project-current) "" " (Also no current project)"
 
 (defmacro eglot--define-process-var
 (var-sym initval  doc mode-line-update-p)
@@ -166,13 +164,12 @@ CONTACT is as `eglot--contact'.  Returns a process 
object."
(match-string 1 singleton)
(string-to-number
 (match-string 2 singleton)))
-(make-process
- :name readable-name
- :buffer buffer
- :command contact
- :connection-type 'pipe
- :stderr (get-buffer-create (format "*%s stderr*"
-name))
+(make-process :name readable-name
+  :buffer buffer
+  :command contact
+  :connection-type 'pipe
+  :stderr (get-buffer-create (format "*%s stderr*"
+ name))
 (set-process-filter proc #'eglot--process-filter)
 (set-process-sentinel proc #'eglot--process-sentinel)
 proc))
@@ -186,9 +183,7 @@ CONTACT is as `eglot--contact'.  Returns a process object."
 
 (defun eglot--project-short-name (project)
   "Give PROJECT a short name."
-  (file-name-base
-   (directory-file-name
-(car (project-roots project)
+  (file-name-base (directory-file-name (car (project-roots project)
 
 (defun eglot--all-major-modes ()
   "Return all know major modes."
@@ -202,14 +197,7 @@ CONTACT is as `eglot--contact'.  Returns a process object."
   "What the EGLOT LSP client supports."
   (eglot--obj
:workspace(eglot--obj
-  :applyEdit nil
-  :workspaceEdit nil
-  :didChangeConfiguration nil
-  :didChangeWatchedFiles nil
-  :symbol nil
-  :executeCommand nil
-  :workspaceFolders nil
-  :configuration nil)
+  :symbol `(:dynamicRegistration :json-false))
:textDocument (eglot--obj
   :synchronization (eglot--obj
 :dynamicRegistration :json-false
@@ -277,8 +265,7 @@ SUCCESS-FN with no args if all goes well."
 (intern
  (completing-read
   "[eglot] Start a server to manage buffers of what major mode? "
-  (mapcar #'symbol-name
-  (eglot--all-major-modes)) nil t
+  (mapcar #'symbol-name (eglot--all-major-modes)) nil t
   (symbol-name major-mode) nil
   (symbol-name major-mode) nil)))
(t major-mode)))
@@ -332,17 +319,16 @@ INTERACTIVE is t if called interactively."
   (eglot-reconnect current-process interactive)
 (when (process-live-p current-process)
   (eglot-shutdown current-process 'sync))
-(eglot--connect
- project
- managed-major-mode
- short-name
- command
- (lambda (proc)
-   (eglot--message "Connected! Process `%s' now managing `%s' \
-buffers in project `%s'."
-   proc
-   managed-major-mode
-   short-name)))
+(eglot--connect project
+managed-major-mode
+short-name
+command
+(lambda (proc)
+  (eglot--message "Connected! Process `%s' now \
+managing `%s' buffers in project `%s'."
+  proc
+  managed-major-mode
+  short-name)))
 
 (defun eglot-reconnect (process  interactive)
   "Reconnect to 

[elpa] externals/elpa 8160cd4 071/139: Handle dynamic registration in general (but nothing specific yet)

2018-05-14 Thread Jo�o T�vora
branch: externals/elpa
commit 8160cd41fd7c0ff1ce436da2d1100f14f7c33efe
Author: João Távora 
Commit: João Távora 

Handle dynamic registration in general (but nothing specific yet)

* eglot.el (eglot--server-client/registerCapability): Implement.
(eglot--register-workspace/didChangeWatchedFiles): Dummy registrator.
---
 eglot.el | 41 -
 1 file changed, 32 insertions(+), 9 deletions(-)

diff --git a/eglot.el b/eglot.el
index 68fe3e2..2b3f270 100644
--- a/eglot.el
+++ b/eglot.el
@@ -1003,15 +1003,28 @@ running.  INTERACTIVE is t if called interactively."
 (cl-defun eglot--server-client/registerCapability
 (proc  id registrations)
   "Handle notification client/registerCapability"
-  (mapc (lambda (reg)
-  (apply (cl-function
-  (lambda ( _id _method _registerOptions)
-;;; TODO: handle this
-))
- reg))
-registrations)
-  (eglot--reply proc id :error (eglot--obj :code -32601
-   :message "sorry :-(")))
+  (catch 'done
+(mapc
+ (lambda (reg)
+   (apply
+(cl-function
+ (lambda ( id method registerOptions)
+   (pcase-let*
+   ((handler-sym (intern (concat "eglot--register-"
+ method)))
+(`(,ok ,message)
+ (and (functionp handler-sym)
+  (apply handler-sym proc :id id registerOptions
+ (unless ok
+   (throw
+'done
+(eglot--reply proc id
+  :error (eglot--obj
+  :code -32601
+  :message (or message "sorry :-("
+reg))
+ registrations)
+(eglot--reply proc id :result (eglot--obj :message "OK"
 
 (defvar eglot--recent-before-changes nil
   "List of recent changes as collected by `eglot--before-change'.")
@@ -1177,6 +1190,16 @@ Calls REPORT-FN maybe if server publishes diagnostics in 
time."
   (eglot--signal-textDocument/didChange))
 
 
+;;; Dynamic registration
+;;;
+(cl-defun eglot--register-workspace/didChangeWatchedFiles
+(_proc  _id _watchers)
+  "Handle dynamic registration of workspace/didChangeWatchedFiles"
+  ;; TODO: file-notify-add-watch and
+  ;; file-notify-rm-watch can probably handle this
+  (list nil "Sorry, can't do this yet"))
+
+
 ;;; Rust-specific
 ;;;
 (cl-defun eglot--server-window/progress



[elpa] externals/elpa 3e0f1c3 122/139: Misc little adjustments for readability

2018-05-14 Thread Jo�o T�vora
branch: externals/elpa
commit 3e0f1c353924e36c6b90b16c1a03bf716a7521d6
Author: João Távora 
Commit: João Távora 

Misc little adjustments for readability

* eglot.el (eglot--log-event, eglot--process-receive)
(eglot--xref-make, xref-backend-apropos): Use cl-destructuring-bind.
(eglot--server-window/showMessageRequest): Compact.
---
 eglot.el | 122 ++-
 1 file changed, 58 insertions(+), 64 deletions(-)

diff --git a/eglot.el b/eglot.el
index 3557303..4c5d53e 100644
--- a/eglot.el
+++ b/eglot.el
@@ -467,62 +467,58 @@ INTERACTIVE is t if called interactively."
 PROC is the current process.  MESSAGE is a JSON-like plist.  TYPE
 is a symbol saying if this is a client or server originated."
   (with-current-buffer (eglot-events-buffer proc)
-(let* ((inhibit-read-only t)
-   (id (plist-get message :id))
-   (error (plist-get message :error))
-   (method (plist-get message :method))
-   (subtype (cond ((and method id)   'request)
-  (method'notification)
-  (id'reply)
-  (t 'message)))
-   (type
-(format "%s-%s" (or type :internal) subtype)))
-  (goto-char (point-max))
-  (let ((msg (format "%s%s%s:\n%s\n"
- type
- (if id (format " (id:%s)" id) "")
- (if error " ERROR" "")
- (pp-to-string message
-(when error
-  (setq msg (propertize msg 'face 'error)))
-(insert-before-markers msg)
+(cl-destructuring-bind ( method id error ) message
+  (let* ((inhibit-read-only t)
+ (subtype (cond ((and method id)   'request)
+(method'notification)
+(id'reply)
+(t 'message)))
+ (type
+  (format "%s-%s" (or type :internal) subtype)))
+(goto-char (point-max))
+(let ((msg (format "%s%s%s:\n%s\n"
+   type
+   (if id (format " (id:%s)" id) "")
+   (if error " ERROR" "")
+   (pp-to-string message
+  (when error
+(setq msg (propertize msg 'face 'error)))
+  (insert-before-markers msg))
 
 (defun eglot--process-receive (proc message)
   "Process MESSAGE from PROC."
-  (let* ((id (plist-get message :id))
- (method (plist-get message :method))
- (err (plist-get message :error))
- (continuations (and id
- (not method)
- (gethash id (eglot--pending-continuations 
proc)
-(eglot--log-event proc message 'server)
-(when err (setf (eglot--status proc) `(,err t)))
-(cond (method
-   ;; a server notification or a server request
-   (let* ((handler-sym (intern (concat "eglot--server-" method
- (if (functionp handler-sym)
- (apply handler-sym proc (append
-  (plist-get message :params)
-  (if id `(:id ,id
-   (eglot--warn "No implementation of method %s yet" method)
-   (when id
- (eglot--reply
-  proc id
-  :error (eglot--obj :code -32601
- :message "Method unimplemented"))
-  (continuations
-   (cancel-timer (cl-third continuations))
-   (remhash id (eglot--pending-continuations proc))
-   (if err
-   (apply (cl-second continuations) err)
- (let ((res (plist-get message :result)))
-   (if (listp res)
-   (apply (cl-first continuations) res)
- (funcall (cl-first continuations) res)
-  (id
-   (eglot--warn "Ooops no continuation for id %s" id)))
-(eglot--call-deferred proc)
-(force-mode-line-update t)))
+  (cl-destructuring-bind ( method id error ) message
+(let* ((continuations (and id
+   (not method)
+   (gethash id (eglot--pending-continuations 
proc)
+  (eglot--log-event proc message 'server)
+  (when error (setf (eglot--status proc) `(,error t)))
+  (cond (method
+ ;; a server notification or a server request
+ (let* ((handler-sym (intern (concat "eglot--server-" method
+   (if (functionp handler-sym)
+   (apply handler-sym proc (append
+(plist-get message :params)
+(if id `(:id ,id
+  

[elpa] externals/elpa fc6879f 084/139: Explain why didOpen on after-revert-hook is a bad idea

2018-05-14 Thread Jo�o T�vora
branch: externals/elpa
commit fc6879fc69dc0a2cfda6168ee65920efb4a770c1
Author: João Távora 
Commit: João Távora 

Explain why didOpen on after-revert-hook is a bad idea

The reason is that the global find-file-hook is called again, and that
already does the didOpen. Too many didOpen's would be bad.

* eglot.el (eglot--managed-mode): Remove commented lines.
---
 eglot.el | 2 --
 1 file changed, 2 deletions(-)

diff --git a/eglot.el b/eglot.el
index 2ab4781..068e2ca 100644
--- a/eglot.el
+++ b/eglot.el
@@ -784,7 +784,6 @@ 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 '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)
@@ -796,7 +795,6 @@ Meaning only return locally if successful, otherwise exit 
non-locally."
 (remove-hook 'before-change-functions 'eglot--before-change t)
 (remove-hook 'kill-buffer-hook 'eglot--signal-textDocument/didClose t)
 (remove-hook 'before-revert-hook 'eglot--signal-textDocument/didClose t)
-;; (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)



[elpa] externals/elpa a3545fb 050/139: Rename RPC methods for clarity

2018-05-14 Thread Jo�o T�vora
branch: externals/elpa
commit a3545fbf2a0e896b7129a49d3eafe1f4c0dee98b
Author: João Távora 
Commit: João Távora 

Rename RPC methods for clarity

* eglot.el (eglot--process-receive): Search for RPC server methods
under `eglot--server-'
(eglot-editing-mode, eglot--maybe-activate-editing-mode): Use new
signal names.
(eglot--server-window/showMessage): Rename from
eglot--window/showMessage.
(eglot--server-textDocument/publishDiagnostics): Renamed from
eglot--textDocument/publishDiagnostics.
(eglot--current-buffer-versioned-identifier): Remove.
(eglot--current-buffer-VersionedTextDocumentIdentifier): Use
eglot--versioned-identifier.
(eglot--signal-textDocument/didChange): Renamed from
eglot--maybe-signal-didChange.
(eglot--signal-textDocument/didOpen): Renamed from
eglot--signalDidOpen.
(eglot--signal-textDocument/didClose): Rename from
eglot--signalDidClose.
(eglot-flymake-backend): Call eglot--signal-textDocument/didChange.
(eglot--server-window/progress): Rename from
eglot--window/progress.
---
 eglot.el | 36 
 1 file changed, 16 insertions(+), 20 deletions(-)

diff --git a/eglot.el b/eglot.el
index 7d44e6d..469d3f7 100644
--- a/eglot.el
+++ b/eglot.el
@@ -455,12 +455,12 @@ identifier.  ERROR is non-nil if this is an error."
   (apply (cl-first continuations) (plist-get message 
:result)
   (t
(let* ((method (plist-get message :method))
-  (handler-sym (intern (concat "eglot--"
+  (handler-sym (intern (concat "eglot--server-"
method
  (if (functionp handler-sym)
  (apply handler-sym proc (plist-get message :params))
-   (eglot--debug "No implemetation for notification %s yet"
- method)))
+   (eglot--warn "No implemetation for notification %s yet"
+method)))
 
 (defvar eglot--expect-carriage-return nil)
 
@@ -612,15 +612,15 @@ identifier.  ERROR is non-nil if this is an error."
 (eglot-mode 1)
 (add-hook 'after-change-functions 'eglot--after-change nil t)
 (add-hook 'flymake-diagnostic-functions 'eglot-flymake-backend nil t)
-(add-hook 'kill-buffer-hook 'eglot--signalDidClose nil t)
+(add-hook 'kill-buffer-hook 'eglot--signal-textDocument/didClose nil t)
 (flymake-mode 1)
 (if (eglot--current-process)
-(eglot--signalDidOpen)
+(eglot--signal-textDocument/didOpen)
   (eglot--warn "No process, start one with `M-x eglot'")))
(t
 (remove-hook 'flymake-diagnostic-functions 'eglot-flymake-backend t)
 (remove-hook 'after-change-functions 'eglot--after-change t)
-(remove-hook 'kill-buffer-hook 'eglot--signalDidClose t
+(remove-hook 'kill-buffer-hook 'eglot--signal-textDocument/didClose t
 
 (define-minor-mode eglot-mode
   "Minor mode for all buffers managed by EGLOT in some way."  nil
@@ -643,7 +643,7 @@ that case, also signal textDocument/didOpen."
 (and proc (eq proc cur)))
 (unless eglot-editing-mode
   (eglot-editing-mode 1))
-(eglot--signalDidOpen)
+(eglot--signal-textDocument/didOpen)
 (flymake-start)
 
 (add-hook 'find-file-hook 'eglot--maybe-activate-editing-mode)
@@ -805,7 +805,7 @@ running.  INTERACTIVE is t if called interactively."
  :async-p (not sync)
  :timeout-fn brutal)))
 
-(cl-defun eglot--window/showMessage
+(cl-defun eglot--server-window/showMessage
 (process  type message)
   "Handle notification window/showMessage"
   (when (<= 1 type)
@@ -821,7 +821,7 @@ running.  INTERACTIVE is t if called interactively."
 (defvar-local eglot--unreported-diagnostics nil
   "Unreported diagnostics for this buffer.")
 
-(cl-defun eglot--textDocument/publishDiagnostics
+(cl-defun eglot--server-textDocument/publishDiagnostics
 (_process  uri diagnostics)
   "Handle notification publishDiagnostics"
   (let* ((obj (url-generic-parse-url uri))
@@ -873,11 +873,6 @@ running.  INTERACTIVE is t if called interactively."
 
 (defvar-local eglot--versioned-identifier 0)
 
-(defun eglot--current-buffer-versioned-identifier ()
-  "Return a VersionedTextDocumentIdentifier."
-  ;; FIXME: later deal with workspaces
-  eglot--versioned-identifier)
-
 (defun eglot--current-buffer-VersionedTextDocumentIdentifier ()
   "Compute VersionedTextDocumentIdentifier object for current buffer."
   (eglot--obj :uri
@@ -885,7 +880,8 @@ running.  INTERACTIVE is t if called interactively."
   (url-hexify-string
(file-truename buffer-file-name)
url-path-allowed-chars))
-  :version (eglot--current-buffer-versioned-identifier)))
+  ;; FIXME: later deal with workspaces
+  :version 

[elpa] externals/elpa a7ddce6 080/139: Support javascript's javascript-typescript-langserver

2018-05-14 Thread Jo�o T�vora
branch: externals/elpa
commit a7ddce694ac1f35c240700ff6f9edd379704feeb
Author: João Távora 
Commit: João Távora 

Support javascript's javascript-typescript-langserver

* README.md: Improve a bit

* eglot.el (eglot--make-process): Take MANAGED-MAJOR-MODE arg
(eglot-executables): Add basic javascript support.
(eglot--connect): Pass mode to eglot--make-process
(eglot--interactive): Check that guessed command is a listp.
(eglot): Minor improvement to message.
(eglot--current-buffer-TextDocumentItem): Guess language from mode
symbol.
---
 README.md | 42 +-
 eglot.el  | 41 +++--
 2 files changed, 60 insertions(+), 23 deletions(-)

diff --git a/README.md b/README.md
index 8809421..0314664 100644
--- a/README.md
+++ b/README.md
@@ -11,14 +11,41 @@ M-x eglot
 ```
 
 *That's it*. Either this guesses the local LSP program to start for
-the language of your choice or it prompts you for such a thing. You
-can also enter a `server:port` pattern to connect to an LSP server. To
-skip the guess and always be prompted use `C-u M-x eglot`.
+the language of your choice or it prompts you for such a
+thing. Currently, if you have these programs installed, it works
+out-of-the-box for:
 
-## Differences to lsp-mode.el
+* Javascript's [javascript-typescript-stdio][javascript-typescript-langserver]
+* Rust's [rls][rls]
+* Python's [pyls][pyls]
+
+You can also enter a `server:port` pattern to connect to an LSP
+server. To skip the guess and always be prompted use `C-u M-x eglot`.
+
+# Supported Protocol features
+
+- [x] textDocument/didChange (incremental)
+- [x] textDocument/didClose
+- [x] textDocument/didOpen
+- [x] textDocument/didSave
+
+- [ ] textDocument/codeAction
+- [ ] textDocument/completion (incl. completion/resolve)
+- [x] textDocument/definition
+- [ ] textDocument/documentHighlight
+- [ ] textDocument/documentSymbol
+- [ ] textDocument/executeCommand
+- [ ] textDocument/format
+- [ ] textDocument/hover
+- [ ] textDocument/rename
+- [x] textDocument/references
+- [ ] textDocument/signatureHelp
+- [x] workspace/symbol
+
+# Differences to lsp-mode.el
 
 This is really beta and currently does less than
-[lsp-mode.el](https://github.com/emacs-lsp/lsp-mode) which is more
+[lsp-mode.el][emacs-lsp] which is more
 mature. Though I think `eglot.el` will eventually beat it, you could
 be better served with `lsp-mode.el` for now.
 
@@ -45,5 +72,10 @@ Differences under the hood:
   tiny change. 
 - Its missing tests! This is *not good*
 
+[rls]: https://github.com/rust-lang-nursery/rls
+[pyls]: https://github.com/palantir/python-language-server
+[javascript-typescript-langserver]: 
https://github.com/sourcegraph/javascript-typescript-langserver
+[emacs-lsp]: https://github.com/emacs-lsp/lsp-mode
+
 

diff --git a/eglot.el b/eglot.el
index cd48519..045588d 100644
--- a/eglot.el
+++ b/eglot.el
@@ -42,8 +42,10 @@
   :prefix "eglot-"
   :group 'applications)
 
-(defvar eglot-executables '((rust-mode . ("rls"))
-(python-mode . ("pyls")))
+(defvar eglot-executables
+  '((rust-mode . ("rls"))
+(python-mode . ("pyls"))
+(js-mode . ("javascript-typescript-stdio")))
   "Alist mapping major modes to server executables.")
 
 (defface eglot-mode-line
@@ -145,23 +147,24 @@ list of a single string of the form :")
 (eglot--define-process-var eglot--buffer-open-count (make-hash-table)
   "Keeps track of didOpen/didClose notifs for each buffer.")
 
-(defun eglot--make-process (name contact)
+(defun eglot--make-process (name managed-major-mode contact)
   "Make a process from CONTACT.
 NAME is a name to give the inferior process or connection.
+MANAGED-MAJOR-MODE is a symbol naming a major mode.
 CONTACT is as `eglot--contact'.  Returns a process object."
-  (let* ((readable-name (format "EGLOT server (%s)" name))
+  (let* ((readable-name (format "EGLOT server (%s/%s)" name 
managed-major-mode))
  (buffer (get-buffer-create
   (format "*%s inferior*" readable-name)))
- (singleton (and (null (cdr contact)) (car contact)))
+ singleton
  (proc
-  (if (and
-   singleton
-   (string-match "^[\s\t]*\\(.*\\):\\([[:digit:]]+\\)[\s\t]*$"
- singleton))
+  (if (and (setq singleton (and (null (cdr contact)) (car contact)))
+   (string-match "^[\s\t]*\\(.*\\):\\([[:digit:]]+\\)[\s\t]*$"
+ singleton))
   (open-network-stream readable-name
buffer
(match-string 1 singleton)
-   (string-to-number (match-string 2 
singleton)))
+   (string-to-number
+(match-string 2 singleton)))
 (make-process
  

[elpa] externals/elpa 4d4b85d 061/139: eglot-editing-mode becomes eglot--managed-mode

2018-05-14 Thread Jo�o T�vora
branch: externals/elpa
commit 4d4b85d9a7592a745c3edb50f3cd40162561f0fe
Author: João Távora 
Commit: João Távora 

eglot-editing-mode becomes eglot--managed-mode

* eglot.el (eglot--sentinel): Use eglot--managed-mode.
(eglot--managed-mode-map): Renamed from eglot-editing-mode-map.
(eglot--managed-mode): Renamed from eglot-editing-mode.
(eglot-mode): Simplify.
(eglot--buffer-managed-p): New function.
(eglot--maybe-activate-editing-mode): Simplify.
---
 eglot.el | 63 +--
 1 file changed, 33 insertions(+), 30 deletions(-)

diff --git a/eglot.el b/eglot.el
index ec7f3e6..0300ad3 100644
--- a/eglot.el
+++ b/eglot.el
@@ -341,12 +341,20 @@ INTERACTIVE is t if called interactively."
   "(sentinel) Cancelling timer for continuation %s" id)
  (cancel-timer timeout)))
  (eglot--pending-continuations process))
+;; Turn off `eglot--managed-mode' where appropriate.
+;;
+(dolist (buffer (buffer-list))
+  (with-current-buffer buffer
+(when (eglot--buffer-managed-p process)
+  (eglot--managed-mode -1
+;; Forget about the process-project relationship
+;;
+(setf (gethash (eglot--project process) eglot--processes-by-project)
+  (delq process
+(gethash (eglot--project process) 
eglot--processes-by-project)))
 (cond ((eglot--moribund process)
(eglot--message "(sentinel) Moribund process exited with status %s"
-   (process-exit-status process))
-   (setf (gethash (eglot--project process) eglot--processes-by-project)
- (delq process
-   (gethash (eglot--project process) 
eglot--processes-by-project
+   (process-exit-status process)))
   (t
(eglot--warn
 "(sentinel) Reconnecting after process unexpectedly changed to %s."
@@ -641,60 +649,55 @@ identifier.  ERROR is non-nil if this is an error."
 ;;;
 (defvar eglot-mode-map (make-sparse-keymap))
 
-(defvar eglot-editing-mode-map (make-sparse-keymap))
+(defvar eglot--managed-mode-map (make-sparse-keymap))
 
-(define-minor-mode eglot-editing-mode
-  "Minor mode for source buffers where EGLOT helps you edit."
+(define-minor-mode eglot--managed-mode
+  "Mode for source buffers managed by some EGLOT project."
   nil
   nil
   eglot-mode-map
   (cond
-   (eglot-editing-mode
+   (eglot--managed-mode
 (eglot-mode 1)
 (add-hook 'after-change-functions 'eglot--after-change nil t)
 (add-hook 'before-change-functions 'eglot--before-change nil t)
 (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)
-(flymake-mode 1)
-(unless (eglot--current-process)
-  (eglot--warn "No process, start one with `M-x eglot'")))
+(flymake-mode 1))
(t
 (remove-hook 'flymake-diagnostic-functions 'eglot-flymake-backend t)
 (remove-hook 'after-change-functions 'eglot--after-change t)
 (remove-hook 'before-change-functions 'eglot--before-change t)
 (remove-hook 'kill-buffer-hook 'eglot--signal-textDocument/didClose t)
 (remove-hook 'before-revert-hook 'eglot--signal-textDocument/didClose t)
-(remove-hook 'after-revert-hook 'eglot--signal-textDocument/didOpen t)
+;; (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
 
 (define-minor-mode eglot-mode
   "Minor mode for all buffers managed by EGLOT in some way."  nil
-  nil eglot-mode-map
-  (cond (eglot-mode
- (when (and buffer-file-name
-(not eglot-editing-mode))
-   (eglot-editing-mode 1)))
-(t
- (when eglot-editing-mode
-   (eglot-editing-mode -1)
+  nil eglot-mode-map)
+
+(defun eglot--buffer-managed-p ( proc)
+  "Tell if current buffer is managed by PROC."
+  (and buffer-file-name
+   (let ((cur (eglot--current-process)))
+ (or (and (null proc) cur)
+ (and proc (eq proc cur))
 
 (defun eglot--maybe-activate-editing-mode ( proc)
-  "Maybe activate mode function `eglot-editing-mode'.
+  "Maybe activate mode function `eglot--managed-mode'.
 If PROC is supplied, do it only if BUFFER is managed by it.  In
 that case, also signal textDocument/didOpen."
-  (when buffer-file-name
-(let 

[elpa] externals/elpa 29f58a6 127/139: Get rid of catch/loop/throw idiom (suggested by Thien-Thi Nguyen)

2018-05-14 Thread Jo�o T�vora
branch: externals/elpa
commit 29f58a6514aec28e4e6df9611e4f58c7289e3cc6
Author: João Távora 
Commit: João Távora 

Get rid of catch/loop/throw idiom (suggested by Thien-Thi Nguyen)

* eglot.el (eglot--process-filter)
(eglot--request): Replace catch/loop/throw idiom with let/test/loop/set
---
 eglot.el | 44 +++-
 1 file changed, 19 insertions(+), 25 deletions(-)

diff --git a/eglot.el b/eglot.el
index aabaf54..c8612cf 100644
--- a/eglot.el
+++ b/eglot.el
@@ -400,8 +400,7 @@ INTERACTIVE is t if called interactively."
   (when (buffer-live-p (process-buffer proc))
 (with-current-buffer (process-buffer proc)
   (let ((inhibit-read-only t)
-(expected-bytes (eglot--expected-bytes proc))
-(done (make-symbol "eglot--process-filter-done-tag")))
+(expected-bytes (eglot--expected-bytes proc)))
 ;; Insert the text, advancing the process marker.
 ;;
 (save-excursion
@@ -411,8 +410,8 @@ INTERACTIVE is t if called interactively."
 ;; Loop (more than one message might have arrived)
 ;;
 (unwind-protect
-(catch done
-  (while t
+(let (done)
+  (while (not done)
 (cond
  ((not expected-bytes)
   ;; Starting a new message
@@ -425,7 +424,7 @@ INTERACTIVE is t if called interactively."
   t)
  (string-to-number (match-string 1
   (unless expected-bytes
-(throw done :waiting-for-new-message)))
+(setq done :waiting-for-new-message)))
  (t
   ;; Attempt to complete a message body
   ;;
@@ -453,7 +452,7 @@ INTERACTIVE is t if called interactively."
  (t
   ;; Message is still incomplete
   ;;
-  (throw done 
:waiting-for-more-bytes-in-this-message
+  (setq done 
:waiting-for-more-bytes-in-this-message
   ;; Saved parsing state for next visit to this filter
   ;;
   (setf (eglot--expected-bytes proc) expected-bytes))
@@ -652,25 +651,20 @@ DEFERRED is passed to `eglot--async-request', which see."
   ;; bad idea, since that might lead to the request never having a
   ;; chance to run, because `eglot--ready-predicates'.
   (when deferred (eglot--signal-textDocument/didChange))
-  (let* ((done (make-symbol "eglot--request-catch-tag"))
- (res
-  (catch done (eglot--async-request
-   proc method params
-   :success-fn (lambda ( args)
- (throw done (if (vectorp (car args))
- (car args) args)))
-   :error-fn (eglot--lambda
- ( code message )
-   (throw done
-  `(error ,(format "Oops: %s: %s"
-   code message
-   :timeout-fn (lambda ()
- (throw done '(error "Timed out")))
-   :deferred deferred)
- ;; now spin, baby!
- (while t (accept-process-output nil 0.01)
-(when (and (listp res) (eq 'error (car res))) (eglot--error (cadr res)))
-res))
+  (let ((retval))
+(eglot--async-request
+ proc method params
+ :success-fn (lambda ( args)
+   (setq retval `(done ,(if (vectorp (car args))
+(car args) args
+ :error-fn (eglot--lambda ( code message )
+ (setq retval `(error ,(format "Oops: %s: %s" code message
+ :timeout-fn (lambda ()
+   (setq retval '(error "Timed out")))
+ :deferred deferred)
+(while (not retval) (accept-process-output nil 30))
+(when (eq 'error (car retval)) (eglot--error (cadr retval)))
+(cadr retval)))
 
 (cl-defun eglot--notify (process method params)
   "Notify PROCESS of something, don't expect a reply.e"



[elpa] externals/elpa 56c2e1d 104/139: Get rid of eglot-mode

2018-05-14 Thread Jo�o T�vora
branch: externals/elpa
commit 56c2e1dec4413e146242e97714867c0c9a6ed947
Author: João Távora 
Commit: João Távora 

Get rid of eglot-mode

* eglot.el (eglot--managed-mode): Don't call eglot-mode. When
shutting down, offer to kill server.
(mode-line-misc-info): Update to use eglot--managed-mode
---
 eglot.el | 13 ++---
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/eglot.el b/eglot.el
index 3eb43ce..bed98ed 100644
--- a/eglot.el
+++ b/eglot.el
@@ -769,7 +769,6 @@ Meaning only return locally if successful, otherwise exit 
non-locally."
   nil nil eglot-mode-map
   (cond
(eglot--managed-mode
-(eglot-mode 1)
 (add-hook 'after-change-functions 'eglot--after-change nil t)
 (add-hook 'before-change-functions 'eglot--before-change nil t)
 (add-hook 'flymake-diagnostic-functions 'eglot-flymake-backend nil t)
@@ -796,11 +795,10 @@ Meaning only return locally if successful, otherwise exit 
non-locally."
 (remove-hook 'completion-at-point-functions #'eglot-completion-at-point t)
 (remove-function (local 'eldoc-documentation-function)
  #'eglot-eldoc-function)
-(remove-function (local imenu-create-index-function) #'eglot-imenu
-
-(define-minor-mode eglot-mode
-  "Minor mode for all buffers managed by EGLOT in some way."  nil
-  nil eglot-mode-map)
+(remove-function (local imenu-create-index-function) #'eglot-imenu)
+(let ((proc (eglot--current-process)))
+  (when (and (process-live-p proc) (y-or-n-p "[eglot] Kill server too? "))
+(eglot-shutdown proc nil t))
 
 (defun eglot--buffer-managed-p ( proc)
   "Tell if current buffer is managed by PROC."
@@ -886,7 +884,8 @@ Uses THING, FACE, DEFS and PREPEND."
(mouse-3 eglot-clear-status  "clear this status"))
  (format "%d pending requests\n" pending)
 
-(add-to-list 'mode-line-misc-info `(eglot-mode (" [" eglot--mode-line-format 
"] ")))
+(add-to-list 'mode-line-misc-info
+ `(eglot--managed-mode (" [" eglot--mode-line-format "] ")))
 
 
 ;;; Protocol implementation (Requests, notifications, etc)



[elpa] externals/elpa 1add335 078/139: Workaround two suspected Emacs bugs

2018-05-14 Thread Jo�o T�vora
branch: externals/elpa
commit 1add3354d5c46bae530565b77636b8f11207f40f
Author: João Távora 
Commit: João Távora 

Workaround two suspected Emacs bugs

* eglot.el (eglot--process-filter): Use a proper unique tag. Use
unwind-protect.
(eglot--sync-request): Rework.
(eglot--server-client/registerCapability): Use a proper done tag.
---
 eglot.el | 135 ++-
 1 file changed, 72 insertions(+), 63 deletions(-)

diff --git a/eglot.el b/eglot.el
index 321307d..1d72b4c 100644
--- a/eglot.el
+++ b/eglot.el
@@ -415,7 +415,8 @@ INTERACTIVE is t if called interactively."
   (when (buffer-live-p (process-buffer proc))
 (with-current-buffer (process-buffer proc)
   (let ((inhibit-read-only t)
-(expected-bytes (eglot--expected-bytes proc)))
+(expected-bytes (eglot--expected-bytes proc))
+(done (make-symbol "eglot--process-filter-done-tag")))
 ;; Insert the text, advancing the process marker.
 ;;
 (save-excursion
@@ -424,51 +425,52 @@ INTERACTIVE is t if called interactively."
   (set-marker (process-mark proc) (point)))
 ;; Loop (more than one message might have arrived)
 ;;
-(catch 'done
-  (while t
-(cond ((not expected-bytes)
-   ;; Starting a new message
-   ;;
-   (setq expected-bytes
- (and (search-forward-regexp
-   "\\(?:.*: .*\r\n\\)*Content-Length: \
+(unwind-protect
+(catch done
+  (while t
+(cond ((not expected-bytes)
+   ;; Starting a new message
+   ;;
+   (setq expected-bytes
+ (and (search-forward-regexp
+   "\\(?:.*: .*\r\n\\)*Content-Length: \
 *\\([[:digit:]]+\\)\r\n\\(?:.*: .*\r\n\\)*\r\n"
-   (+ (point) 100)
-   t)
-  (string-to-number (match-string 1
-   (unless expected-bytes
- (throw 'done :waiting-for-new-message)))
-  (t
-   ;; Attempt to complete a message body
-   ;;
-   (let ((available-bytes (- (position-bytes (process-mark 
proc))
- (position-bytes (point)
- (cond
-  ((>= available-bytes
-   expected-bytes)
-   (let* ((message-end (byte-to-position
-(+ (position-bytes (point))
-   expected-bytes
- (unwind-protect
- (save-restriction
-   (narrow-to-region (point) message-end)
-   (let* ((json-object-type 'plist)
-  (json-message (json-read)))
- ;; Process content in another buffer,
- ;; shielding buffer from tamper
- ;;
- (with-temp-buffer
-   (eglot--process-receive proc 
json-message
-   (goto-char message-end)
-   (delete-region (point-min) (point))
-   (setq expected-bytes nil
+   (+ (point) 100)
+   t)
+  (string-to-number (match-string 1
+   (unless expected-bytes
+ (throw done :waiting-for-new-message)))
   (t
-   ;; Message is still incomplete
+   ;; Attempt to complete a message body
;;
-   (throw 'done 
:waiting-for-more-bytes-in-this-message
-;; Saved parsing state for next visit to this filter
-;;
-(setf (eglot--expected-bytes proc) expected-bytes)
+   (let ((available-bytes (- (position-bytes (process-mark 
proc))
+ (position-bytes (point)
+ (cond
+  ((>= available-bytes
+   expected-bytes)
+   (let* ((message-end (byte-to-position
+(+ (position-bytes (point))
+   expected-bytes
+ (unwind-protect
+ (save-restriction
+   (narrow-to-region (point) message-end)
+  

[elpa] externals/eglot f76f04e 057/139: More correctly keep track of didOpen/didClose per buffer

2018-05-14 Thread Jo�o T�vora
branch: externals/eglot
commit f76f04e1226dc6a3ebe7b913ee9c6ddaef73634e
Author: João Távora 
Commit: João Távora 

More correctly keep track of didOpen/didClose per buffer

* eglot.el (eglot--buffer-open-count): Now a process-local var.
(eglot--signal-textDocument/didOpen, eglot--signal-textDocument/didClose):
Use it.
---
 eglot.el | 42 +++---
 1 file changed, 27 insertions(+), 15 deletions(-)

diff --git a/eglot.el b/eglot.el
index bdd339d..ac52b9a 100644
--- a/eglot.el
+++ b/eglot.el
@@ -138,6 +138,9 @@ A list (WHAT SERIOUS-P)." t)
 Must be a function of one arg, a name, returning a process
 object.")
 
+(eglot--define-process-var eglot--buffer-open-count (make-hash-table)
+  "Keeps track of didOpen/didClose notifs for each buffer.")
+
 (defun eglot-make-local-process (name command)
   "Make a local LSP process from COMMAND.
 NAME is a name to give the inferior process or connection.
@@ -1026,26 +1029,35 @@ Records START, END and PRE-CHANGE-LENGTH locally."
   (setq eglot--recent-before-changes nil
 eglot--recent-after-changes nil))
 
-(defvar-local eglot--buffer-open-count 0)
 (defun eglot--signal-textDocument/didOpen ()
   "Send textDocument/didOpen to server."
-  (cl-incf eglot--buffer-open-count)
-  (when (> eglot--buffer-open-count 1)
-(error "Too many textDocument/didOpen notifs for %s" (current-buffer)))
-  (eglot--notify (eglot--current-process-or-lose)
- :textDocument/didOpen
- (eglot--obj :textDocument
- (eglot--current-buffer-TextDocumentItem
+  (let* ((proc (eglot--current-process-or-lose))
+ (count (1+ (or (gethash (current-buffer)
+ (eglot--buffer-open-count proc))
+0
+(when (> count 1)
+  (eglot--error "Too many textDocument/didOpen notifs for %s" 
(current-buffer)))
+(setf (gethash (current-buffer) (eglot--buffer-open-count proc))
+  count)
+(eglot--notify proc
+   :textDocument/didOpen
+   (eglot--obj :textDocument
+   (eglot--current-buffer-TextDocumentItem)
 
 (defun eglot--signal-textDocument/didClose ()
   "Send textDocument/didClose to server."
-  (cl-decf eglot--buffer-open-count)
-  (when (< eglot--buffer-open-count 0)
-(error "Too many textDocument/didClose notifs for %s" (current-buffer)))
-  (eglot--notify (eglot--current-process-or-lose)
- :textDocument/didClose
- (eglot--obj :textDocument
- (eglot--current-buffer-TextDocumentItem
+  (let* ((proc (eglot--current-process-or-lose))
+ (count (1- (or (gethash (current-buffer)
+ (eglot--buffer-open-count proc))
+0
+(when (< count 0)
+  (eglot--error "Too many textDocument/didClose notifs for %s" 
(current-buffer)))
+(setf (gethash (current-buffer) (eglot--buffer-open-count proc))
+  count)
+(eglot--notify proc
+   :textDocument/didClose
+   (eglot--obj :textDocument
+   (eglot--current-buffer-TextDocumentItem)
 
 (defun eglot--signal-textDocument/willSave ()
   "Send textDocument/willSave to server."



[elpa] externals/elpa fceb6bb 090/139: Get rid of eglot--special-buffer-process

2018-05-14 Thread Jo�o T�vora
branch: externals/elpa
commit fceb6bb5dd740101033d61c5a094bdd1f8b89957
Author: João Távora 
Commit: João Távora 

Get rid of eglot--special-buffer-process

Hasn't really proved useful yet.

* eglot.el (eglot--special-buffer-process): Delete.
(eglot--current-process): Simplify.
(eglot--events-buffer): Simplify.
---
 eglot.el | 18 --
 1 file changed, 4 insertions(+), 14 deletions(-)

diff --git a/eglot.el b/eglot.el
index ba3b5be..1318fee 100644
--- a/eglot.el
+++ b/eglot.el
@@ -61,19 +61,11 @@
 (defvar eglot--processes-by-project (make-hash-table :test #'equal)
   "Keys are projects.  Values are lists of processes.")
 
-(defvar-local eglot--special-buffer-process nil
-  "Current buffer's eglot process.")
-
 (defun eglot--current-process ()
   "The current logical EGLOT process."
-  (or eglot--special-buffer-process
-  (let* ((cur (project-current))
- (processes
-  (and cur
-   (gethash cur eglot--processes-by-project
-(cl-find major-mode
- processes
- :key #'eglot--major-mode
+  (let* ((cur (project-current))
+ (processes (and cur (gethash cur eglot--processes-by-project
+(cl-find major-mode processes :key #'eglot--major-mode)))
 
 (defun eglot--current-process-or-lose ()
   "Return the current EGLOT process or error."
@@ -465,9 +457,7 @@ INTERACTIVE is t if called interactively."
(with-current-buffer buffer
  (buffer-disable-undo)
  (read-only-mode t)
- (setf (eglot--events-buffer process) buffer
-   eglot--special-buffer-process process)
- (eglot-mode))
+ (setf (eglot--events-buffer process) buffer))
buffer
 (when interactive (display-buffer buffer))
 buffer))



[elpa] externals/elpa 9882bf2 072/139: Cleanup mistake with TextDocumentItem and TextDocumentIdentifier

2018-05-14 Thread Jo�o T�vora
branch: externals/elpa
commit 9882bf243cc5b2a4f3700838d2a42a2d9d792f18
Author: João Távora 
Commit: João Távora 

Cleanup mistake with TextDocumentItem and TextDocumentIdentifier

Also introduce eglot--path-to-uri

* eglot.el (eglot--path-to-uri): Rename from eglot--uri and rework.
(eglot--connect): Use it.
(eglot--current-buffer-TextDocumentIdentifier): New function.
(eglot--current-buffer-VersionedTextDocumentIdentifier)
(eglot--signal-textDocument/didChange)
(eglot--signal-textDocument/didClose)
(eglot--signal-textDocument/willSave)
(eglot--signal-textDocument/didSave): Use it.
---
 eglot.el | 30 --
 1 file changed, 16 insertions(+), 14 deletions(-)

diff --git a/eglot.el b/eglot.el
index 2b3f270..2afb0e7 100644
--- a/eglot.el
+++ b/eglot.el
@@ -254,9 +254,8 @@ SUCCESS-FN with no args if all goes well."
  (eglot--obj :processId (unless (eq (process-type proc)
 'network)
   (emacs-pid))
- :rootUri  (eglot--uri
-(expand-file-name (car (project-roots
-(project-current)
+ :rootUri  (eglot--path-to-uri
+(car (project-roots (project-current
  :initializationOptions  []
  :capabilities (eglot--client-capabilities))
  :success-fn
@@ -699,7 +698,11 @@ identifier.  ERROR is non-nil if this is a JSON-RPC error."
  (apply #'format format args)
  :warning)))
 
-(defun eglot--uri (path) "Add file:// to PATH." (concat "file://" path))
+(defun eglot--path-to-uri (path)
+  "Urify PATH."
+  (url-hexify-string
+   (concat "file://" (file-truename path))
+   url-path-allowed-chars))
 
 
 ;;; Minor modes
@@ -1033,15 +1036,14 @@ running.  INTERACTIVE is t if called interactively."
 
 (defvar-local eglot--versioned-identifier 0)
 
+(defun eglot--current-buffer-TextDocumentIdentifier ()
+  "Compute TextDocumentIdentifier object for current buffer."
+  (eglot--obj :uri (eglot--path-to-uri buffer-file-name)))
+
 (defun eglot--current-buffer-VersionedTextDocumentIdentifier ()
   "Compute VersionedTextDocumentIdentifier object for current buffer."
-  (eglot--obj :uri
-  (eglot--uri
-   (url-hexify-string
-(file-truename buffer-file-name)
-url-path-allowed-chars))
-  ;; FIXME: later deal with workspaces
-  :version eglot--versioned-identifier))
+  (append (eglot--current-buffer-TextDocumentIdentifier)
+  (eglot--obj :version eglot--versioned-identifier)))
 
 (defun eglot--current-buffer-TextDocumentItem ()
   "Compute TextDocumentItem object for current buffer."
@@ -1154,7 +1156,7 @@ Records START, END and PRE-CHANGE-LENGTH locally."
 (eglot--notify proc
:textDocument/didClose
(eglot--obj :textDocument
-   (eglot--current-buffer-TextDocumentItem)
+   
(eglot--current-buffer-TextDocumentIdentifier)
 
 (defun eglot--signal-textDocument/willSave ()
   "Send textDocument/willSave to server."
@@ -1163,7 +1165,7 @@ Records START, END and PRE-CHANGE-LENGTH locally."
:textDocument/willSave
(eglot--obj
 :reason 1 ; Manual, emacs laughs in the face of auto-save muahahahaha
-:textDocument (eglot--current-buffer-TextDocumentItem
+:textDocument (eglot--current-buffer-TextDocumentIdentifier
 
 (defun eglot--signal-textDocument/didSave ()
   "Send textDocument/didSave to server."
@@ -1173,7 +1175,7 @@ Records START, END and PRE-CHANGE-LENGTH locally."
(eglot--obj
 ;; TODO: Handle TextDocumentSaveRegistrationOptions to control this.
 :text (buffer-substring-no-properties (point-min) (point-max))
-:textDocument (eglot--current-buffer-TextDocumentItem
+:textDocument (eglot--current-buffer-TextDocumentIdentifier
 
 (defun eglot-flymake-backend (report-fn  _more)
   "An EGLOT Flymake backend.



[elpa] externals/elpa 9577dfc 125/139: Duh, json.el is in Emacs, and json-mode.el is useless here

2018-05-14 Thread Jo�o T�vora
branch: externals/elpa
commit 9577dfc251ed6be8c355b406bc1a196e9d059a07
Author: João Távora 
Commit: João Távora 

Duh, json.el is in Emacs, and json-mode.el is useless here

* eglot.el (Package-Requires): Don't require json-mode
---
 eglot.el | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/eglot.el b/eglot.el
index e33e540..3b3aada 100644
--- a/eglot.el
+++ b/eglot.el
@@ -7,7 +7,7 @@
 ;; Maintainer: João Távora 
 ;; URL: https://github.com/joaotavora/eglot
 ;; Keywords: convenience, languages
-;; Package-Requires: ((emacs "26.1") (json-mode "1.6.0"))
+;; Package-Requires: ((emacs "26.1"))
 
 ;; This program is free software; you can redistribute it and/or modify
 ;; it under the terms of the GNU General Public License as published by



[elpa] externals/eglot 4d4b85d 061/139: eglot-editing-mode becomes eglot--managed-mode

2018-05-14 Thread Jo�o T�vora
branch: externals/eglot
commit 4d4b85d9a7592a745c3edb50f3cd40162561f0fe
Author: João Távora 
Commit: João Távora 

eglot-editing-mode becomes eglot--managed-mode

* eglot.el (eglot--sentinel): Use eglot--managed-mode.
(eglot--managed-mode-map): Renamed from eglot-editing-mode-map.
(eglot--managed-mode): Renamed from eglot-editing-mode.
(eglot-mode): Simplify.
(eglot--buffer-managed-p): New function.
(eglot--maybe-activate-editing-mode): Simplify.
---
 eglot.el | 63 +--
 1 file changed, 33 insertions(+), 30 deletions(-)

diff --git a/eglot.el b/eglot.el
index ec7f3e6..0300ad3 100644
--- a/eglot.el
+++ b/eglot.el
@@ -341,12 +341,20 @@ INTERACTIVE is t if called interactively."
   "(sentinel) Cancelling timer for continuation %s" id)
  (cancel-timer timeout)))
  (eglot--pending-continuations process))
+;; Turn off `eglot--managed-mode' where appropriate.
+;;
+(dolist (buffer (buffer-list))
+  (with-current-buffer buffer
+(when (eglot--buffer-managed-p process)
+  (eglot--managed-mode -1
+;; Forget about the process-project relationship
+;;
+(setf (gethash (eglot--project process) eglot--processes-by-project)
+  (delq process
+(gethash (eglot--project process) 
eglot--processes-by-project)))
 (cond ((eglot--moribund process)
(eglot--message "(sentinel) Moribund process exited with status %s"
-   (process-exit-status process))
-   (setf (gethash (eglot--project process) eglot--processes-by-project)
- (delq process
-   (gethash (eglot--project process) 
eglot--processes-by-project
+   (process-exit-status process)))
   (t
(eglot--warn
 "(sentinel) Reconnecting after process unexpectedly changed to %s."
@@ -641,60 +649,55 @@ identifier.  ERROR is non-nil if this is an error."
 ;;;
 (defvar eglot-mode-map (make-sparse-keymap))
 
-(defvar eglot-editing-mode-map (make-sparse-keymap))
+(defvar eglot--managed-mode-map (make-sparse-keymap))
 
-(define-minor-mode eglot-editing-mode
-  "Minor mode for source buffers where EGLOT helps you edit."
+(define-minor-mode eglot--managed-mode
+  "Mode for source buffers managed by some EGLOT project."
   nil
   nil
   eglot-mode-map
   (cond
-   (eglot-editing-mode
+   (eglot--managed-mode
 (eglot-mode 1)
 (add-hook 'after-change-functions 'eglot--after-change nil t)
 (add-hook 'before-change-functions 'eglot--before-change nil t)
 (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)
-(flymake-mode 1)
-(unless (eglot--current-process)
-  (eglot--warn "No process, start one with `M-x eglot'")))
+(flymake-mode 1))
(t
 (remove-hook 'flymake-diagnostic-functions 'eglot-flymake-backend t)
 (remove-hook 'after-change-functions 'eglot--after-change t)
 (remove-hook 'before-change-functions 'eglot--before-change t)
 (remove-hook 'kill-buffer-hook 'eglot--signal-textDocument/didClose t)
 (remove-hook 'before-revert-hook 'eglot--signal-textDocument/didClose t)
-(remove-hook 'after-revert-hook 'eglot--signal-textDocument/didOpen t)
+;; (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
 
 (define-minor-mode eglot-mode
   "Minor mode for all buffers managed by EGLOT in some way."  nil
-  nil eglot-mode-map
-  (cond (eglot-mode
- (when (and buffer-file-name
-(not eglot-editing-mode))
-   (eglot-editing-mode 1)))
-(t
- (when eglot-editing-mode
-   (eglot-editing-mode -1)
+  nil eglot-mode-map)
+
+(defun eglot--buffer-managed-p ( proc)
+  "Tell if current buffer is managed by PROC."
+  (and buffer-file-name
+   (let ((cur (eglot--current-process)))
+ (or (and (null proc) cur)
+ (and proc (eq proc cur))
 
 (defun eglot--maybe-activate-editing-mode ( proc)
-  "Maybe activate mode function `eglot-editing-mode'.
+  "Maybe activate mode function `eglot--managed-mode'.
 If PROC is supplied, do it only if BUFFER is managed by it.  In
 that case, also signal textDocument/didOpen."
-  (when buffer-file-name
-(let 

[elpa] externals/elpa d0b7773 117/139: Reduce log chatter

2018-05-14 Thread Jo�o T�vora
branch: externals/elpa
commit d0b777334941075d8c6ef1d28d256272973f33f0
Author: João Távora 
Commit: João Távora 

Reduce log chatter

* eglot.el (eglot--process-sentinel, eglot--request): Use
eglot--log-event.
(eglot--log-event): Print "message" if type unknown.
(eglot--debug, eglot--log): Remove.
(eglot--server-window/logMessage, eglot--server-telemetry/event):
Make noops.
(eglot--call-deferred): Also reduce chatter here.
---
 eglot.el | 48 
 1 file changed, 16 insertions(+), 32 deletions(-)

diff --git a/eglot.el b/eglot.el
index 8b8d712..d1e4d15 100644
--- a/eglot.el
+++ b/eglot.el
@@ -341,7 +341,7 @@ INTERACTIVE is t if called interactively."
 
 (defun eglot--process-sentinel (proc change)
   "Called when PROC undergoes CHANGE."
-  (eglot--debug "(sentinel) Process state changed to %s" change)
+  (eglot--log-event proc `(:message "Process state changed" :change ,change))
   (when (not (process-live-p proc))
 ;; Cancel outstanding timers
 (maphash (lambda (_id triplet)
@@ -474,8 +474,7 @@ is a symbol saying if this is a client or server 
originated."
(subtype (cond ((and method id)   'request)
   (method'notification)
   (id'reply)
-  ;; pyls keeps on sending these
-  (t 'unexpected-thingy)))
+  (t 'message)))
(type
 (format "%s-%s" (or type :internal) subtype)))
   (goto-char (point-max))
@@ -553,7 +552,7 @@ is a symbol saying if this is a client or server 
originated."
 
 (defun eglot--call-deferred (proc)
   "Call PROC's deferred actions, who may again defer themselves."
-  (let ((actions (hash-table-values (eglot--deferred-actions proc
+  (when-let ((actions (hash-table-values (eglot--deferred-actions proc
 (eglot--log-event proc `(:running-deferred ,(length actions)))
 (mapc #'funcall (mapcar #'car actions
 
@@ -619,16 +618,15 @@ timeout keeps counting."
 ;; Really run it
 ;;
 (puthash id
- (list (or success-fn (eglot--lambda ( result-body)
-(eglot--debug
- "Request %s, id=%s replied to with 
result=%s"
- method id result-body)))
-   (or error-fn (eglot--lambda
-( code message )
-  (setf (eglot--status proc) `(,message t))
-  (eglot--warn
-   "Request %s, id=%s errored with code=%s: %s"
-   method id code message)))
+ (list (or success-fn
+   (eglot--lambda ( _ignored)
+ (eglot--log-event
+  proc (eglot--obj :message "success ignored" :id 
id
+   (or error-fn
+   (eglot--lambda ( code message )
+ (setf (eglot--status proc) `(,message t))
+ proc (eglot--obj :message "error ignored, status set"
+  :id id :error code)))
(funcall make-timeout))
  (eglot--pending-continuations proc))
 (eglot--process-send proc (eglot--obj :jsonrpc "2.0"
@@ -680,12 +678,6 @@ DEFERRED is passed to `eglot--request', which see."
 
 ;;; Helpers
 ;;;
-(defun eglot--debug (format  args)
-  "Debug message FORMAT with ARGS."
-  (display-warning 'eglot
-   (apply #'format format args)
-   :debug))
-
 (defun eglot--error (format  args)
   "Error out with FORMAT with ARGS."
   (error (apply #'format format args)))
@@ -694,10 +686,6 @@ DEFERRED is passed to `eglot--request', which see."
   "Message out with FORMAT with ARGS."
   (message (concat "[eglot] " (apply #'format format args
 
-(defun eglot--log (format  args)
-  "Log out with FORMAT with ARGS."
-  (message (concat "[eglot-log] " (apply #'format format args
-
 (defun eglot--warn (format  args)
   "Warning message with FORMAT and ARGS."
   (apply #'eglot--message (concat "(warning) " format) args)
@@ -954,15 +942,11 @@ called interactively."
   :error (eglot--obj :code -32800
  :message "User cancelled"))
 
-(cl-defun eglot--server-window/logMessage (_process  type message)
-  "Handle notification window/logMessage"
-  (eglot--log (propertize "Server reports (type=%s): %s"
-  'face (if (<= type 1) 'error))
-  type message))
+(cl-defun eglot--server-window/logMessage (_proc  _type _message)
+  "Handle notification window/logMessage") ;; noop, use events buffer
 
-(cl-defun eglot--server-telemetry/event 

[elpa] externals/eglot 0e95167 042/139: Watch for files opened under umbrella of existing process

2018-05-14 Thread Jo�o T�vora
branch: externals/eglot
commit 0e951677e486a48a1ec583382d77e04b8a457d37
Author: João Távora 
Commit: João Távora 

Watch for files opened under umbrella of existing process

* eglot.el (eglot--connect): Call success-fn with a proc.
(eglot-reconnect): Adapt to new eglot--connect.
(eglot-new-process): Call eglot--maybe-activate-editing-mode
(eglot--maybe-activate-editing-mode): New function.
(find-file-hook): Add it here.
---
 eglot.el | 42 +-
 1 file changed, 25 insertions(+), 17 deletions(-)

diff --git a/eglot.el b/eglot.el
index 10af6c5..f4ac858 100644
--- a/eglot.el
+++ b/eglot.el
@@ -190,7 +190,7 @@ SUCCESS-FN with no args if all goes well."
   (lambda ( capabilities)
 (setf (eglot--capabilities proc) capabilities)
 (setf (eglot--status proc) nil)
-(when success-fn (funcall success-fn)
+(when success-fn (funcall success-fn proc)
 
 (defun eglot-reconnect (process  interactive)
   "Reconnect to PROCESS.
@@ -203,8 +203,8 @@ INTERACTIVE is t if called interactively."
(eglot--major-mode process)
(eglot--short-name process)
(eglot--bootstrap-fn process)
-   (lambda ()
- (eglot--message "Reconnected"
+   (lambda (_proc)
+ (eglot--message "Reconnected!"
 
 (defvar eglot--command-history nil
   "History of COMMAND arguments to `eglot-new-process'.")
@@ -273,21 +273,15 @@ INTERACTIVE is t if called interactively."
(eglot-make-local-process
 name
 command))
- (lambda ()
-   (eglot--message "Connected. Managing `%s' buffers in project %s."
-   managed-major-mode short-name)
+ (lambda (proc)
+   (eglot--message "Connected! Process `%s' now managing `%s'\
+buffers in project %s."
+   proc
+   managed-major-mode
+   short-name)
(dolist (buffer (buffer-list))
  (with-current-buffer buffer
-   (when(and buffer-file-name
- (cl-some
-  (lambda (root)
-(string-prefix-p
- (expand-file-name root)
- (expand-file-name buffer-file-name)))
-  (project-roots project)))
- (unless eglot-editing-mode
-   (eglot-editing-mode 1))
- (eglot--signalDidOpen)))
+   (eglot--maybe-activate-editing-mode proc))
 
 (defun eglot--process-sentinel (process change)
   "Called with PROCESS undergoes CHANGE."
@@ -706,7 +700,7 @@ running.  INTERACTIVE is t if called interactively."
 
 
 
-;;; Mode line
+;;; Minor modes and mode-line
 ;;;
 (defface eglot-mode-line
   '((t (:inherit font-lock-constant-face :weight bold)))
@@ -717,6 +711,20 @@ running.  INTERACTIVE is t if called interactively."
 
 (defvar eglot-editing-mode-map (make-sparse-keymap))
 
+(defun eglot--maybe-activate-editing-mode ( proc)
+  "Maybe activate mode function `eglot-editing-mode'.
+If PROC is supplied, do it only if BUFFER is managed by it.  In
+that case, also signal textDocument/didOpen."
+  (when buffer-file-name
+(let ((cur (eglot--current-process)))
+  (when (or (and (null proc) cur)
+(and proc (eq proc cur)))
+(unless eglot-editing-mode
+  (eglot-editing-mode 1))
+(eglot--signalDidOpen)
+
+(add-hook 'find-file-hook 'eglot--maybe-activate-editing-mode)
+
 (define-minor-mode eglot-editing-mode
   "Minor mode for source buffers where EGLOT helps you edit."
   nil



[elpa] externals/elpa d2eca65 045/139: Fix another Flymake sync bug

2018-05-14 Thread Jo�o T�vora
branch: externals/elpa
commit d2eca65b86acea1e7ce293f737806affec8f89c4
Author: João Távora 
Commit: João Távora 

Fix another Flymake sync bug

* eglot.el (eglot-flymake-backend): Only report unreported sometimes.
(eglot--maybe-activate-editing-mode): Start flymake explicitly
when didOpen.
(eglot--textDocument/publishDiagnostics): No need to set
unreported-diagnostics to nil.
(flymake): Require it.
---
 eglot.el | 24 +---
 1 file changed, 13 insertions(+), 11 deletions(-)

diff --git a/eglot.el b/eglot.el
index ccf4b72..3561da2 100644
--- a/eglot.el
+++ b/eglot.el
@@ -32,6 +32,7 @@
 (require 'pcase)
 (require 'compile) ; for some faces
 (require 'warnings)
+(require 'flymake)
 
 (defgroup eglot nil
   "Interaction with Language Server Protocol servers"
@@ -657,12 +658,11 @@ running.  INTERACTIVE is t if called interactively."
   message
into diags
finally
-   (if (null eglot--current-flymake-report-fn)
-   (setq eglot--unreported-diagnostics
- diags)
- (funcall eglot--current-flymake-report-fn
-  diags)
- (setq eglot--unreported-diagnostics nil))
+   (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)
 
@@ -724,7 +724,8 @@ that case, also signal textDocument/didOpen."
 (and proc (eq proc cur)))
 (unless eglot-editing-mode
   (eglot-editing-mode 1))
-(eglot--signalDidOpen)
+(eglot--signalDidOpen)
+(flymake-start)
 
 (add-hook 'find-file-hook 'eglot--maybe-activate-editing-mode)
 
@@ -947,10 +948,11 @@ Records START, END and LENGTH locally."
 (defun eglot-flymake-backend (report-fn  _more)
   "An EGLOT Flymake backend.
 Calls REPORT-FN maybe if server publishes diagnostics in time."
-  ;; Call immediately with anything unreported (this will clear any
-  ;; pending diags)
-  (funcall report-fn eglot--unreported-diagnostics)
-  (setq eglot--unreported-diagnostics nil)
+  ;; Maybe call immediately if anything unreported (this will clear
+  ;; any pending diags)
+  (when eglot--unreported-diagnostics
+(funcall report-fn eglot--unreported-diagnostics)
+(setq eglot--unreported-diagnostics nil))
   ;; Setup so maybe it's called later, too.
   (setq eglot--current-flymake-report-fn report-fn)
   ;; Take this opportunity to signal a didChange that might eventually



[elpa] externals/elpa 3dcbc30 109/139: Add minimal headers, commentary and autoloads

2018-05-14 Thread Jo�o T�vora
branch: externals/elpa
commit 3dcbc30ee2e56e1fdfb8de653de124f096f55f97
Author: João Távora 
Commit: João Távora 

Add minimal headers, commentary and autoloads
---
 eglot.el | 11 +--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/eglot.el b/eglot.el
index 4739cea..eba0e84 100644
--- a/eglot.el
+++ b/eglot.el
@@ -2,8 +2,11 @@
 
 ;; Copyright (C) 2017  João Távora
 
+;; Version: 0.1
 ;; Author: João Távora
-;; Keywords: extensions
+;; Url: https://github.com/joaotavora/eglot
+;; Keywords: convenience, languages
+;; Package-Requires: ((emacs "26.1"))
 
 ;; This program is free software; you can redistribute it and/or modify
 ;; it under the terms of the GNU General Public License as published by
@@ -20,7 +23,8 @@
 
 ;;; Commentary:
 
-;;
+;; M-x eglot in some file under some .git controlled dir should get
+;; you started, but see README.md.
 
 ;;; Code:
 
@@ -285,6 +289,7 @@ Enter program to execute (or :): "
  guessed-command))
  t)))
 
+;;;###autoload
 (defun eglot (managed-major-mode command  interactive)
   "Start a Language Server Protocol server.
 Server is started with COMMAND and manages buffers of
@@ -1465,8 +1470,10 @@ Proceed? "
   (pcase-let ((`(,_id ,what ,done ,_detail) (eglot--spinner proc)))
 (and (equal "Indexing" what) done
 
+;;;###autoload
 (add-hook 'rust-mode-hook 'eglot--setup-rls-idiosyncrasies)
 
+;;;###autoload
 (defun eglot--setup-rls-idiosyncrasies ()
   "RLS needs special treatment..."
   (add-hook 'eglot--ready-predicates 'eglot--rls-probably-ready-for-p t t))



[elpa] externals/eglot c2862f4 063/139: Don't auto-reconnect if last attempt lasted less than 3 seconds

2018-05-14 Thread Jo�o T�vora
branch: externals/eglot
commit c2862f46c8330a0c0feaf871034166ed5d973894
Author: João Távora 
Commit: João Távora 

Don't auto-reconnect if last attempt lasted less than 3 seconds

* eglot.el (eglot--inhibit-auto-reconnect): New var.
(eglot--process-sentinel): Use it.
---
 eglot.el | 16 ++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/eglot.el b/eglot.el
index 8f371d2..df03d04 100644
--- a/eglot.el
+++ b/eglot.el
@@ -329,6 +329,9 @@ INTERACTIVE is t if called interactively."
(with-current-buffer buffer
  (eglot--maybe-activate-editing-mode proc))
 
+(defvar eglot--inhibit-auto-reconnect nil
+  "If non-nil, don't autoreconnect on unexpected quit.")
+
 (defun eglot--process-sentinel (process change)
   "Called with PROCESS undergoes CHANGE."
   (eglot--debug "(sentinel) Process state changed to %s" change)
@@ -355,11 +358,20 @@ INTERACTIVE is t if called interactively."
 (cond ((eglot--moribund process)
(eglot--message "(sentinel) Moribund process exited with status %s"
(process-exit-status process)))
-  (t
+  ((null eglot--inhibit-auto-reconnect)
(eglot--warn
 "(sentinel) Reconnecting after process unexpectedly changed to %s."
 change)
-   (eglot-reconnect process)))
+   (eglot-reconnect process)
+   (setq eglot--inhibit-auto-reconnect
+ (run-with-timer
+  3 nil
+  (lambda ()
+(setq eglot--inhibit-auto-reconnect nil)
+  (t
+   (eglot--warn
+"(sentinel) Not auto-reconnecting, last one didn't last long."
+change)))
 (force-mode-line-update t)
 (delete-process process)))
 



[elpa] externals/elpa 7ec0dcf 029/139: Events buffer uses eglot-mode, source buffers use eglot-editing-mode

2018-05-14 Thread Jo�o T�vora
branch: externals/elpa
commit 7ec0dcfb25e225e4317a7ad97c525beadfbbf0e6
Author: João Távora 
Commit: João Távora 

Events buffer uses eglot-mode, source buffers use eglot-editing-mode

* eglot.el (eglot--special-buffer-process): New var.
(eglot--current-process): Consider eglot--special-buffer-process.
(eglot-events-buffer): Use eglot-mode
(eglot-editing-mode): New minor mode.
(eglot-mode): Turns on eglot-editing-mode maybe.
---
 eglot.el | 35 +++
 1 file changed, 27 insertions(+), 8 deletions(-)

diff --git a/eglot.el b/eglot.el
index 457f316..9742f88 100644
--- a/eglot.el
+++ b/eglot.el
@@ -43,11 +43,15 @@
 
 (defvar eglot--processes-by-project (make-hash-table :test #'equal))
 
+(defvar eglot--special-buffer-process nil
+  "Current buffer's eglot process.")
+
 (defun eglot--current-process ()
   "The current logical EGLOT process."
-  (let ((cur (project-current)))
-(and cur
- (gethash cur eglot--processes-by-project
+  (or eglot--special-buffer-process
+  (let ((cur (project-current)))
+(and cur
+ (gethash cur eglot--processes-by-project)
 
 (defun eglot--current-process-or-lose ()
   (or (eglot--current-process)
@@ -270,8 +274,9 @@ INTERACTIVE is t if called interactively."
(with-current-buffer buffer
  (buffer-disable-undo)
  (read-only-mode t)
- (setf (eglot--events-buffer process)
-   buffer))
+ (setf (eglot--events-buffer process) buffer
+   eglot--special-buffer-process process)
+ (eglot-mode))
buffer
 (when interactive
   (display-buffer buffer))
@@ -610,12 +615,15 @@ running.  INTERACTIVE is t if called interactively."
 
 (defvar eglot-mode-map (make-sparse-keymap))
 
-(define-minor-mode eglot-mode
-  "Minor mode for buffers where EGLOT is possible"
+(defvar eglot-editing-mode-map (make-sparse-keymap))
+
+(define-minor-mode eglot-editing-mode
+  "Minor mode for source buffers where EGLOT helps you edit."
   nil
   nil
   eglot-mode-map
-  (cond (eglot-mode
+  (cond (eglot-editing-mode
+ (eglot-mode 1)
  (add-hook 'after-change-functions 'eglot--after-change nil t)
  (add-hook 'flymake-diagnostic-functions 'eglot-flymake-backend nil t)
  (if (eglot--current-process)
@@ -625,6 +633,17 @@ running.  INTERACTIVE is t if called interactively."
  (remove-hook 'flymake-diagnostic-functions 'eglot-flymake-backend t)
  (remove-hook 'after-change-functions 'eglot--after-change t
 
+(define-minor-mode eglot-mode
+  "Minor mode for all buffers managed by EGLOT in some way."  nil
+  nil eglot-mode-map
+  (cond (eglot-mode
+ (when (and buffer-file-name
+(not eglot-editing-mode))
+   (eglot-editing-mode 1)))
+(t
+ (when eglot-editing-mode
+   (eglot-editing-mode -1)
+
 (defvar eglot-menu)
 
 (easy-menu-define eglot-menu eglot-mode-map "EGLOT"



[elpa] externals/elpa e86f9b4 073/139: New helper eglot--sync-request

2018-05-14 Thread Jo�o T�vora
branch: externals/elpa
commit e86f9b41beab44bfa3ab7c75882baa7eb80be46b
Author: João Távora 
Commit: João Távora 

New helper eglot--sync-request

This should help with xref definitions

* eglot.el (eglot--request): Rework a bit. Continuation is always
cleared on timeout, regardless of user-supplied fn.
(eglot--sync-request): New function.
(eglot--process-receive): watch out for vector results.
---
 eglot.el | 39 +++
 1 file changed, 31 insertions(+), 8 deletions(-)

diff --git a/eglot.el b/eglot.el
index 2afb0e7..34ce0f8 100644
--- a/eglot.el
+++ b/eglot.el
@@ -546,7 +546,10 @@ identifier.  ERROR is non-nil if this is a JSON-RPC error."
(remhash id (eglot--pending-continuations proc))
(if err
(apply (cl-second continuations) err)
- (apply (cl-first continuations) (plist-get message :result
+ (let ((res (plist-get message :result)))
+   (if (listp res)
+   (apply (cl-first continuations) res)
+ (funcall (cl-first continuations) res)
   (id
(eglot--warn "Ooops no continuation for id %s" id)
 
@@ -592,8 +595,7 @@ identifier.  ERROR is non-nil if this is a JSON-RPC error."
   (or timeout-fn
   (lambda ()
 (eglot--warn
- "(request) Tired of waiting for reply to %s" id)
-(remhash id (eglot--pending-continuations process)
+ "(request) Tired of waiting for reply to %s" id
  (error-fn
   (or error-fn
   (cl-function
@@ -618,11 +620,15 @@ identifier.  ERROR is non-nil if this is a JSON-RPC 
error."
  :params params))
 (catch catch-tag
   (let ((timeout-timer
- (run-with-timer 5 nil
- (if async-p
- timeout-fn
-   (lambda ()
- (throw catch-tag (funcall timeout-fn)))
+ (run-with-timer
+  5 nil
+  (if async-p
+  (lambda ()
+(remhash id (eglot--pending-continuations process))
+(funcall timeout-fn))
+(lambda ()
+  (remhash id (eglot--pending-continuations process))
+  (throw catch-tag (funcall timeout-fn)))
 (puthash id
  (list (if async-p
success-fn
@@ -651,6 +657,23 @@ identifier.  ERROR is non-nil if this is a JSON-RPC error."
"(request) Last-change cancelling timer for continuation %s" id)
   (cancel-timer timeout-timer
 
+(defun eglot--sync-request (proc method params)
+  "Like `eglot--request' for PROC, METHOD and PARAMS, but synchronous.
+Meaning only return locally if successful, otherwise exit non-locally."
+  (eglot--request proc method params
+  :success-fn (lambda ( args)
+(if (vectorp (car args))
+(car args)
+  args))
+  :error-fn (cl-function
+ (lambda ( code message )
+   (eglot--error "Oops: %s: %s" code message)))
+  :timeout-fn (lambda ()
+(lambda ()
+  (eglot--error
+   "Tired of waiting for reply to sync 
request")))
+  :async-p nil))
+
 (cl-defun eglot--notify (process method params)
   "Notify PROCESS of something, don't expect a reply.e"
   (eglot--process-send nil



[elpa] externals/elpa a199c8e 070/139: Honour textDocumentSync

2018-05-14 Thread Jo�o T�vora
branch: externals/elpa
commit a199c8ef754434b6210cbd56f7dcef5f04e686c2
Author: João Távora 
Commit: João Távora 

Honour textDocumentSync

* eglot.el (eglot--signal-textDocument/didChange): Honour textDocumentSync
---
 eglot.el | 72 +---
 1 file changed, 37 insertions(+), 35 deletions(-)

diff --git a/eglot.el b/eglot.el
index 5701422..68fe3e2 100644
--- a/eglot.el
+++ b/eglot.el
@@ -251,7 +251,9 @@ SUCCESS-FN with no args if all goes well."
 (eglot--request
  proc
  :initialize
- (eglot--obj :processId  (emacs-pid)
+ (eglot--obj :processId (unless (eq (process-type proc)
+'network)
+  (emacs-pid))
  :rootUri  (eglot--uri
 (expand-file-name (car (project-roots
 (project-current)
@@ -1070,44 +1072,44 @@ Records START, END and PRE-CHANGE-LENGTH locally."
   "Send textDocument/didChange to server."
   (when (and eglot--recent-before-changes
  eglot--recent-after-changes)
-(save-excursion
+(let* ((proc (eglot--current-process-or-lose))
+   (sync-kind (plist-get (eglot--capabilities proc) 
:textDocumentSync)))
   (save-restriction
 (widen)
-(if (/= (length eglot--recent-before-changes)
-(length eglot--recent-after-changes))
-(eglot--notify
- (eglot--current-process-or-lose)
- :textDocument/didChange
- (eglot--obj
-  :textDocument 
(eglot--current-buffer-VersionedTextDocumentIdentifier)
-  :contentChanges
-  (vector
-   (eglot--obj
-:text (buffer-substring-no-properties (point-min) 
(point-max))
-  (let ((combined (cl-mapcar 'append
- eglot--recent-before-changes
- eglot--recent-after-changes)))
-(eglot--notify
- (eglot--current-process-or-lose)
- :textDocument/didChange
- (eglot--obj
-  :textDocument 
(eglot--current-buffer-VersionedTextDocumentIdentifier)
-  :contentChanges
+(unless (or (not sync-kind)
+(eq sync-kind 0))
+  (eglot--notify
+   proc
+   :textDocument/didChange
+   (eglot--obj
+:textDocument
+(eglot--current-buffer-VersionedTextDocumentIdentifier)
+:contentChanges
+(if (or (eq sync-kind 1)
+(/= (length eglot--recent-before-changes)
+(length eglot--recent-after-changes)))
+(vector
+ (eglot--obj
+  :text (buffer-substring-no-properties (point-min) 
(point-max
   (apply
#'vector
-   (mapcar (pcase-lambda (`(,before-start-position
-,before-end-position
-,after-start
-,after-end
-,len))
- (eglot--obj
-  :range
-  (eglot--obj
-   :start before-start-position
-   :end before-end-position)
-  :rangeLength len
-  :text (buffer-substring-no-properties after-start 
after-end)))
-   (reverse combined))
+   (mapcar
+(pcase-lambda (`(,before-start-position
+ ,before-end-position
+ ,after-start
+ ,after-end
+ ,len))
+  (eglot--obj
+   :range
+   (eglot--obj
+:start before-start-position
+:end before-end-position)
+   :rangeLength len
+   :text (buffer-substring-no-properties after-start 
after-end)))
+(reverse
+ (cl-mapcar 'append
+eglot--recent-before-changes
+eglot--recent-after-changes)))
   (setq eglot--recent-before-changes nil
 eglot--recent-after-changes nil))
 



[elpa] externals/elpa be52e1e 037/139: Rework connection restarting again

2018-05-14 Thread Jo�o T�vora
branch: externals/elpa
commit be52e1ee6a39c6f775a308c229c7a75ac28485bd
Author: João Távora 
Commit: João Távora 

Rework connection restarting again

Quitting a process removes it from the project.

* eglot.el (eglot-editing-mode,eglot-mode): Forward declare.
(eglot--project): New process-local var.
(eglot--connect): Takes a project.
(eglot-new-process): Rework.
(eglot--sentinel): Remove proc from eglot--processes-by-project.
---
 eglot.el | 85 ++--
 1 file changed, 51 insertions(+), 34 deletions(-)

diff --git a/eglot.el b/eglot.el
index b9aa94c..12e7fef 100644
--- a/eglot.el
+++ b/eglot.el
@@ -44,6 +44,9 @@
 
 (defvar eglot--processes-by-project (make-hash-table :test #'equal))
 
+(defvar eglot-editing-mode) ; forward decl
+(defvar eglot-mode) ; forward decl
+
 (defvar eglot--special-buffer-process nil
   "Current buffer's eglot process.")
 
@@ -103,6 +106,9 @@ after setting it."
 (eglot--define-process-var eglot--moribund nil
   "Non-nil if process is about to exit")
 
+(eglot--define-process-var eglot--project nil
+  "The project the process belongs to.")
+
 (eglot--define-process-var eglot--spinner `(nil nil t)
   "\"Spinner\" used by some servers.
 A list (ID WHAT DONE-P)." t)
@@ -134,12 +140,13 @@ Returns a process object."
   name)
 proc))
 
-(defun eglot--connect (short-name bootstrap-fn  success-fn)
-  "Make a connection with SHORT-NAME and BOOTSTRAP-FN.
+(defun eglot--connect (project short-name bootstrap-fn  success-fn)
+  "Make a connection with PROJECT, SHORT-NAME and BOOTSTRAP-FN.
 Call SUCCESS-FN with no args if all goes well."
   (let* ((proc (funcall bootstrap-fn short-name))
  (buffer (process-buffer proc)))
-(setf (eglot--bootstrap-fn proc) bootstrap-fn)
+(setf (eglot--bootstrap-fn proc) bootstrap-fn
+  (eglot--project proc) project)
 (with-current-buffer buffer
   (let ((inhibit-read-only t))
 (setf (eglot--short-name proc) short-name)
@@ -164,48 +171,57 @@ INTERACTIVE is t if called interactively."
   (interactive (list (eglot--current-process-or-lose) t))
   (when (process-live-p process)
 (eglot-quit-server process 'sync interactive))
-  (eglot--connect (eglot--short-name process)
-  (eglot--bootstrap-fn process)
-  (lambda ()
-(eglot--message "Reconnected"
+  (eglot--connect
+   (eglot--project process)
+   (eglot--short-name process)
+   (eglot--bootstrap-fn process)
+   (lambda ()
+ (eglot--message "Reconnected"
 
 (defun eglot-new-process ( interactive)
   "Start a new EGLOT process and initialize it.
 INTERACTIVE is t if called interactively."
   (interactive (list t))
   (let ((project (project-current)))
-(unless project (eglot--error "(new-process) Cannot work without a current 
project!"))
+(unless project (eglot--error
+ "(new-process) Cannot work without a current project!"))
 (let ((current-process (eglot--current-process))
   (command (let ((probe (cdr (assoc major-mode eglot-executables
  (unless probe
(eglot--error "Don't know how to start EGLOT for %s 
buffers"
  major-mode))
  probe)))
-  (cond ((and current-process
-  (process-live-p current-process))
- (eglot--message "(new-process) Reconnecting instead")
- (eglot-reconnect current-process interactive))
-(t
- (eglot--connect
-  (file-name-base
-   (directory-file-name
-(car (project-roots (project-current)
-  (lambda (name)
-(eglot-make-local-process
- name
- command))
-  (lambda ()
-(eglot--message "Connected")
-(dolist (buffer (buffer-list))
-  (with-current-buffer buffer
-(if (and buffer-file-name
- (cl-some
-  (lambda (root)
-(string-prefix-p
- (expand-file-name root)
- (expand-file-name buffer-file-name)))
-  (project-roots project)))
-(eglot--signalDidOpen)))
+  (cond
+   ((and current-process
+ (process-live-p current-process))
+(when (and
+   interactive
+   (y-or-n-p "[eglot] Live process found, reconnect instead? "))
+  (eglot-reconnect current-process interactive)))
+   (t
+(eglot--connect
+ project
+ (file-name-base
+  (directory-file-name
+   (car (project-roots (project-current)
+ (lambda (name)

[elpa] externals/eglot b1554fc 055/139: * eglot.el (eglot--process-receive): Skip null method notifs.

2018-05-14 Thread Jo�o T�vora
branch: externals/eglot
commit b1554fc921f8d91870373cf9d3a089afc3f0f63d
Author: João Távora 
Commit: João Távora 

* eglot.el (eglot--process-receive): Skip null method notifs.
---
 eglot.el | 7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/eglot.el b/eglot.el
index ebc07d2..693535a 100644
--- a/eglot.el
+++ b/eglot.el
@@ -477,8 +477,11 @@ identifier.  ERROR is non-nil if this is an error."
   (plist-get message :params)
   (let ((id (plist-get message :id)))
 (if id `(:id ,id)
-   (eglot--warn "No implemetation for notification %s yet"
-method)))
+   ;; pyls keeps on sending nil notifs for each notif we
+   ;; send it, just ignore these.
+   (unless (null method)
+ (eglot--warn "No implemetation for notification %s yet"
+  method
 
 (defvar eglot--expect-carriage-return nil)
 



[elpa] externals/elpa 7d0bf64 062/139: Workaround RLS's regusal to treat nil as empty json object

2018-05-14 Thread Jo�o T�vora
branch: externals/elpa
commit 7d0bf64235fb3a572396a1fb0db8c2f26141f4aa
Author: João Távora 
Commit: João Távora 

Workaround RLS's regusal to treat nil as empty json object

* eglot.el (eglot--connect): Use dummy params.
---
 eglot.el | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/eglot.el b/eglot.el
index 0300ad3..8f371d2 100644
--- a/eglot.el
+++ b/eglot.el
@@ -229,7 +229,7 @@ SUCCESS-FN with no args if all goes well."
 (setf (eglot--capabilities proc) capabilities)
 (setf (eglot--status proc) nil)
 (when success-fn (funcall success-fn proc))
-(eglot--notify proc :initialized nil
+(eglot--notify proc :initialized (eglot--obj :__dummy__ t)
 
 (defvar eglot--command-history nil
   "History of COMMAND arguments to `eglot'.")



[elpa] externals/elpa e8f859e 031/139: Rework commands for connecting and reconnecting

2018-05-14 Thread Jo�o T�vora
branch: externals/elpa
commit e8f859e77e5e6109efdc62ee257b261c54137aca
Author: João Távora 
Commit: João Távora 

Rework commands for connecting and reconnecting

* eglot.el (eglot--current-process-or-lose): Add doc.
(eglot--command): Remove.
(eglot--bootstrap-fn): New process-local variable.
(eglot--connect): Redesign.
(eglot-make-local-process): New function.
(eglot-reconnect): New interactive command.
(eglot-new-process): Redesign.
(eglot--process-sentinel): Add doc.
(eglot--protocol-initialize): Rework.
(eglot--mode-line-format): Use eglot-reconnect.
---
 eglot.el | 139 +--
 1 file changed, 81 insertions(+), 58 deletions(-)

diff --git a/eglot.el b/eglot.el
index fe63a29..c7bb5d4 100644
--- a/eglot.el
+++ b/eglot.el
@@ -54,6 +54,7 @@
  (gethash cur eglot--processes-by-project)
 
 (defun eglot--current-process-or-lose ()
+  "Return the current EGLOT process or error."
   (or (eglot--current-process)
   (eglot--error "No current EGLOT process%s"
 (if (project-current) ""
@@ -109,29 +110,62 @@ A list (ID WHAT DONE-P)." t)
   "Status as declared by the server.
 A list (WHAT SERIOUS-P)." t)
 
-(defun eglot--command ( errorp)
-  (let ((probe (cdr (assoc major-mode eglot-executables
-(unless (or (not errorp)
-probe)
-  (eglot--error "Don't know how to start EGLOT for %s buffers"
-major-mode))
-probe))
+(eglot--define-process-var eglot--bootstrap-fn nil
+  "Function for returning processes/connetions to LSP servers.
+Must be a function of one arg, a name, returning a process
+object.")
 
-(defun eglot--connect (name filter sentinel)
-  "Helper for `eglot-new-process'.
+(defun eglot-make-local-process (name command)
+  "Make a local LSP process from COMMAND.
 NAME is a name to give the inferior process or connection.
-FILTER and SENTINEL are filter and sentinel.
-Should return a list of (PROCESS BUFFER)."
-  (let ((proc (make-process :name name
-:buffer (get-buffer-create
- (format "*%s inferior*" name))
-:command (eglot--command 'error)
-:connection-type 'pipe
-:filter filter
-:sentinel sentinel
-:stderr (get-buffer-create (format "*%s stderr*"
-   name)
-(list proc (process-buffer proc
+Returns a process object."
+  (let* ((readable-name (format "EGLOT server (%s)" name))
+ (proc
+  (make-process
+   :name readable-name
+   :buffer (get-buffer-create
+(format "*%s inferior*" readable-name))
+   :command command
+   :connection-type 'pipe
+   :filter 'eglot--process-filter
+   :sentinel 'eglot--process-sentinel
+   :stderr (get-buffer-create (format "*%s stderr*"
+  name)
+proc))
+
+(defun eglot--connect (short-name bootstrap-fn  success-fn)
+  "Make a connection with SHORT-NAME and BOOTSTRAP-FN.
+Call SUCCESS-FN with no args if all goes well."
+  (let* ((proc (funcall bootstrap-fn short-name))
+ (buffer (process-buffer proc)))
+(setf (eglot--bootstrap-fn proc) bootstrap-fn)
+(with-current-buffer buffer
+  (let ((inhibit-read-only t))
+(setf (eglot--short-name proc) short-name)
+(puthash (project-current) proc eglot--processes-by-project)
+(erase-buffer)
+(read-only-mode t)
+(with-current-buffer (eglot-events-buffer proc)
+  (let ((inhibit-read-only t))
+(insert
+ (format "\n---\n"
+(eglot--protocol-initialize
+ proc
+ (cl-function
+  (lambda ( capabilities)
+(setf (eglot--capabilities proc) capabilities)
+(setf (eglot--status proc) nil)
+(when success-fn (funcall success-fn)
+
+(defun eglot-reconnect (process  interactive)
+  "Reconnect to PROCESS.
+INTERACTIVE is t if called interactively."
+  (interactive (list (eglot--current-process-or-lose) t))
+  (eglot-quit-server process 'sync interactive)
+  (eglot--connect (eglot--short-name process)
+  (eglot--bootstrap-fn process)
+  (lambda ()
+(eglot--message "Reconnected"
 
 (defun eglot-new-process ( interactive)
   "Start a new EGLOT process and initialize it.
@@ -140,32 +174,28 @@ INTERACTIVE is t if called interactively."
   (let ((project (project-current)))
 (unless project (eglot--error "(new-process) Cannot work without a current 
project!"))
 (let ((current-process (eglot--current-process)))
-  (when (and current-process
-

[elpa] externals/elpa 458bc69 110/139: More correctly setup rust-mode-related autoloads

2018-05-14 Thread Jo�o T�vora
branch: externals/elpa
commit 458bc6989e33ab0b95b6f1c8d2aa90e0a06c468d
Author: João Távora 
Commit: João Távora 

More correctly setup rust-mode-related autoloads

By autoloading the add-hook form and the eglot--setup-rls-idiosyncrasies
definition, a user can start rust-mode without loading eglot.el along
with it.

* eglot.el (rust-mode-hook)
(eglot--setup-rls-idiosyncrasies): Wrap in autoloaded progn.
---
 eglot.el | 11 +--
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/eglot.el b/eglot.el
index eba0e84..fbddf16 100644
--- a/eglot.el
+++ b/eglot.el
@@ -1471,12 +1471,11 @@ Proceed? "
 (and (equal "Indexing" what) done
 
 ;;;###autoload
-(add-hook 'rust-mode-hook 'eglot--setup-rls-idiosyncrasies)
-
-;;;###autoload
-(defun eglot--setup-rls-idiosyncrasies ()
-  "RLS needs special treatment..."
-  (add-hook 'eglot--ready-predicates 'eglot--rls-probably-ready-for-p t t))
+(progn
+  (add-hook 'rust-mode-hook 'eglot--setup-rls-idiosyncrasies)
+  (defun eglot--setup-rls-idiosyncrasies ()
+"Prepare `eglot' to deal with RLS's special treatment."
+(add-hook 'eglot--ready-predicates 'eglot--rls-probably-ready-for-p t t)))
 
 (cl-defun eglot--server-window/progress
 (process  id done title message )



[elpa] externals/elpa 3a6c637 099/139: Support textDocument/rename

2018-05-14 Thread Jo�o T�vora
branch: externals/elpa
commit 3a6c63723370e71b992d21019fbf863d569d024a
Author: João Távora 
Commit: João Távora 

Support textDocument/rename

* README.md: Mention rename support.

* eglot.el (eglot--uri-to-path): Handle uri hidden in keywords.
(eglot--apply-text-edits): New helper.
(eglot-rename): New interactive command.
(eglot--client-capabilities): Add rename capability.
---
 README.md |  2 +-
 eglot.el  | 58 ++
 2 files changed, 59 insertions(+), 1 deletion(-)

diff --git a/README.md b/README.md
index 5838bc5..a8d1c8b 100644
--- a/README.md
+++ b/README.md
@@ -39,7 +39,7 @@ server. To skip the guess and always be prompted use `C-u M-x 
eglot`.
 - [ ] textDocument/executeCommand
 - [ ] textDocument/format
 - [x] textDocument/hover
-- [ ] textDocument/rename
+- [x] textDocument/rename
 - [x] textDocument/references
 - [ ] textDocument/signatureHelp
 - [x] workspace/symbol
diff --git a/eglot.el b/eglot.el
index c5c99f2..9ba87ef 100644
--- a/eglot.el
+++ b/eglot.el
@@ -199,6 +199,7 @@ CONTACT is as `eglot--contact'.  Returns a process object."
   :definition `(:dynamicRegistration :json-false)
   :documentSymbol `(:dynamicRegistration :json-false)
   :documentHighlight  `(:dynamicRegistration :json-false)
+  :rename `(:dynamicRegistration :json-false)
   :publishDiagnostics `(:relatedInformation :json-false))
:experimental (eglot--obj)))
 
@@ -729,6 +730,7 @@ Meaning only return locally if successful, otherwise exit 
non-locally."
 
 (defun eglot--uri-to-path (uri)
   "Convert URI to a file path."
+  (when (keywordp uri) (setq uri (substring (symbol-name uri) 1)))
   (url-filename (url-generic-parse-url (url-unhex-string uri
 
 (defconst eglot--kind-names
@@ -1368,6 +1370,62 @@ DUMMY is ignored"
  entries))
 (funcall oldfun)))
 
+(defun eglot--apply-text-edits (uri edits proc  version)
+  "Apply the EDITS for buffer of URI and return it."
+  (let* ((path (eglot--uri-to-path uri))
+ (buffer (and path
+  (find-file-noselect path
+(unless buffer
+  (eglot--error "Can't find `%s' to perform server edits"))
+(with-current-buffer buffer
+  (unless (eq proc (eglot--current-process))
+(eglot--error "Buffer `%s' for `%s' isn't managed by %s"
+  (current-buffer) uri proc))
+  (unless (or (not version)
+  (equal version eglot--versioned-identifier))
+(eglot--error "Edits on `%s' require version %d, you have %d"
+  uri version eglot--versioned-identifier))
+  (eglot--mapply
+   (eglot--lambda ( range newText)
+ (save-restriction
+   (widen)
+   (save-excursion
+ (let ((start (eglot--lsp-position-to-point (plist-get range 
:start
+   (goto-char start)
+   (delete-region start
+  (eglot--lsp-position-to-point (plist-get range 
:end)))
+   (insert newText)
+   edits)
+  (eglot--message "%s: %s edits" (current-buffer) (length edits)))
+buffer))
+
+(defun eglot-rename (newname)
+  "Rename the current symbol to NEWNAME."
+  (interactive
+   (list
+(read-from-minibuffer (format "Rename `%s' to: " (symbol-at-point)
+  (unless (eglot--server-capable :renameProvider)
+(eglot--error "Server can't rename!"))
+  (let* ((proc (eglot--current-process-or-lose))
+ (workspace-edit
+  (eglot--sync-request proc
+   :textDocument/rename
+   (append
+
(eglot--current-buffer-TextDocumentPositionParams)
+(eglot--obj :newName newname
+ performed)
+(cl-destructuring-bind ( changes documentChanges)
+workspace-edit
+  (cl-loop for change on documentChanges
+   do (push
+   (cl-destructuring-bind ( textDocument edits) change
+ (cl-destructuring-bind ( uri version) textDocument
+   (eglot--apply-text-edits uri edits proc version)))
+   performed))
+  (cl-loop for (uri edits) on changes by #'cddr
+   do (push (eglot--apply-text-edits uri edits proc)
+performed)
+
 
 ;;; Dynamic registration
 ;;;



[elpa] externals/elpa fdb4de1 039/139: Simplify flymake integration

2018-05-14 Thread Jo�o T�vora
branch: externals/elpa
commit fdb4de165885d4ff777a40dcaca289452545db8d
Author: João Távora 
Commit: João Távora 

Simplify flymake integration

And get rid of the ridiculous environment thingy

* eglot.el (eglot--process-sentinel): Continuations are triplets.
(eglot--environment-vars, eglot--environment): Remove.
(eglot--process-receive): Simplify.
(eglot--unreported-diagnostics): New variable.
(eglot--textDocument/publishDiagnostics): Simplify.
(eglot-flymake-backend): Report unreported diagnostics.
---
 eglot.el | 58 +++---
 1 file changed, 23 insertions(+), 35 deletions(-)

diff --git a/eglot.el b/eglot.el
index 8584440..8bb0729 100644
--- a/eglot.el
+++ b/eglot.el
@@ -229,8 +229,8 @@ INTERACTIVE is t if called interactively."
   (when (not (process-live-p process))
 ;; Remember to cancel all timers
 ;;
-(maphash (lambda (id quad)
-   (cl-destructuring-bind (_success _error timeout _env) quad
+(maphash (lambda (id triplet)
+   (cl-destructuring-bind (_success _error timeout) triplet
  (eglot--message
   "(sentinel) Cancelling timer for continuation %s" id)
  (cancel-timer timeout)))
@@ -349,13 +349,6 @@ identifier.  ERROR is non-nil if this is an error."
   (setq msg (propertize msg 'face 'error)))
 (insert msg)
 
-(defvar eglot--environment-vars
-  '(eglot--current-flymake-report-fn)
-  "A list of variables with saved values on every request.")
-
-(defvar eglot--environment nil
-  "Dynamically bound alist of symbol and values.")
-
 (defun eglot--process-receive (proc message)
   "Process MESSAGE from PROC."
   (let* ((response-id (plist-get message :id))
@@ -388,13 +381,9 @@ identifier.  ERROR is non-nil if this is an error."
   (t
(let* ((method (plist-get message :method))
   (handler-sym (intern (concat "eglot--"
-   method)))
-  (eglot--environment (cl-fourth continuations)))
+   method
  (if (functionp handler-sym)
- (cl-progv
- (mapcar #'car eglot--environment)
- (mapcar #'cdr eglot--environment)
-   (apply handler-sym proc (plist-get message :params)))
+ (apply handler-sym proc (plist-get message :params))
(eglot--debug "No implemetation for notification %s yet"
  method)))
 
@@ -476,9 +465,7 @@ identifier.  ERROR is non-nil if this is an error."
error-fn
  (lambda ( args)
(throw catch-tag (apply error-fn args
-   timeout-timer
-   (cl-loop for var in eglot--environment-vars
-collect (cons var (symbol-value var
+   timeout-timer)
  (eglot--pending-continuations process))
 (unless async-p
   (unwind-protect
@@ -563,23 +550,18 @@ running.  INTERACTIVE is t if called interactively."
 
 ;;; Notifications
 ;;;
-(defvar eglot--current-flymake-report-fn nil)
+(defvar-local eglot--current-flymake-report-fn nil
+  "Current flymake report function for this buffer")
+(defvar-local eglot--unreported-diagnostics nil
+  "Unreported diagnostics for this buffer.")
 
 (cl-defun eglot--textDocument/publishDiagnostics
 (_process  uri diagnostics)
   "Handle notification publishDiagnostics"
   (let* ((obj (url-generic-parse-url uri))
 (filename (car (url-path-and-query obj)))
- (buffer (find-buffer-visiting filename))
- (report-fn (cdr (assoc 'eglot--current-flymake-report-fn
-eglot--environment
+ (buffer (find-buffer-visiting filename)))
 (cond
- ((not eglot--current-flymake-report-fn)
-  (eglot--warn "publishDiagnostics called but no report-fn"))
- ((and report-fn
-   (not (eq report-fn
-eglot--current-flymake-report-fn)))
-  (eglot--warn "outdated publishDiagnostics report from server"))
  (buffer
   (with-current-buffer buffer
 (cl-flet ((pos-at
@@ -607,9 +589,12 @@ running.  INTERACTIVE is t if called interactively."
  :note))
   message
into diags
-   finally (funcall
-eglot--current-flymake-report-fn
-diags)
+   finally
+   (if eglot--current-flymake-report-fn
+   (funcall eglot--current-flymake-report-fn
+diags)
+ (setq eglot--unreported-diagnostics
+  

[elpa] externals/eglot 9d404c9 054/139: Update README.md

2018-05-14 Thread Jo�o T�vora
branch: externals/eglot
commit 9d404c98d7de60f02278cfd1ef84416792690169
Author: João Távora 
Commit: João Távora 

Update README.md
---
 README.md | 40 ++--
 1 file changed, 38 insertions(+), 2 deletions(-)

diff --git a/README.md b/README.md
index 7a747fd..8809421 100644
--- a/README.md
+++ b/README.md
@@ -3,11 +3,47 @@ Eglot
 
 *E*macs Poly*glot*. An Emacs client to Language Server Protocol servers.
 
-Coming soon.
-
 ```
 (add-to-list 'load-path "/path/to/eglot")
 (require 'eglot)
 
 M-x eglot
 ```
+
+*That's it*. Either this guesses the local LSP program to start for
+the language of your choice or it prompts you for such a thing. You
+can also enter a `server:port` pattern to connect to an LSP server. To
+skip the guess and always be prompted use `C-u M-x eglot`.
+
+## Differences to lsp-mode.el
+
+This is really beta and currently does less than
+[lsp-mode.el](https://github.com/emacs-lsp/lsp-mode) which is more
+mature. Though I think `eglot.el` will eventually beat it, you could
+be better served with `lsp-mode.el` for now.
+
+User-visible differences:
+
+- Single entry point, `M-x eglot` to enable LSP in a project.
+  Automatically detects current and future opened files under that
+  project and syncs with server.
+- Easy way to restart a server
+- Pretty interactive mode-line section for live tracking of server
+  communication.
+   
+Differences under the hood:
+
+- Message parser is much much simpler
+- Easier to read and maintain elisp. Yeah I know, subjective... But
+  judge for yourself.
+- No external dependencies apart from Emacs (no `flycheck.el`, no
+  `projectile.el`, no Cask, etc).
+- Uses project.el, flymake.el
+- Requires the upcoming emacs 26
+- Contained in one file
+- send `textDocument/didChange` for groups of edits, not one per each
+  tiny change. 
+- Its missing tests! This is *not good*
+
+
+   



[elpa] externals/elpa 6689a15 026/139: Add eglot-clear-status interactive command

2018-05-14 Thread Jo�o T�vora
branch: externals/elpa
commit 6689a1588366a5d461207b11130b167e14a1dcf4
Author: João Távora 
Commit: João Távora 

Add eglot-clear-status interactive command

* eglot.el (eglot-clear-status): New
(eglot-forget-pending-continuations): Fix bug.
(eglot--mode-line-format): Add link to eglot-clear-status.
---
 eglot.el | 12 ++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/eglot.el b/eglot.el
index 1a82cc5..db594f4 100644
--- a/eglot.el
+++ b/eglot.el
@@ -361,9 +361,14 @@ identifier.  ERROR is non-nil if this is an error."
 
 (defun eglot-forget-pending-continuations (process)
   "Stop waiting for responses from the current LSP PROCESS."
-  (interactive (eglot--current-process-or-lose))
+  (interactive (list (eglot--current-process-or-lose)))
   (clrhash (eglot--pending-continuations process)))
 
+(defun eglot-clear-status (process)
+  "Clear most recent error message from PROCESS."
+  (interactive (list (eglot--current-process-or-lose)))
+  (setf (eglot--status process) nil))
+
 (cl-defun eglot--request (process
   method
   params
@@ -668,12 +673,15 @@ running.  INTERACTIVE is t if called interactively."
  `("/"
(:propertize
 ,status
-help-echo ,(concat "mouse-1: go to events buffer")
+help-echo ,(concat "mouse-1: go to events buffer\n"
+   "mouse-3: clear this status")
 mouse-face mode-line-highlight
 face compilation-mode-line-fail
 keymap ,(let ((map (make-sparse-keymap)))
   (define-key map [mode-line mouse-1]
 'eglot-events-buffer)
+  (define-key map [mode-line mouse-3]
+'eglot-clear-status)
   map
  ,@(when (and doing (not done-p))
  `("/"



[elpa] externals/elpa df5d76d 065/139: Reply to client/registerCapability (don't handle it yet)

2018-05-14 Thread Jo�o T�vora
branch: externals/elpa
commit df5d76d6a0f3b0f72a1cf11b73c349aa5d990f5a
Author: João Távora 
Commit: João Távora 

Reply to client/registerCapability (don't handle it yet)

* eglot.el (eglot--server-client/registerCapability): New
function.
---
 eglot.el | 13 +
 1 file changed, 13 insertions(+)

diff --git a/eglot.el b/eglot.el
index 332f1fe..d073be2 100644
--- a/eglot.el
+++ b/eglot.el
@@ -962,6 +962,19 @@ running.  INTERACTIVE is t if called interactively."
  (t
   (eglot--message "OK so %s isn't visited" filename)
 
+(cl-defun eglot--server-client/registerCapability
+(proc  id registrations)
+  "Handle notification client/registerCapability"
+  (mapc (lambda (reg)
+  (apply (cl-function
+  (lambda ( _id _method _registerOptions)
+;;; TODO: handle this
+))
+ reg))
+registrations)
+  (eglot--reply proc id :error (eglot--obj :code -32601
+   :message "sorry :-(")))
+
 (defvar eglot--recent-before-changes nil
   "List of recent changes as collected by `eglot--before-change'.")
 (defvar eglot--recent-after-changes nil



[elpa] externals/elpa 23b79e0 111/139: Shorten summary line to appease package-lint.el

2018-05-14 Thread Jo�o T�vora
branch: externals/elpa
commit 23b79e07da6c62e7f056c6cc5b6b676e43b8017c
Author: João Távora 
Commit: João Távora 

Shorten summary line to appease package-lint.el
---
 eglot.el | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/eglot.el b/eglot.el
index fbddf16..21ec247 100644
--- a/eglot.el
+++ b/eglot.el
@@ -1,4 +1,4 @@
-;;; eglot.el --- A client for Language Server Protocol (LSP) servers  -*- 
lexical-binding: t; -*-
+;;; eglot.el --- Client for Language Server Protocol (LSP) servers  -*- 
lexical-binding: t; -*-
 
 ;; Copyright (C) 2017  João Távora
 



[elpa] externals/eglot c95a0a4 041/139: Multiple servers per project are possible

2018-05-14 Thread Jo�o T�vora
branch: externals/eglot
commit c95a0a40d75a7446f093cc8e9a70702e26a16ea3
Author: João Távora 
Commit: João Távora 

Multiple servers per project are possible

A server manages a specific major-mode within a project.

* eglot.el (eglot--processes-by-project): Add docstring.
(eglot--current-process): Search new eglot--processes-by-project
format.
(eglot--major-mode): New variable.
(eglot--moribund, eglot--project): Update docstring.
(eglot--project-short-name, eglot--all-major-modes): New helpers.
(eglot--connect): Rework.
(eglot-new-process): Rework severely.
(eglot--command-history): New variable.
(eglot--process-sentinel): Use new
eglot--processes-by-project. Update mode line.
(eglot-editing-mode): Don't start processes, just suggest it.
---
 eglot.el | 123 ---
 1 file changed, 95 insertions(+), 28 deletions(-)

diff --git a/eglot.el b/eglot.el
index cd546a3..10af6c5 100644
--- a/eglot.el
+++ b/eglot.el
@@ -42,7 +42,8 @@
 (python-mode . ("pyls")))
   "Alist mapping major modes to server executables.")
 
-(defvar eglot--processes-by-project (make-hash-table :test #'equal))
+(defvar eglot--processes-by-project (make-hash-table :test #'equal)
+  "Keys are projects.  Values are lists of processes.")
 
 (defvar eglot-editing-mode) ; forward decl
 (defvar eglot-mode) ; forward decl
@@ -53,9 +54,13 @@
 (defun eglot--current-process ()
   "The current logical EGLOT process."
   (or eglot--special-buffer-process
-  (let ((cur (project-current)))
-(and cur
- (gethash cur eglot--processes-by-project)
+  (let* ((cur (project-current))
+ (processes
+  (and cur
+   (gethash cur eglot--processes-by-project
+(cl-find major-mode
+ processes
+ :key #'eglot--major-mode
 
 (defun eglot--current-process-or-lose ()
   "Return the current EGLOT process or error."
@@ -91,6 +96,9 @@ after setting it."
 (eglot--define-process-var eglot--short-name nil
   "A short name for the process" t)
 
+(eglot--define-process-var eglot--major-mode nil
+  "The major-mode this server is managing.")
+
 (eglot--define-process-var eglot--expected-bytes nil
   "How many bytes declared by server")
 
@@ -104,10 +112,10 @@ after setting it."
   "Holds list of capabilities that server reported")
 
 (eglot--define-process-var eglot--moribund nil
-  "Non-nil if process is about to exit")
+  "Non-nil if server is about to exit")
 
 (eglot--define-process-var eglot--project nil
-  "The project the process belongs to.")
+  "The project the server belongs to.")
 
 (eglot--define-process-var eglot--spinner `(nil nil t)
   "\"Spinner\" used by some servers.
@@ -122,6 +130,20 @@ A list (WHAT SERIOUS-P)." t)
 Must be a function of one arg, a name, returning a process
 object.")
 
+(defun eglot--project-short-name (project)
+  "Give PROJECT a short name."
+  (file-name-base
+   (directory-file-name
+(car (project-roots project)
+
+(defun eglot--all-major-modes ()
+  "Return all know major modes."
+  (let ((retval))
+(mapatoms (lambda (sym)
+(when (plist-member (symbol-plist sym) 'derived-mode-parent)
+  (push sym retval
+retval))
+
 (defun eglot-make-local-process (name command)
   "Make a local LSP process from COMMAND.
 NAME is a name to give the inferior process or connection.
@@ -140,17 +162,22 @@ Returns a process object."
   name)
 proc))
 
-(defun eglot--connect (project short-name bootstrap-fn  success-fn)
-  "Make a connection with PROJECT, SHORT-NAME and BOOTSTRAP-FN.
-Call SUCCESS-FN with no args if all goes well."
+(defun eglot--connect (project managed-major-mode
+   short-name bootstrap-fn  success-fn)
+  "Make a connection for PROJECT, SHORT-NAME and MANAGED-MAJOR-MODE.
+Use BOOTSTRAP-FN to make the actual process object.  Call
+SUCCESS-FN with no args if all goes well."
   (let* ((proc (funcall bootstrap-fn short-name))
  (buffer (process-buffer proc)))
 (setf (eglot--bootstrap-fn proc) bootstrap-fn
-  (eglot--project proc) project)
+  (eglot--project proc) project
+  (eglot--major-mode proc) managed-major-mode)
 (with-current-buffer buffer
   (let ((inhibit-read-only t))
 (setf (eglot--short-name proc) short-name)
-(puthash (project-current) proc eglot--processes-by-project)
+(push proc
+  (gethash (project-current)
+   eglot--processes-by-project))
 (erase-buffer)
 (read-only-mode t)
 (with-current-buffer (eglot-events-buffer proc)
@@ -173,24 +200,63 @@ INTERACTIVE is t if called interactively."
 (eglot-quit-server process 'sync interactive))
   (eglot--connect
(eglot--project 

[elpa] externals/eglot a3545fb 050/139: Rename RPC methods for clarity

2018-05-14 Thread Jo�o T�vora
branch: externals/eglot
commit a3545fbf2a0e896b7129a49d3eafe1f4c0dee98b
Author: João Távora 
Commit: João Távora 

Rename RPC methods for clarity

* eglot.el (eglot--process-receive): Search for RPC server methods
under `eglot--server-'
(eglot-editing-mode, eglot--maybe-activate-editing-mode): Use new
signal names.
(eglot--server-window/showMessage): Rename from
eglot--window/showMessage.
(eglot--server-textDocument/publishDiagnostics): Renamed from
eglot--textDocument/publishDiagnostics.
(eglot--current-buffer-versioned-identifier): Remove.
(eglot--current-buffer-VersionedTextDocumentIdentifier): Use
eglot--versioned-identifier.
(eglot--signal-textDocument/didChange): Renamed from
eglot--maybe-signal-didChange.
(eglot--signal-textDocument/didOpen): Renamed from
eglot--signalDidOpen.
(eglot--signal-textDocument/didClose): Rename from
eglot--signalDidClose.
(eglot-flymake-backend): Call eglot--signal-textDocument/didChange.
(eglot--server-window/progress): Rename from
eglot--window/progress.
---
 eglot.el | 36 
 1 file changed, 16 insertions(+), 20 deletions(-)

diff --git a/eglot.el b/eglot.el
index 7d44e6d..469d3f7 100644
--- a/eglot.el
+++ b/eglot.el
@@ -455,12 +455,12 @@ identifier.  ERROR is non-nil if this is an error."
   (apply (cl-first continuations) (plist-get message 
:result)
   (t
(let* ((method (plist-get message :method))
-  (handler-sym (intern (concat "eglot--"
+  (handler-sym (intern (concat "eglot--server-"
method
  (if (functionp handler-sym)
  (apply handler-sym proc (plist-get message :params))
-   (eglot--debug "No implemetation for notification %s yet"
- method)))
+   (eglot--warn "No implemetation for notification %s yet"
+method)))
 
 (defvar eglot--expect-carriage-return nil)
 
@@ -612,15 +612,15 @@ identifier.  ERROR is non-nil if this is an error."
 (eglot-mode 1)
 (add-hook 'after-change-functions 'eglot--after-change nil t)
 (add-hook 'flymake-diagnostic-functions 'eglot-flymake-backend nil t)
-(add-hook 'kill-buffer-hook 'eglot--signalDidClose nil t)
+(add-hook 'kill-buffer-hook 'eglot--signal-textDocument/didClose nil t)
 (flymake-mode 1)
 (if (eglot--current-process)
-(eglot--signalDidOpen)
+(eglot--signal-textDocument/didOpen)
   (eglot--warn "No process, start one with `M-x eglot'")))
(t
 (remove-hook 'flymake-diagnostic-functions 'eglot-flymake-backend t)
 (remove-hook 'after-change-functions 'eglot--after-change t)
-(remove-hook 'kill-buffer-hook 'eglot--signalDidClose t
+(remove-hook 'kill-buffer-hook 'eglot--signal-textDocument/didClose t
 
 (define-minor-mode eglot-mode
   "Minor mode for all buffers managed by EGLOT in some way."  nil
@@ -643,7 +643,7 @@ that case, also signal textDocument/didOpen."
 (and proc (eq proc cur)))
 (unless eglot-editing-mode
   (eglot-editing-mode 1))
-(eglot--signalDidOpen)
+(eglot--signal-textDocument/didOpen)
 (flymake-start)
 
 (add-hook 'find-file-hook 'eglot--maybe-activate-editing-mode)
@@ -805,7 +805,7 @@ running.  INTERACTIVE is t if called interactively."
  :async-p (not sync)
  :timeout-fn brutal)))
 
-(cl-defun eglot--window/showMessage
+(cl-defun eglot--server-window/showMessage
 (process  type message)
   "Handle notification window/showMessage"
   (when (<= 1 type)
@@ -821,7 +821,7 @@ running.  INTERACTIVE is t if called interactively."
 (defvar-local eglot--unreported-diagnostics nil
   "Unreported diagnostics for this buffer.")
 
-(cl-defun eglot--textDocument/publishDiagnostics
+(cl-defun eglot--server-textDocument/publishDiagnostics
 (_process  uri diagnostics)
   "Handle notification publishDiagnostics"
   (let* ((obj (url-generic-parse-url uri))
@@ -873,11 +873,6 @@ running.  INTERACTIVE is t if called interactively."
 
 (defvar-local eglot--versioned-identifier 0)
 
-(defun eglot--current-buffer-versioned-identifier ()
-  "Return a VersionedTextDocumentIdentifier."
-  ;; FIXME: later deal with workspaces
-  eglot--versioned-identifier)
-
 (defun eglot--current-buffer-VersionedTextDocumentIdentifier ()
   "Compute VersionedTextDocumentIdentifier object for current buffer."
   (eglot--obj :uri
@@ -885,7 +880,8 @@ running.  INTERACTIVE is t if called interactively."
   (url-hexify-string
(file-truename buffer-file-name)
url-path-allowed-chars))
-  :version (eglot--current-buffer-versioned-identifier)))
+  ;; FIXME: later deal with workspaces
+  :version 

[elpa] externals/elpa 8bd634c 016/139: Start working on this again

2018-05-14 Thread Jo�o T�vora
branch: externals/elpa
commit 8bd634ce9d5058e2db36dcf250bb909cc96eeaeb
Author: João Távora 
Commit: João Távora 

Start working on this again

* eglot.el (url-util): Require it.
(eglot--process-sentinel): pending continuations now are quads (added env).
(eglot--process-filter): Unwind message markers correctly if handling fails.
(eglot--obj): Simple macro.
(eglot--log-event): Add some info to logged event.
(eglot--environment-vars, eglot--environment): Helper vars.
(eglot--process-receive): Improve.
(eglot--process-send): Niver log.
(eglot--request): Use eglot--obj. Add environment.
(eglot--notify): New helper.
(eglot--protocol-initialize): RLS must like file://
(eglot--current-flymake-report-fn): New var.
(eglot--textDocument/publishDiagnostics): Use flymake from Emacs 26.
(eglot-mode): Proper minor mode.
(eglot--recent-changes, eglot--versioned-identifier): New stuff.
(eglot--current-buffer-versioned-identifier)
(eglot--current-buffer-VersionedTextDocumentIdentifier)
(eglot--current-buffer-TextDocumentItem, eglot--after-change)
(eglot--signalDidOpen, eglot--maybe-signal-didChange): New stuff.
(eglot-flymake-backend): More or less a flymake backend function.
---
 eglot.el | 267 ---
 1 file changed, 204 insertions(+), 63 deletions(-)

diff --git a/eglot.el b/eglot.el
index 8946692..8da6267 100644
--- a/eglot.el
+++ b/eglot.el
@@ -28,6 +28,7 @@
 (require 'cl-lib)
 (require 'project)
 (require 'url-parse)
+(require 'url-util)
 
 (defgroup eglot nil
   "Interaction with Language Server Protocol servers"
@@ -143,8 +144,8 @@
 (when (not (process-live-p process))
   ;; Remember to cancel all timers
   ;;
-  (maphash (lambda (id triplet)
- (cl-destructuring-bind (_success _error timeout) triplet
+  (maphash (lambda (id quad)
+ (cl-destructuring-bind (_success _error timeout _env) quad
(eglot--message
 "(sentinel) Cancelling timer for continuation %s" id)
(cancel-timer timeout)))
@@ -185,7 +186,7 @@
 (when new-expected-bytes
   (when expected-bytes
 (eglot--warn
- (concat "Unexpectedly starting new message but %s bytes"
+ (concat "Unexpectedly starting new message but %s bytes "
  "reportedly remaining from previous one")
  expected-bytes))
   (set-marker message-mark (point))
@@ -207,22 +208,29 @@
  (let* ((message-end (byte-to-position
   (+ (position-bytes message-mark)
  expected-bytes
-   (save-excursion
- (save-restriction
-   (goto-char message-mark)
-   (narrow-to-region message-mark
- message-end)
-   (eglot--process-receive
-proc
-(let ((json-object-type 'plist))
-  (json-read)
-   (set-marker message-mark message-end)
-   (setf (eglot--expected-bytes proc) nil)))
+   (unwind-protect
+   (save-excursion
+ (save-restriction
+   (goto-char message-mark)
+   (narrow-to-region message-mark
+ message-end)
+   (eglot--process-receive
+proc
+(let ((json-object-type 'plist))
+  (json-read)
+ (set-marker message-mark message-end)
+ (setf (eglot--expected-bytes proc) nil
 (t
  ;; just adding some stuff to the end that doesn't yet
  ;; complete the message
  )))
 
+(defmacro eglot--obj ( what)
+  "Make an object suitable for `json-encode'"
+  ;; FIXME: maybe later actually do something, for now this just fixes
+  ;; the indenting of literal plists.
+  `(list ,@what))
+
 (defun eglot-events-buffer (process  interactive)
   (interactive (list (eglot--current-process-or-lose) t))
   (let* ((probe (eglot--events-buffer process))
@@ -241,22 +249,39 @@
   (display-buffer buffer))
 buffer))
 
-(defun eglot--log-event (proc type message)
+(defun eglot--log-event (proc type message id error)
   (with-current-buffer (eglot-events-buffer proc)
 (let ((inhibit-read-only t))
   (goto-char (point-max))
-  (insert (format "%s: \n%s\n" type (pp-to-string message))
+  (insert (format "%s%s%s:\n%s\n"
+  type
+  (if id (format " (id:%s)" id) 

[elpa] externals/elpa 51ff863 046/139: Must re-announce didOpen after reconnect

2018-05-14 Thread Jo�o T�vora
branch: externals/elpa
commit 51ff863284138721d4c66ae2232df0696d097f44
Author: João Távora 
Commit: João Távora 

Must re-announce didOpen after reconnect

* eglot.el (eglot-reconnect): Also call
eglot--maybe-activate-editing-mode for all buffers.
---
 eglot.el | 7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/eglot.el b/eglot.el
index 3561da2..86c0a4c 100644
--- a/eglot.el
+++ b/eglot.el
@@ -205,8 +205,11 @@ INTERACTIVE is t if called interactively."
(eglot--major-mode process)
(eglot--short-name process)
(eglot--bootstrap-fn process)
-   (lambda (_proc)
- (eglot--message "Reconnected!"
+   (lambda (proc)
+ (eglot--message "Reconnected!")
+ (dolist (buffer (buffer-list))
+   (with-current-buffer buffer
+ (eglot--maybe-activate-editing-mode proc))
 
 (defvar eglot--command-history nil
   "History of COMMAND arguments to `eglot'.")



[elpa] externals/elpa e1d36d2 014/139: Fix some byte-compilation warnings

2018-05-14 Thread Jo�o T�vora
branch: externals/elpa
commit e1d36d27a2b6566fdd8cf16d0fcd2a9ec033a65d
Author: João Távora 
Commit: João Távora 

Fix some byte-compilation warnings
---
 eglot.el | 82 
 1 file changed, 46 insertions(+), 36 deletions(-)

diff --git a/eglot.el b/eglot.el
index af9904a..0a52da7 100644
--- a/eglot.el
+++ b/eglot.el
@@ -27,6 +27,7 @@
 (require 'json)
 (require 'cl-lib)
 (require 'project)
+(require 'url-parse)
 
 (defgroup eglot nil
   "Interaction with Language Server Protocol servers"
@@ -211,8 +212,10 @@
(goto-char message-mark)
(narrow-to-region message-mark
  message-end)
-  (eglot--process-receive proc 
(let ((json-object-type 'plist))
-   (json-read)
+   (eglot--process-receive
+proc
+(let ((json-object-type 'plist))
+  (json-read)
(set-marker message-mark message-end)
(setf (eglot--expected-bytes proc) nil)))
 (t
@@ -258,21 +261,21 @@
 (not continuations))
(eglot--warn "Ooops no continuation for id %s" response-id))
   (continuations
-   (cancel-timer (third continuations))
+   (cancel-timer (cl-third continuations))
(remhash response-id
 (eglot--pending-continuations))
(cond (err
-  (apply (second continuations) err))
+  (apply (cl-second continuations) err))
  (t
-  (apply (first continuations) (plist-get message :result)
+  (apply (cl-first continuations) (plist-get message 
:result)
   (t
(let* ((method (plist-get message :method))
   (handler-sym (intern (concat "eglot--"
-  method
+   method
  (if (functionp handler-sym)
  (apply handler-sym proc (plist-get message :params))
(eglot--debug "No implemetation for notification %s yet"
- method)))
+ method)))
 
 (defvar eglot--expect-carriage-return nil)
 
@@ -294,9 +297,9 @@
   (clrhash (eglot--pending-continuations process)))
 
 (cl-defun eglot--request (process
-   method
-   params
-success-fn error-fn timeout-fn (async-p t))
+  method
+  params
+   success-fn error-fn timeout-fn (async-p t))
   (let* ((id (eglot--next-request-id))
  (timeout-fn
   (or timeout-fn
@@ -363,6 +366,9 @@
 ;;; Requests
 ;;;
 (defun eglot--protocol-initialize (process interactive)
+  "Initialize LSP protocol.
+PROCESS is a connected process (network or local).
+INTERACTIVE is t if caller was called interactively."
   (eglot--request
process
:initialize
@@ -385,7 +391,7 @@
 (defun eglot-quit-server (process  sync interactive)
   "Politely ask the server PROCESS to quit.
 If SYNC, don't leave this function with the server still
-running."
+running.  INTERACTIVE is t if called interactively."
   (interactive (list (eglot--current-process-or-lose) t t))
   (when interactive
 (eglot--message "(eglot-quit-server) Asking %s politely to terminate"
@@ -437,47 +443,50 @@ running."
 (forward-line (plist-get pos-plist :line))
 (forward-char (plist-get pos-plist :character))
 (point
-  (loop for diag across diagnostics
-do (cl-destructuring-bind ( range severity
-_code _source message)
-   diag
- (cl-destructuring-bind ( start end)
- range
-   (let* ((begin-pos (pos-at start))
-  (end-pos (pos-at end))
-  (ov (make-overlay begin-pos
-end-pos
-buffer)))
- (push ov eglot--diagnostic-overlays)
- (overlay-put ov 'face
-  (case severity
-(1 'flymake-errline)
-(2 'flymake-warnline)))
- (overlay-put ov 'help-echo
-  message)
- (overlay-put ov 'eglot--diagnostic diag
+  (cl-loop for diag across diagnostics
+   

[elpa] externals/elpa 0ec7801 012/139: Simplify `eglot--protocol-initialize`

2018-05-14 Thread Jo�o T�vora
branch: externals/elpa
commit 0ec78011fee3be96f110fc37756a9baac6595348
Author: João Távora 
Commit: João Távora 

Simplify `eglot--protocol-initialize`

* eglot.el (eglot--protocol-initialize): Simplify
---
 eglot.el | 29 +++--
 1 file changed, 7 insertions(+), 22 deletions(-)

diff --git a/eglot.el b/eglot.el
index cd91d78..b59ee02 100644
--- a/eglot.el
+++ b/eglot.el
@@ -70,7 +70,7 @@
   "Point where next unread message starts")
 
 (eglot--define-process-var eglot--short-name nil
-  "A short name")
+  "A short name for the process")
 
 (eglot--define-process-var eglot--expected-bytes nil
   "How many bytes declared by server")
@@ -81,6 +81,9 @@
 (eglot--define-process-var eglot--events-buffer nil
   "A buffer pretty-printing the EGLOT RPC events")
 
+(eglot--define-process-var eglot--capabilities :unreported
+  "Holds list of capabilities that server reported")
+
 (cl-defmacro eglot--request (process
   method
   params
@@ -367,29 +370,11 @@
  :capabilities (:workspace (:executeCommand 
(:dynamicRegistration t))
:textDocument (:synchronization 
(:didSave t
(lambda ( capabilities)
- (cl-destructuring-bind
- ( all
-
-;; capabilities reported by server
-_textDocumentSync
-_hoverProvider
-_completionProvider
-_definitionProvider
-_referencesProvider
-_documentHighlightProvider
-_documentSymbolProvider
-_workspaceSymbolProvider
-_codeActionProvider
-_documentFormattingProvider
-_documentRangeFormattingProvider
-_renameProvider
-_executeCommandProvider
-)
- capabilities
-   (when interactive
+ (setf (eglot--capabilities process) capabilities)
+ (when interactive
  (eglot--message
   "So yeah I got lots (%d) of capabilities"
-  (length all)))
+  (length capabilities))
 
 (defun eglot-quit-server (process  sync)
   (interactive (list (eglot--current-process-or-lose)))



[elpa] externals/elpa 571b08f 076/139: Fix the odd bug here and there

2018-05-14 Thread Jo�o T�vora
branch: externals/elpa
commit 571b08f52bf8420a5e0bb3cfa727235048d94ba6
Author: João Távora 
Commit: João Távora 

Fix the odd bug here and there

* eglot.el (eglot--connect): Activate editing mode where
applicable here.
(eglot, eglot-reconnect): Not here or here.
(eglot--process-sentinel): Catch auto-reconnect errors.
(eglot--notify): Dont send 'id=null', it messes up js's lsp
(eglot--reply): Do send id here.
(eglot--log-event): Simplify protocol. Complexify implementation.
(eglot--process-receive, eglot--process-send): Simplify
eglot--log-event call.
(eglot--request, eglot--notify, eglot--reply): Simplify
eglot--process-send call
(eglot--server-client/registerCapability): Fix bug when replying
with wrong id.
(eglot--xref-reset-known-symbols): Take DUMMY arg.
---
 eglot.el | 131 +--
 1 file changed, 61 insertions(+), 70 deletions(-)

diff --git a/eglot.el b/eglot.el
index cb92361..d6ecdfe 100644
--- a/eglot.el
+++ b/eglot.el
@@ -265,6 +265,9 @@ SUCCESS-FN with no args if all goes well."
   (lambda ( capabilities)
 (setf (eglot--capabilities proc) capabilities)
 (setf (eglot--status proc) nil)
+(dolist (buffer (buffer-list))
+  (with-current-buffer buffer
+(eglot--maybe-activate-editing-mode proc)))
 (when success-fn (funcall success-fn proc))
 (eglot--notify proc :initialized (eglot--obj :__dummy__ t)
 
@@ -344,10 +347,7 @@ INTERACTIVE is t if called interactively."
 buffers in project %s."
proc
managed-major-mode
-   short-name)
-   (dolist (buffer (buffer-list))
- (with-current-buffer buffer
-   (eglot--maybe-activate-editing-mode proc)
+   short-name)))
 
 (defun eglot-reconnect (process  interactive)
   "Reconnect to PROCESS.
@@ -360,11 +360,7 @@ INTERACTIVE is t if called interactively."
(eglot--major-mode process)
(eglot--short-name process)
(eglot--contact process)
-   (lambda (proc)
- (eglot--message "Reconnected!")
- (dolist (buffer (buffer-list))
-   (with-current-buffer buffer
- (eglot--maybe-activate-editing-mode proc))
+   (lambda (_proc) (eglot--message "Reconnected!"
 
 (defvar eglot--inhibit-auto-reconnect nil
   "If non-nil, don't autoreconnect on unexpected quit.")
@@ -397,9 +393,11 @@ INTERACTIVE is t if called interactively."
(process-exit-status process)))
   ((null eglot--inhibit-auto-reconnect)
(eglot--warn
-"(sentinel) Reconnecting after process unexpectedly changed to %s."
+"(sentinel) Reconnecting after process unexpectedly changed to 
`%s'."
 change)
-   (eglot-reconnect process)
+   (condition-case-unless-debug err
+   (eglot-reconnect process)
+ (error (eglot--warn "Auto-reconnect failed: %s " err) ))
(setq eglot--inhibit-auto-reconnect
  (run-with-timer
   3 nil
@@ -493,13 +491,22 @@ INTERACTIVE is t if called interactively."
   (display-buffer buffer))
 buffer))
 
-(defun eglot--log-event (proc type message  id error)
+(defun eglot--log-event (proc message type)
   "Log an eglot-related event.
-PROC is the current process.  TYPE is an identifier.  MESSAGE is
-a JSON-like plist or anything else.  ID is a continuation
-identifier.  ERROR is non-nil if this is a JSON-RPC error."
+PROC is the current process.  MESSAGE is a JSON-like plist.  TYPE
+is a symbol saying if this is a client or server originated."
   (with-current-buffer (eglot-events-buffer proc)
-(let ((inhibit-read-only t))
+(let* ((inhibit-read-only t)
+   (id (plist-get message :id))
+   (error (plist-get message :error))
+   (method (plist-get message :method))
+   (subtype (cond ((and method id)   'request)
+  (method'notification)
+  (id'reply)
+  ;; pyls keeps on sending these
+  (t 'unexpected-thingy)))
+   (type
+(format "%s-%s" type subtype)))
   (goto-char (point-max))
   (let ((msg (format "%s%s%s:\n%s\n"
  type
@@ -518,15 +525,7 @@ identifier.  ERROR is non-nil if this is a JSON-RPC error."
  (continuations (and id
  (not method)
  (gethash id (eglot--pending-continuations 
proc)
-(eglot--log-event proc
-  (cond ((and method id)   'server-request)
-(method'server-notification)
-   

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

2018-05-14 Thread Jo�o T�vora
branch: externals/elpa
commit c4ffabcb5f95d8d2a3676006641362e188df52f8
Author: João Távora 
Commit: João Távora 

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 ( 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)
+  

[elpa] externals/elpa dfab9a0 011/139: Experimental diagnostic overlays

2018-05-14 Thread Jo�o T�vora
branch: externals/elpa
commit dfab9a08a6b6af099c21f9cd8a99f5a00d81cb4e
Author: João Távora 
Commit: João Távora 

Experimental diagnostic overlays
---
 eglot.el | 40 ++--
 1 file changed, 38 insertions(+), 2 deletions(-)

diff --git a/eglot.el b/eglot.el
index 479e87a..cd91d78 100644
--- a/eglot.el
+++ b/eglot.el
@@ -414,11 +414,47 @@
 
 ;;; Notifications
 ;;;
+(defvar-local eglot--diagnostic-overlays nil)
+
 (cl-defun eglot--textDocument/publishDiagnostics
 (_process  uri diagnostics)
   "Handle notification publishDiagnostics"
-  (eglot--message "So yeah I got %s for %s"
-  diagnostics uri))
+  (let* ((obj (url-generic-parse-url uri))
+(filename (car (url-path-and-query obj)))
+ (buffer (find-buffer-visiting filename)))
+(cond
+ (buffer
+  (with-current-buffer buffer
+(eglot--message "OK so add some %s diags" (length diagnostics))
+(mapc #'delete-overlay eglot--diagnostic-overlays)
+(setq eglot--diagnostic-overlays nil)
+(cl-flet ((pos-at (pos-plist)
+  (save-excursion
+(goto-char (point-min))
+(forward-line (plist-get pos-plist :line))
+(forward-char (plist-get pos-plist :character))
+(point
+  (loop for diag across diagnostics
+do (cl-destructuring-bind ( range severity
+_code _source message)
+   diag
+ (cl-destructuring-bind ( start end)
+ range
+   (let* ((begin-pos (pos-at start))
+  (end-pos (pos-at end))
+  (ov (make-overlay begin-pos
+end-pos
+buffer)))
+ (push ov eglot--diagnostic-overlays)
+ (overlay-put ov 'face
+  (case severity
+(1 'flymake-errline)
+(2 'flymake-warnline)))
+ (overlay-put ov 'help-echo
+  message)
+ (overlay-put ov 'eglot--diagnostic diag
+ (t
+  (eglot--message "OK so %s isn't visited" filename)
 
 
 ;;; Helpers



<    1   2   3   >