Skip to content

Commit fea3e01

Browse files
committed
expand-snippet: indent according to the line where snippet is expanded
1 parent b1d1560 commit fea3e01

File tree

3 files changed

+59
-30
lines changed

3 files changed

+59
-30
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: 50 additions & 22 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

@@ -622,6 +623,7 @@ If this is set to nil, `eldoc' will show only the symbol information."
622623
:type 'boolean
623624
:group 'lsp-mode)
624625

626+
625627
(defcustom lsp-before-save-edits t
626628
"If non-nil, `lsp-mode' will apply edits suggested by the language server before saving a document."
627629
:type 'boolean
@@ -3470,10 +3472,14 @@ in that particular folder."
34703472
(lsp-managed-mode 1)
34713473

34723474
(run-hooks 'lsp-after-open-hook)
3473-
(-some-> lsp--cur-workspace
3475+
(-some->> lsp--cur-workspace
34743476
(lsp--workspace-client)
3475-
(lsp--client-after-open-fn)
3476-
(funcall)))
3477+
(funcall (lambda (client)
3478+
(-some-> (lsp--client-after-open-fn client)
3479+
(funcall))
3480+
(-some-> (format "lsp-%s-after-open-hook" (lsp--client-server-id client))
3481+
(intern-soft)
3482+
(run-hooks))))))
34773483

34783484
(defun lsp--text-document-identifier ()
34793485
"Make TextDocumentIdentifier."
@@ -3676,16 +3682,42 @@ The method uses `replace-buffer-contents'."
36763682
beg (+ beg (length new-text))
36773683
length)))))))))
36783684

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

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))
3693+
(defvar-local lsp-enable-relative-indentation nil
3694+
"Enable relative indentation when insert texts, snippets ... from language server.")
3695+
3696+
(defun lsp--expand-snippet (snippet &optional start end expand-env keep-whitespace)
3697+
"Wrapper of `yas-expand-snippet' with all of it arguments.
3698+
The snippet will be convert to LSP style and indent according to
3699+
LSP server result."
3700+
(let* ((inhibit-field-text-motion t)
3701+
(offset (save-excursion
3702+
(goto-char start)
3703+
(back-to-indentation)
3704+
(buffer-substring-no-properties
3705+
(line-beginning-position)
3706+
(point))))
3707+
(yas-indent-line (unless keep-whitespace 'auto))
3708+
(yas-also-auto-indent-first-line nil)
3709+
(indent-line-function (if (or lsp-enable-relative-indentation
3710+
(derived-mode-p 'org-mode))
3711+
(lambda () (save-excursion
3712+
(forward-line 0)
3713+
(insert offset)))
3714+
indent-line-function)))
3715+
(yas-expand-snippet
3716+
(lsp--to-yasnippet-snippet snippet)
3717+
start end expand-env)))
36863718

36873719
(defun lsp--apply-text-edits (edits)
3688-
"Apply the edits described in the TextEdit[] object."
3720+
"Apply the EDITS described in the TextEdit[] object."
36893721
(unless (seq-empty-p edits)
36903722
(atomic-change-group
36913723
(run-hooks 'lsp-before-apply-edits-hook)
@@ -3712,9 +3744,7 @@ it has to calculate indentation based on SRC block position."
37123744
(-when-let ((&SnippetTextEdit :range (&RangeToPoint :start)
37133745
:insert-text-format? :new-text) edit)
37143746
(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))))))))))
3747+
(lsp--expand-snippet new-text start (+ start (length new-text)))))))))
37183748
(undo-amalgamate-change-group change-group)
37193749
(progress-reporter-done reporter))))))
37203750

@@ -4190,14 +4220,6 @@ and the position respectively."
41904220

41914221
(defalias 'lsp--cur-line-diagnotics 'lsp-cur-line-diagnostics)
41924222

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-
42014223
(defun lsp--extract-line-from-buffer (pos)
42024224
"Return the line pointed to by POS (a Position object) in the current buffer."
42034225
(let* ((point (lsp--position-to-point pos))
@@ -6745,7 +6767,13 @@ remote machine and vice versa."
67456767
(seq-every-p (apply-partially #'symbolp)
67466768
(lsp--client-major-modes client))))
67476769
nil "Invalid activation-fn and/or major-modes.")
6748-
(puthash (lsp--client-server-id client) client lsp-clients))
6770+
(let ((client-id (lsp--client-server-id client)))
6771+
(puthash client-id client lsp-clients)
6772+
(setplist (intern (format "lsp-%s-after-open-hook" client-id))
6773+
`(standard-value (nil) custom-type hook
6774+
custom-package-version (lsp-mode . "7.0.1")
6775+
variable-documentation ,(format "Hooks to run after `%s' server is run." client-id)
6776+
custom-requests nil))))
67496777

67506778
(defun lsp--create-initialization-options (_session client)
67516779
"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)