[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] externals/eglot 6e76b08 100/139: Support workspace/applyEdit
From: |
João Távora |
Subject: |
[elpa] externals/eglot 6e76b08 100/139: Support workspace/applyEdit |
Date: |
Mon, 14 May 2018 09:55:02 -0400 (EDT) |
branch: externals/eglot
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/eglot 9ff97a6 079/139: Increase request timeout length to 10 seconds, (continued)
- [elpa] externals/eglot 9ff97a6 079/139: Increase request timeout length to 10 seconds, João Távora, 2018/05/14
- [elpa] externals/eglot 571b08f 076/139: Fix the odd bug here and there, João Távora, 2018/05/14
- [elpa] externals/eglot a7ddce6 080/139: Support javascript's javascript-typescript-langserver, João Távora, 2018/05/14
- [elpa] externals/eglot d40f9ac 094/139: Half-decent imenu support via textDocument/documentSymbol, João Távora, 2018/05/14
- [elpa] externals/eglot bbc64b4 087/139: Clean up client capabilities, João Távora, 2018/05/14
- [elpa] externals/eglot 9882bf2 072/139: Cleanup mistake with TextDocumentItem and TextDocumentIdentifier, João Távora, 2018/05/14
- [elpa] externals/eglot 8160cd4 071/139: Handle dynamic registration in general (but nothing specific yet), João Távora, 2018/05/14
- [elpa] externals/eglot c4ffabc 083/139: Half-decent completion support, João Távora, 2018/05/14
- [elpa] externals/eglot d431d41 088/139: Fix bug in hover support, João Távora, 2018/05/14
- [elpa] externals/eglot 1356844 097/139: Fix odd bugs, João Távora, 2018/05/14
- [elpa] externals/eglot 6e76b08 100/139: Support workspace/applyEdit,
João Távora <=
- [elpa] externals/eglot 5ce9ab0 106/139: Call eglot-eldoc-function after completion finishes, João Távora, 2018/05/14
- [elpa] externals/eglot ecd334f 101/139: Update README, João Távora, 2018/05/14
- [elpa] externals/eglot 39e8b9e 081/139: Add (dummy) tests and Travis CI integration, João Távora, 2018/05/14
- [elpa] externals/eglot 23b79e0 111/139: Shorten summary line to appease package-lint.el, João Távora, 2018/05/14
- [elpa] externals/eglot 37b7329 098/139: Reasonable textDocument/documentHighlight support, João Távora, 2018/05/14
- [elpa] externals/eglot d1cdcf1 119/139: Friendlier M-x eglot, João Távora, 2018/05/14
- [elpa] externals/eglot 764347d 128/139: New command eglot-help-at-point and a README update, João Távora, 2018/05/14
- [elpa] externals/eglot 9bf3166 136/139: Don't define a menu if nothing to show there for now, João Távora, 2018/05/14
- [elpa] externals/eglot 54fc885 113/139: More RLS-specifics: update Flymake diags when indexing done, João Távora, 2018/05/14
- [elpa] externals/eglot 56c2e1d 104/139: Get rid of eglot-mode, João Távora, 2018/05/14