[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] externals/elpa 6e76b08 100/139: Support workspace/applyEdit
From: |
João Távora |
Subject: |
[elpa] externals/elpa 6e76b08 100/139: Support workspace/applyEdit |
Date: |
Mon, 14 May 2018 09:53:44 -0400 (EDT) |
branch: externals/elpa
commit 6e76b0888885a7c21790ee9df905159a7d7b1f90
Author: João Távora <address@hidden>
Commit: João Távora <address@hidden>
Support workspace/applyEdit
* eglot.el (eglot--reply): Don't send result or error if not
provided.
(eglot--server-workspace/applyEdit): New server method.
(eglot--apply-text-edits): Rework.
(eglot--apply-workspace-edit): New helper.
(eglot-rename): Simplify.
---
eglot.el | 135 ++++++++++++++++++++++++++++++++++++++-------------------------
1 file changed, 82 insertions(+), 53 deletions(-)
diff --git a/eglot.el b/eglot.el
index 9ba87ef..37ad616 100644
--- a/eglot.el
+++ b/eglot.el
@@ -664,10 +664,10 @@ Meaning only return locally if successful, otherwise exit
non-locally."
(cl-defun eglot--reply (process id &key result error)
"Reply to PROCESS's request ID with MESSAGE."
- (eglot--process-send process (eglot--obj :jsonrpc "2.0"
- :id id
- :result result
- :error error)))
+ (eglot--process-send
+ process `(:jsonrpc "2.0" :id ,id
+ ,@(when result `(:result ,result))
+ ,@(when error `(:error ,error)))))
;;; Helpers
@@ -1031,6 +1031,20 @@ running. INTERACTIVE is t if called interactively."
registrations)
(eglot--reply proc id :result (eglot--obj :message "OK")))))
+(cl-defun eglot--server-workspace/applyEdit
+ (proc &key id _label edit)
+ "Handle notification client/registerCapability"
+ (condition-case err
+ (progn
+ (eglot--apply-workspace-edit edit 'confirm)
+ (eglot--reply proc id :result `(:applied )))
+ (error
+ (eglot--reply proc id
+ :result `(:applied :json-false)
+ :error
+ (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
@@ -1370,61 +1384,76 @@ DUMMY is ignored"
entries))
(funcall oldfun)))
-(defun eglot--apply-text-edits (uri edits proc &optional 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 (&key 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--apply-text-edits (buffer edits &optional version)
+ "Apply the EDITS for BUFFER."
+ (with-current-buffer buffer
+ (unless (or (not version)
+ (equal version eglot--versioned-identifier))
+ (eglot--error "Edits on `%s' require version %d, you have %d"
+ buffer version eglot--versioned-identifier))
+ (eglot--mapply
+ (eglot--lambda (&key 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: Performed %s edits" (current-buffer) (length edits))))
+
+(defun eglot--apply-workspace-edit (wedit &optional confirm)
+ "Apply the workspace edit WEDIT. If CONFIRM, ask user first."
+ (let (prepared)
+ (cl-destructuring-bind (&key changes documentChanges)
+ wedit
+ (cl-loop
+ for change on documentChanges
+ do (push (cl-destructuring-bind (&key textDocument edits) change
+ (cl-destructuring-bind (&key uri version) textDocument
+ (list (eglot--uri-to-path uri) edits version)))
+ prepared))
+ (cl-loop for (uri edits) on changes by #'cddr
+ do (push (list (eglot--uri-to-path uri) edits) prepared)))
+ (if (or confirm
+ (cl-notevery #'find-buffer-visiting
+ (mapcar #'car prepared)))
+ (unless (y-or-n-p
+ (format "[eglot] Server requests to edit %s files.\n %s\n\
+Proceed? "
+ (length prepared)
+ (mapconcat #'identity
+ (mapcar #'car prepared)
+ "\n ")))
+ (eglot--error "User cancelled server edit")))
+ (unwind-protect
+ (let (edit)
+ (while (setq edit (car prepared))
+ (cl-destructuring-bind (path edits &optional version) edit
+ (eglot--apply-text-edits (find-file-noselect path)
+ edits
+ version)
+ (pop prepared))))
+ (if prepared
+ (eglot--warn "Caution: edits of files %s failed."
+ (mapcar #'car prepared))
+ (eglot--message "Edit successful!")))))
(defun eglot-rename (newname)
"Rename the current symbol to NEWNAME."
(interactive
- (list
- (read-from-minibuffer (format "Rename `%s' to: " (symbol-at-point)))))
+ (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 (&key changes documentChanges)
- workspace-edit
- (cl-loop for change on documentChanges
- do (push
- (cl-destructuring-bind (&key textDocument edits) change
- (cl-destructuring-bind (&key 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)))))
+ (eglot--apply-workspace-edit
+ (eglot--sync-request (eglot--current-process-or-lose)
+ :textDocument/rename
+ (append
+ (eglot--current-buffer-TextDocumentPositionParams)
+ (eglot--obj :newName newname)))
+ current-prefix-arg))
;;; Dynamic registration
- [elpa] externals/elpa 4c0bfc3 139/139: Support didChangeWatchedFiles with dynamic registration, (continued)
- [elpa] externals/elpa 4c0bfc3 139/139: Support didChangeWatchedFiles with dynamic registration, João Távora, 2018/05/14
- [elpa] externals/elpa fceb6bb 090/139: Get rid of eglot--special-buffer-process, João Távora, 2018/05/14
- [elpa] externals/elpa 714e5be 086/139: Half-baked textDocument/hover support, João Távora, 2018/05/14
- [elpa] externals/elpa e9b5e54 077/139: ETOOMANYLAMBDAS, João Távora, 2018/05/14
- [elpa] externals/elpa f257d63 089/139: * eglot.el: Reformat to shave off some lines., João Távora, 2018/05/14
- [elpa] externals/elpa 5ce9ab0 106/139: Call eglot-eldoc-function after completion finishes, João Távora, 2018/05/14
- [elpa] externals/elpa d431d41 088/139: Fix bug in hover support, João Távora, 2018/05/14
- [elpa] externals/elpa d0b7773 117/139: Reduce log chatter, João Távora, 2018/05/14
- [elpa] externals/elpa 9af84a2 124/139: Prepare to sumbit to GNU ELPA, João Távora, 2018/05/14
- [elpa] externals/elpa 9577dfc 125/139: Duh, json.el is in Emacs, and json-mode.el is useless here, João Távora, 2018/05/14
- [elpa] externals/elpa 6e76b08 100/139: Support workspace/applyEdit,
João Távora <=
- [elpa] externals/elpa 3e0f1c3 122/139: Misc little adjustments for readability, João Távora, 2018/05/14
- [elpa] externals/elpa 9bf3166 136/139: Don't define a menu if nothing to show there for now, João Távora, 2018/05/14
- [elpa] externals/elpa 1fb2bcb 132/139: Ask server for textDocument/signatureHelp if it supports it, João Távora, 2018/05/14
- [elpa] externals/elpa c7bd095 118/139: Improve eglot-eldoc-function, João Távora, 2018/05/14
- [elpa] externals/elpa ab575d2 120/139: Rename functions. eglot--request is now the synchronous one, João Távora, 2018/05/14
- [elpa] externals/elpa 8448d9b 133/139: Work with any old directory, no formal project needed, João Távora, 2018/05/14
- [elpa] externals/elpa 589e1ea 138/139: Remove an unused variable, João Távora, 2018/05/14
- [elpa] externals/elpa 571b08f 076/139: Fix the odd bug here and there, João Távora, 2018/05/14
- [elpa] externals/elpa c4ffabc 083/139: Half-decent completion support, João Távora, 2018/05/14
- [elpa] externals/elpa 71e47d2 102/139: Fix odd bugs and tweak stuff, João Távora, 2018/05/14