diff --git a/code/.vscode/launch.json b/code/.vscode/launch.json index 64f2c369384..5e615ad4c33 100644 --- a/code/.vscode/launch.json +++ b/code/.vscode/launch.json @@ -9,10 +9,10 @@ "type": "extensionHost", "request": "launch", "runtimeExecutable": "${execPath}", - "args": ["--extensionDevelopmentPath=${workspaceRoot}"], + "args": ["--extensionDevelopmentPath='./'"], "stopOnEntry": false, "sourceMaps": true, - "outFiles": [ "${workspaceRoot}/out/src/**/*.js" ], + "outFiles": [ "./out/src/**/*.js" ], "preLaunchTask": "npm" }, ] diff --git a/code/src/extension.ts b/code/src/extension.ts index afcbccf63c2..95305db2de9 100644 --- a/code/src/extension.ts +++ b/code/src/extension.ts @@ -111,6 +111,16 @@ function startServer() { ) } ) + client.onRequest( + new lc.RequestType("m/moveCursor"), + (params: lc.Position, token: lc.CancellationToken) => { + let editor = vscode.window.activeTextEditor; + if (editor == null) return + if (!editor.selection.isEmpty) return + let position = client.protocol2CodeConverter.asPosition(params) + editor.selection = new vscode.Selection(position, position); + } + ) }) client.start(); } diff --git a/crates/server/src/main_loop/handlers.rs b/crates/server/src/main_loop/handlers.rs index d7b78b4fa99..f25c64c977f 100644 --- a/crates/server/src/main_loop/handlers.rs +++ b/crates/server/src/main_loop/handlers.rs @@ -6,7 +6,7 @@ SymbolInformation, Position, }; use libanalysis::{World, Query}; -use libeditor; +use libeditor::{self, CursorPosition}; use libsyntax2::TextUnit; use serde_json::{to_value, from_value}; @@ -195,7 +195,7 @@ pub fn handle_execute_command( world: World, path_map: PathMap, mut params: req::ExecuteCommandParams, -) -> Result { +) -> Result<(req::ApplyWorkspaceEditParams, Option)> { if params.command.as_str() != "apply_code_action" { bail!("unknown cmd: {:?}", params.command); } @@ -209,23 +209,24 @@ pub fn handle_execute_command( let action_result = match arg.id { ActionId::FlipComma => libeditor::flip_comma(&file, arg.offset).map(|f| f()), ActionId::AddDerive => libeditor::add_derive(&file, arg.offset).map(|f| f()), - }; - let edit = match action_result { - Some(action_result) => action_result.edit, - None => bail!("command not applicable"), - }; + }.ok_or_else(|| format_err!("command not applicable"))?; let line_index = world.file_line_index(file_id)?; let mut changes = HashMap::new(); changes.insert( arg.text_document.uri, - edit.conv_with(&line_index), + action_result.edit.conv_with(&line_index), ); let edit = WorkspaceEdit { changes: Some(changes), document_changes: None, }; + let edit = req::ApplyWorkspaceEditParams { edit }; + let cursor_pos = match action_result.cursor_position { + CursorPosition::Same => None, + CursorPosition::Offset(offset) => Some(offset.conv_with(&line_index)), + }; - Ok(req::ApplyWorkspaceEditParams { edit }) + Ok((edit, cursor_pos)) } #[derive(Serialize, Deserialize)] diff --git a/crates/server/src/main_loop/mod.rs b/crates/server/src/main_loop/mod.rs index 4d5dfb437f6..1fbcc7d1f85 100644 --- a/crates/server/src/main_loop/mod.rs +++ b/crates/server/src/main_loop/mod.rs @@ -171,21 +171,29 @@ fn on_request( let path_map = path_map.clone(); let sender = sender.clone(); pool.execute(move || { - let task = match handle_execute_command(world, path_map, params) { - Ok(req) => match to_value(req) { - Err(e) => Task::Die(e.into()), - Ok(params) => { - let request = RawRequest { - id: 0, - method: ::METHOD.to_string(), - params, - }; - Task::Request(request) - } - }, - Err(e) => Task::Die(e), + let (edit, cursor) = match handle_execute_command(world, path_map, params) { + Ok(res) => res, + Err(e) => return sender.send(Task::Die(e)), }; - sender.send(task) + match to_value(edit) { + Err(e) => return sender.send(Task::Die(e.into())), + Ok(params) => { + let request = RawRequest { + id: 0, + method: ::METHOD.to_string(), + params, + }; + sender.send(Task::Request(request)) + } + } + if let Some(cursor) = cursor { + let request = RawRequest { + id: 0, + method: ::METHOD.to_string(), + params: to_value(cursor).unwrap(), + }; + sender.send(Task::Request(request)) + } }); Ok(()) })?; diff --git a/crates/server/src/req.rs b/crates/server/src/req.rs index c3efc74893d..73e82150c7d 100644 --- a/crates/server/src/req.rs +++ b/crates/server/src/req.rs @@ -101,3 +101,11 @@ pub struct Decoration { pub range: Range, pub tag: &'static str } + +pub enum MoveCursor {} + +impl Request for MoveCursor { + type Params = Position; + type Result = (); + const METHOD: &'static str = "m/moveCursor"; +}