emacs-lsp / lsp-mode

Emacs client/library for the Language Server Protocol
https://emacs-lsp.github.io/lsp-mode
GNU General Public License v3.0
4.72k stars 860 forks source link

Allow other snippet/template expansion libraries #4474

Open FrauH0lle opened 2 weeks ago

FrauH0lle commented 2 weeks ago

Hey there,

I would like to ask if you would consider supporting other snippet expansion libraries than yasnippet?

Currently I working with tempel and combine it with lsp-snippet which works fairly well after some modifications to lsp-snippet. In the end, this lead me to ask this question, because the package uses a little hack to work (which also does not work after #4413).

So I was thinking about the following changes to make the integration of 3rd party packages easier.

Introduce a variable like

(defcustom lsp-snippet-override nil
  "Allows the use of other snippet expansion packages than yasnippet.")

This could be used in the checks for snippet expansion capabilities here , here and here

...
,(and lsp-enable-snippet (or lsp-snippet-override
                             (fboundp 'yas-minor-mode)))

yasnippet itself is used here:

(defun lsp--expand-snippet (snippet &optional start end expand-env)
  "Wrapper of `yas-expand-snippet' with all of it arguments.
The snippet will be convert to LSP style and indent according to
LSP server result."
  (require 'yasnippet nil t)
  ....)

Here, another variable could be used:

(defcustom lsp-snippet-function #'lsp-snippet-expand-yasnippet
  "Function used to expand snippets. Will be called with the
 arguments SNIPPET &optional START END EXPAND-ENV")

(defun lsp-snippet-expand-yasnippet (snippet &optional start end expand-env)
  "Wrapper of `yas-expand-snippet' with all of it arguments.
The snippet will be convert to LSP style and indent according to
LSP server result."
  (require 'yasnippet nil t)
  (let* ((inhibit-field-text-motion t)
         (yas-wrap-around-region nil)
         (yas-indent-line 'none)
         (yas-also-auto-indent-first-line nil))
    (yas-expand-snippet
     (lsp--to-yasnippet-snippet snippet)
     start end expand-env)))

and change lsp--expand-snippet to

(defun lsp--expand-snippet (snippet &optional start end expand-env)
  "Wrapper of `yas-expand-snippet' with all of it arguments.
The snippet will be convert to LSP style and indent according to
LSP server result."
  (funcall lsp-snippet-function snippet start end expand-env))

Thus, other packages could provide their own expansion machinery and simply hook it to lsp-mode.

Would this be something you would consider?