diff options
Diffstat (limited to 'editors/code/src')
-rw-r--r-- | editors/code/src/commands/syntax_tree.ts | 37 | ||||
-rw-r--r-- | editors/code/src/tasks.ts | 103 |
2 files changed, 102 insertions, 38 deletions
diff --git a/editors/code/src/commands/syntax_tree.ts b/editors/code/src/commands/syntax_tree.ts index b7a397414..cfcf47b2f 100644 --- a/editors/code/src/commands/syntax_tree.ts +++ b/editors/code/src/commands/syntax_tree.ts | |||
@@ -198,7 +198,7 @@ class AstInspector implements vscode.HoverProvider, vscode.DefinitionProvider, D | |||
198 | return new vscode.Hover(["```rust\n" + rustSourceCode + "\n```"], astFileRange); | 198 | return new vscode.Hover(["```rust\n" + rustSourceCode + "\n```"], astFileRange); |
199 | } | 199 | } |
200 | 200 | ||
201 | private findAstNodeRange(astLine: vscode.TextLine) { | 201 | private findAstNodeRange(astLine: vscode.TextLine): vscode.Range { |
202 | const lineOffset = astLine.range.start; | 202 | const lineOffset = astLine.range.start; |
203 | const begin = lineOffset.translate(undefined, astLine.firstNonWhitespaceCharacterIndex); | 203 | const begin = lineOffset.translate(undefined, astLine.firstNonWhitespaceCharacterIndex); |
204 | const end = lineOffset.translate(undefined, astLine.text.trimEnd().length); | 204 | const end = lineOffset.translate(undefined, astLine.text.trimEnd().length); |
@@ -209,10 +209,43 @@ class AstInspector implements vscode.HoverProvider, vscode.DefinitionProvider, D | |||
209 | const parsedRange = /\[(\d+); (\d+)\)/.exec(astLine); | 209 | const parsedRange = /\[(\d+); (\d+)\)/.exec(astLine); |
210 | if (!parsedRange) return; | 210 | if (!parsedRange) return; |
211 | 211 | ||
212 | const [begin, end] = parsedRange.slice(1).map(off => doc.positionAt(+off)); | 212 | const [begin, end] = parsedRange |
213 | .slice(1) | ||
214 | .map(off => this.positionAt(doc, +off)); | ||
213 | 215 | ||
214 | return new vscode.Range(begin, end); | 216 | return new vscode.Range(begin, end); |
215 | } | 217 | } |
218 | |||
219 | // Memoize the last value, otherwise the CPU is at 100% single core | ||
220 | // with quadratic lookups when we build rust2Ast cache | ||
221 | cache?: { doc: vscode.TextDocument; offset: number; line: number }; | ||
222 | |||
223 | positionAt(doc: vscode.TextDocument, targetOffset: number): vscode.Position { | ||
224 | if (doc.eol === vscode.EndOfLine.LF) { | ||
225 | return doc.positionAt(targetOffset); | ||
226 | } | ||
227 | |||
228 | // Shitty workaround for crlf line endings | ||
229 | // We are still in this prehistoric era of carriage returns here... | ||
230 | |||
231 | let line = 0; | ||
232 | let offset = 0; | ||
233 | |||
234 | const cache = this.cache; | ||
235 | if (cache?.doc === doc && cache.offset <= targetOffset) { | ||
236 | ({ line, offset } = cache); | ||
237 | } | ||
238 | |||
239 | while (true) { | ||
240 | const lineLenWithLf = doc.lineAt(line).text.length + 1; | ||
241 | if (offset + lineLenWithLf > targetOffset) { | ||
242 | this.cache = { doc, offset, line }; | ||
243 | return doc.positionAt(targetOffset + line); | ||
244 | } | ||
245 | offset += lineLenWithLf; | ||
246 | line += 1; | ||
247 | } | ||
248 | } | ||
216 | } | 249 | } |
217 | 250 | ||
218 | class Lazy<T> { | 251 | class Lazy<T> { |
diff --git a/editors/code/src/tasks.ts b/editors/code/src/tasks.ts index fa1c4a951..1366c76d6 100644 --- a/editors/code/src/tasks.ts +++ b/editors/code/src/tasks.ts | |||
@@ -4,49 +4,80 @@ import * as vscode from 'vscode'; | |||
4 | // our configuration should be compatible with it so use the same key. | 4 | // our configuration should be compatible with it so use the same key. |
5 | const TASK_TYPE = 'cargo'; | 5 | const TASK_TYPE = 'cargo'; |
6 | 6 | ||
7 | export function activateTaskProvider(target: vscode.WorkspaceFolder): vscode.Disposable { | 7 | interface CargoTaskDefinition extends vscode.TaskDefinition { |
8 | const provider: vscode.TaskProvider = { | 8 | command?: string; |
9 | args?: string[]; | ||
10 | cwd?: string; | ||
11 | env?: { [key: string]: string }; | ||
12 | } | ||
13 | |||
14 | class CargoTaskProvider implements vscode.TaskProvider { | ||
15 | private readonly target: vscode.WorkspaceFolder; | ||
16 | |||
17 | constructor(target: vscode.WorkspaceFolder) { | ||
18 | this.target = target; | ||
19 | } | ||
20 | |||
21 | provideTasks(): vscode.Task[] { | ||
9 | // Detect Rust tasks. Currently we do not do any actual detection | 22 | // Detect Rust tasks. Currently we do not do any actual detection |
10 | // of tasks (e.g. aliases in .cargo/config) and just return a fixed | 23 | // of tasks (e.g. aliases in .cargo/config) and just return a fixed |
11 | // set of tasks that always exist. These tasks cannot be removed in | 24 | // set of tasks that always exist. These tasks cannot be removed in |
12 | // tasks.json - only tweaked. | 25 | // tasks.json - only tweaked. |
13 | provideTasks: () => getStandardCargoTasks(target), | ||
14 | 26 | ||
15 | // We don't need to implement this. | 27 | return [ |
16 | resolveTask: () => undefined, | 28 | { command: 'build', group: vscode.TaskGroup.Build }, |
17 | }; | 29 | { command: 'check', group: vscode.TaskGroup.Build }, |
30 | { command: 'test', group: vscode.TaskGroup.Test }, | ||
31 | { command: 'clean', group: vscode.TaskGroup.Clean }, | ||
32 | { command: 'run', group: undefined }, | ||
33 | ] | ||
34 | .map(({ command, group }) => { | ||
35 | const vscodeTask = new vscode.Task( | ||
36 | // The contents of this object end up in the tasks.json entries. | ||
37 | { | ||
38 | type: TASK_TYPE, | ||
39 | command, | ||
40 | }, | ||
41 | // The scope of the task - workspace or specific folder (global | ||
42 | // is not supported). | ||
43 | this.target, | ||
44 | // The task name, and task source. These are shown in the UI as | ||
45 | // `${source}: ${name}`, e.g. `rust: cargo build`. | ||
46 | `cargo ${command}`, | ||
47 | 'rust', | ||
48 | // What to do when this command is executed. | ||
49 | new vscode.ShellExecution('cargo', [command]), | ||
50 | // Problem matchers. | ||
51 | ['$rustc'], | ||
52 | ); | ||
53 | vscodeTask.group = group; | ||
54 | return vscodeTask; | ||
55 | }); | ||
56 | } | ||
18 | 57 | ||
19 | return vscode.tasks.registerTaskProvider(TASK_TYPE, provider); | 58 | resolveTask(task: vscode.Task): vscode.Task | undefined { |
20 | } | 59 | // VSCode calls this for every cargo task in the user's tasks.json, |
60 | // we need to inform VSCode how to execute that command by creating | ||
61 | // a ShellExecution for it. | ||
21 | 62 | ||
22 | function getStandardCargoTasks(target: vscode.WorkspaceFolder): vscode.Task[] { | 63 | const definition = task.definition as CargoTaskDefinition; |
23 | return [ | 64 | |
24 | { command: 'build', group: vscode.TaskGroup.Build }, | 65 | if (definition.type === 'cargo' && definition.command) { |
25 | { command: 'check', group: vscode.TaskGroup.Build }, | 66 | const args = [definition.command].concat(definition.args ?? []); |
26 | { command: 'test', group: vscode.TaskGroup.Test }, | 67 | |
27 | { command: 'clean', group: vscode.TaskGroup.Clean }, | 68 | return new vscode.Task( |
28 | { command: 'run', group: undefined }, | 69 | definition, |
29 | ] | 70 | task.name, |
30 | .map(({ command, group }) => { | ||
31 | const vscodeTask = new vscode.Task( | ||
32 | // The contents of this object end up in the tasks.json entries. | ||
33 | { | ||
34 | type: TASK_TYPE, | ||
35 | command, | ||
36 | }, | ||
37 | // The scope of the task - workspace or specific folder (global | ||
38 | // is not supported). | ||
39 | target, | ||
40 | // The task name, and task source. These are shown in the UI as | ||
41 | // `${source}: ${name}`, e.g. `rust: cargo build`. | ||
42 | `cargo ${command}`, | ||
43 | 'rust', | 71 | 'rust', |
44 | // What to do when this command is executed. | 72 | new vscode.ShellExecution('cargo', args, definition), |
45 | new vscode.ShellExecution('cargo', [command]), | ||
46 | // Problem matchers. | ||
47 | ['$rustc'], | ||
48 | ); | 73 | ); |
49 | vscodeTask.group = group; | 74 | } |
50 | return vscodeTask; | 75 | |
51 | }); | 76 | return undefined; |
77 | } | ||
52 | } | 78 | } |
79 | |||
80 | export function activateTaskProvider(target: vscode.WorkspaceFolder): vscode.Disposable { | ||
81 | const provider = new CargoTaskProvider(target); | ||
82 | return vscode.tasks.registerTaskProvider(TASK_TYPE, provider); | ||
83 | } \ No newline at end of file | ||