]> git.eshelyaron.com Git - emacs.git/commitdiff
Implement textdocument/rangeformatting
authorMichal Krzywkowski <k.michal@zoho.com>
Tue, 10 Jul 2018 13:10:25 +0000 (15:10 +0200)
committerJoão Távora <joaotavora@gmail.com>
Sat, 28 Jul 2018 18:26:03 +0000 (19:26 +0100)
* 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.

lisp/progmodes/eglot.el

index fbc6a53db5eb79ae717c98f3e30efe59d85f2cdf..f0a4b7144dc47c15624ecc0e9e28aa12809d6236 100644 (file)
@@ -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."