diff options
-rw-r--r-- | code/.vscode/launch.json | 3 | ||||
-rw-r--r-- | code/.vscode/tasks.json | 2 | ||||
-rw-r--r-- | code/package.json | 26 | ||||
-rw-r--r-- | code/src/extension.ts | 42 | ||||
-rw-r--r-- | code/tsconfig.json | 3 | ||||
-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 |
10 files changed, 149 insertions, 32 deletions
diff --git a/code/.vscode/launch.json b/code/.vscode/launch.json index 5e615ad4c..a5dd523df 100644 --- a/code/.vscode/launch.json +++ b/code/.vscode/launch.json | |||
@@ -10,6 +10,9 @@ | |||
10 | "request": "launch", | 10 | "request": "launch", |
11 | "runtimeExecutable": "${execPath}", | 11 | "runtimeExecutable": "${execPath}", |
12 | "args": ["--extensionDevelopmentPath='./'"], | 12 | "args": ["--extensionDevelopmentPath='./'"], |
13 | "env": { | ||
14 | "RUST_LOG": "m=trace" | ||
15 | }, | ||
13 | "stopOnEntry": false, | 16 | "stopOnEntry": false, |
14 | "sourceMaps": true, | 17 | "sourceMaps": true, |
15 | "outFiles": [ "./out/src/**/*.js" ], | 18 | "outFiles": [ "./out/src/**/*.js" ], |
diff --git a/code/.vscode/tasks.json b/code/.vscode/tasks.json index 8e5a8b9ef..e1cfa4deb 100644 --- a/code/.vscode/tasks.json +++ b/code/.vscode/tasks.json | |||
@@ -21,7 +21,7 @@ | |||
21 | "showOutput": "silent", | 21 | "showOutput": "silent", |
22 | 22 | ||
23 | // we run the custom script "compile" as defined in package.json | 23 | // we run the custom script "compile" as defined in package.json |
24 | "args": ["run", "compile", "--loglevel", "silent"], | 24 | "args": ["run", "compile",], |
25 | 25 | ||
26 | // The tsc compiler is started in watching mode | 26 | // The tsc compiler is started in watching mode |
27 | "isBackground": true, | 27 | "isBackground": true, |
diff --git a/code/package.json b/code/package.json index 20a6ceee7..1ed9dfabe 100644 --- a/code/package.json +++ b/code/package.json | |||
@@ -28,6 +28,28 @@ | |||
28 | "onLanguage:rust" | 28 | "onLanguage:rust" |
29 | ], | 29 | ], |
30 | "contributes": { | 30 | "contributes": { |
31 | "taskDefinitions": [ | ||
32 | { | ||
33 | "type": "cargo", | ||
34 | "required": [ | ||
35 | "command" | ||
36 | ], | ||
37 | "properties": { | ||
38 | "label": { | ||
39 | "type": "string" | ||
40 | }, | ||
41 | "command": { | ||
42 | "type": "string" | ||
43 | }, | ||
44 | "args": { | ||
45 | "type": "array" | ||
46 | }, | ||
47 | "env": { | ||
48 | "type": "object" | ||
49 | } | ||
50 | } | ||
51 | } | ||
52 | ], | ||
31 | "commands": [ | 53 | "commands": [ |
32 | { | 54 | { |
33 | "command": "libsyntax-rust.syntaxTree", | 55 | "command": "libsyntax-rust.syntaxTree", |
@@ -48,6 +70,10 @@ | |||
48 | { | 70 | { |
49 | "command": "libsyntax-rust.joinLines", | 71 | "command": "libsyntax-rust.joinLines", |
50 | "title": "Rust Join Lines" | 72 | "title": "Rust Join Lines" |
73 | }, | ||
74 | { | ||
75 | "command": "libsyntax-rust.run", | ||
76 | "title": "Rust Run" | ||
51 | } | 77 | } |
52 | ], | 78 | ], |
53 | "keybindings": [ | 79 | "keybindings": [ |
diff --git a/code/src/extension.ts b/code/src/extension.ts index df2109f50..c25e8cb61 100644 --- a/code/src/extension.ts +++ b/code/src/extension.ts | |||
@@ -81,6 +81,11 @@ export function activate(context: vscode.ExtensionContext) { | |||
81 | let e = await vscode.window.showTextDocument(doc) | 81 | let e = await vscode.window.showTextDocument(doc) |
82 | e.revealRange(range, vscode.TextEditorRevealType.InCenter) | 82 | e.revealRange(range, vscode.TextEditorRevealType.InCenter) |
83 | }) | 83 | }) |
84 | console.log("ping") | ||
85 | registerCommand('libsyntax-rust.run', async (cmd: ProcessSpec) => { | ||
86 | let task = createTask(cmd) | ||
87 | await vscode.tasks.executeTask(task) | ||
88 | }) | ||
84 | 89 | ||
85 | dispose(vscode.workspace.registerTextDocumentContentProvider( | 90 | dispose(vscode.workspace.registerTextDocumentContentProvider( |
86 | 'libsyntax-rust', | 91 | 'libsyntax-rust', |
@@ -265,3 +270,40 @@ interface Decoration { | |||
265 | range: lc.Range, | 270 | range: lc.Range, |
266 | tag: string, | 271 | tag: string, |
267 | } | 272 | } |
273 | |||
274 | interface ProcessSpec { | ||
275 | bin: string; | ||
276 | args: string[]; | ||
277 | env: { [key: string]: string }; | ||
278 | } | ||
279 | |||
280 | interface CargoTaskDefinition extends vscode.TaskDefinition { | ||
281 | type: 'cargo'; | ||
282 | label: string; | ||
283 | command: string; | ||
284 | args: Array<string>; | ||
285 | env?: { [key: string]: string }; | ||
286 | } | ||
287 | |||
288 | |||
289 | function createTask(spec: ProcessSpec): vscode.Task { | ||
290 | const TASK_SOURCE = 'Rust'; | ||
291 | let definition: CargoTaskDefinition = { | ||
292 | type: 'cargo', | ||
293 | label: 'cargo', | ||
294 | command: spec.bin, | ||
295 | args: spec.args, | ||
296 | env: spec.env | ||
297 | } | ||
298 | |||
299 | let execCmd = `${definition.command} ${definition.args.join(' ')}`; | ||
300 | let execOption: vscode.ShellExecutionOptions = { | ||
301 | cwd: '.', | ||
302 | env: definition.env, | ||
303 | }; | ||
304 | let exec = new vscode.ShellExecution(execCmd, execOption); | ||
305 | |||
306 | let f = vscode.workspace.workspaceFolders[0] | ||
307 | let t = new vscode.Task(definition, f, definition.label, TASK_SOURCE, exec, ['$rustc']); | ||
308 | return t; | ||
309 | } | ||
diff --git a/code/tsconfig.json b/code/tsconfig.json index 11c3126e0..32a166d0f 100644 --- a/code/tsconfig.json +++ b/code/tsconfig.json | |||
@@ -7,6 +7,5 @@ | |||
7 | "sourceMap": true, | 7 | "sourceMap": true, |
8 | "rootDir": "." | 8 | "rootDir": "." |
9 | }, | 9 | }, |
10 | "include": [ "src" ], | 10 | "include": [ "src/*.ts" ], |
11 | "exclude": [ "node_modules" ] | ||
12 | } | 11 | } |
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(), |