aboutsummaryrefslogtreecommitdiff
path: root/crates/server/src/main_loop/handlers.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/server/src/main_loop/handlers.rs')
-rw-r--r--crates/server/src/main_loop/handlers.rs91
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;
11use serde_json::{to_value, from_value}; 11use serde_json::{to_value, from_value};
12 12
13use ::{ 13use ::{
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
19pub fn handle_syntax_tree( 19pub 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
28pub fn handle_extend_selection( 29pub 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
43pub fn handle_document_symbol( 45pub 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
82pub fn handle_code_action( 85pub 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
106pub fn handle_workspace_symbol( 110pub 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
147pub fn handle_goto_definition( 155pub 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
163pub fn handle_execute_command( 175pub 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
234pub fn publish_diagnostics(world: World, uri: Url) -> Result<req::PublishDiagnosticsParams> { 247pub 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
251pub fn publish_decorations(world: World, uri: Url) -> Result<req::PublishDecorationsParams> { 268pub 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 {