diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2020-02-14 18:04:32 +0000 |
---|---|---|
committer | GitHub <[email protected]> | 2020-02-14 18:04:32 +0000 |
commit | 53cee86666166c6a7316253317d5d40fc20f30f2 (patch) | |
tree | 5e4e50b502de134813b6d247b57f079f9c9fa71a /docs | |
parent | 619b0e16513fe73054262463340c109028f0e11e (diff) | |
parent | 5acb467894053cb0342eb6ded4d162b4a6912483 (diff) |
Merge #3140
3140: Start manual r=matklad a=matklad
Co-authored-by: Aleksey Kladov <[email protected]>
Diffstat (limited to 'docs')
-rw-r--r-- | docs/user/README.md | 280 | ||||
-rw-r--r-- | docs/user/readme.adoc | 152 |
2 files changed, 152 insertions, 280 deletions
diff --git a/docs/user/README.md b/docs/user/README.md deleted file mode 100644 index 14ca6fd64..000000000 --- a/docs/user/README.md +++ /dev/null | |||
@@ -1,280 +0,0 @@ | |||
1 | [github-releases]: https://github.com/rust-analyzer/rust-analyzer/releases | ||
2 | |||
3 | The main interface to rust-analyzer is the | ||
4 | [LSP](https://microsoft.github.io/language-server-protocol/) implementation. To | ||
5 | install lsp server, you have three options: | ||
6 | |||
7 | * **Preferred and default:** install the plugin/extension for your IDE and it will ask your permission to automatically download the latest lsp server for you from [GitHub releases][github-releases]. (See docs to find out whether this is implemented for your editor below). | ||
8 | * Manually download prebuilt binaries from [GitHub releases][github-releases] | ||
9 | * `ra_lsp_server-linux` for Linux | ||
10 | * `ra_lsp_server-mac` for Mac | ||
11 | * `ra_lsp_server-windows.exe` for Windows | ||
12 | * Clone the repository and build from sources | ||
13 | ```bash | ||
14 | $ git clone [email protected]:rust-analyzer/rust-analyzer && cd rust-analyzer | ||
15 | $ cargo xtask install --server # or cargo install --path ./crates/ra_lsp_server | ||
16 | ``` | ||
17 | |||
18 | This way you will get a binary named `ra_lsp_server` (with os suffix for prebuilt binaries) | ||
19 | which you should be able to use with any LSP-compatible editor. | ||
20 | |||
21 | We make use of custom extensions to LSP, so special client-side support is required to take full | ||
22 | advantage of rust-analyzer. This repository contains support code for VS Code. | ||
23 | |||
24 | Rust Analyzer needs sources of rust standard library to work, so | ||
25 | you might also need to execute | ||
26 | |||
27 | ``` | ||
28 | $ rustup component add rust-src | ||
29 | ``` | ||
30 | |||
31 | See [./features.md](./features.md) document for a list of features that are available. | ||
32 | |||
33 | ## VS Code | ||
34 | |||
35 | ### Prerequisites | ||
36 | |||
37 | You will need the most recent version of VS Code: we don't try to | ||
38 | maintain compatibility with older versions yet. | ||
39 | |||
40 | ### Installation from prebuilt binaries | ||
41 | |||
42 | We ship prebuilt binaries for Linux, Mac and Windows via | ||
43 | [GitHub releases][github-releases]. | ||
44 | In order to use them you need to install the client VSCode extension. | ||
45 | |||
46 | Publishing to VS Code marketplace is currently WIP. Thus, you need to manually download | ||
47 | `rust-analyzer-0.1.0.vsix` file from latest [GitHub release][github-releases]. | ||
48 | |||
49 | After you downloaded the `.vsix` file you can install it from the terminal | ||
50 | |||
51 | ``` | ||
52 | $ code --install-extension rust-analyzer-0.1.0.vsix | ||
53 | ``` | ||
54 | |||
55 | Or open VS Code, press <kbd>Ctrl+Shift+P</kbd>, and search for the following command: | ||
56 | |||
57 | <img width="500px" alt="Install from VSIX command" src="https://user-images.githubusercontent.com/36276403/74108225-c0c11d80-4b80-11ea-9b2a-0a43f09e29af.png"> | ||
58 | |||
59 | Press <kbd>Enter</kbd> and go to `rust-analyzer-0.1.0.vsix` file through the file explorer. | ||
60 | |||
61 | Then open some Rust project and you should | ||
62 | see an info message pop-up. | ||
63 | |||
64 | <img height="140px" src="https://user-images.githubusercontent.com/36276403/74103174-a40df100-4b52-11ea-81f4-372c70797924.png" alt="Download now message"/> | ||
65 | |||
66 | |||
67 | Click `Download now`, wait until the progress is 100% and you are ready to go. | ||
68 | |||
69 | For updates you need to remove installed binary | ||
70 | ``` | ||
71 | rm -rf ${HOME}/.config/Code/User/globalStorage/matklad.rust-analyzer | ||
72 | ``` | ||
73 | |||
74 | `"Download latest language server"` command for VSCode and automatic updates detection is currently WIP. | ||
75 | |||
76 | |||
77 | ### Installation from sources | ||
78 | |||
79 | In order to build the VS Code plugin from sources, you need to have node.js and npm with | ||
80 | a minimum version of 12 installed. Please refer to | ||
81 | [node.js and npm documentation](https://nodejs.org) for installation instructions. | ||
82 | |||
83 | The experimental VS Code plugin can be built and installed by executing the | ||
84 | following commands: | ||
85 | |||
86 | ``` | ||
87 | $ git clone https://github.com/rust-analyzer/rust-analyzer.git --depth 1 | ||
88 | $ cd rust-analyzer | ||
89 | $ cargo xtask install | ||
90 | ``` | ||
91 | |||
92 | After that you need to amend your `settings.json` file to explicitly specify the | ||
93 | path to `ra_lsp_server` that you've just built. | ||
94 | ```json | ||
95 | { | ||
96 | "rust-analyzer.raLspServerPath": "ra_lsp_server" | ||
97 | } | ||
98 | ``` | ||
99 | This should work on all platforms, otherwise if installed `ra_lsp_server` is not available through your `$PATH` then see how to configure it [here](#setting-up-the-PATH-variable). | ||
100 | |||
101 | |||
102 | The automatic installation is expected to *just work* for common cases, if it | ||
103 | doesn't, report bugs! | ||
104 | |||
105 | **Note** [#1831](https://github.com/rust-analyzer/rust-analyzer/issues/1831): If you are using the popular | ||
106 | [Vim emulation plugin](https://github.com/VSCodeVim/Vim), you will likely | ||
107 | need to turn off the `rust-analyzer.enableEnhancedTyping` setting. | ||
108 | (// TODO: This configuration is no longer available, enhanced typing shoud be disabled via removing Enter key binding, [see this issue](https://github.com/rust-analyzer/rust-analyzer/issues/3051)) | ||
109 | |||
110 | If you have an unusual setup (for example, `code` is not in the `PATH`), you | ||
111 | should adapt these manual installation instructions: | ||
112 | |||
113 | ``` | ||
114 | $ git clone https://github.com/rust-analyzer/rust-analyzer.git --depth 1 | ||
115 | $ cd rust-analyzer | ||
116 | $ cargo install --path ./crates/ra_lsp_server/ --force --locked | ||
117 | $ cd ./editors/code | ||
118 | $ npm install | ||
119 | $ npm run package | ||
120 | $ code --install-extension ./rust-analyzer-0.1.0.vsix | ||
121 | ``` | ||
122 | |||
123 | It's better to remove existing Rust plugins to avoid interference. | ||
124 | |||
125 | Beyond basic LSP features, there are some extension commands which you can | ||
126 | invoke via <kbd>Ctrl+Shift+P</kbd> or bind to a shortcut. See [./features.md](./features.md) | ||
127 | for details. | ||
128 | |||
129 | For updates, pull the latest changes from the master branch, run `cargo xtask install` again, and **restart** VS Code instance. | ||
130 | See [microsoft/vscode#72308](https://github.com/microsoft/vscode/issues/72308) for why a full restart is needed. | ||
131 | |||
132 | ### VS Code Remote | ||
133 | |||
134 | You can also use `rust-analyzer` with the Visual Studio Code Remote extensions | ||
135 | (Remote SSH, Remote WSL, Remote Containers). In this case, however, you have to | ||
136 | manually install the `.vsix` package: | ||
137 | |||
138 | 1. Build the extension on the remote host using the instructions above (ignore the | ||
139 | error if `code` cannot be found in your PATH: VSCode doesn't need to be installed | ||
140 | on the remote host). | ||
141 | 2. In Visual Studio Code open a connection to the remote host. | ||
142 | 3. Open the Extensions View (`View > Extensions`, keyboard shortcut: `Ctrl+Shift+X`). | ||
143 | 4. From the top-right kebab menu (`ยทยทยท`) select `Install from VSIX...` | ||
144 | 5. Inside the `rust-analyzer` directory find the `editors/code` subdirectory and choose | ||
145 | the `rust-analyzer-0.1.0.vsix` file. | ||
146 | 6. Restart Visual Studio Code and re-establish the connection to the remote host. | ||
147 | |||
148 | In case of errors please make sure that `~/.cargo/bin` is in your `PATH` on the remote | ||
149 | host. | ||
150 | |||
151 | ### Settings | ||
152 | |||
153 | * `rust-analyzer.highlightingOn`: enables experimental syntax highlighting. | ||
154 | Colors can be configured via `editor.tokenColorCustomizations`. | ||
155 | As an example, [Pale Fire](https://github.com/matklad/pale-fire/) color scheme tweaks rust colors. | ||
156 | * `rust-analyzer.enableEnhancedTyping`: by default, rust-analyzer intercepts the | ||
157 | `Enter` key to make it easier to continue comments. Note that it may conflict with VIM emulation plugin. | ||
158 | * `rust-analyzer.raLspServerPath`: path to `ra_lsp_server` executable, when absent or `null` defaults to prebuilt binary path | ||
159 | * `rust-analyzer.enableCargoWatchOnStartup`: prompt to install & enable `cargo | ||
160 | watch` for live error highlighting (note, this **does not** use rust-analyzer) | ||
161 | * `rust-analyzer.excludeGlobs`: a list of glob-patterns for exclusion (see globset [docs](https://docs.rs/globset) for syntax). | ||
162 | Note: glob patterns are applied to all Cargo packages and a rooted at a package root. | ||
163 | This is not very intuitive and a limitation of a current implementation. | ||
164 | * `rust-analyzer.useClientWatching`: use client provided file watching instead | ||
165 | of notify watching. | ||
166 | * `rust-analyzer.cargo-watch.command`: `cargo-watch` command. (e.g: `clippy` will run as `cargo watch -x clippy` ) | ||
167 | * `rust-analyzer.cargo-watch.arguments`: cargo-watch check arguments. | ||
168 | (e.g: `--features="shumway,pdf"` will run as `cargo watch -x "check --features="shumway,pdf""` ) | ||
169 | * `rust-analyzer.cargo-watch.ignore`: list of patterns for cargo-watch to ignore (will be passed as `--ignore`) | ||
170 | * `rust-analyzer.trace.server`: enables internal logging | ||
171 | * `rust-analyzer.trace.cargo-watch`: enables cargo-watch logging | ||
172 | * `RUST_SRC_PATH`: environment variable that overwrites the sysroot | ||
173 | * `rust-analyzer.featureFlags` -- a JSON object to tweak fine-grained behavior: | ||
174 | ```jsonc | ||
175 | { | ||
176 | // Show diagnostics produced by rust-analyzer itself. | ||
177 | "lsp.diagnostics": true, | ||
178 | // Automatically insert `()` and `<>` when completing functions and types. | ||
179 | "completion.insertion.add-call-parenthesis": true, | ||
180 | // Enable completions like `.if`, `.match`, etc. | ||
181 | "completion.enable-postfix": true, | ||
182 | // Show notification when workspace is fully loaded | ||
183 | "notifications.workspace-loaded": true, | ||
184 | // Show error when no Cargo.toml was found | ||
185 | "notifications.cargo-toml-not-found": true, | ||
186 | } | ||
187 | ``` | ||
188 | |||
189 | |||
190 | ## Emacs | ||
191 | |||
192 | * install recent version of `emacs-lsp` package by following the instructions [here][emacs-lsp] | ||
193 | * set `lsp-rust-server` to `'rust-analyzer` | ||
194 | * run `lsp` in a Rust buffer | ||
195 | * (Optionally) bind commands like `lsp-rust-analyzer-join-lines`, `lsp-extend-selection` and `lsp-rust-analyzer-expand-macro` to keys | ||
196 | |||
197 | [emacs-lsp]: https://github.com/emacs-lsp/lsp-mode | ||
198 | |||
199 | |||
200 | ## Vim and NeoVim (coc-rust-analyzer) | ||
201 | |||
202 | * Install coc.nvim by following the instructions at [coc.nvim][] (nodejs required) | ||
203 | * Run `:CocInstall coc-rust-analyzer` to install [coc-rust-analyzer], this extension implements _most_ of the features supported in the VSCode extension: | ||
204 | - same configurations as VSCode extension, `rust-analyzer.raLspServerPath`, `rust-analyzer.enableCargoWatchOnStartup` etc. | ||
205 | - same commands too, `rust-analyzer.analyzerStatus`, `rust-analyzer.startCargoWatch` etc. | ||
206 | - highlighting and inlay_hints are not implemented yet | ||
207 | |||
208 | [coc.nvim]: https://github.com/neoclide/coc.nvim | ||
209 | [coc-rust-analyzer]: https://github.com/fannheyward/coc-rust-analyzer | ||
210 | |||
211 | ## Vim and NeoVim (LanguageClient-neovim) | ||
212 | |||
213 | * Install LanguageClient-neovim by following the instructions [here][lang-client-neovim] | ||
214 | - The github project wiki has extra tips on configuration | ||
215 | |||
216 | * Configure by adding this to your vim/neovim config file (replacing the existing rust specific line if it exists): | ||
217 | |||
218 | ```vim | ||
219 | let g:LanguageClient_serverCommands = { | ||
220 | \ 'rust': ['ra_lsp_server'], | ||
221 | \ } | ||
222 | ``` | ||
223 | |||
224 | [lang-client-neovim]: https://github.com/autozimu/LanguageClient-neovim | ||
225 | |||
226 | ## NeoVim (nvim-lsp) | ||
227 | |||
228 | NeoVim 0.5 (not yet released) has built in language server support. For a quick start configuration | ||
229 | of rust-analyzer, use [neovim/nvim-lsp](https://github.com/neovim/nvim-lsp#rust_analyzer). | ||
230 | Once `neovim/nvim-lsp` is installed, use `lua require'nvim_lsp'.rust_analyzer.setup({})` in your `init.vim`. | ||
231 | |||
232 | |||
233 | ## Sublime Text 3 | ||
234 | |||
235 | Prequisites: | ||
236 | |||
237 | `LSP` package. | ||
238 | |||
239 | Installation: | ||
240 | |||
241 | * Invoke the command palette with <kbd>Ctrl+Shift+P</kbd> | ||
242 | * Type `LSP Settings` to open the LSP preferences editor | ||
243 | * Add the following LSP client definition to your settings: | ||
244 | |||
245 | ```json | ||
246 | "rust-analyzer": { | ||
247 | "command": ["ra_lsp_server"], | ||
248 | "languageId": "rust", | ||
249 | "scopes": ["source.rust"], | ||
250 | "syntaxes": [ | ||
251 | "Packages/Rust/Rust.sublime-syntax", | ||
252 | "Packages/Rust Enhanced/RustEnhanced.sublime-syntax" | ||
253 | ], | ||
254 | "initializationOptions": { | ||
255 | "featureFlags": { | ||
256 | } | ||
257 | }, | ||
258 | } | ||
259 | ``` | ||
260 | |||
261 | * You can now invoke the command palette and type LSP enable to locally/globally enable the rust-analyzer LSP (type LSP enable, then choose either locally or globally, then select rust-analyzer) | ||
262 | |||
263 | |||
264 | <!-- Update links to this header when changing it! --> | ||
265 | ### Setting up the `PATH` variable | ||
266 | |||
267 | On Unix systems, `rustup` adds `~/.cargo/bin` to `PATH` by modifying the shell's | ||
268 | startup file. Depending on your configuration, your Desktop Environment might not | ||
269 | actually load it. If you find that `rust-analyzer` only runs when starting the | ||
270 | editor from the terminal, you will have to set up your `PATH` variable manually. | ||
271 | |||
272 | There are a couple of ways to do that: | ||
273 | |||
274 | - for Code, set `rust-analyzer.raLspServerPath` to `~/.cargo/bin` (the `~` is | ||
275 | automatically resolved by the extension) | ||
276 | - copy the binary to a location that is already in `PATH`, e.g. `/usr/local/bin` | ||
277 | - on Linux, use PAM to configure the `PATH` variable, by e.g. putting | ||
278 | `PATH DEFAULT=/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:@{HOME}/.cargo/bin:@{HOME}/.local/bin` | ||
279 | in your `~/.pam_environment` file; note that this might interfere with other | ||
280 | defaults set by the system administrator via `/etc/environment`. | ||
diff --git a/docs/user/readme.adoc b/docs/user/readme.adoc new file mode 100644 index 000000000..b9ecc7055 --- /dev/null +++ b/docs/user/readme.adoc | |||
@@ -0,0 +1,152 @@ | |||
1 | = User Manual | ||
2 | :toc: preamble | ||
3 | :sectanchors: | ||
4 | :page-layout: post | ||
5 | |||
6 | |||
7 | // Master copy of this document lives in the https://github.com/rust-analyzer/rust-analyzer repository | ||
8 | |||
9 | At it's core, rust-analyzer is a *library* for semantic analysis of the Rust code as it changes over time. | ||
10 | This manual focuses on a specific usage of the library -- the implementation of | ||
11 | https://microsoft.github.io/language-server-protocol/[Language Server Protocol]. | ||
12 | LSP allows various code editors, like VS Code, Emacs or Vim, to implement semantic feature like completion or goto definition by talking to an external language server process. | ||
13 | |||
14 | == Installation | ||
15 | |||
16 | In theory, one should be able to just install the server binary and have it automatically work with any editor. | ||
17 | We are not there yet, so some editor specific setup is required. | ||
18 | |||
19 | === VS Code | ||
20 | |||
21 | This the best supported editor at the moment. | ||
22 | rust-analyzer plugin for VS Code is maintained | ||
23 | https://github.com/rust-analyzer/rust-analyzer/tree/master/editors/code[in tree]. | ||
24 | |||
25 | You can install the latest release of the plugin from | ||
26 | https://marketplace.visualstudio.com/items?itemName=matklad.rust-analyzer[the marketplace]. | ||
27 | By default, the plugin will download the latest version of the server as well. | ||
28 | |||
29 | image::https://user-images.githubusercontent.com/36276403/74103174-a40df100-4b52-11ea-81f4-372c70797924.png[] | ||
30 | |||
31 | The server binary is stored in `~/.config/Code/User/globalStorage/matklad.rust-analyzer`. | ||
32 | |||
33 | Note that we only support the latest version of VS Code. | ||
34 | |||
35 | ==== Updates | ||
36 | |||
37 | The extension will be updated automatically as new versions become available. | ||
38 | The server update functionality is in progress. | ||
39 | For the time being, the workaround is to remove the binary from `globalStorage` and to restart the extension. | ||
40 | |||
41 | ==== Building From Source | ||
42 | |||
43 | Alternatively, both the server and the plugin can be installed from source: | ||
44 | |||
45 | [source] | ||
46 | ---- | ||
47 | $ git clone https://github.com/rust-analyzer/rust-analyzer.git && cs rust-analyzer | ||
48 | $ cargo xtask install | ||
49 | ---- | ||
50 | |||
51 | You'll need Cargo, nodejs and npm for this. | ||
52 | To make VS Code use the freshly build server, add this to the settings: | ||
53 | |||
54 | [source,json] | ||
55 | ---- | ||
56 | { "rust-analyzer.raLspServerPath": "ra_lsp_server" } | ||
57 | ---- | ||
58 | |||
59 | Note that installing via `xtask install` does not work for VS Code Remote, instead you'll need to install the `.vsix` manually. | ||
60 | |||
61 | === Language Server Binary | ||
62 | |||
63 | Other editors generally require `ra_lsp_server` binary to be in `$PATH`. | ||
64 | You can download pre-build binary from | ||
65 | https://github.com/rust-analyzer/rust-analyzer/releases[relases] | ||
66 | page, or you can install it from source using the following command: | ||
67 | |||
68 | [source,bash] | ||
69 | ---- | ||
70 | $ cargo xtask install --server | ||
71 | ---- | ||
72 | |||
73 | === Emacs | ||
74 | |||
75 | Emacs support is maintained https://github.com/emacs-lsp/lsp-mode/blob/master/lsp-rust.el[upstream]. | ||
76 | |||
77 | 1. Install recent version of `emacs-lsp` package by following the instructions https://github.com/emacs-lsp/lsp-mode[here]. | ||
78 | 2. Set `lsp-rust-server` to `'rust-analyzer`. | ||
79 | 3. Run `lsp` in a Rust buffer. | ||
80 | 4. (Optionally) bind commands like `lsp-rust-analyzer-join-lines`, `lsp-extend-selection` and `lsp-rust-analyzer-expand-macro` to keys. | ||
81 | |||
82 | === Vim | ||
83 | |||
84 | The are several LSP client implementations for vim: | ||
85 | |||
86 | ==== coc-rust-analyzer | ||
87 | |||
88 | 1. Install coc.nvim by following the instructions at | ||
89 | https://github.com/neoclide/coc.nvim[coc.nvim] | ||
90 | (nodejs required) | ||
91 | 2. Run `:CocInstall coc-rust-analyzer` to install | ||
92 | https://github.com/fannheyward/coc-rust-analyzer[coc-rust-analyzer], | ||
93 | this extension implements _most_ of the features supported in the VSCode extension: | ||
94 | * same configurations as VSCode extension, `rust-analyzer.raLspServerPath`, `rust-analyzer.enableCargoWatchOnStartup` etc. | ||
95 | * same commands too, `rust-analyzer.analyzerStatus`, `rust-analyzer.startCargoWatch` etc. | ||
96 | * highlighting and inlay_hints are not implemented yet | ||
97 | |||
98 | ==== LanguageClient-neovim | ||
99 | |||
100 | 1. Install LanguageClient-neovim by following the instructions | ||
101 | https://github.com/autozimu/LanguageClient-neovim[here] | ||
102 | * The github project wiki has extra tips on configuration | ||
103 | |||
104 | 2. Configure by adding this to your vim/neovim config file (replacing the existing rust specific line if it exists): | ||
105 | + | ||
106 | [source,vim] | ||
107 | ---- | ||
108 | let g:LanguageClient_serverCommands = { | ||
109 | \ 'rust': ['ra_lsp_server'], | ||
110 | \ } | ||
111 | ---- | ||
112 | |||
113 | ==== nvim-lsp | ||
114 | |||
115 | NeoVim 0.5 (not yet released) has built in language server support. | ||
116 | For a quick start configuration of rust-analyzer, use https://github.com/neovim/nvim-lsp#rust_analyzer[neovim/nvim-lsp]. | ||
117 | Once `neovim/nvim-lsp` is installed, use `lua require'nvim_lsp'.rust_analyzer.setup({})` in your `init.vim`. | ||
118 | |||
119 | === Sublime Text 3 | ||
120 | |||
121 | Prerequisites: | ||
122 | |||
123 | `LSP` package. | ||
124 | |||
125 | Installation: | ||
126 | |||
127 | 1. Invoke the command palette with <kbd>Ctrl+Shift+P</kbd> | ||
128 | 2. Type `LSP Settings` to open the LSP preferences editor | ||
129 | 3. Add the following LSP client definition to your settings: | ||
130 | + | ||
131 | [source,json] | ||
132 | ---- | ||
133 | "rust-analyzer": { | ||
134 | "command": ["ra_lsp_server"], | ||
135 | "languageId": "rust", | ||
136 | "scopes": ["source.rust"], | ||
137 | "syntaxes": [ | ||
138 | "Packages/Rust/Rust.sublime-syntax", | ||
139 | "Packages/Rust Enhanced/RustEnhanced.sublime-syntax" | ||
140 | ], | ||
141 | "initializationOptions": { | ||
142 | "featureFlags": { | ||
143 | } | ||
144 | }, | ||
145 | } | ||
146 | ---- | ||
147 | |||
148 | 4. You can now invoke the command palette and type LSP enable to locally/globally enable the rust-analyzer LSP (type LSP enable, then choose either locally or globally, then select rust-analyzer) | ||
149 | |||
150 | == Usage | ||
151 | |||
152 | See https://github.com/rust-analyzer/rust-analyzer/blob/master/docs/user/features.md[features.md]. | ||