lean4monaco 1.0.27 → 1.0.29

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.
package/README.md CHANGED
@@ -136,7 +136,10 @@ export default {
136
136
 
137
137
  `lean4monaco` contains a sample project `lean4monaco/demo/` which you can use for comparison.
138
138
 
139
- If you cloned `lean4monaco`, you can run the demo with
139
+ Ideally you clone this repo using `git clone --recurse-submodules <ssh/https address>` to load the included submodule.
140
+ (alternatively, call `git submodule init && git submodule update` inside the cloned the repo).
141
+
142
+ Afterwards, you can run the demo with
140
143
 
141
144
  ```
142
145
  cd lean4monaco
@@ -160,4 +163,4 @@ Some random errors we encountered. If you have more, please share them.
160
163
  ### Warnings on `npm install`
161
164
 
162
165
  * Warnings about `glob` and `inflight` come from `copyfiles`: see [copyfiles#132](https://github.com/calvinmetcalf/copyfiles/pull/132)
163
- * Warning about ` @types/cypress` comes from `cypress-iframe`
166
+ * Warning about ` @types/cypress` comes from `cypress-iframe`
package/dist/editor.js CHANGED
@@ -20,7 +20,7 @@ export class LeanMonacoEditor {
20
20
  // Note: looks like setting options here prevents them from being overwritten later.
21
21
  // TODO: Looks like these options cannot be set in `updateVSCodeOptions` in `leanmonaco.ts`
22
22
  // so we set them here
23
- contextmenu: false, // the context menu breaks mobile support.
23
+ contextmenu: true, // the context menu breaks mobile support.
24
24
  lineNumbersMinChars: 1, // minimal no. of characters for line numbers
25
25
  lineDecorationsWidth: 5, // distance (px) between line number and code.
26
26
  });
@@ -102,7 +102,7 @@ export class LeanMonaco {
102
102
  testLeanVersion: () => { return "lean4/stable"; },
103
103
  getElanDefaultToolchain: () => { return "lean4/stable"; }
104
104
  }, { appendLine: () => { }
105
- }, setupMonacoClient(this.getWebSocketOptions(options)), checkLean4ProjectPreconditions);
105
+ }, checkLean4ProjectPreconditions, setupMonacoClient(this.getWebSocketOptions(options)));
106
106
  const asAbsolutePath = (path) => {
107
107
  switch (path) {
108
108
  // url.pathToFileURL
@@ -181,7 +181,7 @@ export class LeanMonaco {
181
181
  ...packageJson,
182
182
  contributes: {
183
183
  ...packageJson.contributes,
184
- configuration: packageJson.contributes.configuration,
184
+ configuration: packageJson.contributes.configuration, // Apparently `IExtensionContributions.configuration` has type `any`
185
185
  // TODO: This is suspect, the thrid entry does not have "language", yet it doesn't complain
186
186
  // look into that.
187
187
  grammars: packageJson.contributes.grammars,
@@ -0,0 +1,94 @@
1
+ import { SemVer } from 'semver';
2
+ import { OutputChannel } from 'vscode';
3
+ import { ExecutionResult } from '../utils/batch';
4
+ import { FileUri } from '../utils/exturi';
5
+ export type SystemQueryResult = {
6
+ operatingSystem: string;
7
+ cpuArchitecture: string;
8
+ cpuModels: string;
9
+ totalMemory: string;
10
+ };
11
+ export type VersionQueryResult = {
12
+ kind: 'Success';
13
+ version: SemVer;
14
+ } | {
15
+ kind: 'CommandNotFound';
16
+ } | {
17
+ kind: 'CommandError';
18
+ message: string;
19
+ } | {
20
+ kind: 'InvalidVersion';
21
+ versionResult: string;
22
+ };
23
+ export type ElanVersionDiagnosis = {
24
+ kind: 'UpToDate';
25
+ version: SemVer;
26
+ } | {
27
+ kind: 'Outdated';
28
+ currentVersion: SemVer;
29
+ recommendedVersion: SemVer;
30
+ } | {
31
+ kind: 'NotInstalled';
32
+ } | {
33
+ kind: 'ExecutionError';
34
+ message: string;
35
+ };
36
+ export type ProjectSetupDiagnosis = {
37
+ kind: 'SingleFile';
38
+ } | {
39
+ kind: 'MissingLeanToolchain';
40
+ folder: FileUri;
41
+ parentProjectFolder: FileUri | undefined;
42
+ } | {
43
+ kind: 'ValidProjectSetup';
44
+ projectFolder: FileUri;
45
+ };
46
+ export type LeanVersionDiagnosis = {
47
+ kind: 'UpToDate';
48
+ version: SemVer;
49
+ } | {
50
+ kind: 'IsLean3Version';
51
+ version: SemVer;
52
+ } | {
53
+ kind: 'IsAncientLean4Version';
54
+ version: SemVer;
55
+ } | {
56
+ kind: 'NotInstalled';
57
+ } | {
58
+ kind: 'ExecutionError';
59
+ message: string;
60
+ };
61
+ export type VSCodeVersionDiagnosis = {
62
+ kind: 'UpToDate';
63
+ version: SemVer;
64
+ } | {
65
+ kind: 'Outdated';
66
+ currentVersion: SemVer;
67
+ recommendedVersion: SemVer;
68
+ };
69
+ export declare function versionQueryResult(executionResult: ExecutionResult, versionRegex: RegExp): VersionQueryResult;
70
+ export declare function checkElanVersion(elanVersionResult: VersionQueryResult): ElanVersionDiagnosis;
71
+ export declare function checkLeanVersion(leanVersionResult: VersionQueryResult): LeanVersionDiagnosis;
72
+ export declare class SetupDiagnoser {
73
+ readonly channel: OutputChannel | undefined;
74
+ readonly cwdUri: FileUri | undefined;
75
+ readonly toolchain: string | undefined;
76
+ constructor(channel: OutputChannel | undefined, cwdUri: FileUri | undefined, toolchain?: string | undefined);
77
+ checkCurlAvailable(): Promise<boolean>;
78
+ checkGitAvailable(): Promise<boolean>;
79
+ queryLakeVersion(): Promise<VersionQueryResult>;
80
+ checkLakeAvailable(): Promise<boolean>;
81
+ querySystemInformation(): SystemQueryResult;
82
+ queryExtensionVersion(): SemVer;
83
+ queryVSCodeVersion(): VSCodeVersionDiagnosis;
84
+ queryLeanVersion(): Promise<VersionQueryResult>;
85
+ queryElanVersion(): Promise<VersionQueryResult>;
86
+ queryElanShow(): Promise<ExecutionResult>;
87
+ elanVersion(): Promise<ElanVersionDiagnosis>;
88
+ projectSetup(): Promise<ProjectSetupDiagnosis>;
89
+ leanVersion(): Promise<LeanVersionDiagnosis>;
90
+ private runSilently;
91
+ private runWithProgress;
92
+ private runLeanCommand;
93
+ }
94
+ export declare function diagnose(channel: OutputChannel | undefined, cwdUri: FileUri | undefined, toolchain?: string | undefined): SetupDiagnoser;
@@ -0,0 +1,180 @@
1
+ import * as os from 'os';
2
+ import { SemVer } from 'semver';
3
+ import { extensions, version } from 'vscode';
4
+ import { ExecutionExitCode, batchExecute, batchExecuteWithProgress } from '../utils/batch';
5
+ import { checkParentFoldersForLeanProject, isValidLeanProject } from '../utils/projectInfo';
6
+ const recommendedElanVersion = new SemVer('3.1.1');
7
+ // Should be bumped in a release *before* we bump the version requirement of the VS Code extension so that
8
+ // users know that they need to update and do not get stuck on an old VS Code version.
9
+ const recommendedVSCodeVersion = new SemVer('1.75.0');
10
+ export function versionQueryResult(executionResult, versionRegex) {
11
+ if (executionResult.exitCode === ExecutionExitCode.CannotLaunch) {
12
+ return { kind: 'CommandNotFound' };
13
+ }
14
+ if (executionResult.exitCode === ExecutionExitCode.ExecutionError) {
15
+ return { kind: 'CommandError', message: executionResult.combined };
16
+ }
17
+ const match = versionRegex.exec(executionResult.stdout);
18
+ if (!match) {
19
+ return { kind: 'InvalidVersion', versionResult: executionResult.stdout };
20
+ }
21
+ return { kind: 'Success', version: new SemVer(match[1]) };
22
+ }
23
+ export function checkElanVersion(elanVersionResult) {
24
+ switch (elanVersionResult.kind) {
25
+ case 'CommandNotFound':
26
+ return { kind: 'NotInstalled' };
27
+ case 'CommandError':
28
+ return { kind: 'ExecutionError', message: elanVersionResult.message };
29
+ case 'InvalidVersion':
30
+ return {
31
+ kind: 'ExecutionError',
32
+ message: `Invalid Elan version format: '${elanVersionResult.versionResult}'`,
33
+ };
34
+ case 'Success':
35
+ if (elanVersionResult.version.compare(recommendedElanVersion) < 0) {
36
+ return {
37
+ kind: 'Outdated',
38
+ currentVersion: elanVersionResult.version,
39
+ recommendedVersion: recommendedElanVersion,
40
+ };
41
+ }
42
+ return { kind: 'UpToDate', version: elanVersionResult.version };
43
+ }
44
+ }
45
+ export function checkLeanVersion(leanVersionResult) {
46
+ if (leanVersionResult.kind === 'CommandNotFound') {
47
+ return { kind: 'NotInstalled' };
48
+ }
49
+ if (leanVersionResult.kind === 'CommandError') {
50
+ return {
51
+ kind: 'ExecutionError',
52
+ message: leanVersionResult.message,
53
+ };
54
+ }
55
+ if (leanVersionResult.kind === 'InvalidVersion') {
56
+ return {
57
+ kind: 'ExecutionError',
58
+ message: `Invalid Lean version format: '${leanVersionResult.versionResult}'`,
59
+ };
60
+ }
61
+ const leanVersion = leanVersionResult.version;
62
+ if (leanVersion.major === 3) {
63
+ return { kind: 'IsLean3Version', version: leanVersion };
64
+ }
65
+ if (leanVersion.major === 4 && leanVersion.minor === 0 && leanVersion.prerelease.length > 0) {
66
+ return { kind: 'IsAncientLean4Version', version: leanVersion };
67
+ }
68
+ return { kind: 'UpToDate', version: leanVersion };
69
+ }
70
+ export class SetupDiagnoser {
71
+ channel;
72
+ cwdUri;
73
+ toolchain;
74
+ constructor(channel, cwdUri, toolchain) {
75
+ this.channel = channel;
76
+ this.cwdUri = cwdUri;
77
+ this.toolchain = toolchain;
78
+ }
79
+ async checkCurlAvailable() {
80
+ const curlVersionResult = await this.runSilently('curl', ['--version']);
81
+ return curlVersionResult.exitCode === ExecutionExitCode.Success;
82
+ }
83
+ async checkGitAvailable() {
84
+ const gitVersionResult = await this.runSilently('git', ['--version']);
85
+ return gitVersionResult.exitCode === ExecutionExitCode.Success;
86
+ }
87
+ async queryLakeVersion() {
88
+ const lakeVersionResult = await this.runLeanCommand('lake', ['--version'], 'Checking Lake version');
89
+ return versionQueryResult(lakeVersionResult, /version (\d+\.\d+\.\d+(\w|-)*)/);
90
+ }
91
+ async checkLakeAvailable() {
92
+ const lakeVersionResult = await this.queryLakeVersion();
93
+ return lakeVersionResult.kind === 'Success';
94
+ }
95
+ querySystemInformation() {
96
+ const cpuModels = os.cpus().map(cpu => cpu.model);
97
+ const groupedCpuModels = new Map();
98
+ for (const cpuModel of cpuModels) {
99
+ const counter = groupedCpuModels.get(cpuModel);
100
+ if (counter === undefined) {
101
+ groupedCpuModels.set(cpuModel, 1);
102
+ }
103
+ else {
104
+ groupedCpuModels.set(cpuModel, counter + 1);
105
+ }
106
+ }
107
+ const formattedCpuModels = Array.from(groupedCpuModels.entries())
108
+ .map(([cpuModel, amount]) => `${amount} x ${cpuModel}`)
109
+ .join(', ');
110
+ const totalMemory = (os.totalmem() / 1_000_000_000).toFixed(2);
111
+ return {
112
+ operatingSystem: `${os.type()} (release: ${os.release()})`,
113
+ cpuArchitecture: os.arch(),
114
+ cpuModels: formattedCpuModels,
115
+ totalMemory: `${totalMemory} GB`,
116
+ };
117
+ }
118
+ queryExtensionVersion() {
119
+ return new SemVer(extensions.getExtension('leanprover.lean4').packageJSON.version);
120
+ }
121
+ queryVSCodeVersion() {
122
+ const currentVSCodeVersion = new SemVer(version);
123
+ if (currentVSCodeVersion.compare(recommendedVSCodeVersion) < 0) {
124
+ return {
125
+ kind: 'Outdated',
126
+ currentVersion: currentVSCodeVersion,
127
+ recommendedVersion: recommendedVSCodeVersion,
128
+ };
129
+ }
130
+ return { kind: 'UpToDate', version: currentVSCodeVersion };
131
+ }
132
+ async queryLeanVersion() {
133
+ const leanVersionResult = await this.runLeanCommand('lean', ['--version'], 'Checking Lean version');
134
+ return versionQueryResult(leanVersionResult, /version (\d+\.\d+\.\d+(\w|-)*)/);
135
+ }
136
+ async queryElanVersion() {
137
+ const elanVersionResult = await this.runSilently('elan', ['--version']);
138
+ return versionQueryResult(elanVersionResult, /elan (\d+\.\d+\.\d+)/);
139
+ }
140
+ async queryElanShow() {
141
+ return await this.runSilently('elan', ['show']);
142
+ }
143
+ async elanVersion() {
144
+ const elanVersionResult = await this.queryElanVersion();
145
+ return checkElanVersion(elanVersionResult);
146
+ }
147
+ async projectSetup() {
148
+ if (this.cwdUri === undefined) {
149
+ return { kind: 'SingleFile' };
150
+ }
151
+ if (!(await isValidLeanProject(this.cwdUri))) {
152
+ const parentProjectFolder = await checkParentFoldersForLeanProject(this.cwdUri);
153
+ return { kind: 'MissingLeanToolchain', folder: this.cwdUri, parentProjectFolder };
154
+ }
155
+ return { kind: 'ValidProjectSetup', projectFolder: this.cwdUri };
156
+ }
157
+ async leanVersion() {
158
+ const leanVersionResult = await this.queryLeanVersion();
159
+ return checkLeanVersion(leanVersionResult);
160
+ }
161
+ async runSilently(executablePath, args) {
162
+ return batchExecute(executablePath, args, this.cwdUri?.fsPath, { combined: this.channel });
163
+ }
164
+ async runWithProgress(executablePath, args, title) {
165
+ return batchExecuteWithProgress(executablePath, args, title, {
166
+ cwd: this.cwdUri?.fsPath,
167
+ channel: this.channel,
168
+ });
169
+ }
170
+ async runLeanCommand(executablePath, args, title) {
171
+ const leanArgs = [...args];
172
+ if (this.toolchain !== undefined) {
173
+ leanArgs.unshift(`+${this.toolchain}`);
174
+ }
175
+ return await this.runWithProgress(executablePath, leanArgs, title);
176
+ }
177
+ }
178
+ export function diagnose(channel, cwdUri, toolchain) {
179
+ return new SetupDiagnoser(channel, cwdUri, toolchain);
180
+ }
@@ -0,0 +1,21 @@
1
+ import { OutputChannel } from 'vscode';
2
+ import { ExtUri, FileUri } from '../utils/exturi';
3
+ import { LeanInstaller } from '../utils/leanInstaller';
4
+ import { PreconditionCheckResult } from './setupNotifs';
5
+ export declare function checkAll(...checks: (() => Promise<PreconditionCheckResult>)[]): Promise<PreconditionCheckResult>;
6
+ export declare function checkAreDependenciesInstalled(channel: OutputChannel, cwdUri: FileUri | undefined): Promise<PreconditionCheckResult>;
7
+ export declare function checkIsLean4Installed(installer: LeanInstaller, cwdUri: FileUri | undefined): Promise<PreconditionCheckResult>;
8
+ export declare function checkIsElanUpToDate(installer: LeanInstaller, cwdUri: FileUri | undefined, options: {
9
+ elanMustBeInstalled: boolean;
10
+ modal: boolean;
11
+ }): Promise<PreconditionCheckResult>;
12
+ export declare function checkIsValidProjectFolder(channel: OutputChannel, folderUri: ExtUri): Promise<PreconditionCheckResult>;
13
+ export declare function checkIsLeanVersionUpToDate(channel: OutputChannel, folderUri: ExtUri, options: {
14
+ toolchainOverride?: string | undefined;
15
+ modal: boolean;
16
+ }): Promise<PreconditionCheckResult>;
17
+ export declare function checkIsLakeInstalledCorrectly(channel: OutputChannel, folderUri: ExtUri, options: {
18
+ toolchainOverride?: string | undefined;
19
+ }): Promise<PreconditionCheckResult>;
20
+ export declare function checkIsVSCodeUpToDate(): Promise<PreconditionCheckResult>;
21
+ export declare function checkLean4ProjectPreconditions(channel: OutputChannel, folderUri: ExtUri): Promise<PreconditionCheckResult>;
@@ -0,0 +1,150 @@
1
+ import { commands } from 'vscode';
2
+ import { extUriToCwdUri } from '../utils/exturi';
3
+ import { willUseLakeServer } from '../utils/projectInfo';
4
+ import { diagnose } from './setupDiagnoser';
5
+ import { displayDependencySetupError, displayElanOutdatedSetupWarning, displayElanSetupError, displayElanSetupWarning, displaySetupError, displaySetupErrorWithOutput, displaySetupWarning, displaySetupWarningWithOptionalInput, displaySetupWarningWithOutput, worstPreconditionViolation, } from './setupNotifs';
6
+ export async function checkAll(...checks) {
7
+ let worstViolation = 'Fulfilled';
8
+ for (const check of checks) {
9
+ const result = await check();
10
+ worstViolation = worstPreconditionViolation(worstViolation, result);
11
+ if (worstViolation === 'Fatal') {
12
+ return 'Fatal';
13
+ }
14
+ }
15
+ return worstViolation;
16
+ }
17
+ const singleFileWarningMessage = `Lean 4 server is operating in restricted single file mode.
18
+ Please open a valid Lean 4 project containing a \'lean-toolchain\' file for full functionality.
19
+ Click the following link to learn how to set up or open Lean projects: [(Show Setup Guide)](command:lean4.docs.showSetupGuide)`;
20
+ const missingLeanToolchainWarningMessage = `Opened folder does not contain a valid Lean 4 project.
21
+ Please open a valid Lean 4 project containing a \'lean-toolchain\' file for full functionality.
22
+ Click the following link to learn how to set up or open Lean projects: [(Show Setup Guide)](command:lean4.docs.showSetupGuide)`;
23
+ const missingLeanToolchainWithParentProjectWarningMessage = (parentProjectFolder) => `Opened folder does not contain a valid Lean 4 project folder because it does not contain a 'lean-toolchain' file.
24
+ However, a valid Lean 4 project folder was found in one of the parent directories at '${parentProjectFolder.fsPath}'.
25
+ Open this project instead?`;
26
+ const lean3ProjectErrorMessage = (origin, projectVersion) => `${origin} is using Lean 3 (version: ${projectVersion.toString()}).
27
+ If you want to use Lean 3, disable this extension ('Extensions' in the left sidebar > Cog icon on 'lean4' > 'Disable') and install the 'lean' extension for Lean 3 support.`;
28
+ const ancientLean4ProjectWarningMessage = (origin, projectVersion) => `${origin} is using a Lean 4 version (${projectVersion.toString()}) from before the first Lean 4 stable release (4.0.0).
29
+ Pre-stable Lean 4 versions are increasingly less supported, so please consider updating to a newer Lean 4 version.`;
30
+ export async function checkAreDependenciesInstalled(channel, cwdUri) {
31
+ const missingDeps = [];
32
+ if (!(await diagnose(channel, cwdUri).checkCurlAvailable())) {
33
+ missingDeps.push('curl');
34
+ }
35
+ if (!(await diagnose(channel, cwdUri).checkGitAvailable())) {
36
+ missingDeps.push('git');
37
+ }
38
+ if (missingDeps.length === 0) {
39
+ return 'Fulfilled';
40
+ }
41
+ displayDependencySetupError(missingDeps);
42
+ return 'Fatal';
43
+ }
44
+ export async function checkIsLean4Installed(installer, cwdUri) {
45
+ const leanVersionResult = await diagnose(installer.getOutputChannel(), cwdUri).queryLeanVersion();
46
+ switch (leanVersionResult.kind) {
47
+ case 'Success':
48
+ return 'Fulfilled';
49
+ case 'CommandError':
50
+ return displaySetupErrorWithOutput(`Error while checking Lean version: ${leanVersionResult.message}`);
51
+ case 'InvalidVersion':
52
+ return displaySetupErrorWithOutput(`Error while checking Lean version: 'lean --version' returned a version that could not be parsed: '${leanVersionResult.versionResult}'`);
53
+ case 'CommandNotFound':
54
+ return await displayElanSetupError(installer, 'Lean is not installed.');
55
+ }
56
+ }
57
+ export async function checkIsElanUpToDate(installer, cwdUri, options) {
58
+ const elanDiagnosis = await diagnose(installer.getOutputChannel(), cwdUri).elanVersion();
59
+ switch (elanDiagnosis.kind) {
60
+ case 'NotInstalled':
61
+ if (options.elanMustBeInstalled) {
62
+ return await displayElanSetupError(installer, "Lean's version manager Elan is not installed.");
63
+ }
64
+ return await displayElanSetupWarning(installer, "Lean's version manager Elan is not installed. This means that the correct Lean 4 toolchain version of Lean 4 projects will not be selected or installed automatically.");
65
+ case 'ExecutionError':
66
+ return await displaySetupWarningWithOutput('Cannot determine Elan version: ' + elanDiagnosis.message, {
67
+ modal: options.modal,
68
+ });
69
+ case 'Outdated':
70
+ return await displayElanOutdatedSetupWarning(installer, elanDiagnosis.currentVersion, elanDiagnosis.recommendedVersion);
71
+ case 'UpToDate':
72
+ return 'Fulfilled';
73
+ }
74
+ }
75
+ export async function checkIsValidProjectFolder(channel, folderUri) {
76
+ const projectSetupDiagnosis = await diagnose(channel, extUriToCwdUri(folderUri)).projectSetup();
77
+ switch (projectSetupDiagnosis.kind) {
78
+ case 'SingleFile':
79
+ return await displaySetupWarning(singleFileWarningMessage);
80
+ case 'MissingLeanToolchain':
81
+ const parentProjectFolder = projectSetupDiagnosis.parentProjectFolder;
82
+ if (parentProjectFolder === undefined) {
83
+ return await displaySetupWarning(missingLeanToolchainWarningMessage);
84
+ }
85
+ else {
86
+ return displaySetupWarningWithOptionalInput(missingLeanToolchainWithParentProjectWarningMessage(parentProjectFolder), 'Open Parent Directory Project',
87
+ // this kills the extension host
88
+ () => commands.executeCommand('vscode.openFolder', parentProjectFolder));
89
+ }
90
+ case 'ValidProjectSetup':
91
+ return 'Fulfilled';
92
+ }
93
+ }
94
+ export async function checkIsLeanVersionUpToDate(channel, folderUri, options) {
95
+ let origin;
96
+ if (options.toolchainOverride !== undefined) {
97
+ origin = `Project toolchain '${options.toolchainOverride}'`;
98
+ }
99
+ else if (folderUri.scheme === 'untitled') {
100
+ origin = 'Opened file';
101
+ }
102
+ else {
103
+ origin = 'Opened project';
104
+ }
105
+ const projectLeanVersionDiagnosis = await diagnose(channel, extUriToCwdUri(folderUri), options.toolchainOverride).leanVersion();
106
+ switch (projectLeanVersionDiagnosis.kind) {
107
+ case 'NotInstalled':
108
+ return displaySetupErrorWithOutput("Error while checking Lean version: 'lean' command was not found.");
109
+ case 'ExecutionError':
110
+ return displaySetupErrorWithOutput(`Error while checking Lean version: ${projectLeanVersionDiagnosis.message}`);
111
+ case 'IsLean3Version':
112
+ return displaySetupError(lean3ProjectErrorMessage(origin, projectLeanVersionDiagnosis.version));
113
+ case 'IsAncientLean4Version':
114
+ return await displaySetupWarning(ancientLean4ProjectWarningMessage(origin, projectLeanVersionDiagnosis.version), {
115
+ modal: options.modal,
116
+ });
117
+ case 'UpToDate':
118
+ return 'Fulfilled';
119
+ }
120
+ }
121
+ export async function checkIsLakeInstalledCorrectly(channel, folderUri, options) {
122
+ const lakeVersionResult = await diagnose(channel, extUriToCwdUri(folderUri), options.toolchainOverride).queryLakeVersion();
123
+ switch (lakeVersionResult.kind) {
124
+ case 'CommandNotFound':
125
+ return displaySetupErrorWithOutput("Error while checking Lake version: 'lake' command was not found.");
126
+ case 'CommandError':
127
+ return displaySetupErrorWithOutput(`Error while checking Lake version: ${lakeVersionResult.message}`);
128
+ case 'InvalidVersion':
129
+ return displaySetupErrorWithOutput(`Error while checking Lake version: Invalid Lake version format: '${lakeVersionResult.versionResult}'`);
130
+ case 'Success':
131
+ return 'Fulfilled';
132
+ }
133
+ }
134
+ export async function checkIsVSCodeUpToDate() {
135
+ const vscodeVersionResult = diagnose(undefined, undefined).queryVSCodeVersion();
136
+ switch (vscodeVersionResult.kind) {
137
+ case 'Outdated':
138
+ return displaySetupWarning(`VS Code version is too out-of-date for new versions of the Lean 4 VS Code extension. The current VS Code version is ${vscodeVersionResult.currentVersion}, but at least a version of ${vscodeVersionResult.recommendedVersion} is recommended so that new versions of the Lean 4 VS Code extension can be installed.`);
139
+ case 'UpToDate':
140
+ return 'Fulfilled';
141
+ }
142
+ }
143
+ export async function checkLean4ProjectPreconditions(channel, folderUri) {
144
+ return await checkAll(() => checkIsValidProjectFolder(channel, folderUri), () => checkIsLeanVersionUpToDate(channel, folderUri, { modal: false }), async () => {
145
+ if (!(await willUseLakeServer(folderUri))) {
146
+ return 'Fulfilled';
147
+ }
148
+ return await checkIsLakeInstalledCorrectly(channel, folderUri, {});
149
+ });
150
+ }
@@ -6,8 +6,8 @@ import { LeanClient } from '../leanclient';
6
6
  import { ExtUri } from './exturi';
7
7
  import { LeanInstaller } from './leanInstaller';
8
8
  export declare class LeanClientProvider implements Disposable {
9
- private setupClient;
10
9
  private checkLean4ProjectPreconditions;
10
+ private setupClient;
11
11
  private subscriptions;
12
12
  private outputChannel;
13
13
  private installer;
@@ -24,7 +24,7 @@ export declare class LeanClientProvider implements Disposable {
24
24
  clientRemoved: import("vscode").Event<LeanClient>;
25
25
  private clientStoppedEmitter;
26
26
  clientStopped: import("vscode").Event<[LeanClient, boolean, ServerStoppedReason]>;
27
- constructor(installer: LeanInstaller, outputChannel: OutputChannel, setupClient: (clientOptions: LanguageClientOptions, folderUri: ExtUri, elanDefaultToolchain: string) => Promise<BaseLanguageClient>, checkLean4ProjectPreconditions: (channel: OutputChannel, folderUri: ExtUri) => Promise<PreconditionCheckResult>);
27
+ constructor(installer: LeanInstaller, outputChannel: OutputChannel, checkLean4ProjectPreconditions: (channel: OutputChannel, folderUri: ExtUri) => Promise<PreconditionCheckResult>, setupClient: (clientOptions: LanguageClientOptions, folderUri: ExtUri, elanDefaultToolchain: string) => Promise<BaseLanguageClient>);
28
28
  getActiveClient(): LeanClient | undefined;
29
29
  private onInstallChanged;
30
30
  private restartFile;
@@ -6,8 +6,8 @@ import { displayError } from './notifs';
6
6
  import { findLeanProjectRoot } from './projectInfo';
7
7
  // This class ensures we have one LeanClient per folder.
8
8
  export class LeanClientProvider {
9
- setupClient;
10
9
  checkLean4ProjectPreconditions;
10
+ setupClient;
11
11
  subscriptions = [];
12
12
  outputChannel;
13
13
  installer;
@@ -24,9 +24,9 @@ export class LeanClientProvider {
24
24
  clientRemoved = this.clientRemovedEmitter.event;
25
25
  clientStoppedEmitter = new EventEmitter();
26
26
  clientStopped = this.clientStoppedEmitter.event;
27
- constructor(installer, outputChannel, setupClient, checkLean4ProjectPreconditions) {
28
- this.setupClient = setupClient;
27
+ constructor(installer, outputChannel, checkLean4ProjectPreconditions, setupClient) {
29
28
  this.checkLean4ProjectPreconditions = checkLean4ProjectPreconditions;
29
+ this.setupClient = setupClient;
30
30
  this.outputChannel = outputChannel;
31
31
  this.installer = installer;
32
32
  // we must setup the installChanged event handler first before any didOpenEditor calls.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lean4monaco",
3
- "version": "1.0.27",
3
+ "version": "1.0.29",
4
4
  "description": "Monaco Editor support for the Lean 4 theorem prover.",
5
5
  "keywords": [
6
6
  "lean",
@@ -33,14 +33,15 @@
33
33
  "url": "https://github.com/hhu-adam/lean4monaco"
34
34
  },
35
35
  "scripts": {
36
- "start": "concurrently \"tsc -w --preserveWatchOutput\" \"webpack --watch\" \"npm run watch:copyfiles\" \"cd demo && npm run start_client\" \"cd demo && npm run start_server\" -n tsc,webpack,copyfiles,vite,server -c \"bgGreen.bold,bgBlue.bold,bgCyan.bold,bgYellow.bold,bgMagenta.bold\"",
36
+ "setup_demo": "concurrently \"(cd demo && npm install)\" \"npm run build\" -n install,build -c \"bgCyan.bold,bgBlue.bold\"",
37
+ "start": "npm run setup_demo && concurrently \"tsc -w --preserveWatchOutput\" \"webpack --watch\" \"npm run watch:copyfiles\" \"cd demo && npm run start_client\" \"cd demo && npm run start_server\" -n tsc,webpack,copyfiles,vite,server -c \"bgGreen.bold,bgBlue.bold,bgCyan.bold,bgYellow.bold,bgMagenta.bold\"",
37
38
  "watch:copyfiles": "nodemon --watch ./src --exec \"npm run build:copyfiles\"",
38
39
  "build": "tsc && webpack && npm run build:copyfiles",
39
40
  "build:copyfiles": "cd src && copyfiles \"**/*.json\" \"**/*.css\" \"**/*.ttf\" \"**/*.otf\" \"**/*.svg\" ../dist/",
40
- "test": "(cd demo && npm install && npm run build_server) && concurrently --kill-others \"npm start 1> /dev/null\" \"wait-on http://localhost:5173 && cypress run\" -n server,cypress -s command-cypress"
41
+ "test": "concurrently --hide 0 --kill-others \"npm start\" \"wait-on http://localhost:5173 && cypress run\" -n server,cypress -s command-cypress"
41
42
  },
42
43
  "dependencies": {
43
- "@leanprover/infoview": "^0.7.0",
44
+ "@leanprover/infoview": "^0.7.3",
44
45
  "@leanprover/infoview-api": "^0.4.0",
45
46
  "@leanprover/unicode-input": "^0.1.0",
46
47
  "concurrently": "^8.2.2",