How to show suggestions for YASnippets when using eglot

2.2k Views Asked by At

I'm currently using Emacs with eglot (minimal lsp client). However, no completions for snippets have appeared when I use the snippet library (e.g., YASnippet, tempel) together. Now I can specify the snippet name and expand it in the code. But I want emacs to work like when I type the snippet's name, it shows suggestions of the snippet.

I'll appreciate it if there's a way to show suggestions for snippets when using eglot. My emacs configuration is shown below.

  • eglot
(use-package eglot
  :ensure t
  :config
  (add-to-list 'eglot-server-programs '(c-mode . ("clangd")))
  (add-to-list 'eglot-server-programs '(c++-mode . ("clangd")))
  (add-to-list 'eglot-server-programs '(go-mode . ("gopls")))
  (add-to-list 'eglot-server-programs '(rustic-mode . ("rust-analyzer")))
  (add-to-list 'eglot-server-programs '(python-mode . ("pyls")))
  (add-to-list 'eglot-server-programs '(LaTeX-mode . ("digestif")))
  (add-hook 'c-mode-hook 'eglot-ensure)
  (add-hook 'c++-mode-hook 'eglot-ensure)
  (add-hook 'go-mode-hook 'eglot-ensure)
  (add-hook 'rustic-mode-hook 'eglot-ensure)
  (add-hook 'python-mode-hook 'eglot-ensure)
  (add-hook 'LaTeX-mode-hook 'eglot-ensure)
  ;; format on save
  (add-hook 'c-mode-hook '(lambda() (add-hook 'before-save-hook 'eglot-format-buffer nil t)))
  (add-hook 'c++-mode-hook '(lambda() (add-hook 'before-save-hook 'eglot-format-buffer nil t)))
  (add-hook 'python-mode-hook '(lambda() (add-hook 'before-save-hook 'eglot-format-buffer nil t)))
  (define-key eglot-mode-map (kbd "C-c r") 'eglot-rename))
  • YASnippet
(use-package yasnippet
  :ensure t
  :hook
  (prog-mode . yas-minor-mode)
  :bind
  (("C-c y n" . yas-new-snippet)
   ("C-c y v" . yas-visit-snippet-file)
   ("C-c y i" . yas-insert-snippet))
  :config
  (yas-reload-all)
  (setq yas-snippet-dirs
        '("~/.emacs.d/snippets")))

Company (I do not use company right now, transferred to corfu/cape instead.)

(use-package company
   :ensure t
   :diminish company-mode
   :bind
   (("C-M-i" . company-complete)
    :map company-active-map
    ("M-n" . nil)
    ("M-p" . nil)
    ("C-h" . nil)
    ("C-n" . company-select-next)
    ("C-p" . company-select-previous)
    ("C-s" . company-filter-candidates)
    ("C-i" . company-complete-selection)
    ([tab] . company-complete-selection))
   :hook
   (after-init . global-company-mode)
   :config
   (setq company-backends '((company-capf :with company-yasnippet)))
   (setq company-idle-delay 0
        company-minimum-prefix-length 2
        company-selection-wrap-around t
        completion-ignore-case t
        company-show-quick-access t))
  • Corfu / Cape
(use-package corfu
  :ensure t
  :custom
  (corfu-cycle t)
  (corfu-auto t)
  (corfu-quit-at-boundary nil)
  (corfu-scroll-margin 5)
  (corfu-echo-documentation t)
  :bind
  (:map corfu-map
        ("TAB" . corfu-insert)
        ([tab] . corfu-insert)
        ("C-n" . corfu-next)
        ("C-p" . corfu-previous))
  :init
  (global-corfu-mode))


;;;;; cape ;;;;;
(use-package cape
  :ensure t
  :config
  (add-to-list 'completion-at-point-functions (cape-company-to-capf #'company-yasnippet)))
1

There are 1 best solutions below

0
On BEST ANSWER

I finally got the solution from emacs-jp slack. I will reprint them in the hope that they will be of help to others who are similarly troubled.

;; for company

(add-hook 'eglot-managed-mode-hook (lambda ()
                                     (add-to-list 'company-backends
                                                  '(company-capf :with company-yasnippet))))


;; for corfu
(straight-use-package 'cape)

(defun my/eglot-capf ()
  (setq-local completion-at-point-functions
              (list (cape-super-capf
                     #'eglot-completion-at-point
                     (cape-company-to-capf #'company-yasnippet)))))

(add-hook 'eglot-managed-mode-hook #'my/eglot-capf)