I’ve got elixir-mode and eglot configured in my emacs.d and it mostly works. One thing I can’t figure out though is how to work with the code completion (via company) in elixir code.
Say I type defm
at this point I get the completion options pop up. I select defmodule
and then it expands to
defmodule $1 do
$0
end
But the cursor (point) moves to the end of end
. I get no opportunity to specify the module name and also complete the module body.
When I disable eglot
and use only elixir-mode
I get the expected behaviour were selecting defmodule
from the completion list places the cursor (point) between defmodule
and do
where I type the module name then another tab places the cursor inside the module body.
What is the way to work with what seems to be eglot’s way of code completion?
@thepreacher I couldn’t reproduce this bug. Running latest eglot in elpa, and elixir-lsp/elixir-ls (more updated fork at the moment). When I hit enter on defmodule completion, works as expected: cursor at module name, and tab goes to module body.
I wonder if you have a company
issue, or with another package.
@rodrigues can I take a look around your emacs.d
? My company config is really simple below and I spent hours going over it without success.
;; Company mode
(add-to-list 'completion-styles 'initials t)
(use-package company
:ensure t
:hook (after-init . global-company-mode)
:init
(setq company-minimum-prefix-length 2)
;;(setq company-auto-complete nil)
(setq company-idle-delay 0)
(setq company-require-match 'never)
(setq-default company-dabbrev-other-buffers 'all
company-tooltip-align-annotations t)
(setq tab-always-indent 'complete)
;;(defvar completion-at-point-functions-saved nil)
:config
(define-key company-mode-map (kbd "M-/") 'company-complete)
(define-key company-active-map (kbd "C-n") 'company-select-next)
(define-key company-active-map (kbd "C-p") 'company-select-previous))
Eglot currently is setup like so
(use-package eglot
:ensure t)
and Elixir’s looks like this:
(use-package elixir-mode
:after (company flycheck)
:ensure t
:init
;;(add-to-list 'exec-path "/Users/napo/Github/elixir-ls/release")
(add-to-list 'eglot-server-programs '(elixir-mode . ("/Users/napo/Github/elixir-ls/release/language_server.sh")))
;;(add-hook 'elixir-mode-hook #'lsp)
(add-hook 'elixir-mode-hook 'eglot-ensure)
(add-hook 'elixir-mode-hook 'flycheck-mode)
(add-hook 'elixir-mode-hook #'smartparens-mode)
(add-hook 'elixir-mode-hook
(lambda () (add-hook 'before-save-hook 'eglot-format nil t))))
1 Like
@thepreacher my emacs.d repo gets constantly rebased with https://github.com/purcell/emacs.d
Other than that, that’s my only company specific custom config:
(add-hook 'after-init-hook 'global-company-mode)
(setq company-dabbrev-downcase 0)
(setq company-idle-delay 0)
As for eglot/elixir, there it is, at the moment:
(require-package 'elixir-mode)
(require-package 'eglot)
(require 'eglot)
(require 'eldoc-box)
(add-to-list
'eglot-server-programs
'(elixir-mode . ("sh" "/Users/rodrigues/code/elixir-ls/release/language_server.sh")))
(add-hook
'elixir-mode-hook
(lambda ()
(subword-mode)
(eglot-ensure)
(company-mode)
(flymake-mode)
(add-hook 'before-save-hook 'eglot-format nil t)))
1 Like
I run into same issue with my Emacs setup, and I was able to solve it.
Based on the github issue I was able to deduce that Eglot upon start communicates to Language Server that he supports snippets, and I would guess, that based on this start-up info it will either try to pass it into snippet engine or not. You could look into your *EGLOT (....) events*
buffer; find first message ( with M-<
), and verify your settings.
client-request (id:1) Fri Jan 31 00:35:47 2020:
(:jsonrpc "2.0" :id 1 :method "initialize" :params
(:processId 14783 :rootPath ....
(:workspace
......
(:dynamicRegistration :json-false :completionItem
(:snippetSupport t)
:contextSupport t)
I was able to achieve such setup by installing Yasnippets, and turning them on in elixir-mode
(use-package elixir-mode)
(use-package eglot
:commands (eglot eglot-ensures)
:hook
(elixir-mode . eglot-ensure)
(before-save . eglot-format-buffer)
:config
(add-to-list
`eglot-server-programs `(elixir-mode ,(expand-file-name "~/elixir_ls/release/language_server.sh"))))
(use-package yasnippet
:hook (elixir-mode . yas-minor-mode))
2 Likes