aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2020-05-18 08:37:04 +0100
committerGitHub <[email protected]>2020-05-18 08:37:04 +0100
commitc6ed08967193cadc927dfaf422601bcd160a6fc9 (patch)
treeaaccb210353786d000a3455264e368b76f61ff98 /crates
parent31611da2538e66027ea67482235f6b8659bedf09 (diff)
parent78817a319476d8af40c4f78e8c47dc958781f88f (diff)
Merge #4499
4499: CodeLens configuration options r=vsrs a=vsrs This PR - adds an option to granularly enable\disable all CodeLens, just like the TypeScript extension. - fixes a minor bug for doctests. It makes no sense to show `Debug` lens for them as cargo `Can't skip running doc tests with --no-run`. Co-authored-by: vsrs <[email protected]>
Diffstat (limited to 'crates')
-rw-r--r--crates/rust-analyzer/src/config.rs41
-rw-r--r--crates/rust-analyzer/src/main_loop/handlers.rs166
2 files changed, 134 insertions, 73 deletions
diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs
index 53aee833d..b5dc6f0fa 100644
--- a/crates/rust-analyzer/src/config.rs
+++ b/crates/rust-analyzer/src/config.rs
@@ -33,6 +33,36 @@ pub struct Config {
33 pub inlay_hints: InlayHintsConfig, 33 pub inlay_hints: InlayHintsConfig,
34 pub completion: CompletionConfig, 34 pub completion: CompletionConfig,
35 pub call_info_full: bool, 35 pub call_info_full: bool,
36 pub lens: LensConfig,
37}
38
39#[derive(Clone, Debug, PartialEq, Eq)]
40pub struct LensConfig {
41 pub run: bool,
42 pub debug: bool,
43 pub impementations: bool,
44}
45
46impl Default for LensConfig {
47 fn default() -> Self {
48 Self { run: true, debug: true, impementations: true }
49 }
50}
51
52impl LensConfig {
53 pub const NO_LENS: LensConfig = Self { run: false, debug: false, impementations: false };
54
55 pub fn any(&self) -> bool {
56 self.impementations || self.runnable()
57 }
58
59 pub fn none(&self) -> bool {
60 !self.any()
61 }
62
63 pub fn runnable(&self) -> bool {
64 self.run || self.debug
65 }
36} 66}
37 67
38#[derive(Debug, Clone)] 68#[derive(Debug, Clone)]
@@ -107,6 +137,7 @@ impl Default for Config {
107 ..CompletionConfig::default() 137 ..CompletionConfig::default()
108 }, 138 },
109 call_info_full: true, 139 call_info_full: true,
140 lens: LensConfig::default(),
110 } 141 }
111 } 142 }
112} 143}
@@ -196,6 +227,16 @@ impl Config {
196 set(value, "/completion/addCallArgumentSnippets", &mut self.completion.add_call_argument_snippets); 227 set(value, "/completion/addCallArgumentSnippets", &mut self.completion.add_call_argument_snippets);
197 set(value, "/callInfo/full", &mut self.call_info_full); 228 set(value, "/callInfo/full", &mut self.call_info_full);
198 229
230 let mut lens_enabled = true;
231 set(value, "/lens/enable", &mut lens_enabled);
232 if lens_enabled {
233 set(value, "/lens/run", &mut self.lens.run);
234 set(value, "/lens/debug", &mut self.lens.debug);
235 set(value, "/lens/implementations", &mut self.lens.impementations);
236 } else {
237 self.lens = LensConfig::NO_LENS;
238 }
239
199 log::info!("Config::update() = {:#?}", self); 240 log::info!("Config::update() = {:#?}", self);
200 241
201 fn get<'a, T: Deserialize<'a>>(value: &'a serde_json::Value, pointer: &str) -> Option<T> { 242 fn get<'a, T: Deserialize<'a>>(value: &'a serde_json::Value, pointer: &str) -> Option<T> {
diff --git a/crates/rust-analyzer/src/main_loop/handlers.rs b/crates/rust-analyzer/src/main_loop/handlers.rs
index 6b14830b6..e67556752 100644
--- a/crates/rust-analyzer/src/main_loop/handlers.rs
+++ b/crates/rust-analyzer/src/main_loop/handlers.rs
@@ -812,88 +812,108 @@ pub fn handle_code_lens(
812 params: lsp_types::CodeLensParams, 812 params: lsp_types::CodeLensParams,
813) -> Result<Option<Vec<CodeLens>>> { 813) -> Result<Option<Vec<CodeLens>>> {
814 let _p = profile("handle_code_lens"); 814 let _p = profile("handle_code_lens");
815 let file_id = from_proto::file_id(&world, &params.text_document.uri)?;
816 let line_index = world.analysis().file_line_index(file_id)?;
817
818 let mut lenses: Vec<CodeLens> = Default::default(); 815 let mut lenses: Vec<CodeLens> = Default::default();
819 816
817 if world.config.lens.none() {
818 // early return before any db query!
819 return Ok(Some(lenses));
820 }
821
822 let file_id = from_proto::file_id(&world, &params.text_document.uri)?;
823 let line_index = world.analysis().file_line_index(file_id)?;
820 let cargo_spec = CargoTargetSpec::for_file(&world, file_id)?; 824 let cargo_spec = CargoTargetSpec::for_file(&world, file_id)?;
821 // Gather runnables 825
822 for runnable in world.analysis().runnables(file_id)? { 826 if world.config.lens.runnable() {
823 let title = match &runnable.kind { 827 // Gather runnables
824 RunnableKind::Test { .. } | RunnableKind::TestMod { .. } => "▶\u{fe0e} Run Test", 828 for runnable in world.analysis().runnables(file_id)? {
825 RunnableKind::DocTest { .. } => "▶\u{fe0e} Run Doctest", 829 let (run_title, debugee) = match &runnable.kind {
826 RunnableKind::Bench { .. } => "Run Bench", 830 RunnableKind::Test { .. } | RunnableKind::TestMod { .. } => {
827 RunnableKind::Bin => { 831 ("▶️\u{fe0e}Run Test", true)
828 // Do not suggest binary run on other target than binary
829 match &cargo_spec {
830 Some(spec) => match spec.target_kind {
831 TargetKind::Bin => "Run",
832 _ => continue,
833 },
834 None => continue,
835 } 832 }
833 RunnableKind::DocTest { .. } => {
834 // cargo does not support -no-run for doctests
835 ("▶️\u{fe0e}Run Doctest", false)
836 }
837 RunnableKind::Bench { .. } => {
838 // Nothing wrong with bench debugging
839 ("Run Bench", true)
840 }
841 RunnableKind::Bin => {
842 // Do not suggest binary run on other target than binary
843 match &cargo_spec {
844 Some(spec) => match spec.target_kind {
845 TargetKind::Bin => ("Run", true),
846 _ => continue,
847 },
848 None => continue,
849 }
850 }
851 };
852
853 let mut r = to_lsp_runnable(&world, file_id, runnable)?;
854 if world.config.lens.run {
855 let lens = CodeLens {
856 range: r.range,
857 command: Some(Command {
858 title: run_title.to_string(),
859 command: "rust-analyzer.runSingle".into(),
860 arguments: Some(vec![to_value(&r).unwrap()]),
861 }),
862 data: None,
863 };
864 lenses.push(lens);
836 } 865 }
837 }
838 .to_string();
839 let mut r = to_lsp_runnable(&world, file_id, runnable)?;
840 let lens = CodeLens {
841 range: r.range,
842 command: Some(Command {
843 title,
844 command: "rust-analyzer.runSingle".into(),
845 arguments: Some(vec![to_value(&r).unwrap()]),
846 }),
847 data: None,
848 };
849 lenses.push(lens);
850 866
851 if r.args[0] == "run" { 867 if debugee && world.config.lens.debug {
852 r.args[0] = "build".into(); 868 if r.args[0] == "run" {
853 } else { 869 r.args[0] = "build".into();
854 r.args.push("--no-run".into()); 870 } else {
871 r.args.push("--no-run".into());
872 }
873 let debug_lens = CodeLens {
874 range: r.range,
875 command: Some(Command {
876 title: "Debug".into(),
877 command: "rust-analyzer.debugSingle".into(),
878 arguments: Some(vec![to_value(r).unwrap()]),
879 }),
880 data: None,
881 };
882 lenses.push(debug_lens);
883 }
855 } 884 }
856 let debug_lens = CodeLens {
857 range: r.range,
858 command: Some(Command {
859 title: "Debug".into(),
860 command: "rust-analyzer.debugSingle".into(),
861 arguments: Some(vec![to_value(r).unwrap()]),
862 }),
863 data: None,
864 };
865 lenses.push(debug_lens);
866 } 885 }
867 886
868 // Handle impls 887 if world.config.lens.impementations {
869 lenses.extend( 888 // Handle impls
870 world 889 lenses.extend(
871 .analysis() 890 world
872 .file_structure(file_id)? 891 .analysis()
873 .into_iter() 892 .file_structure(file_id)?
874 .filter(|it| match it.kind { 893 .into_iter()
875 SyntaxKind::TRAIT_DEF | SyntaxKind::STRUCT_DEF | SyntaxKind::ENUM_DEF => true, 894 .filter(|it| match it.kind {
876 _ => false, 895 SyntaxKind::TRAIT_DEF | SyntaxKind::STRUCT_DEF | SyntaxKind::ENUM_DEF => true,
877 }) 896 _ => false,
878 .map(|it| { 897 })
879 let range = to_proto::range(&line_index, it.node_range); 898 .map(|it| {
880 let pos = range.start; 899 let range = to_proto::range(&line_index, it.node_range);
881 let lens_params = lsp_types::request::GotoImplementationParams { 900 let pos = range.start;
882 text_document_position_params: lsp_types::TextDocumentPositionParams::new( 901 let lens_params = lsp_types::request::GotoImplementationParams {
883 params.text_document.clone(), 902 text_document_position_params: lsp_types::TextDocumentPositionParams::new(
884 pos, 903 params.text_document.clone(),
885 ), 904 pos,
886 work_done_progress_params: Default::default(), 905 ),
887 partial_result_params: Default::default(), 906 work_done_progress_params: Default::default(),
888 }; 907 partial_result_params: Default::default(),
889 CodeLens { 908 };
890 range, 909 CodeLens {
891 command: None, 910 range,
892 data: Some(to_value(CodeLensResolveData::Impls(lens_params)).unwrap()), 911 command: None,
893 } 912 data: Some(to_value(CodeLensResolveData::Impls(lens_params)).unwrap()),
894 }), 913 }
895 ); 914 }),
896 915 );
916 }
897 Ok(Some(lenses)) 917 Ok(Some(lenses))
898} 918}
899 919