An Erlang server implementing Microsoft's Language Server Protocol 3.15.
Get context-aware code completions for function names, macros, records, variable names and more.
Navigate to the definition of a function, macro, record or type.
Hovering a gen_server:start_link
call? Jump to the respective init
function with a single keystroke.
Never remember the order of the lists:keytake/3
arguments? You are
not alone. We got you covered.
Display warnings and errors from the compiler. Inline.
It has never been so easy to make Dialyzer happy.
Display Elvis style suggestions inline. No more nit-picking comments from colleagues!
Hover a local or remote function to see its edoc
. You will miss this
feature so much when edocs are not available that you will start
writing them!
Navigate to included files with a single click.
Who is calling this function? Figure it out without leaving the current context.
Get a nice outline of your module on the side and jump between functions.
Jump to the module you're looking for, in no time.
Focus on what's important, fold the rest.
- Erlang OTP 21+
- rebar3 3.9.1+
Compile the project:
make
These are the command-line arguments that can be provided to the
erlang_ls
escript:
Argument | Description |
---|---|
--transport tcp / stdio | Specifies the transport the server will use for the connection with the client (default: tcp ) |
--port PORT | Used when the transport is tcp (default: 10000 ) |
--log-dir DIR | Directory where logs will be written. When not provided no logs are generated. |
The official lsp-mode
package includes a client for the Erlang
Language Server.
Here you can find a sample Emacs configuration file which installs and configures all packages required to get all of the Erlang LS features working. Use this configuration file as a starting point for your Erlang LS Emacs configuration.
Whenever opening a project for the first time, you will be prompted by
emacs-lsp
to select the correct project root. In that occasion, you
also have the opportunity to blacklist projects. Information about
projects is stored in a file pointed by the lsp-session-file
variable. Its default location is ~/.emacs.d/.lsp-session-v1
. You
may need to prune or amend this file if you change your mind about
blacklisting a project or if you erroneously select a project
root. For more information about the lsp-session-file
and
emacs-lsp
in general, please refer to the official
documentation.
Remember that the Erlang Language Server requires Erlang/OTP 21 or
higher to run, so ensure that OTP 21+ is available in your PATH
.
This can be achieved, for example, by using the
exec-path-from-shell
Emacs package.
If things do not work as expected, we advise you to start Emacs with only the configuration from the provided sample file, using the following command:
emacs -q -l [PATH-TO-ERLANG-LS]/misc/dotemacs
This will remove from the equation potential incompatibilities with other packages or configurations that you may have on your workstation and that could conflict with Erlang LS.
To be sure that you don't have outdated or incompatible packages
installed, you may also want to rename your ~/.emacs.d
directory
while you are troubleshooting your Erlang LS Emacs setup.
Also, ensure that Erlang (i.e. erl
, escript
and friends) and the
erlang_ls
executable are all available in your PATH
. If they are
not, you can try the following:
;; Ensure your Emacs environment looks like your user's shell one
(package-require 'exec-path-from-shell)
(exec-path-from-shell-initialize)
Finally, to enable logging on the client-side, just:
(setq lsp-log-io t)
The Erlang Language Server is available in VSCode via a dedicated extension.
To try it out, simply open VSCode and install the extension via the Marketplace:
Preferences > Extensions
Look for the erlang-ls
extension and install it. That's it.
Remember that the Erlang Language Server requires Erlang/OTP 21 or
higher to run, so ensure that OTP 21+ is available in your PATH
.
It is possible to use Erlang LS in Theia IDE by including Erlang/OTP in your running instance and installing the VSCode extension.
If you want to give it a try by using GitPod click
here.
To use this same setup with your Erlang project (hosted in GitHub or
Gitlab) you can find the GitPod configuration in
.gitpod.yml
.
Using the Command Palette, select Package Control: Install Package
and install the LSP
package.
After that is done, go to:
Preferences -> Package Settings -> LSP -> Settings
Add an Erlang client by adding the following configuration to the
LSP.sublime-settings - User
file:
{
"clients":
{
"erlang-ls":
{
"command" : [ "/path/to/my/erlang_ls", "--transport", "stdio" ],
"enabled" : true,
"languageId": "erlang",
"scopes" : [ "source.erlang" ],
"syntaxes" : ["Packages/Erlang/Erlang.sublime-syntax"]
}
}
}
That's it. Open a new Erlang project and enjoy Erlang LS.
In case of issues, you can enable extra logging for the LSP
package
by adding the following configuration to your LSP.sublime-settings - User
file:
{
// Show verbose debug messages in the sublime console.
"log_debug": true,
// Show messages from language servers in the Language Servers output
// panel.
"log_server": true,
// Show language server stderr output in the Language Servers output
// panel.
"log_stderr": true,
// Show full JSON-RPC requests/responses/notifications in the Language
// Servers output panel.
"log_payloads": true
}
The Sublime console can be toggled using the Ctrl-`
shortcut. The
output panel can be toggled from the command palette with the command
LSP: Toggle Panel: Language Servers
.
WARNING: The current version of the IntelliJ LSP plugin (1.5.4) is quite limited, so not all of the Erlang Language Server capabilities are available in IntelliJ.
First of all, ensure you have the LSP Support plugin installed. If you don't, you can simply navigate to:
Preferences > Plugins > Browse Repositories
Search for "LSP Support" and install the respective plugin.
Restart IntelliJ, then navigate to:
Preferences > Languages and Frameworks > Language Server Protocol > Server Definitions
There you can instruct IntelliJ on how to start the server. Select
Raw Command
, set erl;hrl
as the extension, then add as the
command:
/ABSOLUTE/PATH/TO/erlang_ls/_build/debug/bin/erlang_ls --transport stdio
Ensure you use an absolute path. The plugin does not seem to
understand the ~
symbol. For the above command to work, IntelliJ
requires the PATH
variable to be correctly configured to include
Erlang 20+. To circumvent this issues on Mac OS, the best way is to
start IntelliJ from the terminal (i.e. via the idea
command) and not
via Spotlight.
To visualize documentation and type specs while hovering a function, ensure the Show quick documentation on mouse move option is enabled in your IntelliJ preferences:
Preferences > Editor > General
There, you can also set a delay in milliseconds.
For more information about how to configure the IntelliJ LSP Client, please refer to the project GitHub page.
In some cases, the IntelliJ LSP client may not be able to connect to the server. In such cases, the first step is to enable logging:
Preferences > Languages and Frameworks > Language Server Protocol
Check the Log servers communications check-box there.
After restarting IntelliJ, you will notice an extra lsp
directory
created inside your Erlang project. This directory contains the
error
and output
logs, which should give you a hint about what is
going on.
An alternative source of information is represented by the IntelliJ logs:
Help > Show Logs
Note: While these instructions are for NeoVim, they should be transferable to Vim.
For vim-plug users, install
Coc and its plugin
coc-erlang_ls by entering the
following in your init.vim
or .vimrc
plugin section:
" Use release branch (Recommend)
Plug 'neoclide/coc.nvim', {'branch': 'release'}
Plug 'hyhugh/coc-erlang_ls', {'do': 'yarn install --frozen-lockfile'}
You should ensure your yarn
has frozen-lockfile support (current version
distributed by brew
does not). Then restart vim and run :PlugInstall
. If
the erlang_ls server is running, and you have configured the CoC
plugin, then when vim starts
you should see the message that Coc has connected to it:
[coc.nvim] coc-erlang_ls is ready
For suggestions on configuring Coc see its example configuration documentation.
This section summarizes the functionalities currently implemented by
the erlang_ls
server.
Code navigation is currently available for the following elements:
- Function applications (both local and remote)
- BIFs
- Behaviour attributes
- Included files
- Type definitions
- Record definitions
- Macro definitions
- Export list entries
- Import list entries
Completion requests are sent from the client to the server to compute completion items at a given cursor position. Completion items are presented to the user for easy selection.
Code completion are currently triggered by the following characters:
:
, ?
.
Code completion is available for the following elements:
- Exported functions
It is possible to customize the behaviour of the erlang_ls
server
via a configuration file, named erlang_ls.config
. The
erlang_ls.config
file should be placed in the root directory of a
given project to store the configuration for that project.
It is also possible to store a system-wide default configuration in an
erlang_ls.config
file located in the User Config directory. The
exact location of the User Config directory depends on the operating
system used and it can be identified by executing the following
command on an Erlang shell:
> filename:basedir(user_config, "erlang_ls").
Normally, the location of the User Config directory is:
Operating System | User Config Directory |
---|---|
Linux | /home/USER/.config/erlang_ls |
OS X | /Users/USER/Library/Application\ Support/erlang_ls |
Windows | c:/Users/USER/AppData/Local/erlang_ls |
A sample erlang_ls.config
file would look like the following:
otp_path: "/path/to/otp/lib/erlang"
deps_dirs:
- "lib/*"
include_dirs:
- "include"
- "_build/default/lib"
macros:
- name: DEFINED_WITH_VALUE
value: 42
- name: DEFINED_WITHOUT_VALUE
code_reload:
node: node@example
The file format is yaml
.
The following customizations are possible:
Parameter | Description |
---|---|
otp_path | Path to the OTP installation |
plt_path | Path to the dialyzer PLT file. When none is provided the dialyzer diagnostics will not be available. |
deps_dirs | List of directories containing dependencies. It supports wildcards. |
apps_dirs | List of directories containing project applications. It supports wildcards. |
include_dirs | List of directories provided to the compiler as include dirs. It supports wildcards. |
macros | List of cusom macros to be passed to the compiler, expressed as a name/value pair. If the value is omitted or is invalid, 'true' is used. |
otp_apps_exclude | List of OTP applications that will not be indexed (default: megaco, diameter, snmp, wx) |
code_reload | Whether or not an rpc call should be made to a remote node to compile and reload a module |
The code_reload
takes the following options:
Parameter | Description |
---|---|
node | The node to be called for code reloading. Example erlang_ls@hostname |
It is possible to compile and start the language server in debug mode:
rebar3 as debug escriptize
Ensure you update your PATH
to include the new executable which now
resides in:
/path/to/erlang_ls/_build/debug/bin/erlang_ls
Once an instance of the server is running, find the name of the node in
the logs or by running epmd -names
. It will look something like:
$ epmd -names
epmd: up and running on port 4369 with data:
name erlang_ls_62880311918 at port 50819
And you can connect to it via:
erl -sname debug -remsh erlang_ls_62880311918@`HOSTNAME`
The redbug application is included in debug mode, so feel free to use it.
The erlang_ls
language server uses
Mnesia to persist
information. A new database is created and maintained for each
project/OTP pair. Databases are stored in the application cache
directory, which varies according to the operating system used.
Generally speaking, the directory should be:
Operating System | Database Dir |
---|---|
Linux | /home/USER/.cache/erlang_ls |
OS X | /Users/USER/Library/Caches/erlang_ls |
Windows | c:/Users/USER/AppData/Local/erlang_ls/Cache |
You can also run the following command on an Erlang shell to identify the Database Directory on your system:
> filename:basedir(user_cache, "erlang_ls").
When the escript is built using the debug
profile as above, logging
will be enabled and the logs will be written to your platform's log
directory (i.e. the return value from filename:basedir(user_log, "erlang_ls")
), in a file named server.log
.
It's possible to customize the logging directory by using the
--log-dir
option when starting the server.
It's also possible to specify the verbosity of the logs by using the
--log-level
option. In addition to the notice
, debug
, info
,
warning
and error
levels, syslog style loglevel comparison
flags
can also be used.
When the escript
is built in the default
mode (i.e. rebar3 escript
),
no log files are generated, unless the --log-dir
option is provided.
If you have any questions about the project, feel free to open a new
issue. You can also join the #language-server
channel in the
Erlanger Slack if you would like to get involved or if you prefer a
more informal mean of communication.
All contributions are welcome, be them in the form of a bug report, a question, feedback, or code.
A wiki is also available and I occasionally blog about the project on Medium.
https://microsoft.github.io/language-server-protocol/
The erlang_ls
project is licensed under the Apache License 2.0. Please refer
to the LICENSE
file for details.