Skip to content

Commit c333e49

Browse files
authored
expand-snippet: indent according to the line where snippet is expanded (#1939)
1 parent a7532c3 commit c333e49

File tree

3 files changed

+57
-31
lines changed

3 files changed

+57
-31
lines changed

lsp-completion.el

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -427,7 +427,8 @@ Others: TRIGGER-CHARS"
427427
'lsp-completion-markers markers
428428
'lsp-completion-prefix prefix)
429429
(text-properties-at 0 candidate))
430-
((&CompletionItem :label :insert-text? :text-edit? :insert-text-format? :additional-text-edits?)
430+
((&CompletionItem :label :insert-text? :text-edit? :insert-text-format?
431+
:additional-text-edits? :keep-whitespace?)
431432
item))
432433
(cond
433434
(text-edit?
@@ -440,12 +441,12 @@ Others: TRIGGER-CHARS"
440441
(delete-region start-point (point))
441442
(insert (or insert-text? label))))
442443

443-
(when (eq insert-text-format? 2)
444-
(let ((yas-indent-line (lsp--indent-snippets?)))
445-
(yas-expand-snippet
446-
(lsp--to-yasnippet-snippet (buffer-substring start-point (point)))
447-
start-point
448-
(point))))
444+
(when (equal insert-text-format? lsp/insert-text-format-snippet)
445+
(lsp--expand-snippet (buffer-substring start-point (point))
446+
start-point
447+
(point)
448+
nil
449+
keep-whitespace?))
449450

450451
(when lsp-completion-enable-additional-text-edit
451452
(if (or (get-text-property 0 'lsp-completion-resolved candidate)

lsp-mode.el

Lines changed: 48 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@
6969
(defvar company-backends)
7070
(defvar yas-inhibit-overlay-modification-protection)
7171
(defvar yas-indent-line)
72+
(defvar yas-also-auto-indent-first-line)
7273
(defvar dap-auto-configure-mode)
7374
(defvar dap-ui-menu-items)
7475

@@ -3470,10 +3471,12 @@ in that particular folder."
34703471
(lsp-managed-mode 1)
34713472

34723473
(run-hooks 'lsp-after-open-hook)
3473-
(-some-> lsp--cur-workspace
3474-
(lsp--workspace-client)
3475-
(lsp--client-after-open-fn)
3476-
(funcall)))
3474+
(when-let ((client (-some-> lsp--cur-workspace (lsp--workspace-client))))
3475+
(-some-> (lsp--client-after-open-fn client)
3476+
(funcall))
3477+
(-some-> (format "lsp-%s-after-open-hook" (lsp--client-server-id client))
3478+
(intern-soft)
3479+
(run-hooks))))
34773480

34783481
(defun lsp--text-document-identifier ()
34793482
"Make TextDocumentIdentifier."
@@ -3676,16 +3679,42 @@ The method uses `replace-buffer-contents'."
36763679
beg (+ beg (length new-text))
36773680
length)))))))))
36783681

3679-
(defun lsp--indent-snippets? ()
3680-
"Enable indenting of snippets for everything but `org-mode'.
3682+
(defun lsp--to-yasnippet-snippet (snippet)
3683+
"Convert LSP SNIPPET to yasnippet snippet."
3684+
;; LSP snippet doesn't escape "{", but yasnippet requires escaping it.
3685+
(replace-regexp-in-string (rx (or bos (not (any "$" "\\"))) (group "{"))
3686+
(rx "\\" (backref 1))
3687+
snippet
3688+
nil nil 1))
36813689

3682-
Indending snippets is extremely slow in `org-mode' buffers since
3683-
it has to calculate indentation based on SRC block position."
3684-
(unless (derived-mode-p 'org-mode)
3685-
'auto))
3690+
(defvar-local lsp-enable-relative-indentation nil
3691+
"Enable relative indentation when insert texts, snippets ... from language server.")
3692+
3693+
(defun lsp--expand-snippet (snippet &optional start end expand-env keep-whitespace)
3694+
"Wrapper of `yas-expand-snippet' with all of it arguments.
3695+
The snippet will be convert to LSP style and indent according to
3696+
LSP server result."
3697+
(let* ((inhibit-field-text-motion t)
3698+
(offset (save-excursion
3699+
(goto-char start)
3700+
(back-to-indentation)
3701+
(buffer-substring-no-properties
3702+
(line-beginning-position)
3703+
(point))))
3704+
(yas-indent-line (unless keep-whitespace 'auto))
3705+
(yas-also-auto-indent-first-line nil)
3706+
(indent-line-function (if (or lsp-enable-relative-indentation
3707+
(derived-mode-p 'org-mode))
3708+
(lambda () (save-excursion
3709+
(forward-line 0)
3710+
(insert offset)))
3711+
indent-line-function)))
3712+
(yas-expand-snippet
3713+
(lsp--to-yasnippet-snippet snippet)
3714+
start end expand-env)))
36863715

36873716
(defun lsp--apply-text-edits (edits)
3688-
"Apply the edits described in the TextEdit[] object."
3717+
"Apply the EDITS described in the TextEdit[] object."
36893718
(unless (seq-empty-p edits)
36903719
(atomic-change-group
36913720
(run-hooks 'lsp-before-apply-edits-hook)
@@ -3712,9 +3741,7 @@ it has to calculate indentation based on SRC block position."
37123741
(-when-let ((&SnippetTextEdit :range (&RangeToPoint :start)
37133742
:insert-text-format? :new-text) edit)
37143743
(when (eq insert-text-format? lsp/insert-text-format-snippet)
3715-
(let ((yas-indent-line (lsp--indent-snippets?)))
3716-
(yas-expand-snippet (lsp--to-yasnippet-snippet new-text)
3717-
start (+ start (length new-text))))))))))
3744+
(lsp--expand-snippet new-text start (+ start (length new-text)))))))))
37183745
(undo-amalgamate-change-group change-group)
37193746
(progress-reporter-done reporter))))))
37203747

