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

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

[elpa] externals/eglot 88ebed6 17/62: Implement TextDocument/rangeFormat


From: Stefan Monnier
Subject: [elpa] externals/eglot 88ebed6 17/62: Implement TextDocument/rangeFormatting
Date: Sat, 29 Sep 2018 17:13:30 -0400 (EDT)

branch: externals/eglot
commit 88ebed60aa55677a029bb5f947c2d5d29ecb526f
Author: Michał K <address@hidden>
Commit: João Távora <address@hidden>

    Implement TextDocument/rangeFormatting
    
    * eglot.el (eglot-format): New command.
    (eglot-format-buffer): Use it as implementation.
    (eglot-client-capabilities): Add :rangeFormatting.
    * eglot-tests.el (formatting): Also test range formatting.
    * README.md (Commands and keybindings): Mention eglot-format.
    (Language features): Tick textDocument/rangeFormatting.
---
 README.md      |  6 +++---
 eglot-tests.el | 34 +++++++++++++++++++++-------------
 eglot.el       | 41 ++++++++++++++++++++++++++++++-----------
 3 files changed, 54 insertions(+), 27 deletions(-)

diff --git a/README.md b/README.md
index f32f478..860dda8 100644
--- a/README.md
+++ b/README.md
@@ -96,8 +96,8 @@ Here's a summary of available commands:
 
 - `M-x eglot-rename` ask the server to rename the symbol at point;
 
-- `M-x eglot-format-buffer` ask the server to reformat the current
-  buffer;
+- `M-x eglot-format` asks the server to format buffer or the active
+  region;
 
 - `M-x eglot-code-actions` asks the server for any code actions at
   point. These may tipically be simple fixes, like deleting an unused
@@ -206,7 +206,7 @@ eglot-shutdown`.
 - [ ] textDocument/documentColor
 - [ ] textDocument/colorPresentation (3.6.0)
 - [x] textDocument/formatting 
-- [ ] textDocument/rangeFormatting
+- [x] textDocument/rangeFormatting
 - [ ] textDocument/onTypeFormatting
 - [x] textDocument/rename
 
diff --git a/eglot-tests.el b/eglot-tests.el
index 3932769..6940fcd 100644
--- a/eglot-tests.el
+++ b/eglot-tests.el
@@ -376,23 +376,31 @@ Pass TIMEOUT to `eglot--with-timeout'."
       (should (string-match "^exit" eldoc-last-message)))))
 
 (ert-deftest formatting ()
-  "Test document formatting in a python LSP"
+  "Test formatting in a python LSP"
   (skip-unless (and (executable-find "pyls")
                     (or (executable-find "yapf")
                         (executable-find "autopep8"))))
   (eglot--with-dirs-and-files
-      '(("project" . (("something.py" . "def foo():pass"))))
-    (with-current-buffer
-        (eglot--find-file-noselect "project/something.py")
-      (should (eglot--tests-connect))
-      (search-forward ":pa")
-      (eglot-format-buffer)
-      (should (looking-at "ss"))
-      (should (or
-               ;; yapf
-               (string= (buffer-string) "def foo():\n    pass\n")
-               ;; autopep8
-               (string= (buffer-string) "def foo(): pass\n"))))))
+   '(("project" . (("something.py" . "def a():pass\ndef b():pass"))))
+   (with-current-buffer
+       (eglot--find-file-noselect "project/something.py")
+     (should (eglot--tests-connect))
+     (search-forward "b():pa")
+     (eglot-format (point-at-bol) (point-at-eol))
+     (should (looking-at "ss"))
+     (should
+      (or
+       ;; yapf
+       (string= (buffer-string) "def a():pass\n\n\ndef b():\n    pass\n")
+       ;; autopep8
+       (string= (buffer-string) "def a():pass\n\n\ndef b(): pass\n")))
+     (eglot-format-buffer)
+     (should 
+      (or
+       ;; yapf
+       (string= (buffer-string) "def a():\n    pass\n\n\ndef b():\n    pass\n")
+       ;; autopep8
+       (string= (buffer-string) "def a(): pass\n\n\ndef b(): pass\n"))))))
 
 (ert-deftest javascript-basic ()
   "Test basic autocompletion in a python LSP"
diff --git a/eglot.el b/eglot.el
index fbc6a53..f0a4b71 100644
--- a/eglot.el
+++ b/eglot.el
@@ -183,6 +183,7 @@ lasted more than that many seconds."
              :documentHighlight  `(:dynamicRegistration :json-false)
              :codeAction         `(:dynamicRegistration :json-false)
              :formatting         `(:dynamicRegistration :json-false)
+             :rangeFormatting    `(:dynamicRegistration :json-false)
              :rename             `(:dynamicRegistration :json-false)
              :publishDiagnostics `(:relatedInformation :json-false))
             :experimental (list))))
@@ -1227,17 +1228,35 @@ DUMMY is ignored."
 (defun eglot-format-buffer ()
   "Format contents of current buffer."
   (interactive)
-  (unless (eglot--server-capable :documentFormattingProvider)
-    (eglot--error "Server can't format!"))
-  (eglot--apply-text-edits
-   (jsonrpc-request
-    (eglot--current-server-or-lose)
-    :textDocument/formatting
-    (list :textDocument (eglot--TextDocumentIdentifier)
-          :options (list :tabSize tab-width
-                         :insertSpaces
-                         (if indent-tabs-mode :json-false t)))
-    :deferred :textDocument/formatting)))
+  (eglot-format nil nil))
+
+(defun eglot-format (&optional beg end)
+  "Format region BEG END.
+If either BEG or END is nil, format entire buffer.
+Interactively, format active region, or entire buffer if region
+is not active."
+  (interactive (and (region-active-p) (list (region-beginning) (region-end))))
+  (pcase-let ((`(,method ,cap ,args)
+               (cond
+                ((and beg end)
+                 `(:textDocument/rangeFormatting
+                   :documentRangeFormattingProvider
+                   (:range ,(list :start (eglot--pos-to-lsp-position beg)
+                                  :end (eglot--pos-to-lsp-position end)))))
+                (t
+                 '(:textDocument/formatting :documentFormattingProvider 
nil)))))
+    (unless (eglot--server-capable cap)
+      (eglot--error "Server can't format!"))
+    (eglot--apply-text-edits
+     (jsonrpc-request
+      (eglot--current-server-or-lose)
+      method
+      (cl-list*
+       :textDocument (eglot--TextDocumentIdentifier)
+       :options (list :tabSize tab-width
+                      :insertSpaces (if indent-tabs-mode :json-false t))
+       args)
+      :deferred method))))
 
 (defun eglot-completion-at-point ()
   "EGLOT's `completion-at-point' function."



reply via email to

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