more modules
This commit is contained in:
137
crates/server/src/main_loop/handlers.rs
Normal file
137
crates/server/src/main_loop/handlers.rs
Normal file
@@ -0,0 +1,137 @@
|
||||
use languageserver_types::{
|
||||
Diagnostic, DiagnosticSeverity, Url, DocumentSymbol,
|
||||
Command
|
||||
};
|
||||
use libanalysis::World;
|
||||
use libeditor;
|
||||
use serde_json::to_value;
|
||||
|
||||
use ::{
|
||||
req::{self, Decoration}, Result,
|
||||
util::FilePath,
|
||||
conv::{Conv, ConvWith},
|
||||
};
|
||||
|
||||
pub fn handle_syntax_tree(
|
||||
world: World,
|
||||
params: req::SyntaxTreeParams,
|
||||
) -> Result<String> {
|
||||
let path = params.text_document.file_path()?;
|
||||
let file = world.file_syntax(&path)?;
|
||||
Ok(libeditor::syntax_tree(&file))
|
||||
}
|
||||
|
||||
pub fn handle_extend_selection(
|
||||
world: World,
|
||||
params: req::ExtendSelectionParams,
|
||||
) -> Result<req::ExtendSelectionResult> {
|
||||
let path = params.text_document.file_path()?;
|
||||
let file = world.file_syntax(&path)?;
|
||||
let line_index = world.file_line_index(&path)?;
|
||||
let selections = params.selections.into_iter()
|
||||
.map(|r| r.conv_with(&line_index))
|
||||
.map(|r| libeditor::extend_selection(&file, r).unwrap_or(r))
|
||||
.map(|r| r.conv_with(&line_index))
|
||||
.collect();
|
||||
Ok(req::ExtendSelectionResult { selections })
|
||||
}
|
||||
|
||||
pub fn handle_document_symbol(
|
||||
world: World,
|
||||
params: req::DocumentSymbolParams,
|
||||
) -> Result<Option<req::DocumentSymbolResponse>> {
|
||||
let path = params.text_document.file_path()?;
|
||||
let file = world.file_syntax(&path)?;
|
||||
let line_index = world.file_line_index(&path)?;
|
||||
|
||||
let mut res: Vec<DocumentSymbol> = Vec::new();
|
||||
|
||||
for symbol in libeditor::file_symbols(&file) {
|
||||
let doc_symbol = DocumentSymbol {
|
||||
name: symbol.name.clone(),
|
||||
detail: Some(symbol.name),
|
||||
kind: symbol.kind.conv(),
|
||||
deprecated: None,
|
||||
range: symbol.node_range.conv_with(&line_index),
|
||||
selection_range: symbol.name_range.conv_with(&line_index),
|
||||
children: None,
|
||||
};
|
||||
if let Some(idx) = symbol.parent {
|
||||
let children = &mut res[idx].children;
|
||||
if children.is_none() {
|
||||
*children = Some(Vec::new());
|
||||
}
|
||||
children.as_mut().unwrap().push(doc_symbol);
|
||||
} else {
|
||||
res.push(doc_symbol);
|
||||
}
|
||||
}
|
||||
Ok(Some(req::DocumentSymbolResponse::Nested(res)))
|
||||
}
|
||||
|
||||
pub fn handle_code_action(
|
||||
world: World,
|
||||
params: req::CodeActionParams,
|
||||
) -> Result<Option<Vec<Command>>> {
|
||||
let path = params.text_document.file_path()?;
|
||||
let file = world.file_syntax(&path)?;
|
||||
let line_index = world.file_line_index(&path)?;
|
||||
let offset = params.range.conv_with(&line_index).start();
|
||||
let ret = if libeditor::flip_comma(&file, offset).is_some() {
|
||||
Some(vec![apply_code_action_cmd(ActionId::FlipComma)])
|
||||
} else {
|
||||
None
|
||||
};
|
||||
Ok(ret)
|
||||
}
|
||||
|
||||
fn apply_code_action_cmd(id: ActionId) -> Command {
|
||||
Command {
|
||||
title: id.title().to_string(),
|
||||
command: "apply_code_action".to_string(),
|
||||
arguments: Some(vec![to_value(id).unwrap()]),
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Copy)]
|
||||
enum ActionId {
|
||||
FlipComma
|
||||
}
|
||||
|
||||
impl ActionId {
|
||||
fn title(&self) -> &'static str {
|
||||
match *self {
|
||||
ActionId::FlipComma => "Flip `,`",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn publish_diagnostics(world: World, uri: Url) -> Result<req::PublishDiagnosticsParams> {
|
||||
let path = uri.file_path()?;
|
||||
let file = world.file_syntax(&path)?;
|
||||
let line_index = world.file_line_index(&path)?;
|
||||
let diagnostics = libeditor::diagnostics(&file)
|
||||
.into_iter()
|
||||
.map(|d| Diagnostic {
|
||||
range: d.range.conv_with(&line_index),
|
||||
severity: Some(DiagnosticSeverity::Error),
|
||||
code: None,
|
||||
source: Some("libsyntax2".to_string()),
|
||||
message: d.msg,
|
||||
related_information: None,
|
||||
}).collect();
|
||||
Ok(req::PublishDiagnosticsParams { uri, diagnostics })
|
||||
}
|
||||
|
||||
pub fn publish_decorations(world: World, uri: Url) -> Result<req::PublishDecorationsParams> {
|
||||
let path = uri.file_path()?;
|
||||
let file = world.file_syntax(&path)?;
|
||||
let line_index = world.file_line_index(&path)?;
|
||||
let decorations = libeditor::highlight(&file)
|
||||
.into_iter()
|
||||
.map(|h| Decoration {
|
||||
range: h.range.conv_with(&line_index),
|
||||
tag: h.tag,
|
||||
}).collect();
|
||||
Ok(req::PublishDecorationsParams { uri, decorations })
|
||||
}
|
||||
Reference in New Issue
Block a user