mirror of
https://github.com/microsoft/monaco-editor.git
synced 2025-12-22 22:02:55 +01:00
Merge pull request #82 from Kingwl/inlayhints-support
Add inlay hints support
This commit is contained in:
commit
3ecea82819
15 changed files with 31146 additions and 23803 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -1,3 +1,4 @@
|
||||||
/node_modules/
|
/node_modules/
|
||||||
/out/
|
/out/
|
||||||
/release/
|
/release/
|
||||||
|
.DS_Store
|
||||||
16
monaco.d.ts
vendored
16
monaco.d.ts
vendored
|
|
@ -154,6 +154,15 @@ declare namespace monaco.languages.typescript {
|
||||||
/** A full HTTP path to a JavaScript file which adds a function `customTSWorkerFactory` to the self inside a web-worker */
|
/** A full HTTP path to a JavaScript file which adds a function `customTSWorkerFactory` to the self inside a web-worker */
|
||||||
customWorkerPath?: string;
|
customWorkerPath?: string;
|
||||||
}
|
}
|
||||||
|
interface InlayHintsOptions {
|
||||||
|
readonly includeInlayParameterNameHints?: 'none' | 'literals' | 'all';
|
||||||
|
readonly includeInlayParameterNameHintsWhenArgumentMatchesName?: boolean;
|
||||||
|
readonly includeInlayFunctionParameterTypeHints?: boolean;
|
||||||
|
readonly includeInlayVariableTypeHints?: boolean;
|
||||||
|
readonly includeInlayPropertyDeclarationTypeHints?: boolean;
|
||||||
|
readonly includeInlayFunctionLikeReturnTypeHints?: boolean;
|
||||||
|
readonly includeInlayEnumMemberValueHints?: boolean;
|
||||||
|
}
|
||||||
interface IExtraLib {
|
interface IExtraLib {
|
||||||
content: string;
|
content: string;
|
||||||
version: number;
|
version: number;
|
||||||
|
|
@ -212,6 +221,7 @@ declare namespace monaco.languages.typescript {
|
||||||
*/
|
*/
|
||||||
readonly onDidExtraLibsChange: IEvent<void>;
|
readonly onDidExtraLibsChange: IEvent<void>;
|
||||||
readonly workerOptions: WorkerOptions;
|
readonly workerOptions: WorkerOptions;
|
||||||
|
readonly inlayHintsOptions: InlayHintsOptions;
|
||||||
/**
|
/**
|
||||||
* Get the current extra libs registered with the language service.
|
* Get the current extra libs registered with the language service.
|
||||||
*/
|
*/
|
||||||
|
|
@ -413,6 +423,12 @@ declare namespace monaco.languages.typescript {
|
||||||
errorCodes: number[],
|
errorCodes: number[],
|
||||||
formatOptions: any
|
formatOptions: any
|
||||||
): Promise<ReadonlyArray<any>>;
|
): Promise<ReadonlyArray<any>>;
|
||||||
|
/**
|
||||||
|
* Get inlay hints in the range of the file.
|
||||||
|
* @param fileName
|
||||||
|
* @returns `Promise<typescript.InlayHint[]>`
|
||||||
|
*/
|
||||||
|
provideInlayHints(fileName: string, start: number, end: number): Promise<ReadonlyArray<any>>;
|
||||||
}
|
}
|
||||||
export const typescriptVersion: string;
|
export const typescriptVersion: string;
|
||||||
export const typescriptDefaults: LanguageServiceDefaults;
|
export const typescriptDefaults: LanguageServiceDefaults;
|
||||||
|
|
|
||||||
6
package-lock.json
generated
6
package-lock.json
generated
|
|
@ -461,9 +461,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"typescript": {
|
"typescript": {
|
||||||
"version": "4.3.2",
|
"version": "4.4.2",
|
||||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.2.tgz",
|
||||||
"integrity": "sha512-zZ4hShnmnoVnAHpVHWpTcxdv7dWP60S2FsydQLV8V5PbS3FifjWFFRiHSWpDJahly88PRyV5teTSLoq4eG7mKw==",
|
"integrity": "sha512-gzP+t5W4hdy4c+68bfcv0t400HVJMMd2+H9B7gae1nQlBzCqvrXX+6GL/b3GAgyTH966pzrZ70/fRjwAtZksSQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"which": {
|
"which": {
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@
|
||||||
"pretty-quick": "^3.1.0",
|
"pretty-quick": "^3.1.0",
|
||||||
"requirejs": "^2.3.6",
|
"requirejs": "^2.3.6",
|
||||||
"terser": "^5.6.0",
|
"terser": "^5.6.0",
|
||||||
"typescript": "^4.3.2"
|
"typescript": "^4.4.2"
|
||||||
},
|
},
|
||||||
"husky": {
|
"husky": {
|
||||||
"hooks": {
|
"hooks": {
|
||||||
|
|
|
||||||
|
|
@ -242,7 +242,9 @@ export class DiagnosticsAdapter extends Adapter {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
this._disposables.push(editor.onDidCreateModel((model) => onModelAdd(<IInternalEditorModel>model)));
|
this._disposables.push(
|
||||||
|
editor.onDidCreateModel((model) => onModelAdd(<IInternalEditorModel>model))
|
||||||
|
);
|
||||||
this._disposables.push(editor.onWillDisposeModel(onModelRemoved));
|
this._disposables.push(editor.onWillDisposeModel(onModelRemoved));
|
||||||
this._disposables.push(
|
this._disposables.push(
|
||||||
editor.onDidChangeModelLanguage((event) => {
|
editor.onDidChangeModelLanguage((event) => {
|
||||||
|
|
@ -574,9 +576,9 @@ function tagToString(tag: ts.JSDocTagInfo): string {
|
||||||
if (tag.name === 'param' && tag.text) {
|
if (tag.name === 'param' && tag.text) {
|
||||||
const [paramName, ...rest] = tag.text;
|
const [paramName, ...rest] = tag.text;
|
||||||
tagLabel += `\`${paramName.text}\``;
|
tagLabel += `\`${paramName.text}\``;
|
||||||
if (rest.length > 0) tagLabel += ` — ${rest.map(r => r.text).join(' ')}`;
|
if (rest.length > 0) tagLabel += ` — ${rest.map((r) => r.text).join(' ')}`;
|
||||||
} else if (Array.isArray(tag.text)) {
|
} else if (Array.isArray(tag.text)) {
|
||||||
tagLabel += ` — ${tag.text.map(r => r.text).join(' ')}`;
|
tagLabel += ` — ${tag.text.map((r) => r.text).join(' ')}`;
|
||||||
} else if (tag.text) {
|
} else if (tag.text) {
|
||||||
tagLabel += ` — ${tag.text}`;
|
tagLabel += ` — ${tag.text}`;
|
||||||
}
|
}
|
||||||
|
|
@ -793,16 +795,14 @@ export class DefinitionAdapter extends Adapter {
|
||||||
range: this._textSpanToRange(refModel, entry.textSpan)
|
range: this._textSpanToRange(refModel, entry.textSpan)
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
const matchedLibFile = typescriptDefaults.getExtraLibs()[entry.fileName]
|
const matchedLibFile = typescriptDefaults.getExtraLibs()[entry.fileName];
|
||||||
if (matchedLibFile) {
|
if (matchedLibFile) {
|
||||||
const libModel = editor.createModel(matchedLibFile.content, 'typescript', uri);
|
const libModel = editor.createModel(matchedLibFile.content, 'typescript', uri);
|
||||||
return {
|
return {
|
||||||
uri: uri,
|
uri: uri,
|
||||||
range: this._textSpanToRange(libModel, entry.textSpan)
|
range: this._textSpanToRange(libModel, entry.textSpan)
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
|
@ -894,7 +894,7 @@ export class OutlineAdapter extends Adapter implements languages.DocumentSymbolP
|
||||||
kind: <languages.SymbolKind>(outlineTypeTable[item.kind] || languages.SymbolKind.Variable),
|
kind: <languages.SymbolKind>(outlineTypeTable[item.kind] || languages.SymbolKind.Variable),
|
||||||
range: this._textSpanToRange(model, item.spans[0]),
|
range: this._textSpanToRange(model, item.spans[0]),
|
||||||
selectionRange: this._textSpanToRange(model, item.spans[0]),
|
selectionRange: this._textSpanToRange(model, item.spans[0]),
|
||||||
tags: [],
|
tags: []
|
||||||
};
|
};
|
||||||
|
|
||||||
if (containerLabel) result.containerName = containerLabel;
|
if (containerLabel) result.containerName = containerLabel;
|
||||||
|
|
@ -1221,3 +1221,49 @@ export class RenameAdapter extends Adapter implements languages.RenameProvider {
|
||||||
return { edits };
|
return { edits };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --- inlay hints ----
|
||||||
|
|
||||||
|
export class InlayHintsAdapter extends Adapter implements languages.InlayHintsProvider {
|
||||||
|
public async provideInlayHints(
|
||||||
|
model: editor.ITextModel,
|
||||||
|
range: Range,
|
||||||
|
token: CancellationToken
|
||||||
|
): Promise<languages.InlayHint[]> {
|
||||||
|
const resource = model.uri;
|
||||||
|
const fileName = resource.toString();
|
||||||
|
const start = model.getOffsetAt({
|
||||||
|
lineNumber: range.startLineNumber,
|
||||||
|
column: range.startColumn
|
||||||
|
});
|
||||||
|
const end = model.getOffsetAt({
|
||||||
|
lineNumber: range.endLineNumber,
|
||||||
|
column: range.endColumn
|
||||||
|
});
|
||||||
|
const worker = await this._worker(resource);
|
||||||
|
if (model.isDisposed()) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
const hints = await worker.provideInlayHints(fileName, start, end);
|
||||||
|
|
||||||
|
return hints.map((hint) => {
|
||||||
|
return {
|
||||||
|
...hint,
|
||||||
|
position: model.getPositionAt(hint.position),
|
||||||
|
kind: this._convertHintKind(hint.kind)
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private _convertHintKind(kind?: ts.InlayHintKind) {
|
||||||
|
switch (kind) {
|
||||||
|
case 'Parameter':
|
||||||
|
return languages.InlayHintKind.Parameter;
|
||||||
|
case 'Type':
|
||||||
|
return languages.InlayHintKind.Type;
|
||||||
|
default:
|
||||||
|
return languages.InlayHintKind.Other;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
871
src/lib/typescriptServices.d.ts
vendored
871
src/lib/typescriptServices.d.ts
vendored
File diff suppressed because it is too large
Load diff
File diff suppressed because one or more lines are too long
|
|
@ -2,4 +2,4 @@
|
||||||
// **NOTE**: Do not edit directly! This file is generated using `npm run import-typescript`
|
// **NOTE**: Do not edit directly! This file is generated using `npm run import-typescript`
|
||||||
//
|
//
|
||||||
|
|
||||||
export const typescriptVersion = "4.3.2";
|
export const typescriptVersion = "4.4.2";
|
||||||
|
|
|
||||||
|
|
@ -169,6 +169,16 @@ export interface WorkerOptions {
|
||||||
customWorkerPath?: string;
|
customWorkerPath?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface InlayHintsOptions {
|
||||||
|
readonly includeInlayParameterNameHints?: 'none' | 'literals' | 'all';
|
||||||
|
readonly includeInlayParameterNameHintsWhenArgumentMatchesName?: boolean;
|
||||||
|
readonly includeInlayFunctionParameterTypeHints?: boolean;
|
||||||
|
readonly includeInlayVariableTypeHints?: boolean;
|
||||||
|
readonly includeInlayPropertyDeclarationTypeHints?: boolean;
|
||||||
|
readonly includeInlayFunctionLikeReturnTypeHints?: boolean;
|
||||||
|
readonly includeInlayEnumMemberValueHints?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
interface IExtraLib {
|
interface IExtraLib {
|
||||||
content: string;
|
content: string;
|
||||||
version: number;
|
version: number;
|
||||||
|
|
@ -230,6 +240,8 @@ export interface LanguageServiceDefaults {
|
||||||
|
|
||||||
readonly workerOptions: WorkerOptions;
|
readonly workerOptions: WorkerOptions;
|
||||||
|
|
||||||
|
readonly inlayHintsOptions: InlayHintsOptions;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the current extra libs registered with the language service.
|
* Get the current extra libs registered with the language service.
|
||||||
*/
|
*/
|
||||||
|
|
@ -452,6 +464,13 @@ export interface TypeScriptWorker {
|
||||||
errorCodes: number[],
|
errorCodes: number[],
|
||||||
formatOptions: any
|
formatOptions: any
|
||||||
): Promise<ReadonlyArray<any>>;
|
): Promise<ReadonlyArray<any>>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get inlay hints in the range of the file.
|
||||||
|
* @param fileName
|
||||||
|
* @returns `Promise<typescript.InlayHint[]>`
|
||||||
|
*/
|
||||||
|
provideInlayHints(fileName: string, start: number, end: number): Promise<ReadonlyArray<any>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- TypeScript configuration and defaults ---------
|
// --- TypeScript configuration and defaults ---------
|
||||||
|
|
@ -467,11 +486,13 @@ class LanguageServiceDefaultsImpl implements LanguageServiceDefaults {
|
||||||
private _diagnosticsOptions!: DiagnosticsOptions;
|
private _diagnosticsOptions!: DiagnosticsOptions;
|
||||||
private _workerOptions!: WorkerOptions;
|
private _workerOptions!: WorkerOptions;
|
||||||
private _onDidExtraLibsChangeTimeout: number;
|
private _onDidExtraLibsChangeTimeout: number;
|
||||||
|
private _inlayHintsOptions!: InlayHintsOptions;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
compilerOptions: CompilerOptions,
|
compilerOptions: CompilerOptions,
|
||||||
diagnosticsOptions: DiagnosticsOptions,
|
diagnosticsOptions: DiagnosticsOptions,
|
||||||
workerOptions: WorkerOptions
|
workerOptions: WorkerOptions,
|
||||||
|
inlayHintsOptions: InlayHintsOptions
|
||||||
) {
|
) {
|
||||||
this._extraLibs = Object.create(null);
|
this._extraLibs = Object.create(null);
|
||||||
this._removedExtraLibs = Object.create(null);
|
this._removedExtraLibs = Object.create(null);
|
||||||
|
|
@ -479,6 +500,7 @@ class LanguageServiceDefaultsImpl implements LanguageServiceDefaults {
|
||||||
this.setCompilerOptions(compilerOptions);
|
this.setCompilerOptions(compilerOptions);
|
||||||
this.setDiagnosticsOptions(diagnosticsOptions);
|
this.setDiagnosticsOptions(diagnosticsOptions);
|
||||||
this.setWorkerOptions(workerOptions);
|
this.setWorkerOptions(workerOptions);
|
||||||
|
this.setInlayHintsOptions(inlayHintsOptions);
|
||||||
this._onDidExtraLibsChangeTimeout = -1;
|
this._onDidExtraLibsChangeTimeout = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -494,6 +516,10 @@ class LanguageServiceDefaultsImpl implements LanguageServiceDefaults {
|
||||||
return this._workerOptions;
|
return this._workerOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get inlayHintsOptions(): InlayHintsOptions {
|
||||||
|
return this._inlayHintsOptions;
|
||||||
|
}
|
||||||
|
|
||||||
getExtraLibs(): IExtraLibs {
|
getExtraLibs(): IExtraLibs {
|
||||||
return this._extraLibs;
|
return this._extraLibs;
|
||||||
}
|
}
|
||||||
|
|
@ -604,6 +630,11 @@ class LanguageServiceDefaultsImpl implements LanguageServiceDefaults {
|
||||||
this._onDidChange.fire(undefined);
|
this._onDidChange.fire(undefined);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setInlayHintsOptions(options: InlayHintsOptions): void {
|
||||||
|
this._inlayHintsOptions = options || Object.create(null);
|
||||||
|
this._onDidChange.fire(undefined);
|
||||||
|
}
|
||||||
|
|
||||||
setMaximumWorkerIdleTime(value: number): void {}
|
setMaximumWorkerIdleTime(value: number): void {}
|
||||||
|
|
||||||
setEagerModelSync(value: boolean) {
|
setEagerModelSync(value: boolean) {
|
||||||
|
|
@ -622,12 +653,14 @@ export const typescriptVersion: string = tsversion;
|
||||||
export const typescriptDefaults: LanguageServiceDefaults = new LanguageServiceDefaultsImpl(
|
export const typescriptDefaults: LanguageServiceDefaults = new LanguageServiceDefaultsImpl(
|
||||||
{ allowNonTsExtensions: true, target: ScriptTarget.Latest },
|
{ allowNonTsExtensions: true, target: ScriptTarget.Latest },
|
||||||
{ noSemanticValidation: false, noSyntaxValidation: false, onlyVisible: false },
|
{ noSemanticValidation: false, noSyntaxValidation: false, onlyVisible: false },
|
||||||
|
{},
|
||||||
{}
|
{}
|
||||||
);
|
);
|
||||||
|
|
||||||
export const javascriptDefaults: LanguageServiceDefaults = new LanguageServiceDefaultsImpl(
|
export const javascriptDefaults: LanguageServiceDefaults = new LanguageServiceDefaultsImpl(
|
||||||
{ allowNonTsExtensions: true, allowJs: true, target: ScriptTarget.Latest },
|
{ allowNonTsExtensions: true, allowJs: true, target: ScriptTarget.Latest },
|
||||||
{ noSemanticValidation: true, noSyntaxValidation: false, onlyVisible: false },
|
{ noSemanticValidation: true, noSyntaxValidation: false, onlyVisible: false },
|
||||||
|
{},
|
||||||
{}
|
{}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -81,7 +81,7 @@ function setupMode(
|
||||||
);
|
);
|
||||||
languages.registerCodeActionProvider(modeId, new languageFeatures.CodeActionAdaptor(worker));
|
languages.registerCodeActionProvider(modeId, new languageFeatures.CodeActionAdaptor(worker));
|
||||||
languages.registerRenameProvider(modeId, new languageFeatures.RenameAdapter(worker));
|
languages.registerRenameProvider(modeId, new languageFeatures.RenameAdapter(worker));
|
||||||
|
languages.registerInlayHintsProvider(modeId, new languageFeatures.InlayHintsAdapter(worker));
|
||||||
new languageFeatures.DiagnosticsAdapter(libFiles, defaults, modeId, worker);
|
new languageFeatures.DiagnosticsAdapter(libFiles, defaults, modeId, worker);
|
||||||
|
|
||||||
return worker;
|
return worker;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -39,11 +39,13 @@ export class TypeScriptWorker implements ts.LanguageServiceHost, ITypeScriptWork
|
||||||
private _extraLibs: IExtraLibs = Object.create(null);
|
private _extraLibs: IExtraLibs = Object.create(null);
|
||||||
private _languageService = ts.createLanguageService(this);
|
private _languageService = ts.createLanguageService(this);
|
||||||
private _compilerOptions: ts.CompilerOptions;
|
private _compilerOptions: ts.CompilerOptions;
|
||||||
|
private _inlayHintsOptions?: ts.InlayHintsOptions;
|
||||||
|
|
||||||
constructor(ctx: worker.IWorkerContext, createData: ICreateData) {
|
constructor(ctx: worker.IWorkerContext, createData: ICreateData) {
|
||||||
this._ctx = ctx;
|
this._ctx = ctx;
|
||||||
this._compilerOptions = createData.compilerOptions;
|
this._compilerOptions = createData.compilerOptions;
|
||||||
this._extraLibs = createData.extraLibs;
|
this._extraLibs = createData.extraLibs;
|
||||||
|
this._inlayHintsOptions = createData.inlayHintsOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- language service host ---------------
|
// --- language service host ---------------
|
||||||
|
|
@ -191,7 +193,9 @@ export class TypeScriptWorker implements ts.LanguageServiceHost, ITypeScriptWork
|
||||||
diagnostic.relatedInformation = [];
|
diagnostic.relatedInformation = [];
|
||||||
for (const tsRelatedDiagnostic of tsDiagnostic.relatedInformation) {
|
for (const tsRelatedDiagnostic of tsDiagnostic.relatedInformation) {
|
||||||
const relatedDiagnostic: DiagnosticRelatedInformation = { ...tsRelatedDiagnostic };
|
const relatedDiagnostic: DiagnosticRelatedInformation = { ...tsRelatedDiagnostic };
|
||||||
relatedDiagnostic.file = relatedDiagnostic.file ? { fileName: relatedDiagnostic.file.fileName } : undefined
|
relatedDiagnostic.file = relatedDiagnostic.file
|
||||||
|
? { fileName: relatedDiagnostic.file.fileName }
|
||||||
|
: undefined;
|
||||||
diagnostic.relatedInformation.push(relatedDiagnostic);
|
diagnostic.relatedInformation.push(relatedDiagnostic);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -253,7 +257,7 @@ export class TypeScriptWorker implements ts.LanguageServiceHost, ITypeScriptWork
|
||||||
entry,
|
entry,
|
||||||
undefined,
|
undefined,
|
||||||
undefined,
|
undefined,
|
||||||
undefined,
|
undefined,
|
||||||
undefined
|
undefined
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -415,12 +419,34 @@ export class TypeScriptWorker implements ts.LanguageServiceHost, ITypeScriptWork
|
||||||
async updateExtraLibs(extraLibs: IExtraLibs): Promise<void> {
|
async updateExtraLibs(extraLibs: IExtraLibs): Promise<void> {
|
||||||
this._extraLibs = extraLibs;
|
this._extraLibs = extraLibs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async provideInlayHints(
|
||||||
|
fileName: string,
|
||||||
|
start: number,
|
||||||
|
end: number
|
||||||
|
): Promise<readonly ts.InlayHint[]> {
|
||||||
|
if (fileNameIsLib(fileName)) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
const preferences: ts.InlayHintsOptions = this._inlayHintsOptions ?? {};
|
||||||
|
const span: ts.TextSpan = {
|
||||||
|
start,
|
||||||
|
length: end - start
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
return this._languageService.provideInlayHints(fileName, span, preferences);
|
||||||
|
} catch {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ICreateData {
|
export interface ICreateData {
|
||||||
compilerOptions: ts.CompilerOptions;
|
compilerOptions: ts.CompilerOptions;
|
||||||
extraLibs: IExtraLibs;
|
extraLibs: IExtraLibs;
|
||||||
customWorkerPath?: string;
|
customWorkerPath?: string;
|
||||||
|
inlayHintsOptions?: ts.InlayHintsOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** The shape of the factory */
|
/** The shape of the factory */
|
||||||
|
|
|
||||||
|
|
@ -71,7 +71,8 @@ export class WorkerManager {
|
||||||
createData: {
|
createData: {
|
||||||
compilerOptions: this._defaults.getCompilerOptions(),
|
compilerOptions: this._defaults.getCompilerOptions(),
|
||||||
extraLibs: this._defaults.getExtraLibs(),
|
extraLibs: this._defaults.getExtraLibs(),
|
||||||
customWorkerPath: this._defaults.workerOptions.customWorkerPath
|
customWorkerPath: this._defaults.workerOptions.customWorkerPath,
|
||||||
|
inlayHintsOptions: this._defaults.inlayHintsOptions
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
219
test/inlayHints.html
Normal file
219
test/inlayHints.html
Normal file
|
|
@ -0,0 +1,219 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||||
|
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
|
||||||
|
<link
|
||||||
|
rel="stylesheet"
|
||||||
|
data-name="vs/editor/editor.main"
|
||||||
|
href="../node_modules/monaco-editor-core/dev/vs/editor/editor.main.css"
|
||||||
|
/>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h2>Monaco Editor TypeScript test page</h2>
|
||||||
|
<button id="resetBtn">Reset Sample</button>
|
||||||
|
<div id="container" style="width: 800px; height: 600px; border: 1px solid grey"></div>
|
||||||
|
<h3>Inlay Hints options</h3>
|
||||||
|
<textarea style="font-family: monospace" id="inlayHintsOpts" cols="60" rows="30"></textarea
|
||||||
|
><br />
|
||||||
|
<button id="updateInlayHintsOptionsBtn">Update Inaly Hints options</button>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
const paths = {
|
||||||
|
'vs/basic-languages': '../node_modules/monaco-languages/release/dev',
|
||||||
|
'vs/language/typescript/fillers/monaco-editor-core':
|
||||||
|
'../out/amd/fillers/monaco-editor-core-amd',
|
||||||
|
'vs/language/typescript': '../out/amd',
|
||||||
|
vs: '../node_modules/monaco-editor-core/dev/vs'
|
||||||
|
};
|
||||||
|
if (document.location.protocol === 'http:') {
|
||||||
|
// Add support for running local http server
|
||||||
|
let testIndex = document.location.pathname.indexOf('/test/');
|
||||||
|
if (testIndex !== -1) {
|
||||||
|
let prefix = document.location.pathname.substr(0, testIndex);
|
||||||
|
paths['vs/language/typescript'] = prefix + '/out/amd';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.require = {
|
||||||
|
paths: paths
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<script src="../node_modules/monaco-editor-core/dev/vs/loader.js"></script>
|
||||||
|
<script src="../node_modules/monaco-editor-core/dev/vs/editor/editor.main.nls.js"></script>
|
||||||
|
<script src="../node_modules/monaco-editor-core/dev/vs/editor/editor.main.js"></script>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
function getDefaultCode() {
|
||||||
|
return [
|
||||||
|
'/* Game of Life',
|
||||||
|
' * Implemented in TypeScript',
|
||||||
|
' * To learn more about TypeScript, please visit http://www.typescriptlang.org/',
|
||||||
|
' */',
|
||||||
|
'',
|
||||||
|
'module Conway {',
|
||||||
|
'',
|
||||||
|
' export class Cell {',
|
||||||
|
' public row: number;',
|
||||||
|
' public col: number;',
|
||||||
|
' public live: boolean;',
|
||||||
|
'',
|
||||||
|
' constructor(row: number, col: number, live: boolean) {',
|
||||||
|
' this.row = row;',
|
||||||
|
' this.col = col;',
|
||||||
|
' this.live = live',
|
||||||
|
' }',
|
||||||
|
' }',
|
||||||
|
'',
|
||||||
|
' export class GameOfLife {',
|
||||||
|
' private gridSize: number;',
|
||||||
|
' private canvasSize: number;',
|
||||||
|
' private lineColor: string;',
|
||||||
|
' private liveColor: string;',
|
||||||
|
' private deadColor: string;',
|
||||||
|
' private initialLifeProbability: number;',
|
||||||
|
' private animationRate: number;',
|
||||||
|
' private cellSize: number;',
|
||||||
|
' private context: CanvasRenderingContext2D;',
|
||||||
|
' private world;',
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
' constructor() {',
|
||||||
|
' this.gridSize = 50;',
|
||||||
|
' this.canvasSize = 600;',
|
||||||
|
" this.lineColor = '#cdcdcd';",
|
||||||
|
" this.liveColor = '#666';",
|
||||||
|
" this.deadColor = '#eee';",
|
||||||
|
' this.initialLifeProbability = 0.5;',
|
||||||
|
' this.animationRate = 60;',
|
||||||
|
' this.cellSize = 0;',
|
||||||
|
' this.world = this.createWorld();',
|
||||||
|
' this.circleOfLife();',
|
||||||
|
' }',
|
||||||
|
'',
|
||||||
|
' public createWorld() {',
|
||||||
|
' return this.travelWorld( (cell : Cell) => {',
|
||||||
|
' cell.live = Math.random() < this.initialLifeProbability;',
|
||||||
|
' return cell;',
|
||||||
|
' });',
|
||||||
|
' }',
|
||||||
|
'',
|
||||||
|
' public circleOfLife() : void {',
|
||||||
|
' this.world = this.travelWorld( (cell: Cell) => {',
|
||||||
|
' cell = this.world[cell.row][cell.col];',
|
||||||
|
' this.draw(cell);',
|
||||||
|
' return this.resolveNextGeneration(cell);',
|
||||||
|
' });',
|
||||||
|
' setTimeout( () => {this.circleOfLife()}, this.animationRate);',
|
||||||
|
' }',
|
||||||
|
'',
|
||||||
|
' public resolveNextGeneration(cell : Cell) {',
|
||||||
|
' var count = this.countNeighbors(cell);',
|
||||||
|
' var newCell = new Cell(cell.row, cell.col, cell.live);',
|
||||||
|
' if(count < 2 || count > 3) newCell.live = false;',
|
||||||
|
' else if(count == 3) newCell.live = true;',
|
||||||
|
' return newCell;',
|
||||||
|
' }',
|
||||||
|
'',
|
||||||
|
' public countNeighbors(cell : Cell) {',
|
||||||
|
' var neighbors = 0;',
|
||||||
|
' for(var row = -1; row <=1; row++) {',
|
||||||
|
' for(var col = -1; col <= 1; col++) {',
|
||||||
|
' if(row == 0 && col == 0) continue;',
|
||||||
|
' if(this.isAlive(cell.row + row, cell.col + col)) {',
|
||||||
|
' neighbors++;',
|
||||||
|
' }',
|
||||||
|
' }',
|
||||||
|
' }',
|
||||||
|
' return neighbors;',
|
||||||
|
' }',
|
||||||
|
'',
|
||||||
|
' public isAlive(row : number, col : number) {',
|
||||||
|
' if(row < 0 || col < 0 || row >= this.gridSize || col >= this.gridSize) return false;',
|
||||||
|
' return this.world[row][col].live;',
|
||||||
|
' }',
|
||||||
|
'',
|
||||||
|
' public travelWorld(callback) {',
|
||||||
|
' var result = [];',
|
||||||
|
' for(var row = 0; row < this.gridSize; row++) {',
|
||||||
|
' var rowData = [];',
|
||||||
|
' for(var col = 0; col < this.gridSize; col++) {',
|
||||||
|
' rowData.push(callback(new Cell(row, col, false)));',
|
||||||
|
' }',
|
||||||
|
' result.push(rowData);',
|
||||||
|
' }',
|
||||||
|
' return result;',
|
||||||
|
' }',
|
||||||
|
'',
|
||||||
|
' public draw(cell : Cell) {',
|
||||||
|
' if(this.context == null) this.context = this.createDrawingContext();',
|
||||||
|
' if(this.cellSize == 0) this.cellSize = this.canvasSize/this.gridSize;',
|
||||||
|
'',
|
||||||
|
' this.context.strokeStyle = this.lineColor;',
|
||||||
|
' this.context.strokeRect(cell.row * this.cellSize, cell.col*this.cellSize, this.cellSize, this.cellSize);',
|
||||||
|
' this.context.fillStyle = cell.live ? this.liveColor : this.deadColor;',
|
||||||
|
' this.context.fillRect(cell.row * this.cellSize, cell.col*this.cellSize, this.cellSize, this.cellSize);',
|
||||||
|
' }',
|
||||||
|
'',
|
||||||
|
' public createDrawingContext() {',
|
||||||
|
" var canvas = <HTMLCanvasElement> document.getElementById('conway-canvas');",
|
||||||
|
' if(canvas == null) {',
|
||||||
|
" canvas = document.createElement('canvas');",
|
||||||
|
" canvas.id = 'conway-canvas';",
|
||||||
|
' canvas.width = this.canvasSize;',
|
||||||
|
' canvas.height = this.canvasSize;',
|
||||||
|
' document.body.appendChild(canvas);',
|
||||||
|
' }',
|
||||||
|
" return canvas.getContext('2d');",
|
||||||
|
' }',
|
||||||
|
' }',
|
||||||
|
'}',
|
||||||
|
'',
|
||||||
|
'var game = new Conway.GameOfLife();'
|
||||||
|
].join('\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
function getDefaultInlayHintsOpts() {
|
||||||
|
return {
|
||||||
|
includeInlayParameterNameHints: 'all',
|
||||||
|
includeInlayParameterNameHintsWhenArgumentMatchesName: true,
|
||||||
|
includeInlayFunctionParameterTypeHints: true,
|
||||||
|
includeInlayVariableTypeHints: true,
|
||||||
|
includeInlayPropertyDeclarationTypeHints: true,
|
||||||
|
includeInlayFunctionLikeReturnTypeHints: true,
|
||||||
|
includeInlayEnumMemberValueHints: true
|
||||||
|
};
|
||||||
|
}
|
||||||
|
require([
|
||||||
|
'vs/basic-languages/monaco.contribution',
|
||||||
|
'vs/language/typescript/monaco.contribution'
|
||||||
|
], () => {
|
||||||
|
const editor = monaco.editor.create(document.getElementById('container'), {
|
||||||
|
value: localStorage.getItem('code') || getDefaultCode(),
|
||||||
|
language: 'typescript',
|
||||||
|
lightbulb: { enabled: true }
|
||||||
|
});
|
||||||
|
|
||||||
|
editor.onDidChangeModelContent(() => {
|
||||||
|
const code = editor.getModel().getValue();
|
||||||
|
localStorage.setItem('code', code);
|
||||||
|
});
|
||||||
|
|
||||||
|
document.getElementById('resetBtn').onclick = () => {
|
||||||
|
editor.setValue(getDefaultCode());
|
||||||
|
};
|
||||||
|
|
||||||
|
const optsString =
|
||||||
|
localStorage.getItem('inlay-hints-opts') ||
|
||||||
|
JSON.stringify(getDefaultInlayHintsOpts(), null, 4);
|
||||||
|
document.getElementById('inlayHintsOpts').textContent = optsString;
|
||||||
|
monaco.languages.typescript.typescriptDefaults.setInlayHintsOptions(JSON.parse(optsString));
|
||||||
|
|
||||||
|
document.getElementById('updateInlayHintsOptionsBtn').onclick = () => {
|
||||||
|
const newOpts = document.getElementById('inlayHintsOpts').value;
|
||||||
|
monaco.languages.typescript.typescriptDefaults.setInlayHintsOptions(JSON.parse(newOpts));
|
||||||
|
localStorage.setItem('inlay-hints-opts', newOpts);
|
||||||
|
};
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Loading…
Add table
Add a link
Reference in a new issue