LFE Language Server implementation
About ↟
LFE language server written in LFE.
I started this project because I wanted to try LFE in a real project and LFE has a bit of a lack of tooling.
It is largely work in progress. The following LSP functionality is implemented:
initialize
request/responseinitialized
notificationtextDocument/didOpen
notification which loads and maintains documents in memory.textDocument/didChange
notification which updates the document in memory. Currently the sync transfers the full document. There is room form optimization here to implement a incremental sync.textDocument/didClose
notification which deletes the document in memory.textDocument/didSave
notificationtextDocument/completion
request/response implements global symbols and loaded modules as well as module functions.textDocument/publishDiagnostics
notification to push compile diagnostics on saving a file.textDocument/hover
request/response that shows module/function documentation
didOpen
and didSave
will compile the source file on the server to provide diagnostics to the client.
However, this does not replace the C-c-k
key sequence to compile the and reload the module in the REPL in order to take the changes into effect.
Planned further support is:
- showing signature support for functions
Auto-completion is rudimentary right now. It completes global symbols/atoms, functions/macros and functions on a module basis by parsing the text and looking for ':' character which indicates completing for a module. There is a lot of room for improvement. I.e.: functions within a module could be parsed from the text, or variables within a let.
To allow Emacs with Eglot (or also lsp-mode) to trigger completion on :
character one has to tweak the lfe-mode to change lfe-mode-syntax-table
and set :
to be a punctuation character. Here is the full function (found in lfe-mode.el):
(defvar lfe-mode-syntax-table
(let ((table (copy-syntax-table lisp-mode-syntax-table)))
;; Like scheme we allow [ ... ] as alternate parentheses.
(modify-syntax-entry ?\[ "(] " table)
(modify-syntax-entry ?\] ")[ " table)
;; ":" character should be used as punctuation to separate symbols
(modify-syntax-entry ?: "." table)
table)
"Syntax table in use in Lisp Flavoured Erlang mode buffers.")
lfe-ls
automatically adds _build/test/lib
as include to the compiler.
So if ltest is added as a test dependency then its includes like:
(include-lib "ltest/include/ltest-macros.lfe")
will automatically be found.
In order to allow lfe-ls to work with a workspace folder it is a must to create a git repository in the folder your are operating. That will Emacs to recognize the folder as a project.
Build ↟
Compile with:
$ rebar3 lfe compile
To create a release do:
$ rebar3 as prod do clean,release,escriptize
An executable can be started as _build/prod/bin/lfe-ls
.
To add lfe-ls as a server in Eglot the following can be added to the Eglot config:
(add-to-list
'eglot-server-programs
'(lfe-mode . ("/path/to/lfe-ls/_build/prod/bin/lfe-ls"
"--transport" "tcp" "--port" :autoport)))
Start the Project REPL ↟
$ rebar3 lfe repl
Starting the repl in this way wilkl automatically start the lfe-ls application and ls server.
Tests ↟
$ rebar3 as test eunit
License ↟
Apache License, Version 2.0
Copyright © 2022, Manfred Bergmann mb@software-by-mabe.com.