diff options
Diffstat (limited to 'crates/ra_flycheck/src/lib.rs')
-rw-r--r-- | crates/ra_flycheck/src/lib.rs | 62 |
1 files changed, 39 insertions, 23 deletions
diff --git a/crates/ra_flycheck/src/lib.rs b/crates/ra_flycheck/src/lib.rs index 6c4170529..7b9f48eb0 100644 --- a/crates/ra_flycheck/src/lib.rs +++ b/crates/ra_flycheck/src/lib.rs | |||
@@ -3,6 +3,7 @@ | |||
3 | //! LSP diagnostics based on the output of the command. | 3 | //! LSP diagnostics based on the output of the command. |
4 | 4 | ||
5 | use std::{ | 5 | use std::{ |
6 | fmt, | ||
6 | io::{self, BufReader}, | 7 | io::{self, BufReader}, |
7 | path::PathBuf, | 8 | path::PathBuf, |
8 | process::{Command, Stdio}, | 9 | process::{Command, Stdio}, |
@@ -16,6 +17,9 @@ pub use cargo_metadata::diagnostic::{ | |||
16 | Applicability, Diagnostic, DiagnosticLevel, DiagnosticSpan, DiagnosticSpanMacroExpansion, | 17 | Applicability, Diagnostic, DiagnosticLevel, DiagnosticSpan, DiagnosticSpanMacroExpansion, |
17 | }; | 18 | }; |
18 | 19 | ||
20 | type Progress = ra_progress::Progress<(), String>; | ||
21 | type ProgressSource = ra_progress::ProgressSource<(), String>; | ||
22 | |||
19 | #[derive(Clone, Debug, PartialEq, Eq)] | 23 | #[derive(Clone, Debug, PartialEq, Eq)] |
20 | pub enum FlycheckConfig { | 24 | pub enum FlycheckConfig { |
21 | CargoCommand { | 25 | CargoCommand { |
@@ -31,6 +35,17 @@ pub enum FlycheckConfig { | |||
31 | }, | 35 | }, |
32 | } | 36 | } |
33 | 37 | ||
38 | impl fmt::Display for FlycheckConfig { | ||
39 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
40 | match self { | ||
41 | FlycheckConfig::CargoCommand { command, .. } => write!(f, "cargo {}", command), | ||
42 | FlycheckConfig::CustomCommand { command, args } => { | ||
43 | write!(f, "{} {}", command, args.join(" ")) | ||
44 | } | ||
45 | } | ||
46 | } | ||
47 | } | ||
48 | |||
34 | /// Flycheck wraps the shared state and communication machinery used for | 49 | /// Flycheck wraps the shared state and communication machinery used for |
35 | /// running `cargo check` (or other compatible command) and providing | 50 | /// running `cargo check` (or other compatible command) and providing |
36 | /// diagnostics based on the output. | 51 | /// diagnostics based on the output. |
@@ -44,11 +59,15 @@ pub struct Flycheck { | |||
44 | } | 59 | } |
45 | 60 | ||
46 | impl Flycheck { | 61 | impl Flycheck { |
47 | pub fn new(config: FlycheckConfig, workspace_root: PathBuf) -> Flycheck { | 62 | pub fn new( |
63 | config: FlycheckConfig, | ||
64 | workspace_root: PathBuf, | ||
65 | progress_src: ProgressSource, | ||
66 | ) -> Flycheck { | ||
48 | let (task_send, task_recv) = unbounded::<CheckTask>(); | 67 | let (task_send, task_recv) = unbounded::<CheckTask>(); |
49 | let (cmd_send, cmd_recv) = unbounded::<CheckCommand>(); | 68 | let (cmd_send, cmd_recv) = unbounded::<CheckCommand>(); |
50 | let handle = jod_thread::spawn(move || { | 69 | let handle = jod_thread::spawn(move || { |
51 | FlycheckThread::new(config, workspace_root).run(&task_send, &cmd_recv); | 70 | FlycheckThread::new(config, workspace_root, progress_src).run(&task_send, &cmd_recv); |
52 | }); | 71 | }); |
53 | Flycheck { task_recv, cmd_send, handle } | 72 | Flycheck { task_recv, cmd_send, handle } |
54 | } | 73 | } |
@@ -66,16 +85,6 @@ pub enum CheckTask { | |||
66 | 85 | ||
67 | /// Request adding a diagnostic with fixes included to a file | 86 | /// Request adding a diagnostic with fixes included to a file |
68 | AddDiagnostic { workspace_root: PathBuf, diagnostic: Diagnostic }, | 87 | AddDiagnostic { workspace_root: PathBuf, diagnostic: Diagnostic }, |
69 | |||
70 | /// Request check progress notification to client | ||
71 | Status(Status), | ||
72 | } | ||
73 | |||
74 | #[derive(Debug)] | ||
75 | pub enum Status { | ||
76 | Being, | ||
77 | Progress(String), | ||
78 | End, | ||
79 | } | 88 | } |
80 | 89 | ||
81 | pub enum CheckCommand { | 90 | pub enum CheckCommand { |
@@ -87,6 +96,8 @@ struct FlycheckThread { | |||
87 | config: FlycheckConfig, | 96 | config: FlycheckConfig, |
88 | workspace_root: PathBuf, | 97 | workspace_root: PathBuf, |
89 | last_update_req: Option<Instant>, | 98 | last_update_req: Option<Instant>, |
99 | progress_src: ProgressSource, | ||
100 | progress: Option<Progress>, | ||
90 | // XXX: drop order is significant | 101 | // XXX: drop order is significant |
91 | message_recv: Receiver<CheckEvent>, | 102 | message_recv: Receiver<CheckEvent>, |
92 | /// WatchThread exists to wrap around the communication needed to be able to | 103 | /// WatchThread exists to wrap around the communication needed to be able to |
@@ -98,11 +109,17 @@ struct FlycheckThread { | |||
98 | } | 109 | } |
99 | 110 | ||
100 | impl FlycheckThread { | 111 | impl FlycheckThread { |
101 | fn new(config: FlycheckConfig, workspace_root: PathBuf) -> FlycheckThread { | 112 | fn new( |
113 | config: FlycheckConfig, | ||
114 | workspace_root: PathBuf, | ||
115 | progress_src: ProgressSource, | ||
116 | ) -> FlycheckThread { | ||
102 | FlycheckThread { | 117 | FlycheckThread { |
103 | config, | 118 | config, |
104 | workspace_root, | 119 | workspace_root, |
120 | progress_src, | ||
105 | last_update_req: None, | 121 | last_update_req: None, |
122 | progress: None, | ||
106 | message_recv: never(), | 123 | message_recv: never(), |
107 | check_process: None, | 124 | check_process: None, |
108 | } | 125 | } |
@@ -140,9 +157,9 @@ impl FlycheckThread { | |||
140 | } | 157 | } |
141 | } | 158 | } |
142 | 159 | ||
143 | fn clean_previous_results(&self, task_send: &Sender<CheckTask>) { | 160 | fn clean_previous_results(&mut self, task_send: &Sender<CheckTask>) { |
144 | task_send.send(CheckTask::ClearDiagnostics).unwrap(); | 161 | task_send.send(CheckTask::ClearDiagnostics).unwrap(); |
145 | task_send.send(CheckTask::Status(Status::End)).unwrap(); | 162 | self.progress = None; |
146 | } | 163 | } |
147 | 164 | ||
148 | fn should_recheck(&mut self) -> bool { | 165 | fn should_recheck(&mut self) -> bool { |
@@ -161,18 +178,17 @@ impl FlycheckThread { | |||
161 | } | 178 | } |
162 | } | 179 | } |
163 | 180 | ||
164 | fn handle_message(&self, msg: CheckEvent, task_send: &Sender<CheckTask>) { | 181 | fn handle_message(&mut self, msg: CheckEvent, task_send: &Sender<CheckTask>) { |
165 | match msg { | 182 | match msg { |
166 | CheckEvent::Begin => { | 183 | CheckEvent::Begin => { |
167 | task_send.send(CheckTask::Status(Status::Being)).unwrap(); | 184 | self.progress = Some(self.progress_src.begin(())); |
168 | } | 185 | } |
169 | 186 | CheckEvent::End => self.progress = None, | |
170 | CheckEvent::End => { | ||
171 | task_send.send(CheckTask::Status(Status::End)).unwrap(); | ||
172 | } | ||
173 | |||
174 | CheckEvent::Msg(Message::CompilerArtifact(msg)) => { | 187 | CheckEvent::Msg(Message::CompilerArtifact(msg)) => { |
175 | task_send.send(CheckTask::Status(Status::Progress(msg.target.name))).unwrap(); | 188 | self.progress |
189 | .as_mut() | ||
190 | .expect("check process reported progress without the 'Begin' notification") | ||
191 | .report(msg.target.name); | ||
176 | } | 192 | } |
177 | 193 | ||
178 | CheckEvent::Msg(Message::CompilerMessage(msg)) => { | 194 | CheckEvent::Msg(Message::CompilerMessage(msg)) => { |