diff options
author | Aleksey Kladov <[email protected]> | 2018-08-10 20:23:17 +0100 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2018-08-10 20:23:17 +0100 |
commit | 26262aaf05983c5b7f41cc438e287523268fe1eb (patch) | |
tree | 4473bd2559c838e0df5a10c9ea1307b49d51b8bc /codeless/server/src/handlers.rs | |
parent | 3fff5e94ebf772f8485aaa2bda2ea36be766fdb3 (diff) |
extend selection via LSP
Diffstat (limited to 'codeless/server/src/handlers.rs')
-rw-r--r-- | codeless/server/src/handlers.rs | 58 |
1 files changed, 53 insertions, 5 deletions
diff --git a/codeless/server/src/handlers.rs b/codeless/server/src/handlers.rs index 3f257941a..5ee87a4dd 100644 --- a/codeless/server/src/handlers.rs +++ b/codeless/server/src/handlers.rs | |||
@@ -1,13 +1,61 @@ | |||
1 | use languageserver_types::{Range, Position}; | ||
1 | use libanalysis::World; | 2 | use libanalysis::World; |
2 | use libeditor; | 3 | use libeditor::{self, LineIndex, LineCol, TextRange, TextUnit}; |
3 | use {req, Result}; | 4 | use {req, Result, FilePath}; |
4 | 5 | ||
5 | pub fn handle_syntax_tree( | 6 | pub fn handle_syntax_tree( |
6 | world: World, | 7 | world: World, |
7 | params: req::SyntaxTreeParams | 8 | params: req::SyntaxTreeParams, |
8 | ) -> Result<String> { | 9 | ) -> Result<String> { |
9 | let path = params.text_document.uri.to_file_path() | 10 | let path = params.text_document.file_path()?; |
10 | .map_err(|()| format_err!("invalid path"))?; | ||
11 | let file = world.file_syntax(&path)?; | 11 | let file = world.file_syntax(&path)?; |
12 | Ok(libeditor::syntax_tree(&file)) | 12 | Ok(libeditor::syntax_tree(&file)) |
13 | } | 13 | } |
14 | |||
15 | pub fn handle_extend_selection( | ||
16 | world: World, | ||
17 | params: req::ExtendSelectionParams, | ||
18 | ) -> Result<req::ExtendSelectionResult> { | ||
19 | let path = params.text_document.file_path()?; | ||
20 | let file = world.file_syntax(&path)?; | ||
21 | let line_index = world.file_line_index(&path)?; | ||
22 | let selections = params.selections.into_iter() | ||
23 | .map(|r| { | ||
24 | let r = to_text_range(&line_index, r); | ||
25 | let r = libeditor::extend_selection(&file, r).unwrap_or(r); | ||
26 | to_vs_range(&line_index, r) | ||
27 | }) | ||
28 | .collect(); | ||
29 | Ok(req::ExtendSelectionResult { selections }) | ||
30 | } | ||
31 | |||
32 | |||
33 | fn to_text_range(line_index: &LineIndex, range: Range) -> TextRange { | ||
34 | TextRange::from_to( | ||
35 | to_text_unit(line_index, range.start), | ||
36 | to_text_unit(line_index, range.end), | ||
37 | ) | ||
38 | } | ||
39 | |||
40 | fn to_text_unit(line_index: &LineIndex, position: Position) -> TextUnit { | ||
41 | // TODO: UTF-16 | ||
42 | let line_col = LineCol { | ||
43 | line: position.line as u32, | ||
44 | col: (position.character as u32).into(), | ||
45 | }; | ||
46 | line_index.offset(line_col) | ||
47 | } | ||
48 | |||
49 | |||
50 | fn to_vs_range(line_index: &LineIndex, range: TextRange) -> Range { | ||
51 | Range::new( | ||
52 | to_vs_position(line_index, range.start()), | ||
53 | to_vs_position(line_index, range.end()), | ||
54 | ) | ||
55 | } | ||
56 | |||
57 | fn to_vs_position(line_index: &LineIndex, offset: TextUnit) -> Position { | ||
58 | let line_col = line_index.line_col(offset); | ||
59 | // TODO: UTF-16 | ||
60 | Position::new(line_col.line as u64, u32::from(line_col.col) as u64) | ||
61 | } | ||