mirror of https://github.com/helix-editor/helix
Merge branch 'master' into issue-2719
commit
ab57115567
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,164 @@
|
|||||||
|
## Building from source
|
||||||
|
|
||||||
|
- [Configuring Helix's runtime files](#configuring-helixs-runtime-files)
|
||||||
|
- [Linux and macOS](#linux-and-macos)
|
||||||
|
- [Windows](#windows)
|
||||||
|
- [Multiple runtime directories](#multiple-runtime-directories)
|
||||||
|
- [Note to packagers](#note-to-packagers)
|
||||||
|
- [Validating the installation](#validating-the-installation)
|
||||||
|
- [Configure the desktop shortcut](#configure-the-desktop-shortcut)
|
||||||
|
|
||||||
|
Requirements:
|
||||||
|
|
||||||
|
Clone the Helix GitHub repository into a directory of your choice. The
|
||||||
|
examples in this documentation assume installation into either `~/src/` on
|
||||||
|
Linux and macOS, or `%userprofile%\src\` on Windows.
|
||||||
|
|
||||||
|
- The [Rust toolchain](https://www.rust-lang.org/tools/install)
|
||||||
|
- The [Git version control system](https://git-scm.com/)
|
||||||
|
- A C++14 compatible compiler to build the tree-sitter grammars, for example GCC or Clang
|
||||||
|
|
||||||
|
If you are using the `musl-libc` standard library instead of `glibc` the following environment variable must be set during the build to ensure tree-sitter grammars can be loaded correctly:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
RUSTFLAGS="-C target-feature=-crt-static"
|
||||||
|
```
|
||||||
|
|
||||||
|
1. Clone the repository:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
git clone https://github.com/helix-editor/helix
|
||||||
|
cd helix
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Compile from source:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
cargo install --path helix-term --locked
|
||||||
|
```
|
||||||
|
|
||||||
|
This command will create the `hx` executable and construct the tree-sitter
|
||||||
|
grammars in the local `runtime` folder.
|
||||||
|
|
||||||
|
> 💡 If you do not want to fetch or build grammars, set an environment variable `HELIX_DISABLE_AUTO_GRAMMAR_BUILD`
|
||||||
|
|
||||||
|
> 💡 Tree-sitter grammars can be fetched and compiled if not pre-packaged. Fetch
|
||||||
|
> grammars with `hx --grammar fetch` and compile them with
|
||||||
|
> `hx --grammar build`. This will install them in
|
||||||
|
> the `runtime` directory within the user's helix config directory (more
|
||||||
|
> [details below](#multiple-runtime-directories)).
|
||||||
|
|
||||||
|
### Configuring Helix's runtime files
|
||||||
|
|
||||||
|
#### Linux and macOS
|
||||||
|
|
||||||
|
The **runtime** directory is one below the Helix source, so either export a
|
||||||
|
`HELIX_RUNTIME` environment variable to point to that directory and add it to
|
||||||
|
your `~/.bashrc` or equivalent:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
export HELIX_RUNTIME=~/src/helix/runtime
|
||||||
|
```
|
||||||
|
|
||||||
|
Or, create a symbolic link:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
ln -Ts $PWD/runtime ~/.config/helix/runtime
|
||||||
|
```
|
||||||
|
|
||||||
|
If the above command fails to create a symbolic link because the file exists either move `~/.config/helix/runtime` to a new location or delete it, then run the symlink command above again.
|
||||||
|
|
||||||
|
#### Windows
|
||||||
|
|
||||||
|
Either set the `HELIX_RUNTIME` environment variable to point to the runtime files using the Windows setting (search for
|
||||||
|
`Edit environment variables for your account`) or use the `setx` command in
|
||||||
|
Cmd:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
setx HELIX_RUNTIME "%userprofile%\source\repos\helix\runtime"
|
||||||
|
```
|
||||||
|
|
||||||
|
> 💡 `%userprofile%` resolves to your user directory like
|
||||||
|
> `C:\Users\Your-Name\` for example.
|
||||||
|
|
||||||
|
Or, create a symlink in `%appdata%\helix\` that links to the source code directory:
|
||||||
|
|
||||||
|
| Method | Command |
|
||||||
|
| ---------- | -------------------------------------------------------------------------------------- |
|
||||||
|
| PowerShell | `New-Item -ItemType Junction -Target "runtime" -Path "$Env:AppData\helix\runtime"` |
|
||||||
|
| Cmd | `cd %appdata%\helix` <br/> `mklink /D runtime "%userprofile%\src\helix\runtime"` |
|
||||||
|
|
||||||
|
> 💡 On Windows, creating a symbolic link may require running PowerShell or
|
||||||
|
> Cmd as an administrator.
|
||||||
|
|
||||||
|
#### Multiple runtime directories
|
||||||
|
|
||||||
|
When Helix finds multiple runtime directories it will search through them for files in the
|
||||||
|
following order:
|
||||||
|
|
||||||
|
1. `runtime/` sibling directory to `$CARGO_MANIFEST_DIR` directory (this is intended for
|
||||||
|
developing and testing helix only).
|
||||||
|
2. `runtime/` subdirectory of OS-dependent helix user config directory.
|
||||||
|
3. `$HELIX_RUNTIME`
|
||||||
|
4. Distribution-specific fallback directory (set at compile time—not run time—
|
||||||
|
with the `HELIX_DEFAULT_RUNTIME` environment variable)
|
||||||
|
5. `runtime/` subdirectory of path to Helix executable.
|
||||||
|
|
||||||
|
This order also sets the priority for selecting which file will be used if multiple runtime
|
||||||
|
directories have files with the same name.
|
||||||
|
|
||||||
|
#### Note to packagers
|
||||||
|
|
||||||
|
If you are making a package of Helix for end users, to provide a good out of
|
||||||
|
the box experience, you should set the `HELIX_DEFAULT_RUNTIME` environment
|
||||||
|
variable at build time (before invoking `cargo build`) to a directory which
|
||||||
|
will store the final runtime files after installation. For example, say you want
|
||||||
|
to package the runtime into `/usr/lib/helix/runtime`. The rough steps a build
|
||||||
|
script could follow are:
|
||||||
|
|
||||||
|
1. `export HELIX_DEFAULT_RUNTIME=/usr/lib/helix/runtime`
|
||||||
|
1. `cargo build --profile opt --locked --path helix-term`
|
||||||
|
1. `cp -r runtime $BUILD_DIR/usr/lib/helix/`
|
||||||
|
1. `cp target/opt/hx $BUILD_DIR/usr/bin/hx`
|
||||||
|
|
||||||
|
This way the resulting `hx` binary will always look for its runtime directory in
|
||||||
|
`/usr/lib/helix/runtime` if the user has no custom runtime in `~/.config/helix`
|
||||||
|
or `HELIX_RUNTIME`.
|
||||||
|
|
||||||
|
### Validating the installation
|
||||||
|
|
||||||
|
To make sure everything is set up as expected you should run the Helix health
|
||||||
|
check:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
hx --health
|
||||||
|
```
|
||||||
|
|
||||||
|
For more information on the health check results refer to
|
||||||
|
[Health check](https://github.com/helix-editor/helix/wiki/Healthcheck).
|
||||||
|
|
||||||
|
### Configure the desktop shortcut
|
||||||
|
|
||||||
|
If your desktop environment supports the
|
||||||
|
[XDG desktop menu](https://specifications.freedesktop.org/menu-spec/menu-spec-latest.html)
|
||||||
|
you can configure Helix to show up in the application menu by copying the
|
||||||
|
provided `.desktop` and icon files to their correct folders:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
cp contrib/Helix.desktop ~/.local/share/applications
|
||||||
|
cp contrib/helix.png ~/.icons # or ~/.local/share/icons
|
||||||
|
```
|
||||||
|
It is recommended to convert the links in the `.desktop` file to absolute paths to avoid potential problems:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
sed -i -e "s|Exec=hx %F|Exec=$(readlink -f ~/.cargo/bin/hx) %F|g" \
|
||||||
|
-e "s|Icon=helix|Icon=$(readlink -f ~/.icons/helix.png)|g" ~/.local/share/applications/Helix.desktop
|
||||||
|
```
|
||||||
|
|
||||||
|
To use another terminal than the system default, you can modify the `.desktop`
|
||||||
|
file. For example, to use `kitty`:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
sed -i "s|Exec=hx %F|Exec=kitty hx %F|g" ~/.local/share/applications/Helix.desktop
|
||||||
|
sed -i "s|Terminal=true|Terminal=false|g" ~/.local/share/applications/Helix.desktop
|
||||||
|
```
|
@ -0,0 +1,435 @@
|
|||||||
|
## Editor
|
||||||
|
|
||||||
|
- [`[editor]` Section](#editor-section)
|
||||||
|
- [`[editor.statusline]` Section](#editorstatusline-section)
|
||||||
|
- [`[editor.lsp]` Section](#editorlsp-section)
|
||||||
|
- [`[editor.cursor-shape]` Section](#editorcursor-shape-section)
|
||||||
|
- [`[editor.file-picker]` Section](#editorfile-picker-section)
|
||||||
|
- [`[editor.auto-pairs]` Section](#editorauto-pairs-section)
|
||||||
|
- [`[editor.search]` Section](#editorsearch-section)
|
||||||
|
- [`[editor.whitespace]` Section](#editorwhitespace-section)
|
||||||
|
- [`[editor.indent-guides]` Section](#editorindent-guides-section)
|
||||||
|
- [`[editor.gutters]` Section](#editorgutters-section)
|
||||||
|
- [`[editor.gutters.line-numbers]` Section](#editorguttersline-numbers-section)
|
||||||
|
- [`[editor.gutters.diagnostics]` Section](#editorguttersdiagnostics-section)
|
||||||
|
- [`[editor.gutters.diff]` Section](#editorguttersdiff-section)
|
||||||
|
- [`[editor.gutters.spacer]` Section](#editorguttersspacer-section)
|
||||||
|
- [`[editor.soft-wrap]` Section](#editorsoft-wrap-section)
|
||||||
|
- [`[editor.smart-tab]` Section](#editorsmart-tab-section)
|
||||||
|
- [`[editor.inline-diagnostics]` Section](#editorinline-diagnostics-section)
|
||||||
|
|
||||||
|
### `[editor]` Section
|
||||||
|
|
||||||
|
| Key | Description | Default |
|
||||||
|
|--|--|---------|
|
||||||
|
| `scrolloff` | Number of lines of padding around the edge of the screen when scrolling | `5` |
|
||||||
|
| `mouse` | Enable mouse mode | `true` |
|
||||||
|
| `middle-click-paste` | Middle click paste support | `true` |
|
||||||
|
| `scroll-lines` | Number of lines to scroll per scroll wheel step | `3` |
|
||||||
|
| `shell` | Shell to use when running external commands | Unix: `["sh", "-c"]`<br/>Windows: `["cmd", "/C"]` |
|
||||||
|
| `line-number` | Line number display: `absolute` simply shows each line's number, while `relative` shows the distance from the current line. When unfocused or in insert mode, `relative` will still show absolute line numbers | `absolute` |
|
||||||
|
| `cursorline` | Highlight all lines with a cursor | `false` |
|
||||||
|
| `cursorcolumn` | Highlight all columns with a cursor | `false` |
|
||||||
|
| `gutters` | Gutters to display: Available are `diagnostics` and `diff` and `line-numbers` and `spacer`, note that `diagnostics` also includes other features like breakpoints, 1-width padding will be inserted if gutters is non-empty | `["diagnostics", "spacer", "line-numbers", "spacer", "diff"]` |
|
||||||
|
| `auto-completion` | Enable automatic pop up of auto-completion | `true` |
|
||||||
|
| `auto-format` | Enable automatic formatting on save | `true` |
|
||||||
|
| `idle-timeout` | Time in milliseconds since last keypress before idle timers trigger. | `250` |
|
||||||
|
| `completion-timeout` | Time in milliseconds after typing a word character before completions are shown, set to 5 for instant. | `250` |
|
||||||
|
| `preview-completion-insert` | Whether to apply completion item instantly when selected | `true` |
|
||||||
|
| `completion-trigger-len` | The min-length of word under cursor to trigger autocompletion | `2` |
|
||||||
|
| `completion-replace` | Set to `true` to make completions always replace the entire word and not just the part before the cursor | `false` |
|
||||||
|
| `auto-info` | Whether to display info boxes | `true` |
|
||||||
|
| `true-color` | Set to `true` to override automatic detection of terminal truecolor support in the event of a false negative | `false` |
|
||||||
|
| `undercurl` | Set to `true` to override automatic detection of terminal undercurl support in the event of a false negative | `false` |
|
||||||
|
| `rulers` | List of column positions at which to display the rulers. Can be overridden by language specific `rulers` in `languages.toml` file | `[]` |
|
||||||
|
| `bufferline` | Renders a line at the top of the editor displaying open buffers. Can be `always`, `never` or `multiple` (only shown if more than one buffer is in use) | `never` |
|
||||||
|
| `color-modes` | Whether to color the mode indicator with different colors depending on the mode itself | `false` |
|
||||||
|
| `text-width` | Maximum line length. Used for the `:reflow` command and soft-wrapping if `soft-wrap.wrap-at-text-width` is set | `80` |
|
||||||
|
| `workspace-lsp-roots` | Directories relative to the workspace root that are treated as LSP roots. Should only be set in `.helix/config.toml` | `[]` |
|
||||||
|
| `default-line-ending` | The line ending to use for new documents. Can be `native`, `lf`, `crlf`, `ff`, `cr` or `nel`. `native` uses the platform's native line ending (`crlf` on Windows, otherwise `lf`). | `native` |
|
||||||
|
| `insert-final-newline` | Whether to automatically insert a trailing line-ending on write if missing | `true` |
|
||||||
|
| `popup-border` | Draw border around `popup`, `menu`, `all`, or `none` | `none` |
|
||||||
|
| `indent-heuristic` | How the indentation for a newly inserted line is computed: `simple` just copies the indentation level from the previous line, `tree-sitter` computes the indentation based on the syntax tree and `hybrid` combines both approaches. If the chosen heuristic is not available, a different one will be used as a fallback (the fallback order being `hybrid` -> `tree-sitter` -> `simple`). | `hybrid`
|
||||||
|
| `jump-label-alphabet` | The characters that are used to generate two character jump labels. Characters at the start of the alphabet are used first. | `"abcdefghijklmnopqrstuvwxyz"`
|
||||||
|
| `end-of-line-diagnostics` | Minimum severity of diagnostics to render at the end of the line. Set to `disable` to disable entirely. Refer to the setting about `inline-diagnostics` for more details | "disable"
|
||||||
|
|
||||||
|
### `[editor.statusline]` Section
|
||||||
|
|
||||||
|
Allows configuring the statusline at the bottom of the editor.
|
||||||
|
|
||||||
|
The configuration distinguishes between three areas of the status line:
|
||||||
|
|
||||||
|
`[ ... ... LEFT ... ... | ... ... ... CENTER ... ... ... | ... ... RIGHT ... ... ]`
|
||||||
|
|
||||||
|
Statusline elements can be defined as follows:
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[editor.statusline]
|
||||||
|
left = ["mode", "spinner"]
|
||||||
|
center = ["file-name"]
|
||||||
|
right = ["diagnostics", "selections", "position", "file-encoding", "file-line-ending", "file-type"]
|
||||||
|
separator = "│"
|
||||||
|
mode.normal = "NORMAL"
|
||||||
|
mode.insert = "INSERT"
|
||||||
|
mode.select = "SELECT"
|
||||||
|
```
|
||||||
|
The `[editor.statusline]` key takes the following sub-keys:
|
||||||
|
|
||||||
|
| Key | Description | Default |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| `left` | A list of elements aligned to the left of the statusline | `["mode", "spinner", "file-name", "read-only-indicator", "file-modification-indicator"]` |
|
||||||
|
| `center` | A list of elements aligned to the middle of the statusline | `[]` |
|
||||||
|
| `right` | A list of elements aligned to the right of the statusline | `["diagnostics", "selections", "register", "position", "file-encoding"]` |
|
||||||
|
| `separator` | The character used to separate elements in the statusline | `"│"` |
|
||||||
|
| `mode.normal` | The text shown in the `mode` element for normal mode | `"NOR"` |
|
||||||
|
| `mode.insert` | The text shown in the `mode` element for insert mode | `"INS"` |
|
||||||
|
| `mode.select` | The text shown in the `mode` element for select mode | `"SEL"` |
|
||||||
|
|
||||||
|
The following statusline elements can be configured:
|
||||||
|
|
||||||
|
| Key | Description |
|
||||||
|
| ------ | ----------- |
|
||||||
|
| `mode` | The current editor mode (`mode.normal`/`mode.insert`/`mode.select`) |
|
||||||
|
| `spinner` | A progress spinner indicating LSP activity |
|
||||||
|
| `file-name` | The path/name of the opened file |
|
||||||
|
| `file-absolute-path` | The absolute path/name of the opened file |
|
||||||
|
| `file-base-name` | The basename of the opened file |
|
||||||
|
| `file-modification-indicator` | The indicator to show whether the file is modified (a `[+]` appears when there are unsaved changes) |
|
||||||
|
| `file-encoding` | The encoding of the opened file if it differs from UTF-8 |
|
||||||
|
| `file-line-ending` | The file line endings (CRLF or LF) |
|
||||||
|
| `read-only-indicator` | An indicator that shows `[readonly]` when a file cannot be written |
|
||||||
|
| `total-line-numbers` | The total line numbers of the opened file |
|
||||||
|
| `file-type` | The type of the opened file |
|
||||||
|
| `diagnostics` | The number of warnings and/or errors |
|
||||||
|
| `workspace-diagnostics` | The number of warnings and/or errors on workspace |
|
||||||
|
| `selections` | The number of active selections |
|
||||||
|
| `primary-selection-length` | The number of characters currently in primary selection |
|
||||||
|
| `position` | The cursor position |
|
||||||
|
| `position-percentage` | The cursor position as a percentage of the total number of lines |
|
||||||
|
| `separator` | The string defined in `editor.statusline.separator` (defaults to `"│"`) |
|
||||||
|
| `spacer` | Inserts a space between elements (multiple/contiguous spacers may be specified) |
|
||||||
|
| `version-control` | The current branch name or detached commit hash of the opened workspace |
|
||||||
|
| `register` | The current selected register |
|
||||||
|
|
||||||
|
### `[editor.lsp]` Section
|
||||||
|
|
||||||
|
| Key | Description | Default |
|
||||||
|
| --- | ----------- | ------- |
|
||||||
|
| `enable` | Enables LSP integration. Setting to false will completely disable language servers regardless of language settings.| `true` |
|
||||||
|
| `display-messages` | Display LSP progress messages below statusline[^1] | `false` |
|
||||||
|
| `auto-signature-help` | Enable automatic popup of signature help (parameter hints) | `true` |
|
||||||
|
| `display-inlay-hints` | Display inlay hints[^2] | `false` |
|
||||||
|
| `display-signature-help-docs` | Display docs under signature help popup | `true` |
|
||||||
|
| `snippets` | Enables snippet completions. Requires a server restart (`:lsp-restart`) to take effect after `:config-reload`/`:set`. | `true` |
|
||||||
|
| `goto-reference-include-declaration` | Include declaration in the goto references popup. | `true` |
|
||||||
|
|
||||||
|
[^1]: By default, a progress spinner is shown in the statusline beside the file path.
|
||||||
|
|
||||||
|
[^2]: You may also have to activate them in the LSP config for them to appear, not just in Helix. Inlay hints in Helix are still being improved on and may be a little bit laggy/janky under some circumstances. Please report any bugs you see so we can fix them!
|
||||||
|
|
||||||
|
### `[editor.cursor-shape]` Section
|
||||||
|
|
||||||
|
Defines the shape of cursor in each mode.
|
||||||
|
Valid values for these options are `block`, `bar`, `underline`, or `hidden`.
|
||||||
|
|
||||||
|
> 💡 Due to limitations of the terminal environment, only the primary cursor can
|
||||||
|
> change shape.
|
||||||
|
|
||||||
|
| Key | Description | Default |
|
||||||
|
| --- | ----------- | ------- |
|
||||||
|
| `normal` | Cursor shape in [normal mode][normal mode] | `block` |
|
||||||
|
| `insert` | Cursor shape in [insert mode][insert mode] | `block` |
|
||||||
|
| `select` | Cursor shape in [select mode][select mode] | `block` |
|
||||||
|
|
||||||
|
[normal mode]: ./keymap.md#normal-mode
|
||||||
|
[insert mode]: ./keymap.md#insert-mode
|
||||||
|
[select mode]: ./keymap.md#select--extend-mode
|
||||||
|
|
||||||
|
### `[editor.file-picker]` Section
|
||||||
|
|
||||||
|
Set options for file picker and global search. Ignoring a file means it is
|
||||||
|
not visible in the Helix file picker and global search.
|
||||||
|
|
||||||
|
All git related options are only enabled in a git repository.
|
||||||
|
|
||||||
|
| Key | Description | Default |
|
||||||
|
|--|--|---------|
|
||||||
|
|`hidden` | Enables ignoring hidden files | `true`
|
||||||
|
|`follow-symlinks` | Follow symlinks instead of ignoring them | `true`
|
||||||
|
|`deduplicate-links` | Ignore symlinks that point at files already shown in the picker | `true`
|
||||||
|
|`parents` | Enables reading ignore files from parent directories | `true`
|
||||||
|
|`ignore` | Enables reading `.ignore` files | `true`
|
||||||
|
|`git-ignore` | Enables reading `.gitignore` files | `true`
|
||||||
|
|`git-global` | Enables reading global `.gitignore`, whose path is specified in git's config: `core.excludesfile` option | `true`
|
||||||
|
|`git-exclude` | Enables reading `.git/info/exclude` files | `true`
|
||||||
|
|`max-depth` | Set with an integer value for maximum depth to recurse | Unset by default
|
||||||
|
|
||||||
|
Ignore files can be placed locally as `.ignore` or put in your home directory as `~/.ignore`. They support the usual ignore and negative ignore (unignore) rules used in `.gitignore` files.
|
||||||
|
|
||||||
|
Additionally, you can use Helix-specific ignore files by creating a local `.helix/ignore` file in the current workspace or a global `ignore` file located in your Helix config directory:
|
||||||
|
- Linux and Mac: `~/.config/helix/ignore`
|
||||||
|
- Windows: `%AppData%\helix\ignore`
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```ini
|
||||||
|
# unignore in file picker and global search
|
||||||
|
!.github/
|
||||||
|
!.gitignore
|
||||||
|
!.gitattributes
|
||||||
|
```
|
||||||
|
|
||||||
|
### `[editor.auto-pairs]` Section
|
||||||
|
|
||||||
|
Enables automatic insertion of pairs to parentheses, brackets, etc. Can be a
|
||||||
|
simple boolean value, or a specific mapping of pairs of single characters.
|
||||||
|
|
||||||
|
To disable auto-pairs altogether, set `auto-pairs` to `false`:
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[editor]
|
||||||
|
auto-pairs = false # defaults to `true`
|
||||||
|
```
|
||||||
|
|
||||||
|
The default pairs are <code>(){}[]''""``</code>, but these can be customized by
|
||||||
|
setting `auto-pairs` to a TOML table:
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[editor.auto-pairs]
|
||||||
|
'(' = ')'
|
||||||
|
'{' = '}'
|
||||||
|
'[' = ']'
|
||||||
|
'"' = '"'
|
||||||
|
'`' = '`'
|
||||||
|
'<' = '>'
|
||||||
|
```
|
||||||
|
|
||||||
|
Additionally, this setting can be used in a language config. Unless
|
||||||
|
the editor setting is `false`, this will override the editor config in
|
||||||
|
documents with this language.
|
||||||
|
|
||||||
|
Example `languages.toml` that adds `<>` and removes `''`
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[[language]]
|
||||||
|
name = "rust"
|
||||||
|
|
||||||
|
[language.auto-pairs]
|
||||||
|
'(' = ')'
|
||||||
|
'{' = '}'
|
||||||
|
'[' = ']'
|
||||||
|
'"' = '"'
|
||||||
|
'`' = '`'
|
||||||
|
'<' = '>'
|
||||||
|
```
|
||||||
|
|
||||||
|
### `[editor.auto-save]` Section
|
||||||
|
|
||||||
|
Control auto save behavior.
|
||||||
|
|
||||||
|
| Key | Description | Default |
|
||||||
|
|--|--|---------|
|
||||||
|
| `focus-lost` | Enable automatic saving on the focus moving away from Helix. Requires [focus event support](https://github.com/helix-editor/helix/wiki/Terminal-Support) from your terminal | `false` |
|
||||||
|
| `after-delay.enable` | Enable automatic saving after `auto-save.after-delay.timeout` milliseconds have passed since last edit. | `false` |
|
||||||
|
| `after-delay.timeout` | Time in milliseconds since last edit before auto save timer triggers. | `3000` |
|
||||||
|
|
||||||
|
### `[editor.search]` Section
|
||||||
|
|
||||||
|
Search specific options.
|
||||||
|
|
||||||
|
| Key | Description | Default |
|
||||||
|
|--|--|---------|
|
||||||
|
| `smart-case` | Enable smart case regex searching (case-insensitive unless pattern contains upper case characters) | `true` |
|
||||||
|
| `wrap-around`| Whether the search should wrap after depleting the matches | `true` |
|
||||||
|
|
||||||
|
### `[editor.whitespace]` Section
|
||||||
|
|
||||||
|
Options for rendering whitespace with visible characters. Use `:set whitespace.render all` to temporarily enable visible whitespace.
|
||||||
|
|
||||||
|
| Key | Description | Default |
|
||||||
|
|-----|-------------|---------|
|
||||||
|
| `render` | Whether to render whitespace. May either be `all` or `none`, or a table with sub-keys `space`, `nbsp`, `nnbsp`, `tab`, and `newline` | `none` |
|
||||||
|
| `characters` | Literal characters to use when rendering whitespace. Sub-keys may be any of `tab`, `space`, `nbsp`, `nnbsp`, `newline` or `tabpad` | See example below |
|
||||||
|
|
||||||
|
Example
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[editor.whitespace]
|
||||||
|
render = "all"
|
||||||
|
# or control each character
|
||||||
|
[editor.whitespace.render]
|
||||||
|
space = "all"
|
||||||
|
tab = "all"
|
||||||
|
nbsp = "none"
|
||||||
|
nnbsp = "none"
|
||||||
|
newline = "none"
|
||||||
|
|
||||||
|
[editor.whitespace.characters]
|
||||||
|
space = "·"
|
||||||
|
nbsp = "⍽"
|
||||||
|
nnbsp = "␣"
|
||||||
|
tab = "→"
|
||||||
|
newline = "⏎"
|
||||||
|
tabpad = "·" # Tabs will look like "→···" (depending on tab width)
|
||||||
|
```
|
||||||
|
|
||||||
|
### `[editor.indent-guides]` Section
|
||||||
|
|
||||||
|
Options for rendering vertical indent guides.
|
||||||
|
|
||||||
|
| Key | Description | Default |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| `render` | Whether to render indent guides | `false` |
|
||||||
|
| `character` | Literal character to use for rendering the indent guide | `│` |
|
||||||
|
| `skip-levels` | Number of indent levels to skip | `0` |
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[editor.indent-guides]
|
||||||
|
render = true
|
||||||
|
character = "╎" # Some characters that work well: "▏", "┆", "┊", "⸽"
|
||||||
|
skip-levels = 1
|
||||||
|
```
|
||||||
|
|
||||||
|
### `[editor.gutters]` Section
|
||||||
|
|
||||||
|
For simplicity, `editor.gutters` accepts an array of gutter types, which will
|
||||||
|
use default settings for all gutter components.
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[editor]
|
||||||
|
gutters = ["diff", "diagnostics", "line-numbers", "spacer"]
|
||||||
|
```
|
||||||
|
|
||||||
|
To customize the behavior of gutters, the `[editor.gutters]` section must
|
||||||
|
be used. This section contains top level settings, as well as settings for
|
||||||
|
specific gutter components as subsections.
|
||||||
|
|
||||||
|
| Key | Description | Default |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| `layout` | A vector of gutters to display | `["diagnostics", "spacer", "line-numbers", "spacer", "diff"]` |
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[editor.gutters]
|
||||||
|
layout = ["diff", "diagnostics", "line-numbers", "spacer"]
|
||||||
|
```
|
||||||
|
|
||||||
|
#### `[editor.gutters.line-numbers]` Section
|
||||||
|
|
||||||
|
Options for the line number gutter
|
||||||
|
|
||||||
|
| Key | Description | Default |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| `min-width` | The minimum number of characters to use | `3` |
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[editor.gutters.line-numbers]
|
||||||
|
min-width = 1
|
||||||
|
```
|
||||||
|
|
||||||
|
#### `[editor.gutters.diagnostics]` Section
|
||||||
|
|
||||||
|
Currently unused
|
||||||
|
|
||||||
|
#### `[editor.gutters.diff]` Section
|
||||||
|
|
||||||
|
The `diff` gutter option displays colored bars indicating whether a `git` diff represents that a line was added, removed or changed.
|
||||||
|
These colors are controlled by the theme attributes `diff.plus`, `diff.minus` and `diff.delta`.
|
||||||
|
|
||||||
|
Other diff providers will eventually be supported by a future plugin system.
|
||||||
|
|
||||||
|
There are currently no options for this section.
|
||||||
|
|
||||||
|
#### `[editor.gutters.spacer]` Section
|
||||||
|
|
||||||
|
Currently unused
|
||||||
|
|
||||||
|
### `[editor.soft-wrap]` Section
|
||||||
|
|
||||||
|
Options for soft wrapping lines that exceed the view width:
|
||||||
|
|
||||||
|
| Key | Description | Default |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| `enable` | Whether soft wrapping is enabled. | `false` |
|
||||||
|
| `max-wrap` | Maximum free space left at the end of the line. | `20` |
|
||||||
|
| `max-indent-retain` | Maximum indentation to carry over when soft wrapping a line. | `40` |
|
||||||
|
| `wrap-indicator` | Text inserted before soft wrapped lines, highlighted with `ui.virtual.wrap` | `↪ ` |
|
||||||
|
| `wrap-at-text-width` | Soft wrap at `text-width` instead of using the full viewport size. | `false` |
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[editor.soft-wrap]
|
||||||
|
enable = true
|
||||||
|
max-wrap = 25 # increase value to reduce forced mid-word wrapping
|
||||||
|
max-indent-retain = 0
|
||||||
|
wrap-indicator = "" # set wrap-indicator to "" to hide it
|
||||||
|
```
|
||||||
|
|
||||||
|
### `[editor.smart-tab]` Section
|
||||||
|
|
||||||
|
Options for navigating and editing using tab key.
|
||||||
|
|
||||||
|
| Key | Description | Default |
|
||||||
|
|------------|-------------|---------|
|
||||||
|
| `enable` | If set to true, then when the cursor is in a position with non-whitespace to its left, instead of inserting a tab, it will run `move_parent_node_end`. If there is only whitespace to the left, then it inserts a tab as normal. With the default bindings, to explicitly insert a tab character, press Shift-tab. | `true` |
|
||||||
|
| `supersede-menu` | Normally, when a menu is on screen, such as when auto complete is triggered, the tab key is bound to cycling through the items. This means when menus are on screen, one cannot use the tab key to trigger the `smart-tab` command. If this option is set to true, the `smart-tab` command always takes precedence, which means one cannot use the tab key to cycle through menu items. One of the other bindings must be used instead, such as arrow keys or `C-n`/`C-p`. | `false` |
|
||||||
|
|
||||||
|
|
||||||
|
Due to lack of support for S-tab in some terminals, the default keybindings don't fully embrace smart-tab editing experience. If you enjoy smart-tab navigation and a terminal that supports the [Enhanced Keyboard protocol](https://github.com/helix-editor/helix/wiki/Terminal-Support#enhanced-keyboard-protocol), consider setting extra keybindings:
|
||||||
|
|
||||||
|
```
|
||||||
|
[keys.normal]
|
||||||
|
tab = "move_parent_node_end"
|
||||||
|
S-tab = "move_parent_node_start"
|
||||||
|
|
||||||
|
[keys.insert]
|
||||||
|
S-tab = "move_parent_node_start"
|
||||||
|
|
||||||
|
[keys.select]
|
||||||
|
tab = "extend_parent_node_end"
|
||||||
|
S-tab = "extend_parent_node_start"
|
||||||
|
```
|
||||||
|
|
||||||
|
### `[editor.inline-diagnostics]` Section
|
||||||
|
|
||||||
|
Options for rendering diagnostics inside the text like shown below
|
||||||
|
|
||||||
|
```
|
||||||
|
fn main() {
|
||||||
|
let foo = bar;
|
||||||
|
└─ no such value in this scope
|
||||||
|
}
|
||||||
|
````
|
||||||
|
|
||||||
|
| Key | Description | Default |
|
||||||
|
|------------|-------------|---------|
|
||||||
|
| `cursor-line` | The minimum severity that a diagnostic must have to be shown inline on the line that contains the primary cursor. Set to `disable` to not show any diagnostics inline. This option does not have any effect when in insert-mode and will only take effect 350ms after moving the cursor to a different line. | `"disable"` |
|
||||||
|
| `other-lines` | The minimum severity that a diagnostic must have to be shown inline on a line that does not contain the cursor-line. Set to `disable` to not show any diagnostics inline. | `"disable"` |
|
||||||
|
| `prefix-len` | How many horizontal bars `─` are rendered before the diagnostic text. | `1` |
|
||||||
|
| `max-wrap` | Equivalent of the `editor.soft-wrap.max-wrap` option for diagnostics. | `20` |
|
||||||
|
| `max-diagnostics` | Maximum number of diagnostics to render inline for a given line | `10` |
|
||||||
|
|
||||||
|
The (first) diagnostic with the highest severity that is not shown inline is rendered at the end of the line (as long as its severity is higher than the `end-of-line-diagnostics` config option):
|
||||||
|
|
||||||
|
```
|
||||||
|
fn main() {
|
||||||
|
let baz = 1;
|
||||||
|
let foo = bar; a local variable with a similar name exists: baz
|
||||||
|
└─ no such value in this scope
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
The new diagnostic rendering is not yet enabled by default. As soon as end of line or inline diagnostics are enabled the old diagnostics rendering is automatically disabled. The recommended default setting are:
|
||||||
|
|
||||||
|
```
|
||||||
|
end-of-line-diagnostics = "hint"
|
||||||
|
[editor.inline-diagnostics]
|
||||||
|
cursor-line = "warning" # show warnings and errors on the cursorline inline
|
||||||
|
```
|
@ -0,0 +1,150 @@
|
|||||||
|
## Package managers
|
||||||
|
|
||||||
|
- [Linux](#linux)
|
||||||
|
- [Ubuntu](#ubuntu)
|
||||||
|
- [Fedora/RHEL](#fedorarhel)
|
||||||
|
- [Arch Linux extra](#arch-linux-extra)
|
||||||
|
- [NixOS](#nixos)
|
||||||
|
- [Flatpak](#flatpak)
|
||||||
|
- [Snap](#snap)
|
||||||
|
- [AppImage](#appimage)
|
||||||
|
- [macOS](#macos)
|
||||||
|
- [Homebrew Core](#homebrew-core)
|
||||||
|
- [MacPorts](#macports)
|
||||||
|
- [Windows](#windows)
|
||||||
|
- [Winget](#winget)
|
||||||
|
- [Scoop](#scoop)
|
||||||
|
- [Chocolatey](#chocolatey)
|
||||||
|
- [MSYS2](#msys2)
|
||||||
|
|
||||||
|
[![Packaging status](https://repology.org/badge/vertical-allrepos/helix.svg)](https://repology.org/project/helix/versions)
|
||||||
|
|
||||||
|
## Linux
|
||||||
|
|
||||||
|
The following third party repositories are available:
|
||||||
|
|
||||||
|
### Ubuntu
|
||||||
|
|
||||||
|
Add the `PPA` for Helix:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
sudo add-apt-repository ppa:maveonair/helix-editor
|
||||||
|
sudo apt update
|
||||||
|
sudo apt install helix
|
||||||
|
```
|
||||||
|
|
||||||
|
### Fedora/RHEL
|
||||||
|
|
||||||
|
```sh
|
||||||
|
sudo dnf install helix
|
||||||
|
```
|
||||||
|
|
||||||
|
### Arch Linux extra
|
||||||
|
|
||||||
|
Releases are available in the `extra` repository:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
sudo pacman -S helix
|
||||||
|
```
|
||||||
|
|
||||||
|
> 💡 When installed from the `extra` repository, run Helix with `helix` instead of `hx`.
|
||||||
|
>
|
||||||
|
> For example:
|
||||||
|
> ```sh
|
||||||
|
> helix --health
|
||||||
|
> ```
|
||||||
|
> to check health
|
||||||
|
|
||||||
|
Additionally, a [helix-git](https://aur.archlinux.org/packages/helix-git/) package is available
|
||||||
|
in the AUR, which builds the master branch.
|
||||||
|
|
||||||
|
### NixOS
|
||||||
|
|
||||||
|
Helix is available in [nixpkgs](https://github.com/nixos/nixpkgs) through the `helix` attribute,
|
||||||
|
the unstable channel usually carries the latest release.
|
||||||
|
|
||||||
|
Helix is also available as a [flake](https://wiki.nixos.org/wiki/Flakes) in the project
|
||||||
|
root. Use `nix develop` to spin up a reproducible development shell. Outputs are
|
||||||
|
cached for each push to master using [Cachix](https://www.cachix.org/). The
|
||||||
|
flake is configured to automatically make use of this cache assuming the user
|
||||||
|
accepts the new settings on first use.
|
||||||
|
|
||||||
|
If you are using a version of Nix without flakes enabled,
|
||||||
|
[install Cachix CLI](https://docs.cachix.org/installation) and use
|
||||||
|
`cachix use helix` to configure Nix to use cached outputs when possible.
|
||||||
|
|
||||||
|
### Flatpak
|
||||||
|
|
||||||
|
Helix is available on [Flathub](https://flathub.org/en-GB/apps/com.helix_editor.Helix):
|
||||||
|
|
||||||
|
```sh
|
||||||
|
flatpak install flathub com.helix_editor.Helix
|
||||||
|
flatpak run com.helix_editor.Helix
|
||||||
|
```
|
||||||
|
|
||||||
|
### Snap
|
||||||
|
|
||||||
|
Helix is available on [Snapcraft](https://snapcraft.io/helix) and can be installed with:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
snap install --classic helix
|
||||||
|
```
|
||||||
|
|
||||||
|
This will install Helix as both `/snap/bin/helix` and `/snap/bin/hx`, so make sure `/snap/bin` is in your `PATH`.
|
||||||
|
|
||||||
|
### AppImage
|
||||||
|
|
||||||
|
Install Helix using the Linux [AppImage](https://appimage.org/) format.
|
||||||
|
Download the official Helix AppImage from the [latest releases](https://github.com/helix-editor/helix/releases/latest) page.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
chmod +x helix-*.AppImage # change permission for executable mode
|
||||||
|
./helix-*.AppImage # run helix
|
||||||
|
```
|
||||||
|
|
||||||
|
## macOS
|
||||||
|
|
||||||
|
### Homebrew Core
|
||||||
|
|
||||||
|
```sh
|
||||||
|
brew install helix
|
||||||
|
```
|
||||||
|
|
||||||
|
### MacPorts
|
||||||
|
|
||||||
|
```sh
|
||||||
|
port install helix
|
||||||
|
```
|
||||||
|
|
||||||
|
## Windows
|
||||||
|
|
||||||
|
Install on Windows using [Winget](https://learn.microsoft.com/en-us/windows/package-manager/winget/), [Scoop](https://scoop.sh/), [Chocolatey](https://chocolatey.org/)
|
||||||
|
or [MSYS2](https://msys2.org/).
|
||||||
|
|
||||||
|
### Winget
|
||||||
|
Windows Package Manager winget command-line tool is by default available on Windows 11 and modern versions of Windows 10 as a part of the App Installer.
|
||||||
|
You can get [App Installer from the Microsoft Store](https://www.microsoft.com/p/app-installer/9nblggh4nns1#activetab=pivot:overviewtab). If it's already installed, make sure it is updated with the latest version.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
winget install Helix.Helix
|
||||||
|
```
|
||||||
|
|
||||||
|
### Scoop
|
||||||
|
|
||||||
|
```sh
|
||||||
|
scoop install helix
|
||||||
|
```
|
||||||
|
|
||||||
|
### Chocolatey
|
||||||
|
|
||||||
|
```sh
|
||||||
|
choco install helix
|
||||||
|
```
|
||||||
|
|
||||||
|
### MSYS2
|
||||||
|
|
||||||
|
For 64-bit Windows 8.1 or above:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
pacman -S mingw-w64-ucrt-x86_64-helix
|
||||||
|
```
|
@ -0,0 +1,11 @@
|
|||||||
|
## Using pickers
|
||||||
|
|
||||||
|
Helix has a variety of pickers, which are interactive windows used to select various kinds of items. These include a file picker, global search picker, and more. Most pickers are accessed via keybindings in [space mode](./keymap.md#space-mode). Pickers have their own [keymap](./keymap.md#picker) for navigation.
|
||||||
|
|
||||||
|
### Filtering Picker Results
|
||||||
|
|
||||||
|
Most pickers perform fuzzy matching using [fzf syntax](https://github.com/junegunn/fzf?tab=readme-ov-file#search-syntax). Two exceptions are the global search picker, which uses regex, and the workspace symbol picker, which passes search terms to the LSP. Note that OR operations (`|`) are not currently supported.
|
||||||
|
|
||||||
|
If a picker shows multiple columns, you may apply the filter to a specific column by prefixing the column name with `%`. Column names can be shortened to any prefix, so `%p`, `%pa` or `%pat` all mean the same as `%path`. For example, a query of `helix %p .toml !lang` in the global search picker searches for the term "helix" within files with paths ending in ".toml" but not including "lang".
|
||||||
|
|
||||||
|
You can insert the contents of a [register](./registers.md) using `Ctrl-r` followed by a register name. For example, one could insert the currently selected text using `Ctrl-r`-`.`, or the directory of the current file using `Ctrl-r`-`%` followed by `Ctrl-w` to remove the last path section. The global search picker will use the contents of the [search register](./registers.md#default-registers) if you press `Enter` without typing a filter. For example, pressing `*`-`Space-/`-`Enter` will start a global search for the currently selected text.
|
@ -0,0 +1,54 @@
|
|||||||
|
## Registers
|
||||||
|
|
||||||
|
- [User-defined registers](#user-defined-registers)
|
||||||
|
- [Default registers](#default-registers)
|
||||||
|
- [Special registers](#special-registers)
|
||||||
|
|
||||||
|
In Helix, registers are storage locations for text and other data, such as the
|
||||||
|
result of a search. Registers can be used to cut, copy, and paste text, similar
|
||||||
|
to the clipboard in other text editors. Usage is similar to Vim, with `"` being
|
||||||
|
used to select a register.
|
||||||
|
|
||||||
|
### User-defined registers
|
||||||
|
|
||||||
|
Helix allows you to create your own named registers for storing text, for
|
||||||
|
example:
|
||||||
|
|
||||||
|
- `"ay` - Yank the current selection to register `a`.
|
||||||
|
- `"op` - Paste the text in register `o` after the selection.
|
||||||
|
|
||||||
|
If a register is selected before invoking a change or delete command, the selection will be stored in the register and the action will be carried out:
|
||||||
|
|
||||||
|
- `"hc` - Store the selection in register `h` and then change it (delete and enter insert mode).
|
||||||
|
- `"md` - Store the selection in register `m` and delete it.
|
||||||
|
|
||||||
|
### Default registers
|
||||||
|
|
||||||
|
Commands that use registers, like yank (`y`), use a default register if none is specified.
|
||||||
|
These registers are used as defaults:
|
||||||
|
|
||||||
|
| Register character | Contains |
|
||||||
|
| --- | --- |
|
||||||
|
| `/` | Last search |
|
||||||
|
| `:` | Last executed command |
|
||||||
|
| `"` | Last yanked text |
|
||||||
|
| `@` | Last recorded macro |
|
||||||
|
|
||||||
|
### Special registers
|
||||||
|
|
||||||
|
Some registers have special behavior when read from and written to.
|
||||||
|
|
||||||
|
| Register character | When read | When written |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| `_` | No values are returned | All values are discarded |
|
||||||
|
| `#` | Selection indices (first selection is `1`, second is `2`, etc.) | This register is not writable |
|
||||||
|
| `.` | Contents of the current selections | This register is not writable |
|
||||||
|
| `%` | Name of the current file | This register is not writable |
|
||||||
|
| `+` | Reads from the system clipboard | Joins and yanks to the system clipboard |
|
||||||
|
| `*` | Reads from the primary clipboard | Joins and yanks to the primary clipboard |
|
||||||
|
|
||||||
|
When yanking multiple selections to the clipboard registers, the selections
|
||||||
|
are joined with newlines. Pasting from these registers will paste multiple
|
||||||
|
selections if the clipboard was last yanked to by the Helix session. Otherwise
|
||||||
|
the clipboard contents are pasted as one selection.
|
||||||
|
|
@ -0,0 +1,24 @@
|
|||||||
|
## Surround
|
||||||
|
|
||||||
|
Helix includes built-in functionality similar to [vim-surround](https://github.com/tpope/vim-surround).
|
||||||
|
The keymappings have been inspired from [vim-sandwich](https://github.com/machakann/vim-sandwich):
|
||||||
|
|
||||||
|
![Surround demo](https://user-images.githubusercontent.com/23398472/122865801-97073180-d344-11eb-8142-8f43809982c6.gif)
|
||||||
|
|
||||||
|
| Key Sequence | Action |
|
||||||
|
| --------------------------------- | --------------------------------------- |
|
||||||
|
| `ms<char>` (after selecting text) | Add surround characters to selection |
|
||||||
|
| `mr<char_to_replace><new_char>` | Replace the closest surround characters |
|
||||||
|
| `md<char_to_delete>` | Delete the closest surround characters |
|
||||||
|
|
||||||
|
You can use counts to act on outer pairs.
|
||||||
|
|
||||||
|
Surround can also act on multiple selections. For example, to change every occurrence of `(use)` to `[use]`:
|
||||||
|
|
||||||
|
1. `%` to select the whole file
|
||||||
|
2. `s` to split the selections on a search term
|
||||||
|
3. Input `use` and hit Enter
|
||||||
|
4. `mr([` to replace the parentheses with square brackets
|
||||||
|
|
||||||
|
Multiple characters are currently not supported, but planned for future release.
|
||||||
|
|
@ -0,0 +1,66 @@
|
|||||||
|
## Moving the selection with syntax-aware motions
|
||||||
|
|
||||||
|
`Alt-p`, `Alt-o`, `Alt-i`, and `Alt-n` (or `Alt` and arrow keys) allow you to move the
|
||||||
|
selection according to its location in the syntax tree. For example, many languages have the
|
||||||
|
following syntax for function calls:
|
||||||
|
|
||||||
|
```js
|
||||||
|
func(arg1, arg2, arg3);
|
||||||
|
```
|
||||||
|
|
||||||
|
A function call might be parsed by tree-sitter into a tree like the following.
|
||||||
|
|
||||||
|
```tsq
|
||||||
|
(call
|
||||||
|
function: (identifier) ; func
|
||||||
|
arguments:
|
||||||
|
(arguments ; (arg1, arg2, arg3)
|
||||||
|
(identifier) ; arg1
|
||||||
|
(identifier) ; arg2
|
||||||
|
(identifier))) ; arg3
|
||||||
|
```
|
||||||
|
|
||||||
|
Use `:tree-sitter-subtree` to view the syntax tree of the primary selection. In
|
||||||
|
a more intuitive tree format:
|
||||||
|
|
||||||
|
```
|
||||||
|
┌────┐
|
||||||
|
│call│
|
||||||
|
┌─────┴────┴─────┐
|
||||||
|
│ │
|
||||||
|
┌─────▼────┐ ┌────▼────┐
|
||||||
|
│identifier│ │arguments│
|
||||||
|
│ "func" │ ┌────┴───┬─────┴───┐
|
||||||
|
└──────────┘ │ │ │
|
||||||
|
│ │ │
|
||||||
|
┌─────────▼┐ ┌────▼─────┐ ┌▼─────────┐
|
||||||
|
│identifier│ │identifier│ │identifier│
|
||||||
|
│ "arg1" │ │ "arg2" │ │ "arg3" │
|
||||||
|
└──────────┘ └──────────┘ └──────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
If you have a selection that wraps `arg1` (see the tree above), and you use
|
||||||
|
`Alt-n`, it will select the next sibling in the syntax tree: `arg2`.
|
||||||
|
|
||||||
|
```js
|
||||||
|
// before
|
||||||
|
func([arg1], arg2, arg3)
|
||||||
|
// after
|
||||||
|
func(arg1, [arg2], arg3);
|
||||||
|
```
|
||||||
|
|
||||||
|
Similarly, `Alt-o` will expand the selection to the parent node, in this case, the
|
||||||
|
arguments node.
|
||||||
|
|
||||||
|
```js
|
||||||
|
func[(arg1, arg2, arg3)];
|
||||||
|
```
|
||||||
|
|
||||||
|
There is also some nuanced behavior that prevents you from getting stuck on a
|
||||||
|
node with no sibling. When using `Alt-p` with a selection on `arg1`, the previous
|
||||||
|
child node will be selected. In the event that `arg1` does not have a previous
|
||||||
|
sibling, the selection will move up the syntax tree and select the previous
|
||||||
|
element. As a result, using `Alt-p` with a selection on `arg1` will move the
|
||||||
|
selection to the "func" `identifier`.
|
||||||
|
|
||||||
|
[lang-support]: ./lang-support.md
|
@ -0,0 +1,47 @@
|
|||||||
|
## Selecting and manipulating text with textobjects
|
||||||
|
|
||||||
|
In Helix, textobjects are a way to select, manipulate and operate on a piece of
|
||||||
|
text in a structured way. They allow you to refer to blocks of text based on
|
||||||
|
their structure or purpose, such as a word, sentence, paragraph, or even a
|
||||||
|
function or block of code.
|
||||||
|
|
||||||
|
![Textobject demo](https://user-images.githubusercontent.com/23398472/124231131-81a4bb00-db2d-11eb-9d10-8e577ca7b177.gif)
|
||||||
|
![Textobject tree-sitter demo](https://user-images.githubusercontent.com/23398472/132537398-2a2e0a54-582b-44ab-a77f-eb818942203d.gif)
|
||||||
|
|
||||||
|
- `ma` - Select around the object (`va` in Vim, `<alt-a>` in Kakoune)
|
||||||
|
- `mi` - Select inside the object (`vi` in Vim, `<alt-i>` in Kakoune)
|
||||||
|
|
||||||
|
| Key after `mi` or `ma` | Textobject selected |
|
||||||
|
| --- | --- |
|
||||||
|
| `w` | Word |
|
||||||
|
| `W` | WORD |
|
||||||
|
| `p` | Paragraph |
|
||||||
|
| `(`, `[`, `'`, etc. | Specified surround pairs |
|
||||||
|
| `m` | The closest surround pair |
|
||||||
|
| `f` | Function |
|
||||||
|
| `t` | Type (or Class) |
|
||||||
|
| `a` | Argument/parameter |
|
||||||
|
| `c` | Comment |
|
||||||
|
| `T` | Test |
|
||||||
|
| `g` | Change |
|
||||||
|
|
||||||
|
> 💡 `f`, `t`, etc. need a tree-sitter grammar active for the current
|
||||||
|
document and a special tree-sitter query file to work properly. [Only
|
||||||
|
some grammars](./lang-support.md) currently have the query file implemented.
|
||||||
|
Contributions are welcome!
|
||||||
|
|
||||||
|
## Navigating using tree-sitter textobjects
|
||||||
|
|
||||||
|
Navigating between functions, classes, parameters, and other elements is
|
||||||
|
possible using tree-sitter and textobject queries. For
|
||||||
|
example to move to the next function use `]f`, to move to previous
|
||||||
|
type use `[t`, and so on.
|
||||||
|
|
||||||
|
![Tree-sitter-nav-demo](https://user-images.githubusercontent.com/23398472/152332550-7dfff043-36a2-4aec-b8f2-77c13eb56d6f.gif)
|
||||||
|
|
||||||
|
For the full reference see the [unimpaired](./keymap.html#unimpaired) section of the key bind
|
||||||
|
documentation.
|
||||||
|
|
||||||
|
> 💡 This feature relies on tree-sitter textobjects
|
||||||
|
> and requires the corresponding query file to work properly.
|
||||||
|
|
@ -1,15 +1,18 @@
|
|||||||
#!/usr/bin/env fish
|
#!/usr/bin/env fish
|
||||||
# Fish completion script for Helix editor
|
# Fish completion script for Helix editor
|
||||||
|
|
||||||
set -l langs (hx --health |tail -n '+7' |awk '{print $1}' |sed 's/\x1b\[[0-9;]*m//g')
|
|
||||||
|
|
||||||
complete -c hx -s h -l help -d "Prints help information"
|
complete -c hx -s h -l help -d "Prints help information"
|
||||||
complete -c hx -l tutor -d "Loads the tutorial"
|
complete -c hx -l tutor -d "Loads the tutorial"
|
||||||
complete -c hx -l health -x -a "$langs" -d "Checks for errors in editor setup"
|
complete -c hx -l health -xa "(__hx_langs_ops)" -d "Checks for errors"
|
||||||
complete -c hx -s g -l grammar -x -a "fetch build" -d "Fetches or builds tree-sitter grammars"
|
complete -c hx -s g -l grammar -x -a "fetch build" -d "Fetch or build tree-sitter grammars"
|
||||||
complete -c hx -s v -o vv -o vvv -d "Increases logging verbosity"
|
complete -c hx -s v -o vv -o vvv -d "Increases logging verbosity"
|
||||||
complete -c hx -s V -l version -d "Prints version information"
|
complete -c hx -s V -l version -d "Prints version information"
|
||||||
complete -c hx -l vsplit -d "Splits all given files vertically into different windows"
|
complete -c hx -l vsplit -d "Splits all given files vertically"
|
||||||
complete -c hx -l hsplit -d "Splits all given files horizontally into different windows"
|
complete -c hx -l hsplit -d "Splits all given files horizontally"
|
||||||
complete -c hx -s c -l config -r -d "Specifies a file to use for completion"
|
complete -c hx -s c -l config -r -d "Specifies a file to use for config"
|
||||||
complete -c hx -l log -r -d "Specifies a file to write log data into"
|
complete -c hx -l log -r -d "Specifies a file to use for logging"
|
||||||
|
complete -c hx -s w -l working-dir -d "Specify initial working directory" -xa "(__fish_complete_directories)"
|
||||||
|
|
||||||
|
function __hx_langs_ops
|
||||||
|
hx --health languages | tail -n '+2' | string replace -fr '^(\S+) .*' '$1'
|
||||||
|
end
|
||||||
|
@ -0,0 +1,29 @@
|
|||||||
|
# Completions for Helix: <https://github.com/helix-editor/helix>
|
||||||
|
#
|
||||||
|
# NOTE: the `+N` syntax is not supported in Nushell (https://github.com/nushell/nushell/issues/13418)
|
||||||
|
# so it has not been specified here and will not be proposed in the autocompletion of Nushell.
|
||||||
|
# The help message won't be overriden though, so it will still be present here
|
||||||
|
|
||||||
|
def health_categories [] {
|
||||||
|
let languages = ^hx --health languages | detect columns | get Language | filter { $in != null }
|
||||||
|
let completions = [ "all", "clipboard", "languages" ] | append $languages
|
||||||
|
return $completions
|
||||||
|
}
|
||||||
|
|
||||||
|
def grammar_categories [] { ["fetch", "build"] }
|
||||||
|
|
||||||
|
# A post-modern text editor.
|
||||||
|
export extern hx [
|
||||||
|
--help(-h), # Prints help information
|
||||||
|
--tutor, # Loads the tutorial
|
||||||
|
--health: string@health_categories, # Checks for potential errors in editor setup
|
||||||
|
--grammar(-g): string@grammar_categories, # Fetches or builds tree-sitter grammars listed in `languages.toml`
|
||||||
|
--config(-c): glob, # Specifies a file to use for configuration
|
||||||
|
-v, # Increases logging verbosity each use for up to 3 times
|
||||||
|
--log: glob, # Specifies a file to use for logging
|
||||||
|
--version(-V), # Prints version information
|
||||||
|
--vsplit, # Splits all given files vertically into different windows
|
||||||
|
--hsplit, # Splits all given files horizontally into different windows
|
||||||
|
--working-dir(-w): glob, # Specify an initial working directory
|
||||||
|
...files: glob, # Sets the input file to use, position can also be specified via file[:row[:col]]
|
||||||
|
]
|
@ -0,0 +1,125 @@
|
|||||||
|
use std::{
|
||||||
|
fmt,
|
||||||
|
path::{Path, PathBuf},
|
||||||
|
sync::Arc,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// A generic pointer to a file location.
|
||||||
|
///
|
||||||
|
/// Currently this type only supports paths to local files.
|
||||||
|
///
|
||||||
|
/// Cloning this type is cheap: the internal representation uses an Arc.
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
|
#[non_exhaustive]
|
||||||
|
pub enum Uri {
|
||||||
|
File(Arc<Path>),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Uri {
|
||||||
|
// This clippy allow mirrors url::Url::from_file_path
|
||||||
|
#[allow(clippy::result_unit_err)]
|
||||||
|
pub fn to_url(&self) -> Result<url::Url, ()> {
|
||||||
|
match self {
|
||||||
|
Uri::File(path) => url::Url::from_file_path(path),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn as_path(&self) -> Option<&Path> {
|
||||||
|
match self {
|
||||||
|
Self::File(path) => Some(path),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<PathBuf> for Uri {
|
||||||
|
fn from(path: PathBuf) -> Self {
|
||||||
|
Self::File(path.into())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for Uri {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
Self::File(path) => write!(f, "{}", path.display()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct UrlConversionError {
|
||||||
|
source: url::Url,
|
||||||
|
kind: UrlConversionErrorKind,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum UrlConversionErrorKind {
|
||||||
|
UnsupportedScheme,
|
||||||
|
UnableToConvert,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for UrlConversionError {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
match self.kind {
|
||||||
|
UrlConversionErrorKind::UnsupportedScheme => {
|
||||||
|
write!(
|
||||||
|
f,
|
||||||
|
"unsupported scheme '{}' in URL {}",
|
||||||
|
self.source.scheme(),
|
||||||
|
self.source
|
||||||
|
)
|
||||||
|
}
|
||||||
|
UrlConversionErrorKind::UnableToConvert => {
|
||||||
|
write!(f, "unable to convert URL to file path: {}", self.source)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::error::Error for UrlConversionError {}
|
||||||
|
|
||||||
|
fn convert_url_to_uri(url: &url::Url) -> Result<Uri, UrlConversionErrorKind> {
|
||||||
|
if url.scheme() == "file" {
|
||||||
|
url.to_file_path()
|
||||||
|
.map(|path| Uri::File(helix_stdx::path::normalize(path).into()))
|
||||||
|
.map_err(|_| UrlConversionErrorKind::UnableToConvert)
|
||||||
|
} else {
|
||||||
|
Err(UrlConversionErrorKind::UnsupportedScheme)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<url::Url> for Uri {
|
||||||
|
type Error = UrlConversionError;
|
||||||
|
|
||||||
|
fn try_from(url: url::Url) -> Result<Self, Self::Error> {
|
||||||
|
convert_url_to_uri(&url).map_err(|kind| Self::Error { source: url, kind })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<&url::Url> for Uri {
|
||||||
|
type Error = UrlConversionError;
|
||||||
|
|
||||||
|
fn try_from(url: &url::Url) -> Result<Self, Self::Error> {
|
||||||
|
convert_url_to_uri(url).map_err(|kind| Self::Error {
|
||||||
|
source: url.clone(),
|
||||||
|
kind,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
use super::*;
|
||||||
|
use url::Url;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn unknown_scheme() {
|
||||||
|
let url = Url::parse("csharp:/metadata/foo/bar/Baz.cs").unwrap();
|
||||||
|
assert!(matches!(
|
||||||
|
Uri::try_from(url),
|
||||||
|
Err(UrlConversionError {
|
||||||
|
kind: UrlConversionErrorKind::UnsupportedScheme,
|
||||||
|
..
|
||||||
|
})
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,176 @@
|
|||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bitflags"
|
||||||
|
version = "1.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "form_urlencoded"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8"
|
||||||
|
dependencies = [
|
||||||
|
"percent-encoding",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "idna"
|
||||||
|
version = "0.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-bidi",
|
||||||
|
"unicode-normalization",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "itoa"
|
||||||
|
version = "1.0.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lsp-types"
|
||||||
|
version = "0.95.1"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"serde_repr",
|
||||||
|
"url",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "percent-encoding"
|
||||||
|
version = "2.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro2"
|
||||||
|
version = "1.0.47"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quote"
|
||||||
|
version = "1.0.21"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ryu"
|
||||||
|
version = "1.0.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde"
|
||||||
|
version = "1.0.145"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "728eb6351430bccb993660dfffc5a72f91ccc1295abaa8ce19b27ebe4f75568b"
|
||||||
|
dependencies = [
|
||||||
|
"serde_derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_derive"
|
||||||
|
version = "1.0.145"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "81fa1584d3d1bcacd84c277a0dfe21f5b0f6accf4a23d04d4c6d61f1af522b4c"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_json"
|
||||||
|
version = "1.0.86"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "41feea4228a6f1cd09ec7a3593a682276702cd67b5273544757dae23c096f074"
|
||||||
|
dependencies = [
|
||||||
|
"itoa",
|
||||||
|
"ryu",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_repr"
|
||||||
|
version = "0.1.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1fe39d9fbb0ebf5eb2c7cb7e2a47e4f462fad1379f1166b8ae49ad9eae89a7ca"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "syn"
|
||||||
|
version = "1.0.102"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3fcd952facd492f9be3ef0d0b7032a6e442ee9b361d4acc2b1d0c4aaa5f613a1"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tinyvec"
|
||||||
|
version = "1.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50"
|
||||||
|
dependencies = [
|
||||||
|
"tinyvec_macros",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tinyvec_macros"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-bidi"
|
||||||
|
version = "0.3.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-ident"
|
||||||
|
version = "1.0.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-normalization"
|
||||||
|
version = "0.1.22"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921"
|
||||||
|
dependencies = [
|
||||||
|
"tinyvec",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "url"
|
||||||
|
version = "2.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643"
|
||||||
|
dependencies = [
|
||||||
|
"form_urlencoded",
|
||||||
|
"idna",
|
||||||
|
"percent-encoding",
|
||||||
|
"serde",
|
||||||
|
]
|
@ -0,0 +1,34 @@
|
|||||||
|
[package]
|
||||||
|
name = "helix-lsp-types"
|
||||||
|
version = "0.95.1"
|
||||||
|
authors = [
|
||||||
|
# Original authors
|
||||||
|
"Markus Westerlind <marwes91@gmail.com>",
|
||||||
|
"Bruno Medeiros <bruno.do.medeiros@gmail.com>",
|
||||||
|
# Since forking
|
||||||
|
"Helix contributors"
|
||||||
|
]
|
||||||
|
edition = "2018"
|
||||||
|
description = "Types for interaction with a language server, using VSCode's Language Server Protocol"
|
||||||
|
|
||||||
|
repository = "https://github.com/gluon-lang/lsp-types"
|
||||||
|
documentation = "https://docs.rs/lsp-types"
|
||||||
|
|
||||||
|
readme = "README.md"
|
||||||
|
|
||||||
|
keywords = ["language", "server", "lsp", "vscode", "lsif"]
|
||||||
|
|
||||||
|
license = "MIT"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
bitflags = "2.6.0"
|
||||||
|
serde = { version = "1.0.209", features = ["derive"] }
|
||||||
|
serde_json = "1.0.127"
|
||||||
|
serde_repr = "0.1"
|
||||||
|
url = {version = "2.0.0", features = ["serde"]}
|
||||||
|
|
||||||
|
[features]
|
||||||
|
default = []
|
||||||
|
# Enables proposed LSP extensions.
|
||||||
|
# NOTE: No semver compatibility is guaranteed for types enabled by this feature.
|
||||||
|
proposed = []
|
@ -0,0 +1,22 @@
|
|||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2016 Markus Westerlind
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
|
@ -0,0 +1,3 @@
|
|||||||
|
# Helix's `lsp-types`
|
||||||
|
|
||||||
|
This is a fork of the [`lsp-types`](https://crates.io/crates/lsp-types) crate ([`gluon-lang/lsp-types`](https://github.com/gluon-lang/lsp-types)) taken at version v0.95.1 (commit [3e6daee](https://github.com/gluon-lang/lsp-types/commit/3e6daee771d14db4094a554b8d03e29c310dfcbe)). This fork focuses usability improvements that make the types easier to work with for the Helix codebase. For example the URL type - the `uri` crate at this version of `lsp-types` - will be replaced with a wrapper around a string.
|
@ -0,0 +1,127 @@
|
|||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use serde_json::Value;
|
||||||
|
use url::Url;
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
DynamicRegistrationClientCapabilities, PartialResultParams, Range, SymbolKind, SymbolTag,
|
||||||
|
TextDocumentPositionParams, WorkDoneProgressOptions, WorkDoneProgressParams,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub type CallHierarchyClientCapabilities = DynamicRegistrationClientCapabilities;
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize, Copy)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct CallHierarchyOptions {
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub work_done_progress_options: WorkDoneProgressOptions,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize, Copy)]
|
||||||
|
#[serde(untagged)]
|
||||||
|
pub enum CallHierarchyServerCapability {
|
||||||
|
Simple(bool),
|
||||||
|
Options(CallHierarchyOptions),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<CallHierarchyOptions> for CallHierarchyServerCapability {
|
||||||
|
fn from(from: CallHierarchyOptions) -> Self {
|
||||||
|
Self::Options(from)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<bool> for CallHierarchyServerCapability {
|
||||||
|
fn from(from: bool) -> Self {
|
||||||
|
Self::Simple(from)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct CallHierarchyPrepareParams {
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub text_document_position_params: TextDocumentPositionParams,
|
||||||
|
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub work_done_progress_params: WorkDoneProgressParams,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct CallHierarchyItem {
|
||||||
|
/// The name of this item.
|
||||||
|
pub name: String,
|
||||||
|
|
||||||
|
/// The kind of this item.
|
||||||
|
pub kind: SymbolKind,
|
||||||
|
|
||||||
|
/// Tags for this item.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub tags: Option<Vec<SymbolTag>>,
|
||||||
|
|
||||||
|
/// More detail for this item, e.g. the signature of a function.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub detail: Option<String>,
|
||||||
|
|
||||||
|
/// The resource identifier of this item.
|
||||||
|
pub uri: Url,
|
||||||
|
|
||||||
|
/// The range enclosing this symbol not including leading/trailing whitespace but everything else, e.g. comments and code.
|
||||||
|
pub range: Range,
|
||||||
|
|
||||||
|
/// The range that should be selected and revealed when this symbol is being picked, e.g. the name of a function.
|
||||||
|
/// Must be contained by the [`range`](#CallHierarchyItem.range).
|
||||||
|
pub selection_range: Range,
|
||||||
|
|
||||||
|
/// A data entry field that is preserved between a call hierarchy prepare and incoming calls or outgoing calls requests.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub data: Option<Value>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct CallHierarchyIncomingCallsParams {
|
||||||
|
pub item: CallHierarchyItem,
|
||||||
|
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub work_done_progress_params: WorkDoneProgressParams,
|
||||||
|
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub partial_result_params: PartialResultParams,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Represents an incoming call, e.g. a caller of a method or constructor.
|
||||||
|
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct CallHierarchyIncomingCall {
|
||||||
|
/// The item that makes the call.
|
||||||
|
pub from: CallHierarchyItem,
|
||||||
|
|
||||||
|
/// The range at which at which the calls appears. This is relative to the caller
|
||||||
|
/// denoted by [`this.from`](#CallHierarchyIncomingCall.from).
|
||||||
|
pub from_ranges: Vec<Range>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct CallHierarchyOutgoingCallsParams {
|
||||||
|
pub item: CallHierarchyItem,
|
||||||
|
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub work_done_progress_params: WorkDoneProgressParams,
|
||||||
|
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub partial_result_params: PartialResultParams,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Represents an outgoing call, e.g. calling a getter from a method or a method from a constructor etc.
|
||||||
|
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct CallHierarchyOutgoingCall {
|
||||||
|
/// The item that is called.
|
||||||
|
pub to: CallHierarchyItem,
|
||||||
|
|
||||||
|
/// The range at which this item is called. This is the range relative to the caller, e.g the item
|
||||||
|
/// passed to [`provideCallHierarchyOutgoingCalls`](#CallHierarchyItemProvider.provideCallHierarchyOutgoingCalls)
|
||||||
|
/// and not [`this.to`](#CallHierarchyOutgoingCall.to).
|
||||||
|
pub from_ranges: Vec<Range>,
|
||||||
|
}
|
@ -0,0 +1,395 @@
|
|||||||
|
use crate::{
|
||||||
|
Command, Diagnostic, PartialResultParams, Range, TextDocumentIdentifier,
|
||||||
|
WorkDoneProgressOptions, WorkDoneProgressParams, WorkspaceEdit,
|
||||||
|
};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use serde_json::Value;
|
||||||
|
|
||||||
|
use std::borrow::Cow;
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
|
||||||
|
#[serde(untagged)]
|
||||||
|
pub enum CodeActionProviderCapability {
|
||||||
|
Simple(bool),
|
||||||
|
Options(CodeActionOptions),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<CodeActionOptions> for CodeActionProviderCapability {
|
||||||
|
fn from(from: CodeActionOptions) -> Self {
|
||||||
|
Self::Options(from)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<bool> for CodeActionProviderCapability {
|
||||||
|
fn from(from: bool) -> Self {
|
||||||
|
Self::Simple(from)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct CodeActionClientCapabilities {
|
||||||
|
///
|
||||||
|
/// This capability supports dynamic registration.
|
||||||
|
///
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub dynamic_registration: Option<bool>,
|
||||||
|
|
||||||
|
/// The client support code action literals as a valid
|
||||||
|
/// response of the `textDocument/codeAction` request.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub code_action_literal_support: Option<CodeActionLiteralSupport>,
|
||||||
|
|
||||||
|
/// Whether code action supports the `isPreferred` property.
|
||||||
|
///
|
||||||
|
/// @since 3.15.0
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub is_preferred_support: Option<bool>,
|
||||||
|
|
||||||
|
/// Whether code action supports the `disabled` property.
|
||||||
|
///
|
||||||
|
/// @since 3.16.0
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub disabled_support: Option<bool>,
|
||||||
|
|
||||||
|
/// Whether code action supports the `data` property which is
|
||||||
|
/// preserved between a `textDocument/codeAction` and a
|
||||||
|
/// `codeAction/resolve` request.
|
||||||
|
///
|
||||||
|
/// @since 3.16.0
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub data_support: Option<bool>,
|
||||||
|
|
||||||
|
/// Whether the client supports resolving additional code action
|
||||||
|
/// properties via a separate `codeAction/resolve` request.
|
||||||
|
///
|
||||||
|
/// @since 3.16.0
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub resolve_support: Option<CodeActionCapabilityResolveSupport>,
|
||||||
|
|
||||||
|
/// Whether the client honors the change annotations in
|
||||||
|
/// text edits and resource operations returned via the
|
||||||
|
/// `CodeAction#edit` property by for example presenting
|
||||||
|
/// the workspace edit in the user interface and asking
|
||||||
|
/// for confirmation.
|
||||||
|
///
|
||||||
|
/// @since 3.16.0
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub honors_change_annotations: Option<bool>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Whether the client supports resolving additional code action
|
||||||
|
/// properties via a separate `codeAction/resolve` request.
|
||||||
|
///
|
||||||
|
/// @since 3.16.0
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct CodeActionCapabilityResolveSupport {
|
||||||
|
/// The properties that a client can resolve lazily.
|
||||||
|
pub properties: Vec<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct CodeActionLiteralSupport {
|
||||||
|
/// The code action kind is support with the following value set.
|
||||||
|
pub code_action_kind: CodeActionKindLiteralSupport,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct CodeActionKindLiteralSupport {
|
||||||
|
/// The code action kind values the client supports. When this
|
||||||
|
/// property exists the client also guarantees that it will
|
||||||
|
/// handle values outside its set gracefully and falls back
|
||||||
|
/// to a default value when unknown.
|
||||||
|
pub value_set: Vec<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Params for the CodeActionRequest
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct CodeActionParams {
|
||||||
|
/// The document in which the command was invoked.
|
||||||
|
pub text_document: TextDocumentIdentifier,
|
||||||
|
|
||||||
|
/// The range for which the command was invoked.
|
||||||
|
pub range: Range,
|
||||||
|
|
||||||
|
/// Context carrying additional information.
|
||||||
|
pub context: CodeActionContext,
|
||||||
|
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub work_done_progress_params: WorkDoneProgressParams,
|
||||||
|
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub partial_result_params: PartialResultParams,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// response for CodeActionRequest
|
||||||
|
pub type CodeActionResponse = Vec<CodeActionOrCommand>;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
|
||||||
|
#[serde(untagged)]
|
||||||
|
pub enum CodeActionOrCommand {
|
||||||
|
Command(Command),
|
||||||
|
CodeAction(CodeAction),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Command> for CodeActionOrCommand {
|
||||||
|
fn from(command: Command) -> Self {
|
||||||
|
CodeActionOrCommand::Command(command)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<CodeAction> for CodeActionOrCommand {
|
||||||
|
fn from(action: CodeAction) -> Self {
|
||||||
|
CodeActionOrCommand::CodeAction(action)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq, Hash, PartialOrd, Clone, Deserialize, Serialize)]
|
||||||
|
pub struct CodeActionKind(Cow<'static, str>);
|
||||||
|
|
||||||
|
impl CodeActionKind {
|
||||||
|
/// Empty kind.
|
||||||
|
pub const EMPTY: CodeActionKind = CodeActionKind::new("");
|
||||||
|
|
||||||
|
/// Base kind for quickfix actions: 'quickfix'
|
||||||
|
pub const QUICKFIX: CodeActionKind = CodeActionKind::new("quickfix");
|
||||||
|
|
||||||
|
/// Base kind for refactoring actions: 'refactor'
|
||||||
|
pub const REFACTOR: CodeActionKind = CodeActionKind::new("refactor");
|
||||||
|
|
||||||
|
/// Base kind for refactoring extraction actions: 'refactor.extract'
|
||||||
|
///
|
||||||
|
/// Example extract actions:
|
||||||
|
///
|
||||||
|
/// - Extract method
|
||||||
|
/// - Extract function
|
||||||
|
/// - Extract variable
|
||||||
|
/// - Extract interface from class
|
||||||
|
/// - ...
|
||||||
|
pub const REFACTOR_EXTRACT: CodeActionKind = CodeActionKind::new("refactor.extract");
|
||||||
|
|
||||||
|
/// Base kind for refactoring inline actions: 'refactor.inline'
|
||||||
|
///
|
||||||
|
/// Example inline actions:
|
||||||
|
///
|
||||||
|
/// - Inline function
|
||||||
|
/// - Inline variable
|
||||||
|
/// - Inline constant
|
||||||
|
/// - ...
|
||||||
|
pub const REFACTOR_INLINE: CodeActionKind = CodeActionKind::new("refactor.inline");
|
||||||
|
|
||||||
|
/// Base kind for refactoring rewrite actions: 'refactor.rewrite'
|
||||||
|
///
|
||||||
|
/// Example rewrite actions:
|
||||||
|
///
|
||||||
|
/// - Convert JavaScript function to class
|
||||||
|
/// - Add or remove parameter
|
||||||
|
/// - Encapsulate field
|
||||||
|
/// - Make method static
|
||||||
|
/// - Move method to base class
|
||||||
|
/// - ...
|
||||||
|
pub const REFACTOR_REWRITE: CodeActionKind = CodeActionKind::new("refactor.rewrite");
|
||||||
|
|
||||||
|
/// Base kind for source actions: `source`
|
||||||
|
///
|
||||||
|
/// Source code actions apply to the entire file.
|
||||||
|
pub const SOURCE: CodeActionKind = CodeActionKind::new("source");
|
||||||
|
|
||||||
|
/// Base kind for an organize imports source action: `source.organizeImports`
|
||||||
|
pub const SOURCE_ORGANIZE_IMPORTS: CodeActionKind =
|
||||||
|
CodeActionKind::new("source.organizeImports");
|
||||||
|
|
||||||
|
/// Base kind for a 'fix all' source action: `source.fixAll`.
|
||||||
|
///
|
||||||
|
/// 'Fix all' actions automatically fix errors that have a clear fix that
|
||||||
|
/// do not require user input. They should not suppress errors or perform
|
||||||
|
/// unsafe fixes such as generating new types or classes.
|
||||||
|
///
|
||||||
|
/// @since 3.17.0
|
||||||
|
pub const SOURCE_FIX_ALL: CodeActionKind = CodeActionKind::new("source.fixAll");
|
||||||
|
|
||||||
|
pub const fn new(tag: &'static str) -> Self {
|
||||||
|
CodeActionKind(Cow::Borrowed(tag))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn as_str(&self) -> &str {
|
||||||
|
&self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<String> for CodeActionKind {
|
||||||
|
fn from(from: String) -> Self {
|
||||||
|
CodeActionKind(Cow::from(from))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&'static str> for CodeActionKind {
|
||||||
|
fn from(from: &'static str) -> Self {
|
||||||
|
CodeActionKind::new(from)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Clone, Default, Deserialize, Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct CodeAction {
|
||||||
|
/// A short, human-readable, title for this code action.
|
||||||
|
pub title: String,
|
||||||
|
|
||||||
|
/// The kind of the code action.
|
||||||
|
/// Used to filter code actions.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub kind: Option<CodeActionKind>,
|
||||||
|
|
||||||
|
/// The diagnostics that this code action resolves.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub diagnostics: Option<Vec<Diagnostic>>,
|
||||||
|
|
||||||
|
/// The workspace edit this code action performs.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub edit: Option<WorkspaceEdit>,
|
||||||
|
|
||||||
|
/// A command this code action executes. If a code action
|
||||||
|
/// provides an edit and a command, first the edit is
|
||||||
|
/// executed and then the command.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub command: Option<Command>,
|
||||||
|
|
||||||
|
/// Marks this as a preferred action. Preferred actions are used by the `auto fix` command and can be targeted
|
||||||
|
/// by keybindings.
|
||||||
|
/// A quick fix should be marked preferred if it properly addresses the underlying error.
|
||||||
|
/// A refactoring should be marked preferred if it is the most reasonable choice of actions to take.
|
||||||
|
///
|
||||||
|
/// @since 3.15.0
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub is_preferred: Option<bool>,
|
||||||
|
|
||||||
|
/// Marks that the code action cannot currently be applied.
|
||||||
|
///
|
||||||
|
/// Clients should follow the following guidelines regarding disabled code actions:
|
||||||
|
///
|
||||||
|
/// - Disabled code actions are not shown in automatic
|
||||||
|
/// [lightbulb](https://code.visualstudio.com/docs/editor/editingevolved#_code-action)
|
||||||
|
/// code action menu.
|
||||||
|
///
|
||||||
|
/// - Disabled actions are shown as faded out in the code action menu when the user request
|
||||||
|
/// a more specific type of code action, such as refactorings.
|
||||||
|
///
|
||||||
|
/// - If the user has a keybinding that auto applies a code action and only a disabled code
|
||||||
|
/// actions are returned, the client should show the user an error message with `reason`
|
||||||
|
/// in the editor.
|
||||||
|
///
|
||||||
|
/// @since 3.16.0
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub disabled: Option<CodeActionDisabled>,
|
||||||
|
|
||||||
|
/// A data entry field that is preserved on a code action between
|
||||||
|
/// a `textDocument/codeAction` and a `codeAction/resolve` request.
|
||||||
|
///
|
||||||
|
/// @since 3.16.0
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub data: Option<Value>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct CodeActionDisabled {
|
||||||
|
/// Human readable description of why the code action is currently disabled.
|
||||||
|
///
|
||||||
|
/// This is displayed in the code actions UI.
|
||||||
|
pub reason: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The reason why code actions were requested.
|
||||||
|
///
|
||||||
|
/// @since 3.17.0
|
||||||
|
#[derive(Eq, PartialEq, Clone, Copy, Deserialize, Serialize)]
|
||||||
|
#[serde(transparent)]
|
||||||
|
pub struct CodeActionTriggerKind(i32);
|
||||||
|
lsp_enum! {
|
||||||
|
impl CodeActionTriggerKind {
|
||||||
|
/// Code actions were explicitly requested by the user or by an extension.
|
||||||
|
pub const INVOKED: CodeActionTriggerKind = CodeActionTriggerKind(1);
|
||||||
|
|
||||||
|
/// Code actions were requested automatically.
|
||||||
|
///
|
||||||
|
/// This typically happens when current selection in a file changes, but can
|
||||||
|
/// also be triggered when file content changes.
|
||||||
|
pub const AUTOMATIC: CodeActionTriggerKind = CodeActionTriggerKind(2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Contains additional diagnostic information about the context in which
|
||||||
|
/// a code action is run.
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct CodeActionContext {
|
||||||
|
/// An array of diagnostics.
|
||||||
|
pub diagnostics: Vec<Diagnostic>,
|
||||||
|
|
||||||
|
/// Requested kind of actions to return.
|
||||||
|
///
|
||||||
|
/// Actions not of this kind are filtered out by the client before being shown. So servers
|
||||||
|
/// can omit computing them.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub only: Option<Vec<CodeActionKind>>,
|
||||||
|
|
||||||
|
/// The reason why code actions were requested.
|
||||||
|
///
|
||||||
|
/// @since 3.17.0
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub trigger_kind: Option<CodeActionTriggerKind>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize, Default)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct CodeActionOptions {
|
||||||
|
/// CodeActionKinds that this server may return.
|
||||||
|
///
|
||||||
|
/// The list of kinds may be generic, such as `CodeActionKind.Refactor`, or the server
|
||||||
|
/// may list out every specific kind they provide.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub code_action_kinds: Option<Vec<CodeActionKind>>,
|
||||||
|
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub work_done_progress_options: WorkDoneProgressOptions,
|
||||||
|
|
||||||
|
/// The server provides support to resolve additional
|
||||||
|
/// information for a code action.
|
||||||
|
///
|
||||||
|
/// @since 3.16.0
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub resolve_provider: Option<bool>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use crate::tests::test_serialization;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_code_action_response() {
|
||||||
|
test_serialization(
|
||||||
|
&vec![
|
||||||
|
CodeActionOrCommand::Command(Command {
|
||||||
|
title: "title".to_string(),
|
||||||
|
command: "command".to_string(),
|
||||||
|
arguments: None,
|
||||||
|
}),
|
||||||
|
CodeActionOrCommand::CodeAction(CodeAction {
|
||||||
|
title: "title".to_string(),
|
||||||
|
kind: Some(CodeActionKind::QUICKFIX),
|
||||||
|
command: None,
|
||||||
|
diagnostics: None,
|
||||||
|
edit: None,
|
||||||
|
is_preferred: None,
|
||||||
|
..CodeAction::default()
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
r#"[{"title":"title","command":"command"},{"title":"title","kind":"quickfix"}]"#,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,66 @@
|
|||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use serde_json::Value;
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
Command, DynamicRegistrationClientCapabilities, PartialResultParams, Range,
|
||||||
|
TextDocumentIdentifier, WorkDoneProgressParams,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub type CodeLensClientCapabilities = DynamicRegistrationClientCapabilities;
|
||||||
|
|
||||||
|
/// Code Lens options.
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize, Copy)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct CodeLensOptions {
|
||||||
|
/// Code lens has a resolve provider as well.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub resolve_provider: Option<bool>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct CodeLensParams {
|
||||||
|
/// The document to request code lens for.
|
||||||
|
pub text_document: TextDocumentIdentifier,
|
||||||
|
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub work_done_progress_params: WorkDoneProgressParams,
|
||||||
|
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub partial_result_params: PartialResultParams,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A code lens represents a command that should be shown along with
|
||||||
|
/// source text, like the number of references, a way to run tests, etc.
|
||||||
|
///
|
||||||
|
/// A code lens is _unresolved_ when no command is associated to it. For performance
|
||||||
|
/// reasons the creation of a code lens and resolving should be done in two stages.
|
||||||
|
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct CodeLens {
|
||||||
|
/// The range in which this code lens is valid. Should only span a single line.
|
||||||
|
pub range: Range,
|
||||||
|
|
||||||
|
/// The command this code lens represents.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub command: Option<Command>,
|
||||||
|
|
||||||
|
/// A data entry field that is preserved on a code lens item between
|
||||||
|
/// a code lens and a code lens resolve request.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub data: Option<Value>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct CodeLensWorkspaceClientCapabilities {
|
||||||
|
/// Whether the client implementation supports a refresh request sent from the
|
||||||
|
/// server to the client.
|
||||||
|
///
|
||||||
|
/// Note that this event is global and will force the client to refresh all
|
||||||
|
/// code lenses currently shown. It should be used with absolute care and is
|
||||||
|
/// useful for situation where a server for example detect a project wide
|
||||||
|
/// change that requires such a calculation.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub refresh_support: Option<bool>,
|
||||||
|
}
|
@ -0,0 +1,122 @@
|
|||||||
|
use crate::{
|
||||||
|
DocumentSelector, DynamicRegistrationClientCapabilities, PartialResultParams, Range,
|
||||||
|
TextDocumentIdentifier, TextEdit, WorkDoneProgressParams,
|
||||||
|
};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
pub type DocumentColorClientCapabilities = DynamicRegistrationClientCapabilities;
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct ColorProviderOptions {}
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct StaticTextDocumentColorProviderOptions {
|
||||||
|
/// A document selector to identify the scope of the registration. If set to null
|
||||||
|
/// the document selector provided on the client side will be used.
|
||||||
|
pub document_selector: Option<DocumentSelector>,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub id: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
|
||||||
|
#[serde(untagged)]
|
||||||
|
pub enum ColorProviderCapability {
|
||||||
|
Simple(bool),
|
||||||
|
ColorProvider(ColorProviderOptions),
|
||||||
|
Options(StaticTextDocumentColorProviderOptions),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<ColorProviderOptions> for ColorProviderCapability {
|
||||||
|
fn from(from: ColorProviderOptions) -> Self {
|
||||||
|
Self::ColorProvider(from)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<StaticTextDocumentColorProviderOptions> for ColorProviderCapability {
|
||||||
|
fn from(from: StaticTextDocumentColorProviderOptions) -> Self {
|
||||||
|
Self::Options(from)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<bool> for ColorProviderCapability {
|
||||||
|
fn from(from: bool) -> Self {
|
||||||
|
Self::Simple(from)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct DocumentColorParams {
|
||||||
|
/// The text document
|
||||||
|
pub text_document: TextDocumentIdentifier,
|
||||||
|
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub work_done_progress_params: WorkDoneProgressParams,
|
||||||
|
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub partial_result_params: PartialResultParams,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct ColorInformation {
|
||||||
|
/// The range in the document where this color appears.
|
||||||
|
pub range: Range,
|
||||||
|
/// The actual color value for this color range.
|
||||||
|
pub color: Color,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize, Copy)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct Color {
|
||||||
|
/// The red component of this color in the range [0-1].
|
||||||
|
pub red: f32,
|
||||||
|
/// The green component of this color in the range [0-1].
|
||||||
|
pub green: f32,
|
||||||
|
/// The blue component of this color in the range [0-1].
|
||||||
|
pub blue: f32,
|
||||||
|
/// The alpha component of this color in the range [0-1].
|
||||||
|
pub alpha: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct ColorPresentationParams {
|
||||||
|
/// The text document.
|
||||||
|
pub text_document: TextDocumentIdentifier,
|
||||||
|
|
||||||
|
/// The color information to request presentations for.
|
||||||
|
pub color: Color,
|
||||||
|
|
||||||
|
/// The range where the color would be inserted. Serves as a context.
|
||||||
|
pub range: Range,
|
||||||
|
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub work_done_progress_params: WorkDoneProgressParams,
|
||||||
|
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub partial_result_params: PartialResultParams,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Eq, Deserialize, Serialize, Default, Clone)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct ColorPresentation {
|
||||||
|
/// The label of this color presentation. It will be shown on the color
|
||||||
|
/// picker header. By default this is also the text that is inserted when selecting
|
||||||
|
/// this color presentation.
|
||||||
|
pub label: String,
|
||||||
|
|
||||||
|
/// An [edit](#TextEdit) which is applied to a document when selecting
|
||||||
|
/// this presentation for the color. When `falsy` the [label](#ColorPresentation.label)
|
||||||
|
/// is used.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub text_edit: Option<TextEdit>,
|
||||||
|
|
||||||
|
/// An optional array of additional [text edits](#TextEdit) that are applied when
|
||||||
|
/// selecting this color presentation. Edits must not overlap with the main [edit](#ColorPresentation.textEdit) nor with themselves.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub additional_text_edits: Option<Vec<TextEdit>>,
|
||||||
|
}
|
@ -0,0 +1,622 @@
|
|||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
Command, Documentation, MarkupKind, PartialResultParams, TagSupport,
|
||||||
|
TextDocumentPositionParams, TextDocumentRegistrationOptions, TextEdit, WorkDoneProgressOptions,
|
||||||
|
WorkDoneProgressParams,
|
||||||
|
};
|
||||||
|
|
||||||
|
use crate::Range;
|
||||||
|
use serde_json::Value;
|
||||||
|
use std::fmt::Debug;
|
||||||
|
|
||||||
|
/// Defines how to interpret the insert text in a completion item
|
||||||
|
#[derive(Eq, PartialEq, Clone, Copy, Serialize, Deserialize)]
|
||||||
|
#[serde(transparent)]
|
||||||
|
pub struct InsertTextFormat(i32);
|
||||||
|
lsp_enum! {
|
||||||
|
impl InsertTextFormat {
|
||||||
|
pub const PLAIN_TEXT: InsertTextFormat = InsertTextFormat(1);
|
||||||
|
pub const SNIPPET: InsertTextFormat = InsertTextFormat(2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The kind of a completion entry.
|
||||||
|
#[derive(Eq, PartialEq, Clone, Copy, Serialize, Deserialize)]
|
||||||
|
#[serde(transparent)]
|
||||||
|
pub struct CompletionItemKind(i32);
|
||||||
|
lsp_enum! {
|
||||||
|
impl CompletionItemKind {
|
||||||
|
pub const TEXT: CompletionItemKind = CompletionItemKind(1);
|
||||||
|
pub const METHOD: CompletionItemKind = CompletionItemKind(2);
|
||||||
|
pub const FUNCTION: CompletionItemKind = CompletionItemKind(3);
|
||||||
|
pub const CONSTRUCTOR: CompletionItemKind = CompletionItemKind(4);
|
||||||
|
pub const FIELD: CompletionItemKind = CompletionItemKind(5);
|
||||||
|
pub const VARIABLE: CompletionItemKind = CompletionItemKind(6);
|
||||||
|
pub const CLASS: CompletionItemKind = CompletionItemKind(7);
|
||||||
|
pub const INTERFACE: CompletionItemKind = CompletionItemKind(8);
|
||||||
|
pub const MODULE: CompletionItemKind = CompletionItemKind(9);
|
||||||
|
pub const PROPERTY: CompletionItemKind = CompletionItemKind(10);
|
||||||
|
pub const UNIT: CompletionItemKind = CompletionItemKind(11);
|
||||||
|
pub const VALUE: CompletionItemKind = CompletionItemKind(12);
|
||||||
|
pub const ENUM: CompletionItemKind = CompletionItemKind(13);
|
||||||
|
pub const KEYWORD: CompletionItemKind = CompletionItemKind(14);
|
||||||
|
pub const SNIPPET: CompletionItemKind = CompletionItemKind(15);
|
||||||
|
pub const COLOR: CompletionItemKind = CompletionItemKind(16);
|
||||||
|
pub const FILE: CompletionItemKind = CompletionItemKind(17);
|
||||||
|
pub const REFERENCE: CompletionItemKind = CompletionItemKind(18);
|
||||||
|
pub const FOLDER: CompletionItemKind = CompletionItemKind(19);
|
||||||
|
pub const ENUM_MEMBER: CompletionItemKind = CompletionItemKind(20);
|
||||||
|
pub const CONSTANT: CompletionItemKind = CompletionItemKind(21);
|
||||||
|
pub const STRUCT: CompletionItemKind = CompletionItemKind(22);
|
||||||
|
pub const EVENT: CompletionItemKind = CompletionItemKind(23);
|
||||||
|
pub const OPERATOR: CompletionItemKind = CompletionItemKind(24);
|
||||||
|
pub const TYPE_PARAMETER: CompletionItemKind = CompletionItemKind(25);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct CompletionItemCapability {
|
||||||
|
/// Client supports snippets as insert text.
|
||||||
|
///
|
||||||
|
/// A snippet can define tab stops and placeholders with `$1`, `$2`
|
||||||
|
/// and `${3:foo}`. `$0` defines the final tab stop, it defaults to
|
||||||
|
/// the end of the snippet. Placeholders with equal identifiers are linked,
|
||||||
|
/// that is typing in one will update others too.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub snippet_support: Option<bool>,
|
||||||
|
|
||||||
|
/// Client supports commit characters on a completion item.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub commit_characters_support: Option<bool>,
|
||||||
|
|
||||||
|
/// Client supports the follow content formats for the documentation
|
||||||
|
/// property. The order describes the preferred format of the client.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub documentation_format: Option<Vec<MarkupKind>>,
|
||||||
|
|
||||||
|
/// Client supports the deprecated property on a completion item.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub deprecated_support: Option<bool>,
|
||||||
|
|
||||||
|
/// Client supports the preselect property on a completion item.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub preselect_support: Option<bool>,
|
||||||
|
|
||||||
|
/// Client supports the tag property on a completion item. Clients supporting
|
||||||
|
/// tags have to handle unknown tags gracefully. Clients especially need to
|
||||||
|
/// preserve unknown tags when sending a completion item back to the server in
|
||||||
|
/// a resolve call.
|
||||||
|
#[serde(
|
||||||
|
default,
|
||||||
|
skip_serializing_if = "Option::is_none",
|
||||||
|
deserialize_with = "TagSupport::deserialize_compat"
|
||||||
|
)]
|
||||||
|
pub tag_support: Option<TagSupport<CompletionItemTag>>,
|
||||||
|
|
||||||
|
/// Client support insert replace edit to control different behavior if a
|
||||||
|
/// completion item is inserted in the text or should replace text.
|
||||||
|
///
|
||||||
|
/// @since 3.16.0
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub insert_replace_support: Option<bool>,
|
||||||
|
|
||||||
|
/// Indicates which properties a client can resolve lazily on a completion
|
||||||
|
/// item. Before version 3.16.0 only the predefined properties `documentation`
|
||||||
|
/// and `details` could be resolved lazily.
|
||||||
|
///
|
||||||
|
/// @since 3.16.0
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub resolve_support: Option<CompletionItemCapabilityResolveSupport>,
|
||||||
|
|
||||||
|
/// The client supports the `insertTextMode` property on
|
||||||
|
/// a completion item to override the whitespace handling mode
|
||||||
|
/// as defined by the client.
|
||||||
|
///
|
||||||
|
/// @since 3.16.0
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub insert_text_mode_support: Option<InsertTextModeSupport>,
|
||||||
|
|
||||||
|
/// The client has support for completion item label
|
||||||
|
/// details (see also `CompletionItemLabelDetails`).
|
||||||
|
///
|
||||||
|
/// @since 3.17.0
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub label_details_support: Option<bool>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct CompletionItemCapabilityResolveSupport {
|
||||||
|
/// The properties that a client can resolve lazily.
|
||||||
|
pub properties: Vec<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct InsertTextModeSupport {
|
||||||
|
pub value_set: Vec<InsertTextMode>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// How whitespace and indentation is handled during completion
|
||||||
|
/// item insertion.
|
||||||
|
///
|
||||||
|
/// @since 3.16.0
|
||||||
|
#[derive(Eq, PartialEq, Clone, Copy, Serialize, Deserialize)]
|
||||||
|
#[serde(transparent)]
|
||||||
|
pub struct InsertTextMode(i32);
|
||||||
|
lsp_enum! {
|
||||||
|
impl InsertTextMode {
|
||||||
|
/// The insertion or replace strings is taken as it is. If the
|
||||||
|
/// value is multi line the lines below the cursor will be
|
||||||
|
/// inserted using the indentation defined in the string value.
|
||||||
|
/// The client will not apply any kind of adjustments to the
|
||||||
|
/// string.
|
||||||
|
pub const AS_IS: InsertTextMode = InsertTextMode(1);
|
||||||
|
|
||||||
|
/// The editor adjusts leading whitespace of new lines so that
|
||||||
|
/// they match the indentation up to the cursor of the line for
|
||||||
|
/// which the item is accepted.
|
||||||
|
///
|
||||||
|
/// Consider a line like this: `<2tabs><cursor><3tabs>foo`. Accepting a
|
||||||
|
/// multi line completion item is indented using 2 tabs all
|
||||||
|
/// following lines inserted will be indented using 2 tabs as well.
|
||||||
|
pub const ADJUST_INDENTATION: InsertTextMode = InsertTextMode(2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Eq, PartialEq, Clone, Deserialize, Serialize)]
|
||||||
|
#[serde(transparent)]
|
||||||
|
pub struct CompletionItemTag(i32);
|
||||||
|
lsp_enum! {
|
||||||
|
impl CompletionItemTag {
|
||||||
|
pub const DEPRECATED: CompletionItemTag = CompletionItemTag(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct CompletionItemKindCapability {
|
||||||
|
/// The completion item kind values the client supports. When this
|
||||||
|
/// property exists the client also guarantees that it will
|
||||||
|
/// handle values outside its set gracefully and falls back
|
||||||
|
/// to a default value when unknown.
|
||||||
|
///
|
||||||
|
/// If this property is not present the client only supports
|
||||||
|
/// the completion items kinds from `Text` to `Reference` as defined in
|
||||||
|
/// the initial version of the protocol.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub value_set: Option<Vec<CompletionItemKind>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct CompletionListCapability {
|
||||||
|
/// The client supports the following itemDefaults on
|
||||||
|
/// a completion list.
|
||||||
|
///
|
||||||
|
/// The value lists the supported property names of the
|
||||||
|
/// `CompletionList.itemDefaults` object. If omitted
|
||||||
|
/// no properties are supported.
|
||||||
|
///
|
||||||
|
/// @since 3.17.0
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub item_defaults: Option<Vec<String>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct CompletionClientCapabilities {
|
||||||
|
/// Whether completion supports dynamic registration.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub dynamic_registration: Option<bool>,
|
||||||
|
|
||||||
|
/// The client supports the following `CompletionItem` specific
|
||||||
|
/// capabilities.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub completion_item: Option<CompletionItemCapability>,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub completion_item_kind: Option<CompletionItemKindCapability>,
|
||||||
|
|
||||||
|
/// The client supports to send additional context information for a
|
||||||
|
/// `textDocument/completion` request.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub context_support: Option<bool>,
|
||||||
|
|
||||||
|
/// The client's default when the completion item doesn't provide a
|
||||||
|
/// `insertTextMode` property.
|
||||||
|
///
|
||||||
|
/// @since 3.17.0
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub insert_text_mode: Option<InsertTextMode>,
|
||||||
|
|
||||||
|
/// The client supports the following `CompletionList` specific
|
||||||
|
/// capabilities.
|
||||||
|
///
|
||||||
|
/// @since 3.17.0
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub completion_list: Option<CompletionListCapability>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A special text edit to provide an insert and a replace operation.
|
||||||
|
///
|
||||||
|
/// @since 3.16.0
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct InsertReplaceEdit {
|
||||||
|
/// The string to be inserted.
|
||||||
|
pub new_text: String,
|
||||||
|
|
||||||
|
/// The range if the insert is requested
|
||||||
|
pub insert: Range,
|
||||||
|
|
||||||
|
/// The range if the replace is requested.
|
||||||
|
pub replace: Range,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
|
||||||
|
#[serde(untagged)]
|
||||||
|
pub enum CompletionTextEdit {
|
||||||
|
Edit(TextEdit),
|
||||||
|
InsertAndReplace(InsertReplaceEdit),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<TextEdit> for CompletionTextEdit {
|
||||||
|
fn from(edit: TextEdit) -> Self {
|
||||||
|
CompletionTextEdit::Edit(edit)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<InsertReplaceEdit> for CompletionTextEdit {
|
||||||
|
fn from(edit: InsertReplaceEdit) -> Self {
|
||||||
|
CompletionTextEdit::InsertAndReplace(edit)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Completion options.
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct CompletionOptions {
|
||||||
|
/// The server provides support to resolve additional information for a completion item.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub resolve_provider: Option<bool>,
|
||||||
|
|
||||||
|
/// Most tools trigger completion request automatically without explicitly
|
||||||
|
/// requesting it using a keyboard shortcut (e.g. Ctrl+Space). Typically they
|
||||||
|
/// do so when the user starts to type an identifier. For example if the user
|
||||||
|
/// types `c` in a JavaScript file code complete will automatically pop up
|
||||||
|
/// present `console` besides others as a completion item. Characters that
|
||||||
|
/// make up identifiers don't need to be listed here.
|
||||||
|
///
|
||||||
|
/// If code complete should automatically be trigger on characters not being
|
||||||
|
/// valid inside an identifier (for example `.` in JavaScript) list them in
|
||||||
|
/// `triggerCharacters`.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub trigger_characters: Option<Vec<String>>,
|
||||||
|
|
||||||
|
/// The list of all possible characters that commit a completion. This field
|
||||||
|
/// can be used if clients don't support individual commit characters per
|
||||||
|
/// completion item. See client capability
|
||||||
|
/// `completion.completionItem.commitCharactersSupport`.
|
||||||
|
///
|
||||||
|
/// If a server provides both `allCommitCharacters` and commit characters on
|
||||||
|
/// an individual completion item the ones on the completion item win.
|
||||||
|
///
|
||||||
|
/// @since 3.2.0
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub all_commit_characters: Option<Vec<String>>,
|
||||||
|
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub work_done_progress_options: WorkDoneProgressOptions,
|
||||||
|
|
||||||
|
/// The server supports the following `CompletionItem` specific
|
||||||
|
/// capabilities.
|
||||||
|
///
|
||||||
|
/// @since 3.17.0
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub completion_item: Option<CompletionOptionsCompletionItem>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct CompletionOptionsCompletionItem {
|
||||||
|
/// The server has support for completion item label
|
||||||
|
/// details (see also `CompletionItemLabelDetails`) when receiving
|
||||||
|
/// a completion item in a resolve call.
|
||||||
|
///
|
||||||
|
/// @since 3.17.0
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub label_details_support: Option<bool>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct CompletionRegistrationOptions {
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub text_document_registration_options: TextDocumentRegistrationOptions,
|
||||||
|
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub completion_options: CompletionOptions,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
|
||||||
|
#[serde(untagged)]
|
||||||
|
pub enum CompletionResponse {
|
||||||
|
Array(Vec<CompletionItem>),
|
||||||
|
List(CompletionList),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Vec<CompletionItem>> for CompletionResponse {
|
||||||
|
fn from(items: Vec<CompletionItem>) -> Self {
|
||||||
|
CompletionResponse::Array(items)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<CompletionList> for CompletionResponse {
|
||||||
|
fn from(list: CompletionList) -> Self {
|
||||||
|
CompletionResponse::List(list)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct CompletionParams {
|
||||||
|
// This field was "mixed-in" from TextDocumentPositionParams
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub text_document_position: TextDocumentPositionParams,
|
||||||
|
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub work_done_progress_params: WorkDoneProgressParams,
|
||||||
|
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub partial_result_params: PartialResultParams,
|
||||||
|
|
||||||
|
// CompletionParams properties:
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub context: Option<CompletionContext>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct CompletionContext {
|
||||||
|
/// How the completion was triggered.
|
||||||
|
pub trigger_kind: CompletionTriggerKind,
|
||||||
|
|
||||||
|
/// The trigger character (a single character) that has trigger code complete.
|
||||||
|
/// Is undefined if `triggerKind !== CompletionTriggerKind.TriggerCharacter`
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub trigger_character: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// How a completion was triggered.
|
||||||
|
#[derive(Eq, PartialEq, Clone, Copy, Deserialize, Serialize)]
|
||||||
|
#[serde(transparent)]
|
||||||
|
pub struct CompletionTriggerKind(i32);
|
||||||
|
lsp_enum! {
|
||||||
|
impl CompletionTriggerKind {
|
||||||
|
pub const INVOKED: CompletionTriggerKind = CompletionTriggerKind(1);
|
||||||
|
pub const TRIGGER_CHARACTER: CompletionTriggerKind = CompletionTriggerKind(2);
|
||||||
|
pub const TRIGGER_FOR_INCOMPLETE_COMPLETIONS: CompletionTriggerKind = CompletionTriggerKind(3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Represents a collection of [completion items](#CompletionItem) to be presented
|
||||||
|
/// in the editor.
|
||||||
|
#[derive(Debug, PartialEq, Clone, Default, Deserialize, Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct CompletionList {
|
||||||
|
/// This list it not complete. Further typing should result in recomputing
|
||||||
|
/// this list.
|
||||||
|
pub is_incomplete: bool,
|
||||||
|
|
||||||
|
/// The completion items.
|
||||||
|
pub items: Vec<CompletionItem>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Default, Deserialize, Serialize, Clone)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct CompletionItem {
|
||||||
|
/// The label of this completion item. By default
|
||||||
|
/// also the text that is inserted when selecting
|
||||||
|
/// this completion.
|
||||||
|
pub label: String,
|
||||||
|
|
||||||
|
/// Additional details for the label
|
||||||
|
///
|
||||||
|
/// @since 3.17.0
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub label_details: Option<CompletionItemLabelDetails>,
|
||||||
|
|
||||||
|
/// The kind of this completion item. Based of the kind
|
||||||
|
/// an icon is chosen by the editor.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub kind: Option<CompletionItemKind>,
|
||||||
|
|
||||||
|
/// A human-readable string with additional information
|
||||||
|
/// about this item, like type or symbol information.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub detail: Option<String>,
|
||||||
|
|
||||||
|
/// A human-readable string that represents a doc-comment.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub documentation: Option<Documentation>,
|
||||||
|
|
||||||
|
/// Indicates if this item is deprecated.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub deprecated: Option<bool>,
|
||||||
|
|
||||||
|
/// Select this item when showing.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub preselect: Option<bool>,
|
||||||
|
|
||||||
|
/// A string that should be used when comparing this item
|
||||||
|
/// with other items. When `falsy` the label is used
|
||||||
|
/// as the sort text for this item.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub sort_text: Option<String>,
|
||||||
|
|
||||||
|
/// A string that should be used when filtering a set of
|
||||||
|
/// completion items. When `falsy` the label is used as the
|
||||||
|
/// filter text for this item.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub filter_text: Option<String>,
|
||||||
|
|
||||||
|
/// A string that should be inserted into a document when selecting
|
||||||
|
/// this completion. When `falsy` the label is used as the insert text
|
||||||
|
/// for this item.
|
||||||
|
///
|
||||||
|
/// The `insertText` is subject to interpretation by the client side.
|
||||||
|
/// Some tools might not take the string literally. For example
|
||||||
|
/// VS Code when code complete is requested in this example
|
||||||
|
/// `con<cursor position>` and a completion item with an `insertText` of
|
||||||
|
/// `console` is provided it will only insert `sole`. Therefore it is
|
||||||
|
/// recommended to use `textEdit` instead since it avoids additional client
|
||||||
|
/// side interpretation.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub insert_text: Option<String>,
|
||||||
|
|
||||||
|
/// The format of the insert text. The format applies to both the `insertText` property
|
||||||
|
/// and the `newText` property of a provided `textEdit`. If omitted defaults to `InsertTextFormat.PlainText`.
|
||||||
|
///
|
||||||
|
/// @since 3.16.0
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub insert_text_format: Option<InsertTextFormat>,
|
||||||
|
|
||||||
|
/// How whitespace and indentation is handled during completion
|
||||||
|
/// item insertion. If not provided the client's default value depends on
|
||||||
|
/// the `textDocument.completion.insertTextMode` client capability.
|
||||||
|
///
|
||||||
|
/// @since 3.16.0
|
||||||
|
/// @since 3.17.0 - support for `textDocument.completion.insertTextMode`
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub insert_text_mode: Option<InsertTextMode>,
|
||||||
|
|
||||||
|
/// An edit which is applied to a document when selecting
|
||||||
|
/// this completion. When an edit is provided the value of
|
||||||
|
/// insertText is ignored.
|
||||||
|
///
|
||||||
|
/// Most editors support two different operation when accepting a completion item. One is to insert a
|
||||||
|
|
||||||
|
/// completion text and the other is to replace an existing text with a completion text. Since this can
|
||||||
|
/// usually not predetermined by a server it can report both ranges. Clients need to signal support for
|
||||||
|
/// `InsertReplaceEdits` via the `textDocument.completion.insertReplaceSupport` client capability
|
||||||
|
/// property.
|
||||||
|
///
|
||||||
|
/// *Note 1:* The text edit's range as well as both ranges from a insert replace edit must be a
|
||||||
|
/// [single line] and they must contain the position at which completion has been requested.
|
||||||
|
/// *Note 2:* If an `InsertReplaceEdit` is returned the edit's insert range must be a prefix of
|
||||||
|
/// the edit's replace range, that means it must be contained and starting at the same position.
|
||||||
|
///
|
||||||
|
/// @since 3.16.0 additional type `InsertReplaceEdit`
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub text_edit: Option<CompletionTextEdit>,
|
||||||
|
|
||||||
|
/// An optional array of additional text edits that are applied when
|
||||||
|
/// selecting this completion. Edits must not overlap with the main edit
|
||||||
|
/// nor with themselves.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub additional_text_edits: Option<Vec<TextEdit>>,
|
||||||
|
|
||||||
|
/// An optional command that is executed *after* inserting this completion. *Note* that
|
||||||
|
/// additional modifications to the current document should be described with the
|
||||||
|
/// additionalTextEdits-property.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub command: Option<Command>,
|
||||||
|
|
||||||
|
/// An optional set of characters that when pressed while this completion is
|
||||||
|
/// active will accept it first and then type that character. *Note* that all
|
||||||
|
/// commit characters should have `length=1` and that superfluous characters
|
||||||
|
/// will be ignored.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub commit_characters: Option<Vec<String>>,
|
||||||
|
|
||||||
|
/// An data entry field that is preserved on a completion item between
|
||||||
|
/// a completion and a completion resolve request.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub data: Option<Value>,
|
||||||
|
|
||||||
|
/// Tags for this completion item.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub tags: Option<Vec<CompletionItemTag>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CompletionItem {
|
||||||
|
/// Create a CompletionItem with the minimum possible info (label and detail).
|
||||||
|
pub fn new_simple(label: String, detail: String) -> CompletionItem {
|
||||||
|
CompletionItem {
|
||||||
|
label,
|
||||||
|
detail: Some(detail),
|
||||||
|
..Self::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Additional details for a completion item label.
|
||||||
|
///
|
||||||
|
/// @since 3.17.0
|
||||||
|
#[derive(Debug, PartialEq, Default, Deserialize, Serialize, Clone)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct CompletionItemLabelDetails {
|
||||||
|
/// An optional string which is rendered less prominently directly after
|
||||||
|
/// {@link CompletionItemLabel.label label}, without any spacing. Should be
|
||||||
|
/// used for function signatures or type annotations.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub detail: Option<String>,
|
||||||
|
|
||||||
|
/// An optional string which is rendered less prominently after
|
||||||
|
/// {@link CompletionItemLabel.detail}. Should be used for fully qualified
|
||||||
|
/// names or file path.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub description: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use crate::tests::test_deserialization;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_tag_support_deserialization() {
|
||||||
|
let empty = CompletionItemCapability {
|
||||||
|
tag_support: None,
|
||||||
|
..CompletionItemCapability::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
test_deserialization(r#"{}"#, &empty);
|
||||||
|
test_deserialization(r#"{"tagSupport": false}"#, &empty);
|
||||||
|
|
||||||
|
let t = CompletionItemCapability {
|
||||||
|
tag_support: Some(TagSupport { value_set: vec![] }),
|
||||||
|
..CompletionItemCapability::default()
|
||||||
|
};
|
||||||
|
test_deserialization(r#"{"tagSupport": true}"#, &t);
|
||||||
|
|
||||||
|
let t = CompletionItemCapability {
|
||||||
|
tag_support: Some(TagSupport {
|
||||||
|
value_set: vec![CompletionItemTag::DEPRECATED],
|
||||||
|
}),
|
||||||
|
..CompletionItemCapability::default()
|
||||||
|
};
|
||||||
|
test_deserialization(r#"{"tagSupport": {"valueSet": [1]}}"#, &t);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_debug_enum() {
|
||||||
|
assert_eq!(format!("{:?}", CompletionItemKind::TEXT), "Text");
|
||||||
|
assert_eq!(
|
||||||
|
format!("{:?}", CompletionItemKind::TYPE_PARAMETER),
|
||||||
|
"TypeParameter"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_try_from_enum() {
|
||||||
|
use std::convert::TryInto;
|
||||||
|
assert_eq!("Text".try_into(), Ok(CompletionItemKind::TEXT));
|
||||||
|
assert_eq!(
|
||||||
|
"TypeParameter".try_into(),
|
||||||
|
Ok(CompletionItemKind::TYPE_PARAMETER)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,269 @@
|
|||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use url::Url;
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
Diagnostic, PartialResultParams, StaticRegistrationOptions, TextDocumentIdentifier,
|
||||||
|
TextDocumentRegistrationOptions, WorkDoneProgressOptions, WorkDoneProgressParams,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Client capabilities specific to diagnostic pull requests.
|
||||||
|
///
|
||||||
|
/// @since 3.17.0
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct DiagnosticClientCapabilities {
|
||||||
|
/// Whether implementation supports dynamic registration.
|
||||||
|
///
|
||||||
|
/// If this is set to `true` the client supports the new `(TextDocumentRegistrationOptions &
|
||||||
|
/// StaticRegistrationOptions)` return value for the corresponding server capability as well.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub dynamic_registration: Option<bool>,
|
||||||
|
|
||||||
|
/// Whether the clients supports related documents for document diagnostic pulls.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub related_document_support: Option<bool>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Diagnostic options.
|
||||||
|
///
|
||||||
|
/// @since 3.17.0
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct DiagnosticOptions {
|
||||||
|
/// An optional identifier under which the diagnostics are
|
||||||
|
/// managed by the client.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub identifier: Option<String>,
|
||||||
|
|
||||||
|
/// Whether the language has inter file dependencies, meaning that editing code in one file can
|
||||||
|
/// result in a different diagnostic set in another file. Inter file dependencies are common
|
||||||
|
/// for most programming languages and typically uncommon for linters.
|
||||||
|
pub inter_file_dependencies: bool,
|
||||||
|
|
||||||
|
/// The server provides support for workspace diagnostics as well.
|
||||||
|
pub workspace_diagnostics: bool,
|
||||||
|
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub work_done_progress_options: WorkDoneProgressOptions,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Diagnostic registration options.
|
||||||
|
///
|
||||||
|
/// @since 3.17.0
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct DiagnosticRegistrationOptions {
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub text_document_registration_options: TextDocumentRegistrationOptions,
|
||||||
|
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub diagnostic_options: DiagnosticOptions,
|
||||||
|
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub static_registration_options: StaticRegistrationOptions,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
|
||||||
|
#[serde(untagged)]
|
||||||
|
pub enum DiagnosticServerCapabilities {
|
||||||
|
Options(DiagnosticOptions),
|
||||||
|
RegistrationOptions(DiagnosticRegistrationOptions),
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Parameters of the document diagnostic request.
|
||||||
|
///
|
||||||
|
/// @since 3.17.0
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct DocumentDiagnosticParams {
|
||||||
|
/// The text document.
|
||||||
|
pub text_document: TextDocumentIdentifier,
|
||||||
|
|
||||||
|
/// The additional identifier provided during registration.
|
||||||
|
pub identifier: Option<String>,
|
||||||
|
|
||||||
|
/// The result ID of a previous response if provided.
|
||||||
|
pub previous_result_id: Option<String>,
|
||||||
|
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub work_done_progress_params: WorkDoneProgressParams,
|
||||||
|
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub partial_result_params: PartialResultParams,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A diagnostic report with a full set of problems.
|
||||||
|
///
|
||||||
|
/// @since 3.17.0
|
||||||
|
#[derive(Debug, PartialEq, Default, Deserialize, Serialize, Clone)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct FullDocumentDiagnosticReport {
|
||||||
|
/// An optional result ID. If provided it will be sent on the next diagnostic request for the
|
||||||
|
/// same document.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub result_id: Option<String>,
|
||||||
|
|
||||||
|
/// The actual items.
|
||||||
|
pub items: Vec<Diagnostic>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A diagnostic report indicating that the last returned report is still accurate.
|
||||||
|
///
|
||||||
|
/// A server can only return `unchanged` if result ids are provided.
|
||||||
|
///
|
||||||
|
/// @since 3.17.0
|
||||||
|
#[derive(Debug, PartialEq, Deserialize, Serialize, Clone)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct UnchangedDocumentDiagnosticReport {
|
||||||
|
/// A result ID which will be sent on the next diagnostic request for the same document.
|
||||||
|
pub result_id: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The document diagnostic report kinds.
|
||||||
|
///
|
||||||
|
/// @since 3.17.0
|
||||||
|
#[derive(Debug, PartialEq, Deserialize, Serialize, Clone)]
|
||||||
|
#[serde(tag = "kind", rename_all = "lowercase")]
|
||||||
|
pub enum DocumentDiagnosticReportKind {
|
||||||
|
/// A diagnostic report with a full set of problems.
|
||||||
|
Full(FullDocumentDiagnosticReport),
|
||||||
|
/// A report indicating that the last returned report is still accurate.
|
||||||
|
Unchanged(UnchangedDocumentDiagnosticReport),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<FullDocumentDiagnosticReport> for DocumentDiagnosticReportKind {
|
||||||
|
fn from(from: FullDocumentDiagnosticReport) -> Self {
|
||||||
|
DocumentDiagnosticReportKind::Full(from)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<UnchangedDocumentDiagnosticReport> for DocumentDiagnosticReportKind {
|
||||||
|
fn from(from: UnchangedDocumentDiagnosticReport) -> Self {
|
||||||
|
DocumentDiagnosticReportKind::Unchanged(from)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A full diagnostic report with a set of related documents.
|
||||||
|
///
|
||||||
|
/// @since 3.17.0
|
||||||
|
#[derive(Debug, PartialEq, Default, Deserialize, Serialize, Clone)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct RelatedFullDocumentDiagnosticReport {
|
||||||
|
/// Diagnostics of related documents.
|
||||||
|
///
|
||||||
|
/// This information is useful in programming languages where code in a file A can generate
|
||||||
|
/// diagnostics in a file B which A depends on. An example of such a language is C/C++ where
|
||||||
|
/// macro definitions in a file `a.cpp` result in errors in a header file `b.hpp`.
|
||||||
|
///
|
||||||
|
/// @since 3.17.0
|
||||||
|
#[serde(with = "crate::url_map")]
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
#[serde(default)]
|
||||||
|
pub related_documents: Option<HashMap<Url, DocumentDiagnosticReportKind>>,
|
||||||
|
// relatedDocuments?: { [uri: string]: FullDocumentDiagnosticReport | UnchangedDocumentDiagnosticReport; };
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub full_document_diagnostic_report: FullDocumentDiagnosticReport,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// An unchanged diagnostic report with a set of related documents.
|
||||||
|
///
|
||||||
|
/// @since 3.17.0
|
||||||
|
#[derive(Debug, PartialEq, Deserialize, Serialize, Clone)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct RelatedUnchangedDocumentDiagnosticReport {
|
||||||
|
/// Diagnostics of related documents.
|
||||||
|
///
|
||||||
|
/// This information is useful in programming languages where code in a file A can generate
|
||||||
|
/// diagnostics in a file B which A depends on. An example of such a language is C/C++ where
|
||||||
|
/// macro definitions in a file `a.cpp` result in errors in a header file `b.hpp`.
|
||||||
|
///
|
||||||
|
/// @since 3.17.0
|
||||||
|
#[serde(with = "crate::url_map")]
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
#[serde(default)]
|
||||||
|
pub related_documents: Option<HashMap<Url, DocumentDiagnosticReportKind>>,
|
||||||
|
// relatedDocuments?: { [uri: string]: FullDocumentDiagnosticReport | UnchangedDocumentDiagnosticReport; };
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub unchanged_document_diagnostic_report: UnchangedDocumentDiagnosticReport,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The result of a document diagnostic pull request.
|
||||||
|
///
|
||||||
|
/// A report can either be a full report containing all diagnostics for the requested document or
|
||||||
|
/// an unchanged report indicating that nothing has changed in terms of diagnostics in comparison
|
||||||
|
/// to the last pull request.
|
||||||
|
///
|
||||||
|
/// @since 3.17.0
|
||||||
|
#[derive(Debug, PartialEq, Deserialize, Serialize, Clone)]
|
||||||
|
#[serde(tag = "kind", rename_all = "lowercase")]
|
||||||
|
pub enum DocumentDiagnosticReport {
|
||||||
|
/// A diagnostic report with a full set of problems.
|
||||||
|
Full(RelatedFullDocumentDiagnosticReport),
|
||||||
|
/// A report indicating that the last returned report is still accurate.
|
||||||
|
Unchanged(RelatedUnchangedDocumentDiagnosticReport),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<RelatedFullDocumentDiagnosticReport> for DocumentDiagnosticReport {
|
||||||
|
fn from(from: RelatedFullDocumentDiagnosticReport) -> Self {
|
||||||
|
DocumentDiagnosticReport::Full(from)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<RelatedUnchangedDocumentDiagnosticReport> for DocumentDiagnosticReport {
|
||||||
|
fn from(from: RelatedUnchangedDocumentDiagnosticReport) -> Self {
|
||||||
|
DocumentDiagnosticReport::Unchanged(from)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A partial result for a document diagnostic report.
|
||||||
|
///
|
||||||
|
/// @since 3.17.0
|
||||||
|
#[derive(Debug, PartialEq, Default, Deserialize, Serialize, Clone)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct DocumentDiagnosticReportPartialResult {
|
||||||
|
#[serde(with = "crate::url_map")]
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
#[serde(default)]
|
||||||
|
pub related_documents: Option<HashMap<Url, DocumentDiagnosticReportKind>>,
|
||||||
|
// relatedDocuments?: { [uri: string]: FullDocumentDiagnosticReport | UnchangedDocumentDiagnosticReport; };
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Deserialize, Serialize, Clone)]
|
||||||
|
#[serde(untagged)]
|
||||||
|
pub enum DocumentDiagnosticReportResult {
|
||||||
|
Report(DocumentDiagnosticReport),
|
||||||
|
Partial(DocumentDiagnosticReportPartialResult),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<DocumentDiagnosticReport> for DocumentDiagnosticReportResult {
|
||||||
|
fn from(from: DocumentDiagnosticReport) -> Self {
|
||||||
|
DocumentDiagnosticReportResult::Report(from)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<DocumentDiagnosticReportPartialResult> for DocumentDiagnosticReportResult {
|
||||||
|
fn from(from: DocumentDiagnosticReportPartialResult) -> Self {
|
||||||
|
DocumentDiagnosticReportResult::Partial(from)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Cancellation data returned from a diagnostic request.
|
||||||
|
///
|
||||||
|
/// If no data is provided, it defaults to `{ retrigger_request: true }`.
|
||||||
|
///
|
||||||
|
/// @since 3.17.0
|
||||||
|
#[derive(Debug, PartialEq, Deserialize, Serialize, Clone)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct DiagnosticServerCancellationData {
|
||||||
|
pub retrigger_request: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for DiagnosticServerCancellationData {
|
||||||
|
fn default() -> Self {
|
||||||
|
DiagnosticServerCancellationData {
|
||||||
|
retrigger_request: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,51 @@
|
|||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
DynamicRegistrationClientCapabilities, PartialResultParams, Range, TextDocumentPositionParams,
|
||||||
|
WorkDoneProgressParams,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub type DocumentHighlightClientCapabilities = DynamicRegistrationClientCapabilities;
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct DocumentHighlightParams {
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub text_document_position_params: TextDocumentPositionParams,
|
||||||
|
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub work_done_progress_params: WorkDoneProgressParams,
|
||||||
|
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub partial_result_params: PartialResultParams,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A document highlight is a range inside a text document which deserves
|
||||||
|
/// special attention. Usually a document highlight is visualized by changing
|
||||||
|
/// the background color of its range.
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
|
||||||
|
pub struct DocumentHighlight {
|
||||||
|
/// The range this highlight applies to.
|
||||||
|
pub range: Range,
|
||||||
|
|
||||||
|
/// The highlight kind, default is DocumentHighlightKind.Text.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub kind: Option<DocumentHighlightKind>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A document highlight kind.
|
||||||
|
#[derive(Eq, PartialEq, Copy, Clone, Deserialize, Serialize)]
|
||||||
|
#[serde(transparent)]
|
||||||
|
pub struct DocumentHighlightKind(i32);
|
||||||
|
lsp_enum! {
|
||||||
|
impl DocumentHighlightKind {
|
||||||
|
/// A textual occurrence.
|
||||||
|
pub const TEXT: DocumentHighlightKind = DocumentHighlightKind(1);
|
||||||
|
|
||||||
|
/// Read-access of a symbol, like reading a variable.
|
||||||
|
pub const READ: DocumentHighlightKind = DocumentHighlightKind(2);
|
||||||
|
|
||||||
|
/// Write-access of a symbol, like writing to a variable.
|
||||||
|
pub const WRITE: DocumentHighlightKind = DocumentHighlightKind(3);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,67 @@
|
|||||||
|
use crate::{
|
||||||
|
PartialResultParams, Range, TextDocumentIdentifier, WorkDoneProgressOptions,
|
||||||
|
WorkDoneProgressParams,
|
||||||
|
};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use serde_json::Value;
|
||||||
|
use url::Url;
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct DocumentLinkClientCapabilities {
|
||||||
|
/// Whether document link supports dynamic registration.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub dynamic_registration: Option<bool>,
|
||||||
|
|
||||||
|
/// Whether the client support the `tooltip` property on `DocumentLink`.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub tooltip_support: Option<bool>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct DocumentLinkOptions {
|
||||||
|
/// Document links have a resolve provider as well.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub resolve_provider: Option<bool>,
|
||||||
|
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub work_done_progress_options: WorkDoneProgressOptions,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct DocumentLinkParams {
|
||||||
|
/// The document to provide document links for.
|
||||||
|
pub text_document: TextDocumentIdentifier,
|
||||||
|
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub work_done_progress_params: WorkDoneProgressParams,
|
||||||
|
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub partial_result_params: PartialResultParams,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A document link is a range in a text document that links to an internal or external resource, like another
|
||||||
|
/// text document or a web site.
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
|
||||||
|
pub struct DocumentLink {
|
||||||
|
/// The range this link applies to.
|
||||||
|
pub range: Range,
|
||||||
|
/// The uri this link points to.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub target: Option<Url>,
|
||||||
|
|
||||||
|
/// The tooltip text when you hover over this link.
|
||||||
|
///
|
||||||
|
/// If a tooltip is provided, is will be displayed in a string that includes instructions on how to
|
||||||
|
/// trigger the link, such as `{0} (ctrl + click)`. The specific instructions vary depending on OS,
|
||||||
|
/// user settings, and localization.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub tooltip: Option<String>,
|
||||||
|
|
||||||
|
/// A data entry field that is preserved on a document link between a DocumentLinkRequest
|
||||||
|
/// and a DocumentLinkResolveRequest.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub data: Option<Value>,
|
||||||
|
}
|
@ -0,0 +1,134 @@
|
|||||||
|
use crate::{
|
||||||
|
Location, PartialResultParams, Range, SymbolKind, SymbolKindCapability, TextDocumentIdentifier,
|
||||||
|
WorkDoneProgressParams,
|
||||||
|
};
|
||||||
|
|
||||||
|
use crate::{SymbolTag, TagSupport};
|
||||||
|
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct DocumentSymbolClientCapabilities {
|
||||||
|
/// This capability supports dynamic registration.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub dynamic_registration: Option<bool>,
|
||||||
|
|
||||||
|
/// Specific capabilities for the `SymbolKind`.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub symbol_kind: Option<SymbolKindCapability>,
|
||||||
|
|
||||||
|
/// The client support hierarchical document symbols.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub hierarchical_document_symbol_support: Option<bool>,
|
||||||
|
|
||||||
|
/// The client supports tags on `SymbolInformation`. Tags are supported on
|
||||||
|
/// `DocumentSymbol` if `hierarchicalDocumentSymbolSupport` is set to true.
|
||||||
|
/// Clients supporting tags have to handle unknown tags gracefully.
|
||||||
|
///
|
||||||
|
/// @since 3.16.0
|
||||||
|
#[serde(
|
||||||
|
default,
|
||||||
|
skip_serializing_if = "Option::is_none",
|
||||||
|
deserialize_with = "TagSupport::deserialize_compat"
|
||||||
|
)]
|
||||||
|
pub tag_support: Option<TagSupport<SymbolTag>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
|
||||||
|
#[serde(untagged)]
|
||||||
|
pub enum DocumentSymbolResponse {
|
||||||
|
Flat(Vec<SymbolInformation>),
|
||||||
|
Nested(Vec<DocumentSymbol>),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Vec<SymbolInformation>> for DocumentSymbolResponse {
|
||||||
|
fn from(info: Vec<SymbolInformation>) -> Self {
|
||||||
|
DocumentSymbolResponse::Flat(info)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Vec<DocumentSymbol>> for DocumentSymbolResponse {
|
||||||
|
fn from(symbols: Vec<DocumentSymbol>) -> Self {
|
||||||
|
DocumentSymbolResponse::Nested(symbols)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct DocumentSymbolParams {
|
||||||
|
/// The text document.
|
||||||
|
pub text_document: TextDocumentIdentifier,
|
||||||
|
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub work_done_progress_params: WorkDoneProgressParams,
|
||||||
|
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub partial_result_params: PartialResultParams,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Represents programming constructs like variables, classes, interfaces etc.
|
||||||
|
/// that appear in a document. Document symbols can be hierarchical and they have two ranges:
|
||||||
|
/// one that encloses its definition and one that points to its most interesting range,
|
||||||
|
/// e.g. the range of an identifier.
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct DocumentSymbol {
|
||||||
|
/// The name of this symbol.
|
||||||
|
pub name: String,
|
||||||
|
/// More detail for this symbol, e.g the signature of a function. If not provided the
|
||||||
|
/// name is used.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub detail: Option<String>,
|
||||||
|
/// The kind of this symbol.
|
||||||
|
pub kind: SymbolKind,
|
||||||
|
/// Tags for this completion item.
|
||||||
|
///
|
||||||
|
/// @since 3.15.0
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub tags: Option<Vec<SymbolTag>>,
|
||||||
|
/// Indicates if this symbol is deprecated.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
#[deprecated(note = "Use tags instead")]
|
||||||
|
pub deprecated: Option<bool>,
|
||||||
|
/// The range enclosing this symbol not including leading/trailing whitespace but everything else
|
||||||
|
/// like comments. This information is typically used to determine if the the clients cursor is
|
||||||
|
/// inside the symbol to reveal in the symbol in the UI.
|
||||||
|
pub range: Range,
|
||||||
|
/// The range that should be selected and revealed when this symbol is being picked, e.g the name of a function.
|
||||||
|
/// Must be contained by the the `range`.
|
||||||
|
pub selection_range: Range,
|
||||||
|
/// Children of this symbol, e.g. properties of a class.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub children: Option<Vec<DocumentSymbol>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Represents information about programming constructs like variables, classes,
|
||||||
|
/// interfaces etc.
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct SymbolInformation {
|
||||||
|
/// The name of this symbol.
|
||||||
|
pub name: String,
|
||||||
|
|
||||||
|
/// The kind of this symbol.
|
||||||
|
pub kind: SymbolKind,
|
||||||
|
|
||||||
|
/// Tags for this completion item.
|
||||||
|
///
|
||||||
|
/// @since 3.16.0
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub tags: Option<Vec<SymbolTag>>,
|
||||||
|
|
||||||
|
/// Indicates if this symbol is deprecated.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
#[deprecated(note = "Use tags instead")]
|
||||||
|
pub deprecated: Option<bool>,
|
||||||
|
|
||||||
|
/// The location of this symbol.
|
||||||
|
pub location: Location,
|
||||||
|
|
||||||
|
/// The name of the symbol containing this symbol.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub container_name: Option<String>,
|
||||||
|
}
|
@ -0,0 +1,54 @@
|
|||||||
|
//! In this module we only define constants for lsp specific error codes.
|
||||||
|
//! There are other error codes that are defined in the
|
||||||
|
//! [JSON RPC specification](https://www.jsonrpc.org/specification#error_object).
|
||||||
|
|
||||||
|
/// Defined in the LSP specification but in the range reserved for JSON-RPC error codes,
|
||||||
|
/// namely the -32099 to -32000 "Reserved for implementation-defined server-errors." range.
|
||||||
|
/// The code has, nonetheless, been left in this range for backwards compatibility reasons.
|
||||||
|
pub const SERVER_NOT_INITIALIZED: i64 = -32002;
|
||||||
|
|
||||||
|
/// Defined in the LSP specification but in the range reserved for JSON-RPC error codes,
|
||||||
|
/// namely the -32099 to -32000 "Reserved for implementation-defined server-errors." range.
|
||||||
|
/// The code has, nonetheless, left in this range for backwards compatibility reasons.
|
||||||
|
pub const UNKNOWN_ERROR_CODE: i64 = -32001;
|
||||||
|
|
||||||
|
/// This is the start range of LSP reserved error codes.
|
||||||
|
/// It doesn't denote a real error code.
|
||||||
|
///
|
||||||
|
/// @since 3.16.0
|
||||||
|
pub const LSP_RESERVED_ERROR_RANGE_START: i64 = -32899;
|
||||||
|
|
||||||
|
/// A request failed but it was syntactically correct, e.g the
|
||||||
|
/// method name was known and the parameters were valid. The error
|
||||||
|
/// message should contain human readable information about why
|
||||||
|
/// the request failed.
|
||||||
|
///
|
||||||
|
/// @since 3.17.0
|
||||||
|
pub const REQUEST_FAILED: i64 = -32803;
|
||||||
|
|
||||||
|
/// The server cancelled the request. This error code should
|
||||||
|
/// only be used for requests that explicitly support being
|
||||||
|
/// server cancellable.
|
||||||
|
///
|
||||||
|
/// @since 3.17.0
|
||||||
|
pub const SERVER_CANCELLED: i64 = -32802;
|
||||||
|
|
||||||
|
/// The server detected that the content of a document got
|
||||||
|
/// modified outside normal conditions. A server should
|
||||||
|
/// NOT send this error code if it detects a content change
|
||||||
|
/// in it unprocessed messages. The result even computed
|
||||||
|
/// on an older state might still be useful for the client.
|
||||||
|
///
|
||||||
|
/// If a client decides that a result is not of any use anymore
|
||||||
|
/// the client should cancel the request.
|
||||||
|
pub const CONTENT_MODIFIED: i64 = -32801;
|
||||||
|
|
||||||
|
/// The client has canceled a request and a server as detected
|
||||||
|
/// the cancel.
|
||||||
|
pub const REQUEST_CANCELLED: i64 = -32800;
|
||||||
|
|
||||||
|
/// This is the end range of LSP reserved error codes.
|
||||||
|
/// It doesn't denote a real error code.
|
||||||
|
///
|
||||||
|
/// @since 3.16.0
|
||||||
|
pub const LSP_RESERVED_ERROR_RANGE_END: i64 = -32800;
|
@ -0,0 +1,145 @@
|
|||||||
|
use crate::{
|
||||||
|
PartialResultParams, StaticTextDocumentColorProviderOptions, TextDocumentIdentifier,
|
||||||
|
WorkDoneProgressParams,
|
||||||
|
};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct FoldingRangeParams {
|
||||||
|
/// The text document.
|
||||||
|
pub text_document: TextDocumentIdentifier,
|
||||||
|
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub work_done_progress_params: WorkDoneProgressParams,
|
||||||
|
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub partial_result_params: PartialResultParams,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
|
||||||
|
#[serde(untagged)]
|
||||||
|
pub enum FoldingRangeProviderCapability {
|
||||||
|
Simple(bool),
|
||||||
|
FoldingProvider(FoldingProviderOptions),
|
||||||
|
Options(StaticTextDocumentColorProviderOptions),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<StaticTextDocumentColorProviderOptions> for FoldingRangeProviderCapability {
|
||||||
|
fn from(from: StaticTextDocumentColorProviderOptions) -> Self {
|
||||||
|
Self::Options(from)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<FoldingProviderOptions> for FoldingRangeProviderCapability {
|
||||||
|
fn from(from: FoldingProviderOptions) -> Self {
|
||||||
|
Self::FoldingProvider(from)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<bool> for FoldingRangeProviderCapability {
|
||||||
|
fn from(from: bool) -> Self {
|
||||||
|
Self::Simple(from)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
|
||||||
|
pub struct FoldingProviderOptions {}
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct FoldingRangeKindCapability {
|
||||||
|
/// The folding range kind values the client supports. When this
|
||||||
|
/// property exists the client also guarantees that it will
|
||||||
|
/// handle values outside its set gracefully and falls back
|
||||||
|
/// to a default value when unknown.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub value_set: Option<Vec<FoldingRangeKind>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct FoldingRangeCapability {
|
||||||
|
/// If set, the client signals that it supports setting collapsedText on
|
||||||
|
/// folding ranges to display custom labels instead of the default text.
|
||||||
|
///
|
||||||
|
/// @since 3.17.0
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub collapsed_text: Option<bool>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct FoldingRangeClientCapabilities {
|
||||||
|
/// Whether implementation supports dynamic registration for folding range providers. If this is set to `true`
|
||||||
|
/// the client supports the new `(FoldingRangeProviderOptions & TextDocumentRegistrationOptions & StaticRegistrationOptions)`
|
||||||
|
/// return value for the corresponding server capability as well.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub dynamic_registration: Option<bool>,
|
||||||
|
|
||||||
|
/// The maximum number of folding ranges that the client prefers to receive per document. The value serves as a
|
||||||
|
/// hint, servers are free to follow the limit.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub range_limit: Option<u32>,
|
||||||
|
|
||||||
|
/// If set, the client signals that it only supports folding complete lines. If set, client will
|
||||||
|
/// ignore specified `startCharacter` and `endCharacter` properties in a FoldingRange.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub line_folding_only: Option<bool>,
|
||||||
|
|
||||||
|
/// Specific options for the folding range kind.
|
||||||
|
///
|
||||||
|
/// @since 3.17.0
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub folding_range_kind: Option<FoldingRangeKindCapability>,
|
||||||
|
|
||||||
|
/// Specific options for the folding range.
|
||||||
|
///
|
||||||
|
/// @since 3.17.0
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub folding_range: Option<FoldingRangeCapability>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Enum of known range kinds
|
||||||
|
#[derive(Debug, Eq, PartialEq, Deserialize, Serialize, Clone)]
|
||||||
|
#[serde(rename_all = "lowercase")]
|
||||||
|
pub enum FoldingRangeKind {
|
||||||
|
/// Folding range for a comment
|
||||||
|
Comment,
|
||||||
|
/// Folding range for a imports or includes
|
||||||
|
Imports,
|
||||||
|
/// Folding range for a region (e.g. `#region`)
|
||||||
|
Region,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Represents a folding range.
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct FoldingRange {
|
||||||
|
/// The zero-based line number from where the folded range starts.
|
||||||
|
pub start_line: u32,
|
||||||
|
|
||||||
|
/// The zero-based character offset from where the folded range starts. If not defined, defaults to the length of the start line.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub start_character: Option<u32>,
|
||||||
|
|
||||||
|
/// The zero-based line number where the folded range ends.
|
||||||
|
pub end_line: u32,
|
||||||
|
|
||||||
|
/// The zero-based character offset before the folded range ends. If not defined, defaults to the length of the end line.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub end_character: Option<u32>,
|
||||||
|
|
||||||
|
/// Describes the kind of the folding range such as `comment' or 'region'. The kind
|
||||||
|
/// is used to categorize folding ranges and used by commands like 'Fold all comments'. See
|
||||||
|
/// [FoldingRangeKind](#FoldingRangeKind) for an enumeration of standardized kinds.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub kind: Option<FoldingRangeKind>,
|
||||||
|
|
||||||
|
/// The text that the client should show when the specified range is
|
||||||
|
/// collapsed. If not defined or not supported by the client, a default
|
||||||
|
/// will be chosen by the client.
|
||||||
|
///
|
||||||
|
/// @since 3.17.0
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub collapsed_text: Option<String>,
|
||||||
|
}
|
@ -0,0 +1,153 @@
|
|||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
DocumentSelector, DynamicRegistrationClientCapabilities, Range, TextDocumentIdentifier,
|
||||||
|
TextDocumentPositionParams, WorkDoneProgressParams,
|
||||||
|
};
|
||||||
|
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
pub type DocumentFormattingClientCapabilities = DynamicRegistrationClientCapabilities;
|
||||||
|
pub type DocumentRangeFormattingClientCapabilities = DynamicRegistrationClientCapabilities;
|
||||||
|
pub type DocumentOnTypeFormattingClientCapabilities = DynamicRegistrationClientCapabilities;
|
||||||
|
|
||||||
|
/// Format document on type options
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct DocumentOnTypeFormattingOptions {
|
||||||
|
/// A character on which formatting should be triggered, like `}`.
|
||||||
|
pub first_trigger_character: String,
|
||||||
|
|
||||||
|
/// More trigger characters.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub more_trigger_character: Option<Vec<String>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct DocumentFormattingParams {
|
||||||
|
/// The document to format.
|
||||||
|
pub text_document: TextDocumentIdentifier,
|
||||||
|
|
||||||
|
/// The format options.
|
||||||
|
pub options: FormattingOptions,
|
||||||
|
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub work_done_progress_params: WorkDoneProgressParams,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Value-object describing what options formatting should use.
|
||||||
|
#[derive(Debug, PartialEq, Clone, Default, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct FormattingOptions {
|
||||||
|
/// Size of a tab in spaces.
|
||||||
|
pub tab_size: u32,
|
||||||
|
|
||||||
|
/// Prefer spaces over tabs.
|
||||||
|
pub insert_spaces: bool,
|
||||||
|
|
||||||
|
/// Signature for further properties.
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub properties: HashMap<String, FormattingProperty>,
|
||||||
|
|
||||||
|
/// Trim trailing whitespace on a line.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub trim_trailing_whitespace: Option<bool>,
|
||||||
|
|
||||||
|
/// Insert a newline character at the end of the file if one does not exist.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub insert_final_newline: Option<bool>,
|
||||||
|
|
||||||
|
/// Trim all newlines after the final newline at the end of the file.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub trim_final_newlines: Option<bool>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
|
||||||
|
#[serde(untagged)]
|
||||||
|
pub enum FormattingProperty {
|
||||||
|
Bool(bool),
|
||||||
|
Number(i32),
|
||||||
|
String(String),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct DocumentRangeFormattingParams {
|
||||||
|
/// The document to format.
|
||||||
|
pub text_document: TextDocumentIdentifier,
|
||||||
|
|
||||||
|
/// The range to format
|
||||||
|
pub range: Range,
|
||||||
|
|
||||||
|
/// The format options
|
||||||
|
pub options: FormattingOptions,
|
||||||
|
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub work_done_progress_params: WorkDoneProgressParams,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct DocumentOnTypeFormattingParams {
|
||||||
|
/// Text Document and Position fields.
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub text_document_position: TextDocumentPositionParams,
|
||||||
|
|
||||||
|
/// The character that has been typed.
|
||||||
|
pub ch: String,
|
||||||
|
|
||||||
|
/// The format options.
|
||||||
|
pub options: FormattingOptions,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Extends TextDocumentRegistrationOptions
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct DocumentOnTypeFormattingRegistrationOptions {
|
||||||
|
/// A document selector to identify the scope of the registration. If set to null
|
||||||
|
/// the document selector provided on the client side will be used.
|
||||||
|
pub document_selector: Option<DocumentSelector>,
|
||||||
|
|
||||||
|
/// A character on which formatting should be triggered, like `}`.
|
||||||
|
pub first_trigger_character: String,
|
||||||
|
|
||||||
|
/// More trigger characters.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub more_trigger_character: Option<Vec<String>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use crate::tests::test_serialization;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn formatting_options() {
|
||||||
|
test_serialization(
|
||||||
|
&FormattingOptions {
|
||||||
|
tab_size: 123,
|
||||||
|
insert_spaces: true,
|
||||||
|
properties: HashMap::new(),
|
||||||
|
trim_trailing_whitespace: None,
|
||||||
|
insert_final_newline: None,
|
||||||
|
trim_final_newlines: None,
|
||||||
|
},
|
||||||
|
r#"{"tabSize":123,"insertSpaces":true}"#,
|
||||||
|
);
|
||||||
|
|
||||||
|
test_serialization(
|
||||||
|
&FormattingOptions {
|
||||||
|
tab_size: 123,
|
||||||
|
insert_spaces: true,
|
||||||
|
properties: vec![("prop".to_string(), FormattingProperty::Number(1))]
|
||||||
|
.into_iter()
|
||||||
|
.collect(),
|
||||||
|
trim_trailing_whitespace: None,
|
||||||
|
insert_final_newline: None,
|
||||||
|
trim_final_newlines: None,
|
||||||
|
},
|
||||||
|
r#"{"tabSize":123,"insertSpaces":true,"prop":1}"#,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,86 @@
|
|||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
MarkedString, MarkupContent, MarkupKind, Range, TextDocumentPositionParams,
|
||||||
|
TextDocumentRegistrationOptions, WorkDoneProgressOptions, WorkDoneProgressParams,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct HoverClientCapabilities {
|
||||||
|
/// Whether completion supports dynamic registration.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub dynamic_registration: Option<bool>,
|
||||||
|
|
||||||
|
/// Client supports the follow content formats for the content
|
||||||
|
/// property. The order describes the preferred format of the client.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub content_format: Option<Vec<MarkupKind>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Hover options.
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct HoverOptions {
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub work_done_progress_options: WorkDoneProgressOptions,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct HoverRegistrationOptions {
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub text_document_registration_options: TextDocumentRegistrationOptions,
|
||||||
|
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub hover_options: HoverOptions,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
|
||||||
|
#[serde(untagged)]
|
||||||
|
pub enum HoverProviderCapability {
|
||||||
|
Simple(bool),
|
||||||
|
Options(HoverOptions),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<HoverOptions> for HoverProviderCapability {
|
||||||
|
fn from(from: HoverOptions) -> Self {
|
||||||
|
Self::Options(from)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<bool> for HoverProviderCapability {
|
||||||
|
fn from(from: bool) -> Self {
|
||||||
|
Self::Simple(from)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct HoverParams {
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub text_document_position_params: TextDocumentPositionParams,
|
||||||
|
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub work_done_progress_params: WorkDoneProgressParams,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The result of a hover request.
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
|
||||||
|
pub struct Hover {
|
||||||
|
/// The hover's content
|
||||||
|
pub contents: HoverContents,
|
||||||
|
/// An optional range is a range inside a text document
|
||||||
|
/// that is used to visualize a hover, e.g. by changing the background color.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub range: Option<Range>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Hover contents could be single entry or multiple entries.
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Serialize, Deserialize)]
|
||||||
|
#[serde(untagged)]
|
||||||
|
pub enum HoverContents {
|
||||||
|
Scalar(MarkedString),
|
||||||
|
Array(Vec<MarkedString>),
|
||||||
|
Markup(MarkupContent),
|
||||||
|
}
|
@ -0,0 +1,281 @@
|
|||||||
|
use crate::{
|
||||||
|
Command, LSPAny, Location, MarkupContent, Position, Range, StaticRegistrationOptions,
|
||||||
|
TextDocumentIdentifier, TextDocumentRegistrationOptions, TextEdit, WorkDoneProgressOptions,
|
||||||
|
WorkDoneProgressParams,
|
||||||
|
};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
#[serde(untagged)]
|
||||||
|
pub enum InlayHintServerCapabilities {
|
||||||
|
Options(InlayHintOptions),
|
||||||
|
RegistrationOptions(InlayHintRegistrationOptions),
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Inlay hint client capabilities.
|
||||||
|
///
|
||||||
|
/// @since 3.17.0
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct InlayHintClientCapabilities {
|
||||||
|
/// Whether inlay hints support dynamic registration.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub dynamic_registration: Option<bool>,
|
||||||
|
|
||||||
|
/// Indicates which properties a client can resolve lazily on a inlay
|
||||||
|
/// hint.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub resolve_support: Option<InlayHintResolveClientCapabilities>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Inlay hint options used during static registration.
|
||||||
|
///
|
||||||
|
/// @since 3.17.0
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct InlayHintOptions {
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub work_done_progress_options: WorkDoneProgressOptions,
|
||||||
|
|
||||||
|
/// The server provides support to resolve additional
|
||||||
|
/// information for an inlay hint item.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub resolve_provider: Option<bool>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Inlay hint options used during static or dynamic registration.
|
||||||
|
///
|
||||||
|
/// @since 3.17.0
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct InlayHintRegistrationOptions {
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub inlay_hint_options: InlayHintOptions,
|
||||||
|
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub text_document_registration_options: TextDocumentRegistrationOptions,
|
||||||
|
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub static_registration_options: StaticRegistrationOptions,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A parameter literal used in inlay hint requests.
|
||||||
|
///
|
||||||
|
/// @since 3.17.0
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct InlayHintParams {
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub work_done_progress_params: WorkDoneProgressParams,
|
||||||
|
|
||||||
|
/// The text document.
|
||||||
|
pub text_document: TextDocumentIdentifier,
|
||||||
|
|
||||||
|
/// The visible document range for which inlay hints should be computed.
|
||||||
|
pub range: Range,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Inlay hint information.
|
||||||
|
///
|
||||||
|
/// @since 3.17.0
|
||||||
|
#[derive(Debug, Clone, Deserialize, Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct InlayHint {
|
||||||
|
/// The position of this hint.
|
||||||
|
pub position: Position,
|
||||||
|
|
||||||
|
/// The label of this hint. A human readable string or an array of
|
||||||
|
/// InlayHintLabelPart label parts.
|
||||||
|
///
|
||||||
|
/// *Note* that neither the string nor the label part can be empty.
|
||||||
|
pub label: InlayHintLabel,
|
||||||
|
|
||||||
|
/// The kind of this hint. Can be omitted in which case the client
|
||||||
|
/// should fall back to a reasonable default.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub kind: Option<InlayHintKind>,
|
||||||
|
|
||||||
|
/// Optional text edits that are performed when accepting this inlay hint.
|
||||||
|
///
|
||||||
|
/// *Note* that edits are expected to change the document so that the inlay
|
||||||
|
/// hint (or its nearest variant) is now part of the document and the inlay
|
||||||
|
/// hint itself is now obsolete.
|
||||||
|
///
|
||||||
|
/// Depending on the client capability `inlayHint.resolveSupport` clients
|
||||||
|
/// might resolve this property late using the resolve request.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub text_edits: Option<Vec<TextEdit>>,
|
||||||
|
|
||||||
|
/// The tooltip text when you hover over this item.
|
||||||
|
///
|
||||||
|
/// Depending on the client capability `inlayHint.resolveSupport` clients
|
||||||
|
/// might resolve this property late using the resolve request.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub tooltip: Option<InlayHintTooltip>,
|
||||||
|
|
||||||
|
/// Render padding before the hint.
|
||||||
|
///
|
||||||
|
/// Note: Padding should use the editor's background color, not the
|
||||||
|
/// background color of the hint itself. That means padding can be used
|
||||||
|
/// to visually align/separate an inlay hint.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub padding_left: Option<bool>,
|
||||||
|
|
||||||
|
/// Render padding after the hint.
|
||||||
|
///
|
||||||
|
/// Note: Padding should use the editor's background color, not the
|
||||||
|
/// background color of the hint itself. That means padding can be used
|
||||||
|
/// to visually align/separate an inlay hint.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub padding_right: Option<bool>,
|
||||||
|
|
||||||
|
/// A data entry field that is preserved on a inlay hint between
|
||||||
|
/// a `textDocument/inlayHint` and a `inlayHint/resolve` request.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub data: Option<LSPAny>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Deserialize, Serialize)]
|
||||||
|
#[serde(untagged)]
|
||||||
|
pub enum InlayHintLabel {
|
||||||
|
String(String),
|
||||||
|
LabelParts(Vec<InlayHintLabelPart>),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<String> for InlayHintLabel {
|
||||||
|
#[inline]
|
||||||
|
fn from(from: String) -> Self {
|
||||||
|
Self::String(from)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Vec<InlayHintLabelPart>> for InlayHintLabel {
|
||||||
|
#[inline]
|
||||||
|
fn from(from: Vec<InlayHintLabelPart>) -> Self {
|
||||||
|
Self::LabelParts(from)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Deserialize, Serialize)]
|
||||||
|
#[serde(untagged)]
|
||||||
|
pub enum InlayHintTooltip {
|
||||||
|
String(String),
|
||||||
|
MarkupContent(MarkupContent),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<String> for InlayHintTooltip {
|
||||||
|
#[inline]
|
||||||
|
fn from(from: String) -> Self {
|
||||||
|
Self::String(from)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<MarkupContent> for InlayHintTooltip {
|
||||||
|
#[inline]
|
||||||
|
fn from(from: MarkupContent) -> Self {
|
||||||
|
Self::MarkupContent(from)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// An inlay hint label part allows for interactive and composite labels
|
||||||
|
/// of inlay hints.
|
||||||
|
#[derive(Debug, Clone, Default, Deserialize, Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct InlayHintLabelPart {
|
||||||
|
/// The value of this label part.
|
||||||
|
pub value: String,
|
||||||
|
|
||||||
|
/// The tooltip text when you hover over this label part. Depending on
|
||||||
|
/// the client capability `inlayHint.resolveSupport` clients might resolve
|
||||||
|
/// this property late using the resolve request.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub tooltip: Option<InlayHintLabelPartTooltip>,
|
||||||
|
|
||||||
|
/// An optional source code location that represents this
|
||||||
|
/// label part.
|
||||||
|
///
|
||||||
|
/// The editor will use this location for the hover and for code navigation
|
||||||
|
/// features: This part will become a clickable link that resolves to the
|
||||||
|
/// definition of the symbol at the given location (not necessarily the
|
||||||
|
/// location itself), it shows the hover that shows at the given location,
|
||||||
|
/// and it shows a context menu with further code navigation commands.
|
||||||
|
///
|
||||||
|
/// Depending on the client capability `inlayHint.resolveSupport` clients
|
||||||
|
/// might resolve this property late using the resolve request.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub location: Option<Location>,
|
||||||
|
|
||||||
|
/// An optional command for this label part.
|
||||||
|
///
|
||||||
|
/// Depending on the client capability `inlayHint.resolveSupport` clients
|
||||||
|
/// might resolve this property late using the resolve request.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub command: Option<Command>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
|
||||||
|
#[serde(untagged)]
|
||||||
|
pub enum InlayHintLabelPartTooltip {
|
||||||
|
String(String),
|
||||||
|
MarkupContent(MarkupContent),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<String> for InlayHintLabelPartTooltip {
|
||||||
|
#[inline]
|
||||||
|
fn from(from: String) -> Self {
|
||||||
|
Self::String(from)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<MarkupContent> for InlayHintLabelPartTooltip {
|
||||||
|
#[inline]
|
||||||
|
fn from(from: MarkupContent) -> Self {
|
||||||
|
Self::MarkupContent(from)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Inlay hint kinds.
|
||||||
|
///
|
||||||
|
/// @since 3.17.0
|
||||||
|
#[derive(Eq, PartialEq, Copy, Clone, Serialize, Deserialize)]
|
||||||
|
#[serde(transparent)]
|
||||||
|
pub struct InlayHintKind(i32);
|
||||||
|
lsp_enum! {
|
||||||
|
impl InlayHintKind {
|
||||||
|
/// An inlay hint that for a type annotation.
|
||||||
|
pub const TYPE: InlayHintKind = InlayHintKind(1);
|
||||||
|
|
||||||
|
/// An inlay hint that is for a parameter.
|
||||||
|
pub const PARAMETER: InlayHintKind = InlayHintKind(2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Inlay hint client capabilities.
|
||||||
|
///
|
||||||
|
/// @since 3.17.0
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct InlayHintResolveClientCapabilities {
|
||||||
|
/// The properties that a client can resolve lazily.
|
||||||
|
pub properties: Vec<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Client workspace capabilities specific to inlay hints.
|
||||||
|
///
|
||||||
|
/// @since 3.17.0
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct InlayHintWorkspaceClientCapabilities {
|
||||||
|
/// Whether the client implementation supports a refresh request sent from
|
||||||
|
/// the server to the client.
|
||||||
|
///
|
||||||
|
/// Note that this event is global and will force the client to refresh all
|
||||||
|
/// inlay hints currently shown. It should be used with absolute care and
|
||||||
|
/// is useful for situation where a server for example detects a project wide
|
||||||
|
/// change that requires such a calculation.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub refresh_support: Option<bool>,
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(sno2): add tests once stabilized
|
@ -0,0 +1,162 @@
|
|||||||
|
use crate::{
|
||||||
|
Command, InsertTextFormat, Range, StaticRegistrationOptions, TextDocumentPositionParams,
|
||||||
|
TextDocumentRegistrationOptions, WorkDoneProgressOptions, WorkDoneProgressParams,
|
||||||
|
};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
/// Client capabilities specific to inline completions.
|
||||||
|
///
|
||||||
|
/// @since 3.18.0
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct InlineCompletionClientCapabilities {
|
||||||
|
/// Whether implementation supports dynamic registration for inline completion providers.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub dynamic_registration: Option<bool>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Inline completion options used during static registration.
|
||||||
|
///
|
||||||
|
/// @since 3.18.0
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
|
||||||
|
pub struct InlineCompletionOptions {
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub work_done_progress_options: WorkDoneProgressOptions,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Inline completion options used during static or dynamic registration.
|
||||||
|
///
|
||||||
|
// @since 3.18.0
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
|
||||||
|
pub struct InlineCompletionRegistrationOptions {
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub inline_completion_options: InlineCompletionOptions,
|
||||||
|
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub text_document_registration_options: TextDocumentRegistrationOptions,
|
||||||
|
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub static_registration_options: StaticRegistrationOptions,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A parameter literal used in inline completion requests.
|
||||||
|
///
|
||||||
|
/// @since 3.18.0
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct InlineCompletionParams {
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub work_done_progress_params: WorkDoneProgressParams,
|
||||||
|
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub text_document_position: TextDocumentPositionParams,
|
||||||
|
|
||||||
|
/// Additional information about the context in which inline completions were requested.
|
||||||
|
pub context: InlineCompletionContext,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Describes how an [`InlineCompletionItemProvider`] was triggered.
|
||||||
|
///
|
||||||
|
/// @since 3.18.0
|
||||||
|
#[derive(Eq, PartialEq, Clone, Copy, Deserialize, Serialize)]
|
||||||
|
pub struct InlineCompletionTriggerKind(i32);
|
||||||
|
lsp_enum! {
|
||||||
|
impl InlineCompletionTriggerKind {
|
||||||
|
/// Completion was triggered explicitly by a user gesture.
|
||||||
|
/// Return multiple completion items to enable cycling through them.
|
||||||
|
pub const Invoked: InlineCompletionTriggerKind = InlineCompletionTriggerKind(1);
|
||||||
|
|
||||||
|
/// Completion was triggered automatically while editing.
|
||||||
|
/// It is sufficient to return a single completion item in this case.
|
||||||
|
pub const Automatic: InlineCompletionTriggerKind = InlineCompletionTriggerKind(2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Describes the currently selected completion item.
|
||||||
|
///
|
||||||
|
/// @since 3.18.0
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
|
||||||
|
pub struct SelectedCompletionInfo {
|
||||||
|
/// The range that will be replaced if this completion item is accepted.
|
||||||
|
pub range: Range,
|
||||||
|
/// The text the range will be replaced with if this completion is
|
||||||
|
/// accepted.
|
||||||
|
pub text: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Provides information about the context in which an inline completion was
|
||||||
|
/// requested.
|
||||||
|
///
|
||||||
|
/// @since 3.18.0
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct InlineCompletionContext {
|
||||||
|
/// Describes how the inline completion was triggered.
|
||||||
|
pub trigger_kind: InlineCompletionTriggerKind,
|
||||||
|
/// Provides information about the currently selected item in the
|
||||||
|
/// autocomplete widget if it is visible.
|
||||||
|
///
|
||||||
|
/// If set, provided inline completions must extend the text of the
|
||||||
|
/// selected item and use the same range, otherwise they are not shown as
|
||||||
|
/// preview.
|
||||||
|
/// As an example, if the document text is `console.` and the selected item
|
||||||
|
/// is `.log` replacing the `.` in the document, the inline completion must
|
||||||
|
/// also replace `.` and start with `.log`, for example `.log()`.
|
||||||
|
///
|
||||||
|
/// Inline completion providers are requested again whenever the selected
|
||||||
|
/// item changes.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub selected_completion_info: Option<SelectedCompletionInfo>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// InlineCompletion response can be multiple completion items, or a list of completion items
|
||||||
|
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
|
||||||
|
#[serde(untagged)]
|
||||||
|
pub enum InlineCompletionResponse {
|
||||||
|
Array(Vec<InlineCompletionItem>),
|
||||||
|
List(InlineCompletionList),
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Represents a collection of [`InlineCompletionItem`] to be presented in the editor.
|
||||||
|
///
|
||||||
|
/// @since 3.18.0
|
||||||
|
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct InlineCompletionList {
|
||||||
|
/// The inline completion items
|
||||||
|
pub items: Vec<InlineCompletionItem>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// An inline completion item represents a text snippet that is proposed inline
|
||||||
|
/// to complete text that is being typed.
|
||||||
|
///
|
||||||
|
/// @since 3.18.0
|
||||||
|
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct InlineCompletionItem {
|
||||||
|
/// The text to replace the range with. Must be set.
|
||||||
|
/// Is used both for the preview and the accept operation.
|
||||||
|
pub insert_text: String,
|
||||||
|
/// A text that is used to decide if this inline completion should be
|
||||||
|
/// shown. When `falsy` the [`InlineCompletionItem::insertText`] is
|
||||||
|
/// used.
|
||||||
|
///
|
||||||
|
/// An inline completion is shown if the text to replace is a prefix of the
|
||||||
|
/// filter text.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub filter_text: Option<String>,
|
||||||
|
/// The range to replace.
|
||||||
|
/// Must begin and end on the same line.
|
||||||
|
///
|
||||||
|
/// Prefer replacements over insertions to provide a better experience when
|
||||||
|
/// the user deletes typed text.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub range: Option<Range>,
|
||||||
|
/// An optional command that is executed *after* inserting this
|
||||||
|
/// completion.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub command: Option<Command>,
|
||||||
|
/// The format of the insert text. The format applies to the `insertText`.
|
||||||
|
/// If omitted defaults to `InsertTextFormat.PlainText`.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub insert_text_format: Option<InsertTextFormat>,
|
||||||
|
}
|
@ -0,0 +1,218 @@
|
|||||||
|
use crate::{
|
||||||
|
DynamicRegistrationClientCapabilities, Range, StaticRegistrationOptions,
|
||||||
|
TextDocumentIdentifier, TextDocumentRegistrationOptions, WorkDoneProgressOptions,
|
||||||
|
WorkDoneProgressParams,
|
||||||
|
};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
pub type InlineValueClientCapabilities = DynamicRegistrationClientCapabilities;
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
|
||||||
|
#[serde(untagged)]
|
||||||
|
pub enum InlineValueServerCapabilities {
|
||||||
|
Options(InlineValueOptions),
|
||||||
|
RegistrationOptions(InlineValueRegistrationOptions),
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Inline value options used during static registration.
|
||||||
|
///
|
||||||
|
/// @since 3.17.0
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
|
||||||
|
pub struct InlineValueOptions {
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub work_done_progress_options: WorkDoneProgressOptions,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Inline value options used during static or dynamic registration.
|
||||||
|
///
|
||||||
|
/// @since 3.17.0
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
|
||||||
|
pub struct InlineValueRegistrationOptions {
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub inline_value_options: InlineValueOptions,
|
||||||
|
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub text_document_registration_options: TextDocumentRegistrationOptions,
|
||||||
|
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub static_registration_options: StaticRegistrationOptions,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A parameter literal used in inline value requests.
|
||||||
|
///
|
||||||
|
/// @since 3.17.0
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct InlineValueParams {
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub work_done_progress_params: WorkDoneProgressParams,
|
||||||
|
|
||||||
|
/// The text document.
|
||||||
|
pub text_document: TextDocumentIdentifier,
|
||||||
|
|
||||||
|
/// The document range for which inline values should be computed.
|
||||||
|
pub range: Range,
|
||||||
|
|
||||||
|
/// Additional information about the context in which inline values were
|
||||||
|
/// requested.
|
||||||
|
pub context: InlineValueContext,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @since 3.17.0
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct InlineValueContext {
|
||||||
|
/// The stack frame (as a DAP Id) where the execution has stopped.
|
||||||
|
pub frame_id: i32,
|
||||||
|
|
||||||
|
/// The document range where execution has stopped.
|
||||||
|
/// Typically the end position of the range denotes the line where the
|
||||||
|
/// inline values are shown.
|
||||||
|
pub stopped_location: Range,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Provide inline value as text.
|
||||||
|
///
|
||||||
|
/// @since 3.17.0
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
|
||||||
|
pub struct InlineValueText {
|
||||||
|
/// The document range for which the inline value applies.
|
||||||
|
pub range: Range,
|
||||||
|
|
||||||
|
/// The text of the inline value.
|
||||||
|
pub text: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Provide inline value through a variable lookup.
|
||||||
|
///
|
||||||
|
/// If only a range is specified, the variable name will be extracted from
|
||||||
|
/// the underlying document.
|
||||||
|
///
|
||||||
|
/// An optional variable name can be used to override the extracted name.
|
||||||
|
///
|
||||||
|
/// @since 3.17.0
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct InlineValueVariableLookup {
|
||||||
|
/// The document range for which the inline value applies.
|
||||||
|
/// The range is used to extract the variable name from the underlying
|
||||||
|
/// document.
|
||||||
|
pub range: Range,
|
||||||
|
|
||||||
|
/// If specified the name of the variable to look up.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub variable_name: Option<String>,
|
||||||
|
|
||||||
|
/// How to perform the lookup.
|
||||||
|
pub case_sensitive_lookup: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Provide an inline value through an expression evaluation.
|
||||||
|
///
|
||||||
|
/// If only a range is specified, the expression will be extracted from the
|
||||||
|
/// underlying document.
|
||||||
|
///
|
||||||
|
/// An optional expression can be used to override the extracted expression.
|
||||||
|
///
|
||||||
|
/// @since 3.17.0
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct InlineValueEvaluatableExpression {
|
||||||
|
/// The document range for which the inline value applies.
|
||||||
|
/// The range is used to extract the evaluatable expression from the
|
||||||
|
/// underlying document.
|
||||||
|
pub range: Range,
|
||||||
|
|
||||||
|
/// If specified the expression overrides the extracted expression.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub expression: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Inline value information can be provided by different means:
|
||||||
|
/// - directly as a text value (class InlineValueText).
|
||||||
|
/// - as a name to use for a variable lookup (class InlineValueVariableLookup)
|
||||||
|
/// - as an evaluatable expression (class InlineValueEvaluatableExpression)
|
||||||
|
///
|
||||||
|
/// The InlineValue types combines all inline value types into one type.
|
||||||
|
///
|
||||||
|
/// @since 3.17.0
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
|
||||||
|
#[serde(untagged)]
|
||||||
|
pub enum InlineValue {
|
||||||
|
Text(InlineValueText),
|
||||||
|
VariableLookup(InlineValueVariableLookup),
|
||||||
|
EvaluatableExpression(InlineValueEvaluatableExpression),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<InlineValueText> for InlineValue {
|
||||||
|
#[inline]
|
||||||
|
fn from(from: InlineValueText) -> Self {
|
||||||
|
Self::Text(from)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<InlineValueVariableLookup> for InlineValue {
|
||||||
|
#[inline]
|
||||||
|
fn from(from: InlineValueVariableLookup) -> Self {
|
||||||
|
Self::VariableLookup(from)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<InlineValueEvaluatableExpression> for InlineValue {
|
||||||
|
#[inline]
|
||||||
|
fn from(from: InlineValueEvaluatableExpression) -> Self {
|
||||||
|
Self::EvaluatableExpression(from)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Client workspace capabilities specific to inline values.
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
|
||||||
|
///
|
||||||
|
/// @since 3.17.0
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct InlineValueWorkspaceClientCapabilities {
|
||||||
|
/// Whether the client implementation supports a refresh request sent from
|
||||||
|
/// the server to the client.
|
||||||
|
///
|
||||||
|
/// Note that this event is global and will force the client to refresh all
|
||||||
|
/// inline values currently shown. It should be used with absolute care and
|
||||||
|
/// is useful for situation where a server for example detect a project wide
|
||||||
|
/// change that requires such a calculation.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub refresh_support: Option<bool>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use crate::tests::test_serialization;
|
||||||
|
use crate::Position;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn inline_values() {
|
||||||
|
test_serialization(
|
||||||
|
&InlineValueText {
|
||||||
|
range: Range::new(Position::new(0, 0), Position::new(0, 4)),
|
||||||
|
text: "one".to_owned(),
|
||||||
|
},
|
||||||
|
r#"{"range":{"start":{"line":0,"character":0},"end":{"line":0,"character":4}},"text":"one"}"#,
|
||||||
|
);
|
||||||
|
|
||||||
|
test_serialization(
|
||||||
|
&InlineValue::VariableLookup(InlineValueVariableLookup {
|
||||||
|
range: Range::new(Position::new(1, 0), Position::new(1, 4)),
|
||||||
|
variable_name: None,
|
||||||
|
case_sensitive_lookup: false,
|
||||||
|
}),
|
||||||
|
r#"{"range":{"start":{"line":1,"character":0},"end":{"line":1,"character":4}},"caseSensitiveLookup":false}"#,
|
||||||
|
);
|
||||||
|
|
||||||
|
test_serialization(
|
||||||
|
&InlineValue::EvaluatableExpression(InlineValueEvaluatableExpression {
|
||||||
|
range: Range::new(Position::new(2, 0), Position::new(2, 4)),
|
||||||
|
expression: None,
|
||||||
|
}),
|
||||||
|
r#"{"range":{"start":{"line":2,"character":0},"end":{"line":2,"character":4}}}"#,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,61 @@
|
|||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
DynamicRegistrationClientCapabilities, Range, StaticRegistrationOptions,
|
||||||
|
TextDocumentPositionParams, TextDocumentRegistrationOptions, WorkDoneProgressOptions,
|
||||||
|
WorkDoneProgressParams,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub type LinkedEditingRangeClientCapabilities = DynamicRegistrationClientCapabilities;
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct LinkedEditingRangeOptions {
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub work_done_progress_options: WorkDoneProgressOptions,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct LinkedEditingRangeRegistrationOptions {
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub text_document_registration_options: TextDocumentRegistrationOptions,
|
||||||
|
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub linked_editing_range_options: LinkedEditingRangeOptions,
|
||||||
|
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub static_registration_options: StaticRegistrationOptions,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
|
||||||
|
#[serde(untagged)]
|
||||||
|
pub enum LinkedEditingRangeServerCapabilities {
|
||||||
|
Simple(bool),
|
||||||
|
Options(LinkedEditingRangeOptions),
|
||||||
|
RegistrationOptions(LinkedEditingRangeRegistrationOptions),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct LinkedEditingRangeParams {
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub text_document_position_params: TextDocumentPositionParams,
|
||||||
|
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub work_done_progress_params: WorkDoneProgressParams,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct LinkedEditingRanges {
|
||||||
|
/// A list of ranges that can be renamed together. The ranges must have
|
||||||
|
/// identical length and contain identical text content. The ranges cannot overlap.
|
||||||
|
pub ranges: Vec<Range>,
|
||||||
|
|
||||||
|
/// An optional word pattern (regular expression) that describes valid contents for
|
||||||
|
/// the given ranges. If no pattern is provided, the client configuration's word
|
||||||
|
/// pattern will be used.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub word_pattern: Option<String>,
|
||||||
|
}
|
@ -0,0 +1,336 @@
|
|||||||
|
//! Types of Language Server Index Format (LSIF). LSIF is a standard format
|
||||||
|
//! for language servers or other programming tools to dump their knowledge
|
||||||
|
//! about a workspace.
|
||||||
|
//!
|
||||||
|
//! Based on <https://microsoft.github.io/language-server-protocol/specifications/lsif/0.6.0/specification/>
|
||||||
|
|
||||||
|
use crate::{Range, Url};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
pub type Id = crate::NumberOrString;
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[serde(untagged)]
|
||||||
|
pub enum LocationOrRangeId {
|
||||||
|
Location(crate::Location),
|
||||||
|
RangeId(Id),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct Entry {
|
||||||
|
pub id: Id,
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub data: Element,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
#[serde(tag = "type")]
|
||||||
|
pub enum Element {
|
||||||
|
Vertex(Vertex),
|
||||||
|
Edge(Edge),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
||||||
|
pub struct ToolInfo {
|
||||||
|
pub name: String,
|
||||||
|
#[serde(default = "Default::default")]
|
||||||
|
#[serde(skip_serializing_if = "Vec::is_empty")]
|
||||||
|
pub args: Vec<String>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub version: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Serialize, Deserialize, Clone, Copy)]
|
||||||
|
pub enum Encoding {
|
||||||
|
/// Currently only 'utf-16' is supported due to the limitations in LSP.
|
||||||
|
#[serde(rename = "utf-16")]
|
||||||
|
Utf16,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
||||||
|
pub struct RangeBasedDocumentSymbol {
|
||||||
|
pub id: Id,
|
||||||
|
#[serde(default = "Default::default")]
|
||||||
|
#[serde(skip_serializing_if = "Vec::is_empty")]
|
||||||
|
pub children: Vec<RangeBasedDocumentSymbol>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
#[serde(untagged)]
|
||||||
|
pub enum DocumentSymbolOrRangeBasedVec {
|
||||||
|
DocumentSymbol(Vec<crate::DocumentSymbol>),
|
||||||
|
RangeBased(Vec<RangeBasedDocumentSymbol>),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct DefinitionTag {
|
||||||
|
/// The text covered by the range
|
||||||
|
text: String,
|
||||||
|
/// The symbol kind.
|
||||||
|
kind: crate::SymbolKind,
|
||||||
|
/// Indicates if this symbol is deprecated.
|
||||||
|
#[serde(default)]
|
||||||
|
#[serde(skip_serializing_if = "std::ops::Not::not")]
|
||||||
|
deprecated: bool,
|
||||||
|
/// The full range of the definition not including leading/trailing whitespace but everything else, e.g comments and code.
|
||||||
|
/// The range must be included in fullRange.
|
||||||
|
full_range: Range,
|
||||||
|
/// Optional detail information for the definition.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
detail: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct DeclarationTag {
|
||||||
|
/// The text covered by the range
|
||||||
|
text: String,
|
||||||
|
/// The symbol kind.
|
||||||
|
kind: crate::SymbolKind,
|
||||||
|
/// Indicates if this symbol is deprecated.
|
||||||
|
#[serde(default)]
|
||||||
|
deprecated: bool,
|
||||||
|
/// The full range of the definition not including leading/trailing whitespace but everything else, e.g comments and code.
|
||||||
|
/// The range must be included in fullRange.
|
||||||
|
full_range: Range,
|
||||||
|
/// Optional detail information for the definition.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
detail: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct ReferenceTag {
|
||||||
|
text: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct UnknownTag {
|
||||||
|
text: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
#[serde(tag = "type")]
|
||||||
|
pub enum RangeTag {
|
||||||
|
Definition(DefinitionTag),
|
||||||
|
Declaration(DeclarationTag),
|
||||||
|
Reference(ReferenceTag),
|
||||||
|
Unknown(UnknownTag),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
#[serde(tag = "label")]
|
||||||
|
pub enum Vertex {
|
||||||
|
MetaData(MetaData),
|
||||||
|
/// <https://github.com/Microsoft/language-server-protocol/blob/master/indexFormat/specification.md#the-project-vertex>
|
||||||
|
Project(Project),
|
||||||
|
Document(Document),
|
||||||
|
/// <https://github.com/Microsoft/language-server-protocol/blob/master/indexFormat/specification.md#ranges>
|
||||||
|
Range {
|
||||||
|
#[serde(flatten)]
|
||||||
|
range: Range,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
tag: Option<RangeTag>,
|
||||||
|
},
|
||||||
|
/// <https://github.com/Microsoft/language-server-protocol/blob/master/indexFormat/specification.md#result-set>
|
||||||
|
ResultSet(ResultSet),
|
||||||
|
Moniker(crate::Moniker),
|
||||||
|
PackageInformation(PackageInformation),
|
||||||
|
|
||||||
|
#[serde(rename = "$event")]
|
||||||
|
Event(Event),
|
||||||
|
|
||||||
|
DefinitionResult,
|
||||||
|
DeclarationResult,
|
||||||
|
TypeDefinitionResult,
|
||||||
|
ReferenceResult,
|
||||||
|
ImplementationResult,
|
||||||
|
FoldingRangeResult {
|
||||||
|
result: Vec<crate::FoldingRange>,
|
||||||
|
},
|
||||||
|
HoverResult {
|
||||||
|
result: crate::Hover,
|
||||||
|
},
|
||||||
|
DocumentSymbolResult {
|
||||||
|
result: DocumentSymbolOrRangeBasedVec,
|
||||||
|
},
|
||||||
|
DocumentLinkResult {
|
||||||
|
result: Vec<crate::DocumentLink>,
|
||||||
|
},
|
||||||
|
DiagnosticResult {
|
||||||
|
result: Vec<crate::Diagnostic>,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub enum EventKind {
|
||||||
|
Begin,
|
||||||
|
End,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub enum EventScope {
|
||||||
|
Document,
|
||||||
|
Project,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
||||||
|
pub struct Event {
|
||||||
|
pub kind: EventKind,
|
||||||
|
pub scope: EventScope,
|
||||||
|
pub data: Id,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
#[serde(tag = "label")]
|
||||||
|
pub enum Edge {
|
||||||
|
Contains(EdgeDataMultiIn),
|
||||||
|
Moniker(EdgeData),
|
||||||
|
NextMoniker(EdgeData),
|
||||||
|
Next(EdgeData),
|
||||||
|
PackageInformation(EdgeData),
|
||||||
|
Item(Item),
|
||||||
|
|
||||||
|
// Methods
|
||||||
|
#[serde(rename = "textDocument/definition")]
|
||||||
|
Definition(EdgeData),
|
||||||
|
#[serde(rename = "textDocument/declaration")]
|
||||||
|
Declaration(EdgeData),
|
||||||
|
#[serde(rename = "textDocument/hover")]
|
||||||
|
Hover(EdgeData),
|
||||||
|
#[serde(rename = "textDocument/references")]
|
||||||
|
References(EdgeData),
|
||||||
|
#[serde(rename = "textDocument/implementation")]
|
||||||
|
Implementation(EdgeData),
|
||||||
|
#[serde(rename = "textDocument/typeDefinition")]
|
||||||
|
TypeDefinition(EdgeData),
|
||||||
|
#[serde(rename = "textDocument/foldingRange")]
|
||||||
|
FoldingRange(EdgeData),
|
||||||
|
#[serde(rename = "textDocument/documentLink")]
|
||||||
|
DocumentLink(EdgeData),
|
||||||
|
#[serde(rename = "textDocument/documentSymbol")]
|
||||||
|
DocumentSymbol(EdgeData),
|
||||||
|
#[serde(rename = "textDocument/diagnostic")]
|
||||||
|
Diagnostic(EdgeData),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct EdgeData {
|
||||||
|
pub in_v: Id,
|
||||||
|
pub out_v: Id,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct EdgeDataMultiIn {
|
||||||
|
pub in_vs: Vec<Id>,
|
||||||
|
pub out_v: Id,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[serde(untagged)]
|
||||||
|
pub enum DefinitionResultType {
|
||||||
|
Scalar(LocationOrRangeId),
|
||||||
|
Array(LocationOrRangeId),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub enum ItemKind {
|
||||||
|
Declarations,
|
||||||
|
Definitions,
|
||||||
|
References,
|
||||||
|
ReferenceResults,
|
||||||
|
ImplementationResults,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct Item {
|
||||||
|
pub document: Id,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub property: Option<ItemKind>,
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub edge_data: EdgeDataMultiIn,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct Document {
|
||||||
|
pub uri: Url,
|
||||||
|
pub language_id: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <https://github.com/Microsoft/language-server-protocol/blob/master/indexFormat/specification.md#result-set>
|
||||||
|
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct ResultSet {
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub key: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <https://github.com/Microsoft/language-server-protocol/blob/master/indexFormat/specification.md#the-project-vertex>
|
||||||
|
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct Project {
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub resource: Option<Url>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub content: Option<String>,
|
||||||
|
pub kind: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct MetaData {
|
||||||
|
/// The version of the LSIF format using semver notation. See <https://semver.org/>. Please note
|
||||||
|
/// the version numbers starting with 0 don't adhere to semver and adopters have to assume
|
||||||
|
/// that each new version is breaking.
|
||||||
|
pub version: String,
|
||||||
|
|
||||||
|
/// The project root (in form of an URI) used to compute this dump.
|
||||||
|
pub project_root: Url,
|
||||||
|
|
||||||
|
/// The string encoding used to compute line and character values in
|
||||||
|
/// positions and ranges.
|
||||||
|
pub position_encoding: Encoding,
|
||||||
|
|
||||||
|
/// Information about the tool that created the dump
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub tool_info: Option<ToolInfo>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct Repository {
|
||||||
|
pub r#type: String,
|
||||||
|
pub url: String,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub commit_id: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct PackageInformation {
|
||||||
|
pub name: String,
|
||||||
|
pub manager: String,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub uri: Option<Url>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub content: Option<String>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub repository: Option<Repository>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub version: Option<String>,
|
||||||
|
}
|
@ -0,0 +1,92 @@
|
|||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
DynamicRegistrationClientCapabilities, PartialResultParams, TextDocumentPositionParams,
|
||||||
|
TextDocumentRegistrationOptions, WorkDoneProgressOptions, WorkDoneProgressParams,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub type MonikerClientCapabilities = DynamicRegistrationClientCapabilities;
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
|
||||||
|
#[serde(untagged)]
|
||||||
|
pub enum MonikerServerCapabilities {
|
||||||
|
Options(MonikerOptions),
|
||||||
|
RegistrationOptions(MonikerRegistrationOptions),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
|
||||||
|
pub struct MonikerOptions {
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub work_done_progress_options: WorkDoneProgressOptions,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct MonikerRegistrationOptions {
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub text_document_registration_options: TextDocumentRegistrationOptions,
|
||||||
|
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub moniker_options: MonikerOptions,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Moniker uniqueness level to define scope of the moniker.
|
||||||
|
#[derive(Debug, Eq, PartialEq, Deserialize, Serialize, Copy, Clone)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub enum UniquenessLevel {
|
||||||
|
/// The moniker is only unique inside a document
|
||||||
|
Document,
|
||||||
|
/// The moniker is unique inside a project for which a dump got created
|
||||||
|
Project,
|
||||||
|
/// The moniker is unique inside the group to which a project belongs
|
||||||
|
Group,
|
||||||
|
/// The moniker is unique inside the moniker scheme.
|
||||||
|
Scheme,
|
||||||
|
/// The moniker is globally unique
|
||||||
|
Global,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The moniker kind.
|
||||||
|
#[derive(Debug, Eq, PartialEq, Deserialize, Serialize, Copy, Clone)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub enum MonikerKind {
|
||||||
|
/// The moniker represent a symbol that is imported into a project
|
||||||
|
Import,
|
||||||
|
/// The moniker represent a symbol that is exported into a project
|
||||||
|
Export,
|
||||||
|
/// The moniker represents a symbol that is local to a project (e.g. a local
|
||||||
|
/// variable of a function, a class not visible outside the project, ...)
|
||||||
|
Local,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct MonikerParams {
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub text_document_position_params: TextDocumentPositionParams,
|
||||||
|
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub work_done_progress_params: WorkDoneProgressParams,
|
||||||
|
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub partial_result_params: PartialResultParams,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Moniker definition to match LSIF 0.5 moniker definition.
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct Moniker {
|
||||||
|
/// The scheme of the moniker. For example tsc or .Net
|
||||||
|
pub scheme: String,
|
||||||
|
|
||||||
|
/// The identifier of the moniker. The value is opaque in LSIF however
|
||||||
|
/// schema owners are allowed to define the structure if they want.
|
||||||
|
pub identifier: String,
|
||||||
|
|
||||||
|
/// The scope in which the moniker is unique
|
||||||
|
pub unique: UniquenessLevel,
|
||||||
|
|
||||||
|
/// The moniker kind if known.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub kind: Option<MonikerKind>,
|
||||||
|
}
|
@ -0,0 +1,134 @@
|
|||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::NumberOrString;
|
||||||
|
|
||||||
|
pub type ProgressToken = NumberOrString;
|
||||||
|
|
||||||
|
/// The progress notification is sent from the server to the client to ask
|
||||||
|
/// the client to indicate progress.
|
||||||
|
#[derive(Debug, PartialEq, Deserialize, Serialize, Clone)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct ProgressParams {
|
||||||
|
/// The progress token provided by the client.
|
||||||
|
pub token: ProgressToken,
|
||||||
|
|
||||||
|
/// The progress data.
|
||||||
|
pub value: ProgressParamsValue,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Deserialize, Serialize, Clone)]
|
||||||
|
#[serde(untagged)]
|
||||||
|
pub enum ProgressParamsValue {
|
||||||
|
WorkDone(WorkDoneProgress),
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The `window/workDoneProgress/create` request is sent
|
||||||
|
/// from the server to the client to ask the client to create a work done progress.
|
||||||
|
#[derive(Debug, PartialEq, Deserialize, Serialize, Clone)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct WorkDoneProgressCreateParams {
|
||||||
|
/// The token to be used to report progress.
|
||||||
|
pub token: ProgressToken,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The `window/workDoneProgress/cancel` notification is sent from the client
|
||||||
|
/// to the server to cancel a progress initiated on the server side using the `window/workDoneProgress/create`.
|
||||||
|
#[derive(Debug, PartialEq, Deserialize, Serialize, Clone)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct WorkDoneProgressCancelParams {
|
||||||
|
/// The token to be used to report progress.
|
||||||
|
pub token: ProgressToken,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Options to signal work done progress support in server capabilities.
|
||||||
|
#[derive(Debug, Eq, PartialEq, Default, Deserialize, Serialize, Clone)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct WorkDoneProgressOptions {
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub work_done_progress: Option<bool>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// An optional token that a server can use to report work done progress
|
||||||
|
#[derive(Debug, Eq, PartialEq, Default, Deserialize, Serialize, Clone)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct WorkDoneProgressParams {
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub work_done_token: Option<ProgressToken>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Default, Deserialize, Serialize, Clone)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct WorkDoneProgressBegin {
|
||||||
|
/// Mandatory title of the progress operation. Used to briefly inform
|
||||||
|
/// about the kind of operation being performed.
|
||||||
|
/// Examples: "Indexing" or "Linking dependencies".
|
||||||
|
pub title: String,
|
||||||
|
|
||||||
|
/// Controls if a cancel button should show to allow the user to cancel the
|
||||||
|
/// long running operation. Clients that don't support cancellation are allowed
|
||||||
|
/// to ignore the setting.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub cancellable: Option<bool>,
|
||||||
|
|
||||||
|
/// Optional, more detailed associated progress message. Contains
|
||||||
|
/// complementary information to the `title`.
|
||||||
|
///
|
||||||
|
/// Examples: "3/25 files", "project/src/module2", "node_modules/some_dep".
|
||||||
|
/// If unset, the previous progress message (if any) is still valid.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub message: Option<String>,
|
||||||
|
|
||||||
|
/// Optional progress percentage to display (value 100 is considered 100%).
|
||||||
|
/// If not provided infinite progress is assumed and clients are allowed
|
||||||
|
/// to ignore the `percentage` value in subsequent in report notifications.
|
||||||
|
///
|
||||||
|
/// The value should be steadily rising. Clients are free to ignore values
|
||||||
|
/// that are not following this rule. The value range is [0, 100]
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub percentage: Option<u32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Default, Deserialize, Serialize, Clone)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct WorkDoneProgressReport {
|
||||||
|
/// Controls if a cancel button should show to allow the user to cancel the
|
||||||
|
/// long running operation. Clients that don't support cancellation are allowed
|
||||||
|
/// to ignore the setting.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub cancellable: Option<bool>,
|
||||||
|
|
||||||
|
/// Optional, more detailed associated progress message. Contains
|
||||||
|
/// complementary information to the `title`.
|
||||||
|
/// Examples: "3/25 files", "project/src/module2", "node_modules/some_dep".
|
||||||
|
/// If unset, the previous progress message (if any) is still valid.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub message: Option<String>,
|
||||||
|
|
||||||
|
/// Optional progress percentage to display (value 100 is considered 100%).
|
||||||
|
/// If not provided infinite progress is assumed and clients are allowed
|
||||||
|
/// to ignore the `percentage` value in subsequent in report notifications.
|
||||||
|
///
|
||||||
|
/// The value should be steadily rising. Clients are free to ignore values
|
||||||
|
/// that are not following this rule. The value range is [0, 100]
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub percentage: Option<u32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Default, Deserialize, Serialize, Clone)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct WorkDoneProgressEnd {
|
||||||
|
/// Optional, more detailed associated progress message. Contains
|
||||||
|
/// complementary information to the `title`.
|
||||||
|
/// Examples: "3/25 files", "project/src/module2", "node_modules/some_dep".
|
||||||
|
/// If unset, the previous progress message (if any) is still valid.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub message: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Deserialize, Serialize, Clone)]
|
||||||
|
#[serde(tag = "kind", rename_all = "lowercase")]
|
||||||
|
pub enum WorkDoneProgress {
|
||||||
|
Begin(WorkDoneProgressBegin),
|
||||||
|
Report(WorkDoneProgressReport),
|
||||||
|
End(WorkDoneProgressEnd),
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue