diff --git a/Cargo.lock b/Cargo.lock index 81dd812f46..723c1ac5f7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -270,7 +270,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.31 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.32 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -343,7 +343,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.31 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.32 (registry+https://github.com/rust-lang/crates.io-index)", "synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -430,7 +430,7 @@ dependencies = [ "crossbeam-channel 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "lsp-types 0.56.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lsp-types 0.57.0 (git+https://github.com/matklad/lsp-types?branch=selection-range)", "serde 1.0.90 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -634,8 +634,8 @@ dependencies = [ [[package]] name = "lsp-types" -version = "0.56.0" -source = "registry+https://github.com/rust-lang/crates.io-index" +version = "0.57.0" +source = "git+https://github.com/matklad/lsp-types?branch=selection-range#6e37d45bcf411c18c22ab29ec155946ff001339e" dependencies = [ "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "num-derive 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -747,7 +747,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.31 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.32 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -844,7 +844,7 @@ dependencies = [ "pest_meta 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.31 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.32 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1027,7 +1027,7 @@ dependencies = [ "flexi_logger 0.11.4 (registry+https://github.com/rust-lang/crates.io-index)", "gen_lsp_server 0.1.0", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "lsp-types 0.56.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lsp-types 0.57.0 (git+https://github.com/matklad/lsp-types?branch=selection-range)", "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "ra_arena 0.1.0", "ra_ide_api 0.1.0", @@ -1378,7 +1378,7 @@ dependencies = [ "heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.31 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.32 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1423,7 +1423,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.31 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.32 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1501,7 +1501,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "syn" -version = "0.15.31" +version = "0.15.32" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1516,7 +1516,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.31 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.32 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1937,7 +1937,7 @@ dependencies = [ "checksum linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ae91b68aebc4ddb91978b11a1b02ddd8602a05ec19002801c5666000e05e0f83" "checksum lock_api 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "62ebf1391f6acad60e5c8b43706dde4582df75c06698ab44511d15016bc2442c" "checksum log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c84ec4b527950aa83a329754b01dbe3f58361d1c5efacd1f6d68c494d08a17c6" -"checksum lsp-types 0.56.0 (registry+https://github.com/rust-lang/crates.io-index)" = "31954f2cf354421e6f99a48fdcfd5c3113c675a0db311960ffdac0b8d45cf09c" +"checksum lsp-types 0.57.0 (git+https://github.com/matklad/lsp-types?branch=selection-range)" = "" "checksum maplit 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "08cbb6b4fef96b6d77bfc40ec491b1690c779e77b05cd9f07f787ed376fd4c43" "checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" "checksum memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2efc7bc57c883d4a4d6e3246905283d8dae951bb3bd32f49d6ef297f546e1c39" @@ -2010,7 +2010,7 @@ dependencies = [ "checksum stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8" "checksum strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" "checksum superslice 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ab16ced94dbd8a46c82fd81e3ed9a8727dac2977ea869d217bcc4ea1f122e81f" -"checksum syn 0.15.31 (registry+https://github.com/rust-lang/crates.io-index)" = "d2b4cfac95805274c6afdb12d8f770fa2d27c045953e7b630a81801953699a9a" +"checksum syn 0.15.32 (registry+https://github.com/rust-lang/crates.io-index)" = "846620ec526c1599c070eff393bfeeeb88a93afa2513fc3b49f1fea84cf7b0ed" "checksum synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "73687139bf99285483c96ac0add482c3776528beac1d97d444f6e91f203a2015" "checksum tempfile 3.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "b86c784c88d98c801132806dadd3819ed29d8600836c4088e855cdf3e178ed8a" "checksum tera 0.11.20 (registry+https://github.com/rust-lang/crates.io-index)" = "4b505279e19d8f7d24b1a9dc58327c9c36174b1a2c7ebdeac70792d017cb64f3" diff --git a/Cargo.toml b/Cargo.toml index c5155e8996..0e474a184f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,3 +6,4 @@ incremental = true debug = true [patch.'crates-io'] +lsp-types = { git = "https://github.com/matklad/lsp-types", branch = "selection-range" } diff --git a/crates/gen_lsp_server/Cargo.toml b/crates/gen_lsp_server/Cargo.toml index 9e0d819d03..34343e2f25 100644 --- a/crates/gen_lsp_server/Cargo.toml +++ b/crates/gen_lsp_server/Cargo.toml @@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0" description = "Generic LSP server scaffold." [dependencies] -lsp-types = "0.56.0" +lsp-types = "0.57.0" log = "0.4.3" failure = "0.1.4" serde_json = "1.0.34" diff --git a/crates/ra_lsp_server/Cargo.toml b/crates/ra_lsp_server/Cargo.toml index bc181e4eb6..c855d6f680 100644 --- a/crates/ra_lsp_server/Cargo.toml +++ b/crates/ra_lsp_server/Cargo.toml @@ -15,7 +15,7 @@ crossbeam-channel = "0.3.5" flexi_logger = "0.11.0" log = "0.4.3" url_serde = "0.2.0" -lsp-types = "0.56.0" +lsp-types = "0.57.0" rustc-hash = "1.0" parking_lot = "0.7.0" diff --git a/crates/ra_lsp_server/src/caps.rs b/crates/ra_lsp_server/src/caps.rs index 2af2b89fec..f6d2b75e76 100644 --- a/crates/ra_lsp_server/src/caps.rs +++ b/crates/ra_lsp_server/src/caps.rs @@ -2,7 +2,7 @@ use lsp_types::{ CodeActionProviderCapability, CodeLensOptions, CompletionOptions, DocumentOnTypeFormattingOptions, ExecuteCommandOptions, FoldingRangeProviderCapability, RenameOptions, RenameProviderCapability, ServerCapabilities, SignatureHelpOptions, TextDocumentSyncCapability, TextDocumentSyncKind, - TextDocumentSyncOptions, ImplementationProviderCapability, + TextDocumentSyncOptions, ImplementationProviderCapability, GenericCapability, }; pub fn server_capabilities() -> ServerCapabilities { @@ -37,6 +37,7 @@ pub fn server_capabilities() -> ServerCapabilities { first_trigger_character: "=".to_string(), more_trigger_character: Some(vec![".".to_string()]), }), + selection_range_provider: Some(GenericCapability::default()), folding_range_provider: Some(FoldingRangeProviderCapability::Simple(true)), rename_provider: Some(RenameProviderCapability::Options(RenameOptions { prepare_provider: Some(true), diff --git a/crates/ra_lsp_server/src/main_loop.rs b/crates/ra_lsp_server/src/main_loop.rs index 07ac4917a2..dc1f8f3f7a 100644 --- a/crates/ra_lsp_server/src/main_loop.rs +++ b/crates/ra_lsp_server/src/main_loop.rs @@ -297,6 +297,7 @@ fn on_request( .on::(handlers::handle_analyzer_status)? .on::(handlers::handle_syntax_tree)? .on::(handlers::handle_extend_selection)? + .on::(handlers::handle_selection_range)? .on::(handlers::handle_find_matching_brace)? .on::(handlers::handle_join_lines)? .on::(handlers::handle_on_enter)? diff --git a/crates/ra_lsp_server/src/main_loop/handlers.rs b/crates/ra_lsp_server/src/main_loop/handlers.rs index eb8a535455..530081494c 100644 --- a/crates/ra_lsp_server/src/main_loop/handlers.rs +++ b/crates/ra_lsp_server/src/main_loop/handlers.rs @@ -11,7 +11,7 @@ use ra_ide_api::{ FileId, FilePosition, FileRange, FoldKind, Query, RangeInfo, RunnableKind, Severity, Cancelable, AssistId, }; -use ra_syntax::{AstNode, SyntaxKind, TextUnit}; +use ra_syntax::{AstNode, SyntaxKind, TextUnit, TextRange}; use ra_prof::profile; use rustc_hash::FxHashMap; use serde::{Serialize, Deserialize}; @@ -39,10 +39,15 @@ pub fn handle_syntax_tree(world: ServerWorld, params: req::SyntaxTreeParams) -> Ok(res) } +// FIXME: drop this API pub fn handle_extend_selection( world: ServerWorld, params: req::ExtendSelectionParams, ) -> Result { + log::error!( + "extend selection is deprecated and will be removed soon, + use the new selection range API in LSP", + ); let file_id = params.text_document.try_conv_with(&world)?; let line_index = world.analysis().file_line_index(file_id); let selections = params @@ -55,6 +60,46 @@ pub fn handle_extend_selection( Ok(req::ExtendSelectionResult { selections }) } +pub fn handle_selection_range( + world: ServerWorld, + params: req::SelectionRangeParams, +) -> Result> { + let file_id = params.text_document.try_conv_with(&world)?; + let line_index = world.analysis().file_line_index(file_id); + params + .positions + .into_iter() + .map_conv_with(&line_index) + .map(|position| { + let mut ranges = Vec::new(); + { + let mut range = TextRange::from_to(position, position); + loop { + ranges.push(range); + let frange = FileRange { file_id, range }; + let next = world.analysis().extend_selection(frange)?; + if next == range { + break; + } else { + range = next + } + } + } + let mut range = req::SelectionRange { + range: ranges.last().unwrap().conv_with(&line_index), + parent: None, + }; + for r in ranges.iter().rev().skip(1) { + range = req::SelectionRange { + range: r.conv_with(&line_index), + parent: Some(Box::new(range)), + } + } + Ok(range) + }) + .collect() +} + pub fn handle_find_matching_brace( world: ServerWorld, params: req::FindMatchingBraceParams, diff --git a/crates/ra_lsp_server/src/req.rs b/crates/ra_lsp_server/src/req.rs index 4f35ab9b5a..6090eb7b92 100644 --- a/crates/ra_lsp_server/src/req.rs +++ b/crates/ra_lsp_server/src/req.rs @@ -64,6 +64,28 @@ pub struct ExtendSelectionResult { pub selections: Vec, } +pub enum SelectionRangeRequest {} + +impl Request for SelectionRangeRequest { + type Params = SelectionRangeParams; + type Result = Vec; + const METHOD: &'static str = "textDocument/selectionRange"; +} + +#[derive(Deserialize, Debug)] +#[serde(rename_all = "camelCase")] +pub struct SelectionRangeParams { + pub text_document: TextDocumentIdentifier, + pub positions: Vec, +} + +#[derive(Serialize, Debug)] +#[serde(rename_all = "camelCase")] +pub struct SelectionRange { + pub range: Range, + pub parent: Option>, +} + pub enum FindMatchingBrace {} impl Request for FindMatchingBrace { diff --git a/editors/code/package.json b/editors/code/package.json index 8f195c9962..015b912b3c 100644 --- a/editors/code/package.json +++ b/editors/code/package.json @@ -80,11 +80,6 @@ "title": "Show Syntax Tree", "category": "Rust Analyzer" }, - { - "command": "rust-analyzer.extendSelection", - "title": "Extend selection", - "category": "Rust Analyzer" - }, { "command": "rust-analyzer.matchingBrace", "title": "Find matching brace", diff --git a/editors/code/src/commands/extend_selection.ts b/editors/code/src/commands/extend_selection.ts deleted file mode 100644 index 6f4187d15c..0000000000 --- a/editors/code/src/commands/extend_selection.ts +++ /dev/null @@ -1,34 +0,0 @@ -import * as vscode from 'vscode'; - -import { Range, TextDocumentIdentifier } from 'vscode-languageclient'; -import { Server } from '../server'; - -interface ExtendSelectionParams { - textDocument: TextDocumentIdentifier; - selections: Range[]; -} - -interface ExtendSelectionResult { - selections: Range[]; -} - -export async function handle() { - const editor = vscode.window.activeTextEditor; - if (editor == null || editor.document.languageId !== 'rust') { - return; - } - const request: ExtendSelectionParams = { - selections: editor.selections.map(s => - Server.client.code2ProtocolConverter.asRange(s) - ), - textDocument: { uri: editor.document.uri.toString() } - }; - const response = await Server.client.sendRequest( - 'rust-analyzer/extendSelection', - request - ); - editor.selections = response.selections.map((range: Range) => { - const r = Server.client.protocol2CodeConverter.asRange(range); - return new vscode.Selection(r.start, r.end); - }); -} diff --git a/editors/code/src/commands/index.ts b/editors/code/src/commands/index.ts index f36c4b040f..1946584976 100644 --- a/editors/code/src/commands/index.ts +++ b/editors/code/src/commands/index.ts @@ -1,6 +1,5 @@ import * as analyzerStatus from './analyzer_status'; import * as applySourceChange from './apply_source_change'; -import * as extendSelection from './extend_selection'; import * as joinLines from './join_lines'; import * as matchingBrace from './matching_brace'; import * as onEnter from './on_enter'; @@ -11,7 +10,6 @@ import * as syntaxTree from './syntaxTree'; export { analyzerStatus, applySourceChange, - extendSelection, joinLines, matchingBrace, parentModule, diff --git a/editors/code/src/extension.ts b/editors/code/src/extension.ts index 48dd2a6146..c8c3004a7f 100644 --- a/editors/code/src/extension.ts +++ b/editors/code/src/extension.ts @@ -57,10 +57,6 @@ export function activate(context: vscode.ExtensionContext) { registerCommand('rust-analyzer.collectGarbage', () => Server.client.sendRequest('rust-analyzer/collectGarbage', null) ); - registerCommand( - 'rust-analyzer.extendSelection', - commands.extendSelection.handle - ); registerCommand( 'rust-analyzer.matchingBrace', commands.matchingBrace.handle diff --git a/editors/code/src/server.ts b/editors/code/src/server.ts index 5e9a193403..81c2b3fff2 100644 --- a/editors/code/src/server.ts +++ b/editors/code/src/server.ts @@ -74,6 +74,7 @@ export class Server { } } }; + Server.client.registerProposedFeatures(); Server.client.onReady().then(() => { for (const [type, handler] of notificationHandlers) { Server.client.onNotification(type, handler);