aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvsrs <[email protected]>2020-05-17 17:51:44 +0100
committervsrs <[email protected]>2020-05-17 17:51:44 +0100
commitdc217bdf90d555eaa1780041fc3a14e64173994d (patch)
tree547807df99ad67f5be229ccb600610a376189723
parent71e94b1d0bf7c58aa377513f010fcb3f56081f5f (diff)
CodeLens configuration options.
-rw-r--r--crates/rust-analyzer/src/config.rs62
-rw-r--r--crates/rust-analyzer/src/main_loop/handlers.rs164
-rw-r--r--editors/code/package.json15
-rw-r--r--editors/code/src/config.ts11
4 files changed, 164 insertions, 88 deletions
diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs
index 53aee833d..b99b95bfc 100644
--- a/crates/rust-analyzer/src/config.rs
+++ b/crates/rust-analyzer/src/config.rs
@@ -33,6 +33,34 @@ 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 fn any(&self) -> bool {
54 self.impementations || self.runnable()
55 }
56
57 pub fn none(&self) -> bool {
58 !self.any()
59 }
60
61 pub fn runnable(&self) -> bool {
62 self.run || self.debug
63 }
36} 64}
37 65
38#[derive(Debug, Clone)] 66#[derive(Debug, Clone)]
@@ -107,6 +135,7 @@ impl Default for Config {
107 ..CompletionConfig::default() 135 ..CompletionConfig::default()
108 }, 136 },
109 call_info_full: true, 137 call_info_full: true,
138 lens: LensConfig::default(),
110 } 139 }
111 } 140 }
112} 141}
@@ -195,6 +224,9 @@ impl Config {
195 set(value, "/completion/addCallParenthesis", &mut self.completion.add_call_parenthesis); 224 set(value, "/completion/addCallParenthesis", &mut self.completion.add_call_parenthesis);
196 set(value, "/completion/addCallArgumentSnippets", &mut self.completion.add_call_argument_snippets); 225 set(value, "/completion/addCallArgumentSnippets", &mut self.completion.add_call_argument_snippets);
197 set(value, "/callInfo/full", &mut self.call_info_full); 226 set(value, "/callInfo/full", &mut self.call_info_full);
227 set(value, "/lens/run", &mut self.lens.run);
228 set(value, "/lens/debug", &mut self.lens.debug);
229 set(value, "/lens/implementations", &mut self.lens.impementations);
198 230
199 log::info!("Config::update() = {:#?}", self); 231 log::info!("Config::update() = {:#?}", self);
200 232
@@ -212,35 +244,35 @@ impl Config {
212 pub fn update_caps(&mut self, caps: &ClientCapabilities) { 244 pub fn update_caps(&mut self, caps: &ClientCapabilities) {
213 if let Some(doc_caps) = caps.text_document.as_ref() { 245 if let Some(doc_caps) = caps.text_document.as_ref() {
214 if let Some(value) = doc_caps.definition.as_ref().and_then(|it| it.link_support) { 246 if let Some(value) = doc_caps.definition.as_ref().and_then(|it| it.link_support) {
215 self.client_caps.location_link = value; 247 self.client_caps.location_link = value;
216 } 248 }
217 if let Some(value) = doc_caps.folding_range.as_ref().and_then(|it| it.line_folding_only) 249 if let Some(value) = doc_caps.folding_range.as_ref().and_then(|it| it.line_folding_only)
218 { 250 {
219 self.client_caps.line_folding_only = value 251 self.client_caps.line_folding_only = value
220 } 252 }
221 if let Some(value) = doc_caps 253 if let Some(value) = doc_caps
222 .document_symbol 254 .document_symbol
223 .as_ref() 255 .as_ref()
224 .and_then(|it| it.hierarchical_document_symbol_support) 256 .and_then(|it| it.hierarchical_document_symbol_support)
225 { 257 {
226 self.client_caps.hierarchical_symbols = value 258 self.client_caps.hierarchical_symbols = value
227 } 259 }
228 if let Some(value) = doc_caps 260 if let Some(value) = doc_caps
229 .code_action 261 .code_action
230 .as_ref() 262 .as_ref()
231 .and_then(|it| Some(it.code_action_literal_support.is_some())) 263 .and_then(|it| Some(it.code_action_literal_support.is_some()))
232 { 264 {
233 self.client_caps.code_action_literals = value; 265 self.client_caps.code_action_literals = value;
234 } 266 }
235 self.completion.allow_snippets(false); 267 self.completion.allow_snippets(false);
236 if let Some(completion) = &doc_caps.completion { 268 if let Some(completion) = &doc_caps.completion {
237 if let Some(completion_item) = &completion.completion_item { 269 if let Some(completion_item) = &completion.completion_item {
238 if let Some(value) = completion_item.snippet_support { 270 if let Some(value) = completion_item.snippet_support {
239 self.completion.allow_snippets(value); 271 self.completion.allow_snippets(value);
240 }
241 } 272 }
242 } 273 }
243 } 274 }
275 }
244 276
245 if let Some(window_caps) = caps.window.as_ref() { 277 if let Some(window_caps) = caps.window.as_ref() {
246 if let Some(value) = window_caps.work_done_progress { 278 if let Some(value) = window_caps.work_done_progress {
diff --git a/crates/rust-analyzer/src/main_loop/handlers.rs b/crates/rust-analyzer/src/main_loop/handlers.rs
index 6b14830b6..808532d23 100644
--- a/crates/rust-analyzer/src/main_loop/handlers.rs
+++ b/crates/rust-analyzer/src/main_loop/handlers.rs
@@ -812,88 +812,106 @@ 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 { .. } => ("▶️\u{fe0e}Run Test", true),
827 RunnableKind::Bin => { 831 RunnableKind::DocTest { .. } => {
828 // Do not suggest binary run on other target than binary 832 // cargo does not support -no-run for doctests
829 match &cargo_spec { 833 ("▶️\u{fe0e}Run Doctest", false)
830 Some(spec) => match spec.target_kind {
831 TargetKind::Bin => "Run",
832 _ => continue,
833 },
834 None => continue,
835 } 834 }
835 RunnableKind::Bench { .. } => {
836 // Nothing wrong with bench debugging
837 ("Run Bench", true)
838 },
839 RunnableKind::Bin => {
840 // Do not suggest binary run on other target than binary
841 match &cargo_spec {
842 Some(spec) => match spec.target_kind {
843 TargetKind::Bin => ("Run", true),
844 _ => continue,
845 },
846 None => continue,
847 }
848 }
849 };
850
851 let mut r = to_lsp_runnable(&world, file_id, runnable)?;
852 if world.config.lens.run {
853 let lens = CodeLens {
854 range: r.range,
855 command: Some(Command {
856 title: run_title.to_string(),
857 command: "rust-analyzer.runSingle".into(),
858 arguments: Some(vec![to_value(&r).unwrap()]),
859 }),
860 data: None,
861 };
862 lenses.push(lens);
836 } 863 }
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 864
851 if r.args[0] == "run" { 865 if debugee && world.config.lens.debug {
852 r.args[0] = "build".into(); 866 if r.args[0] == "run" {
853 } else { 867 r.args[0] = "build".into();
854 r.args.push("--no-run".into()); 868 } else {
869 r.args.push("--no-run".into());
870 }
871 let debug_lens = CodeLens {
872 range: r.range,
873 command: Some(Command {
874 title: "Debug".into(),
875 command: "rust-analyzer.debugSingle".into(),
876 arguments: Some(vec![to_value(r).unwrap()]),
877 }),
878 data: None,
879 };
880 lenses.push(debug_lens);
881 }
855 } 882 }
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 } 883 }
867 884
868 // Handle impls 885 if world.config.lens.impementations {
869 lenses.extend( 886 // Handle impls
870 world 887 lenses.extend(
871 .analysis() 888 world
872 .file_structure(file_id)? 889 .analysis()
873 .into_iter() 890 .file_structure(file_id)?
874 .filter(|it| match it.kind { 891 .into_iter()
875 SyntaxKind::TRAIT_DEF | SyntaxKind::STRUCT_DEF | SyntaxKind::ENUM_DEF => true, 892 .filter(|it| match it.kind {
876 _ => false, 893 SyntaxKind::TRAIT_DEF | SyntaxKind::STRUCT_DEF | SyntaxKind::ENUM_DEF => true,
877 }) 894 _ => false,
878 .map(|it| { 895 })
879 let range = to_proto::range(&line_index, it.node_range); 896 .map(|it| {
880 let pos = range.start; 897 let range = to_proto::range(&line_index, it.node_range);
881 let lens_params = lsp_types::request::GotoImplementationParams { 898 let pos = range.start;
882 text_document_position_params: lsp_types::TextDocumentPositionParams::new( 899 let lens_params = lsp_types::request::GotoImplementationParams {
883 params.text_document.clone(), 900 text_document_position_params: lsp_types::TextDocumentPositionParams::new(
884 pos, 901 params.text_document.clone(),
885 ), 902 pos,
886 work_done_progress_params: Default::default(), 903 ),
887 partial_result_params: Default::default(), 904 work_done_progress_params: Default::default(),
888 }; 905 partial_result_params: Default::default(),
889 CodeLens { 906 };
890 range, 907 CodeLens {
891 command: None, 908 range,
892 data: Some(to_value(CodeLensResolveData::Impls(lens_params)).unwrap()), 909 command: None,
893 } 910 data: Some(to_value(CodeLensResolveData::Impls(lens_params)).unwrap()),
894 }), 911 }
895 ); 912 }),
896 913 );
914 }
897 Ok(Some(lenses)) 915 Ok(Some(lenses))
898} 916}
899 917
diff --git a/editors/code/package.json b/editors/code/package.json
index 2dbbde852..efed4c7f2 100644
--- a/editors/code/package.json
+++ b/editors/code/package.json
@@ -443,6 +443,21 @@
443 "type": "object", 443 "type": "object",
444 "default": {}, 444 "default": {},
445 "description": "Optional settings passed to the debug engine. Example:\n{ \"lldb\": { \"terminal\":\"external\"} }" 445 "description": "Optional settings passed to the debug engine. Example:\n{ \"lldb\": { \"terminal\":\"external\"} }"
446 },
447 "rust-analyzer.lens.run": {
448 "description": "Whether to show Run lens.",
449 "type": "boolean",
450 "default": true
451 },
452 "rust-analyzer.lens.debug": {
453 "description": "Whether to show Debug lens.",
454 "type": "boolean",
455 "default": true
456 },
457 "rust-analyzer.lens.implementations": {
458 "description": "Whether to show Implementations lens.",
459 "type": "boolean",
460 "default": true
446 } 461 }
447 } 462 }
448 }, 463 },
diff --git a/editors/code/src/config.ts b/editors/code/src/config.ts
index 1652827c3..93d9aa160 100644
--- a/editors/code/src/config.ts
+++ b/editors/code/src/config.ts
@@ -16,6 +16,9 @@ export class Config {
16 "files", 16 "files",
17 "highlighting", 17 "highlighting",
18 "updates.channel", 18 "updates.channel",
19 "lens.run",
20 "lens.debug",
21 "lens.implementations",
19 ] 22 ]
20 .map(opt => `${this.rootSection}.${opt}`); 23 .map(opt => `${this.rootSection}.${opt}`);
21 24
@@ -119,4 +122,12 @@ export class Config {
119 sourceFileMap: sourceFileMap 122 sourceFileMap: sourceFileMap
120 }; 123 };
121 } 124 }
125
126 get lens() {
127 return {
128 run: this.get<boolean>("lens.run"),
129 debug: this.get<boolean>("lens.debug"),
130 implementations: this.get<boolean>("lens.implementations"),
131 };
132 }
122} 133}