diff options
Diffstat (limited to 'editors')
-rw-r--r-- | editors/code/package.json | 5 | ||||
-rw-r--r-- | editors/code/src/client.ts | 2 | ||||
-rw-r--r-- | editors/code/src/commands.ts | 26 | ||||
-rw-r--r-- | editors/code/src/ctx.ts | 47 | ||||
-rw-r--r-- | editors/code/src/lsp_ext.ts | 11 | ||||
-rw-r--r-- | editors/code/src/snippets.ts | 10 |
6 files changed, 39 insertions, 62 deletions
diff --git a/editors/code/package.json b/editors/code/package.json index d263610f5..06ed62d8d 100644 --- a/editors/code/package.json +++ b/editors/code/package.json | |||
@@ -434,6 +434,11 @@ | |||
434 | "default": true, | 434 | "default": true, |
435 | "type": "boolean" | 435 | "type": "boolean" |
436 | }, | 436 | }, |
437 | "rust-analyzer.cargo.useRustcWrapperForBuildScripts": { | ||
438 | "markdownDescription": "Use `RUSTC_WRAPPER=rust-analyzer` when running build scripts to\navoid compiling unnecessary things.", | ||
439 | "default": true, | ||
440 | "type": "boolean" | ||
441 | }, | ||
437 | "rust-analyzer.cargo.noDefaultFeatures": { | 442 | "rust-analyzer.cargo.noDefaultFeatures": { |
438 | "markdownDescription": "Do not activate the `default` feature.", | 443 | "markdownDescription": "Do not activate the `default` feature.", |
439 | "default": false, | 444 | "default": false, |
diff --git a/editors/code/src/client.ts b/editors/code/src/client.ts index 0771ca3b6..116f41df6 100644 --- a/editors/code/src/client.ts +++ b/editors/code/src/client.ts | |||
@@ -159,7 +159,7 @@ class ExperimentalFeatures implements lc.StaticFeature { | |||
159 | caps.snippetTextEdit = true; | 159 | caps.snippetTextEdit = true; |
160 | caps.codeActionGroup = true; | 160 | caps.codeActionGroup = true; |
161 | caps.hoverActions = true; | 161 | caps.hoverActions = true; |
162 | caps.statusNotification = true; | 162 | caps.serverStatusNotification = true; |
163 | capabilities.experimental = caps; | 163 | capabilities.experimental = caps; |
164 | } | 164 | } |
165 | initialize(_capabilities: lc.ServerCapabilities<any>, _documentSelector: lc.DocumentSelector | undefined): void { | 165 | initialize(_capabilities: lc.ServerCapabilities<any>, _documentSelector: lc.DocumentSelector | undefined): void { |
diff --git a/editors/code/src/commands.ts b/editors/code/src/commands.ts index 1a0805bd3..4092435db 100644 --- a/editors/code/src/commands.ts +++ b/editors/code/src/commands.ts | |||
@@ -148,34 +148,16 @@ export function moveItem(ctx: Ctx, direction: ra.Direction): Cmd { | |||
148 | const client = ctx.client; | 148 | const client = ctx.client; |
149 | if (!editor || !client) return; | 149 | if (!editor || !client) return; |
150 | 150 | ||
151 | const edit = await client.sendRequest(ra.moveItem, { | 151 | const lcEdits = await client.sendRequest(ra.moveItem, { |
152 | range: client.code2ProtocolConverter.asRange(editor.selection), | 152 | range: client.code2ProtocolConverter.asRange(editor.selection), |
153 | textDocument: ctx.client.code2ProtocolConverter.asTextDocumentIdentifier(editor.document), | 153 | textDocument: ctx.client.code2ProtocolConverter.asTextDocumentIdentifier(editor.document), |
154 | direction | 154 | direction |
155 | }); | 155 | }); |
156 | 156 | ||
157 | if (!edit) return; | 157 | if (!lcEdits) return; |
158 | 158 | ||
159 | let cursor: vscode.Position | null = null; | 159 | const edits = client.protocol2CodeConverter.asTextEdits(lcEdits); |
160 | 160 | await applySnippetTextEdits(editor, edits); | |
161 | await editor.edit((builder) => { | ||
162 | client.protocol2CodeConverter.asTextEdits(edit.edits).forEach((edit: any) => { | ||
163 | builder.replace(edit.range, edit.newText); | ||
164 | |||
165 | if (direction === ra.Direction.Up) { | ||
166 | if (!cursor || edit.range.end.isBeforeOrEqual(cursor)) { | ||
167 | cursor = edit.range.end; | ||
168 | } | ||
169 | } else { | ||
170 | if (!cursor || edit.range.end.isAfterOrEqual(cursor)) { | ||
171 | cursor = edit.range.end; | ||
172 | } | ||
173 | } | ||
174 | }); | ||
175 | }).then(() => { | ||
176 | const newPosition = cursor ?? editor.selection.start; | ||
177 | editor.selection = new vscode.Selection(newPosition, newPosition); | ||
178 | }); | ||
179 | }; | 161 | }; |
180 | } | 162 | } |
181 | 163 | ||
diff --git a/editors/code/src/ctx.ts b/editors/code/src/ctx.ts index c07583cfa..bd023f803 100644 --- a/editors/code/src/ctx.ts +++ b/editors/code/src/ctx.ts | |||
@@ -5,7 +5,7 @@ import * as ra from './lsp_ext'; | |||
5 | import { Config } from './config'; | 5 | import { Config } from './config'; |
6 | import { createClient } from './client'; | 6 | import { createClient } from './client'; |
7 | import { isRustEditor, RustEditor } from './util'; | 7 | import { isRustEditor, RustEditor } from './util'; |
8 | import { Status } from './lsp_ext'; | 8 | import { ServerStatusParams } from './lsp_ext'; |
9 | 9 | ||
10 | export class Ctx { | 10 | export class Ctx { |
11 | private constructor( | 11 | private constructor( |
@@ -36,7 +36,7 @@ export class Ctx { | |||
36 | 36 | ||
37 | res.pushCleanup(client.start()); | 37 | res.pushCleanup(client.start()); |
38 | await client.onReady(); | 38 | await client.onReady(); |
39 | client.onNotification(ra.status, (params) => res.setStatus(params.status)); | 39 | client.onNotification(ra.serverStatus, (params) => res.setServerStatus(params)); |
40 | return res; | 40 | return res; |
41 | } | 41 | } |
42 | 42 | ||
@@ -66,39 +66,28 @@ export class Ctx { | |||
66 | return this.extCtx.subscriptions; | 66 | return this.extCtx.subscriptions; |
67 | } | 67 | } |
68 | 68 | ||
69 | setStatus(status: Status) { | 69 | setServerStatus(status: ServerStatusParams) { |
70 | switch (status) { | 70 | this.statusBar.tooltip = status.message ?? "Ready"; |
71 | case "loading": | 71 | let icon = ""; |
72 | this.statusBar.text = "$(sync~spin) rust-analyzer"; | 72 | switch (status.health) { |
73 | this.statusBar.tooltip = "Loading the project"; | 73 | case "ok": |
74 | this.statusBar.command = undefined; | ||
75 | this.statusBar.color = undefined; | 74 | this.statusBar.color = undefined; |
76 | break; | 75 | break; |
77 | case "readyPartial": | 76 | case "warning": |
78 | this.statusBar.text = "rust-analyzer"; | 77 | this.statusBar.tooltip += "\nClick to reload."; |
79 | this.statusBar.tooltip = "Ready (Partial)"; | ||
80 | this.statusBar.command = undefined; | ||
81 | this.statusBar.color = undefined; | ||
82 | break; | ||
83 | case "ready": | ||
84 | this.statusBar.text = "rust-analyzer"; | ||
85 | this.statusBar.tooltip = "Ready"; | ||
86 | this.statusBar.command = undefined; | ||
87 | this.statusBar.color = undefined; | ||
88 | break; | ||
89 | case "invalid": | ||
90 | this.statusBar.text = "$(error) rust-analyzer"; | ||
91 | this.statusBar.tooltip = "Failed to load the project"; | ||
92 | this.statusBar.command = undefined; | ||
93 | this.statusBar.color = new vscode.ThemeColor("notificationsErrorIcon.foreground"); | ||
94 | break; | ||
95 | case "needsReload": | ||
96 | this.statusBar.text = "$(warning) rust-analyzer"; | ||
97 | this.statusBar.tooltip = "Click to reload"; | ||
98 | this.statusBar.command = "rust-analyzer.reloadWorkspace"; | 78 | this.statusBar.command = "rust-analyzer.reloadWorkspace"; |
99 | this.statusBar.color = new vscode.ThemeColor("notificationsWarningIcon.foreground"); | 79 | this.statusBar.color = new vscode.ThemeColor("notificationsWarningIcon.foreground"); |
80 | icon = "$(warning) "; | ||
81 | break; | ||
82 | case "error": | ||
83 | this.statusBar.tooltip += "\nClick to reload."; | ||
84 | this.statusBar.command = "rust-analyzer.reloadWorkspace"; | ||
85 | this.statusBar.color = new vscode.ThemeColor("notificationsErrorIcon.foreground"); | ||
86 | icon = "$(error) "; | ||
100 | break; | 87 | break; |
101 | } | 88 | } |
89 | if (!status.quiescent) icon = "$(sync~spin) "; | ||
90 | this.statusBar.text = `${icon} rust-analyzer`; | ||
102 | } | 91 | } |
103 | 92 | ||
104 | pushCleanup(d: Disposable) { | 93 | pushCleanup(d: Disposable) { |
diff --git a/editors/code/src/lsp_ext.ts b/editors/code/src/lsp_ext.ts index 00e128b8c..f78de894b 100644 --- a/editors/code/src/lsp_ext.ts +++ b/editors/code/src/lsp_ext.ts | |||
@@ -10,11 +10,12 @@ export interface AnalyzerStatusParams { | |||
10 | export const analyzerStatus = new lc.RequestType<AnalyzerStatusParams, string, void>("rust-analyzer/analyzerStatus"); | 10 | export const analyzerStatus = new lc.RequestType<AnalyzerStatusParams, string, void>("rust-analyzer/analyzerStatus"); |
11 | export const memoryUsage = new lc.RequestType0<string, void>("rust-analyzer/memoryUsage"); | 11 | export const memoryUsage = new lc.RequestType0<string, void>("rust-analyzer/memoryUsage"); |
12 | 12 | ||
13 | export type Status = "loading" | "ready" | "readyPartial" | "invalid" | "needsReload"; | 13 | export interface ServerStatusParams { |
14 | export interface StatusParams { | 14 | health: "ok" | "warning" | "error"; |
15 | status: Status; | 15 | quiescent: boolean; |
16 | message?: string; | ||
16 | } | 17 | } |
17 | export const status = new lc.NotificationType<StatusParams>("rust-analyzer/status"); | 18 | export const serverStatus = new lc.NotificationType<ServerStatusParams>("experimental/serverStatus"); |
18 | 19 | ||
19 | export const reloadWorkspace = new lc.RequestType0<null, void>("rust-analyzer/reloadWorkspace"); | 20 | export const reloadWorkspace = new lc.RequestType0<null, void>("rust-analyzer/reloadWorkspace"); |
20 | 21 | ||
@@ -128,7 +129,7 @@ export interface OpenCargoTomlParams { | |||
128 | textDocument: lc.TextDocumentIdentifier; | 129 | textDocument: lc.TextDocumentIdentifier; |
129 | } | 130 | } |
130 | 131 | ||
131 | export const moveItem = new lc.RequestType<MoveItemParams, lc.TextDocumentEdit | void, void>("experimental/moveItem"); | 132 | export const moveItem = new lc.RequestType<MoveItemParams, lc.TextEdit[], void>("experimental/moveItem"); |
132 | 133 | ||
133 | export interface MoveItemParams { | 134 | export interface MoveItemParams { |
134 | textDocument: lc.TextDocumentIdentifier; | 135 | textDocument: lc.TextDocumentIdentifier; |
diff --git a/editors/code/src/snippets.ts b/editors/code/src/snippets.ts index dc53ebe2e..9561aa345 100644 --- a/editors/code/src/snippets.ts +++ b/editors/code/src/snippets.ts | |||
@@ -29,7 +29,7 @@ async function editorFromUri(uri: vscode.Uri): Promise<vscode.TextEditor | undef | |||
29 | } | 29 | } |
30 | 30 | ||
31 | export async function applySnippetTextEdits(editor: vscode.TextEditor, edits: vscode.TextEdit[]) { | 31 | export async function applySnippetTextEdits(editor: vscode.TextEditor, edits: vscode.TextEdit[]) { |
32 | let selection: vscode.Selection | undefined = undefined; | 32 | const selections: vscode.Selection[] = []; |
33 | let lineDelta = 0; | 33 | let lineDelta = 0; |
34 | await editor.edit((builder) => { | 34 | await editor.edit((builder) => { |
35 | for (const indel of edits) { | 35 | for (const indel of edits) { |
@@ -44,18 +44,18 @@ export async function applySnippetTextEdits(editor: vscode.TextEditor, edits: vs | |||
44 | indel.range.start.character + placeholderStart | 44 | indel.range.start.character + placeholderStart |
45 | : prefix.length - lastNewline - 1; | 45 | : prefix.length - lastNewline - 1; |
46 | const endColumn = startColumn + placeholderLength; | 46 | const endColumn = startColumn + placeholderLength; |
47 | selection = new vscode.Selection( | 47 | selections.push(new vscode.Selection( |
48 | new vscode.Position(startLine, startColumn), | 48 | new vscode.Position(startLine, startColumn), |
49 | new vscode.Position(startLine, endColumn), | 49 | new vscode.Position(startLine, endColumn), |
50 | ); | 50 | )); |
51 | builder.replace(indel.range, newText); | 51 | builder.replace(indel.range, newText); |
52 | } else { | 52 | } else { |
53 | lineDelta = countLines(indel.newText) - (indel.range.end.line - indel.range.start.line); | ||
54 | builder.replace(indel.range, indel.newText); | 53 | builder.replace(indel.range, indel.newText); |
55 | } | 54 | } |
55 | lineDelta = countLines(indel.newText) - (indel.range.end.line - indel.range.start.line); | ||
56 | } | 56 | } |
57 | }); | 57 | }); |
58 | if (selection) editor.selection = selection; | 58 | if (selections.length > 0) editor.selections = selections; |
59 | } | 59 | } |
60 | 60 | ||
61 | function parseSnippet(snip: string): [string, [number, number]] | undefined { | 61 | function parseSnippet(snip: string): [string, [number, number]] | undefined { |