diff options
-rw-r--r-- | crates/ra_proc_macro/src/process.rs | 103 | ||||
-rw-r--r-- | docs/user/readme.adoc | 43 |
2 files changed, 79 insertions, 67 deletions
diff --git a/crates/ra_proc_macro/src/process.rs b/crates/ra_proc_macro/src/process.rs index e24944af4..673f80a7a 100644 --- a/crates/ra_proc_macro/src/process.rs +++ b/crates/ra_proc_macro/src/process.rs | |||
@@ -9,7 +9,7 @@ use crate::rpc::{ExpansionResult, ExpansionTask, ListMacrosResult, ListMacrosTas | |||
9 | use io::{BufRead, BufReader}; | 9 | use io::{BufRead, BufReader}; |
10 | use std::{ | 10 | use std::{ |
11 | convert::{TryFrom, TryInto}, | 11 | convert::{TryFrom, TryInto}, |
12 | ffi::OsStr, | 12 | ffi::{OsStr, OsString}, |
13 | io::{self, Write}, | 13 | io::{self, Write}, |
14 | path::{Path, PathBuf}, | 14 | path::{Path, PathBuf}, |
15 | process::{Child, Command, Stdio}, | 15 | process::{Child, Command, Stdio}, |
@@ -28,56 +28,6 @@ pub(crate) struct ProcMacroProcessThread { | |||
28 | handle: jod_thread::JoinHandle<()>, | 28 | handle: jod_thread::JoinHandle<()>, |
29 | } | 29 | } |
30 | 30 | ||
31 | struct Task { | ||
32 | req: Request, | ||
33 | result_tx: Sender<Option<Response>>, | ||
34 | } | ||
35 | |||
36 | struct Process { | ||
37 | path: PathBuf, | ||
38 | child: Child, | ||
39 | } | ||
40 | |||
41 | impl Drop for Process { | ||
42 | fn drop(&mut self) { | ||
43 | let _ = self.child.kill(); | ||
44 | } | ||
45 | } | ||
46 | |||
47 | impl Process { | ||
48 | fn run( | ||
49 | process_path: PathBuf, | ||
50 | args: impl IntoIterator<Item = impl AsRef<OsStr>>, | ||
51 | ) -> io::Result<Process> { | ||
52 | let child = Command::new(&process_path) | ||
53 | .args(args) | ||
54 | .stdin(Stdio::piped()) | ||
55 | .stdout(Stdio::piped()) | ||
56 | .stderr(Stdio::null()) | ||
57 | .spawn()?; | ||
58 | |||
59 | Ok(Process { path: process_path, child }) | ||
60 | } | ||
61 | |||
62 | fn restart(&mut self) -> io::Result<()> { | ||
63 | let _ = self.child.kill(); | ||
64 | self.child = Command::new(&self.path) | ||
65 | .stdin(Stdio::piped()) | ||
66 | .stdout(Stdio::piped()) | ||
67 | .stderr(Stdio::null()) | ||
68 | .spawn()?; | ||
69 | Ok(()) | ||
70 | } | ||
71 | |||
72 | fn stdio(&mut self) -> Option<(impl Write, impl BufRead)> { | ||
73 | let stdin = self.child.stdin.take()?; | ||
74 | let stdout = self.child.stdout.take()?; | ||
75 | let read = BufReader::new(stdout); | ||
76 | |||
77 | Some((stdin, read)) | ||
78 | } | ||
79 | } | ||
80 | |||
81 | impl ProcMacroProcessSrv { | 31 | impl ProcMacroProcessSrv { |
82 | pub fn run( | 32 | pub fn run( |
83 | process_path: PathBuf, | 33 | process_path: PathBuf, |
@@ -192,6 +142,57 @@ fn client_loop(task_rx: Receiver<Task>, mut process: Process) { | |||
192 | } | 142 | } |
193 | } | 143 | } |
194 | 144 | ||
145 | struct Task { | ||
146 | req: Request, | ||
147 | result_tx: Sender<Option<Response>>, | ||
148 | } | ||
149 | |||
150 | struct Process { | ||
151 | path: PathBuf, | ||
152 | args: Vec<OsString>, | ||
153 | child: Child, | ||
154 | } | ||
155 | |||
156 | impl Drop for Process { | ||
157 | fn drop(&mut self) { | ||
158 | let _ = self.child.kill(); | ||
159 | } | ||
160 | } | ||
161 | |||
162 | impl Process { | ||
163 | fn run( | ||
164 | path: PathBuf, | ||
165 | args: impl IntoIterator<Item = impl AsRef<OsStr>>, | ||
166 | ) -> io::Result<Process> { | ||
167 | let args = args.into_iter().map(|s| s.as_ref().into()).collect(); | ||
168 | let child = mk_child(&path, &args)?; | ||
169 | Ok(Process { path, args, child }) | ||
170 | } | ||
171 | |||
172 | fn restart(&mut self) -> io::Result<()> { | ||
173 | let _ = self.child.kill(); | ||
174 | self.child = mk_child(&self.path, &self.args)?; | ||
175 | Ok(()) | ||
176 | } | ||
177 | |||
178 | fn stdio(&mut self) -> Option<(impl Write, impl BufRead)> { | ||
179 | let stdin = self.child.stdin.take()?; | ||
180 | let stdout = self.child.stdout.take()?; | ||
181 | let read = BufReader::new(stdout); | ||
182 | |||
183 | Some((stdin, read)) | ||
184 | } | ||
185 | } | ||
186 | |||
187 | fn mk_child(path: &Path, args: impl IntoIterator<Item = impl AsRef<OsStr>>) -> io::Result<Child> { | ||
188 | Command::new(&path) | ||
189 | .args(args) | ||
190 | .stdin(Stdio::piped()) | ||
191 | .stdout(Stdio::piped()) | ||
192 | .stderr(Stdio::null()) | ||
193 | .spawn() | ||
194 | } | ||
195 | |||
195 | fn send_request( | 196 | fn send_request( |
196 | mut writer: &mut impl Write, | 197 | mut writer: &mut impl Write, |
197 | mut reader: &mut impl BufRead, | 198 | mut reader: &mut impl BufRead, |
diff --git a/docs/user/readme.adoc b/docs/user/readme.adoc index abd126340..13ab2acc2 100644 --- a/docs/user/readme.adoc +++ b/docs/user/readme.adoc | |||
@@ -14,9 +14,9 @@ | |||
14 | // Master copy of this document lives in the https://github.com/rust-analyzer/rust-analyzer repository | 14 | // Master copy of this document lives in the https://github.com/rust-analyzer/rust-analyzer repository |
15 | 15 | ||
16 | At its core, rust-analyzer is a *library* for semantic analysis of Rust code as it changes over time. | 16 | At its core, rust-analyzer is a *library* for semantic analysis of Rust code as it changes over time. |
17 | This manual focuses on a specific usage of the library -- the implementation of | 17 | This manual focuses on a specific usage of the library -- running it as part of a server that implements the |
18 | https://microsoft.github.io/language-server-protocol/[Language Server Protocol]. | 18 | https://microsoft.github.io/language-server-protocol/[Language Server Protocol] (LSP). |
19 | LSP allows various code editors, like VS Code, Emacs or Vim, to implement semantic features like completion or goto definition by talking to an external language server process. | 19 | The LSP allows various code editors, like VS Code, Emacs or Vim, to implement semantic features like completion or goto definition by talking to an external language server process. |
20 | 20 | ||
21 | To improve this document, send a pull request against | 21 | To improve this document, send a pull request against |
22 | https://github.com/rust-analyzer/rust-analyzer/blob/master/docs/user/readme.adoc[this file]. | 22 | https://github.com/rust-analyzer/rust-analyzer/blob/master/docs/user/readme.adoc[this file]. |
@@ -26,7 +26,7 @@ https://github.com/rust-analyzer/rust-analyzer/blob/master/docs/user/readme.adoc | |||
26 | In theory, one should be able to just install the server binary and have it automatically work with any editor. | 26 | In theory, one should be able to just install the server binary and have it automatically work with any editor. |
27 | We are not there yet, so some editor specific setup is required. | 27 | We are not there yet, so some editor specific setup is required. |
28 | 28 | ||
29 | Additionally, rust-analyzer needs sources of the standard library. | 29 | Additionally, rust-analyzer needs the sources of the standard library. |
30 | If the source code is not present, rust-analyzer will attempt to install it automatically. | 30 | If the source code is not present, rust-analyzer will attempt to install it automatically. |
31 | 31 | ||
32 | To add the sources manually, run the following command: | 32 | To add the sources manually, run the following command: |
@@ -38,7 +38,7 @@ $ rustup component add rust-src | |||
38 | === VS Code | 38 | === VS Code |
39 | 39 | ||
40 | This is the best supported editor at the moment. | 40 | This is the best supported editor at the moment. |
41 | rust-analyzer plugin for VS Code is maintained | 41 | The rust-analyzer plugin for VS Code is maintained |
42 | https://github.com/rust-analyzer/rust-analyzer/tree/master/editors/code[in tree]. | 42 | https://github.com/rust-analyzer/rust-analyzer/tree/master/editors/code[in tree]. |
43 | 43 | ||
44 | You can install the latest release of the plugin from | 44 | You can install the latest release of the plugin from |
@@ -74,7 +74,7 @@ We ship nightly releases for VS Code. To help us out with testing the newest cod | |||
74 | { "rust-analyzer.updates.channel": "nightly" } | 74 | { "rust-analyzer.updates.channel": "nightly" } |
75 | ---- | 75 | ---- |
76 | 76 | ||
77 | You will be prompted to install the `nightly` extension version. Just click `Download now` and from that moment you will get automatic updates each 24 hours. | 77 | You will be prompted to install the `nightly` extension version. Just click `Download now` and from that moment you will get automatic updates every 24 hours. |
78 | 78 | ||
79 | If you don't want to be asked for `Download now` every day when the new nightly version is released add the following to your `settings.json`: | 79 | If you don't want to be asked for `Download now` every day when the new nightly version is released add the following to your `settings.json`: |
80 | [source,json] | 80 | [source,json] |
@@ -110,19 +110,21 @@ Here are some useful self-diagnostic commands: | |||
110 | 110 | ||
111 | === Language Server Binary | 111 | === Language Server Binary |
112 | 112 | ||
113 | Other editors generally require `rust-analyzer` binary to be in `$PATH`. | 113 | Other editors generally require the `rust-analyzer` binary to be in `$PATH`. |
114 | You can download the pre-built binary from | 114 | You can download the pre-built binary from the https://github.com/rust-analyzer/rust-analyzer/releases[releases] page. Typically, you then need to rename the binary for your platform, e.g. `rust-analyzer-mac` if you're on Mac OS, to `rust-analzyer` and make it executable in addition to moving it into a directory in your `$PATH`. |
115 | https://github.com/rust-analyzer/rust-analyzer/releases[releases] | 115 | |
116 | page, or you can install it from source using the following command: | 116 | Alternatively, you can install it from source using the following command: |
117 | 117 | ||
118 | [source,bash] | 118 | [source,bash] |
119 | ---- | 119 | ---- |
120 | $ cargo xtask install --server | 120 | $ cargo xtask install --server |
121 | ---- | 121 | ---- |
122 | 122 | ||
123 | If your editor can't find the binary even though the binary is on your `$PATH`, the likely explanation is that it doesn't see the same `$PATH` as the shell, see https://github.com/rust-analyzer/rust-analyzer/issues/1811[this issue]. On Unix, running the editor from a shell or changing the `.desktop` file to set the environment should help. | ||
124 | |||
123 | ==== Arch Linux | 125 | ==== Arch Linux |
124 | 126 | ||
125 | `rust-analyzer` binary can be installed from AUR (Arch User Repository): | 127 | The `rust-analyzer` binary can be installed from AUR (Arch User Repository): |
126 | 128 | ||
127 | - https://aur.archlinux.org/packages/rust-analyzer-bin[`rust-analyzer-bin`] (binary from GitHub releases) | 129 | - https://aur.archlinux.org/packages/rust-analyzer-bin[`rust-analyzer-bin`] (binary from GitHub releases) |
128 | - https://aur.archlinux.org/packages/rust-analyzer[`rust-analyzer`] (built from latest tagged source) | 130 | - https://aur.archlinux.org/packages/rust-analyzer[`rust-analyzer`] (built from latest tagged source) |
@@ -156,8 +158,8 @@ The are several LSP client implementations for vim: | |||
156 | 2. Run `:CocInstall coc-rust-analyzer` to install | 158 | 2. Run `:CocInstall coc-rust-analyzer` to install |
157 | https://github.com/fannheyward/coc-rust-analyzer[coc-rust-analyzer], | 159 | https://github.com/fannheyward/coc-rust-analyzer[coc-rust-analyzer], |
158 | this extension implements _most_ of the features supported in the VSCode extension: | 160 | this extension implements _most_ of the features supported in the VSCode extension: |
159 | * same configurations as VSCode extension, `rust-analyzer.serverPath`, `rust-analyzer.enableCargoWatchOnStartup` etc. | 161 | * same configurations as VSCode extension, `rust-analyzer.serverPath`, `rust-analyzer.cargo.features` etc. |
160 | * same commands too, `rust-analyzer.analyzerStatus`, `rust-analyzer.startCargoWatch` etc. | 162 | * same commands too, `rust-analyzer.analyzerStatus`, `rust-analyzer.ssr` etc. |
161 | * highlighting and inlay_hints are not implemented yet | 163 | * highlighting and inlay_hints are not implemented yet |
162 | 164 | ||
163 | ==== LanguageClient-neovim | 165 | ==== LanguageClient-neovim |
@@ -183,11 +185,20 @@ Once `neovim/nvim-lsp` is installed, use `+lua require'nvim_lsp'.rust_analyzer.s | |||
183 | 185 | ||
184 | === Sublime Text 3 | 186 | === Sublime Text 3 |
185 | 187 | ||
186 | Prerequisites: | 188 | Prerequisites: You have installed the <<language-server-binary,`rust-analyzer` binary>>. |
189 | |||
190 | You also need the `LSP` package. To install it: | ||
191 | |||
192 | 1. If you've never installed a Sublime Text package, install Package Control: | ||
193 | * Open the command palette (Win/Linux: `ctrl+shift+p`, Mac: `cmd+shift+p`) | ||
194 | * Type `Install Package Control`, press enter | ||
195 | 2. In the command palette, run `Package control: Install package`, and in the list that pops up, type `LSP` and press enter. | ||
196 | |||
197 | Finally, with your Rust project open, in the command palette, run `LSP: Enable Language Server In Project` or `LSP: Enable Language Server Globally`, then select `rust-analyzer` in the list that pops up to enable the rust-analyzer LSP. The latter means that rust-analzyer is enabled by default in Rust projects. | ||
187 | 198 | ||
188 | `LSP` package. | 199 | If it worked, you should see "rust-analzyer, Line X, Column Y" on the left side of the bottom bar, and after waiting a bit, functionality like tooltips on hovering over variables should become available. |
189 | 200 | ||
190 | Invoke the command palette (`ctrl+shift+p`) 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) | 201 | If you get an error saying `No such file or directory: 'rust-analyzer'`, see the <<language-server-binary,section on installing the language server binary>>. |
191 | 202 | ||
192 | == Usage | 203 | == Usage |
193 | 204 | ||