From dc217bdf90d555eaa1780041fc3a14e64173994d Mon Sep 17 00:00:00 2001 From: vsrs Date: Sun, 17 May 2020 19:51:44 +0300 Subject: CodeLens configuration options. --- crates/rust-analyzer/src/config.rs | 62 +++++++--- crates/rust-analyzer/src/main_loop/handlers.rs | 164 ++++++++++++++----------- editors/code/package.json | 15 +++ editors/code/src/config.ts | 11 ++ 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 { pub inlay_hints: InlayHintsConfig, pub completion: CompletionConfig, pub call_info_full: bool, + pub lens: LensConfig, +} + +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct LensConfig { + pub run: bool, + pub debug: bool, + pub impementations: bool, +} + +impl Default for LensConfig { + fn default() -> Self { + Self { run: true, debug: true, impementations: true } + } +} + +impl LensConfig { + pub fn any(&self) -> bool { + self.impementations || self.runnable() + } + + pub fn none(&self) -> bool { + !self.any() + } + + pub fn runnable(&self) -> bool { + self.run || self.debug + } } #[derive(Debug, Clone)] @@ -107,6 +135,7 @@ impl Default for Config { ..CompletionConfig::default() }, call_info_full: true, + lens: LensConfig::default(), } } } @@ -195,6 +224,9 @@ impl Config { set(value, "/completion/addCallParenthesis", &mut self.completion.add_call_parenthesis); set(value, "/completion/addCallArgumentSnippets", &mut self.completion.add_call_argument_snippets); set(value, "/callInfo/full", &mut self.call_info_full); + set(value, "/lens/run", &mut self.lens.run); + set(value, "/lens/debug", &mut self.lens.debug); + set(value, "/lens/implementations", &mut self.lens.impementations); log::info!("Config::update() = {:#?}", self); @@ -212,35 +244,35 @@ impl Config { pub fn update_caps(&mut self, caps: &ClientCapabilities) { if let Some(doc_caps) = caps.text_document.as_ref() { if let Some(value) = doc_caps.definition.as_ref().and_then(|it| it.link_support) { - self.client_caps.location_link = value; - } + self.client_caps.location_link = value; + } if let Some(value) = doc_caps.folding_range.as_ref().and_then(|it| it.line_folding_only) { - self.client_caps.line_folding_only = value - } + self.client_caps.line_folding_only = value + } if let Some(value) = doc_caps .document_symbol .as_ref() .and_then(|it| it.hierarchical_document_symbol_support) - { - self.client_caps.hierarchical_symbols = value - } + { + self.client_caps.hierarchical_symbols = value + } if let Some(value) = doc_caps .code_action .as_ref() .and_then(|it| Some(it.code_action_literal_support.is_some())) - { - self.client_caps.code_action_literals = value; - } - self.completion.allow_snippets(false); + { + self.client_caps.code_action_literals = value; + } + self.completion.allow_snippets(false); if let Some(completion) = &doc_caps.completion { - if let Some(completion_item) = &completion.completion_item { - if let Some(value) = completion_item.snippet_support { - self.completion.allow_snippets(value); - } + if let Some(completion_item) = &completion.completion_item { + if let Some(value) = completion_item.snippet_support { + self.completion.allow_snippets(value); } } } + } if let Some(window_caps) = caps.window.as_ref() { 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( params: lsp_types::CodeLensParams, ) -> Result>> { let _p = profile("handle_code_lens"); - let file_id = from_proto::file_id(&world, ¶ms.text_document.uri)?; - let line_index = world.analysis().file_line_index(file_id)?; - let mut lenses: Vec = Default::default(); + if world.config.lens.none() { + // early return before any db query! + return Ok(Some(lenses)); + } + + let file_id = from_proto::file_id(&world, ¶ms.text_document.uri)?; + let line_index = world.analysis().file_line_index(file_id)?; let cargo_spec = CargoTargetSpec::for_file(&world, file_id)?; - // Gather runnables - for runnable in world.analysis().runnables(file_id)? { - let title = match &runnable.kind { - RunnableKind::Test { .. } | RunnableKind::TestMod { .. } => "▶\u{fe0e} Run Test", - RunnableKind::DocTest { .. } => "▶\u{fe0e} Run Doctest", - RunnableKind::Bench { .. } => "Run Bench", - RunnableKind::Bin => { - // Do not suggest binary run on other target than binary - match &cargo_spec { - Some(spec) => match spec.target_kind { - TargetKind::Bin => "Run", - _ => continue, - }, - None => continue, + + if world.config.lens.runnable() { + // Gather runnables + for runnable in world.analysis().runnables(file_id)? { + let (run_title, debugee ) = match &runnable.kind { + RunnableKind::Test { .. } | RunnableKind::TestMod { .. } => ("▶️\u{fe0e}Run Test", true), + RunnableKind::DocTest { .. } => { + // cargo does not support -no-run for doctests + ("▶️\u{fe0e}Run Doctest", false) } + RunnableKind::Bench { .. } => { + // Nothing wrong with bench debugging + ("Run Bench", true) + }, + RunnableKind::Bin => { + // Do not suggest binary run on other target than binary + match &cargo_spec { + Some(spec) => match spec.target_kind { + TargetKind::Bin => ("Run", true), + _ => continue, + }, + None => continue, + } + } + }; + + let mut r = to_lsp_runnable(&world, file_id, runnable)?; + if world.config.lens.run { + let lens = CodeLens { + range: r.range, + command: Some(Command { + title: run_title.to_string(), + command: "rust-analyzer.runSingle".into(), + arguments: Some(vec![to_value(&r).unwrap()]), + }), + data: None, + }; + lenses.push(lens); } - } - .to_string(); - let mut r = to_lsp_runnable(&world, file_id, runnable)?; - let lens = CodeLens { - range: r.range, - command: Some(Command { - title, - command: "rust-analyzer.runSingle".into(), - arguments: Some(vec![to_value(&r).unwrap()]), - }), - data: None, - }; - lenses.push(lens); - if r.args[0] == "run" { - r.args[0] = "build".into(); - } else { - r.args.push("--no-run".into()); + if debugee && world.config.lens.debug { + if r.args[0] == "run" { + r.args[0] = "build".into(); + } else { + r.args.push("--no-run".into()); + } + let debug_lens = CodeLens { + range: r.range, + command: Some(Command { + title: "Debug".into(), + command: "rust-analyzer.debugSingle".into(), + arguments: Some(vec![to_value(r).unwrap()]), + }), + data: None, + }; + lenses.push(debug_lens); + } } - let debug_lens = CodeLens { - range: r.range, - command: Some(Command { - title: "Debug".into(), - command: "rust-analyzer.debugSingle".into(), - arguments: Some(vec![to_value(r).unwrap()]), - }), - data: None, - }; - lenses.push(debug_lens); } - // Handle impls - lenses.extend( - world - .analysis() - .file_structure(file_id)? - .into_iter() - .filter(|it| match it.kind { - SyntaxKind::TRAIT_DEF | SyntaxKind::STRUCT_DEF | SyntaxKind::ENUM_DEF => true, - _ => false, - }) - .map(|it| { - let range = to_proto::range(&line_index, it.node_range); - let pos = range.start; - let lens_params = lsp_types::request::GotoImplementationParams { - text_document_position_params: lsp_types::TextDocumentPositionParams::new( - params.text_document.clone(), - pos, - ), - work_done_progress_params: Default::default(), - partial_result_params: Default::default(), - }; - CodeLens { - range, - command: None, - data: Some(to_value(CodeLensResolveData::Impls(lens_params)).unwrap()), - } - }), - ); - + if world.config.lens.impementations { + // Handle impls + lenses.extend( + world + .analysis() + .file_structure(file_id)? + .into_iter() + .filter(|it| match it.kind { + SyntaxKind::TRAIT_DEF | SyntaxKind::STRUCT_DEF | SyntaxKind::ENUM_DEF => true, + _ => false, + }) + .map(|it| { + let range = to_proto::range(&line_index, it.node_range); + let pos = range.start; + let lens_params = lsp_types::request::GotoImplementationParams { + text_document_position_params: lsp_types::TextDocumentPositionParams::new( + params.text_document.clone(), + pos, + ), + work_done_progress_params: Default::default(), + partial_result_params: Default::default(), + }; + CodeLens { + range, + command: None, + data: Some(to_value(CodeLensResolveData::Impls(lens_params)).unwrap()), + } + }), + ); + } Ok(Some(lenses)) } 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 @@ "type": "object", "default": {}, "description": "Optional settings passed to the debug engine. Example:\n{ \"lldb\": { \"terminal\":\"external\"} }" + }, + "rust-analyzer.lens.run": { + "description": "Whether to show Run lens.", + "type": "boolean", + "default": true + }, + "rust-analyzer.lens.debug": { + "description": "Whether to show Debug lens.", + "type": "boolean", + "default": true + }, + "rust-analyzer.lens.implementations": { + "description": "Whether to show Implementations lens.", + "type": "boolean", + "default": true } } }, 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 { "files", "highlighting", "updates.channel", + "lens.run", + "lens.debug", + "lens.implementations", ] .map(opt => `${this.rootSection}.${opt}`); @@ -119,4 +122,12 @@ export class Config { sourceFileMap: sourceFileMap }; } + + get lens() { + return { + run: this.get("lens.run"), + debug: this.get("lens.debug"), + implementations: this.get("lens.implementations"), + }; + } } -- cgit v1.2.3 From dec2f3fa657a2700f9db1962891e7be71c299543 Mon Sep 17 00:00:00 2001 From: vsrs Date: Sun, 17 May 2020 20:29:59 +0300 Subject: Runnable QuickPick with debuggees only --- editors/code/src/commands/runnables.ts | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/editors/code/src/commands/runnables.ts b/editors/code/src/commands/runnables.ts index b1d93fc34..a408021e7 100644 --- a/editors/code/src/commands/runnables.ts +++ b/editors/code/src/commands/runnables.ts @@ -7,7 +7,7 @@ import { startDebugSession, getDebugConfiguration } from '../debug'; const quickPickButtons = [{ iconPath: new vscode.ThemeIcon("save"), tooltip: "Save as a launch.json configurtation." }]; -async function selectRunnable(ctx: Ctx, prevRunnable?: RunnableQuickPick, showButtons: boolean = true): Promise { +async function selectRunnable(ctx: Ctx, prevRunnable?: RunnableQuickPick, debuggeeOnly = false, showButtons: boolean = true): Promise { const editor = ctx.activeRustEditor; const client = ctx.client; if (!editor || !client) return; @@ -33,9 +33,20 @@ async function selectRunnable(ctx: Ctx, prevRunnable?: RunnableQuickPick, showBu ) { continue; } + + if (debuggeeOnly && (r.label.startsWith('doctest') || r.label.startsWith('cargo'))) { + continue; + } items.push(new RunnableQuickPick(r)); } + if( items.length === 0 ) { + // it is the debug case, run always has at least 'cargo check ...' + // see crates\rust-analyzer\src\main_loop\handlers.rs, handle_runnables + vscode.window.showErrorMessage("There's no debug target!"); + return; + } + return await new Promise((resolve) => { const disposables: vscode.Disposable[] = []; const close = (result?: RunnableQuickPick) => { @@ -107,7 +118,7 @@ export function debug(ctx: Ctx): Cmd { let prevDebuggee: RunnableQuickPick | undefined; return async () => { - const item = await selectRunnable(ctx, prevDebuggee); + const item = await selectRunnable(ctx, prevDebuggee, true); if (!item) return; item.detail = 'restart'; @@ -147,7 +158,7 @@ async function makeDebugConfig(ctx: Ctx, item: RunnableQuickPick): Promise export function newDebugConfig(ctx: Ctx): Cmd { return async () => { - const item = await selectRunnable(ctx, undefined, false); + const item = await selectRunnable(ctx, undefined, true, false); if (!item) return; await makeDebugConfig(ctx, item); -- cgit v1.2.3 From 3d445256fe56f4a7ead64514fb57b79079973d84 Mon Sep 17 00:00:00 2001 From: vsrs Date: Sun, 17 May 2020 20:38:50 +0300 Subject: code formatting --- crates/rust-analyzer/src/config.rs | 30 +++++++++++++------------- crates/rust-analyzer/src/main_loop/handlers.rs | 10 +++++---- editors/code/src/commands/runnables.ts | 2 +- 3 files changed, 22 insertions(+), 20 deletions(-) diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs index b99b95bfc..2038ef89b 100644 --- a/crates/rust-analyzer/src/config.rs +++ b/crates/rust-analyzer/src/config.rs @@ -244,35 +244,35 @@ impl Config { pub fn update_caps(&mut self, caps: &ClientCapabilities) { if let Some(doc_caps) = caps.text_document.as_ref() { if let Some(value) = doc_caps.definition.as_ref().and_then(|it| it.link_support) { - self.client_caps.location_link = value; - } + self.client_caps.location_link = value; + } if let Some(value) = doc_caps.folding_range.as_ref().and_then(|it| it.line_folding_only) { - self.client_caps.line_folding_only = value - } + self.client_caps.line_folding_only = value + } if let Some(value) = doc_caps .document_symbol .as_ref() .and_then(|it| it.hierarchical_document_symbol_support) - { - self.client_caps.hierarchical_symbols = value - } + { + self.client_caps.hierarchical_symbols = value + } if let Some(value) = doc_caps .code_action .as_ref() .and_then(|it| Some(it.code_action_literal_support.is_some())) - { - self.client_caps.code_action_literals = value; - } - self.completion.allow_snippets(false); + { + self.client_caps.code_action_literals = value; + } + self.completion.allow_snippets(false); if let Some(completion) = &doc_caps.completion { - if let Some(completion_item) = &completion.completion_item { - if let Some(value) = completion_item.snippet_support { - self.completion.allow_snippets(value); + if let Some(completion_item) = &completion.completion_item { + if let Some(value) = completion_item.snippet_support { + self.completion.allow_snippets(value); + } } } } - } if let Some(window_caps) = caps.window.as_ref() { 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 808532d23..e67556752 100644 --- a/crates/rust-analyzer/src/main_loop/handlers.rs +++ b/crates/rust-analyzer/src/main_loop/handlers.rs @@ -826,16 +826,18 @@ pub fn handle_code_lens( if world.config.lens.runnable() { // Gather runnables for runnable in world.analysis().runnables(file_id)? { - let (run_title, debugee ) = match &runnable.kind { - RunnableKind::Test { .. } | RunnableKind::TestMod { .. } => ("▶️\u{fe0e}Run Test", true), - RunnableKind::DocTest { .. } => { + let (run_title, debugee) = match &runnable.kind { + RunnableKind::Test { .. } | RunnableKind::TestMod { .. } => { + ("▶️\u{fe0e}Run Test", true) + } + RunnableKind::DocTest { .. } => { // cargo does not support -no-run for doctests ("▶️\u{fe0e}Run Doctest", false) } RunnableKind::Bench { .. } => { // Nothing wrong with bench debugging ("Run Bench", true) - }, + } RunnableKind::Bin => { // Do not suggest binary run on other target than binary match &cargo_spec { diff --git a/editors/code/src/commands/runnables.ts b/editors/code/src/commands/runnables.ts index a408021e7..0bd30fb07 100644 --- a/editors/code/src/commands/runnables.ts +++ b/editors/code/src/commands/runnables.ts @@ -40,7 +40,7 @@ async function selectRunnable(ctx: Ctx, prevRunnable?: RunnableQuickPick, debugg items.push(new RunnableQuickPick(r)); } - if( items.length === 0 ) { + if (items.length === 0) { // it is the debug case, run always has at least 'cargo check ...' // see crates\rust-analyzer\src\main_loop\handlers.rs, handle_runnables vscode.window.showErrorMessage("There's no debug target!"); -- cgit v1.2.3 From 78817a319476d8af40c4f78e8c47dc958781f88f Mon Sep 17 00:00:00 2001 From: vsrs Date: Mon, 18 May 2020 10:27:00 +0300 Subject: Add "rust-analyzer.lens.enable" --- crates/rust-analyzer/src/config.rs | 15 ++++++++++++--- editors/code/package.json | 11 ++++++++--- editors/code/src/config.ts | 2 ++ 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs index 2038ef89b..b5dc6f0fa 100644 --- a/crates/rust-analyzer/src/config.rs +++ b/crates/rust-analyzer/src/config.rs @@ -50,6 +50,8 @@ impl Default for LensConfig { } impl LensConfig { + pub const NO_LENS: LensConfig = Self { run: false, debug: false, impementations: false }; + pub fn any(&self) -> bool { self.impementations || self.runnable() } @@ -224,9 +226,16 @@ impl Config { set(value, "/completion/addCallParenthesis", &mut self.completion.add_call_parenthesis); set(value, "/completion/addCallArgumentSnippets", &mut self.completion.add_call_argument_snippets); set(value, "/callInfo/full", &mut self.call_info_full); - set(value, "/lens/run", &mut self.lens.run); - set(value, "/lens/debug", &mut self.lens.debug); - set(value, "/lens/implementations", &mut self.lens.impementations); + + let mut lens_enabled = true; + set(value, "/lens/enable", &mut lens_enabled); + if lens_enabled { + set(value, "/lens/run", &mut self.lens.run); + set(value, "/lens/debug", &mut self.lens.debug); + set(value, "/lens/implementations", &mut self.lens.impementations); + } else { + self.lens = LensConfig::NO_LENS; + } log::info!("Config::update() = {:#?}", self); diff --git a/editors/code/package.json b/editors/code/package.json index efed4c7f2..38c77533c 100644 --- a/editors/code/package.json +++ b/editors/code/package.json @@ -444,18 +444,23 @@ "default": {}, "description": "Optional settings passed to the debug engine. Example:\n{ \"lldb\": { \"terminal\":\"external\"} }" }, + "rust-analyzer.lens.enable": { + "description": "Whether to show CodeLens in Rust files.", + "type": "boolean", + "default": true + }, "rust-analyzer.lens.run": { - "description": "Whether to show Run lens.", + "markdownDescription": "Whether to show Run lens. Only applies when `#rust-analyzer.lens.enable#` is set.", "type": "boolean", "default": true }, "rust-analyzer.lens.debug": { - "description": "Whether to show Debug lens.", + "markdownDescription": "Whether to show Debug lens. Only applies when `#rust-analyzer.lens.enable#` is set.", "type": "boolean", "default": true }, "rust-analyzer.lens.implementations": { - "description": "Whether to show Implementations lens.", + "markdownDescription": "Whether to show Implementations lens. Only applies when `#rust-analyzer.lens.enable#` is set.", "type": "boolean", "default": true } diff --git a/editors/code/src/config.ts b/editors/code/src/config.ts index 93d9aa160..ee294fbe3 100644 --- a/editors/code/src/config.ts +++ b/editors/code/src/config.ts @@ -16,6 +16,7 @@ export class Config { "files", "highlighting", "updates.channel", + "lens.enable", "lens.run", "lens.debug", "lens.implementations", @@ -125,6 +126,7 @@ export class Config { get lens() { return { + enable: this.get("lens.enable"), run: this.get("lens.run"), debug: this.get("lens.debug"), implementations: this.get("lens.implementations"), -- cgit v1.2.3