Skip to content

Commit 7ff41bf

Browse files
committed
Eglot: fix textDocument/onTypeFormatting for 'newline' command
In the newline command, last-input-event is 13 (carriage return), but most, if not all, language servers that support documentOnTypeFormattingProvider expect 10 (linefeed) to be the trigger, so convert 13 to 10 for the purposes of the textDocument/onTypeFormatting request. Also make this common edit silent in the mode-line/messages. * lisp/progmodes/eglot.el (eglot--post-self-insert-hook): Convert linefeed to carriage return. (eglot-format): Pass SILENT to eglot--apply-text-edits. (eglot--apply-text-edits): Take new optional SILENT arg. * etc/EGLOT-NEWS: Mention change
1 parent e2cc16f commit 7ff41bf

File tree

2 files changed

+28
-13
lines changed

2 files changed

+28
-13
lines changed

etc/EGLOT-NEWS

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,13 @@ watching requests. This change slightly reduces the number of file
2727
watcher objects requested from the operating system, which can be a
2828
problem, particularly on Mac OS. See github#1228 and github#1226.
2929

30+
** Fixed "onTypeFormatting" feature
31+
32+
This feature wasn't triggered for the 'newline' command because
33+
language servers often expect 10 (linefeed) to be the trigger
34+
character, but 'newline' emits 13 (carriage return). Also made this
35+
feature less chatty in the mode-line and messages buffer.
36+
3037

3138
* Changes in Eglot 1.15 (29/4/2023)
3239

lisp/progmodes/eglot.el

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2448,15 +2448,17 @@ buffer."
24482448
(defun eglot--post-self-insert-hook ()
24492449
"Set `eglot--last-inserted-char', maybe call on-type-formatting."
24502450
(setq eglot--last-inserted-char last-input-event)
2451-
(let ((ot-provider (eglot--server-capable :documentOnTypeFormattingProvider)))
2451+
(let ((ot-provider (eglot--server-capable :documentOnTypeFormattingProvider))
2452+
;; transform carriage return into line-feed
2453+
(adjusted-ie (if (= last-input-event 13) 10 last-input-event)))
24522454
(when (and ot-provider
24532455
(ignore-errors ; github#906, some LS's send empty strings
2454-
(or (eq last-input-event
2456+
(or (eq adjusted-ie
24552457
(seq-first (plist-get ot-provider :firstTriggerCharacter)))
2456-
(cl-find last-input-event
2458+
(cl-find adjusted-ie
24572459
(plist-get ot-provider :moreTriggerCharacter)
24582460
:key #'seq-first))))
2459-
(eglot-format (point) nil last-input-event))))
2461+
(eglot-format (point) nil adjusted-ie))))
24602462

24612463
(defvar eglot--workspace-symbols-cache (make-hash-table :test #'equal)
24622464
"Cache of `workspace/Symbol' results used by `xref-find-definitions'.")
@@ -2973,7 +2975,9 @@ for which LSP on-type-formatting should be requested."
29732975
:insertSpaces (if indent-tabs-mode :json-false t)
29742976
:insertFinalNewline (if require-final-newline t :json-false)
29752977
:trimFinalNewlines (if delete-trailing-lines t :json-false))
2976-
args)))))
2978+
args))
2979+
nil
2980+
on-type-format)))
29772981

29782982
(defvar eglot-cache-session-completions t
29792983
"If non-nil Eglot caches data during completion sessions.")
@@ -3380,19 +3384,21 @@ Returns a list as described in docstring of `imenu--index-alist'."
33803384
(((SymbolInformation)) (eglot--imenu-SymbolInformation res))
33813385
(((DocumentSymbol)) (eglot--imenu-DocumentSymbol res))))))
33823386

3383-
(cl-defun eglot--apply-text-edits (edits &optional version)
3384-
"Apply EDITS for current buffer if at VERSION, or if it's nil."
3387+
(cl-defun eglot--apply-text-edits (edits &optional version silent)
3388+
"Apply EDITS for current buffer if at VERSION, or if it's nil.
3389+
If SILENT, don't echo progress in mode-line."
33853390
(unless edits (cl-return-from eglot--apply-text-edits))
33863391
(unless (or (not version) (equal version eglot--versioned-identifier))
33873392
(jsonrpc-error "Edits on `%s' require version %d, you have %d"
33883393
(current-buffer) version eglot--versioned-identifier))
33893394
(atomic-change-group
33903395
(let* ((change-group (prepare-change-group))
33913396
(howmany (length edits))
3392-
(reporter (make-progress-reporter
3393-
(format "[eglot] applying %s edits to `%s'..."
3394-
howmany (current-buffer))
3395-
0 howmany))
3397+
(reporter (unless silent
3398+
(make-progress-reporter
3399+
(format "[eglot] applying %s edits to `%s'..."
3400+
howmany (current-buffer))
3401+
0 howmany)))
33963402
(done 0))
33973403
(mapc (pcase-lambda (`(,newText ,beg . ,end))
33983404
(let ((source (current-buffer)))
@@ -3404,12 +3410,14 @@ Returns a list as described in docstring of `imenu--index-alist'."
34043410
(save-restriction
34053411
(narrow-to-region beg end)
34063412
(replace-buffer-contents temp)))
3407-
(eglot--reporter-update reporter (cl-incf done)))))))
3413+
(when reporter
3414+
(eglot--reporter-update reporter (cl-incf done))))))))
34083415
(mapcar (eglot--lambda ((TextEdit) range newText)
34093416
(cons newText (eglot--range-region range 'markers)))
34103417
(reverse edits)))
34113418
(undo-amalgamate-change-group change-group)
3412-
(progress-reporter-done reporter))))
3419+
(when reporter
3420+
(progress-reporter-done reporter)))))
34133421

34143422
(defun eglot--apply-workspace-edit (wedit &optional confirm)
34153423
"Apply the workspace edit WEDIT. If CONFIRM, ask user first."

0 commit comments

Comments
 (0)