diff options
Diffstat (limited to 'crates/ra_lsp_server/src/main_loop')
-rw-r--r-- | crates/ra_lsp_server/src/main_loop/handlers.rs | 111 |
1 files changed, 65 insertions, 46 deletions
diff --git a/crates/ra_lsp_server/src/main_loop/handlers.rs b/crates/ra_lsp_server/src/main_loop/handlers.rs index fa7179cd8..9d7f4f9f1 100644 --- a/crates/ra_lsp_server/src/main_loop/handlers.rs +++ b/crates/ra_lsp_server/src/main_loop/handlers.rs | |||
@@ -268,41 +268,29 @@ pub fn handle_runnables( | |||
268 | }; | 268 | }; |
269 | res.push(r); | 269 | res.push(r); |
270 | } | 270 | } |
271 | let mut check_args = vec!["check".to_string()]; | ||
272 | match CargoTargetSpec::for_file(&world, file_id)? { | ||
273 | Some(spec) => spec.push_to(&mut check_args), | ||
274 | None => check_args.push("--all".to_string()), | ||
275 | } | ||
271 | // Always add `cargo check`. | 276 | // Always add `cargo check`. |
272 | res.push(req::Runnable { | 277 | res.push(req::Runnable { |
273 | range: Default::default(), | 278 | range: Default::default(), |
274 | label: "cargo check".to_string(), | 279 | label: "cargo check".to_string(), |
275 | bin: "cargo".to_string(), | 280 | bin: "cargo".to_string(), |
276 | args: vec!["check".to_string(), "--all".to_string()], | 281 | args: check_args, |
277 | env: FxHashMap::default(), | 282 | env: FxHashMap::default(), |
278 | }); | 283 | }); |
279 | return Ok(res); | 284 | return Ok(res); |
280 | 285 | ||
281 | fn runnable_args(world: &ServerWorld, file_id: FileId, kind: &RunnableKind) -> Result<Vec<String>> { | 286 | fn runnable_args(world: &ServerWorld, file_id: FileId, kind: &RunnableKind) -> Result<Vec<String>> { |
282 | let spec = if let Some(&crate_id) = world.analysis().crate_for(file_id)?.first() { | 287 | let spec = CargoTargetSpec::for_file(world, file_id)?; |
283 | let file_id = world.analysis().crate_root(crate_id)?; | ||
284 | let path = world.path_map.get_path(file_id); | ||
285 | world | ||
286 | .workspaces | ||
287 | .iter() | ||
288 | .filter_map(|ws| { | ||
289 | let tgt = ws.target_by_root(path)?; | ||
290 | Some(( | ||
291 | tgt.package(ws).name(ws), | ||
292 | tgt.name(ws), | ||
293 | tgt.kind(ws), | ||
294 | )) | ||
295 | }) | ||
296 | .next() | ||
297 | } else { | ||
298 | None | ||
299 | }; | ||
300 | let mut res = Vec::new(); | 288 | let mut res = Vec::new(); |
301 | match kind { | 289 | match kind { |
302 | RunnableKind::Test { name } => { | 290 | RunnableKind::Test { name } => { |
303 | res.push("test".to_string()); | 291 | res.push("test".to_string()); |
304 | if let Some((pkg_name, tgt_name, tgt_kind)) = spec { | 292 | if let Some(spec) = spec { |
305 | spec_args(pkg_name, tgt_name, tgt_kind, &mut res); | 293 | spec.push_to(&mut res); |
306 | } | 294 | } |
307 | res.push("--".to_string()); | 295 | res.push("--".to_string()); |
308 | res.push(name.to_string()); | 296 | res.push(name.to_string()); |
@@ -310,38 +298,69 @@ pub fn handle_runnables( | |||
310 | } | 298 | } |
311 | RunnableKind::Bin => { | 299 | RunnableKind::Bin => { |
312 | res.push("run".to_string()); | 300 | res.push("run".to_string()); |
313 | if let Some((pkg_name, tgt_name, tgt_kind)) = spec { | 301 | if let Some(spec) = spec { |
314 | spec_args(pkg_name, tgt_name, tgt_kind, &mut res); | 302 | spec.push_to(&mut res); |
315 | } | 303 | } |
316 | } | 304 | } |
317 | } | 305 | } |
318 | Ok(res) | 306 | Ok(res) |
319 | } | 307 | } |
320 | 308 | ||
321 | fn spec_args(pkg_name: &str, tgt_name: &str, tgt_kind: TargetKind, buf: &mut Vec<String>) { | 309 | struct CargoTargetSpec { |
322 | buf.push("--package".to_string()); | 310 | package: String, |
323 | buf.push(pkg_name.to_string()); | 311 | target: String, |
324 | match tgt_kind { | 312 | target_kind: TargetKind, |
325 | TargetKind::Bin => { | 313 | } |
326 | buf.push("--bin".to_string()); | 314 | |
327 | buf.push(tgt_name.to_string()); | 315 | impl CargoTargetSpec { |
328 | } | 316 | fn for_file(world: &ServerWorld, file_id: FileId) -> Result<Option<CargoTargetSpec>> { |
329 | TargetKind::Test => { | 317 | let &crate_id = match world.analysis().crate_for(file_id)?.first() { |
330 | buf.push("--test".to_string()); | 318 | Some(crate_id) => crate_id, |
331 | buf.push(tgt_name.to_string()); | 319 | None => return Ok(None), |
332 | } | 320 | }; |
333 | TargetKind::Bench => { | 321 | let file_id = world.analysis().crate_root(crate_id)?; |
334 | buf.push("--bench".to_string()); | 322 | let path = world.path_map.get_path(file_id); |
335 | buf.push(tgt_name.to_string()); | 323 | let res = world |
336 | } | 324 | .workspaces |
337 | TargetKind::Example => { | 325 | .iter() |
338 | buf.push("--example".to_string()); | 326 | .find_map(|ws| { |
339 | buf.push(tgt_name.to_string()); | 327 | let tgt = ws.target_by_root(path)?; |
340 | } | 328 | let res = CargoTargetSpec { |
341 | TargetKind::Lib => { | 329 | package: tgt.package(ws).name(ws).to_string(), |
342 | buf.push("--lib".to_string()); | 330 | target: tgt.name(ws).to_string(), |
331 | target_kind: tgt.kind(ws), | ||
332 | }; | ||
333 | Some(res) | ||
334 | }); | ||
335 | Ok(res) | ||
336 | } | ||
337 | |||
338 | fn push_to(self, buf: &mut Vec<String>) { | ||
339 | buf.push("--package".to_string()); | ||
340 | buf.push(self.package); | ||
341 | match self.target_kind { | ||
342 | TargetKind::Bin => { | ||
343 | buf.push("--bin".to_string()); | ||
344 | buf.push(self.target); | ||
345 | } | ||
346 | TargetKind::Test => { | ||
347 | buf.push("--test".to_string()); | ||
348 | buf.push(self.target); | ||
349 | } | ||
350 | TargetKind::Bench => { | ||
351 | buf.push("--bench".to_string()); | ||
352 | buf.push(self.target); | ||
353 | } | ||
354 | TargetKind::Example => { | ||
355 | buf.push("--example".to_string()); | ||
356 | buf.push(self.target); | ||
357 | } | ||
358 | TargetKind::Lib => { | ||
359 | buf.push("--lib".to_string()); | ||
360 | } | ||
361 | TargetKind::Other => (), | ||
343 | } | 362 | } |
344 | TargetKind::Other => (), | 363 | |
345 | } | 364 | } |
346 | } | 365 | } |
347 | } | 366 | } |