lean4monaco 1.1.3 → 1.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. package/README.md +2 -4
  2. package/dist/vscode-lean4/vscode-lean4/src/utils/depInstaller.d.ts +81 -0
  3. package/dist/vscode-lean4/vscode-lean4/src/utils/depInstaller.js +372 -0
  4. package/package.json +1 -1
  5. package/dist/JuliaMono-Regular.ttf +0 -0
  6. package/dist/lean4-infoview/codicon.ttf +0 -0
  7. package/dist/lean4-infoview/esm-shims/react-dom.d.ts +0 -5
  8. package/dist/lean4-infoview/esm-shims/react-jsx-runtime.d.ts +0 -5
  9. package/dist/lean4-infoview/esm-shims/react.d.ts +0 -5
  10. package/dist/lean4-infoview/index.css +0 -4161
  11. package/dist/lean4-infoview/index.d.ts +0 -16
  12. package/dist/lean4-infoview/index.development.js +0 -37312
  13. package/dist/lean4-infoview/index.production.min.js +0 -1528
  14. package/dist/lean4-infoview/infoview/collapsing.d.ts +0 -12
  15. package/dist/lean4-infoview/infoview/contexts.d.ts +0 -10
  16. package/dist/lean4-infoview/infoview/editorConnection.d.ts +0 -22
  17. package/dist/lean4-infoview/infoview/errors.d.ts +0 -14
  18. package/dist/lean4-infoview/infoview/event.d.ts +0 -33
  19. package/dist/lean4-infoview/infoview/goalLocation.d.ts +0 -61
  20. package/dist/lean4-infoview/infoview/goals.d.ts +0 -46
  21. package/dist/lean4-infoview/infoview/info.d.ts +0 -18
  22. package/dist/lean4-infoview/infoview/infos.d.ts +0 -2
  23. package/dist/lean4-infoview/infoview/interactiveCode.d.ts +0 -19
  24. package/dist/lean4-infoview/infoview/main.d.ts +0 -13
  25. package/dist/lean4-infoview/infoview/messages.d.ts +0 -19
  26. package/dist/lean4-infoview/infoview/rpcSessions.d.ts +0 -11
  27. package/dist/lean4-infoview/infoview/serverVersion.d.ts +0 -10
  28. package/dist/lean4-infoview/infoview/tooltips.d.ts +0 -32
  29. package/dist/lean4-infoview/infoview/traceExplorer.d.ts +0 -11
  30. package/dist/lean4-infoview/infoview/userWidget.d.ts +0 -39
  31. package/dist/lean4-infoview/infoview/util.d.ts +0 -144
  32. package/dist/lean4-infoview/loader.d.ts +0 -20
  33. package/dist/lean4-infoview/loader.development.js +0 -1006
  34. package/dist/lean4-infoview/loader.production.min.js +0 -1
  35. package/dist/lean4-infoview/react-dom.development.js +0 -30537
  36. package/dist/lean4-infoview/react-dom.production.min.js +0 -21
  37. package/dist/lean4-infoview/react-jsx-runtime.development.js +0 -1362
  38. package/dist/lean4-infoview/react-jsx-runtime.production.min.js +0 -1
  39. package/dist/lean4-infoview/react.development.js +0 -2823
  40. package/dist/lean4-infoview/react.production.min.js +0 -1
  41. package/dist/monaco-lean4/vscode-lean4/package.json +0 -944
  42. package/dist/monaco-lean4/vscode-lean4/src/abbreviation/AbbreviationFeature.d.ts +0 -9
  43. package/dist/monaco-lean4/vscode-lean4/src/abbreviation/AbbreviationFeature.js +0 -20
  44. package/dist/monaco-lean4/vscode-lean4/src/abbreviation/AbbreviationHoverProvider.d.ts +0 -12
  45. package/dist/monaco-lean4/vscode-lean4/src/abbreviation/AbbreviationHoverProvider.js +0 -40
  46. package/dist/monaco-lean4/vscode-lean4/src/abbreviation/AbbreviationRewriterFeature.d.ts +0 -20
  47. package/dist/monaco-lean4/vscode-lean4/src/abbreviation/AbbreviationRewriterFeature.js +0 -79
  48. package/dist/monaco-lean4/vscode-lean4/src/abbreviation/VSCodeAbbreviationConfig.d.ts +0 -13
  49. package/dist/monaco-lean4/vscode-lean4/src/abbreviation/VSCodeAbbreviationConfig.js +0 -29
  50. package/dist/monaco-lean4/vscode-lean4/src/abbreviation/VSCodeAbbreviationRewriter.d.ts +0 -28
  51. package/dist/monaco-lean4/vscode-lean4/src/abbreviation/VSCodeAbbreviationRewriter.js +0 -124
  52. package/dist/monaco-lean4/vscode-lean4/src/config.d.ts +0 -33
  53. package/dist/monaco-lean4/vscode-lean4/src/config.js +0 -119
  54. package/dist/monaco-lean4/vscode-lean4/src/diagnostics/setupNotifs.d.ts +0 -27
  55. package/dist/monaco-lean4/vscode-lean4/src/diagnostics/setupNotifs.js +0 -133
  56. package/dist/monaco-lean4/vscode-lean4/src/infoview.d.ts +0 -69
  57. package/dist/monaco-lean4/vscode-lean4/src/infoview.js +0 -711
  58. package/dist/monaco-lean4/vscode-lean4/src/leanclient.d.ts +0 -67
  59. package/dist/monaco-lean4/vscode-lean4/src/leanclient.js +0 -443
  60. package/dist/monaco-lean4/vscode-lean4/src/rpc.d.ts +0 -16
  61. package/dist/monaco-lean4/vscode-lean4/src/rpc.js +0 -102
  62. package/dist/monaco-lean4/vscode-lean4/src/taskgutter.d.ts +0 -11
  63. package/dist/monaco-lean4/vscode-lean4/src/taskgutter.js +0 -130
  64. package/dist/monaco-lean4/vscode-lean4/src/utils/batch.d.ts +0 -37
  65. package/dist/monaco-lean4/vscode-lean4/src/utils/batch.js +0 -203
  66. package/dist/monaco-lean4/vscode-lean4/src/utils/clientProvider.d.ts +0 -41
  67. package/dist/monaco-lean4/vscode-lean4/src/utils/clientProvider.js +0 -205
  68. package/dist/monaco-lean4/vscode-lean4/src/utils/converters.d.ts +0 -16
  69. package/dist/monaco-lean4/vscode-lean4/src/utils/converters.js +0 -129
  70. package/dist/monaco-lean4/vscode-lean4/src/utils/elan.d.ts +0 -3
  71. package/dist/monaco-lean4/vscode-lean4/src/utils/elan.js +0 -4
  72. package/dist/monaco-lean4/vscode-lean4/src/utils/envPath.d.ts +0 -21
  73. package/dist/monaco-lean4/vscode-lean4/src/utils/envPath.js +0 -53
  74. package/dist/monaco-lean4/vscode-lean4/src/utils/exturi.d.ts +0 -35
  75. package/dist/monaco-lean4/vscode-lean4/src/utils/exturi.js +0 -136
  76. package/dist/monaco-lean4/vscode-lean4/src/utils/fsHelper.d.ts +0 -17
  77. package/dist/monaco-lean4/vscode-lean4/src/utils/fsHelper.js +0 -36
  78. package/dist/monaco-lean4/vscode-lean4/src/utils/leanInstaller.d.ts +0 -37
  79. package/dist/monaco-lean4/vscode-lean4/src/utils/leanInstaller.js +0 -210
  80. package/dist/monaco-lean4/vscode-lean4/src/utils/logger.d.ts +0 -7
  81. package/dist/monaco-lean4/vscode-lean4/src/utils/logger.js +0 -20
  82. package/dist/monaco-lean4/vscode-lean4/src/utils/notifs.d.ts +0 -24
  83. package/dist/monaco-lean4/vscode-lean4/src/utils/notifs.js +0 -110
  84. package/dist/monaco-lean4/vscode-lean4/src/utils/projectInfo.d.ts +0 -9
  85. package/dist/monaco-lean4/vscode-lean4/src/utils/projectInfo.js +0 -125
  86. package/dist/useragent.d.ts +0 -1
  87. package/dist/useragent.js +0 -31
  88. package/dist/vscode.css +0 -7
