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.
0 commit comments