rust/crates/server/src/handlers.rs

81 lines
2.5 KiB
Rust
Raw Normal View History

2018-08-10 23:30:11 +03:00
use url::Url;
use languageserver_types::{Range, Position, Diagnostic, DiagnosticSeverity};
2018-08-10 21:13:39 +03:00
use libanalysis::World;
2018-08-10 22:23:17 +03:00
use libeditor::{self, LineIndex, LineCol, TextRange, TextUnit};
2018-08-10 23:30:11 +03:00
2018-08-10 22:23:17 +03:00
use {req, Result, FilePath};
2018-08-10 21:13:39 +03:00
pub fn handle_syntax_tree(
world: World,
2018-08-10 22:23:17 +03:00
params: req::SyntaxTreeParams,
2018-08-10 21:13:39 +03:00
) -> Result<String> {
2018-08-10 22:23:17 +03:00
let path = params.text_document.file_path()?;
2018-08-10 21:13:39 +03:00
let file = world.file_syntax(&path)?;
Ok(libeditor::syntax_tree(&file))
}
2018-08-10 22:23:17 +03:00
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| {
let r = to_text_range(&line_index, r);
let r = libeditor::extend_selection(&file, r).unwrap_or(r);
to_vs_range(&line_index, r)
})
.collect();
Ok(req::ExtendSelectionResult { selections })
}
2018-08-10 23:30:11 +03:00
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: to_vs_range(&line_index, d.range),
severity: Some(DiagnosticSeverity::Error),
code: None,
source: Some("libsyntax2".to_string()),
message: d.msg,
related_information: None,
}).collect();
Ok(req::PublishDiagnosticsParams { uri, diagnostics })
}
2018-08-10 22:23:17 +03:00
fn to_text_range(line_index: &LineIndex, range: Range) -> TextRange {
TextRange::from_to(
to_text_unit(line_index, range.start),
to_text_unit(line_index, range.end),
)
}
fn to_text_unit(line_index: &LineIndex, position: Position) -> TextUnit {
// TODO: UTF-16
let line_col = LineCol {
line: position.line as u32,
col: (position.character as u32).into(),
};
line_index.offset(line_col)
}
fn to_vs_range(line_index: &LineIndex, range: TextRange) -> Range {
Range::new(
to_vs_position(line_index, range.start()),
to_vs_position(line_index, range.end()),
)
}
fn to_vs_position(line_index: &LineIndex, offset: TextUnit) -> Position {
let line_col = line_index.line_col(offset);
// TODO: UTF-16
Position::new(line_col.line as u64, u32::from(line_col.col) as u64)
}