Pilgrim

Pilgrim

How is snippet expansion/code completion supposed to work in Emacs with eglot/elixir-ls

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?

Marked As Solved

mpmiszczyk

mpmiszczyk

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))

Also Liked

Pilgrim

Pilgrim

@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))))
rodrigues

rodrigues

@Pilgrim 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)))

Where Next?

Popular in Questions Top

srinivasu
How to handle excepions in elixir? Suppose i have A, B, C ,D, E modules. and each module has get() function. A.get() method will call th...
New
bsollish-terakeet
Credo is smart enough to check for (something like) this: assert length(the_list) == 0 with this response: Checking if an enum is empt...
New
pgiesin
This should be a simple problem but I just can’t seem to figure it out. I have a standalone Elixir app that won’t find the database. Dep...
New
fireproofsocks
I’m working on defining a simple Ecto schema for a table (in PostGres), but I don’t see where I can define a column as NOT NULL. Conside...
New
sacepums
Hey guys. I'm new to elixir and im really stocked about it. But I ran into a bit of problem - I need to convert a date sting, for examp...
New
script
If I have a string “1000 cfu/ml” . I want to remove the characters and / and space . So the string is like this "1000" What is the ...
New
chewm
Hi guys, nice to meet you to the whole forum, I’m new here, I’m trying to configure visual studio code for elixir, right now the intellis...
New
WestKeys
Currently suffering from paralysis by [HTTP client] analysis. This is rather unusual in Elixirland as there tends to be consensus on the ...
New
Exadra37
Sometimes I want to check if the input into a function is not a blank string. My first approach: defmodule Example do def do_stuff(s...
New
lanycrost
Hi everyone! I need implement if…else if…else condition from my elixir code, and anymore of this control flow structures not work proper...
New

Other popular topics Top

sorentwo
Hello! tl;dr Announcing Oban, an Ecto based job processing library with a focus on reliability and historical observability. After spen...
977 41022 311
New
yawaramin
In the Dialyzer docs ( http://erlang.org/doc/man/dialyzer.html#requesting-or-suppressing-warnings-in-source-files ), there is a way to tu...
New
albydarned
Hello all! I am typing this post from my new MacBook Pro with the M1 chip. I’m loving it so far, and will probably use it as my daily dr...
New
New
vac
Hi, I'm quite new in Elixir and I'm trying to format a string to a PEM format. I have the certificate value like MIIDBTCCAe2...... and ...
New
chrismccord
As promised, the first release candidate of Phoenix 1.3.0 is out! This release focuses on code generators with improved project structure...
New
aadeshere1
I have a another noob question about loop. Since elixir is immutable, while loop is not directly possible. total = 10 while total != 0 ...
New
shahryarjb
Hello, I have map which I want to convert it to string like this: the map: %{last_name: "tavakkoli", name: "shahryar"} the string I ne...
New
aesmail
Hello guys, I have finally made it. I created an admin interface for a framework. It’s been on my todo list for years and with the curre...
New
Nvim
Elixir appears to be a superior language to Python. I don’t see any advantage of Python over Elixir. Are there any?
New

We're in Beta

About us Mission Statement