diff options
Diffstat (limited to 'crates')
-rw-r--r-- | crates/libeditor/src/typing.rs | 11 | ||||
-rw-r--r-- | crates/libsyntax2/src/algo/mod.rs | 13 | ||||
-rw-r--r-- | crates/libsyntax2/src/lib.rs | 1 | ||||
-rw-r--r-- | crates/libsyntax2/src/text_utils.rs | 19 | ||||
-rw-r--r-- | crates/server/src/main_loop/handlers.rs | 61 |
5 files changed, 76 insertions, 29 deletions
diff --git a/crates/libeditor/src/typing.rs b/crates/libeditor/src/typing.rs index 04021d164..cc0d3d272 100644 --- a/crates/libeditor/src/typing.rs +++ b/crates/libeditor/src/typing.rs | |||
@@ -5,6 +5,7 @@ use libsyntax2::{ | |||
5 | walk::preorder, | 5 | walk::preorder, |
6 | find_covering_node, | 6 | find_covering_node, |
7 | }, | 7 | }, |
8 | text_utils::intersect, | ||
8 | SyntaxKind::*, | 9 | SyntaxKind::*, |
9 | }; | 10 | }; |
10 | 11 | ||
@@ -53,16 +54,6 @@ pub fn join_lines(file: &ast::ParsedFile, range: TextRange) -> ActionResult { | |||
53 | } | 54 | } |
54 | } | 55 | } |
55 | 56 | ||
56 | fn intersect(r1: TextRange, r2: TextRange) -> Option<TextRange> { | ||
57 | let start = r1.start().max(r2.start()); | ||
58 | let end = r1.end().min(r2.end()); | ||
59 | if start <= end { | ||
60 | Some(TextRange::from_to(start, end)) | ||
61 | } else { | ||
62 | None | ||
63 | } | ||
64 | } | ||
65 | |||
66 | fn remove_newline( | 57 | fn remove_newline( |
67 | edit: &mut EditBuilder, | 58 | edit: &mut EditBuilder, |
68 | node: SyntaxNodeRef, | 59 | node: SyntaxNodeRef, |
diff --git a/crates/libsyntax2/src/algo/mod.rs b/crates/libsyntax2/src/algo/mod.rs index 6efdff12f..2640d60ea 100644 --- a/crates/libsyntax2/src/algo/mod.rs +++ b/crates/libsyntax2/src/algo/mod.rs | |||
@@ -1,7 +1,10 @@ | |||
1 | pub mod walk; | 1 | pub mod walk; |
2 | pub mod visit; | 2 | pub mod visit; |
3 | 3 | ||
4 | use {SyntaxNodeRef, TextUnit, TextRange}; | 4 | use { |
5 | SyntaxNodeRef, TextUnit, TextRange, | ||
6 | text_utils::{contains_offset_nonstrict, is_subrange}, | ||
7 | }; | ||
5 | 8 | ||
6 | pub fn find_leaf_at_offset(node: SyntaxNodeRef, offset: TextUnit) -> LeafAtOffset { | 9 | pub fn find_leaf_at_offset(node: SyntaxNodeRef, offset: TextUnit) -> LeafAtOffset { |
7 | let range = node.range(); | 10 | let range = node.range(); |
@@ -116,14 +119,6 @@ fn common_ancestor<'a>(n1: SyntaxNodeRef<'a>, n2: SyntaxNodeRef<'a>) -> SyntaxNo | |||
116 | panic!("Can't find common ancestor of {:?} and {:?}", n1, n2) | 119 | panic!("Can't find common ancestor of {:?} and {:?}", n1, n2) |
117 | } | 120 | } |
118 | 121 | ||
119 | fn contains_offset_nonstrict(range: TextRange, offset: TextUnit) -> bool { | ||
120 | range.start() <= offset && offset <= range.end() | ||
121 | } | ||
122 | |||
123 | fn is_subrange(range: TextRange, subrange: TextRange) -> bool { | ||
124 | range.start() <= subrange.start() && subrange.end() <= range.end() | ||
125 | } | ||
126 | |||
127 | fn generate<T>(seed: Option<T>, step: impl Fn(&T) -> Option<T>) -> impl Iterator<Item=T> { | 122 | fn generate<T>(seed: Option<T>, step: impl Fn(&T) -> Option<T>) -> impl Iterator<Item=T> { |
128 | ::itertools::unfold(seed, move |slot| { | 123 | ::itertools::unfold(seed, move |slot| { |
129 | slot.take().map(|curr| { | 124 | slot.take().map(|curr| { |
diff --git a/crates/libsyntax2/src/lib.rs b/crates/libsyntax2/src/lib.rs index c078baa3a..53ae18988 100644 --- a/crates/libsyntax2/src/lib.rs +++ b/crates/libsyntax2/src/lib.rs | |||
@@ -39,6 +39,7 @@ mod syntax_kinds; | |||
39 | mod yellow; | 39 | mod yellow; |
40 | /// Utilities for simple uses of the parser. | 40 | /// Utilities for simple uses of the parser. |
41 | pub mod utils; | 41 | pub mod utils; |
42 | pub mod text_utils; | ||
42 | 43 | ||
43 | pub use { | 44 | pub use { |
44 | text_unit::{TextRange, TextUnit}, | 45 | text_unit::{TextRange, TextUnit}, |
diff --git a/crates/libsyntax2/src/text_utils.rs b/crates/libsyntax2/src/text_utils.rs new file mode 100644 index 000000000..e3d73888f --- /dev/null +++ b/crates/libsyntax2/src/text_utils.rs | |||
@@ -0,0 +1,19 @@ | |||
1 | use {TextRange, TextUnit}; | ||
2 | |||
3 | pub fn contains_offset_nonstrict(range: TextRange, offset: TextUnit) -> bool { | ||
4 | range.start() <= offset && offset <= range.end() | ||
5 | } | ||
6 | |||
7 | pub fn is_subrange(range: TextRange, subrange: TextRange) -> bool { | ||
8 | range.start() <= subrange.start() && subrange.end() <= range.end() | ||
9 | } | ||
10 | |||
11 | pub fn intersect(r1: TextRange, r2: TextRange) -> Option<TextRange> { | ||
12 | let start = r1.start().max(r2.start()); | ||
13 | let end = r1.end().min(r2.end()); | ||
14 | if start <= end { | ||
15 | Some(TextRange::from_to(start, end)) | ||
16 | } else { | ||
17 | None | ||
18 | } | ||
19 | } | ||
diff --git a/crates/server/src/main_loop/handlers.rs b/crates/server/src/main_loop/handlers.rs index ae362ddaa..b68e93e46 100644 --- a/crates/server/src/main_loop/handlers.rs +++ b/crates/server/src/main_loop/handlers.rs | |||
@@ -5,10 +5,13 @@ use languageserver_types::{ | |||
5 | Command, TextDocumentIdentifier, WorkspaceEdit, | 5 | Command, TextDocumentIdentifier, WorkspaceEdit, |
6 | SymbolInformation, Position, Location, TextEdit, | 6 | SymbolInformation, Position, Location, TextEdit, |
7 | }; | 7 | }; |
8 | use serde_json::{to_value, from_value}; | ||
8 | use libanalysis::{Query}; | 9 | use libanalysis::{Query}; |
9 | use libeditor; | 10 | use libeditor; |
10 | use libsyntax2::TextUnit; | 11 | use libsyntax2::{ |
11 | use serde_json::{to_value, from_value}; | 12 | TextUnit, |
13 | text_utils::contains_offset_nonstrict, | ||
14 | }; | ||
12 | 15 | ||
13 | use ::{ | 16 | use ::{ |
14 | req::{self, Decoration}, Result, | 17 | req::{self, Decoration}, Result, |
@@ -117,7 +120,7 @@ pub fn handle_code_action( | |||
117 | let file = world.analysis().file_syntax(file_id)?; | 120 | let file = world.analysis().file_syntax(file_id)?; |
118 | let line_index = world.analysis().file_line_index(file_id)?; | 121 | let line_index = world.analysis().file_line_index(file_id)?; |
119 | let offset = params.range.conv_with(&line_index).start(); | 122 | let offset = params.range.conv_with(&line_index).start(); |
120 | let mut ret = Vec::new(); | 123 | let mut res = Vec::new(); |
121 | 124 | ||
122 | let actions = &[ | 125 | let actions = &[ |
123 | (ActionId::FlipComma, libeditor::flip_comma(&file, offset).is_some()), | 126 | (ActionId::FlipComma, libeditor::flip_comma(&file, offset).is_some()), |
@@ -128,10 +131,52 @@ pub fn handle_code_action( | |||
128 | for (id, edit) in actions { | 131 | for (id, edit) in actions { |
129 | if *edit { | 132 | if *edit { |
130 | let cmd = apply_code_action_cmd(*id, params.text_document.clone(), offset); | 133 | let cmd = apply_code_action_cmd(*id, params.text_document.clone(), offset); |
131 | ret.push(cmd); | 134 | res.push(cmd); |
135 | } | ||
136 | } | ||
137 | for runnable in libeditor::runnables(&file) { | ||
138 | if !contains_offset_nonstrict(runnable.range, offset) { | ||
139 | continue; | ||
140 | } | ||
141 | |||
142 | #[derive(Serialize)] | ||
143 | struct ProcessSpec { | ||
144 | bin: String, | ||
145 | args: Vec<String>, | ||
146 | env: HashMap<String, String>, | ||
132 | } | 147 | } |
148 | |||
149 | let spec = ProcessSpec { | ||
150 | bin: "cargo".to_string(), | ||
151 | args: match runnable.kind { | ||
152 | libeditor::RunnableKind::Test { name } => { | ||
153 | vec![ | ||
154 | "test".to_string(), | ||
155 | "--".to_string(), | ||
156 | name, | ||
157 | "--nocapture".to_string(), | ||
158 | ] | ||
159 | } | ||
160 | libeditor::RunnableKind::Bin => vec!["run".to_string()] | ||
161 | }, | ||
162 | env: { | ||
163 | let mut m = HashMap::new(); | ||
164 | m.insert( | ||
165 | "RUST_BACKTRACE".to_string(), | ||
166 | "short".to_string(), | ||
167 | ); | ||
168 | m | ||
169 | } | ||
170 | }; | ||
171 | |||
172 | let cmd = Command { | ||
173 | title: "Run ...".to_string(), | ||
174 | command: "libsyntax-rust.run".to_string(), | ||
175 | arguments: Some(vec![to_value(spec).unwrap()]), | ||
176 | }; | ||
177 | res.push(cmd); | ||
133 | } | 178 | } |
134 | return Ok(Some(ret)); | 179 | return Ok(Some(res)); |
135 | } | 180 | } |
136 | 181 | ||
137 | pub fn handle_workspace_symbol( | 182 | pub fn handle_workspace_symbol( |
@@ -257,11 +302,7 @@ struct ActionRequest { | |||
257 | } | 302 | } |
258 | 303 | ||
259 | fn apply_code_action_cmd(id: ActionId, doc: TextDocumentIdentifier, offset: TextUnit) -> Command { | 304 | fn apply_code_action_cmd(id: ActionId, doc: TextDocumentIdentifier, offset: TextUnit) -> Command { |
260 | let action_request = ActionRequest { | 305 | let action_request = ActionRequest { id, text_document: doc, offset }; |
261 | id, | ||
262 | text_document: doc, | ||
263 | offset, | ||
264 | }; | ||
265 | Command { | 306 | Command { |
266 | title: id.title().to_string(), | 307 | title: id.title().to_string(), |
267 | command: "apply_code_action".to_string(), | 308 | command: "apply_code_action".to_string(), |