diff options
Diffstat (limited to 'crates/server/src/main_loop/handlers.rs')
-rw-r--r-- | crates/server/src/main_loop/handlers.rs | 91 |
1 files changed, 56 insertions, 35 deletions
diff --git a/crates/server/src/main_loop/handlers.rs b/crates/server/src/main_loop/handlers.rs index 9de6f480b..637bf1b24 100644 --- a/crates/server/src/main_loop/handlers.rs +++ b/crates/server/src/main_loop/handlers.rs | |||
@@ -11,27 +11,29 @@ use libsyntax2::TextUnit; | |||
11 | use serde_json::{to_value, from_value}; | 11 | use serde_json::{to_value, from_value}; |
12 | 12 | ||
13 | use ::{ | 13 | use ::{ |
14 | PathMap, | ||
14 | req::{self, Decoration}, Result, | 15 | req::{self, Decoration}, Result, |
15 | util::FilePath, | 16 | conv::{Conv, ConvWith, TryConvWith, MapConvWith, to_location}, |
16 | conv::{Conv, ConvWith, TryConvWith, MapConvWith}, | ||
17 | }; | 17 | }; |
18 | 18 | ||
19 | pub fn handle_syntax_tree( | 19 | pub fn handle_syntax_tree( |
20 | world: World, | 20 | world: World, |
21 | path_map: PathMap, | ||
21 | params: req::SyntaxTreeParams, | 22 | params: req::SyntaxTreeParams, |
22 | ) -> Result<String> { | 23 | ) -> Result<String> { |
23 | let path = params.text_document.file_path()?; | 24 | let id = params.text_document.try_conv_with(&path_map)?; |
24 | let file = world.file_syntax(&path)?; | 25 | let file = world.file_syntax(id)?; |
25 | Ok(libeditor::syntax_tree(&file)) | 26 | Ok(libeditor::syntax_tree(&file)) |
26 | } | 27 | } |
27 | 28 | ||
28 | pub fn handle_extend_selection( | 29 | pub fn handle_extend_selection( |
29 | world: World, | 30 | world: World, |
31 | path_map: PathMap, | ||
30 | params: req::ExtendSelectionParams, | 32 | params: req::ExtendSelectionParams, |
31 | ) -> Result<req::ExtendSelectionResult> { | 33 | ) -> Result<req::ExtendSelectionResult> { |
32 | let path = params.text_document.file_path()?; | 34 | let file_id = params.text_document.try_conv_with(&path_map)?; |
33 | let file = world.file_syntax(&path)?; | 35 | let file = world.file_syntax(file_id)?; |
34 | let line_index = world.file_line_index(&path)?; | 36 | let line_index = world.file_line_index(file_id)?; |
35 | let selections = params.selections.into_iter() | 37 | let selections = params.selections.into_iter() |
36 | .map_conv_with(&line_index) | 38 | .map_conv_with(&line_index) |
37 | .map(|r| libeditor::extend_selection(&file, r).unwrap_or(r)) | 39 | .map(|r| libeditor::extend_selection(&file, r).unwrap_or(r)) |
@@ -42,11 +44,12 @@ pub fn handle_extend_selection( | |||
42 | 44 | ||
43 | pub fn handle_document_symbol( | 45 | pub fn handle_document_symbol( |
44 | world: World, | 46 | world: World, |
47 | path_map: PathMap, | ||
45 | params: req::DocumentSymbolParams, | 48 | params: req::DocumentSymbolParams, |
46 | ) -> Result<Option<req::DocumentSymbolResponse>> { | 49 | ) -> Result<Option<req::DocumentSymbolResponse>> { |
47 | let path = params.text_document.file_path()?; | 50 | let file_id = params.text_document.try_conv_with(&path_map)?; |
48 | let file = world.file_syntax(&path)?; | 51 | let file = world.file_syntax(file_id)?; |
49 | let line_index = world.file_line_index(&path)?; | 52 | let line_index = world.file_line_index(file_id)?; |
50 | 53 | ||
51 | let mut parents: Vec<(DocumentSymbol, Option<usize>)> = Vec::new(); | 54 | let mut parents: Vec<(DocumentSymbol, Option<usize>)> = Vec::new(); |
52 | 55 | ||
@@ -81,11 +84,12 @@ pub fn handle_document_symbol( | |||
81 | 84 | ||
82 | pub fn handle_code_action( | 85 | pub fn handle_code_action( |
83 | world: World, | 86 | world: World, |
87 | path_map: PathMap, | ||
84 | params: req::CodeActionParams, | 88 | params: req::CodeActionParams, |
85 | ) -> Result<Option<Vec<Command>>> { | 89 | ) -> Result<Option<Vec<Command>>> { |
86 | let path = params.text_document.file_path()?; | 90 | let file_id = params.text_document.try_conv_with(&path_map)?; |
87 | let file = world.file_syntax(&path)?; | 91 | let file = world.file_syntax(file_id)?; |
88 | let line_index = world.file_line_index(&path)?; | 92 | let line_index = world.file_line_index(file_id)?; |
89 | let offset = params.range.conv_with(&line_index).start(); | 93 | let offset = params.range.conv_with(&line_index).start(); |
90 | let mut ret = Vec::new(); | 94 | let mut ret = Vec::new(); |
91 | 95 | ||
@@ -105,6 +109,7 @@ pub fn handle_code_action( | |||
105 | 109 | ||
106 | pub fn handle_workspace_symbol( | 110 | pub fn handle_workspace_symbol( |
107 | world: World, | 111 | world: World, |
112 | path_map: PathMap, | ||
108 | params: req::WorkspaceSymbolParams, | 113 | params: req::WorkspaceSymbolParams, |
109 | ) -> Result<Option<Vec<SymbolInformation>>> { | 114 | ) -> Result<Option<Vec<SymbolInformation>>> { |
110 | let all_symbols = params.query.contains("#"); | 115 | let all_symbols = params.query.contains("#"); |
@@ -119,23 +124,26 @@ pub fn handle_workspace_symbol( | |||
119 | q.limit(128); | 124 | q.limit(128); |
120 | q | 125 | q |
121 | }; | 126 | }; |
122 | let mut res = exec_query(&world, query)?; | 127 | let mut res = exec_query(&world, &path_map, query)?; |
123 | if res.is_empty() && !all_symbols { | 128 | if res.is_empty() && !all_symbols { |
124 | let mut query = Query::new(params.query); | 129 | let mut query = Query::new(params.query); |
125 | query.limit(128); | 130 | query.limit(128); |
126 | res = exec_query(&world, query)?; | 131 | res = exec_query(&world, &path_map, query)?; |
127 | } | 132 | } |
128 | 133 | ||
129 | return Ok(Some(res)); | 134 | return Ok(Some(res)); |
130 | 135 | ||
131 | fn exec_query(world: &World, query: Query) -> Result<Vec<SymbolInformation>> { | 136 | fn exec_query(world: &World, path_map: &PathMap, query: Query) -> Result<Vec<SymbolInformation>> { |
132 | let mut res = Vec::new(); | 137 | let mut res = Vec::new(); |
133 | for (path, symbol) in world.world_symbols(query) { | 138 | for (file_id, symbol) in world.world_symbols(query) { |
134 | let line_index = world.file_line_index(path)?; | 139 | let line_index = world.file_line_index(file_id)?; |
135 | let info = SymbolInformation { | 140 | let info = SymbolInformation { |
136 | name: symbol.name.to_string(), | 141 | name: symbol.name.to_string(), |
137 | kind: symbol.kind.conv(), | 142 | kind: symbol.kind.conv(), |
138 | location: (path, symbol.node_range).try_conv_with(&line_index)?, | 143 | location: to_location( |
144 | file_id, symbol.node_range, | ||
145 | path_map, &line_index | ||
146 | )?, | ||
139 | container_name: None, | 147 | container_name: None, |
140 | }; | 148 | }; |
141 | res.push(info); | 149 | res.push(info); |
@@ -146,15 +154,19 @@ pub fn handle_workspace_symbol( | |||
146 | 154 | ||
147 | pub fn handle_goto_definition( | 155 | pub fn handle_goto_definition( |
148 | world: World, | 156 | world: World, |
157 | path_map: PathMap, | ||
149 | params: req::TextDocumentPositionParams, | 158 | params: req::TextDocumentPositionParams, |
150 | ) -> Result<Option<req::GotoDefinitionResponse>> { | 159 | ) -> Result<Option<req::GotoDefinitionResponse>> { |
151 | let path = params.text_document.file_path()?; | 160 | let file_id = params.text_document.try_conv_with(&path_map)?; |
152 | let line_index = world.file_line_index(&path)?; | 161 | let line_index = world.file_line_index(file_id)?; |
153 | let offset = params.position.conv_with(&line_index); | 162 | let offset = params.position.conv_with(&line_index); |
154 | let mut res = Vec::new(); | 163 | let mut res = Vec::new(); |
155 | for (path, symbol) in world.approximately_resolve_symbol(&path, offset)? { | 164 | for (file_id, symbol) in world.approximately_resolve_symbol(file_id, offset)? { |
156 | let line_index = world.file_line_index(path)?; | 165 | let line_index = world.file_line_index(file_id)?; |
157 | let location = (path, symbol.node_range).try_conv_with(&line_index)?; | 166 | let location = to_location( |
167 | file_id, symbol.node_range, | ||
168 | &path_map, &line_index, | ||
169 | )?; | ||
158 | res.push(location) | 170 | res.push(location) |
159 | } | 171 | } |
160 | Ok(Some(req::GotoDefinitionResponse::Array(res))) | 172 | Ok(Some(req::GotoDefinitionResponse::Array(res))) |
@@ -162,6 +174,7 @@ pub fn handle_goto_definition( | |||
162 | 174 | ||
163 | pub fn handle_execute_command( | 175 | pub fn handle_execute_command( |
164 | world: World, | 176 | world: World, |
177 | path_map: PathMap, | ||
165 | mut params: req::ExecuteCommandParams, | 178 | mut params: req::ExecuteCommandParams, |
166 | ) -> Result<req::ApplyWorkspaceEditParams> { | 179 | ) -> Result<req::ApplyWorkspaceEditParams> { |
167 | if params.command.as_str() != "apply_code_action" { | 180 | if params.command.as_str() != "apply_code_action" { |
@@ -172,8 +185,8 @@ pub fn handle_execute_command( | |||
172 | } | 185 | } |
173 | let arg = params.arguments.pop().unwrap(); | 186 | let arg = params.arguments.pop().unwrap(); |
174 | let arg: ActionRequest = from_value(arg)?; | 187 | let arg: ActionRequest = from_value(arg)?; |
175 | let path = arg.text_document.file_path()?; | 188 | let file_id = arg.text_document.try_conv_with(&path_map)?; |
176 | let file = world.file_syntax(&path)?; | 189 | let file = world.file_syntax(file_id)?; |
177 | let edit = match arg.id { | 190 | let edit = match arg.id { |
178 | ActionId::FlipComma => libeditor::flip_comma(&file, arg.offset).map(|edit| edit()), | 191 | ActionId::FlipComma => libeditor::flip_comma(&file, arg.offset).map(|edit| edit()), |
179 | ActionId::AddDerive => libeditor::add_derive(&file, arg.offset).map(|edit| edit()), | 192 | ActionId::AddDerive => libeditor::add_derive(&file, arg.offset).map(|edit| edit()), |
@@ -182,7 +195,7 @@ pub fn handle_execute_command( | |||
182 | Some(edit) => edit, | 195 | Some(edit) => edit, |
183 | None => bail!("command not applicable"), | 196 | None => bail!("command not applicable"), |
184 | }; | 197 | }; |
185 | let line_index = world.file_line_index(&path)?; | 198 | let line_index = world.file_line_index(file_id)?; |
186 | let mut changes = HashMap::new(); | 199 | let mut changes = HashMap::new(); |
187 | changes.insert( | 200 | changes.insert( |
188 | arg.text_document.uri, | 201 | arg.text_document.uri, |
@@ -231,10 +244,14 @@ impl ActionId { | |||
231 | } | 244 | } |
232 | } | 245 | } |
233 | 246 | ||
234 | pub fn publish_diagnostics(world: World, uri: Url) -> Result<req::PublishDiagnosticsParams> { | 247 | pub fn publish_diagnostics( |
235 | let path = uri.file_path()?; | 248 | world: World, |
236 | let file = world.file_syntax(&path)?; | 249 | path_map: PathMap, |
237 | let line_index = world.file_line_index(&path)?; | 250 | uri: Url |
251 | ) -> Result<req::PublishDiagnosticsParams> { | ||
252 | let file_id = uri.try_conv_with(&path_map)?; | ||
253 | let file = world.file_syntax(file_id)?; | ||
254 | let line_index = world.file_line_index(file_id)?; | ||
238 | let diagnostics = libeditor::diagnostics(&file) | 255 | let diagnostics = libeditor::diagnostics(&file) |
239 | .into_iter() | 256 | .into_iter() |
240 | .map(|d| Diagnostic { | 257 | .map(|d| Diagnostic { |
@@ -248,10 +265,14 @@ pub fn publish_diagnostics(world: World, uri: Url) -> Result<req::PublishDiagnos | |||
248 | Ok(req::PublishDiagnosticsParams { uri, diagnostics }) | 265 | Ok(req::PublishDiagnosticsParams { uri, diagnostics }) |
249 | } | 266 | } |
250 | 267 | ||
251 | pub fn publish_decorations(world: World, uri: Url) -> Result<req::PublishDecorationsParams> { | 268 | pub fn publish_decorations( |
252 | let path = uri.file_path()?; | 269 | world: World, |
253 | let file = world.file_syntax(&path)?; | 270 | path_map: PathMap, |
254 | let line_index = world.file_line_index(&path)?; | 271 | uri: Url |
272 | ) -> Result<req::PublishDecorationsParams> { | ||
273 | let file_id = uri.try_conv_with(&path_map)?; | ||
274 | let file = world.file_syntax(file_id)?; | ||
275 | let line_index = world.file_line_index(file_id)?; | ||
255 | let decorations = libeditor::highlight(&file) | 276 | let decorations = libeditor::highlight(&file) |
256 | .into_iter() | 277 | .into_iter() |
257 | .map(|h| Decoration { | 278 | .map(|h| Decoration { |