@@ -4190,14 +4217,6 @@ and the position respectively."
41904217

41914218
(defalias 'lsp--cur-line-diagnotics 'lsp-cur-line-diagnostics)
41924219

4193-
(defun lsp--to-yasnippet-snippet (text)
4194-
"Convert LSP snippet TEXT to yasnippet snippet."
4195-
;; LSP snippet doesn't escape "{", but yasnippet requires escaping it.
4196-
(replace-regexp-in-string (rx (or bos (not (any "$" "\\"))) (group "{"))
4197-
(rx "\\" (backref 1))
4198-
text
4199-
nil nil 1))
4200-
42014220
(defun lsp--extract-line-from-buffer (pos)
42024221
"Return the line pointed to by POS (a Position object) in the current buffer."
42034222
(let* ((point (lsp--position-to-point pos))
@@ -6745,7 +6764,13 @@ remote machine and vice versa."
67456764
(seq-every-p (apply-partially #'symbolp)
67466765
(lsp--client-major-modes client))))
67476766
nil "Invalid activation-fn and/or major-modes.")
6748-
(puthash (lsp--client-server-id client) client lsp-clients))
6767+
(let ((client-id (lsp--client-server-id client)))
6768+
(puthash client-id client lsp-clients)
6769+
(setplist (intern (format "lsp-%s-after-open-hook" client-id))
6770+
`(standard-value (nil) custom-type hook
6771+
custom-package-version (lsp-mode . "7.0.1")
6772+
variable-documentation ,(format "Hooks to run after `%s' server is run." client-id)
6773+
custom-requests nil))))
67496774

67506775
(defun lsp--create-initialization-options (_session client)
67516776
"Create initialization-options from SESSION and CLIENT.

lsp-protocol.el

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -404,7 +404,7 @@ See `-let' for a description of the destructuring mechanism."
404404
(Command (:title :command) (:arguments))
405405
(CompletionCapabilities nil (:completionItem :completionItemKind :contextSupport :dynamicRegistration))
406406
(CompletionContext (:triggerKind) (:triggerCharacter))
407-
(CompletionItem (:label) (:additionalTextEdits :command :commitCharacters :data :deprecated :detail :documentation :filterText :insertText :insertTextFormat :kind :preselect :sortText :tags :textEdit :score))
407+
(CompletionItem (:label) (:additionalTextEdits :command :commitCharacters :data :deprecated :detail :documentation :filterText :insertText :insertTextFormat :kind :preselect :sortText :tags :textEdit :score :keepWhitespace))
408408
(CompletionItemCapabilities nil (:commitCharactersSupport :deprecatedSupport :documentationFormat :preselectSupport :snippetSupport :tagSupport))
409409
(CompletionItemKindCapabilities nil (:valueSet))
410410
(CompletionItemTagSupportCapabilities (:valueSet) nil)

0 commit comments

Comments
 (0)