diff --git a/code/package.json b/code/package.json index fd3b8e4232..042821b1ca 100644 --- a/code/package.json +++ b/code/package.json @@ -41,6 +41,11 @@ "command": "libsyntax-rust.matchingBrace", "key": "ctrl+shift+m", "title": "Rust Matching Brace" + }, + { + "command": "libsyntax-rust.parentModule", + "key": "ctrl+u", + "title": "Rust Parent Module" } ], "keybindings": [ diff --git a/code/src/extension.ts b/code/src/extension.ts index 084a9d7694..fb6841fa0f 100644 --- a/code/src/extension.ts +++ b/code/src/extension.ts @@ -51,6 +51,22 @@ export function activate(context: vscode.ExtensionContext) { return new vscode.Selection(anchor, active) }) }) + registerCommand('libsyntax-rust.parentModule', async () => { + let editor = vscode.window.activeTextEditor + if (editor == null || editor.document.languageId != "rust") return + let request: lc.TextDocumentIdentifier = { + uri: editor.document.uri.toString() + } + let response = await client.sendRequest("m/parentModule", request) + let loc: lc.Location = response[0] + if (loc == null) return + let uri = client.protocol2CodeConverter.asUri(loc.uri) + let range = client.protocol2CodeConverter.asRange(loc.range) + + let doc = await vscode.workspace.openTextDocument(uri) + let e = await vscode.window.showTextDocument(doc) + e.revealRange(range, vscode.TextEditorRevealType.InCenter) + }) dispose(vscode.workspace.registerTextDocumentContentProvider( 'libsyntax-rust', diff --git a/crates/server/src/main_loop/handlers.rs b/crates/server/src/main_loop/handlers.rs index 675f69bec5..16cc924645 100644 --- a/crates/server/src/main_loop/handlers.rs +++ b/crates/server/src/main_loop/handlers.rs @@ -3,7 +3,7 @@ use std::collections::HashMap; use languageserver_types::{ Diagnostic, DiagnosticSeverity, Url, DocumentSymbol, Command, TextDocumentIdentifier, WorkspaceEdit, - SymbolInformation, Position, + SymbolInformation, Position, Location, }; use libanalysis::{Query}; use libeditor::{self, CursorPosition}; @@ -184,6 +184,23 @@ pub fn handle_goto_definition( Ok(Some(req::GotoDefinitionResponse::Array(res))) } +pub fn handle_parent_module( + world: ServerWorld, + params: TextDocumentIdentifier, +) -> Result> { + let file_id = params.try_conv_with(&world)?; + let mut res = Vec::new(); + for (file_id, symbol) in world.analysis().parent_module(file_id) { + let line_index = world.analysis().file_line_index(file_id)?; + let location = to_location( + file_id, symbol.node_range, + &world, &line_index + )?; + res.push(location); + } + Ok(res) +} + pub fn handle_execute_command( world: ServerWorld, mut params: req::ExecuteCommandParams, diff --git a/crates/server/src/main_loop/mod.rs b/crates/server/src/main_loop/mod.rs index 752d6ddb21..9499b826c2 100644 --- a/crates/server/src/main_loop/mod.rs +++ b/crates/server/src/main_loop/mod.rs @@ -26,6 +26,7 @@ use { handle_workspace_symbol, handle_goto_definition, handle_find_matching_brace, + handle_parent_module, }, }; @@ -141,6 +142,9 @@ fn on_request( handle_request_on_threadpool::( &mut req, pool, world, sender, handle_goto_definition, )?; + handle_request_on_threadpool::( + &mut req, pool, world, sender, handle_parent_module, + )?; dispatch::handle_request::(&mut req, |params, resp| { io.send(RawMsg::Response(resp.into_response(Ok(None))?)); diff --git a/crates/server/src/req.rs b/crates/server/src/req.rs index 73e82150c7..a8aa246295 100644 --- a/crates/server/src/req.rs +++ b/crates/server/src/req.rs @@ -1,5 +1,5 @@ use serde::{ser::Serialize, de::DeserializeOwned}; -use languageserver_types::{TextDocumentIdentifier, Range, Url, Position}; +use languageserver_types::{TextDocumentIdentifier, Range, Url, Position, Location}; use url_serde; pub use languageserver_types::{ @@ -109,3 +109,11 @@ impl Request for MoveCursor { type Result = (); const METHOD: &'static str = "m/moveCursor"; } + +pub enum ParentModule {} + +impl Request for ParentModule { + type Params = TextDocumentIdentifier; + type Result = Vec; + const METHOD: &'static str = "m/parentModule"; +}