Skip to content

Commit

Permalink
Add initial mkdocs documentation website (#619)
Browse files Browse the repository at this point in the history
* Add initial mkdocs docsite

* Add guide on mkdocs website dev

* Add Mkdocs website deployment stages
  • Loading branch information
Daniils Petrovs authored Nov 21, 2021
1 parent 87b48c6 commit 8d28a85
Show file tree
Hide file tree
Showing 16 changed files with 436 additions and 0 deletions.
19 changes: 19 additions & 0 deletions .github/workflows/release-asset.yml
Original file line number Diff line number Diff line change
Expand Up @@ -85,3 +85,22 @@ jobs:
asset_path: ./elixir-ls.zip
asset_name: elixir-ls.zip
asset_content_type: application/zip

build-docsite:
name: Build Mkdocs website
runs-on: ubuntu-latest
container:
image: squidfunk/mkdocs-material
steps:
- name: Build
run: mkdocs build -s

publish-docsite:
name: Publish Mkdocs website to GH Pages
runs-on: ubuntu-latest
steps:
- name: Publish
uses: JamesIves/[email protected]
with:
branch: mkdocs
folder: site
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,6 @@ erl_crash.dump
# But many contributors will use their own to specify their own minimum
# supported version
.tool-versions

# Mkdocs static website build directory
/site
20 changes: 20 additions & 0 deletions DEVELOPMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,23 @@ Publish the draft release
If you're debugging a running server than `IO.inspect` is a good approach, any messages you create with it will be sent to your LSP client as a log message

To debug in tests you can use `IO.inspect(Process.whereis(:user), message, label: "message")` to send your output directly to the group leader of the test process.

# Documentation website

The documentation website is built using the [Mkdocs](https://www.mkdocs.org) static website generator. The content is written in Markdown format in the directory [docs](./docs) and is configured via the [mkdocs.yml](./mkdocs.yml) file.

## Development

Make sure you have a recent version of Python 3 and [Pip](https://pip.readthedocs.io/en/stable/installing/) installed.

Install `mkdocs` and the `material` theme with Pip:

```shell
pip install mkdocs mkdocs-material
```

Once installed, simply run `mkdocs serve` from the project root. This will start a local web server with a file watcher.

## Build

To compile the website for deployment, run `mkdocs build` from the project root. The built static assets will be located in the `site` directory. These can then be served by any web hosting solution.
57 changes: 57 additions & 0 deletions docs/features.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# Features

- Debugger support
- Automatic, incremental Dialyzer analysis
- Automatic inline suggestion of @specs based on Dialyzer's inferred success typings
- Inline reporting of build warnings and errors
- Documentation lookup on hover
- Go-to-definition
- Code completion
- Code formatter
- Find references to functions and modules (Thanks to @mattbaker)
- Quick symbol lookup in file (Thanks to @mattbaker)
- Quick symbol lookup in workspace and stdlib (both Elixir and erlang) (@lukaszsamson)

## Automatic builds and error reporting

Builds are performed automatically when files are saved. If you want this to happen automatically when you type, you can turn on "autosave" in your IDE.

Starting in Elixir 1.6, Mix compilers adhere to the [Mix.Task.Compiler](https://hexdocs.pm/mix/master/Mix.Task.Compiler.html) behaviour and return their error and warning diagnostics in a standardized way. Errors and warnings will be shown inline in your code as well as in the "Problems" pane in the IDE. If you're using an earlier version of Elixir, you'll need to look at the text log from the extension to see the errors and warnings.

## Dialyzer integration

ElixirLS will automatically analyze your project with [Dialyzer](http://erlang.org/doc/apps/dialyzer/dialyzer_chapter.html) after each successful build. It maintains a "manifest" file in `.elixir_ls/dialyzer_manifest` that stores the results of the analysis. The initial analysis for a project can take a few minutes, but after that's completed, modules are re-analyzed only if necessary, so subsequent analyses are typically very fast -- often less than a second. It also looks at your modules' abstract code to determine whether they reference any modules that haven't been analyzed and includes them automatically.

You can control which warnings are shown using the `elixirLS.dialyzerWarnOpts` setting in your project or IDE's `settings.json`. Find available options in Erlang [docs](http://erlang.org/doc/man/dialyzer.html) at section "Warning options".

To disable Dialyzer completely, set `elixirLS.dialyzerEnabled` to false.

Check usage details in Dialyxir docs on [GitHub](https://github.com/jeremyjh/dialyxir#usage) and [hexdocs](https://hexdocs.pm/dialyxir/readme.html).

ElixirLS's Dialyzer integration uses internal, undocumented Dialyzer APIs, and so it won't be robust against changes to these APIs in future Erlang versions.

## Code completion

ElixirLS bundles an advanced code completion provider. The provider builds on [Elixir Sense](https://github.com/elixir-lsp/elixir_sense) library and utilizes two main mechanisms. The first one is reflection - getting information about compiled modules from Erlang and Elixir APIs. The second one is AST analysis of the current text buffer. While reflection gives precise results, it is not well suited for on demand completion of symbols from the currently edited file. The compiled version is likely to be outdated or the file may not compile at all. AST analysis helps in that case but it has its limitations. Unfortunately it is infeasible to be 100% accurate, especially with Elixir being a metaprogramming heavy language.

The completions include:

- keywords
- special form snippets
- functions
- macros
- modules
- variables
- struct fields (only if the struct type is explicitly stated or can be inferred from the variable binding)
- atom map keys (if map keys can be inferred from variable binding)
- attributes
- types (in typespecs)
- behaviour callbacks (inside the body of implementing module)
- protocol functions (inside the body of implementing module)
- keys in keyword functions arguments (if defined in spec)
- function returns (if defined in spec)

## Workspace Symbols

With Dialyzer integration enabled ElixirLS will build an index of symbols (modules, functions, types and callbacks). The symbols are taken from the current workspace, all dependencies and stdlib (Elixir and erlang). This feature enables quick navigation to symbol definitions.

99 changes: 99 additions & 0 deletions docs/getting-started/emacs.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
# Emacs

## Setup

Download the latest release:
`https://github.com/elixir-lsp/elixir-ls/releases/latest` and unzip it into a
directory (this is the directory referred to as the
`"path-to-elixir-ls/release"` below)

If using `lsp-mode` add this configuration:
```elisp
(use-package lsp-mode
:commands lsp
:ensure t
:diminish lsp-mode
:hook
(elixir-mode . lsp)
:init
(add-to-list 'exec-path "path-to-elixir-ls/release"))
```

For `eglot` users:
```elisp
(require 'eglot)
;; This is optional. It automatically runs `M-x eglot` for you whenever you are in `elixir-mode`
(add-hook 'elixir-mode-hook 'eglot-ensure)
;; Make sure to edit the path appropriately, use the .bat script instead for Windows
(add-to-list 'eglot-server-programs '(elixir-mode "path-to-elixir-ls/release/language_server.sh"))
```

The official `lsp-mode` package includes a client for the Elixir
Language Server.

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](https://emacs-lsp.github.io/lsp-mode/).

Remember that ElixirLS requires **Erlang/OTP 22** and **Elixir 1.10.0** or
higher to run, so ensure that Erlang and Elixir are available in your `PATH`.
This can be achieved, for example, by using the
[exec-path-from-shell](https://github.com/purcell/exec-path-from-shell)
Emacs package.

## Restarting the language server

You may want to quickly restart the language server for a given
workspace (e.g. after an update or in case of a server crash). To do
so:

```
M-x lsp-workspace-restart
```

## Troubleshooting

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 ElixirLS Emacs setup.

Also, ensure that Erlang, Elixir (i.e. `erl`, `escript` and friends) and the
`language_server.sh` script are all available in your `PATH`. If they are
not, you can try the following:

```elisp
;; 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:

```elisp
(setq lsp-log-io t)
```

You can then follow the client logs for the current workspace by doing:

```
M-x lsp-workspace-show-log
```

## Tips and Tricks

### Shortcuts for code lenses and quick actions

You can run `M-x lsp-avy-lens` to show _letters_ next to code
lenses. You can then press those letters to trigger the respective
action.

If your `sideline` is enabled (`(setq lsp-ui-sideline-enable t)`), you
can also use `M-x lsp-execute-code-action` to trigger quick-fix
actions.
38 changes: 38 additions & 0 deletions docs/getting-started/kakoune.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Kakoune

## Setup

Install the [kak-lsp](https://github.com/kak-lsp/kak-lsp) client for the [Kakoune](http://kakoune.org) editor.

## Limitations

### Encoding

kak-lsp works only with UTF-8 documents.

### `Position.character` interpretation

Currently, kak-lsp doesn't conform to the spec regarding the interpretation of `Position.character`.
LSP spec says that

____
A position inside a document (see Position definition below) is expressed as a zero-based line and
character offset. The offsets are based on a UTF-16 string representation. So for a string of the
form `a𐐀b` the character offset of the character `a` is 0, the character offset of `𐐀` is
1 and the character offset of `b` is 3 since `𐐀` is represented using two code units in UTF-16.
____

However, kak-lsp treats `Position.character` as an offset in UTF-8 code points by default.
Fortunately, it appears to produce the same result within the Basic Multilingual Plane (BMP) which
includes a lot of characters.

Unfortunately, many language servers violate the spec as well, and in an inconsistent manner. Please
refer https://github.com/Microsoft/language-server-protocol/issues/376 for more information. There
are two main types of violations we met in the wild:

1) Using UTF-8 code points, just like kak-lsp does. Those should work well with kak-lsp for
characters outside BMP out of the box.

2) Using UTF-8 code units (bytes), just like Kakoune does. Those are supported by kak-lsp but
require adding `offset_encoding = "utf-8"` to the language server configuration in `kak-lsp.toml`.

5 changes: 5 additions & 0 deletions docs/getting-started/kate.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Kate

## Setup

Use the built-in [LSP client for Kate.](https://kate-editor.org/post/2020/2020-01-01-kate-lsp-client-status/)
11 changes: 11 additions & 0 deletions docs/getting-started/neovim.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Setup

There are several plugins available for NeoVim:

| Plugin | Notes |
|:--|:--|
| [coc.nvim](https://github.com/neoclide/coc.nvim) | Does not support debugger |
| [nvim-dap](https://github.com/mfussenegger/nvim-dap) | Only debugger |
| [ALE](https://github.com/w0rp/ale) | Does not support debugger or typespec suggestions |
| [elixir-lsp/coc-elixir](https://github.com/elixir-lsp/coc-elixir) | Does not support debugger |
| [vim-lsp](https://github.com/prabirshrestha/vim-lsp) | Does not support debugger |
5 changes: 5 additions & 0 deletions docs/getting-started/nova.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Nova

## Setup

Install the [extension for Nova](https://github.com/raulchedrese/nova-elixir-ls).
20 changes: 20 additions & 0 deletions docs/getting-started/overview.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Getting Started

The Erlang LS language server works with all text editors and IDEs
which adhere to the _LSP_ protocol. The list of supported editors
include _Emacs_, _Vim_, _VS Code_, _Sublime Text 3_ and more.

These pages contain all the information needed to configure your
favourite text editor or IDE to use ErlangLS. You will also find
instructions on how to configure the server to recognize the structure
of your projects and to troubleshoot your installation when things do
not work as expected.

* [Emacs](emacs.md)
* [Kakoune](kakoune.md)
* [Kate](kate.md)
* [Neovim](neovim.md)
* [Nova](nova.md)
* [Sublime Text 3](sublime.md)
* [VS Code](vscode.md)

7 changes: 7 additions & 0 deletions docs/getting-started/sublime.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Sublime

## Setup

Install the extension [LSP-Elixir](https://github.com/sublimelsp/LSP-elixir).

Note that it does not have debugger support.
66 changes: 66 additions & 0 deletions docs/getting-started/vscode.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# Emacs

## Setup

Install the official [ElixirLS extension](https://github.com/elixir-lsp/vscode-elixir-ls) and enable it.

## Debugger

ElixirLS includes debugger support adhering to the [VS Code debugger protocol](https://code.visualstudio.com/docs/extensionAPI/api-debugging) which is closely related to the Language Server Protocol. At the moment, only line breakpoints are supported.

When debugging in Elixir or Erlang, only modules that have been "interpreted" (using `:int.ni/1` or `:int.i/1`) will accept breakpoints or show up in stack traces. The debugger in ElixirLS automatically interprets all modules in the Mix project and dependencies prior to launching the Mix task, so you can set breakpoints anywhere in your project or dependency modules.

In order to debug modules in `.exs` files (such as tests), they must be specified under `requireFiles` in your launch configuration so they can be loaded and interpreted prior to running the task. For example, the default launch configuration for "mix test" in the VS Code plugin looks like this:

```json
{
"type": "mix_task",
"name": "mix test",
"request": "launch",
"task": "test",
"taskArgs": ["--trace"],
"projectDir": "${workspaceRoot}",
"requireFiles": [
"test/**/test_helper.exs",
"test/**/*_test.exs"
]
}
```

In order to debug a single test or a single test file it is currently necessary to modify `taskArgs` and make sure no other tests are required in `requireFiles`.

```json
{
"type": "mix_task",
"name": "mix test",
"request": "launch",
"task": "test",
"taskArgs": ["tests/some_test.exs:123"],
"projectDir": "${workspaceRoot}",
"requireFiles": [
"test/**/test_helper.exs",
"test/some_test.exs"
]
}
```

Please note that due to `:int` limitation NIF modules cannot be interpreted and need to be excluded via `excludeModules` option. This option can be also used to disable interpreting for some modules when it is not desirable e.g. when performance is not satisfactory.

```json
{
"type": "mix_task",
"name": "mix test",
"request": "launch",
"task": "test",
"taskArgs": ["--trace"],
"projectDir": "${workspaceRoot}",
"requireFiles": [
"test/**/test_helper.exs",
"test/**/*_test.exs"
],
"excludeModules": [
":some_nif",
"Some.SlowModule"
]
}
```
21 changes: 21 additions & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Welcome to ElixirLS

Implementing features such as _auto-complete_ or _go-to-definition_
for a programming language is not trivial. Traditionally, this work
had to be repeated for each development tool and it required a mix of
expertise in both the targeted programming language and the
programming language internally used by the development tool of
choice.

The [Elixir Language Server][git] (ElixirLS) provides a server that runs in the background, providing IDEs, editors, and other tools with information about Elixir Mix projects. It adheres to the _LSP_, a standard for frontend-independent IDE support. Debugger integration is accomplished through the similar VS Code Debug Protocol.

These pages contain all the information needed to configure your
favourite text editor or IDE and to work with the ElixirLS. You will also
find instructions on how to configure the server to recognize the
structure of your projects and to troubleshoot your installation when
things do not work as expected.

[git]:https://github.com/elixir-lsp/elixir-ls
[lsp]:https://microsoft.github.io/language-server-protocol/
[elixir]:https://www.elixir-lang.org
[issue]:https://github.com/elixir-lsp/elixir-ls/issues
Loading

0 comments on commit 8d28a85

Please sign in to comment.