@@ -1,130 +0,0 @@
1
- import { LeanFileProgressKind } from '@leanprover/infoview-api';
2
- import { OverviewRulerLane, Range, window } from 'vscode';
3
- class LeanFileTaskGutter {
4
- uri;
5
- decorations;
6
- processed;
7
- timeout;
8
- constructor(uri, decorations, processed) {
9
- this.uri = uri;
10
- this.decorations = decorations;
11
- this.processed = processed;
12
- this.schedule(100);
13
- }
14
- setProcessed(processed) {
15
- if (processed === this.processed)
16
- return;
17
- const oldProcessed = this.processed;
18
- this.processed = processed;
19
- if (processed === undefined) {
20
- this.processed = [];
21
- this.clearTimeout();
22
- this.updateDecos();
23
- }
24
- else if (this.timeout === undefined) {
25
- this.schedule(oldProcessed === undefined ? 500 : 20);
26
- }
27
- }
28
- schedule(ms) {
29
- this.timeout = setTimeout(() => {
30
- this.timeout = undefined;
31
- this.updateDecos();
32
- }, ms);
33
- }
34
- clearTimeout() {
35
- if (this.timeout !== undefined) {
36
- clearTimeout(this.timeout);
37
- this.timeout = undefined;
38
- }
39
- }
40
- updateDecos() {
41
- for (const editor of window.visibleTextEditors) {
42
- if (editor.document.uri.toString() === this.uri) {
43
- for (const [kind, [decoration, message]] of this.decorations) {
44
- editor.setDecorations(decoration, this.processed
45
- .filter(info => (info.kind === undefined ? LeanFileProgressKind.Processing : info.kind) === kind)
46
- .map(info => ({
47
- range: new Range(info.range.start.line, 0, info.range.end.line, 0),
48
- hoverMessage: message,
49
- })));
50
- }
51
- }
52
- }
53
- }
54
- dispose() {
55
- this.clearTimeout();
56
- }
57
- }
58
- export class LeanTaskGutter {
59
- decorations = new Map();
60
- status = {};
61
- gutters = {};
62
- subscriptions = [];
63
- constructor(client, context) {
64
- this.decorations.set(LeanFileProgressKind.Processing, [
65
- window.createTextEditorDecorationType({
66
- overviewRulerLane: OverviewRulerLane.Left,
67
- overviewRulerColor: 'rgba(255, 165, 0, 0.5)',
68
- dark: {
69
- gutterIconPath: context.asAbsolutePath('media/progress-dark.svg'),
70
- },
71
- light: {
72
- gutterIconPath: context.asAbsolutePath('media/progress-light.svg'),
73
- },
74
- gutterIconSize: 'contain',
75
- }),
76
- 'busily processing...',
77
- ]);
78
- this.decorations.set(LeanFileProgressKind.FatalError, [
79
- window.createTextEditorDecorationType({
80
- overviewRulerLane: OverviewRulerLane.Left,
81
- overviewRulerColor: 'rgba(255, 0, 0, 0.5)',
82
- dark: {
83
- gutterIconPath: context.asAbsolutePath('media/progress-error-dark.svg'),
84
- },
85
- light: {
86
- gutterIconPath: context.asAbsolutePath('media/progress-error-light.svg'),
87
- },
88
- gutterIconSize: 'contain',
89
- }),
90
- 'processing stopped',
91
- ]);
92
- this.subscriptions.push(window.onDidChangeVisibleTextEditors(() => this.updateDecos()), client.progressChanged(([uri, processing]) => {
93
- this.status[uri] = processing;
94
- this.updateDecos();
95
- }));
96
- }
97
- updateDecos() {
98
- const uris = {};
99
- for (const editor of window.visibleTextEditors) {
100
- if (editor.document.languageId !== 'lean4')
101
- continue;
102
- const uri = editor.document.uri.toString();
103
- uris[uri] = true;
104
- const processed = uri in this.status ? this.status[uri] : [];
105
- if (this.gutters[uri]) {
106
- const gutter = this.gutters[uri];
107
- if (gutter)
108
- gutter.setProcessed(processed);
109
- }
110
- else {
111
- this.gutters[uri] = new LeanFileTaskGutter(uri, this.decorations, processed);
112
- }
113
- }
114
- for (const uri of Object.getOwnPropertyNames(this.gutters)) {
115
- if (!uris[uri]) {
116
- this.gutters[uri]?.dispose();
117
- this.gutters[uri] = undefined;
118
- // TODO: also clear this.status for this uri ?
119
- }
120
- }
121
- }
122
- dispose() {
123
- for (const [decoration, _message] of this.decorations.values()) {
124
- decoration.dispose();
125
- }
126
- for (const s of this.subscriptions) {
127
- s.dispose();
128
- }
129
- }
130
- }
@@ -1,37 +0,0 @@
1
- /// <reference types="node" />
2
- import { ChildProcessWithoutNullStreams } from 'child_process';
3
- import { OutputChannel } from 'vscode';
4
- export interface ExecutionChannel {
5
- combined?: OutputChannel | undefined;
6
- stdout?: OutputChannel | undefined;
7
- stderr?: OutputChannel | undefined;
8
- }
9
- export declare enum ExecutionExitCode {
10
- Success = 0,
11
- CannotLaunch = 1,
12
- ExecutionError = 2,
13
- Cancelled = 3
14
- }
15
- export interface ExecutionResult {
16
- exitCode: ExecutionExitCode;
17
- stdout: string;
18
- stderr: string;
19
- combined: string;
20
- }
21
- export declare function batchExecuteWithProc(executablePath: string, args: string[], workingDirectory?: string | undefined, channel?: ExecutionChannel | undefined): [ChildProcessWithoutNullStreams | 'CannotLaunch', Promise<ExecutionResult>];
22
- export declare function batchExecute(executablePath: string, args: string[], workingDirectory?: string | undefined, channel?: ExecutionChannel | undefined): Promise<ExecutionResult>;
23
- interface ProgressExecutionOptions {
24
- cwd?: string | undefined;
25
- channel?: OutputChannel | undefined;
26
- translator?: ((line: string) => string | undefined) | undefined;
27
- allowCancellation?: boolean;
28
- }
29
- export declare function batchExecuteWithProgress(executablePath: string, args: string[], title: string, options?: ProgressExecutionOptions): Promise<ExecutionResult>;
30
- type ExecutionHandler = () => Promise<ExecutionResult>;
31
- export interface BatchExecution {
32
- execute: ExecutionHandler;
33
- optional?: boolean | undefined;
34
- }
35
- export declare function executeAll(executions: BatchExecution[]): Promise<ExecutionResult[]>;
36
- export declare function displayResultError(result: ExecutionResult, message: string): void;
37
- export {};
@@ -1,203 +0,0 @@
1
- import { spawn } from 'child_process';
2
- import { ProgressLocation, window } from 'vscode';
3
- import { logger } from './logger';
4
- import { displayErrorWithOutput } from './notifs';
5
- export var ExecutionExitCode;
6
- (function (ExecutionExitCode) {
7
- ExecutionExitCode[ExecutionExitCode["Success"] = 0] = "Success";
8
- ExecutionExitCode[ExecutionExitCode["CannotLaunch"] = 1] = "CannotLaunch";
9
- ExecutionExitCode[ExecutionExitCode["ExecutionError"] = 2] = "ExecutionError";
10
- ExecutionExitCode[ExecutionExitCode["Cancelled"] = 3] = "Cancelled";
11
- })(ExecutionExitCode || (ExecutionExitCode = {}));
12
- function createCannotLaunchExecutionResult(message) {
13
- return {
14
- exitCode: ExecutionExitCode.CannotLaunch,
15
- stdout: message,
16
- stderr: '',
17
- combined: message,
18
- };
19
- }
20
- export function batchExecuteWithProc(executablePath, args, workingDirectory, channel) {
21
- let stdout = '';
22
- let stderr = '';
23
- let combined = '';
24
- let options = {};
25
- if (workingDirectory !== undefined) {
26
- options = { cwd: workingDirectory };
27
- }
28
- if (channel?.combined) {
29
- const formattedCwd = workingDirectory ? `${workingDirectory}` : '';
30
- const formattedArgs = args.map(arg => (arg.includes(' ') ? `"${arg}"` : arg)).join(' ');
31
- channel.combined.appendLine(`${formattedCwd}> ${executablePath} ${formattedArgs}`);
32
- }
33
- let proc;
34
- try {
35
- proc = spawn(executablePath, args, options);
36
- }
37
- catch (e) {
38
- return ['CannotLaunch', new Promise(resolve => resolve(createCannotLaunchExecutionResult('')))];
39
- }
40
- const execPromise = new Promise(resolve => {
41
- const conclude = (r) => resolve({
42
- exitCode: r.exitCode,
43
- stdout: r.stdout.trim(),
44
- stderr: r.stderr.trim(),
45
- combined: r.combined.trim(),
46
- });
47
- proc.on('error', err => {
48
- conclude(createCannotLaunchExecutionResult(err.message));
49
- });
50
- proc.stdout.on('data', line => {
51
- const s = line.toString();
52
- if (channel?.combined)
53
- channel.combined.appendLine(s);
54
- if (channel?.stdout)
55
- channel.stdout.appendLine(s);
56
- stdout += s + '\n';
57
- combined += s + '\n';
58
- });
59
- proc.stderr.on('data', line => {
60
- const s = line.toString();
61
- if (channel?.combined)
62
- channel.combined.appendLine(s);
63
- if (channel?.stderr)
64
- channel.stderr.appendLine(s);
65
- stderr += s + '\n';
66
- combined += s + '\n';
67
- });
68
- proc.on('close', (code, signal) => {
69
- logger.log(`child process exited with code ${code}`);
70
- if (signal === 'SIGTERM') {
71
- if (channel?.combined) {
72
- channel.combined.appendLine('=> Operation cancelled by user.');
73
- }
74
- conclude({
75
- exitCode: ExecutionExitCode.Cancelled,
76
- stdout,
77
- stderr,
78
- combined,
79
- });
80
- return;
81
- }
82
- if (code !== 0) {
83
- if (channel?.combined) {
84
- const formattedCode = code ? `Exit code: ${code}.` : '';
85
- const formattedSignal = signal ? `Signal: ${signal}.` : '';
86
- channel.combined.appendLine(`=> Operation failed. ${formattedCode} ${formattedSignal}`.trim());
87
- }
88
- conclude({
89
- exitCode: ExecutionExitCode.ExecutionError,
90
- stdout,
91
- stderr,
92
- combined,
93
- });
94
- return;
95
- }
96
- conclude({
97
- exitCode: ExecutionExitCode.Success,
98
- stdout,
99
- stderr,
100
- combined,
101
- });
102
- });
103
- });
104
- return [proc, execPromise];
105
- }
106
- export async function batchExecute(executablePath, args, workingDirectory, channel) {
107
- const [_, execPromise] = batchExecuteWithProc(executablePath, args, workingDirectory, channel);
108
- return execPromise;
109
- }
110
- export async function batchExecuteWithProgress(executablePath, args, title, options = {}) {
111
- const titleSuffix = options.channel ? ' [(Details)](command:lean4.troubleshooting.showOutput)' : '';
112
- const progressOptions = {
113
- location: ProgressLocation.Notification,
114
- title: title + titleSuffix,
115
- cancellable: options.allowCancellation === true,
116
- };
117
- let inc = 0;
118
- let lastReportedMessage;
119
- let progress;
120
- const progressChannel = {
121
- name: 'ProgressChannel',
122
- append(value) {
123
- if (options.translator) {
124
- const translatedValue = options.translator(value);
125
- if (translatedValue === undefined) {
126
- return;
127
- }
128
- value = translatedValue;
129
- }
130
- if (options.channel) {
131
- options.channel.appendLine(value.trimEnd());
132
- }
133
- if (inc < 90) {
134
- inc += 2;
135
- }
136
- if (progress !== undefined) {
137
- progress.report({ increment: inc, message: value });
138
- }
139
- lastReportedMessage = value;
140
- },
141
- appendLine(value) {
142
- this.append(value + '\n');
143
- },
144
- replace(_) {
145
- /* empty */
146
- },
147
- clear() {
148
- /* empty */
149
- },
150
- show() {
151
- /* empty */
152
- },
153
- hide() {
154
- /* empty */
155
- },
156
- dispose() {
157
- /* empty */
158
- },
159
- };
160
- const expensiveExecutionTimeoutPromise = new Promise((resolve, _) => setTimeout(() => resolve(undefined), 250));
161
- const [proc, executionPromise] = batchExecuteWithProc(executablePath, args, options.cwd, {
162
- combined: progressChannel,
163
- });
164
- if (proc === 'CannotLaunch') {
165
- return executionPromise; // resolves to a 'CannotLaunch' ExecutionResult
166
- }
167
- const preliminaryResult = await Promise.race([expensiveExecutionTimeoutPromise, executionPromise]);
168
- if (preliminaryResult !== undefined) {
169
- return preliminaryResult;
170
- }
171
- // Execution already took longer than 250ms, let's start displaying a progress bar now
172
- const result = await window.withProgress(progressOptions, (p, token) => {
173
- progress = p;
174
- token.onCancellationRequested(() => proc.kill());
175
- progress.report({ message: lastReportedMessage, increment: inc });
176
- return executionPromise;
177
- });
178
- return result;
179
- }
180
- export async function executeAll(executions) {
181
- const results = [];
182
- for (const execution of executions) {
183
- const result = await execution.execute();
184
- results.push(result);
185
- if (execution.optional !== true && result.exitCode !== ExecutionExitCode.Success) {
186
- break;
187
- }
188
- }
189
- return results;
190
- }
191
- export function displayResultError(result, message) {
192
- if (result.exitCode === ExecutionExitCode.Success) {
193
- throw Error();
194
- }
195
- const errorMessage = formatErrorMessage(result, message);
196
- displayErrorWithOutput(errorMessage);
197
- }
198
- function formatErrorMessage(error, message) {
199
- if (error.combined === '') {
200
- return `${message}`;
201
- }
202
- return `${message} Command output: ${error.combined}`;
203
- }
@@ -1,41 +0,0 @@
1
- import { LeanFileProgressProcessingInfo, ServerStoppedReason } from '@leanprover/infoview-api';
2
- import { Disposable, OutputChannel, TextDocument } from 'vscode';
3
- import { PreconditionCheckResult } from '../diagnostics/setupNotifs';
4
- import { LeanClient } from '../leanclient';
5
- import { ExtUri } from './exturi';
6
- import { LeanInstaller } from './leanInstaller';
7
- import { BaseLanguageClient, LanguageClientOptions } from 'vscode-languageclient/node';
8
- export declare class LeanClientProvider implements Disposable {
9
- private setupClient;
10
- private checkLean4ProjectPreconditions;
11
- private isOpenLeanDocument;
12
- private subscriptions;
13
- private outputChannel;
14
- private installer;
15
- private clients;
16
- private pending;
17
- private pendingInstallChanged;
18
- private processingInstallChanged;
19
- private activeClient;
20
- private progressChangedEmitter;
21
- progressChanged: import("vscode").Event<[string, LeanFileProgressProcessingInfo[]]>;
22
- private clientAddedEmitter;
23
- clientAdded: import("vscode").Event<LeanClient>;
24
- private clientRemovedEmitter;
25
- clientRemoved: import("vscode").Event<LeanClient>;
26
- private clientStoppedEmitter;
27
- clientStopped: import("vscode").Event<[LeanClient, boolean, ServerStoppedReason]>;
28
- constructor(installer: LeanInstaller, outputChannel: OutputChannel, setupClient: (clientOptions: LanguageClientOptions, folderUri: ExtUri, elanDefaultToolchain: string) => Promise<BaseLanguageClient>, checkLean4ProjectPreconditions: (channel: OutputChannel, folderUri: ExtUri) => Promise<PreconditionCheckResult>, isOpenLeanDocument: (docUri: ExtUri) => boolean);
29
- getActiveClient(): LeanClient | undefined;
30
- private onInstallChanged;
31
- private restartFile;
32
- private stopActiveClient;
33
- private restartActiveClient;
34
- clientIsStarted(): void;
35
- didOpenEditor(document: TextDocument): Promise<void>;
36
- findClient(path: ExtUri): LeanClient | undefined;
37
- getClients(): LeanClient[];
38
- getClientForFolder(folder: ExtUri): LeanClient | undefined;
39
- ensureClient(uri: ExtUri): Promise<[boolean, LeanClient | undefined]>;
40
- dispose(): void;
41
- }
@@ -1,205 +0,0 @@
1
- import { EventEmitter, commands, window, workspace } from 'vscode';
2
- import { LeanClient } from '../leanclient';
3
- import { UntitledUri, getWorkspaceFolderUri, toExtUri } from './exturi';
4
- import { logger } from './logger';
5
- import { displayError } from './notifs';
6
- import { findLeanProjectRoot } from './projectInfo';
7
- // This class ensures we have one LeanClient per folder.
8
- export class LeanClientProvider {
9
- setupClient;
10
- checkLean4ProjectPreconditions;
11
- isOpenLeanDocument;
12
- subscriptions = [];
13
- outputChannel;
14
- installer;
15
- clients = new Map();
16
- pending = new Map();
17
- pendingInstallChanged = [];
18
- processingInstallChanged = false;
19
- activeClient = undefined;
20
- progressChangedEmitter = new EventEmitter();
21
- progressChanged = this.progressChangedEmitter.event;
22
- clientAddedEmitter = new EventEmitter();
23
- clientAdded = this.clientAddedEmitter.event;
24
- clientRemovedEmitter = new EventEmitter();
25
- clientRemoved = this.clientRemovedEmitter.event;
26
- clientStoppedEmitter = new EventEmitter();
27
- clientStopped = this.clientStoppedEmitter.event;
28
- constructor(installer, outputChannel, setupClient, checkLean4ProjectPreconditions, isOpenLeanDocument) {
29
- this.setupClient = setupClient;
30
- this.checkLean4ProjectPreconditions = checkLean4ProjectPreconditions;
31
- this.isOpenLeanDocument = isOpenLeanDocument;
32
- this.outputChannel = outputChannel;
33
- this.installer = installer;
34
- // we must setup the installChanged event handler first before any didOpenEditor calls.
35
- this.subscriptions.push(installer.installChanged(async (uri) => await this.onInstallChanged(uri)));
36
- window.visibleTextEditors.forEach(e => this.didOpenEditor(e.document));
37
- this.subscriptions.push(window.onDidChangeActiveTextEditor(async (e) => {
38
- if (!e) {
39
- return;
40
- }
41
- await this.didOpenEditor(e.document);
42
- }));
43
- this.subscriptions.push(commands.registerCommand('lean4.restartFile', () => this.restartFile()), commands.registerCommand('lean4.refreshFileDependencies', () => this.restartFile()), commands.registerCommand('lean4.restartServer', () => this.restartActiveClient()), commands.registerCommand('lean4.stopServer', () => this.stopActiveClient()));
44
- this.subscriptions.push(workspace.onDidOpenTextDocument(document => this.didOpenEditor(document)));
45
- this.subscriptions.push(workspace.onDidChangeWorkspaceFolders(event => {
46
- // Remove all clients that are not referenced by any folder anymore
47
- if (event.removed.length === 0) {
48
- return;
49
- }
50
- this.clients.forEach((client, key) => {
51
- if (client.folderUri.scheme === 'untitled' || getWorkspaceFolderUri(client.folderUri)) {
52
- return;
53
- }
54
- logger.log(`[ClientProvider] onDidChangeWorkspaceFolders removing client for ${key}`);
55
- this.clients.delete(key);
56
- client.dispose();
57
- this.clientRemovedEmitter.fire(client);
58
- });
59
- }));
60
- }
61
- getActiveClient() {
62
- return this.activeClient;
63
- }
64
- async onInstallChanged(uri) {
65
- // Uri is a package Uri in the case a lean package file was changed.
66
- logger.log(`[ClientProvider] installChanged for ${uri}`);
67
- this.pendingInstallChanged.push(uri);
68
- if (this.processingInstallChanged) {
69
- // avoid re-entrancy.
70
- return;
71
- }
72
- this.processingInstallChanged = true;
73
- while (true) {
74
- const uri = this.pendingInstallChanged.pop();
75
- if (!uri) {
76
- break;
77
- }
78
- try {
79
- const projectUri = await findLeanProjectRoot(uri);
80
- const preconditionCheckResult = await this.checkLean4ProjectPreconditions(this.outputChannel, projectUri);
81
- if (preconditionCheckResult !== 'Fatal') {
82
- logger.log('[ClientProvider] got lean version 4');
83
- const [cached, client] = await this.ensureClient(uri);
84
- if (cached && client) {
85
- await client.restart();
86
- logger.log('[ClientProvider] restart complete');
87
- }
88
- }
89
- }
90
- catch (e) {
91
- logger.log(`[ClientProvider] Exception checking lean version: ${e}`);
92
- }
93
- }
94
- this.processingInstallChanged = false;
95
- }
96
- restartFile() {
97
- if (!this.activeClient || !this.activeClient.isRunning()) {
98
- displayError('No active client.');
99
- return;
100
- }
101
- if (!window.activeTextEditor || window.activeTextEditor.document.languageId !== 'lean4') {
102
- displayError('No active Lean editor tab. Make sure to focus the Lean editor tab for which you want to issue a restart.');
103
- return;
104
- }
105
- void this.activeClient.restartFile(window.activeTextEditor.document);
106
- }
107
- stopActiveClient() {
108
- if (this.activeClient && this.activeClient.isStarted()) {
109
- void this.activeClient?.stop();
110
- }
111
- }
112
- async restartActiveClient() {
113
- void this.activeClient?.restart();
114
- }
115
- clientIsStarted() {
116
- void this.activeClient?.isStarted();
117
- }
118
- async didOpenEditor(document) {
119
- // bail as quickly as possible on non-lean files.
120
- if (document.languageId !== 'lean4') {
121
- return;
122
- }
123
- const uri = toExtUri(document.uri);
124
- if (uri === undefined) {
125
- return;
126
- }
127
- await this.ensureClient(uri);
128
- }
129
- // Find the client for a given document.
130
- findClient(path) {
131
- const candidates = this.getClients().filter(client => client.isInFolderManagedByThisClient(path));
132
- // All candidate folders are a prefix of `path`, so they must necessarily be prefixes of one another
133
- // => the best candidate (the most top-level client folder) is just the one with the shortest path
134
- let bestCandidate;
135
- for (const candidate of candidates) {
136
- if (!bestCandidate) {
137
- bestCandidate = candidate;
138
- continue;
139
- }
140
- const folder = candidate.getClientFolder();
141
- const bestFolder = bestCandidate.getClientFolder();
142
- if (folder.scheme === 'file' &&
143
- bestFolder.scheme === 'file' &&
144
- folder.fsPath.length < bestFolder.fsPath.length) {
145
- bestCandidate = candidate;
146
- }
147
- }
148
- return bestCandidate;
149
- }
150
- getClients() {
151
- return Array.from(this.clients.values());
152
- }
153
- getClientForFolder(folder) {
154
- return this.clients.get(folder.toString());
155
- }
156
- // Starts a LeanClient if the given file is in a new workspace we haven't seen before.
157
- // Returns a boolean "true" if the LeanClient was already created.
158
- // Returns a null client if it turns out the new workspace is a lean3 workspace.
159
- async ensureClient(uri) {
160
- const folderUri = uri.scheme === 'file' ? await findLeanProjectRoot(uri) : new UntitledUri();
161
- let client = this.getClientForFolder(folderUri);
162
- if (client) {
163
- this.activeClient = client;
164
- return [true, client];
165
- }
166
- const key = folderUri.toString();
167
- if (this.pending.has(key)) {
168
- return [false, undefined];
169
- }
170
- this.pending.set(key, true);
171
- const preconditionCheckResult = await this.checkLean4ProjectPreconditions(this.outputChannel, folderUri);
172
- if (preconditionCheckResult === 'Fatal') {
173
- this.pending.delete(key);
174
- return [false, undefined];
175
- }
176
- logger.log('[ClientProvider] Creating LeanClient for ' + folderUri.toString());
177
- const elanDefaultToolchain = await this.installer.getElanDefaultToolchain(folderUri);
178
- client = new LeanClient(folderUri, this.outputChannel, elanDefaultToolchain, this.setupClient, this.isOpenLeanDocument);
179
- this.subscriptions.push(client);
180
- this.clients.set(key, client);
181
- client.serverFailed(err => {
182
- this.clients.delete(key);
183
- client.dispose();
184
- displayError(err);
185
- });
186
- client.stopped(reason => {
187
- this.clientStoppedEmitter.fire([client, client === this.activeClient, reason]);
188
- });
189
- // aggregate progress changed events.
190
- client.progressChanged(arg => {
191
- this.progressChangedEmitter.fire(arg);
192
- });
193
- this.pending.delete(key);
194
- this.clientAddedEmitter.fire(client);
195
- await client.start();
196
- // tell the InfoView about this activated client.
197
- this.activeClient = client;
198
- return [false, client];
199
- }
200
- dispose() {
201
- for (const s of this.subscriptions) {
202
- s.dispose();
203
- }
204
- }
205
- }
@@ -1,16 +0,0 @@
1
- /**
2
- * For LSP communication, we need a way to translate between LSP types and corresponding VSCode types.
3
- * By default this translation is provided as a bunch of methods on a `LanguageClient`, but this is
4
- * awkward to use in multi-client workspaces wherein we need to look up specific clients. In fact the
5
- * conversions are *not* stateful, so having them depend on the client is unnecessary. Instead, we
6
- * provide global converters here.
7
- *
8
- * Some of the conversions are patched to support extended Lean-specific structures.
9
- *
10
- * @module
11
- */
12
- import { Code2ProtocolConverter, DidOpenTextDocumentParams, Protocol2CodeConverter } from 'vscode-languageclient';
13
- export declare function setDependencyBuildMode(params: DidOpenTextDocumentParams, dependencyBuildMode: 'once' | 'never'): DidOpenTextDocumentParams;
14
- export declare const p2cConverter: Protocol2CodeConverter;
15
- export declare const c2pConverter: Code2ProtocolConverter;
16
- export declare function patchConverters(p2cConverter: Protocol2CodeConverter, c2pConverter: Code2ProtocolConverter): void;