aboutsummaryrefslogtreecommitdiff
path: root/crates/server/src/main_loop/handlers.rs
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2018-08-13 00:38:34 +0100
committerAleksey Kladov <[email protected]>2018-08-13 00:38:34 +0100
commitbe742a587704f27f4e503c50f549aa9ec1527fcc (patch)
treefb15d3dd05c64c441c9cddbbce6aee3776d6ddd1 /crates/server/src/main_loop/handlers.rs
parent25aebb5225da91d34a2cb946f93435f9f7e82a47 (diff)
Apply code actions
Diffstat (limited to 'crates/server/src/main_loop/handlers.rs')
-rw-r--r--crates/server/src/main_loop/handlers.rs72
1 files changed, 64 insertions, 8 deletions
diff --git a/crates/server/src/main_loop/handlers.rs b/crates/server/src/main_loop/handlers.rs
index c6db22289..d4ae2a368 100644
--- a/crates/server/src/main_loop/handlers.rs
+++ b/crates/server/src/main_loop/handlers.rs
@@ -1,15 +1,18 @@
1use std::collections::HashMap;
2
1use languageserver_types::{ 3use languageserver_types::{
2 Diagnostic, DiagnosticSeverity, Url, DocumentSymbol, 4 Diagnostic, DiagnosticSeverity, Url, DocumentSymbol,
3 Command 5 Command, TextDocumentIdentifier, WorkspaceEdit
4}; 6};
5use libanalysis::World; 7use libanalysis::World;
6use libeditor; 8use libeditor;
7use serde_json::to_value; 9use libsyntax2::TextUnit;
10use serde_json::{to_value, from_value};
8 11
9use ::{ 12use ::{
10 req::{self, Decoration}, Result, 13 req::{self, Decoration}, Result,
11 util::FilePath, 14 util::FilePath,
12 conv::{Conv, ConvWith}, 15 conv::{Conv, ConvWith, MapConvWith},
13}; 16};
14 17
15pub fn handle_syntax_tree( 18pub fn handle_syntax_tree(
@@ -29,9 +32,9 @@ pub fn handle_extend_selection(
29 let file = world.file_syntax(&path)?; 32 let file = world.file_syntax(&path)?;
30 let line_index = world.file_line_index(&path)?; 33 let line_index = world.file_line_index(&path)?;
31 let selections = params.selections.into_iter() 34 let selections = params.selections.into_iter()
32 .map(|r| r.conv_with(&line_index)) 35 .map_conv_with(&line_index)
33 .map(|r| libeditor::extend_selection(&file, r).unwrap_or(r)) 36 .map(|r| libeditor::extend_selection(&file, r).unwrap_or(r))
34 .map(|r| r.conv_with(&line_index)) 37 .map_conv_with(&line_index)
35 .collect(); 38 .collect();
36 Ok(req::ExtendSelectionResult { selections }) 39 Ok(req::ExtendSelectionResult { selections })
37} 40}
@@ -78,18 +81,71 @@ pub fn handle_code_action(
78 let line_index = world.file_line_index(&path)?; 81 let line_index = world.file_line_index(&path)?;
79 let offset = params.range.conv_with(&line_index).start(); 82 let offset = params.range.conv_with(&line_index).start();
80 let ret = if libeditor::flip_comma(&file, offset).is_some() { 83 let ret = if libeditor::flip_comma(&file, offset).is_some() {
81 Some(vec![apply_code_action_cmd(ActionId::FlipComma)]) 84 let cmd = apply_code_action_cmd(
85 ActionId::FlipComma,
86 params.text_document,
87 offset,
88 );
89 Some(vec![cmd])
82 } else { 90 } else {
83 None 91 None
84 }; 92 };
85 Ok(ret) 93 Ok(ret)
86} 94}
87 95
88fn apply_code_action_cmd(id: ActionId) -> Command { 96pub fn handle_execute_command(
97 world: World,
98 mut params: req::ExecuteCommandParams,
99) -> Result<req::ApplyWorkspaceEditParams> {
100 if params.command.as_str() != "apply_code_action" {
101 bail!("unknown cmd: {:?}", params.command);
102 }
103 if params.arguments.len() != 1 {
104 bail!("expected single arg, got {}", params.arguments.len());
105 }
106 let arg = params.arguments.pop().unwrap();
107 let arg: ActionRequest = from_value(arg)?;
108 match arg.id {
109 ActionId::FlipComma => {
110 let path = arg.text_document.file_path()?;
111 let file = world.file_syntax(&path)?;
112 let line_index = world.file_line_index(&path)?;
113 let edit = match libeditor::flip_comma(&file, arg.offset) {
114 Some(edit) => edit(),
115 None => bail!("command not applicable"),
116 };
117 let mut changes = HashMap::new();
118 changes.insert(
119 arg.text_document.uri,
120 edit.conv_with(&line_index),
121 );
122 let edit = WorkspaceEdit {
123 changes: Some(changes),
124 document_changes: None,
125 };
126
127 Ok(req::ApplyWorkspaceEditParams { edit })
128 }
129 }
130}
131
132#[derive(Serialize, Deserialize)]
133struct ActionRequest {
134 id: ActionId,
135 text_document: TextDocumentIdentifier,
136 offset: TextUnit,
137}
138
139fn apply_code_action_cmd(id: ActionId, doc: TextDocumentIdentifier, offset: TextUnit) -> Command {
140 let action_request = ActionRequest {
141 id,
142 text_document: doc,
143 offset,
144 };
89 Command { 145 Command {
90 title: id.title().to_string(), 146 title: id.title().to_string(),
91 command: "apply_code_action".to_string(), 147 command: "apply_code_action".to_string(),
92 arguments: Some(vec![to_value(id).unwrap()]), 148 arguments: Some(vec![to_value(action_request).unwrap()]),
93 } 149 }
94} 150}
95 151