]> git.eshelyaron.com Git - emacs.git/commitdiff
Implement on-type-formatting support
authorFelicián Németh <felician.nemeth@gmail.com>
Wed, 23 Mar 2022 20:47:45 +0000 (21:47 +0100)
committerJoão Távora <joaotavora@gmail.com>
Tue, 29 Mar 2022 09:03:40 +0000 (10:03 +0100)
* eglot.el (eglot-format): Add new optional argument `on-type-format'
to request :textDocument/onTypeFormatting, and ...
(eglot--post-self-insert-hook): ... call it from here when necessary.

* eglot-tests.el (eglot--simulate-key-event): New helper defun.
(rust-on-type-formatting): New test.

* NEWS.md: mention feature.

GitHub-reference: close https://github.com/joaotavora/eglot/issues/899

lisp/progmodes/eglot.el

index 58ad4588aed1a64ba0cf2e6ea02e52d8b77aae8c..1cf0b7ae639900984a097202ca0fe6e7da9bb82a 100644 (file)
@@ -1974,8 +1974,18 @@ THINGS are either registrations or unregisterations (sic)."
   "If non-nil, value of the last inserted character in buffer.")
 
 (defun eglot--post-self-insert-hook ()
-  "Set `eglot--last-inserted-char'."
-  (setq eglot--last-inserted-char last-input-event))
+  "Set `eglot--last-inserted-char', call on-type-formatting if necessary."
+  (setq eglot--last-inserted-char last-input-event)
+  (when (or (eq last-input-event
+                (elt (eglot--server-capable
+                      :documentOnTypeFormattingProvider
+                      :firstTriggerCharacter)
+                     0))
+            (seq-find (lambda (elt) (eq last-input-event (elt elt 0)))
+                      (eglot--server-capable
+                         :documentOnTypeFormattingProvider
+                         :moreTriggerCharacter)))
+    (eglot-format (point) nil (string last-input-event))))
 
 (defun eglot--pre-command-hook ()
   "Reset `eglot--last-inserted-char'."
@@ -2357,14 +2367,23 @@ Try to visit the target file for a richer summary line."
   (interactive)
   (eglot-format nil nil))
 
-(defun eglot-format (&optional beg end)
+(defun eglot-format (&optional beg end on-type-format)
   "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."
+is not active.
+
+If ON-TYPE-FORMAT is non-nil, request on-type-formatting from the
+server.  The argument should be a one-character-long string that
+has just been inserted at BEG."
   (interactive (and (region-active-p) (list (region-beginning) (region-end))))
   (pcase-let ((`(,method ,cap ,args)
                (cond
+                ((and beg on-type-format)
+                 `(:textDocument/onTypeFormatting
+                   :documentOnTypeFormattingProvider
+                   ,`(:position ,(eglot--pos-to-lsp-position beg)
+                      :ch ,on-type-format)))
                 ((and beg end)
                  `(:textDocument/rangeFormatting
                    :documentRangeFormattingProvider