aboutsummaryrefslogtreecommitdiff
path: root/crates/server/src/main_loop
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2018-08-14 11:33:44 +0100
committerAleksey Kladov <[email protected]>2018-08-14 11:33:44 +0100
commit1141d448d960eedba0a5647d525910de706bf778 (patch)
tree144842663edc382addc6b2cb115717d5bb7eb736 /crates/server/src/main_loop
parent5953a348bd6102a868f303d3f732a6ec7d465833 (diff)
Add derive intention
Diffstat (limited to 'crates/server/src/main_loop')
-rw-r--r--crates/server/src/main_loop/handlers.rs107
1 files changed, 60 insertions, 47 deletions
diff --git a/crates/server/src/main_loop/handlers.rs b/crates/server/src/main_loop/handlers.rs
index 8789ef0d2..9de6f480b 100644
--- a/crates/server/src/main_loop/handlers.rs
+++ b/crates/server/src/main_loop/handlers.rs
@@ -87,27 +87,28 @@ pub fn handle_code_action(
87 let file = world.file_syntax(&path)?; 87 let file = world.file_syntax(&path)?;
88 let line_index = world.file_line_index(&path)?; 88 let line_index = world.file_line_index(&path)?;
89 let offset = params.range.conv_with(&line_index).start(); 89 let offset = params.range.conv_with(&line_index).start();
90 let ret = if libeditor::flip_comma(&file, offset).is_some() { 90 let mut ret = Vec::new();
91 let cmd = apply_code_action_cmd( 91
92 ActionId::FlipComma, 92 let actions = &[
93 params.text_document, 93 (ActionId::FlipComma, libeditor::flip_comma(&file, offset).is_some()),
94 offset, 94 (ActionId::AddDerive, libeditor::add_derive(&file, offset).is_some()),
95 ); 95 ];
96 Some(vec![cmd]) 96
97 } else { 97 for (id, edit) in actions {
98 None 98 if *edit {
99 }; 99 let cmd = apply_code_action_cmd(*id, params.text_document.clone(), offset);
100 Ok(ret) 100 ret.push(cmd);
101 }
102 }
103 return Ok(Some(ret));
101} 104}
102 105
103pub fn handle_workspace_symbol( 106pub fn handle_workspace_symbol(
104 world: World, 107 world: World,
105 params: req::WorkspaceSymbolParams, 108 params: req::WorkspaceSymbolParams,
106) -> Result<Option<Vec<SymbolInformation>>> { 109) -> Result<Option<Vec<SymbolInformation>>> {
107 let mut acc = Vec::new(); 110 let all_symbols = params.query.contains("#");
108
109 let query = { 111 let query = {
110 let all_symbols = params.query.contains("#");
111 let query: String = params.query.chars() 112 let query: String = params.query.chars()
112 .filter(|&c| c != '#') 113 .filter(|&c| c != '#')
113 .collect(); 114 .collect();
@@ -118,19 +119,29 @@ pub fn handle_workspace_symbol(
118 q.limit(128); 119 q.limit(128);
119 q 120 q
120 }; 121 };
122 let mut res = exec_query(&world, query)?;
123 if res.is_empty() && !all_symbols {
124 let mut query = Query::new(params.query);
125 query.limit(128);
126 res = exec_query(&world, query)?;
127 }
121 128
122 for (path, symbol) in world.world_symbols(query) { 129 return Ok(Some(res));
123 let line_index = world.file_line_index(path)?;
124 let info = SymbolInformation {
125 name: symbol.name.to_string(),
126 kind: symbol.kind.conv(),
127 location: (path, symbol.node_range).try_conv_with(&line_index)?,
128 container_name: None,
129 };
130 acc.push(info);
131 };
132 130
133 Ok(Some(acc)) 131 fn exec_query(world: &World, query: Query) -> Result<Vec<SymbolInformation>> {
132 let mut res = Vec::new();
133 for (path, symbol) in world.world_symbols(query) {
134 let line_index = world.file_line_index(path)?;
135 let info = SymbolInformation {
136 name: symbol.name.to_string(),
137 kind: symbol.kind.conv(),
138 location: (path, symbol.node_range).try_conv_with(&line_index)?,
139 container_name: None,
140 };
141 res.push(info);
142 };
143 Ok(res)
144 }
134} 145}
135 146
136pub fn handle_goto_definition( 147pub fn handle_goto_definition(
@@ -161,28 +172,28 @@ pub fn handle_execute_command(
161 } 172 }
162 let arg = params.arguments.pop().unwrap(); 173 let arg = params.arguments.pop().unwrap();
163 let arg: ActionRequest = from_value(arg)?; 174 let arg: ActionRequest = from_value(arg)?;
164 match arg.id { 175 let path = arg.text_document.file_path()?;
165 ActionId::FlipComma => { 176 let file = world.file_syntax(&path)?;
166 let path = arg.text_document.file_path()?; 177 let edit = match arg.id {
167 let file = world.file_syntax(&path)?; 178 ActionId::FlipComma => libeditor::flip_comma(&file, arg.offset).map(|edit| edit()),
168 let line_index = world.file_line_index(&path)?; 179 ActionId::AddDerive => libeditor::add_derive(&file, arg.offset).map(|edit| edit()),
169 let edit = match libeditor::flip_comma(&file, arg.offset) { 180 };
170 Some(edit) => edit(), 181 let edit = match edit {
171 None => bail!("command not applicable"), 182 Some(edit) => edit,
172 }; 183 None => bail!("command not applicable"),
173 let mut changes = HashMap::new(); 184 };
174 changes.insert( 185 let line_index = world.file_line_index(&path)?;
175 arg.text_document.uri, 186 let mut changes = HashMap::new();
176 edit.conv_with(&line_index), 187 changes.insert(
177 ); 188 arg.text_document.uri,
178 let edit = WorkspaceEdit { 189 edit.conv_with(&line_index),
179 changes: Some(changes), 190 );
180 document_changes: None, 191 let edit = WorkspaceEdit {
181 }; 192 changes: Some(changes),
193 document_changes: None,
194 };
182 195
183 Ok(req::ApplyWorkspaceEditParams { edit }) 196 Ok(req::ApplyWorkspaceEditParams { edit })
184 }
185 }
186} 197}
187 198
188#[derive(Serialize, Deserialize)] 199#[derive(Serialize, Deserialize)]
@@ -207,13 +218,15 @@ fn apply_code_action_cmd(id: ActionId, doc: TextDocumentIdentifier, offset: Text
207 218
208#[derive(Serialize, Deserialize, Clone, Copy)] 219#[derive(Serialize, Deserialize, Clone, Copy)]
209enum ActionId { 220enum ActionId {
210 FlipComma 221 FlipComma,
222 AddDerive,
211} 223}
212 224
213impl ActionId { 225impl ActionId {
214 fn title(&self) -> &'static str { 226 fn title(&self) -> &'static str {
215 match *self { 227 match *self {
216 ActionId::FlipComma => "Flip `,`", 228 ActionId::FlipComma => "Flip `,`",
229 ActionId::AddDerive => "Add `#[derive]`",
217 } 230 }
218 } 231 }
219} 232}