From c0a0ae7fe466091aa89145aa11f10d42dde5db09 Mon Sep 17 00:00:00 2001 From: ricbet Date: Tue, 26 Dec 2023 11:44:55 +0800 Subject: [PATCH 01/10] feat: support compile common js module --- build/gulpfile.editor.js | 62 +- build/lib/compilation.js | 21 +- build/lib/compilation.ts | 25 +- build/lib/monaco-api.js | 140 +- build/lib/monaco-api.ts | 143 +- build/lib/standalone.js | 10 +- build/lib/standalone.ts | 10 +- build/lib/treeshaking.js | 137 +- build/lib/treeshaking.ts | 153 +- build/monaco/monaco.d.ts.recipe | 27 +- package.json | 1 - src/vs/base/common/cancellation.ts | 4 +- src/vs/editor/common/languages.ts | 6 - src/vs/monaco.d.ts | 2424 ++++++++++++++++++++++++++-- 14 files changed, 2783 insertions(+), 380 deletions(-) diff --git a/build/gulpfile.editor.js b/build/gulpfile.editor.js index 739c37fc677..fbb15996d21 100644 --- a/build/gulpfile.editor.js +++ b/build/gulpfile.editor.js @@ -87,7 +87,8 @@ const extractEditorSrcTask = task.define('extract-editor-src', () => { // Disable mangling for the editor, as it complicates debugging & quite a few users rely on private/protected fields. // Disable NLS task to remove english strings to preserve backwards compatibility when we removed the `vs/nls!` AMD plugin. -const compileEditorAMDTask = task.define('compile-editor-amd', compilation.compileTask('out-editor-src', 'out-editor-build', true, { disableMangle: true, preserveEnglish: true })); +const compileEditorAMDTask = task.define('compile-editor-amd', compilation.compileTask('out-editor-src', 'out-editor-build', true, { disableMangle: true, preserveEnglish: true }, false)); +const compileEditorEsmTask = task.define('compile-editor-esm-core', compilation.compileTask('out-editor-esm', 'out-monaco-editor-core/esm', true, { disableMangle: true }, true, 1 /** CommonJS */)); const bundleEditorAMDTask = task.define('bundle-editor-amd', optimize.bundleTask( { @@ -110,6 +111,21 @@ const createESMSourcesAndResourcesTask = task.define('extract-editor-esm', () => ignores: [ 'inlineEntryPoint:0.ts', 'inlineEntryPoint:1.ts', + 'inlineEntryPoint:0.js', + 'inlineEntryPoint:1.js', + 'inlineEntryPoint:0.js.map', + 'inlineEntryPoint:1.js.map', + 'inlineEntryPoint:0.d.ts', + 'inlineEntryPoint:1.d.ts', + 'inlineEntryPoint.0.ts', + 'inlineEntryPoint.1.ts', + 'inlineEntryPoint.0.js', + 'inlineEntryPoint.1.js', + 'inlineEntryPoint.0.js.map', + 'inlineEntryPoint.1.js.map', + 'inlineEntryPoint.0.d.ts', + 'inlineEntryPoint.1.d.ts', + 'vs/nls.ts', 'vs/loader.js', 'vs/base/worker/workerMain.ts', ], @@ -345,6 +361,13 @@ gulp.task('extract-editor-src', ) ); +const monacodtsTask = task.define('monacodts', () => { + const result = monacoapi.execute(); + fs.writeFileSync(result.filePath, result.content); + fs.writeFileSync(path.join(root, 'src/vs/editor/common/standalone/standaloneEnums.ts'), result.enums); + return Promise.resolve(true); +}); + gulp.task('editor-distro', task.series( task.parallel( @@ -356,21 +379,54 @@ gulp.task('editor-distro', util.rimraf('out-editor-min') ), extractEditorSrcTask, + monacodtsTask, task.parallel( task.series( compileEditorAMDTask, bundleEditorAMDTask, - minifyEditorAMDTask + // minifyEditorAMDTask ), task.series( createESMSourcesAndResourcesTask, - compileEditorESMTask, + appendJSToESMImportsTask, + compileEditorEsmTask ) ), finalEditorResourcesTask ) ); +const bundleEditorESMTask = task.define('editor-esm-bundle-webpack', () => { + const webpack = require('webpack'); + const webpackGulp = require('webpack-stream'); + + const result = es.through(); + + const webpackConfigPath = path.join(root, 'build/monaco/monaco.webpack.config.js'); + + const webpackConfig = { + ...require(webpackConfigPath), + ...{ mode: 'production' } + }; + + const webpackDone = (err, stats) => { + if (err) { + result.emit('error', err); + return; + } + const { compilation } = stats; + if (compilation.errors.length > 0) { + result.emit('error', compilation.errors.join('\n')); + } + if (compilation.warnings.length > 0) { + result.emit('data', compilation.warnings.join('\n')); + } + }; + + return webpackGulp(webpackConfig, webpack, webpackDone) + .pipe(gulp.dest('out-editor-esm-bundle')); +}); + gulp.task('editor-esm', task.series( task.parallel( diff --git a/build/lib/compilation.js b/build/lib/compilation.js index 7b9d73facbb..67df7ef91b5 100644 --- a/build/lib/compilation.js +++ b/build/lib/compilation.js @@ -27,11 +27,14 @@ const ts = require("typescript"); const watch = require('./watch'); // --- gulp-tsb: compile and transpile -------------------------------- const reporter = (0, reporter_1.createReporter)(); -function getTypeScriptCompilerOptions(src) { +function getTypeScriptCompilerOptions(src, module) { const rootDir = path.join(__dirname, `../../${src}`); const options = {}; options.verbose = false; options.sourceMap = true; + if (module) { + options.module = module; + } if (process.env['VSCODE_NO_SOURCEMAP']) { // To be used by developers in a hurry options.sourceMap = false; } @@ -41,13 +44,14 @@ function getTypeScriptCompilerOptions(src) { options.newLine = /\r\n/.test(fs.readFileSync(__filename, 'utf8')) ? 0 : 1; return options; } -function createCompile(src, { build, emitError, transpileOnly, preserveEnglish }) { +function createCompile(src, { build, emitError, transpileOnly, preserveEnglish, module }) { const tsb = require('./tsb'); const sourcemaps = require('gulp-sourcemaps'); const projectPath = path.join(__dirname, '../../', src, 'tsconfig.json'); - const overrideOptions = { ...getTypeScriptCompilerOptions(src), inlineSources: Boolean(build) }; + const overrideOptions = { ...getTypeScriptCompilerOptions(src, module), inlineSources: Boolean(build) }; if (!build) { overrideOptions.inlineSourceMap = true; + overrideOptions.noEmitOnError = false; } const compilation = tsb.create(projectPath, overrideOptions, { verbose: false, @@ -104,7 +108,7 @@ function compileTask(src, out, build, options = {}) { if (os.totalmem() < 4_000_000_000) { throw new Error('compilation requires 4GB of RAM'); } - const compile = createCompile(src, { build, emitError: true, transpileOnly: false, preserveEnglish: !!options.preserveEnglish }); + const compile = createCompile(src, { build, emitError: false, transpileOnly: false, preserveEnglish: !!options.preserveEnglish, module: options.module }); const srcPipe = gulp.src(`${src}/**`, { base: `${src}` }); const generator = new MonacoGenerator(false); if (src === 'src') { @@ -134,11 +138,20 @@ function compileTask(src, out, build, options = {}) { .pipe(mangleStream) .pipe(generator.stream) .pipe(compile()) + .pipe(options.extractConstEnum ? doExtractConstEnum() : es.through()) .pipe(gulp.dest(out)); }; task.taskName = `compile-${path.basename(src)}`; return task; } +function doExtractConstEnum() { + return es.map((file, cb) => { + if (/\.ts$/.test(file.path)) { + file.contents = Buffer.from(file.contents.toString().replace(/const enum/g, 'enum')); + } + cb(null, file); + }); +} function watchTask(out, build, srcPath = 'src') { const task = () => { const compile = createCompile(srcPath, { build, emitError: false, transpileOnly: false, preserveEnglish: false }); diff --git a/build/lib/compilation.ts b/build/lib/compilation.ts index 124bcc17c17..edc3b3cd662 100644 --- a/build/lib/compilation.ts +++ b/build/lib/compilation.ts @@ -27,11 +27,14 @@ const watch = require('./watch'); const reporter = createReporter(); -function getTypeScriptCompilerOptions(src: string): ts.CompilerOptions { +function getTypeScriptCompilerOptions(src: string, module?: ts.ModuleKind): ts.CompilerOptions { const rootDir = path.join(__dirname, `../../${src}`); const options: ts.CompilerOptions = {}; options.verbose = false; options.sourceMap = true; + if (module) { + options.module = module; + } if (process.env['VSCODE_NO_SOURCEMAP']) { // To be used by developers in a hurry options.sourceMap = false; } @@ -47,17 +50,19 @@ interface ICompileTaskOptions { readonly emitError: boolean; readonly transpileOnly: boolean | { esbuild: boolean }; readonly preserveEnglish: boolean; + readonly module?: ts.ModuleKind; } -function createCompile(src: string, { build, emitError, transpileOnly, preserveEnglish }: ICompileTaskOptions) { +function createCompile(src: string, { build, emitError, transpileOnly, preserveEnglish, module }: ICompileTaskOptions) { const tsb = require('./tsb') as typeof import('./tsb'); const sourcemaps = require('gulp-sourcemaps') as typeof import('gulp-sourcemaps'); const projectPath = path.join(__dirname, '../../', src, 'tsconfig.json'); - const overrideOptions = { ...getTypeScriptCompilerOptions(src), inlineSources: Boolean(build) }; + const overrideOptions = { ...getTypeScriptCompilerOptions(src, module), inlineSources: Boolean(build) }; if (!build) { overrideOptions.inlineSourceMap = true; + overrideOptions.noEmitOnError = false; } const compilation = tsb.create(projectPath, overrideOptions, { @@ -121,7 +126,7 @@ export function transpileTask(src: string, out: string, esbuild: boolean): task. return task; } -export function compileTask(src: string, out: string, build: boolean, options: { disableMangle?: boolean; preserveEnglish?: boolean } = {}): task.StreamTask { +export function compileTask(src: string, out: string, build: boolean, options: { disableMangle?: boolean; preserveEnglish?: boolean, extractConstEnum?: boolean, module?: ts.ModuleKind } = {}): task.StreamTask { const task = () => { @@ -129,7 +134,7 @@ export function compileTask(src: string, out: string, build: boolean, options: { throw new Error('compilation requires 4GB of RAM'); } - const compile = createCompile(src, { build, emitError: true, transpileOnly: false, preserveEnglish: !!options.preserveEnglish }); + const compile = createCompile(src, { build, emitError: false, transpileOnly: false, preserveEnglish: !!options.preserveEnglish, module: options.module }); const srcPipe = gulp.src(`${src}/**`, { base: `${src}` }); const generator = new MonacoGenerator(false); if (src === 'src') { @@ -163,6 +168,7 @@ export function compileTask(src: string, out: string, build: boolean, options: { .pipe(mangleStream) .pipe(generator.stream) .pipe(compile()) + .pipe(options.extractConstEnum ? doExtractConstEnum() : es.through()) .pipe(gulp.dest(out)); }; @@ -170,6 +176,15 @@ export function compileTask(src: string, out: string, build: boolean, options: { return task; } +function doExtractConstEnum() { + return es.map((file: File, cb: any) => { + if (/\.ts$/.test(file.path)) { + file.contents = Buffer.from(file.contents.toString().replace(/const enum/g, 'enum')); + } + cb(null, file); + }); +} + export function watchTask(out: string, build: boolean, srcPath: string = 'src'): task.StreamTask { const task = () => { diff --git a/build/lib/monaco-api.js b/build/lib/monaco-api.js index 2052806c46b..c37e24761d5 100644 --- a/build/lib/monaco-api.js +++ b/build/lib/monaco-api.js @@ -58,14 +58,29 @@ function getAllTopLevelDeclarations(ts, sourceFile) { const triviaStart = interfaceDeclaration.pos; const triviaEnd = interfaceDeclaration.name.pos; const triviaText = getNodeText(sourceFile, { pos: triviaStart, end: triviaEnd }); - if (triviaText.indexOf('@internal') === -1) { + if (triviaText.indexOf('@internal') === -1 || node.kind === ts.SyntaxKind.InterfaceDeclaration) { + /** 标记为 @internal 的 class 和 interface 不需要暴露 */ + /** 标记为 @internal 的 class 和 interface 不需要暴露 */ all.push(node); } } else { const nodeText = getNodeText(sourceFile, node); if (nodeText.indexOf('@internal') === -1) { + /** 标记为 @internal 的顶层声明不需要导出 */ + /** + * @example + * ```ts + * export const a = 'test'; + * export function foo() { + * }; + * ``` + */ all.push(node); + /** 标记为 @internal 的顶层声明不需要导出 */ + } + else if (node.kind === ts.SyntaxKind.EnumDeclaration) { + // all.push(node); } } return false /*continue*/; @@ -111,6 +126,24 @@ function isStatic(ts, member) { } return false; } +function isPrivate(ts, member) { + if (ts.canHaveModifiers(member)) { + return hasModifier(ts.getModifiers(member), ts.SyntaxKind.PrivateKeyword); + } + return false; +} +function isProtected(ts, member) { + if (ts.canHaveModifiers(member)) { + return hasModifier(ts.getModifiers(member), ts.SyntaxKind.ProtectedKeyword); + } + return false; +} +function isAbstractClass(ts, member) { + if (ts.canHaveModifiers(member)) { + return hasModifier(ts.getModifiers(member), ts.SyntaxKind.AbstractKeyword); + } + return false; +} function isDefaultExport(ts, declaration) { return (hasModifier(declaration.modifiers, ts.SyntaxKind.DefaultKeyword) && hasModifier(declaration.modifiers, ts.SyntaxKind.ExportKeyword)); @@ -118,41 +151,86 @@ function isDefaultExport(ts, declaration) { function getMassagedTopLevelDeclarationText(ts, sourceFile, declaration, importName, usage, enums) { let result = getNodeText(sourceFile, declaration); if (declaration.kind === ts.SyntaxKind.InterfaceDeclaration || declaration.kind === ts.SyntaxKind.ClassDeclaration) { - const interfaceDeclaration = declaration; - const staticTypeName = (isDefaultExport(ts, interfaceDeclaration) - ? `${importName}.default` - : `${importName}.${declaration.name.text}`); - let instanceTypeName = staticTypeName; - const typeParametersCnt = (interfaceDeclaration.typeParameters ? interfaceDeclaration.typeParameters.length : 0); - if (typeParametersCnt > 0) { - const arr = []; - for (let i = 0; i < typeParametersCnt; i++) { - arr.push('any'); - } - instanceTypeName = `${instanceTypeName}<${arr.join(',')}>`; - } - const members = interfaceDeclaration.members; - members.forEach((member) => { - try { - const memberText = getNodeText(sourceFile, member); - if (memberText.indexOf('@internal') >= 0 || memberText.indexOf('private') >= 0) { - result = result.replace(memberText, ''); + /** + * 不要将标记为 @internal 的 class 和 interface 暴露出来 + * 这里仅需要公开 API 的私有属性 + */ + if (!isAbstractClass(ts, declaration)) { + const interfaceDeclaration = declaration; + const staticTypeName = (isDefaultExport(ts, interfaceDeclaration) + ? `${importName}.default` + : `${importName}.${declaration.name.text}`); + let instanceTypeName = staticTypeName; + const typeParametersCnt = (interfaceDeclaration.typeParameters ? interfaceDeclaration.typeParameters.length : 0); + if (typeParametersCnt > 0) { + const arr = []; + for (let i = 0; i < typeParametersCnt; i++) { + arr.push('any'); } - else { - const memberName = member.name.text; - const memberAccess = (memberName.indexOf('.') >= 0 ? `['${memberName}']` : `.${memberName}`); - if (isStatic(ts, member)) { - usage.push(`a = ${staticTypeName}${memberAccess};`); - } - else { - usage.push(`a = (<${instanceTypeName}>b)${memberAccess};`); + instanceTypeName = `${instanceTypeName}<${arr.join(',')}>`; + } + const members = interfaceDeclaration.members; + members.forEach((member) => { + try { + /** ------------------------ 这段是原始代码,主要内容是过滤掉了 class 的 private 成员与注释为 @internal 的成员 ------------------------ */ + // const memberText = getNodeText(sourceFile, member); + // if (memberText.indexOf('@internal') >= 0 || memberText.indexOf('private') >= 0) { + // result = result.replace(memberText, ''); + // } else { + // const memberName = (member.name).text; + // const memberAccess = (memberName.indexOf('.') >= 0 ? `['${memberName}']` : `.${memberName}`); + // if (isStatic(ts, member)) { + // usage.push(`a = ${staticTypeName}${memberAccess};`); + // } else { + // usage.push(`a = (<${instanceTypeName}>b)${memberAccess};`); + // } + // } + /** ------------------------ 这段是原始代码,主要内容是过滤掉了 class 的 private 成员与注释为 @internal 的成员 ------------------------ */ + /** ------------------------ 这段是修改后的代码,主要内容是过滤掉 private 及 protected 成员,但保留了 @internal 成员 ------------------------ */ + if (!isPrivate(ts, member) && !isProtected(ts, member)) { + // console.log('usage class or interface member', (member.name).text); + const memberName = member.name.text; + const memberAccess = (memberName.indexOf('.') >= 0 ? `['${memberName}']` : `.${memberName}`); + if (isStatic(ts, member)) { + usage.push(`a = ${staticTypeName}${memberAccess};`); + } + else { + const memberText = getNodeText(sourceFile, member); + if (memberText.indexOf('@internal') >= 0) { + // result = result.replace(memberText, ''); + } + else { + } + usage.push(`a = (<${instanceTypeName}>b)${memberAccess};`); + } } + /** ------------------------ 这段是修改后的代码,主要内容是过滤掉 private 及 protected 成员,但保留了 @internal 成员 ------------------------ */ + } + catch (err) { + // life.. + } + }); + } + } + else if (declaration.kind === ts.SyntaxKind.VariableStatement) { + const jsDoc = result.substr(0, declaration.getLeadingTriviaWidth(sourceFile)); + if (jsDoc.indexOf('@monacodtsreplace') >= 0) { + const jsDocLines = jsDoc.split(/\r\n|\r|\n/); + let directives = []; + for (const jsDocLine of jsDocLines) { + const m = jsDocLine.match(/^\s*\* \/([^/]+)\/([^/]+)\/$/); + if (m) { + directives.push([new RegExp(m[1], 'g'), m[2]]); } } - catch (err) { - // life.. + // remove the jsdoc + result = result.substr(jsDoc.length); + if (directives.length > 0) { + // apply replace directives + const replacer = createReplacerFromDirectives(directives); + result = replacer(result); } - }); + } } result = result.replace(/export default /g, 'export '); result = result.replace(/export declare /g, 'export '); diff --git a/build/lib/monaco-api.ts b/build/lib/monaco-api.ts index 288bec0f858..918de5729a0 100644 --- a/build/lib/monaco-api.ts +++ b/build/lib/monaco-api.ts @@ -75,13 +75,27 @@ function getAllTopLevelDeclarations(ts: typeof import('typescript'), sourceFile: const triviaEnd = interfaceDeclaration.name.pos; const triviaText = getNodeText(sourceFile, { pos: triviaStart, end: triviaEnd }); - if (triviaText.indexOf('@internal') === -1) { + if (triviaText.indexOf('@internal') === -1 || node.kind === ts.SyntaxKind.InterfaceDeclaration) { + /** 标记为 @internal 的 class 和 interface 不需要暴露 */ + /** 标记为 @internal 的 class 和 interface 不需要暴露 */ all.push(node); } } else { const nodeText = getNodeText(sourceFile, node); if (nodeText.indexOf('@internal') === -1) { + /** 标记为 @internal 的顶层声明不需要导出 */ + /** + * @example + * ```ts + * export const a = 'test'; + * export function foo() { + * }; + * ``` + */ all.push(node); + /** 标记为 @internal 的顶层声明不需要导出 */ + } else if (node.kind === ts.SyntaxKind.EnumDeclaration) { + // all.push(node); } } return false /*continue*/; @@ -134,6 +148,27 @@ function isStatic(ts: typeof import('typescript'), member: ts.ClassElement | ts. return false; } +function isPrivate(ts: typeof import('typescript'), member: ts.ClassElement | ts.TypeElement): boolean { + if (ts.canHaveModifiers(member)) { + return hasModifier(ts.getModifiers(member), ts.SyntaxKind.PrivateKeyword); + } + return false; +} + +function isProtected(ts: typeof import('typescript'), member: ts.ClassElement | ts.TypeElement): boolean { + if (ts.canHaveModifiers(member)) { + return hasModifier(ts.getModifiers(member), ts.SyntaxKind.ProtectedKeyword); + } + return false; +} + +function isAbstractClass(ts: typeof import('typescript'), member: ts.ClassDeclaration): boolean { + if (ts.canHaveModifiers(member)) { + return hasModifier(ts.getModifiers(member), ts.SyntaxKind.AbstractKeyword); + } + return false; +} + function isDefaultExport(ts: typeof import('typescript'), declaration: ts.InterfaceDeclaration | ts.ClassDeclaration): boolean { return ( hasModifier(declaration.modifiers, ts.SyntaxKind.DefaultKeyword) @@ -144,43 +179,89 @@ function isDefaultExport(ts: typeof import('typescript'), declaration: ts.Interf function getMassagedTopLevelDeclarationText(ts: typeof import('typescript'), sourceFile: ts.SourceFile, declaration: TSTopLevelDeclare, importName: string, usage: string[], enums: IEnumEntry[]): string { let result = getNodeText(sourceFile, declaration); if (declaration.kind === ts.SyntaxKind.InterfaceDeclaration || declaration.kind === ts.SyntaxKind.ClassDeclaration) { - const interfaceDeclaration = declaration; - const staticTypeName = ( - isDefaultExport(ts, interfaceDeclaration) - ? `${importName}.default` - : `${importName}.${declaration.name!.text}` - ); + /** + * 不要将标记为 @internal 的 class 和 interface 暴露出来 + * 这里仅需要公开 API 的私有属性 + */ + if (!isAbstractClass(ts, declaration)) { + const interfaceDeclaration = declaration; + + const staticTypeName = ( + isDefaultExport(ts, interfaceDeclaration) + ? `${importName}.default` + : `${importName}.${declaration.name!.text}` + ); - let instanceTypeName = staticTypeName; - const typeParametersCnt = (interfaceDeclaration.typeParameters ? interfaceDeclaration.typeParameters.length : 0); - if (typeParametersCnt > 0) { - const arr: string[] = []; - for (let i = 0; i < typeParametersCnt; i++) { - arr.push('any'); + let instanceTypeName = staticTypeName; + const typeParametersCnt = (interfaceDeclaration.typeParameters ? interfaceDeclaration.typeParameters.length : 0); + if (typeParametersCnt > 0) { + const arr: string[] = []; + for (let i = 0; i < typeParametersCnt; i++) { + arr.push('any'); + } + instanceTypeName = `${instanceTypeName}<${arr.join(',')}>`; } - instanceTypeName = `${instanceTypeName}<${arr.join(',')}>`; - } - const members: ts.NodeArray = interfaceDeclaration.members; - members.forEach((member) => { - try { - const memberText = getNodeText(sourceFile, member); - if (memberText.indexOf('@internal') >= 0 || memberText.indexOf('private') >= 0) { - result = result.replace(memberText, ''); - } else { - const memberName = (member.name).text; - const memberAccess = (memberName.indexOf('.') >= 0 ? `['${memberName}']` : `.${memberName}`); - if (isStatic(ts, member)) { - usage.push(`a = ${staticTypeName}${memberAccess};`); - } else { - usage.push(`a = (<${instanceTypeName}>b)${memberAccess};`); + const members: ts.NodeArray = interfaceDeclaration.members; + members.forEach((member) => { + try { + /** ------------------------ 这段是原始代码,主要内容是过滤掉了 class 的 private 成员与注释为 @internal 的成员 ------------------------ */ + // const memberText = getNodeText(sourceFile, member); + // if (memberText.indexOf('@internal') >= 0 || memberText.indexOf('private') >= 0) { + // result = result.replace(memberText, ''); + // } else { + // const memberName = (member.name).text; + // const memberAccess = (memberName.indexOf('.') >= 0 ? `['${memberName}']` : `.${memberName}`); + // if (isStatic(ts, member)) { + // usage.push(`a = ${staticTypeName}${memberAccess};`); + // } else { + // usage.push(`a = (<${instanceTypeName}>b)${memberAccess};`); + // } + // } + /** ------------------------ 这段是原始代码,主要内容是过滤掉了 class 的 private 成员与注释为 @internal 的成员 ------------------------ */ + + /** ------------------------ 这段是修改后的代码,主要内容是过滤掉 private 及 protected 成员,但保留了 @internal 成员 ------------------------ */ + if (!isPrivate(ts, member) && !isProtected(ts, member)) { + // console.log('usage class or interface member', (member.name).text); + const memberName = (member.name).text; + const memberAccess = (memberName.indexOf('.') >= 0 ? `['${memberName}']` : `.${memberName}`); + if (isStatic(ts, member)) { + usage.push(`a = ${staticTypeName}${memberAccess};`); + } else { + const memberText = getNodeText(sourceFile, member); + if (memberText.indexOf('@internal') >= 0) { + // result = result.replace(memberText, ''); + } else { + } + usage.push(`a = (<${instanceTypeName}>b)${memberAccess};`); + } } + /** ------------------------ 这段是修改后的代码,主要内容是过滤掉 private 及 protected 成员,但保留了 @internal 成员 ------------------------ */ + } catch (err) { + // life.. + } + }); + } + } else if (declaration.kind === ts.SyntaxKind.VariableStatement) { + const jsDoc = result.substr(0, declaration.getLeadingTriviaWidth(sourceFile)); + if (jsDoc.indexOf('@monacodtsreplace') >= 0) { + const jsDocLines = jsDoc.split(/\r\n|\r|\n/); + let directives: [RegExp, string][] = []; + for (const jsDocLine of jsDocLines) { + const m = jsDocLine.match(/^\s*\* \/([^/]+)\/([^/]+)\/$/); + if (m) { + directives.push([new RegExp(m[1], 'g'), m[2]]); } - } catch (err) { - // life.. } - }); + // remove the jsdoc + result = result.substr(jsDoc.length); + if (directives.length > 0) { + // apply replace directives + const replacer = createReplacerFromDirectives(directives); + result = replacer(result); + } + } } result = result.replace(/export default /g, 'export '); result = result.replace(/export declare /g, 'export '); diff --git a/build/lib/standalone.js b/build/lib/standalone.js index 16ae1e2b2d8..3bc083cb507 100644 --- a/build/lib/standalone.js +++ b/build/lib/standalone.js @@ -41,8 +41,8 @@ function extractEditor(options) { tsConfig.compilerOptions = compilerOptions; compilerOptions.noEmit = false; compilerOptions.noUnusedLocals = false; - compilerOptions.preserveConstEnums = false; - compilerOptions.declaration = false; + compilerOptions.preserveConstEnums = true; + compilerOptions.declaration = true; compilerOptions.moduleResolution = ts.ModuleResolutionKind.Classic; options.compilerOptions = compilerOptions; console.log(`Running tree shaker with shakeLevel ${tss.toStringShakeLevel(options.shakeLevel)}`); @@ -174,7 +174,8 @@ function createESMSourcesAndResources2(options) { mode = 1; continue; } - if (/\/\/ ESM-uncomment-begin/.test(line)) { + // if (/\/\/ ESM-uncomment-begin/.test(line)) { + if (/\/\/ CJS-comment-begin/.test(line)) { mode = 2; continue; } @@ -189,7 +190,8 @@ function createESMSourcesAndResources2(options) { continue; } if (mode === 2) { - if (/\/\/ ESM-uncomment-end/.test(line)) { + // if (/\/\/ ESM-uncomment-end/.test(line)) { + if (/\/\/ CJS-comment-end/.test(line)) { mode = 0; continue; } diff --git a/build/lib/standalone.ts b/build/lib/standalone.ts index 8736583fb09..76e0a5ed822 100644 --- a/build/lib/standalone.ts +++ b/build/lib/standalone.ts @@ -44,8 +44,8 @@ export function extractEditor(options: tss.ITreeShakingOptions & { destRoot: str compilerOptions.noEmit = false; compilerOptions.noUnusedLocals = false; - compilerOptions.preserveConstEnums = false; - compilerOptions.declaration = false; + compilerOptions.preserveConstEnums = true; + compilerOptions.declaration = true; compilerOptions.moduleResolution = ts.ModuleResolutionKind.Classic; @@ -206,7 +206,8 @@ export function createESMSourcesAndResources2(options: IOptions2): void { mode = 1; continue; } - if (/\/\/ ESM-uncomment-begin/.test(line)) { + // if (/\/\/ ESM-uncomment-begin/.test(line)) { + if (/\/\/ CJS-comment-begin/.test(line)) { mode = 2; continue; } @@ -223,7 +224,8 @@ export function createESMSourcesAndResources2(options: IOptions2): void { } if (mode === 2) { - if (/\/\/ ESM-uncomment-end/.test(line)) { + // if (/\/\/ ESM-uncomment-end/.test(line)) { + if (/\/\/ CJS-comment-end/.test(line)) { mode = 0; continue; } diff --git a/build/lib/treeshaking.js b/build/lib/treeshaking.js index af06f4e3ec5..9b4f8faccd6 100644 --- a/build/lib/treeshaking.js +++ b/build/lib/treeshaking.js @@ -285,6 +285,7 @@ function isVariableStatementWithSideEffects(ts, node) { node.forEachChild(visitNode); return hasSideEffects; } +// @ts-ignore function isStaticMemberWithSideEffects(ts, node) { if (!ts.isPropertyDeclaration(node)) { return false; @@ -377,6 +378,7 @@ function markNodes(ts, languageService, options) { } while (_node); return null; } + // @ts-ignore function enqueue_gray(node) { if (nodeOrParentIsBlack(node) || getColor(node) === 1 /* NodeColor.Gray */) { return; @@ -418,25 +420,27 @@ function markNodes(ts, languageService, options) { } setColor(node, 2 /* NodeColor.Black */); black_queue.push(node); - if (options.shakeLevel === 2 /* ShakeLevel.ClassMembers */ && (ts.isMethodDeclaration(node) || ts.isMethodSignature(node) || ts.isPropertySignature(node) || ts.isPropertyDeclaration(node) || ts.isGetAccessor(node) || ts.isSetAccessor(node))) { - const references = languageService.getReferencesAtPosition(node.getSourceFile().fileName, node.name.pos + node.name.getLeadingTriviaWidth()); - if (references) { - for (let i = 0, len = references.length; i < len; i++) { - const reference = references[i]; - const referenceSourceFile = program.getSourceFile(reference.fileName); - if (!referenceSourceFile) { - continue; - } - const referenceNode = getTokenAtPosition(ts, referenceSourceFile, reference.textSpan.start, false, false); - if (ts.isMethodDeclaration(referenceNode.parent) - || ts.isPropertyDeclaration(referenceNode.parent) - || ts.isGetAccessor(referenceNode.parent) - || ts.isSetAccessor(referenceNode.parent)) { - enqueue_gray(referenceNode.parent); - } - } - } - } + // if (options.shakeLevel === ShakeLevel.ClassMembers && (ts.isMethodDeclaration(node) || ts.isMethodSignature(node) || ts.isPropertySignature(node) || ts.isPropertyDeclaration(node) || ts.isGetAccessor(node) || ts.isSetAccessor(node))) { + // const references = languageService.getReferencesAtPosition(node.getSourceFile().fileName, node.name.pos + node.name.getLeadingTriviaWidth()); + // if (references) { + // for (let i = 0, len = references.length; i < len; i++) { + // const reference = references[i]; + // const referenceSourceFile = program!.getSourceFile(reference.fileName); + // if (!referenceSourceFile) { + // continue; + // } + // const referenceNode = getTokenAtPosition(ts, referenceSourceFile, reference.textSpan.start, false, false); + // if ( + // ts.isMethodDeclaration(referenceNode.parent) + // || ts.isPropertyDeclaration(referenceNode.parent) + // || ts.isGetAccessor(referenceNode.parent) + // || ts.isSetAccessor(referenceNode.parent) + // ) { + // enqueue_gray(referenceNode.parent); + // } + // } + // } + // } } function enqueueFile(filename) { const sourceFile = program.getSourceFile(filename); @@ -515,38 +519,38 @@ function markNodes(ts, languageService, options) { // (they can be the declaration of a module import) continue; } - if (options.shakeLevel === 2 /* ShakeLevel.ClassMembers */ && (ts.isClassDeclaration(declaration) || ts.isInterfaceDeclaration(declaration)) && !isLocalCodeExtendingOrInheritingFromDefaultLibSymbol(ts, program, checker, declaration)) { - enqueue_black(declaration.name); - for (let j = 0; j < declaration.members.length; j++) { - const member = declaration.members[j]; - const memberName = member.name ? member.name.getText() : null; - if (ts.isConstructorDeclaration(member) - || ts.isConstructSignatureDeclaration(member) - || ts.isIndexSignatureDeclaration(member) - || ts.isCallSignatureDeclaration(member) - || memberName === '[Symbol.iterator]' - || memberName === '[Symbol.toStringTag]' - || memberName === 'toJSON' - || memberName === 'toString' - || memberName === 'dispose' // TODO: keeping all `dispose` methods - || /^_(.*)Brand$/.test(memberName || '') // TODO: keeping all members ending with `Brand`... - ) { - enqueue_black(member); - } - if (isStaticMemberWithSideEffects(ts, member)) { - enqueue_black(member); - } - } - // queue the heritage clauses - if (declaration.heritageClauses) { - for (const heritageClause of declaration.heritageClauses) { - enqueue_black(heritageClause); - } - } - } - else { - enqueue_black(declaration); - } + // if (options.shakeLevel === ShakeLevel.ClassMembers && (ts.isClassDeclaration(declaration) || ts.isInterfaceDeclaration(declaration)) && !isLocalCodeExtendingOrInheritingFromDefaultLibSymbol(ts, program, checker, declaration)) { + // enqueue_black(declaration.name!); + // for (let j = 0; j < declaration.members.length; j++) { + // const member = declaration.members[j]; + // const memberName = member.name ? member.name.getText() : null; + // if ( + // ts.isConstructorDeclaration(member) + // || ts.isConstructSignatureDeclaration(member) + // || ts.isIndexSignatureDeclaration(member) + // || ts.isCallSignatureDeclaration(member) + // || memberName === '[Symbol.iterator]' + // || memberName === '[Symbol.toStringTag]' + // || memberName === 'toJSON' + // || memberName === 'toString' + // || memberName === 'dispose'// TODO: keeping all `dispose` methods + // || /^_(.*)Brand$/.test(memberName || '') // TODO: keeping all members ending with `Brand`... + // ) { + // enqueue_black(member); + // } + // if (isStaticMemberWithSideEffects(ts, member)) { + // enqueue_black(member); + // } + // } + // // queue the heritage clauses + // if (declaration.heritageClauses) { + // for (const heritageClause of declaration.heritageClauses) { + // enqueue_black(heritageClause); + // } + // } + // } else { + enqueue_black(declaration); + // } } } } @@ -583,6 +587,7 @@ function nodeIsInItsOwnDeclaration(nodeSourceFile, node, symbol) { } return false; } +// @ts-ignore function generateResult(ts, languageService, shakeLevel) { const program = languageService.getProgram(); if (!program) { @@ -676,20 +681,20 @@ function generateResult(ts, languageService, shakeLevel) { } } } - if (shakeLevel === 2 /* ShakeLevel.ClassMembers */ && (ts.isClassDeclaration(node) || ts.isInterfaceDeclaration(node)) && nodeOrChildIsBlack(node)) { - let toWrite = node.getFullText(); - for (let i = node.members.length - 1; i >= 0; i--) { - const member = node.members[i]; - if (getColor(member) === 2 /* NodeColor.Black */ || !member.name) { - // keep method - continue; - } - const pos = member.pos - node.pos; - const end = member.end - node.pos; - toWrite = toWrite.substring(0, pos) + toWrite.substring(end); - } - return write(toWrite); - } + // if (shakeLevel === ShakeLevel.ClassMembers && (ts.isClassDeclaration(node) || ts.isInterfaceDeclaration(node)) && nodeOrChildIsBlack(node)) { + // let toWrite = node.getFullText(); + // for (let i = node.members.length - 1; i >= 0; i--) { + // const member = node.members[i]; + // if (getColor(member) === NodeColor.Black || !member.name) { + // // keep method + // continue; + // } + // const pos = member.pos - node.pos; + // const end = member.end - node.pos; + // toWrite = toWrite.substring(0, pos) + toWrite.substring(end); + // } + // return write(toWrite); + // } if (ts.isFunctionDeclaration(node)) { // Do not go inside functions if they haven't been marked return; @@ -725,6 +730,7 @@ function generateResult(ts, languageService, shakeLevel) { } //#endregion //#region Utils +// @ts-ignore function isLocalCodeExtendingOrInheritingFromDefaultLibSymbol(ts, program, checker, declaration) { if (!program.isSourceFileDefaultLibrary(declaration.getSourceFile()) && declaration.heritageClauses) { for (const heritageClause of declaration.heritageClauses) { @@ -885,6 +891,7 @@ function getRealNodeSymbol(ts, checker, node) { } } /** Get the token whose text contains the position */ +// @ts-ignore function getTokenAtPosition(ts, sourceFile, position, allowPositionInLeadingTrivia, includeEndPosition) { let current = sourceFile; outer: while (true) { diff --git a/build/lib/treeshaking.ts b/build/lib/treeshaking.ts index cd17c5f0278..0c649a44b17 100644 --- a/build/lib/treeshaking.ts +++ b/build/lib/treeshaking.ts @@ -366,7 +366,7 @@ function isVariableStatementWithSideEffects(ts: typeof import('typescript'), nod node.forEachChild(visitNode); return hasSideEffects; } - +// @ts-ignore function isStaticMemberWithSideEffects(ts: typeof import('typescript'), node: ts.ClassElement | ts.TypeElement): boolean { if (!ts.isPropertyDeclaration(node)) { return false; @@ -473,7 +473,7 @@ function markNodes(ts: typeof import('typescript'), languageService: ts.Language } while (_node); return null; } - + // @ts-ignore function enqueue_gray(node: ts.Node): void { if (nodeOrParentIsBlack(node) || getColor(node) === NodeColor.Gray) { return; @@ -526,28 +526,28 @@ function markNodes(ts: typeof import('typescript'), languageService: ts.Language setColor(node, NodeColor.Black); black_queue.push(node); - if (options.shakeLevel === ShakeLevel.ClassMembers && (ts.isMethodDeclaration(node) || ts.isMethodSignature(node) || ts.isPropertySignature(node) || ts.isPropertyDeclaration(node) || ts.isGetAccessor(node) || ts.isSetAccessor(node))) { - const references = languageService.getReferencesAtPosition(node.getSourceFile().fileName, node.name.pos + node.name.getLeadingTriviaWidth()); - if (references) { - for (let i = 0, len = references.length; i < len; i++) { - const reference = references[i]; - const referenceSourceFile = program!.getSourceFile(reference.fileName); - if (!referenceSourceFile) { - continue; - } - - const referenceNode = getTokenAtPosition(ts, referenceSourceFile, reference.textSpan.start, false, false); - if ( - ts.isMethodDeclaration(referenceNode.parent) - || ts.isPropertyDeclaration(referenceNode.parent) - || ts.isGetAccessor(referenceNode.parent) - || ts.isSetAccessor(referenceNode.parent) - ) { - enqueue_gray(referenceNode.parent); - } - } - } - } + // if (options.shakeLevel === ShakeLevel.ClassMembers && (ts.isMethodDeclaration(node) || ts.isMethodSignature(node) || ts.isPropertySignature(node) || ts.isPropertyDeclaration(node) || ts.isGetAccessor(node) || ts.isSetAccessor(node))) { + // const references = languageService.getReferencesAtPosition(node.getSourceFile().fileName, node.name.pos + node.name.getLeadingTriviaWidth()); + // if (references) { + // for (let i = 0, len = references.length; i < len; i++) { + // const reference = references[i]; + // const referenceSourceFile = program!.getSourceFile(reference.fileName); + // if (!referenceSourceFile) { + // continue; + // } + + // const referenceNode = getTokenAtPosition(ts, referenceSourceFile, reference.textSpan.start, false, false); + // if ( + // ts.isMethodDeclaration(referenceNode.parent) + // || ts.isPropertyDeclaration(referenceNode.parent) + // || ts.isGetAccessor(referenceNode.parent) + // || ts.isSetAccessor(referenceNode.parent) + // ) { + // enqueue_gray(referenceNode.parent); + // } + // } + // } + // } } function enqueueFile(filename: string): void { @@ -636,41 +636,41 @@ function markNodes(ts: typeof import('typescript'), languageService: ts.Language continue; } - if (options.shakeLevel === ShakeLevel.ClassMembers && (ts.isClassDeclaration(declaration) || ts.isInterfaceDeclaration(declaration)) && !isLocalCodeExtendingOrInheritingFromDefaultLibSymbol(ts, program, checker, declaration)) { - enqueue_black(declaration.name!); - - for (let j = 0; j < declaration.members.length; j++) { - const member = declaration.members[j]; - const memberName = member.name ? member.name.getText() : null; - if ( - ts.isConstructorDeclaration(member) - || ts.isConstructSignatureDeclaration(member) - || ts.isIndexSignatureDeclaration(member) - || ts.isCallSignatureDeclaration(member) - || memberName === '[Symbol.iterator]' - || memberName === '[Symbol.toStringTag]' - || memberName === 'toJSON' - || memberName === 'toString' - || memberName === 'dispose'// TODO: keeping all `dispose` methods - || /^_(.*)Brand$/.test(memberName || '') // TODO: keeping all members ending with `Brand`... - ) { - enqueue_black(member); - } - - if (isStaticMemberWithSideEffects(ts, member)) { - enqueue_black(member); - } - } - - // queue the heritage clauses - if (declaration.heritageClauses) { - for (const heritageClause of declaration.heritageClauses) { - enqueue_black(heritageClause); - } - } - } else { - enqueue_black(declaration); - } + // if (options.shakeLevel === ShakeLevel.ClassMembers && (ts.isClassDeclaration(declaration) || ts.isInterfaceDeclaration(declaration)) && !isLocalCodeExtendingOrInheritingFromDefaultLibSymbol(ts, program, checker, declaration)) { + // enqueue_black(declaration.name!); + + // for (let j = 0; j < declaration.members.length; j++) { + // const member = declaration.members[j]; + // const memberName = member.name ? member.name.getText() : null; + // if ( + // ts.isConstructorDeclaration(member) + // || ts.isConstructSignatureDeclaration(member) + // || ts.isIndexSignatureDeclaration(member) + // || ts.isCallSignatureDeclaration(member) + // || memberName === '[Symbol.iterator]' + // || memberName === '[Symbol.toStringTag]' + // || memberName === 'toJSON' + // || memberName === 'toString' + // || memberName === 'dispose'// TODO: keeping all `dispose` methods + // || /^_(.*)Brand$/.test(memberName || '') // TODO: keeping all members ending with `Brand`... + // ) { + // enqueue_black(member); + // } + + // if (isStaticMemberWithSideEffects(ts, member)) { + // enqueue_black(member); + // } + // } + + // // queue the heritage clauses + // if (declaration.heritageClauses) { + // for (const heritageClause of declaration.heritageClauses) { + // enqueue_black(heritageClause); + // } + // } + // } else { + enqueue_black(declaration); + // } } } } @@ -711,7 +711,7 @@ function nodeIsInItsOwnDeclaration(nodeSourceFile: ts.SourceFile, node: ts.Node, return false; } - +// @ts-ignore function generateResult(ts: typeof import('typescript'), languageService: ts.LanguageService, shakeLevel: ShakeLevel): ITreeShakingResult { const program = languageService.getProgram(); if (!program) { @@ -812,21 +812,21 @@ function generateResult(ts: typeof import('typescript'), languageService: ts.Lan } } - if (shakeLevel === ShakeLevel.ClassMembers && (ts.isClassDeclaration(node) || ts.isInterfaceDeclaration(node)) && nodeOrChildIsBlack(node)) { - let toWrite = node.getFullText(); - for (let i = node.members.length - 1; i >= 0; i--) { - const member = node.members[i]; - if (getColor(member) === NodeColor.Black || !member.name) { - // keep method - continue; - } - - const pos = member.pos - node.pos; - const end = member.end - node.pos; - toWrite = toWrite.substring(0, pos) + toWrite.substring(end); - } - return write(toWrite); - } + // if (shakeLevel === ShakeLevel.ClassMembers && (ts.isClassDeclaration(node) || ts.isInterfaceDeclaration(node)) && nodeOrChildIsBlack(node)) { + // let toWrite = node.getFullText(); + // for (let i = node.members.length - 1; i >= 0; i--) { + // const member = node.members[i]; + // if (getColor(member) === NodeColor.Black || !member.name) { + // // keep method + // continue; + // } + + // const pos = member.pos - node.pos; + // const end = member.end - node.pos; + // toWrite = toWrite.substring(0, pos) + toWrite.substring(end); + // } + // return write(toWrite); + // } if (ts.isFunctionDeclaration(node)) { // Do not go inside functions if they haven't been marked @@ -866,7 +866,7 @@ function generateResult(ts: typeof import('typescript'), languageService: ts.Lan //#endregion //#region Utils - +// @ts-ignore function isLocalCodeExtendingOrInheritingFromDefaultLibSymbol(ts: typeof import('typescript'), program: ts.Program, checker: ts.TypeChecker, declaration: ts.ClassDeclaration | ts.InterfaceDeclaration): boolean { if (!program.isSourceFileDefaultLibrary(declaration.getSourceFile()) && declaration.heritageClauses) { for (const heritageClause of declaration.heritageClauses) { @@ -1044,6 +1044,7 @@ function getRealNodeSymbol(ts: typeof import('typescript'), checker: ts.TypeChec } /** Get the token whose text contains the position */ +// @ts-ignore function getTokenAtPosition(ts: typeof import('typescript'), sourceFile: ts.SourceFile, position: number, allowPositionInLeadingTrivia: boolean, includeEndPosition: boolean): ts.Node { let current: ts.Node = sourceFile; outer: while (true) { diff --git a/build/monaco/monaco.d.ts.recipe b/build/monaco/monaco.d.ts.recipe index ef5c2e39ae5..15c7975454a 100644 --- a/build/monaco/monaco.d.ts.recipe +++ b/build/monaco/monaco.d.ts.recipe @@ -79,7 +79,7 @@ declare namespace monaco { #include(vs/base/common/keyCodes): KeyCode #include(vs/editor/common/services/editorBaseApi): KeyMod #include(vs/base/common/htmlContent): IMarkdownString, MarkdownStringTrustedOptions -#include(vs/base/browser/keyboardEvent): IKeyboardEvent +#include(vs/base/browser/keyboardEvent;KeyCodeChord=>any): IKeyboardEvent #include(vs/base/browser/mouseEvent): IMouseEvent #include(vs/editor/common/editorCommon): IScrollEvent #include(vs/editor/common/core/position): IPosition, Position @@ -109,20 +109,22 @@ export interface ICommandMetadata { #include(vs/platform/markers/common/markers): IMarker, IMarkerData, IRelatedInformation #include(vs/editor/standalone/browser/colorizer): IColorizerOptions, IColorizerElementOptions #include(vs/base/common/scrollable): ScrollbarVisibility -#include(vs/base/common/themables): ThemeColor +#include(vs/base/common/themables): ThemeIcon,ThemeColor #include(vs/editor/common/core/editOperation): ISingleEditOperation #include(vs/editor/common/core/wordHelper): IWordAtPosition -#includeAll(vs/editor/common/model): IScrollEvent #include(vs/editor/common/diff/legacyLinesDiffComputer): IChange, ICharChange, ILineChange #include(vs/editor/common/core/dimension): IDimension #includeAll(vs/editor/common/editorCommon): IScrollEvent #includeAll(vs/editor/common/textModelEvents): +#includeAll(vs/editor/common/config/editorOptions;IConfigurationPropertySchema=>any;ComputeOptionsMemory):BaseEditorOption,ComputedEditorOption,EditorFontLigatures,EditorLayoutInfoComputer,EditorLayoutInfoComputerEnv +#include(vs/editor/browser/config/editorConfiguration): IEditorConstructionOptions #includeAll(vs/editor/common/cursorEvents): +#includeAll(vs/editor/browser/editorBrowser;IMouseWheelEvent=>any;editorCommon.=>;InjectedText=>any;ServicesAccessor=>any;IViewModel=>any;IDiffComputationResult=>any;IContextKeyService=>any;IBoundarySashes=>any):IOverviewRuler +#include(vs/editor/common/config/fontInfo;IValidatedEditorOptions=>any): FontInfo, BareFontInfo +#includeAll(vs/editor/common/model;StandardTokenType=>any;IBracketPairsTextModelPart=>any;ITokenizationTextModelPart=>any;IGuidesTextModelPart=>any;LanguageIdentifier=>any;ContiguousMultilineTokens=>any;SparseMultilineTokens=>any;InternalModelContentChangeEvent=>any;MultilineTokens=>any;MultilineTokens2=>any;LineTokens=>any;SearchData=>any;LanguageId=>any;FormattingOptions=>languages.FormattingOptions;ModelRawContentChangedEvent=>any;ApplyEditsResult=>any;ValidAnnotatedEditOperation=>any;TextChange=> any;ModelInjectedTextChangedEvent=>any;PositionNormalizationAffinity=>any;IndentGuide=>any;ILanguageSelection=>languages.ILanguageSelection;UndoRedoGroup=>any): IScrollEvent,TextChange #include(vs/platform/accessibility/common/accessibility): AccessibilitySupport -#includeAll(vs/editor/common/config/editorOptions): -#include(vs/editor/browser/config/editorConfiguration): IEditorConstructionOptions -#includeAll(vs/editor/browser/editorBrowser;editorCommon.=>): -#include(vs/editor/common/config/fontInfo): FontInfo, BareFontInfo +#include(vs/editor/common/viewModel): IEditorWhitespace + #include(vs/editor/common/config/editorZoom): EditorZoom, IEditorZoom //compatibility: @@ -134,16 +136,19 @@ declare namespace monaco.languages { #include(vs/base/common/glob): IRelativePattern #include(vs/editor/common/languageSelector): LanguageSelector, LanguageFilter -#includeAll(vs/editor/standalone/browser/standaloneLanguages;languages.=>;editorCommon.=>editor.;model.=>editor.;IMarkerData=>editor.IMarkerData): +#includeAll(vs/editor/standalone/browser/standaloneLanguages;modes.=>;languages.=>;editorCommon.=>editor.;model.=>editor.;IMarkerData=>editor.IMarkerData): #includeAll(vs/editor/common/languages/languageConfiguration): -#includeAll(vs/editor/common/languages;IMarkerData=>editor.IMarkerData;ISingleEditOperation=>editor.ISingleEditOperation;model.=>editor.): Token -#include(vs/editor/common/languages/language): ILanguageExtensionPoint +#includeAll(vs/editor/common/languages;IMarkerData=>editor.IMarkerData;ISingleEditOperation=>editor.ISingleEditOperation;model.=>editor.;CommentMode=>any;ExtensionIdentifier=>any;ITokenizationSupportFactory=>any;CommentThreadState=>any;CommentThreadCollapsibleState=>any;CommentThreadState=>any;ContiguousMultilineTokens=>any;ThemeIcon=>editor.ThemeIcon;VSBuffer=>any):ITokenPresentation,ILanguageIdCodec,ITokenizationRegistry,ITokenizationSupport,ILazyTokenizationSupport,ITokenizationSupportFactory,CodeActionContext,Token,DocumentPasteEditProvider,DocumentOnDropEditProvider +#include(vs/editor/common/languages/language): ILanguageExtensionPoint,ILanguageIcon,ILanguageSelection #includeAll(vs/editor/standalone/common/monarch/monarchTypes): - +export type InlineValue = InlineValueText | InlineValueVariableLookup | InlineValueExpression; } declare namespace monaco.worker { +#include(vs/editor/common/languages/defaultDocumentColorsComputer):IDocumentColorComputerTarget +#include(vs/editor/common/core/wordHelper):IWordAtPosition +#include(vs/editor/common/languages/linkComputer):ILinkComputerTarget #include(vs/editor/common/model/mirrorTextModel): IMirrorTextModel #includeAll(vs/editor/common/services/editorSimpleWorker;): diff --git a/package.json b/package.json index 78bebe05ee6..155daf2d243 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,6 @@ "watch-extensions": "node --max-old-space-size=8192 ./node_modules/gulp/bin/gulp.js watch-extensions watch-extension-media", "watch-extensionsd": "deemon npm run watch-extensions", "kill-watch-extensionsd": "deemon --kill npm run watch-extensions", - "precommit": "node build/hygiene.js", "gulp": "node --max-old-space-size=8192 ./node_modules/gulp/bin/gulp.js", "electron": "node build/lib/electron", "7z": "7z", diff --git a/src/vs/base/common/cancellation.ts b/src/vs/base/common/cancellation.ts index c5b8133ae6c..5edad20cd8b 100644 --- a/src/vs/base/common/cancellation.ts +++ b/src/vs/base/common/cancellation.ts @@ -96,8 +96,8 @@ class MutableToken implements CancellationToken { export class CancellationTokenSource { - private _token?: CancellationToken = undefined; - private _parentListener?: IDisposable = undefined; + public _token?: CancellationToken = undefined; + public _parentListener?: IDisposable = undefined; constructor(parent?: CancellationToken) { this._parentListener = parent && parent.onCancellationRequested(this.cancel, this); diff --git a/src/vs/editor/common/languages.ts b/src/vs/editor/common/languages.ts index 68bb4cd7fb3..967adf2c8cd 100644 --- a/src/vs/editor/common/languages.ts +++ b/src/vs/editor/common/languages.ts @@ -95,9 +95,6 @@ export interface ITreeSitterTokenizationSupport { onDidChangeTokens: Event<{ textModel: model.ITextModel; changes: IModelTokensChangedEvent }>; } -/** - * @internal - */ export interface ITokenizationSupport { /** * If true, the background tokenizer will only be used to verify tokens against the default background tokenizer. @@ -2244,9 +2241,6 @@ export enum ExternalUriOpenerPriority { Preferred = 3, } -/** - * @internal - */ export type DropYieldTo = { readonly kind: HierarchicalKind } | { readonly mimeType: string }; /** diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index f26d9206020..4b9e1073cd4 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -87,6 +87,8 @@ declare namespace monaco { } export class CancellationTokenSource { + _token?: CancellationToken; + _parentListener?: IDisposable; constructor(parent?: CancellationToken); get token(): CancellationToken; cancel(): void; @@ -148,6 +150,14 @@ declare namespace monaco { * fragment is the 'fragment' part of 'http://www.example.com/some/path?query#fragment'. */ readonly fragment: string; + /** + * @internal + */ + protected constructor(scheme: string, authority?: string, path?: string, query?: string, fragment?: string, _strict?: boolean); + /** + * @internal + */ + protected constructor(components: UriComponents); /** * Returns a string representing the corresponding file system path of this Uri. * Will handle UNC paths, normalizes windows drive letters to lower-case, and uses the @@ -499,6 +509,10 @@ declare namespace monaco { readonly altGraphKey: boolean; readonly keyCode: KeyCode; readonly code: string; + /** + * @internal + */ + toKeyCodeChord(): any; equals(keybinding: number): boolean; preventDefault(): void; stopPropagation(): void; @@ -683,6 +697,11 @@ declare namespace monaco { * Test if `position` is in `range`. If the position is at the edges, will return true. */ static containsPosition(range: IRange, position: IPosition): boolean; + /** + * Test if `position` is in `range`. If the position is at the edges, will return false. + * @internal + */ + static strictContainsPosition(range: IRange, position: IPosition): boolean; /** * Test if range is in this range. If the range is equal to this range, will return true. */ @@ -1523,6 +1542,11 @@ declare namespace monaco.editor { Visible = 3 } + export interface ThemeIcon { + readonly id: string; + readonly color?: ThemeColor; + } + export interface ThemeColor { id: string; } @@ -2470,6 +2494,11 @@ declare namespace monaco.editor { * A command that modifies text / cursor state on a model. */ export interface ICommand { + /** + * Signal that this command is inserting automatic whitespace that should be trimmed if possible. + * @internal + */ + readonly insertsAutoWhitespace?: boolean; /** * Get the edit operations needed to execute this command. * @param model The model the command will execute on. @@ -2619,6 +2648,16 @@ declare namespace monaco.editor { * Update the editor's options after the editor has been created. */ updateOptions(newOptions: IEditorOptions): void; + /** + * Indicates that the editor becomes visible. + * @internal + */ + onVisible(): void; + /** + * Indicates that the editor becomes hidden. + * @internal + */ + onHide(): void; /** * Instructs the editor to remeasure its container. This method should * be called when the container of the editor gets resized. @@ -2653,6 +2692,11 @@ declare namespace monaco.editor { * Given a position, returns a column number that takes tab-widths into account. */ getVisibleColumnFromPosition(position: IPosition): number; + /** + * Given a position, returns a column number that takes tab-widths into account. + * @internal + */ + getStatusbarColumn(position: IPosition): number; /** * Returns the primary position of the cursor. */ @@ -2805,6 +2849,48 @@ declare namespace monaco.editor { * These decorations will be automatically cleared when the editor's model changes. */ createDecorationsCollection(decorations?: IModelDeltaDecoration[]): IEditorDecorationsCollection; + /** + * Change the decorations. All decorations added through this changeAccessor + * will get the ownerId of the editor (meaning they will not show up in other + * editors). + * @see {@link ITextModel.changeDecorations} + * @internal + */ + changeDecorations(callback: (changeAccessor: IModelDecorationsChangeAccessor) => any): any; + } + + /** + * A diff editor. + * + * @internal + */ + export interface IDiffEditor extends IEditor { + /** + * Type the getModel() of IEditor. + */ + getModel(): IDiffEditorModel | null; + /** + * Get the `original` editor. + */ + getOriginalEditor(): IEditor; + /** + * Get the `modified` editor. + */ + getModifiedEditor(): IEditor; + } + + /** + * @internal + */ + export interface ICompositeCodeEditor { + /** + * An event that signals that the active editor has changed + */ + readonly onDidChangeActiveEditor: IEvent; + /** + * The active code editor iff any + */ + readonly activeCodeEditor: IEditor | undefined; } /** @@ -2864,6 +2950,131 @@ declare namespace monaco.editor { restoreViewState?(state: any): void; } + /** + * A diff editor contribution that gets created every time a new diffeditor gets created and gets disposed when the diff editor gets disposed. + * @internal + */ + export interface IDiffEditorContribution { + /** + * Dispose this contribution. + */ + dispose(): void; + } + + /** + * @internal + */ + export interface IThemeDecorationRenderOptions { + backgroundColor?: string | ThemeColor; + outline?: string; + outlineColor?: string | ThemeColor; + outlineStyle?: string; + outlineWidth?: string; + border?: string; + borderColor?: string | ThemeColor; + borderRadius?: string; + borderSpacing?: string; + borderStyle?: string; + borderWidth?: string; + fontStyle?: string; + fontWeight?: string; + fontSize?: string; + textDecoration?: string; + cursor?: string; + color?: string | ThemeColor; + opacity?: string; + letterSpacing?: string; + gutterIconPath?: UriComponents; + gutterIconSize?: string; + overviewRulerColor?: string | ThemeColor; + /** + * @deprecated + */ + before?: IContentDecorationRenderOptions; + /** + * @deprecated + */ + after?: IContentDecorationRenderOptions; + /** + * @deprecated + */ + beforeInjectedText?: IContentDecorationRenderOptions & { + affectsLetterSpacing?: boolean; + }; + /** + * @deprecated + */ + afterInjectedText?: IContentDecorationRenderOptions & { + affectsLetterSpacing?: boolean; + }; + } + + /** + * @internal + */ + export interface IContentDecorationRenderOptions { + contentText?: string; + contentIconPath?: UriComponents; + border?: string; + borderColor?: string | ThemeColor; + borderRadius?: string; + fontStyle?: string; + fontWeight?: string; + fontSize?: string; + fontFamily?: string; + textDecoration?: string; + color?: string | ThemeColor; + backgroundColor?: string | ThemeColor; + opacity?: string; + verticalAlign?: string; + margin?: string; + padding?: string; + width?: string; + height?: string; + } + + /** + * @internal + */ + export interface IDecorationRenderOptions extends IThemeDecorationRenderOptions { + isWholeLine?: boolean; + rangeBehavior?: TrackedRangeStickiness; + overviewRulerLane?: OverviewRulerLane; + light?: IThemeDecorationRenderOptions; + dark?: IThemeDecorationRenderOptions; + } + + /** + * @internal + */ + export interface IThemeDecorationInstanceRenderOptions { + /** + * @deprecated + */ + before?: IContentDecorationRenderOptions; + /** + * @deprecated + */ + after?: IContentDecorationRenderOptions; + } + + /** + * @internal + */ + export interface IDecorationInstanceRenderOptions extends IThemeDecorationInstanceRenderOptions { + light?: IThemeDecorationInstanceRenderOptions; + dark?: IThemeDecorationInstanceRenderOptions; + } + + /** + * @internal + */ + export interface IDecorationOptions { + range: IRange; + hoverMessage?: IMarkdownString | IMarkdownString[]; + renderOptions?: IDecorationInstanceRenderOptions; + } + /** * The type of the `IEditor`. */ @@ -2872,6 +3083,41 @@ declare namespace monaco.editor { IDiffEditor: string; }; + /** + * @internal + */ + export interface TypePayload { + text: string; + } + + /** + * @internal + */ + export interface ReplacePreviousCharPayload { + text: string; + replaceCharCnt: number; + } + + /** + * @internal + */ + export interface CompositionTypePayload { + text: string; + replacePrevCharCnt: number; + replaceNextCharCnt: number; + positionDelta: number; + } + + /** + * @internal + */ + export interface PastePayload { + text: string; + pasteOnNewLine: boolean; + multicursorText: string[] | null; + mode: string | null; + } + /** * An event describing that the current language associated with a model has changed. */ @@ -2960,6 +3206,24 @@ declare namespace monaco.editor { readonly affectsLineNumber: boolean; } + /** + * An event describing that some ranges of lines have been tokenized (their tokens have changed). + * @internal + */ + export interface IModelTokensChangedEvent { + readonly semanticTokensApplied: boolean; + readonly ranges: { + /** + * The start of the range (inclusive) + */ + readonly fromLineNumber: number; + /** + * The end of the range (inclusive) + */ + readonly toLineNumber: number; + }[]; + } + export interface IModelOptionsChangedEvent { readonly tabSize: boolean; readonly indentSize: boolean; @@ -2967,105 +3231,6 @@ declare namespace monaco.editor { readonly trimAutoWhitespace: boolean; } - /** - * Describes the reason the cursor has changed its position. - */ - export enum CursorChangeReason { - /** - * Unknown or not set. - */ - NotSet = 0, - /** - * A `model.setValue()` was called. - */ - ContentFlush = 1, - /** - * The `model` has been changed outside of this cursor and the cursor recovers its position from associated markers. - */ - RecoverFromMarkers = 2, - /** - * There was an explicit user gesture. - */ - Explicit = 3, - /** - * There was a Paste. - */ - Paste = 4, - /** - * There was an Undo. - */ - Undo = 5, - /** - * There was a Redo. - */ - Redo = 6 - } - - /** - * An event describing that the cursor position has changed. - */ - export interface ICursorPositionChangedEvent { - /** - * Primary cursor's position. - */ - readonly position: Position; - /** - * Secondary cursors' position. - */ - readonly secondaryPositions: Position[]; - /** - * Reason. - */ - readonly reason: CursorChangeReason; - /** - * Source of the call that caused the event. - */ - readonly source: string; - } - - /** - * An event describing that the cursor selection has changed. - */ - export interface ICursorSelectionChangedEvent { - /** - * The primary selection. - */ - readonly selection: Selection; - /** - * The secondary selections. - */ - readonly secondarySelections: Selection[]; - /** - * The model version id. - */ - readonly modelVersionId: number; - /** - * The old selections. - */ - readonly oldSelections: Selection[] | null; - /** - * The model version id the that `oldSelections` refer to. - */ - readonly oldModelVersionId: number; - /** - * Source of the call that caused the event. - */ - readonly source: string; - /** - * Reason. - */ - readonly reason: CursorChangeReason; - } - - export enum AccessibilitySupport { - /** - * This should be the browser case where it is not known if a screen reader is attached or no. - */ - Unknown = 0, - Disabled = 1, - Enabled = 2 - } - /** * Configuration options for auto closing quotes and brackets */ @@ -3938,6 +4103,11 @@ declare namespace monaco.editor { * An event describing that the configuration of the editor has changed. */ export class ConfigurationChangedEvent { + private readonly _values; + /** + * @internal + */ + constructor(values: boolean[]); hasChanged(id: EditorOption): boolean; } @@ -3948,10 +4118,43 @@ declare namespace monaco.editor { get(id: T): FindComputedEditorOptionValueById; } + /** + * @internal + */ + export interface IEnvironmentalOptions { + readonly memory: undefined | null; + readonly outerWidth: number; + readonly outerHeight: number; + readonly fontInfo: FontInfo; + readonly extraEditorClassName: string; + readonly isDominatedByLongLines: boolean; + readonly viewLineCount: number; + readonly lineNumbersDigitCount: number; + readonly emptySelectionClipboard: boolean; + readonly pixelRatio: number; + readonly tabFocusMode: boolean; + readonly accessibilitySupport: AccessibilitySupport; + readonly glyphMarginDecorationLaneCount: number; + } + export interface IEditorOption { readonly id: K; readonly name: string; defaultValue: V; + /** + * @internal + */ + readonly schema: any | { + [path: string]: any; + } | undefined; + /** + * @internal + */ + validate(input: any): V; + /** + * @internal + */ + compute(env: IEnvironmentalOptions, options: IComputedEditorOptions, value: V): V; /** * Might modify `value`. */ @@ -4057,6 +4260,11 @@ declare namespace monaco.editor { */ autoFindInSelection?: 'never' | 'always' | 'multiline'; addExtraSpaceOnTop?: boolean; + /** + * @internal + * Controls if the Find Widget should read or modify the shared find clipboard on macOS + */ + globalFindClipboard?: boolean; /** * Controls whether the search result and diff result automatically restarts from the beginning (or the end) when no further matches can be found */ @@ -5203,18 +5411,108 @@ declare namespace monaco.editor { } /** - * A view zone is a full horizontal rectangle that 'pushes' text down. - * The editor reserves space for view zones when rendering. + * Describes the reason the cursor has changed its position. */ - export interface IViewZone { + export enum CursorChangeReason { /** - * The line number after which this zone should appear. - * Use 0 to place a view zone before the first line number. + * Unknown or not set. */ - afterLineNumber: number; + NotSet = 0, /** - * The column after which this zone should appear. - * If not set, the maxLineColumn of `afterLineNumber` will be used. + * A `model.setValue()` was called. + */ + ContentFlush = 1, + /** + * The `model` has been changed outside of this cursor and the cursor recovers its position from associated markers. + */ + RecoverFromMarkers = 2, + /** + * There was an explicit user gesture. + */ + Explicit = 3, + /** + * There was a Paste. + */ + Paste = 4, + /** + * There was an Undo. + */ + Undo = 5, + /** + * There was a Redo. + */ + Redo = 6 + } + + /** + * An event describing that the cursor position has changed. + */ + export interface ICursorPositionChangedEvent { + /** + * Primary cursor's position. + */ + readonly position: Position; + /** + * Secondary cursors' position. + */ + readonly secondaryPositions: Position[]; + /** + * Reason. + */ + readonly reason: CursorChangeReason; + /** + * Source of the call that caused the event. + */ + readonly source: string; + } + + /** + * An event describing that the cursor selection has changed. + */ + export interface ICursorSelectionChangedEvent { + /** + * The primary selection. + */ + readonly selection: Selection; + /** + * The secondary selections. + */ + readonly secondarySelections: Selection[]; + /** + * The model version id. + */ + readonly modelVersionId: number; + /** + * The old selections. + */ + readonly oldSelections: Selection[] | null; + /** + * The model version id the that `oldSelections` refer to. + */ + readonly oldModelVersionId: number; + /** + * Source of the call that caused the event. + */ + readonly source: string; + /** + * Reason. + */ + readonly reason: CursorChangeReason; + } + + /** + * A view zone is a full horizontal rectangle that 'pushes' text down. + * The editor reserves space for view zones when rendering. + */ + export interface IViewZone { + /** + * The line number after which this zone should appear. + * Use 0 to place a view zone before the first line number. + */ + afterLineNumber: number; + /** + * The column after which this zone should appear. + * If not set, the maxLineColumn of `afterLineNumber` will be used. * This is relevant for wrapped lines. */ afterColumn?: number; @@ -5624,6 +5922,10 @@ declare namespace monaco.editor { export interface IMouseTargetContentTextData { readonly mightBeForeignElement: boolean; + /** + * @internal + */ + readonly injectedText: any | null; } export interface IMouseTargetContentText extends IBaseMouseTarget { @@ -5702,6 +6004,15 @@ declare namespace monaco.editor { readonly clipboardEvent?: ClipboardEvent; } + /** + * Editor aria options. + * @internal + */ + export interface IEditorAriaOptions { + activeDescendant: string | undefined; + role?: string; + } + export interface IDiffEditorConstructionOptions extends IDiffEditorOptions, IEditorConstructionOptions { /** * Place overflow widgets inside an external DOM node. @@ -5722,6 +6033,16 @@ declare namespace monaco.editor { * A rich code editor. */ export interface ICodeEditor extends IEditor { + /** + * This editor is used as an alternative to an box, i.e. as a simple widget. + * @internal + */ + readonly isSimpleWidget: boolean; + /** + * The editor's scoped context key service. + * @internal + */ + readonly contextKeyService: any; /** * An event emitted when the content of the current model has changed. * @event @@ -5772,6 +6093,11 @@ declare namespace monaco.editor { * @event */ readonly onDidChangeModelDecorations: IEvent; + /** + * An event emitted when the tokens of the current model have changed. + * @internal + */ + readonly onDidChangeModelTokens: IEvent; /** * An event emitted when the text inside this editor gained focus (i.e. cursor starts blinking). * @event @@ -5792,6 +6118,18 @@ declare namespace monaco.editor { * @event */ readonly onDidBlurEditorWidget: IEvent; + /** + * An event emitted before interpreting typed characters (on the keyboard). + * @event + * @internal + */ + readonly onWillType: IEvent; + /** + * An event emitted after interpreting typed characters (on the keyboard). + * @event + * @internal + */ + readonly onDidType: IEvent; /** * An event emitted after composition has started. */ @@ -5820,6 +6158,33 @@ declare namespace monaco.editor { * @event */ readonly onMouseDown: IEvent; + /** + * An event emitted on a "mousedrag". + * @internal + * @event + */ + readonly onMouseDrag: IEvent; + /** + * An event emitted on a "mousedrop". + * @internal + * @event + */ + readonly onMouseDrop: IEvent; + /** + * An event emitted on a "mousedropcanceled". + * @internal + * @event + */ + readonly onMouseDropCanceled: IEvent; + /** + * An event emitted when content is dropped into the editor. + * @internal + * @event + */ + readonly onDropIntoEditor: IEvent<{ + readonly position: IPosition; + readonly event: DragEvent; + }>; /** * An event emitted on a "contextmenu". * @event @@ -5835,6 +6200,12 @@ declare namespace monaco.editor { * @event */ readonly onMouseLeave: IEvent; + /** + * An event emitted on a "mousewheel" + * @event + * @internal + */ + readonly onMouseWheel: IEvent; /** * An event emitted on a "keyup". * @event @@ -5895,6 +6266,11 @@ declare namespace monaco.editor { * @return The contribution or null if contribution not found. */ getContribution(id: string): T | null; + /** + * Execute `fn` with the editor's services. + * @internal + */ + invokeWithinContext(fn: (accessor: any) => T): T; /** * Type the getModel() of IEditor. */ @@ -5920,6 +6296,14 @@ declare namespace monaco.editor { * Returns the editor's configuration (without any validation or defaults). */ getRawOptions(): IEditorOptions; + /** + * @internal + */ + getOverflowWidgetsDomNode(): HTMLElement | undefined; + /** + * @internal + */ + getConfiguredWordAtPosition(position: Position): IWordAtPosition | null; /** * Get value of the current model attached to this editor. * @see {@link ITextModel.getValue} @@ -6010,6 +6394,10 @@ declare namespace monaco.editor { * @param command The commands to execute */ executeCommands(source: string | null | undefined, commands: (ICommand | null)[]): void; + /** + * @internal + */ + _getViewModel(): any | null; /** * Get all the decorations on a line (filtering out decorations from other editors). */ @@ -6028,6 +6416,18 @@ declare namespace monaco.editor { * Remove previously added decorations. */ removeDecorations(decorationIds: string[]): void; + /** + * @internal + */ + setDecorationsByType(description: string, decorationTypeKey: string, ranges: IDecorationOptions[]): void; + /** + * @internal + */ + setDecorationsByTypeFast(decorationTypeKey: string, ranges: IRange[]): void; + /** + * @internal + */ + removeDecorationsByType(decorationTypeKey: string): void; /** * Get the layout info for the editor. */ @@ -6037,6 +6437,15 @@ declare namespace monaco.editor { * Does not account for horizontal scrolling. */ getVisibleRanges(): Range[]; + /** + * @internal + */ + getVisibleRangesPlusViewportAboveBelow(): Range[]; + /** + * Get the view zones. + * @internal + */ + getWhitespaces(): IEditorWhitespace[]; /** * Get the vertical position (top offset) for the line's top w.r.t. to the first line. */ @@ -6049,10 +6458,27 @@ declare namespace monaco.editor { * Get the vertical position (top offset) for the position w.r.t. to the first line. */ getTopForPosition(lineNumber: number, column: number): number; + /** + * Set the model ranges that will be hidden in the view. + * Hidden areas are stored per source. + * @internal + */ + setHiddenAreas(ranges: IRange[], source?: unknown): void; + /** + * Sets the editor aria options, primarily the active descendent. + * @internal + */ + setAriaOptions(options: IEditorAriaOptions): void; /** * Write the screen reader content to be the current selection */ writeScreenReaderContent(reason: string): void; + /** + * @internal + */ + getTelemetryData(): { + [key: string]: any; + } | undefined; /** * Returns the editor's container dom node */ @@ -6137,6 +6563,11 @@ declare namespace monaco.editor { * Apply the same font settings as the editor to `target`. */ applyFontInfo(target: HTMLElement): void; + /** + * Check if the current instance has a model attached. + * @internal + */ + hasModel(): this is IActiveCodeEditor; setBanner(bannerDomNode: HTMLElement | null, height: number): void; /** * Is called when the model has been set, view state was restored and options are updated. @@ -6145,10 +6576,75 @@ declare namespace monaco.editor { handleInitialized?(): void; } + /** + * @internal + */ + export interface IActiveCodeEditor extends ICodeEditor { + /** + * Returns the primary position of the cursor. + */ + getPosition(): Position; + /** + * Returns the primary selection of the editor. + */ + getSelection(): Selection; + /** + * Returns all the selections of the editor. + */ + getSelections(): Selection[]; + /** + * Saves current view state of the editor in a serializable object. + */ + saveViewState(): ICodeEditorViewState; + /** + * Type the getModel() of IEditor. + */ + getModel(): ITextModel; + /** + * @internal + */ + _getViewModel(): any; + /** + * Get all the decorations on a line (filtering out decorations from other editors). + */ + getLineDecorations(lineNumber: number): IModelDecoration[]; + /** + * Returns the editor's dom node + */ + getDomNode(): HTMLElement; + /** + * Get the visible position for `position`. + * The result position takes scrolling into account and is relative to the top left corner of the editor. + * Explanation 1: the results of this method will change for the same `position` if the user scrolls the editor. + * Explanation 2: the results of this method will not change if the container of the editor gets repositioned. + * Warning: the results of this method are inaccurate for positions that are outside the current editor viewport. + */ + getScrolledVisiblePosition(position: IPosition): { + top: number; + left: number; + height: number; + }; + } + /** * A rich diff editor. */ export interface IDiffEditor extends IEditor { + /** + * Returns whether the diff editor is ignoring trim whitespace or not. + * @internal + */ + readonly ignoreTrimWhitespace: boolean; + /** + * Returns whether the diff editor is rendering side by side or inline. + * @internal + */ + readonly renderSideBySide: boolean; + /** + * Timeout in milliseconds after which diff computation is cancelled. + * @internal + */ + readonly maxComputationTime: number; /** * @see {@link ICodeEditor.getContainerDomNode} */ @@ -6197,49 +6693,1340 @@ declare namespace monaco.editor { * Get the computed diff information. */ getLineChanges(): ILineChange[] | null; + /** + * Get the computed diff information. + * @internal + */ + getDiffComputationResult(): any | null; /** * Update the editor's options after the editor has been created. */ updateOptions(newOptions: IDiffEditorOptions): void; + /** + * @internal + */ + setBoundarySashes(sashes: any): void; /** * Jumps to the next or previous diff. */ goToDiff(target: 'next' | 'previous'): void; /** - * Scrolls to the first diff. - * (Waits until the diff computation finished.) + * Scrolls to the first diff. + * (Waits until the diff computation finished.) + */ + revealFirstDiff(): unknown; + accessibleDiffViewerNext(): void; + accessibleDiffViewerPrev(): void; + handleInitialized(): void; + } + + export class FontInfo extends BareFontInfo { + readonly _editorStylingBrand: void; + readonly version: number; + readonly isTrusted: boolean; + readonly isMonospace: boolean; + readonly typicalHalfwidthCharacterWidth: number; + readonly typicalFullwidthCharacterWidth: number; + readonly canUseHalfwidthRightwardsArrow: boolean; + readonly spaceWidth: number; + readonly middotWidth: number; + readonly wsmiddotWidth: number; + readonly maxDigitWidth: number; + /** + * @internal + */ + constructor(opts: { + pixelRatio: number; + fontFamily: string; + fontWeight: string; + fontSize: number; + fontFeatureSettings: string; + fontVariationSettings: string; + lineHeight: number; + letterSpacing: number; + isMonospace: boolean; + typicalHalfwidthCharacterWidth: number; + typicalFullwidthCharacterWidth: number; + canUseHalfwidthRightwardsArrow: boolean; + spaceWidth: number; + middotWidth: number; + wsmiddotWidth: number; + maxDigitWidth: number; + }, isTrusted: boolean); + /** + * @internal + */ + equals(other: FontInfo): boolean; + } + + export class BareFontInfo { + readonly _bareFontInfoBrand: void; + /** + * @internal + */ + static createFromValidatedSettings(options: any, pixelRatio: number, ignoreEditorZoom: boolean): BareFontInfo; + /** + * @internal + */ + static createFromRawSettings(opts: { + fontFamily?: string; + fontWeight?: string; + fontSize?: number; + fontLigatures?: boolean | string; + fontVariations?: boolean | string; + lineHeight?: number; + letterSpacing?: number; + }, pixelRatio: number, ignoreEditorZoom?: boolean): BareFontInfo; + /** + * @internal + */ + private static _create; + readonly pixelRatio: number; + readonly fontFamily: string; + readonly fontWeight: string; + readonly fontSize: number; + readonly fontFeatureSettings: string; + readonly fontVariationSettings: string; + readonly lineHeight: number; + readonly letterSpacing: number; + /** + * @internal + */ + protected constructor(opts: { + pixelRatio: number; + fontFamily: string; + fontWeight: string; + fontSize: number; + fontFeatureSettings: string; + fontVariationSettings: string; + lineHeight: number; + letterSpacing: number; + }); + /** + * @internal + */ + getId(): string; + /** + * @internal + */ + getMassagedFontFamily(): string; + private static _wrapInQuotes; + } + + /** + * Vertical Lane in the overview ruler of the editor. + */ + export enum OverviewRulerLane { + Left = 1, + Center = 2, + Right = 4, + Full = 7 + } + + /** + * Vertical Lane in the glyph margin of the editor. + */ + export enum GlyphMarginLane { + Left = 1, + Right = 2 + } + + /** + * Position in the minimap to render the decoration. + */ + export enum MinimapPosition { + Inline = 1, + Gutter = 2 + } + + export interface IDecorationOptions { + /** + * CSS color to render. + * e.g.: rgba(100, 100, 100, 0.5) or a color from the color registry + */ + color: string | ThemeColor | undefined; + /** + * CSS color to render. + * e.g.: rgba(100, 100, 100, 0.5) or a color from the color registry + */ + darkColor?: string | ThemeColor; + } + + export interface IModelDecorationGlyphMarginOptions { + /** + * The position in the glyph margin. + */ + position: GlyphMarginLane; + } + + /** + * Options for rendering a model decoration in the overview ruler. + */ + export interface IModelDecorationOverviewRulerOptions extends IDecorationOptions { + /** + * The position in the overview ruler. + */ + position: OverviewRulerLane; + } + + /** + * Options for rendering a model decoration in the minimap. + */ + export interface IModelDecorationMinimapOptions extends IDecorationOptions { + /** + * The position in the minimap. + */ + position: MinimapPosition; + } + + /** + * Options for a model decoration. + */ + export interface IModelDecorationOptions { + /** + * A debug description that can be used for inspecting model decorations. + * @internal + */ + description: string; + /** + * Customize the growing behavior of the decoration when typing at the edges of the decoration. + * Defaults to TrackedRangeStickiness.AlwaysGrowsWhenTypingAtEdges + */ + stickiness?: TrackedRangeStickiness; + /** + * CSS class name describing the decoration. + */ + className?: string | null; + /** + * Indicates whether the decoration should span across the entire line when it continues onto the next line. + */ + shouldFillLineOnLineBreak?: boolean | null; + blockClassName?: string | null; + /** + * Indicates if this block should be rendered after the last line. + * In this case, the range must be empty and set to the last line. + */ + blockIsAfterEnd?: boolean | null; + blockDoesNotCollapse?: boolean | null; + blockPadding?: [top: number, right: number, bottom: number, left: number] | null; + /** + * Message to be rendered when hovering over the glyph margin decoration. + */ + glyphMarginHoverMessage?: IMarkdownString | IMarkdownString[] | null; + /** + * Array of MarkdownString to render as the decoration message. + */ + hoverMessage?: IMarkdownString | IMarkdownString[] | null; + /** + * Should the decoration expand to encompass a whole line. + */ + isWholeLine?: boolean; + /** + * Always render the decoration (even when the range it encompasses is collapsed). + */ + showIfCollapsed?: boolean; + /** + * Collapse the decoration if its entire range is being replaced via an edit. + * @internal + */ + collapseOnReplaceEdit?: boolean; + /** + * Specifies the stack order of a decoration. + * A decoration with greater stack order is always in front of a decoration with + * a lower stack order when the decorations are on the same line. + */ + zIndex?: number; + /** + * If set, render this decoration in the overview ruler. + */ + overviewRuler?: IModelDecorationOverviewRulerOptions | null; + /** + * If set, render this decoration in the minimap. + */ + minimap?: IModelDecorationMinimapOptions | null; + /** + * If set, the decoration will be rendered in the glyph margin with this CSS class name. + */ + glyphMarginClassName?: string | null; + /** + * If set and the decoration has {@link glyphMarginClassName} set, render this decoration + * with the specified {@link IModelDecorationGlyphMarginOptions} in the glyph margin. + */ + glyphMargin?: IModelDecorationGlyphMarginOptions | null; + /** + * If set, the decoration will be rendered in the lines decorations with this CSS class name. + */ + linesDecorationsClassName?: string | null; + /** + * If set, the decoration will be rendered in the lines decorations with this CSS class name, but only for the first line in case of line wrapping. + */ + firstLineDecorationClassName?: string | null; + /** + * If set, the decoration will be rendered in the margin (covering its full width) with this CSS class name. + */ + marginClassName?: string | null; + /** + * If set, the decoration will be rendered inline with the text with this CSS class name. + * Please use this only for CSS rules that must impact the text. For example, use `className` + * to have a background color decoration. + */ + inlineClassName?: string | null; + /** + * If there is an `inlineClassName` which affects letter spacing. + */ + inlineClassNameAffectsLetterSpacing?: boolean; + /** + * If set, the decoration will be rendered before the text with this CSS class name. + */ + beforeContentClassName?: string | null; + /** + * If set, the decoration will be rendered after the text with this CSS class name. + */ + afterContentClassName?: string | null; + /** + * If set, text will be injected in the view after the range. + */ + after?: InjectedTextOptions | null; + /** + * If set, text will be injected in the view before the range. + */ + before?: InjectedTextOptions | null; + /** + * If set, this decoration will not be rendered for comment tokens. + * @internal + */ + hideInCommentTokens?: boolean | null; + /** + * If set, this decoration will not be rendered for string tokens. + * @internal + */ + hideInStringTokens?: boolean | null; + } + + /** + * Configures text that is injected into the view without changing the underlying document. + */ + export interface InjectedTextOptions { + /** + * Sets the text to inject. Must be a single line. + */ + readonly content: string; + /** + * If set, the decoration will be rendered inline with the text with this CSS class name. + */ + readonly inlineClassName?: string | null; + /** + * If there is an `inlineClassName` which affects letter spacing. + */ + readonly inlineClassNameAffectsLetterSpacing?: boolean; + /** + * This field allows to attach data to this injected text. + * The data can be read when injected texts at a given position are queried. + */ + readonly attachedData?: unknown; + /** + * Configures cursor stops around injected text. + * Defaults to {@link InjectedTextCursorStops.Both}. + */ + readonly cursorStops?: InjectedTextCursorStops | null; + } + + export enum InjectedTextCursorStops { + Both = 0, + Right = 1, + Left = 2, + None = 3 + } + + /** + * New model decorations. + */ + export interface IModelDeltaDecoration { + /** + * Range that this decoration covers. + */ + range: IRange; + /** + * Options associated with this decoration. + */ + options: IModelDecorationOptions; + } + + /** + * A decoration in the model. + */ + export interface IModelDecoration { + /** + * Identifier for a decoration. + */ + readonly id: string; + /** + * Identifier for a decoration's owner. + */ + readonly ownerId: number; + /** + * Range that this decoration covers. + */ + readonly range: Range; + /** + * Options associated with this decoration. + */ + readonly options: IModelDecorationOptions; + } + + /** + * An accessor that can add, change or remove model decorations. + * @internal + */ + export interface IModelDecorationsChangeAccessor { + /** + * Add a new decoration. + * @param range Range that this decoration covers. + * @param options Options associated with this decoration. + * @return An unique identifier associated with this decoration. + */ + addDecoration(range: IRange, options: IModelDecorationOptions): string; + /** + * Change the range that an existing decoration covers. + * @param id The unique identifier associated with the decoration. + * @param newRange The new range that this decoration covers. + */ + changeDecoration(id: string, newRange: IRange): void; + /** + * Change the options associated with an existing decoration. + * @param id The unique identifier associated with the decoration. + * @param newOptions The new options associated with this decoration. + */ + changeDecorationOptions(id: string, newOptions: IModelDecorationOptions): void; + /** + * Remove an existing decoration. + * @param id The unique identifier associated with the decoration. + */ + removeDecoration(id: string): void; + /** + * Perform a minimum amount of operations, in order to transform the decorations + * identified by `oldDecorations` to the decorations described by `newDecorations` + * and returns the new identifiers associated with the resulting decorations. + * + * @param oldDecorations Array containing previous decorations identifiers. + * @param newDecorations Array describing what decorations should result after the call. + * @return An array containing the new decorations identifiers. + */ + deltaDecorations(oldDecorations: readonly string[], newDecorations: readonly IModelDeltaDecoration[]): string[]; + } + + /** + * End of line character preference. + */ + export enum EndOfLinePreference { + /** + * Use the end of line character identified in the text buffer. + */ + TextDefined = 0, + /** + * Use line feed (\n) as the end of line character. + */ + LF = 1, + /** + * Use carriage return and line feed (\r\n) as the end of line character. + */ + CRLF = 2 + } + + /** + * The default end of line to use when instantiating models. + */ + export enum DefaultEndOfLine { + /** + * Use line feed (\n) as the end of line character. + */ + LF = 1, + /** + * Use carriage return and line feed (\r\n) as the end of line character. + */ + CRLF = 2 + } + + /** + * End of line character preference. + */ + export enum EndOfLineSequence { + /** + * Use line feed (\n) as the end of line character. + */ + LF = 0, + /** + * Use carriage return and line feed (\r\n) as the end of line character. + */ + CRLF = 1 + } + + /** + * An identifier for a single edit operation. + * @internal + */ + export interface ISingleEditOperationIdentifier { + /** + * Identifier major + */ + major: number; + /** + * Identifier minor + */ + minor: number; + } + + /** + * A single edit operation, that has an identifier. + */ + export interface IIdentifiedSingleEditOperation extends ISingleEditOperation { + /** + * An identifier associated with this single edit operation. + * @internal + */ + identifier?: ISingleEditOperationIdentifier | null; + /** + * This indicates that this operation is inserting automatic whitespace + * that can be removed on next model edit operation if `config.trimAutoWhitespace` is true. + * @internal + */ + isAutoWhitespaceEdit?: boolean; + /** + * This indicates that this operation is in a set of operations that are tracked and should not be "simplified". + * @internal + */ + _isTracked?: boolean; + } + + export interface IValidEditOperation { + /** + * An identifier associated with this single edit operation. + * @internal + */ + identifier: ISingleEditOperationIdentifier | null; + /** + * The range to replace. This can be empty to emulate a simple insert. + */ + range: Range; + /** + * The text to replace with. This can be empty to emulate a simple delete. + */ + text: string; + /** + * @internal + */ + textChange: any; + } + + /** + * A callback that can compute the cursor state after applying a series of edit operations. + */ + export interface ICursorStateComputer { + /** + * A callback that can compute the resulting cursors state after some edit operations have been executed. + */ + (inverseEditOperations: IValidEditOperation[]): Selection[] | null; + } + + export class TextModelResolvedOptions { + _textModelResolvedOptionsBrand: void; + readonly tabSize: number; + readonly indentSize: number; + private readonly _indentSizeIsTabSize; + readonly insertSpaces: boolean; + readonly defaultEOL: DefaultEndOfLine; + readonly trimAutoWhitespace: boolean; + readonly bracketPairColorizationOptions: BracketPairColorizationOptions; + get originalIndentSize(): number | 'tabSize'; + /** + * @internal + */ + constructor(src: { + tabSize: number; + indentSize: number | 'tabSize'; + insertSpaces: boolean; + defaultEOL: DefaultEndOfLine; + trimAutoWhitespace: boolean; + bracketPairColorizationOptions: BracketPairColorizationOptions; + }); + /** + * @internal + */ + equals(other: TextModelResolvedOptions): boolean; + /** + * @internal + */ + createChangeEvent(newOpts: TextModelResolvedOptions): IModelOptionsChangedEvent; + } + + /** + * @internal + */ + export interface ITextModelCreationOptions { + tabSize: number; + indentSize: number | 'tabSize'; + insertSpaces: boolean; + detectIndentation: boolean; + trimAutoWhitespace: boolean; + defaultEOL: DefaultEndOfLine; + isForSimpleWidget: boolean; + largeFileOptimizations: boolean; + bracketPairColorizationOptions: BracketPairColorizationOptions; + } + + export interface BracketPairColorizationOptions { + enabled: boolean; + independentColorPoolPerBracketType: boolean; + } + + export interface ITextModelUpdateOptions { + tabSize?: number; + indentSize?: number | 'tabSize'; + insertSpaces?: boolean; + trimAutoWhitespace?: boolean; + bracketColorizationOptions?: BracketPairColorizationOptions; + } + + export class FindMatch { + _findMatchBrand: void; + readonly range: Range; + readonly matches: string[] | null; + /** + * @internal + */ + constructor(range: Range, matches: string[] | null); + } + + /** + * Describes the behavior of decorations when typing/editing near their edges. + * Note: Please do not edit the values, as they very carefully match `DecorationRangeBehavior` + */ + export enum TrackedRangeStickiness { + AlwaysGrowsWhenTypingAtEdges = 0, + NeverGrowsWhenTypingAtEdges = 1, + GrowsOnlyWhenTypingBefore = 2, + GrowsOnlyWhenTypingAfter = 3 + } + + /** + * Text snapshot that works like an iterator. + * Will try to return chunks of roughly ~64KB size. + * Will return null when finished. + */ + export interface ITextSnapshot { + read(): string | null; + } + + /** + * A model. + */ + export interface ITextModel { + /** + * Gets the resource associated with this editor model. + */ + readonly uri: Uri; + /** + * A unique identifier associated with this model. + */ + readonly id: string; + /** + * This model is constructed for a simple widget code editor. + * @internal + */ + readonly isForSimpleWidget: boolean; + /** + * If true, the text model might contain RTL. + * If false, the text model **contains only** contain LTR. + * @internal + */ + mightContainRTL(): boolean; + /** + * If true, the text model might contain LINE SEPARATOR (LS), PARAGRAPH SEPARATOR (PS). + * If false, the text model definitely does not contain these. + * @internal + */ + mightContainUnusualLineTerminators(): boolean; + /** + * @internal + */ + removeUnusualLineTerminators(selections?: Selection[]): void; + /** + * If true, the text model might contain non basic ASCII. + * If false, the text model **contains only** basic ASCII. + * @internal + */ + mightContainNonBasicASCII(): boolean; + /** + * Get the resolved options for this model. + */ + getOptions(): TextModelResolvedOptions; + /** + * Get the formatting options for this model. + * @internal + */ + getFormattingOptions(): languages.FormattingOptions; + /** + * Get the current version id of the model. + * Anytime a change happens to the model (even undo/redo), + * the version id is incremented. + */ + getVersionId(): number; + /** + * Get the alternative version id of the model. + * This alternative version id is not always incremented, + * it will return the same values in the case of undo-redo. + */ + getAlternativeVersionId(): number; + /** + * Replace the entire text buffer value contained in this model. + */ + setValue(newValue: string | ITextSnapshot): void; + /** + * Get the text stored in this model. + * @param eol The end of line character preference. Defaults to `EndOfLinePreference.TextDefined`. + * @param preserverBOM Preserve a BOM character if it was detected when the model was constructed. + * @return The text. + */ + getValue(eol?: EndOfLinePreference, preserveBOM?: boolean): string; + /** + * Get the text stored in this model. + * @param preserverBOM Preserve a BOM character if it was detected when the model was constructed. + * @return The text snapshot (it is safe to consume it asynchronously). + */ + createSnapshot(preserveBOM?: boolean): ITextSnapshot; + /** + * Get the length of the text stored in this model. + */ + getValueLength(eol?: EndOfLinePreference, preserveBOM?: boolean): number; + /** + * Check if the raw text stored in this model equals another raw text. + * @internal + */ + equalsTextBuffer(other: ITextBuffer): boolean; + /** + * Get the underling text buffer. + * @internal + */ + getTextBuffer(): ITextBuffer; + /** + * Get the text in a certain range. + * @param range The range describing what text to get. + * @param eol The end of line character preference. This will only be used for multiline ranges. Defaults to `EndOfLinePreference.TextDefined`. + * @return The text. + */ + getValueInRange(range: IRange, eol?: EndOfLinePreference): string; + /** + * Get the length of text in a certain range. + * @param range The range describing what text length to get. + * @return The text length. + */ + getValueLengthInRange(range: IRange, eol?: EndOfLinePreference): number; + /** + * Get the character count of text in a certain range. + * @param range The range describing what text length to get. + */ + getCharacterCountInRange(range: IRange, eol?: EndOfLinePreference): number; + /** + * Splits characters in two buckets. First bucket (A) is of characters that + * sit in lines with length < `LONG_LINE_BOUNDARY`. Second bucket (B) is of + * characters that sit in lines with length >= `LONG_LINE_BOUNDARY`. + * If count(B) > count(A) return true. Returns false otherwise. + * @internal + */ + isDominatedByLongLines(): boolean; + /** + * Get the number of lines in the model. + */ + getLineCount(): number; + /** + * Get the text for a certain line. + */ + getLineContent(lineNumber: number): string; + /** + * Get the text length for a certain line. + */ + getLineLength(lineNumber: number): number; + /** + * Get the text for all lines. + */ + getLinesContent(): string[]; + /** + * Get the end of line sequence predominantly used in the text buffer. + * @return EOL char sequence (e.g.: '\n' or '\r\n'). + */ + getEOL(): string; + /** + * Get the end of line sequence predominantly used in the text buffer. + */ + getEndOfLineSequence(): EndOfLineSequence; + /** + * Get the minimum legal column for line at `lineNumber` + */ + getLineMinColumn(lineNumber: number): number; + /** + * Get the maximum legal column for line at `lineNumber` + */ + getLineMaxColumn(lineNumber: number): number; + /** + * Returns the column before the first non whitespace character for line at `lineNumber`. + * Returns 0 if line is empty or contains only whitespace. + */ + getLineFirstNonWhitespaceColumn(lineNumber: number): number; + /** + * Returns the column after the last non whitespace character for line at `lineNumber`. + * Returns 0 if line is empty or contains only whitespace. + */ + getLineLastNonWhitespaceColumn(lineNumber: number): number; + /** + * Create a valid position. + */ + validatePosition(position: IPosition): Position; + /** + * Advances the given position by the given offset (negative offsets are also accepted) + * and returns it as a new valid position. + * + * If the offset and position are such that their combination goes beyond the beginning or + * end of the model, throws an exception. + * + * If the offset is such that the new position would be in the middle of a multi-byte + * line terminator, throws an exception. + */ + modifyPosition(position: IPosition, offset: number): Position; + /** + * Create a valid range. + */ + validateRange(range: IRange): Range; + /** + * Converts the position to a zero-based offset. + * + * The position will be [adjusted](#TextDocument.validatePosition). + * + * @param position A position. + * @return A valid zero-based offset. + */ + getOffsetAt(position: IPosition): number; + /** + * Converts a zero-based offset to a position. + * + * @param offset A zero-based offset. + * @return A valid [position](#Position). + */ + getPositionAt(offset: number): Position; + /** + * Get a range covering the entire model. + */ + getFullModelRange(): Range; + /** + * Returns if the model was disposed or not. + */ + isDisposed(): boolean; + /** + * This model is so large that it would not be a good idea to sync it over + * to web workers or other places. + * @internal + */ + isTooLargeForSyncing(): boolean; + /** + * The file is so large, that even tokenization is disabled. + * @internal + */ + isTooLargeForTokenization(): boolean; + /** + * The file is so large, that operations on it might be too large for heap + * and can lead to OOM crashes so they should be disabled. + * @internal + */ + isTooLargeForHeapOperation(): boolean; + /** + * Search the model. + * @param searchString The string used to search. If it is a regular expression, set `isRegex` to true. + * @param searchOnlyEditableRange Limit the searching to only search inside the editable range of the model. + * @param isRegex Used to indicate that `searchString` is a regular expression. + * @param matchCase Force the matching to match lower/upper case exactly. + * @param wordSeparators Force the matching to match entire words only. Pass null otherwise. + * @param captureMatches The result will contain the captured groups. + * @param limitResultCount Limit the number of results + * @return The ranges where the matches are. It is empty if not matches have been found. + */ + findMatches(searchString: string, searchOnlyEditableRange: boolean, isRegex: boolean, matchCase: boolean, wordSeparators: string | null, captureMatches: boolean, limitResultCount?: number): FindMatch[]; + /** + * Search the model. + * @param searchString The string used to search. If it is a regular expression, set `isRegex` to true. + * @param searchScope Limit the searching to only search inside these ranges. + * @param isRegex Used to indicate that `searchString` is a regular expression. + * @param matchCase Force the matching to match lower/upper case exactly. + * @param wordSeparators Force the matching to match entire words only. Pass null otherwise. + * @param captureMatches The result will contain the captured groups. + * @param limitResultCount Limit the number of results + * @return The ranges where the matches are. It is empty if no matches have been found. + */ + findMatches(searchString: string, searchScope: IRange | IRange[], isRegex: boolean, matchCase: boolean, wordSeparators: string | null, captureMatches: boolean, limitResultCount?: number): FindMatch[]; + /** + * Search the model for the next match. Loops to the beginning of the model if needed. + * @param searchString The string used to search. If it is a regular expression, set `isRegex` to true. + * @param searchStart Start the searching at the specified position. + * @param isRegex Used to indicate that `searchString` is a regular expression. + * @param matchCase Force the matching to match lower/upper case exactly. + * @param wordSeparators Force the matching to match entire words only. Pass null otherwise. + * @param captureMatches The result will contain the captured groups. + * @return The range where the next match is. It is null if no next match has been found. + */ + findNextMatch(searchString: string, searchStart: IPosition, isRegex: boolean, matchCase: boolean, wordSeparators: string | null, captureMatches: boolean): FindMatch | null; + /** + * Search the model for the previous match. Loops to the end of the model if needed. + * @param searchString The string used to search. If it is a regular expression, set `isRegex` to true. + * @param searchStart Start the searching at the specified position. + * @param isRegex Used to indicate that `searchString` is a regular expression. + * @param matchCase Force the matching to match lower/upper case exactly. + * @param wordSeparators Force the matching to match entire words only. Pass null otherwise. + * @param captureMatches The result will contain the captured groups. + * @return The range where the previous match is. It is null if no previous match has been found. + */ + findPreviousMatch(searchString: string, searchStart: IPosition, isRegex: boolean, matchCase: boolean, wordSeparators: string | null, captureMatches: boolean): FindMatch | null; + /** + * Get the language associated with this model. + */ + getLanguageId(): string; + /** + * Set the current language mode associated with the model. + * @param languageId The new language. + * @param source The source of the call that set the language. + * @internal + */ + setLanguage(languageId: string, source?: string): void; + /** + * Set the current language mode associated with the model. + * @param languageSelection The new language selection. + * @param source The source of the call that set the language. + * @internal + */ + setLanguage(languageSelection: languages.ILanguageSelection, source?: string): void; + /** + * Returns the real (inner-most) language mode at a given position. + * The result might be inaccurate. Use `forceTokenization` to ensure accurate tokens. + * @internal + */ + getLanguageIdAtPosition(lineNumber: number, column: number): string; + /** + * Get the word under or besides `position`. + * @param position The position to look for a word. + * @return The word under or besides `position`. Might be null. + */ + getWordAtPosition(position: IPosition): IWordAtPosition | null; + /** + * Get the word under or besides `position` trimmed to `position`.column + * @param position The position to look for a word. + * @return The word under or besides `position`. Will never be null. + */ + getWordUntilPosition(position: IPosition): IWordAtPosition; + /** + * Change the decorations. The callback will be called with a change accessor + * that becomes invalid as soon as the callback finishes executing. + * This allows for all events to be queued up until the change + * is completed. Returns whatever the callback returns. + * @param ownerId Identifies the editor id in which these decorations should appear. If no `ownerId` is provided, the decorations will appear in all editors that attach this model. + * @internal + */ + changeDecorations(callback: (changeAccessor: IModelDecorationsChangeAccessor) => T, ownerId?: number): T | null; + /** + * Perform a minimum amount of operations, in order to transform the decorations + * identified by `oldDecorations` to the decorations described by `newDecorations` + * and returns the new identifiers associated with the resulting decorations. + * + * @param oldDecorations Array containing previous decorations identifiers. + * @param newDecorations Array describing what decorations should result after the call. + * @param ownerId Identifies the editor id in which these decorations should appear. If no `ownerId` is provided, the decorations will appear in all editors that attach this model. + * @return An array containing the new decorations identifiers. + */ + deltaDecorations(oldDecorations: string[], newDecorations: IModelDeltaDecoration[], ownerId?: number): string[]; + /** + * Remove all decorations that have been added with this specific ownerId. + * @param ownerId The owner id to search for. + * @internal + */ + removeAllDecorationsWithOwnerId(ownerId: number): void; + /** + * Get the options associated with a decoration. + * @param id The decoration id. + * @return The decoration options or null if the decoration was not found. + */ + getDecorationOptions(id: string): IModelDecorationOptions | null; + /** + * Get the range associated with a decoration. + * @param id The decoration id. + * @return The decoration range or null if the decoration was not found. + */ + getDecorationRange(id: string): Range | null; + /** + * Gets all the decorations for the line `lineNumber` as an array. + * @param lineNumber The line number + * @param ownerId If set, it will ignore decorations belonging to other owners. + * @param filterOutValidation If set, it will ignore decorations specific to validation (i.e. warnings, errors). + * @return An array with the decorations + */ + getLineDecorations(lineNumber: number, ownerId?: number, filterOutValidation?: boolean): IModelDecoration[]; + /** + * Gets all the decorations for the lines between `startLineNumber` and `endLineNumber` as an array. + * @param startLineNumber The start line number + * @param endLineNumber The end line number + * @param ownerId If set, it will ignore decorations belonging to other owners. + * @param filterOutValidation If set, it will ignore decorations specific to validation (i.e. warnings, errors). + * @return An array with the decorations + */ + getLinesDecorations(startLineNumber: number, endLineNumber: number, ownerId?: number, filterOutValidation?: boolean): IModelDecoration[]; + /** + * Gets all the decorations in a range as an array. Only `startLineNumber` and `endLineNumber` from `range` are used for filtering. + * So for now it returns all the decorations on the same line as `range`. + * @param range The range to search in + * @param ownerId If set, it will ignore decorations belonging to other owners. + * @param filterOutValidation If set, it will ignore decorations specific to validation (i.e. warnings, errors). + * @param onlyMinimapDecorations If set, it will return only decorations that render in the minimap. + * @param onlyMarginDecorations If set, it will return only decorations that render in the glyph margin. + * @return An array with the decorations + */ + getDecorationsInRange(range: IRange, ownerId?: number, filterOutValidation?: boolean, onlyMinimapDecorations?: boolean, onlyMarginDecorations?: boolean): IModelDecoration[]; + /** + * Gets all the decorations as an array. + * @param ownerId If set, it will ignore decorations belonging to other owners. + * @param filterOutValidation If set, it will ignore decorations specific to validation (i.e. warnings, errors). + */ + getAllDecorations(ownerId?: number, filterOutValidation?: boolean): IModelDecoration[]; + /** + * Gets all decorations that render in the glyph margin as an array. + * @param ownerId If set, it will ignore decorations belonging to other owners. + */ + getAllMarginDecorations(ownerId?: number): IModelDecoration[]; + /** + * Gets all the decorations that should be rendered in the overview ruler as an array. + * @param ownerId If set, it will ignore decorations belonging to other owners. + * @param filterOutValidation If set, it will ignore decorations specific to validation (i.e. warnings, errors). + */ + getOverviewRulerDecorations(ownerId?: number, filterOutValidation?: boolean): IModelDecoration[]; + /** + * Gets all the decorations that contain injected text. + * @param ownerId If set, it will ignore decorations belonging to other owners. + */ + getInjectedTextDecorations(ownerId?: number): IModelDecoration[]; + /** + * @internal + */ + _getTrackedRange(id: string): Range | null; + /** + * @internal + */ + _setTrackedRange(id: string | null, newRange: null, newStickiness: TrackedRangeStickiness): null; + /** + * @internal + */ + _setTrackedRange(id: string | null, newRange: Range, newStickiness: TrackedRangeStickiness): string; + /** + * Normalize a string containing whitespace according to indentation rules (converts to spaces or to tabs). + */ + normalizeIndentation(str: string): string; + /** + * Change the options of this model. + */ + updateOptions(newOpts: ITextModelUpdateOptions): void; + /** + * Detect the indentation options for this model from its content. + */ + detectIndentation(defaultInsertSpaces: boolean, defaultTabSize: number): void; + /** + * Close the current undo-redo element. + * This offers a way to create an undo/redo stop point. + */ + pushStackElement(): void; + /** + * Open the current undo-redo element. + * This offers a way to remove the current undo/redo stop point. + */ + popStackElement(): void; + /** + * Push edit operations, basically editing the model. This is the preferred way + * of editing the model. The edit operations will land on the undo stack. + * @param beforeCursorState The cursor state before the edit operations. This cursor state will be returned when `undo` or `redo` are invoked. + * @param editOperations The edit operations. + * @param cursorStateComputer A callback that can compute the resulting cursors state after the edit operations have been executed. + * @return The cursor state returned by the `cursorStateComputer`. + */ + pushEditOperations(beforeCursorState: Selection[] | null, editOperations: IIdentifiedSingleEditOperation[], cursorStateComputer: ICursorStateComputer): Selection[] | null; + /** + * @internal + */ + pushEditOperations(beforeCursorState: Selection[] | null, editOperations: IIdentifiedSingleEditOperation[], cursorStateComputer: ICursorStateComputer, group?: any): Selection[] | null; + /** + * Change the end of line sequence. This is the preferred way of + * changing the eol sequence. This will land on the undo stack. + */ + pushEOL(eol: EndOfLineSequence): void; + /** + * Edit the model without adding the edits to the undo stack. + * This can have dire consequences on the undo stack! See @pushEditOperations for the preferred way. + * @param operations The edit operations. + * @return If desired, the inverse edit operations, that, when applied, will bring the model back to the previous state. + */ + applyEdits(operations: IIdentifiedSingleEditOperation[]): void; + applyEdits(operations: IIdentifiedSingleEditOperation[], computeUndoEdits: false): void; + applyEdits(operations: IIdentifiedSingleEditOperation[], computeUndoEdits: true): IValidEditOperation[]; + /** + * Change the end of line sequence without recording in the undo stack. + * This can have dire consequences on the undo stack! See @pushEOL for the preferred way. + */ + setEOL(eol: EndOfLineSequence): void; + /** + * @internal + */ + _applyUndo(changes: any[], eol: EndOfLineSequence, resultingAlternativeVersionId: number, resultingSelection: Selection[] | null): void; + /** + * @internal + */ + _applyRedo(changes: any[], eol: EndOfLineSequence, resultingAlternativeVersionId: number, resultingSelection: Selection[] | null): void; + /** + * Undo edit operations until the previous undo/redo point. + * The inverse edit operations will be pushed on the redo stack. + * @internal + */ + undo(): void | Promise; + /** + * Is there anything in the undo stack? + * @internal + */ + canUndo(): boolean; + /** + * Redo edit operations until the next undo/redo point. + * The inverse edit operations will be pushed on the undo stack. + * @internal + */ + redo(): void | Promise; + /** + * Is there anything in the redo stack? + * @internal + */ + canRedo(): boolean; + /** + * @deprecated Please use `onDidChangeContent` instead. + * An event emitted when the contents of the model have changed. + * @internal + * @event + */ + readonly onDidChangeContentOrInjectedText: IEvent; + /** + * An event emitted when the contents of the model have changed. + * @event + */ + onDidChangeContent(listener: (e: IModelContentChangedEvent) => void): IDisposable; + /** + * An event emitted when decorations of the model have changed. + * @event + */ + readonly onDidChangeDecorations: IEvent; + /** + * An event emitted when the model options have changed. + * @event + */ + readonly onDidChangeOptions: IEvent; + /** + * An event emitted when the language associated with the model has changed. + * @event + */ + readonly onDidChangeLanguage: IEvent; + /** + * An event emitted when the language configuration associated with the model has changed. + * @event + */ + readonly onDidChangeLanguageConfiguration: IEvent; + /** + * An event emitted when the tokens associated with the model have changed. + * @event + * @internal + */ + readonly onDidChangeTokens: IEvent; + /** + * An event emitted when the model has been attached to the first editor or detached from the last editor. + * @event + */ + readonly onDidChangeAttached: IEvent; + /** + * An event emitted right before disposing the model. + * @event + */ + readonly onWillDispose: IEvent; + /** + * Destroy this model. + */ + dispose(): void; + /** + * @internal + */ + onBeforeAttached(): IAttachedView; + /** + * @internal + */ + onBeforeDetached(view: IAttachedView): void; + /** + * Returns if this model is attached to an editor or not. + */ + isAttachedToEditor(): boolean; + /** + * Returns the count of editors this model is attached to. + * @internal + */ + getAttachedEditorCount(): number; + /** + * Among all positions that are projected to the same position in the underlying text model as + * the given position, select a unique position as indicated by the affinity. + * + * PositionAffinity.Left: + * The normalized position must be equal or left to the requested position. + * + * PositionAffinity.Right: + * The normalized position must be equal or right to the requested position. + * + * @internal + */ + normalizePosition(position: Position, affinity: PositionAffinity): Position; + /** + * Gets the column at which indentation stops at a given line. + * @internal + */ + getLineIndentColumn(lineNumber: number): number; + /** + * Returns an object that can be used to query brackets. + * @internal + */ + readonly bracketPairs: any; + /** + * Returns an object that can be used to query indent guides. + * @internal + */ + readonly guides: any; + /** + * @internal + */ + readonly tokenization: any; + } + + /** + * @internal + */ + export interface IAttachedView { + /** + * @param stabilized Indicates if the visible lines are probably going to change soon or can be considered stable. + * Is true on reveal range and false on scroll. + * Tokenizers should tokenize synchronously if stabilized is true. + */ + setVisibleLines(visibleLines: { + startLineNumber: number; + endLineNumber: number; + }[], stabilized: boolean): void; + } + + export enum PositionAffinity { + /** + * Prefers the left most position. + */ + Left = 0, + /** + * Prefers the right most position. + */ + Right = 1, + /** + * No preference. + */ + None = 2, + /** + * If the given position is on injected text, prefers the position left of it. + */ + LeftOfInjectedText = 3, + /** + * If the given position is on injected text, prefers the position right of it. + */ + RightOfInjectedText = 4 + } + + /** + * @internal + */ + export interface ITextBufferBuilder { + acceptChunk(chunk: string): void; + finish(): ITextBufferFactory; + } + + /** + * @internal + */ + export interface ITextBufferFactory { + create(defaultEOL: DefaultEndOfLine): { + textBuffer: ITextBuffer; + disposable: IDisposable; + }; + getFirstLineText(lengthLimit: number): string; + } + + /** + * @internal + * + * `lineNumber` is 1 based. + */ + export interface IReadonlyTextBuffer { + onDidChangeContent: IEvent; + equals(other: ITextBuffer): boolean; + mightContainRTL(): boolean; + mightContainUnusualLineTerminators(): boolean; + resetMightContainUnusualLineTerminators(): void; + mightContainNonBasicASCII(): boolean; + getBOM(): string; + getEOL(): string; + getOffsetAt(lineNumber: number, column: number): number; + getPositionAt(offset: number): Position; + getRangeAt(offset: number, length: number): Range; + getValueInRange(range: Range, eol: EndOfLinePreference): string; + createSnapshot(preserveBOM: boolean): ITextSnapshot; + getValueLengthInRange(range: Range, eol: EndOfLinePreference): number; + getCharacterCountInRange(range: Range, eol: EndOfLinePreference): number; + getLength(): number; + getLineCount(): number; + getLinesContent(): string[]; + getLineContent(lineNumber: number): string; + getLineCharCode(lineNumber: number, index: number): number; + getCharCode(offset: number): number; + getLineLength(lineNumber: number): number; + getLineFirstNonWhitespaceColumn(lineNumber: number): number; + getLineLastNonWhitespaceColumn(lineNumber: number): number; + findMatchesLineByLine(searchRange: Range, searchData: any, captureMatches: boolean, limitResultCount: number): FindMatch[]; + } + + /** + * @internal + */ + export interface ITextBuffer extends IReadonlyTextBuffer, IDisposable { + setEOL(newEOL: '\r\n' | '\n'): void; + applyEdits(rawOperations: any[], recordTrimAutoWhitespace: boolean, computeUndoEdits: boolean): any; + } + + /** + * @internal + */ + export interface IInternalModelContentChange extends IModelContentChange { + range: Range; + forceMoveMarkers: boolean; + } + + export enum AccessibilitySupport { + /** + * This should be the browser case where it is not known if a screen reader is attached or no. */ - revealFirstDiff(): unknown; - accessibleDiffViewerNext(): void; - accessibleDiffViewerPrev(): void; - handleInitialized(): void; + Unknown = 0, + Disabled = 1, + Enabled = 2 } - export class FontInfo extends BareFontInfo { - readonly _editorStylingBrand: void; - readonly version: number; - readonly isTrusted: boolean; - readonly isMonospace: boolean; - readonly typicalHalfwidthCharacterWidth: number; - readonly typicalFullwidthCharacterWidth: number; - readonly canUseHalfwidthRightwardsArrow: boolean; - readonly spaceWidth: number; - readonly middotWidth: number; - readonly wsmiddotWidth: number; - readonly maxDigitWidth: number; + export interface IEditorWhitespace { + readonly id: string; + readonly afterLineNumber: number; + readonly height: number; } - export class BareFontInfo { - readonly _bareFontInfoBrand: void; - readonly pixelRatio: number; - readonly fontFamily: string; - readonly fontWeight: string; - readonly fontSize: number; - readonly fontFeatureSettings: string; - readonly fontVariationSettings: string; - readonly lineHeight: number; - readonly letterSpacing: number; - } export const EditorZoom: IEditorZoom; @@ -6858,6 +8645,55 @@ declare namespace monaco.languages { removeText?: number; } + /** + * @internal + */ + export interface CompleteEnterAction { + /** + * Describe what to do with the indentation. + */ + indentAction: IndentAction; + /** + * Describes text to be appended after the new line and after the indentation. + */ + appendText: string; + /** + * Describes the number of characters to remove from the new line's indentation. + */ + removeText: number; + /** + * The line's indentation minus removeText + */ + indentation: string; + } + + /** + * @internal + */ + export interface IBackgroundTokenizer extends IDisposable { + /** + * Instructs the background tokenizer to set the tokens for the given range again. + * + * This might be necessary if the renderer overwrote those tokens with heuristically computed ones for some viewport, + * when the change does not even propagate to that viewport. + */ + requestTokens(startLineNumber: number, endLineNumberExclusive: number): void; + reportMismatchingTokens?(lineNumber: number): void; + } + + /** + * @internal + */ + export interface IBackgroundTokenizationStore { + setTokens(tokens: any[]): void; + setEndState(lineNumber: number, state: IState): void; + /** + * Should be called to indicate that the background tokenization has finished for now. + * (This triggers bracket pair colorization to re-parse the bracket pairs with token information) + */ + backgroundTokenizationFinished(): void; + } + /** * The state of the tokenizer between two lines. * It is useful to store flags such as in multiline comment, etc. @@ -6943,6 +8779,93 @@ declare namespace monaco.languages { Decrease = 1 } + /** + * An evaluatable expression represents additional information for an expression in a document. Evaluatable expressions are + * evaluated by a debugger or runtime and their result is rendered in a tooltip-like widget. + * @internal + */ + export interface EvaluatableExpression { + /** + * The range to which this expression applies. + */ + range: IRange; + /** + * This expression overrides the expression extracted from the range. + */ + expression?: string; + } + + /** + * The evaluatable expression provider interface defines the contract between extensions and + * the debug hover. + * @internal + */ + export interface EvaluatableExpressionProvider { + /** + * Provide a hover for the given position and document. Multiple hovers at the same + * position will be merged by the editor. A hover can have a range which defaults + * to the word range at the position when omitted. + */ + provideEvaluatableExpression(model: editor.ITextModel, position: Position, token: CancellationToken): ProviderResult; + } + + /** + * A value-object that contains contextual information when requesting inline values from a InlineValuesProvider. + * @internal + */ + export interface InlineValueContext { + frameId: number; + stoppedLocation: Range; + } + + /** + * Provide inline value as text. + * @internal + */ + export interface InlineValueText { + type: 'text'; + range: IRange; + text: string; + } + + /** + * Provide inline value through a variable lookup. + * @internal + */ + export interface InlineValueVariableLookup { + type: 'variable'; + range: IRange; + variableName?: string; + caseSensitiveLookup: boolean; + } + + /** + * Provide inline value through an expression evaluation. + * @internal + */ + export interface InlineValueExpression { + type: 'expression'; + range: IRange; + expression?: string; + } + + /** + * The inline values provider interface defines the contract between extensions and + * the debugger's inline values feature. + * @internal + */ + export interface InlineValuesProvider { + /** + */ + onDidChangeInlineValues?: IEvent | undefined; + /** + * Provide the "inline values" for the given range and document. Multiple hovers at the same + * position will be merged by the editor. A hover can have a range which defaults + * to the word range at the position when omitted. + */ + provideInlineValues(model: editor.ITextModel, viewPort: Range, context: InlineValueContext, token: CancellationToken): ProviderResult; + } + export enum CompletionItemKind { Method = 0, Function = 1, @@ -7086,12 +9009,24 @@ declare namespace monaco.languages { * A command that should be run upon acceptance of this item. */ command?: Command; + /** + * @internal + */ + extensionId?: any; + /** + * @internal + */ + _id?: [number, number]; } export interface CompletionList { suggestions: CompletionItem[]; incomplete?: boolean; dispose?(): void; + /** + * @internal + */ + duration?: number; } /** @@ -7148,6 +9083,13 @@ declare namespace monaco.languages { * the item, like adding {@link CompletionItem.documentation doc-comment} or {@link CompletionItem.detail details}. */ export interface CompletionItemProvider { + /** + * Used to identify completions in the (debug) UI and telemetry. This isn't the extension identifier because extensions + * often contribute multiple completion item providers. + * + * @internal + */ + _debugDisplayName: string; triggerCharacters?: string[]; /** * Provide completion items for the given position and document. @@ -7298,6 +9240,49 @@ declare namespace monaco.languages { readonly actions: ReadonlyArray; } + /** + * The code action interface defines the contract between extensions and + * the [light bulb](https://code.visualstudio.com/docs/editor/editingevolved#_code-action) feature. + * @internal + */ + export interface CodeActionProvider { + displayName?: string; + /** + * Provide commands for the given document and range. + */ + provideCodeActions(model: editor.ITextModel, range: Range | Selection, context: CodeActionContext, token: CancellationToken): ProviderResult; + /** + * Given a code action fill in the edit. Will only invoked when missing. + */ + resolveCodeAction?(codeAction: CodeAction, token: CancellationToken): ProviderResult; + /** + * Optional list of CodeActionKinds that this provider returns. + */ + readonly providedCodeActionKinds?: ReadonlyArray; + readonly documentation?: ReadonlyArray<{ + readonly kind: string; + readonly command: Command; + }>; + /** + * @internal + */ + _getAdditionalMenuItems?(context: CodeActionContext, actions: readonly CodeAction[]): Command[]; + } + + /** + * @internal + */ + export interface DocumentPasteEdit { + readonly label: string; + readonly detail: string; + readonly handledMimeType?: string; + readonly yieldTo?: readonly DropYieldTo[]; + insertText: string | { + readonly snippet: string; + }; + additionalEdit?: WorkspaceEdit; + } + /** * Represents a parameter of a callable-signature. A parameter can * have a label and a doc-comment. @@ -7690,6 +9675,10 @@ declare namespace monaco.languages { * the formatting-feature. */ export interface DocumentFormattingEditProvider { + /** + * @internal + */ + readonly extensionId?: any; readonly displayName?: string; /** * Provide formatting edits for a whole document. @@ -7702,6 +9691,10 @@ declare namespace monaco.languages { * the formatting-feature. */ export interface DocumentRangeFormattingEditProvider { + /** + * @internal + */ + readonly extensionId?: any; readonly displayName?: string; /** * Provide formatting edits for a range in a document. @@ -7719,6 +9712,10 @@ declare namespace monaco.languages { * the formatting-feature. */ export interface OnTypeFormattingEditProvider { + /** + * @internal + */ + readonly extensionId?: any; autoFormatTriggerCharacters: string[]; /** * Provide formatting edits after a character has been typed. @@ -7730,6 +9727,14 @@ declare namespace monaco.languages { provideOnTypeFormattingEdits(model: editor.ITextModel, position: Position, ch: string, options: FormattingOptions, token: CancellationToken): ProviderResult; } + /** + * @internal + */ + export interface IInplaceReplaceSupportResult { + value: string; + range: IRange; + } + /** * A link inside the editor. */ @@ -7842,6 +9847,10 @@ declare namespace monaco.languages { * A provider of folding ranges for editor models. */ export interface FoldingRangeProvider { + /** + * @internal + */ + readonly id?: string; /** * An optional event to signal that the folding ranges from this provider have changed. */ @@ -7903,6 +9912,13 @@ declare namespace monaco.languages { needsConfirmation: boolean; label: string; description?: string; + /** + * @internal + */ + iconPath?: editor.ThemeIcon | Uri | { + light: Uri; + dark: Uri; + }; } export interface WorkspaceFileEditOptions { @@ -7914,6 +9930,10 @@ declare namespace monaco.languages { folder?: boolean; skipTrashBin?: boolean; maxSize?: number; + /** + * @internal + */ + contents?: Promise; } export interface IWorkspaceFileEdit { @@ -7999,6 +10019,28 @@ declare namespace monaco.languages { cursor: IPosition; } + /** + * @internal + */ + export interface CommentThreadChangedEvent { + /** + * Pending comment threads. + */ + readonly pending: PendingCommentThread[]; + /** + * Added comment threads. + */ + readonly added: CommentThread[]; + /** + * Removed comment threads. + */ + readonly removed: CommentThread[]; + /** + * Changed comment threads. + */ + readonly changed: CommentThread[]; + } + export interface CodeLens { range: IRange; id?: string; @@ -8083,6 +10125,33 @@ declare namespace monaco.languages { provideDocumentRangeSemanticTokens(model: editor.ITextModel, range: Range, token: CancellationToken): ProviderResult; } + /** + * @internal + */ + export interface ITokenizationSupportChangedEvent { + changedLanguages: string[]; + changedColorMap: boolean; + } + + export type DropYieldTo = { + readonly providerId: string; + } | { + readonly mimeType: string; + }; + + /** + * @internal + */ + export interface DocumentOnDropEdit { + readonly label: string; + readonly handledMimeType?: string; + readonly yieldTo?: readonly DropYieldTo[]; + insertText: string | { + readonly snippet: string; + }; + additionalEdit?: WorkspaceEdit; + } + export interface DocumentContextItem { readonly uri: Uri; readonly version: number; @@ -8139,6 +10208,20 @@ declare namespace monaco.languages { aliases?: string[]; mimetypes?: string[]; configuration?: Uri; + /** + * @internal + */ + icon?: ILanguageIcon; + } + + export interface ILanguageIcon { + readonly light: Uri; + readonly dark: Uri; + } + + export interface ILanguageSelection { + readonly languageId: string; + readonly onDidChange: IEvent; } /** * A Monarch language definition @@ -8276,12 +10359,41 @@ declare namespace monaco.languages { */ token: string; } - + export type InlineValue = InlineValueText | InlineValueVariableLookup | InlineValueExpression; } declare namespace monaco.worker { + export interface IDocumentColorComputerTarget { + getValue(): string; + positionAt(offset: number): IPosition; + findMatches(regex: RegExp): RegExpMatchArray[]; + } + + /** + * Word inside a model. + */ + export interface IWordAtPosition { + /** + * The word. + */ + readonly word: string; + /** + * The column where the word starts. + */ + readonly startColumn: number; + /** + * The column where the word ends. + */ + readonly endColumn: number; + } + + export interface ILinkComputerTarget { + getLineCount(): number; + getLineContent(lineNumber: number): string; + } + export interface IMirrorTextModel { readonly version: number; } @@ -8303,6 +10415,44 @@ declare namespace monaco.worker { getMirrorModels(): IMirrorModel[]; } + /** + * @internal + */ + export interface IRawModelData { + url: string; + versionId: number; + lines: string[]; + EOL: string; + } + + /** + * @internal + */ + export interface ICommonModel extends ILinkComputerTarget, IDocumentColorComputerTarget, IMirrorModel { + uri: Uri; + version: number; + eol: string; + getValue(): string; + getLinesContent(): string[]; + getLineCount(): number; + getLineContent(lineNumber: number): string; + getLineWords(lineNumber: number, wordDefinition: RegExp): IWordAtPosition[]; + words(wordDefinition: RegExp): Iterable; + getWordUntilPosition(position: IPosition, wordDefinition: RegExp): IWordAtPosition; + getValueInRange(range: IRange): string; + getWordAtPosition(position: IPosition, wordDefinition: RegExp): Range | null; + offsetAt(position: IPosition): number; + positionAt(offset: number): IPosition; + findMatches(regex: RegExp): RegExpMatchArray[]; + } + + /** + * @internal + */ + export interface IForeignModuleFactory { + (ctx: IWorkerContext, createData: any): any; + } + } //dtsv=3 From 374b60930d3ba200eaf5b0e4032e8b839b31876d Mon Sep 17 00:00:00 2001 From: ricbet Date: Tue, 26 Dec 2023 13:57:13 +0800 Subject: [PATCH 02/10] chore: cherry-pick 0.47.0 patch --- build/hygiene.js | 5 +++ src/vs/base/browser/settings.ts | 26 +++++++++++++ .../contentWidgets/contentWidgets.ts | 14 ++++--- .../browser/viewParts/viewLines/viewLine.ts | 2 +- .../editor/common/languages/modesRegistry.ts | 6 +-- .../common/services/languagesRegistry.ts | 37 +++++++------------ .../workbench/api/common/extHostTreeViews.ts | 2 +- 7 files changed, 58 insertions(+), 34 deletions(-) create mode 100644 src/vs/base/browser/settings.ts diff --git a/build/hygiene.js b/build/hygiene.js index fe32fe33e12..2e504c087fe 100644 --- a/build/hygiene.js +++ b/build/hygiene.js @@ -19,6 +19,7 @@ const copyrightHeaderLines = [ ' * Licensed under the MIT License. See License.txt in the project root for license information.', ' *--------------------------------------------------------------------------------------------*/', ]; +const skipCopyrightFiles = ['src/vs/base/browser/settings.ts']; function hygiene(some, linting = true) { const eslint = require('./gulp-eslint'); @@ -98,6 +99,10 @@ function hygiene(some, linting = true) { }); const copyrights = es.through(function (file) { + if (skipCopyrightFiles.includes(file.relative)) { + this.emit('data', file); + return; + } const lines = file.__lines; for (let i = 0; i < copyrightHeaderLines.length; i++) { diff --git a/src/vs/base/browser/settings.ts b/src/vs/base/browser/settings.ts new file mode 100644 index 00000000000..9e76403eb52 --- /dev/null +++ b/src/vs/base/browser/settings.ts @@ -0,0 +1,26 @@ +/* eslint-disable header/header */ + +class OverflowContentWidgetsSettings { + private _TOP_PADDING = 22; + private _BOTTOM_PADDING = 22; + + set topPadding(num: number) { + if (Number.isInteger(num)) { + this._TOP_PADDING = num; + } + } + get topPadding() { + return this._TOP_PADDING; + } + + set bottomPadding(num: number) { + if (Number.isInteger(num)) { + this._BOTTOM_PADDING = num; + } + } + get bottomPadding() { + return this._BOTTOM_PADDING; + } +} + +export const overflowWidgetsSettings = new OverflowContentWidgetsSettings(); diff --git a/src/vs/editor/browser/viewParts/contentWidgets/contentWidgets.ts b/src/vs/editor/browser/viewParts/contentWidgets/contentWidgets.ts index be7bd39b7f9..9c6eac5248c 100644 --- a/src/vs/editor/browser/viewParts/contentWidgets/contentWidgets.ts +++ b/src/vs/editor/browser/viewParts/contentWidgets/contentWidgets.ts @@ -16,6 +16,7 @@ import { IDimension } from '../../../common/core/dimension.js'; import { PositionAffinity } from '../../../common/model.js'; import { IPosition, Position } from '../../../common/core/position.js'; import { IViewModel } from '../../../common/viewModel.js'; +import { overflowWidgetsSettings } from '../../../../base/browser/settings.js'; /** * This view part is responsible for rendering the content widgets, which are @@ -306,6 +307,9 @@ class Widget { private _layoutBoxInViewport(anchor: AnchorCoordinate, width: number, height: number, ctx: RenderingContext): IBoxLayoutResult { // Our visible box is split horizontally by the current line => 2 boxes + // 这里获取 domNode 的 clientHeight 可能为 0,会导致下面计算 contentWidget 定位时整体向下偏移了一行 + // 由于获取的是缓存的 height,且 domNode 渲染时机暂时不好修改,所以如果高度为0的话,在这里重新获取一次高度 + const contentHeight = height === 0 ? this.domNode.domNode.clientHeight : height; // a) the box above the line const aboveLineTop = anchor.top; @@ -315,10 +319,10 @@ class Widget { const underLineTop = anchor.top + anchor.height; const heightAvailableUnderLine = ctx.viewportHeight - underLineTop; - const aboveTop = aboveLineTop - height; - const fitsAbove = (heightAvailableAboveLine >= height); + const aboveTop = aboveLineTop - contentHeight; + const fitsAbove = (heightAvailableAboveLine >= contentHeight); const belowTop = underLineTop; - const fitsBelow = (heightAvailableUnderLine >= height); + const fitsBelow = (heightAvailableUnderLine >= contentHeight); // And its left let left = anchor.left; @@ -374,8 +378,8 @@ class Widget { const [left, absoluteAboveLeft] = this._layoutHorizontalSegmentInPage(windowSize, domNodePosition, anchor.left - ctx.scrollLeft + this._contentLeft, width); // Leave some clearance to the top/bottom - const TOP_PADDING = 22; - const BOTTOM_PADDING = 22; + const TOP_PADDING = overflowWidgetsSettings.topPadding; + const BOTTOM_PADDING = overflowWidgetsSettings.bottomPadding; const fitsAbove = (absoluteAboveTop >= TOP_PADDING); const fitsBelow = (absoluteBelowTop + height <= windowSize.height - BOTTOM_PADDING); diff --git a/src/vs/editor/browser/viewParts/viewLines/viewLine.ts b/src/vs/editor/browser/viewParts/viewLines/viewLine.ts index 5e555246cea..1250a9f6249 100644 --- a/src/vs/editor/browser/viewParts/viewLines/viewLine.ts +++ b/src/vs/editor/browser/viewParts/viewLines/viewLine.ts @@ -481,7 +481,7 @@ class RenderedViewLine implements IRenderedViewLine { if (!this.domNode) { return 0; } - if (this._cachedWidth === -1) { + if (this._cachedWidth <= 0) { this._cachedWidth = this._getReadingTarget(this.domNode).offsetWidth; context?.markDidDomLayout(); } diff --git a/src/vs/editor/common/languages/modesRegistry.ts b/src/vs/editor/common/languages/modesRegistry.ts index 871265804d2..db8a2e04f4e 100644 --- a/src/vs/editor/common/languages/modesRegistry.ts +++ b/src/vs/editor/common/languages/modesRegistry.ts @@ -20,8 +20,8 @@ export class EditorModesRegistry { private readonly _languages: ILanguageExtensionPoint[]; - private readonly _onDidChangeLanguages = new Emitter(); - public readonly onDidChangeLanguages: Event = this._onDidChangeLanguages.event; + private readonly _onDidChangeLanguages = new Emitter(); + public readonly onDidChangeLanguages: Event = this._onDidChangeLanguages.event; constructor() { this._languages = []; @@ -29,7 +29,7 @@ export class EditorModesRegistry { public registerLanguage(def: ILanguageExtensionPoint): IDisposable { this._languages.push(def); - this._onDidChangeLanguages.fire(undefined); + this._onDidChangeLanguages.fire(def); return { dispose: () => { for (let i = 0, len = this._languages.length; i < len; i++) { diff --git a/src/vs/editor/common/services/languagesRegistry.ts b/src/vs/editor/common/services/languagesRegistry.ts index 3ea71cff4ee..c94f773c6e8 100644 --- a/src/vs/editor/common/services/languagesRegistry.ts +++ b/src/vs/editor/common/services/languagesRegistry.ts @@ -92,8 +92,8 @@ export class LanguagesRegistry extends Disposable { if (useModesRegistry) { this._initializeFromRegistry(); - this._register(ModesRegistry.onDidChangeLanguages((m) => { - this._initializeFromRegistry(); + this._register(ModesRegistry.onDidChangeLanguages((lang) => { + this._registerLanguage(lang); })); } } @@ -105,7 +105,7 @@ export class LanguagesRegistry extends Disposable { public setDynamicLanguages(def: ILanguageExtensionPoint[]): void { this._dynamicLanguages = def; - this._initializeFromRegistry(); + this._registerLanguages(this._dynamicLanguages); } private _initializeFromRegistry(): void { @@ -115,8 +115,6 @@ export class LanguagesRegistry extends Disposable { this._lowercaseNameMap = {}; clearPlatformLanguageAssociations(); - const desc = ([]).concat(ModesRegistry.getLanguages()).concat(this._dynamicLanguages); - this._registerLanguages(desc); } registerLanguage(desc: ILanguageExtensionPoint): IDisposable { @@ -124,28 +122,10 @@ export class LanguagesRegistry extends Disposable { } _registerLanguages(desc: ILanguageExtensionPoint[]): void { - for (const d of desc) { this._registerLanguage(d); } - // Rebuild fast path maps - this._mimeTypesMap = {}; - this._nameMap = {}; - this._lowercaseNameMap = {}; - Object.keys(this._languages).forEach((langId) => { - const language = this._languages[langId]; - if (language.name) { - this._nameMap[language.name] = language.identifier; - } - language.aliases.forEach((alias) => { - this._lowercaseNameMap[alias.toLowerCase()] = language.identifier; - }); - language.mimetypes.forEach((mimetype) => { - this._mimeTypesMap[mimetype] = language.identifier; - }); - }); - Registry.as(Extensions.Configuration).registerOverrideIdentifiers(this.getRegisteredLanguageIds()); this._onDidChange.fire(); @@ -153,7 +133,6 @@ export class LanguagesRegistry extends Disposable { private _registerLanguage(lang: ILanguageExtensionPoint): void { const langId = lang.id; - let resolvedLanguage: IResolvedLanguage; if (hasOwnProperty.call(this._languages, langId)) { resolvedLanguage = this._languages[langId]; @@ -173,6 +152,16 @@ export class LanguagesRegistry extends Disposable { } this._mergeLanguage(resolvedLanguage, lang); + // Rebuild fast path maps + if (resolvedLanguage.name) { + this._nameMap[resolvedLanguage.name] = resolvedLanguage.identifier; + } + resolvedLanguage.aliases.forEach((alias) => { + this._lowercaseNameMap[alias.toLowerCase()] = resolvedLanguage.identifier; + }); + resolvedLanguage.mimetypes.forEach((mimetype) => { + this._mimeTypesMap[mimetype] = resolvedLanguage.identifier; + }); } private _mergeLanguage(resolvedLanguage: IResolvedLanguage, lang: ILanguageExtensionPoint): void { diff --git a/src/vs/workbench/api/common/extHostTreeViews.ts b/src/vs/workbench/api/common/extHostTreeViews.ts index d3c2aae3c12..a5d2fbaeae4 100644 --- a/src/vs/workbench/api/common/extHostTreeViews.ts +++ b/src/vs/workbench/api/common/extHostTreeViews.ts @@ -385,7 +385,7 @@ class ExtHostTreeView extends Disposable { result.message = true; } return result; - }, 200, true); + }, 200); this._register(onDidChangeData(({ message, elements }) => { if (elements.length) { this.refreshQueue = this.refreshQueue.then(() => { From 7daf6fc7a2794b7db45181d74d4d708edb61ed5d Mon Sep 17 00:00:00 2001 From: "qingyi.xjh" Date: Tue, 19 Nov 2024 15:55:02 +0800 Subject: [PATCH 03/10] feat: extraction interface & type --- build/gulpfile.editor.js | 1 - build/monaco/monaco.d.ts.recipe | 13 +- src/vs/editor/common/languages.ts | 11 +- .../common/standalone/standaloneEnums.ts | 17 + .../standalone/browser/standaloneEditor.ts | 8 +- .../standalone/browser/standaloneLanguages.ts | 4 + src/vs/monaco.d.ts | 1879 ++++++++--------- 7 files changed, 911 insertions(+), 1022 deletions(-) diff --git a/build/gulpfile.editor.js b/build/gulpfile.editor.js index fbb15996d21..8f6d8f7c08d 100644 --- a/build/gulpfile.editor.js +++ b/build/gulpfile.editor.js @@ -388,7 +388,6 @@ gulp.task('editor-distro', ), task.series( createESMSourcesAndResourcesTask, - appendJSToESMImportsTask, compileEditorEsmTask ) ), diff --git a/build/monaco/monaco.d.ts.recipe b/build/monaco/monaco.d.ts.recipe index 15c7975454a..757ed825132 100644 --- a/build/monaco/monaco.d.ts.recipe +++ b/build/monaco/monaco.d.ts.recipe @@ -104,6 +104,7 @@ export interface ILocalizedString { export interface ICommandMetadata { readonly description: ILocalizedString | string; } +#include(vs/platform/actions/common/actions): MenuId #include(vs/platform/contextkey/common/contextkey): IContextKey, ContextKeyValue #include(vs/editor/standalone/browser/standaloneServices): IEditorOverrideServices #include(vs/platform/markers/common/markers): IMarker, IMarkerData, IRelatedInformation @@ -114,6 +115,7 @@ export interface ICommandMetadata { #include(vs/editor/common/core/wordHelper): IWordAtPosition #include(vs/editor/common/diff/legacyLinesDiffComputer): IChange, ICharChange, ILineChange #include(vs/editor/common/core/dimension): IDimension +#include(vs/editor/common/core/offsetRange): OffsetRange, IOffsetRange #includeAll(vs/editor/common/editorCommon): IScrollEvent #includeAll(vs/editor/common/textModelEvents): #includeAll(vs/editor/common/config/editorOptions;IConfigurationPropertySchema=>any;ComputeOptionsMemory):BaseEditorOption,ComputedEditorOption,EditorFontLigatures,EditorLayoutInfoComputer,EditorLayoutInfoComputerEnv @@ -121,10 +123,10 @@ export interface ICommandMetadata { #includeAll(vs/editor/common/cursorEvents): #includeAll(vs/editor/browser/editorBrowser;IMouseWheelEvent=>any;editorCommon.=>;InjectedText=>any;ServicesAccessor=>any;IViewModel=>any;IDiffComputationResult=>any;IContextKeyService=>any;IBoundarySashes=>any):IOverviewRuler #include(vs/editor/common/config/fontInfo;IValidatedEditorOptions=>any): FontInfo, BareFontInfo -#includeAll(vs/editor/common/model;StandardTokenType=>any;IBracketPairsTextModelPart=>any;ITokenizationTextModelPart=>any;IGuidesTextModelPart=>any;LanguageIdentifier=>any;ContiguousMultilineTokens=>any;SparseMultilineTokens=>any;InternalModelContentChangeEvent=>any;MultilineTokens=>any;MultilineTokens2=>any;LineTokens=>any;SearchData=>any;LanguageId=>any;FormattingOptions=>languages.FormattingOptions;ModelRawContentChangedEvent=>any;ApplyEditsResult=>any;ValidAnnotatedEditOperation=>any;TextChange=> any;ModelInjectedTextChangedEvent=>any;PositionNormalizationAffinity=>any;IndentGuide=>any;ILanguageSelection=>languages.ILanguageSelection;UndoRedoGroup=>any): IScrollEvent,TextChange +#includeAll(vs/editor/common/model;StandardTokenType=>any;IBracketPairsTextModelPart=>any;ITokenizationTextModelPart=>any;IGuidesTextModelPart=>any;LanguageIdentifier=>any;ContiguousMultilineTokens=>any;SparseMultilineTokens=>any;InternalModelContentChangeEvent=>any;MultilineTokens=>any;MultilineTokens2=>any;LineTokens=>any;SearchData=>any;FormattingOptions=>languages.FormattingOptions;ModelRawContentChangedEvent=>any;ApplyEditsResult=>any;ValidAnnotatedEditOperation=>any;TextChange=> any;ModelInjectedTextChangedEvent=>any;PositionNormalizationAffinity=>any;IndentGuide=>any;ILanguageSelection=>languages.ILanguageSelection;UndoRedoGroup=>any): IScrollEvent,TextChange #include(vs/platform/accessibility/common/accessibility): AccessibilitySupport #include(vs/editor/common/viewModel): IEditorWhitespace - +#includeAll(vs/editor/common/tokens/tokenArray): #include(vs/editor/common/config/editorZoom): EditorZoom, IEditorZoom //compatibility: @@ -135,11 +137,14 @@ export type IModel = ITextModel; declare namespace monaco.languages { #include(vs/base/common/glob): IRelativePattern +#include(vs/base/common/hierarchicalKind): HierarchicalKind +#include(vs/base/common/dataTransfer): IDataTransferItem, IReadonlyVSDataTransfer, IDataTransferFile #include(vs/editor/common/languageSelector): LanguageSelector, LanguageFilter #includeAll(vs/editor/standalone/browser/standaloneLanguages;modes.=>;languages.=>;editorCommon.=>editor.;model.=>editor.;IMarkerData=>editor.IMarkerData): #includeAll(vs/editor/common/languages/languageConfiguration): -#includeAll(vs/editor/common/languages;IMarkerData=>editor.IMarkerData;ISingleEditOperation=>editor.ISingleEditOperation;model.=>editor.;CommentMode=>any;ExtensionIdentifier=>any;ITokenizationSupportFactory=>any;CommentThreadState=>any;CommentThreadCollapsibleState=>any;CommentThreadState=>any;ContiguousMultilineTokens=>any;ThemeIcon=>editor.ThemeIcon;VSBuffer=>any):ITokenPresentation,ILanguageIdCodec,ITokenizationRegistry,ITokenizationSupport,ILazyTokenizationSupport,ITokenizationSupportFactory,CodeActionContext,Token,DocumentPasteEditProvider,DocumentOnDropEditProvider -#include(vs/editor/common/languages/language): ILanguageExtensionPoint,ILanguageIcon,ILanguageSelection +#include(vs/editor/common/encodedTokenAttributes): LanguageId +#includeAll(vs/editor/common/languages/language): ILanguageService +#includeAll(vs/editor/common/languages;IMarkerData=>editor.IMarkerData;ISingleEditOperation=>editor.ISingleEditOperation;model.=>editor.;CommentMode=>any;ExtensionIdentifier=>any;ITokenizationSupportFactory=>any;CommentThreadState=>any;CommentThreadCollapsibleState=>any;CommentThreadState=>any;ContiguousMultilineTokens=>any;ThemeIcon=>editor.ThemeIcon;VSBuffer=>any):ITokenPresentation,ITokenizationRegistry,ITokenizationSupport,ILazyTokenizationSupport,ITokenizationSupportFactory,CodeActionContext,Token,DocumentPasteEditProvider,DocumentOnDropEditProvider,ITreeSitterTokenizationSupport #includeAll(vs/editor/standalone/common/monarch/monarchTypes): export type InlineValue = InlineValueText | InlineValueVariableLookup | InlineValueExpression; } diff --git a/src/vs/editor/common/languages.ts b/src/vs/editor/common/languages.ts index 967adf2c8cd..3c247229750 100644 --- a/src/vs/editor/common/languages.ts +++ b/src/vs/editor/common/languages.ts @@ -29,9 +29,8 @@ import { IMarkerData } from '../../platform/markers/common/markers.js'; import { IModelTokensChangedEvent } from './textModelEvents.js'; import type { Parser } from '@vscode/tree-sitter-wasm'; -/** - * @internal - */ +export { HierarchicalKind } from '../../base/common/hierarchicalKind.js'; + export interface ILanguageIdCodec { encodeLanguageId(languageId: string): LanguageId; decodeLanguageId(languageId: LanguageId): string; @@ -897,9 +896,6 @@ export interface DocumentPasteEdit { additionalEdit?: WorkspaceEdit; } -/** - * @internal - */ export enum DocumentPasteTriggerKind { Automatic = 0, PasteAs = 1, @@ -1857,9 +1853,6 @@ export enum CommentThreadState { Resolved = 1 } -/** - * @internal - */ export enum CommentThreadApplicability { Current = 0, Outdated = 1 diff --git a/src/vs/editor/common/standalone/standaloneEnums.ts b/src/vs/editor/common/standalone/standaloneEnums.ts index 01607d8310b..5e24af5e645 100644 --- a/src/vs/editor/common/standalone/standaloneEnums.ts +++ b/src/vs/editor/common/standalone/standaloneEnums.ts @@ -20,6 +20,11 @@ export enum CodeActionTriggerType { Auto = 2 } +export enum CommentThreadApplicability { + Current = 0, + Outdated = 1 +} + export enum CompletionItemInsertTextRule { None = 0, /** @@ -161,6 +166,11 @@ export enum DocumentHighlightKind { Write = 2 } +export enum DocumentPasteTriggerKind { + Automatic = 0, + PasteAs = 1 +} + /** * Configuration options for auto indentation in the editor */ @@ -640,6 +650,13 @@ export enum KeyCode { */ MAX_VALUE = 132 } +/** + * Open ended enum at runtime + */ +export enum LanguageId { + Null = 0, + PlainText = 1 +} export enum MarkerSeverity { Hint = 1, diff --git a/src/vs/editor/standalone/browser/standaloneEditor.ts b/src/vs/editor/standalone/browser/standaloneEditor.ts index 92df7c57a64..85d1e343f34 100644 --- a/src/vs/editor/standalone/browser/standaloneEditor.ts +++ b/src/vs/editor/standalone/browser/standaloneEditor.ts @@ -39,6 +39,8 @@ import { IKeybindingService } from '../../../platform/keybinding/common/keybindi import { IMarker, IMarkerData, IMarkerService } from '../../../platform/markers/common/markers.js'; import { IOpenerService } from '../../../platform/opener/common/opener.js'; import { MultiDiffEditorWidget } from '../../browser/widget/multiDiffEditor/multiDiffEditorWidget.js'; +import { OffsetRange } from '../../common/core/offsetRange.js'; +import { TokenArray, TokenArrayBuilder, TokenInfo } from '../../common/tokens/tokenArray.js'; /** * Create a new editor under `domElement`. @@ -565,6 +567,7 @@ export function createMonacoEditorAPI(): typeof monaco.editor { InjectedTextCursorStops: standaloneEnums.InjectedTextCursorStops, PositionAffinity: standaloneEnums.PositionAffinity, ShowLightbulbIconMode: standaloneEnums.ShowLightbulbIconMode, + MenuId: MenuId, // classes ConfigurationChangedEvent: ConfigurationChangedEvent, @@ -574,8 +577,11 @@ export function createMonacoEditorAPI(): typeof monaco.editor { FindMatch: FindMatch, ApplyUpdateResult: ApplyUpdateResult, EditorZoom: EditorZoom, - createMultiFileDiffEditor: createMultiFileDiffEditor, + OffsetRange: OffsetRange, + TokenArray: TokenArray, + TokenInfo: TokenInfo, + TokenArrayBuilder: TokenArrayBuilder, // vars EditorType: EditorType, diff --git a/src/vs/editor/standalone/browser/standaloneLanguages.ts b/src/vs/editor/standalone/browser/standaloneLanguages.ts index 849e4dc42d7..e065929554e 100644 --- a/src/vs/editor/standalone/browser/standaloneLanguages.ts +++ b/src/vs/editor/standalone/browser/standaloneLanguages.ts @@ -812,9 +812,13 @@ export function createMonacoLanguagesAPI(): typeof monaco.languages { NewSymbolNameTriggerKind: standaloneEnums.NewSymbolNameTriggerKind, PartialAcceptTriggerKind: standaloneEnums.PartialAcceptTriggerKind, HoverVerbosityAction: standaloneEnums.HoverVerbosityAction, + LanguageId: standaloneEnums.LanguageId, + DocumentPasteTriggerKind: standaloneEnums.DocumentPasteTriggerKind, + CommentThreadApplicability: standaloneEnums.CommentThreadApplicability, // classes FoldingRangeKind: languages.FoldingRangeKind, SelectedSuggestionInfo: languages.SelectedSuggestionInfo, + HierarchicalKind: languages.HierarchicalKind, }; } diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index 4b9e1073cd4..e7545fd2f4a 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -1464,954 +1464,330 @@ declare namespace monaco.editor { readonly description: ILocalizedString | string; } - export interface IContextKey { - set(value: T): void; - reset(): void; - get(): T | undefined; - } - - export type ContextKeyValue = null | undefined | boolean | number | string | Array | Record; - - export interface IEditorOverrideServices { - [index: string]: any; - } - - export interface IMarker { - owner: string; - resource: Uri; - severity: MarkerSeverity; - code?: string | { - value: string; - target: Uri; - }; - message: string; - source?: string; - startLineNumber: number; - startColumn: number; - endLineNumber: number; - endColumn: number; - modelVersionId?: number; - relatedInformation?: IRelatedInformation[]; - tags?: MarkerTag[]; - } - - /** - * A structure defining a problem/warning/etc. - */ - export interface IMarkerData { - code?: string | { - value: string; - target: Uri; - }; - severity: MarkerSeverity; - message: string; - source?: string; - startLineNumber: number; - startColumn: number; - endLineNumber: number; - endColumn: number; - modelVersionId?: number; - relatedInformation?: IRelatedInformation[]; - tags?: MarkerTag[]; - } - - /** - * - */ - export interface IRelatedInformation { - resource: Uri; - message: string; - startLineNumber: number; - startColumn: number; - endLineNumber: number; - endColumn: number; - } - - export interface IColorizerOptions { - tabSize?: number; - } - - export interface IColorizerElementOptions extends IColorizerOptions { - theme?: string; - mimeType?: string; - } - - export enum ScrollbarVisibility { - Auto = 1, - Hidden = 2, - Visible = 3 - } - - export interface ThemeIcon { - readonly id: string; - readonly color?: ThemeColor; - } - - export interface ThemeColor { - id: string; - } - - /** - * A single edit operation, that acts as a simple replace. - * i.e. Replace text at `range` with `text` in model. - */ - export interface ISingleEditOperation { - /** - * The range to replace. This can be empty to emulate a simple insert. - */ - range: IRange; - /** - * The text to replace with. This can be null to emulate a simple delete. - */ - text: string | null; - /** - * This indicates that this operation has "insert" semantics. - * i.e. forceMoveMarkers = true => if `range` is collapsed, all markers at the position will be moved. - */ - forceMoveMarkers?: boolean; - } - - /** - * Word inside a model. - */ - export interface IWordAtPosition { - /** - * The word. - */ - readonly word: string; - /** - * The column where the word starts. - */ - readonly startColumn: number; - /** - * The column where the word ends. - */ - readonly endColumn: number; - } - - /** - * Vertical Lane in the overview ruler of the editor. - */ - export enum OverviewRulerLane { - Left = 1, - Center = 2, - Right = 4, - Full = 7 - } - - /** - * Vertical Lane in the glyph margin of the editor. - */ - export enum GlyphMarginLane { - Left = 1, - Center = 2, - Right = 3 - } - - export interface IGlyphMarginLanesModel { - /** - * The number of lanes that should be rendered in the editor. - */ - readonly requiredLanes: number; - /** - * Gets the lanes that should be rendered starting at a given line number. - */ - getLanesAtLine(lineNumber: number): GlyphMarginLane[]; - /** - * Resets the model and ensures it can contain at least `maxLine` lines. - */ - reset(maxLine: number): void; - /** - * Registers that a lane should be visible at the Range in the model. - * @param persist - if true, notes that the lane should always be visible, - * even on lines where there's no specific request for that lane. - */ - push(lane: GlyphMarginLane, range: Range, persist?: boolean): void; - } - - /** - * Position in the minimap to render the decoration. - */ - export enum MinimapPosition { - Inline = 1, - Gutter = 2 - } - - /** - * Section header style. - */ - export enum MinimapSectionHeaderStyle { - Normal = 1, - Underlined = 2 - } - - export interface IDecorationOptions { - /** - * CSS color to render. - * e.g.: rgba(100, 100, 100, 0.5) or a color from the color registry - */ - color: string | ThemeColor | undefined; - /** - * CSS color to render. - * e.g.: rgba(100, 100, 100, 0.5) or a color from the color registry - */ - darkColor?: string | ThemeColor; - } - - export interface IModelDecorationGlyphMarginOptions { - /** - * The position in the glyph margin. - */ - position: GlyphMarginLane; - /** - * Whether the glyph margin lane in {@link position} should be rendered even - * outside of this decoration's range. - */ - persistLane?: boolean; - } - - /** - * Options for rendering a model decoration in the overview ruler. - */ - export interface IModelDecorationOverviewRulerOptions extends IDecorationOptions { - /** - * The position in the overview ruler. - */ - position: OverviewRulerLane; - } - - /** - * Options for rendering a model decoration in the minimap. - */ - export interface IModelDecorationMinimapOptions extends IDecorationOptions { - /** - * The position in the minimap. - */ - position: MinimapPosition; - /** - * If the decoration is for a section header, which header style. - */ - sectionHeaderStyle?: MinimapSectionHeaderStyle | null; - /** - * If the decoration is for a section header, the header text. - */ - sectionHeaderText?: string | null; - } - - /** - * Options for a model decoration. - */ - export interface IModelDecorationOptions { - /** - * Customize the growing behavior of the decoration when typing at the edges of the decoration. - * Defaults to TrackedRangeStickiness.AlwaysGrowsWhenTypingAtEdges - */ - stickiness?: TrackedRangeStickiness; - /** - * CSS class name describing the decoration. - */ - className?: string | null; - /** - * Indicates whether the decoration should span across the entire line when it continues onto the next line. - */ - shouldFillLineOnLineBreak?: boolean | null; - blockClassName?: string | null; - /** - * Indicates if this block should be rendered after the last line. - * In this case, the range must be empty and set to the last line. - */ - blockIsAfterEnd?: boolean | null; - blockDoesNotCollapse?: boolean | null; - blockPadding?: [top: number, right: number, bottom: number, left: number] | null; - /** - * Message to be rendered when hovering over the glyph margin decoration. - */ - glyphMarginHoverMessage?: IMarkdownString | IMarkdownString[] | null; - /** - * Array of MarkdownString to render as the decoration message. - */ - hoverMessage?: IMarkdownString | IMarkdownString[] | null; - /** - * Array of MarkdownString to render as the line number message. - */ - lineNumberHoverMessage?: IMarkdownString | IMarkdownString[] | null; - /** - * Should the decoration expand to encompass a whole line. - */ - isWholeLine?: boolean; - /** - * Always render the decoration (even when the range it encompasses is collapsed). - */ - showIfCollapsed?: boolean; - /** - * Specifies the stack order of a decoration. - * A decoration with greater stack order is always in front of a decoration with - * a lower stack order when the decorations are on the same line. - */ - zIndex?: number; - /** - * If set, render this decoration in the overview ruler. - */ - overviewRuler?: IModelDecorationOverviewRulerOptions | null; - /** - * If set, render this decoration in the minimap. - */ - minimap?: IModelDecorationMinimapOptions | null; - /** - * If set, the decoration will be rendered in the glyph margin with this CSS class name. - */ - glyphMarginClassName?: string | null; - /** - * If set and the decoration has {@link glyphMarginClassName} set, render this decoration - * with the specified {@link IModelDecorationGlyphMarginOptions} in the glyph margin. - */ - glyphMargin?: IModelDecorationGlyphMarginOptions | null; - /** - * If set, the decoration will be rendered in the lines decorations with this CSS class name. - */ - linesDecorationsClassName?: string | null; - /** - * Controls the tooltip text of the line decoration. - */ - linesDecorationsTooltip?: string | null; - /** - * If set, the decoration will be rendered on the line number. - */ - lineNumberClassName?: string | null; - /** - * If set, the decoration will be rendered in the lines decorations with this CSS class name, but only for the first line in case of line wrapping. - */ - firstLineDecorationClassName?: string | null; - /** - * If set, the decoration will be rendered in the margin (covering its full width) with this CSS class name. - */ - marginClassName?: string | null; - /** - * If set, the decoration will be rendered inline with the text with this CSS class name. - * Please use this only for CSS rules that must impact the text. For example, use `className` - * to have a background color decoration. - */ - inlineClassName?: string | null; - /** - * If there is an `inlineClassName` which affects letter spacing. - */ - inlineClassNameAffectsLetterSpacing?: boolean; - /** - * If set, the decoration will be rendered before the text with this CSS class name. - */ - beforeContentClassName?: string | null; - /** - * If set, the decoration will be rendered after the text with this CSS class name. - */ - afterContentClassName?: string | null; - /** - * If set, text will be injected in the view after the range. - */ - after?: InjectedTextOptions | null; - /** - * If set, text will be injected in the view before the range. - */ - before?: InjectedTextOptions | null; - } - - /** - * Configures text that is injected into the view without changing the underlying document. - */ - export interface InjectedTextOptions { - /** - * Sets the text to inject. Must be a single line. - */ - readonly content: string; - /** - * If set, the decoration will be rendered inline with the text with this CSS class name. - */ - readonly inlineClassName?: string | null; - /** - * If there is an `inlineClassName` which affects letter spacing. - */ - readonly inlineClassNameAffectsLetterSpacing?: boolean; - /** - * This field allows to attach data to this injected text. - * The data can be read when injected texts at a given position are queried. - */ - readonly attachedData?: unknown; - /** - * Configures cursor stops around injected text. - * Defaults to {@link InjectedTextCursorStops.Both}. - */ - readonly cursorStops?: InjectedTextCursorStops | null; - } - - export enum InjectedTextCursorStops { - Both = 0, - Right = 1, - Left = 2, - None = 3 - } - - /** - * New model decorations. - */ - export interface IModelDeltaDecoration { - /** - * Range that this decoration covers. - */ - range: IRange; - /** - * Options associated with this decoration. - */ - options: IModelDecorationOptions; - } - - /** - * A decoration in the model. - */ - export interface IModelDecoration { - /** - * Identifier for a decoration. - */ - readonly id: string; - /** - * Identifier for a decoration's owner. - */ - readonly ownerId: number; - /** - * Range that this decoration covers. - */ - readonly range: Range; - /** - * Options associated with this decoration. - */ - readonly options: IModelDecorationOptions; - } - - /** - * End of line character preference. - */ - export enum EndOfLinePreference { - /** - * Use the end of line character identified in the text buffer. - */ - TextDefined = 0, - /** - * Use line feed (\n) as the end of line character. - */ - LF = 1, - /** - * Use carriage return and line feed (\r\n) as the end of line character. - */ - CRLF = 2 - } - - /** - * The default end of line to use when instantiating models. - */ - export enum DefaultEndOfLine { - /** - * Use line feed (\n) as the end of line character. - */ - LF = 1, - /** - * Use carriage return and line feed (\r\n) as the end of line character. - */ - CRLF = 2 - } - - /** - * End of line character preference. - */ - export enum EndOfLineSequence { - /** - * Use line feed (\n) as the end of line character. - */ - LF = 0, - /** - * Use carriage return and line feed (\r\n) as the end of line character. - */ - CRLF = 1 - } - - /** - * A single edit operation, that has an identifier. - */ - export interface IIdentifiedSingleEditOperation extends ISingleEditOperation { - } - - export interface IValidEditOperation { - /** - * The range to replace. This can be empty to emulate a simple insert. - */ - range: Range; - /** - * The text to replace with. This can be empty to emulate a simple delete. - */ - text: string; - } - - /** - * A callback that can compute the cursor state after applying a series of edit operations. - */ - export interface ICursorStateComputer { - /** - * A callback that can compute the resulting cursors state after some edit operations have been executed. - */ - (inverseEditOperations: IValidEditOperation[]): Selection[] | null; - } - - export class TextModelResolvedOptions { - _textModelResolvedOptionsBrand: void; - readonly tabSize: number; - readonly indentSize: number; - readonly insertSpaces: boolean; - readonly defaultEOL: DefaultEndOfLine; - readonly trimAutoWhitespace: boolean; - readonly bracketPairColorizationOptions: BracketPairColorizationOptions; - get originalIndentSize(): number | 'tabSize'; - } - - export interface BracketPairColorizationOptions { - enabled: boolean; - independentColorPoolPerBracketType: boolean; - } - - export interface ITextModelUpdateOptions { - tabSize?: number; - indentSize?: number | 'tabSize'; - insertSpaces?: boolean; - trimAutoWhitespace?: boolean; - bracketColorizationOptions?: BracketPairColorizationOptions; - } - - export class FindMatch { - _findMatchBrand: void; - readonly range: Range; - readonly matches: string[] | null; - } - - /** - * Describes the behavior of decorations when typing/editing near their edges. - * Note: Please do not edit the values, as they very carefully match `DecorationRangeBehavior` - */ - export enum TrackedRangeStickiness { - AlwaysGrowsWhenTypingAtEdges = 0, - NeverGrowsWhenTypingAtEdges = 1, - GrowsOnlyWhenTypingBefore = 2, - GrowsOnlyWhenTypingAfter = 3 - } - - /** - * Text snapshot that works like an iterator. - * Will try to return chunks of roughly ~64KB size. - * Will return null when finished. - */ - export interface ITextSnapshot { - read(): string | null; - } - - /** - * A model. - */ - export interface ITextModel { - /** - * Gets the resource associated with this editor model. - */ - readonly uri: Uri; - /** - * A unique identifier associated with this model. - */ - readonly id: string; - /** - * Get the resolved options for this model. - */ - getOptions(): TextModelResolvedOptions; - /** - * Get the current version id of the model. - * Anytime a change happens to the model (even undo/redo), - * the version id is incremented. - */ - getVersionId(): number; - /** - * Get the alternative version id of the model. - * This alternative version id is not always incremented, - * it will return the same values in the case of undo-redo. - */ - getAlternativeVersionId(): number; - /** - * Replace the entire text buffer value contained in this model. - */ - setValue(newValue: string | ITextSnapshot): void; - /** - * Get the text stored in this model. - * @param eol The end of line character preference. Defaults to `EndOfLinePreference.TextDefined`. - * @param preserverBOM Preserve a BOM character if it was detected when the model was constructed. - * @return The text. - */ - getValue(eol?: EndOfLinePreference, preserveBOM?: boolean): string; - /** - * Get the text stored in this model. - * @param preserverBOM Preserve a BOM character if it was detected when the model was constructed. - * @return The text snapshot (it is safe to consume it asynchronously). - */ - createSnapshot(preserveBOM?: boolean): ITextSnapshot; - /** - * Get the length of the text stored in this model. - */ - getValueLength(eol?: EndOfLinePreference, preserveBOM?: boolean): number; - /** - * Get the text in a certain range. - * @param range The range describing what text to get. - * @param eol The end of line character preference. This will only be used for multiline ranges. Defaults to `EndOfLinePreference.TextDefined`. - * @return The text. - */ - getValueInRange(range: IRange, eol?: EndOfLinePreference): string; - /** - * Get the length of text in a certain range. - * @param range The range describing what text length to get. - * @return The text length. - */ - getValueLengthInRange(range: IRange, eol?: EndOfLinePreference): number; - /** - * Get the character count of text in a certain range. - * @param range The range describing what text length to get. - */ - getCharacterCountInRange(range: IRange, eol?: EndOfLinePreference): number; - /** - * Get the number of lines in the model. - */ - getLineCount(): number; - /** - * Get the text for a certain line. - */ - getLineContent(lineNumber: number): string; - /** - * Get the text length for a certain line. - */ - getLineLength(lineNumber: number): number; - /** - * Get the text for all lines. - */ - getLinesContent(): string[]; - /** - * Get the end of line sequence predominantly used in the text buffer. - * @return EOL char sequence (e.g.: '\n' or '\r\n'). - */ - getEOL(): string; - /** - * Get the end of line sequence predominantly used in the text buffer. - */ - getEndOfLineSequence(): EndOfLineSequence; - /** - * Get the minimum legal column for line at `lineNumber` - */ - getLineMinColumn(lineNumber: number): number; - /** - * Get the maximum legal column for line at `lineNumber` - */ - getLineMaxColumn(lineNumber: number): number; - /** - * Returns the column before the first non whitespace character for line at `lineNumber`. - * Returns 0 if line is empty or contains only whitespace. - */ - getLineFirstNonWhitespaceColumn(lineNumber: number): number; - /** - * Returns the column after the last non whitespace character for line at `lineNumber`. - * Returns 0 if line is empty or contains only whitespace. - */ - getLineLastNonWhitespaceColumn(lineNumber: number): number; - /** - * Create a valid position. - */ - validatePosition(position: IPosition): Position; - /** - * Advances the given position by the given offset (negative offsets are also accepted) - * and returns it as a new valid position. - * - * If the offset and position are such that their combination goes beyond the beginning or - * end of the model, throws an exception. - * - * If the offset is such that the new position would be in the middle of a multi-byte - * line terminator, throws an exception. - */ - modifyPosition(position: IPosition, offset: number): Position; - /** - * Create a valid range. - */ - validateRange(range: IRange): Range; - /** - * Converts the position to a zero-based offset. - * - * The position will be [adjusted](#TextDocument.validatePosition). - * - * @param position A position. - * @return A valid zero-based offset. - */ - getOffsetAt(position: IPosition): number; - /** - * Converts a zero-based offset to a position. - * - * @param offset A zero-based offset. - * @return A valid [position](#Position). - */ - getPositionAt(offset: number): Position; - /** - * Get a range covering the entire model. - */ - getFullModelRange(): Range; - /** - * Returns if the model was disposed or not. - */ - isDisposed(): boolean; - /** - * Search the model. - * @param searchString The string used to search. If it is a regular expression, set `isRegex` to true. - * @param searchOnlyEditableRange Limit the searching to only search inside the editable range of the model. - * @param isRegex Used to indicate that `searchString` is a regular expression. - * @param matchCase Force the matching to match lower/upper case exactly. - * @param wordSeparators Force the matching to match entire words only. Pass null otherwise. - * @param captureMatches The result will contain the captured groups. - * @param limitResultCount Limit the number of results - * @return The ranges where the matches are. It is empty if not matches have been found. - */ - findMatches(searchString: string, searchOnlyEditableRange: boolean, isRegex: boolean, matchCase: boolean, wordSeparators: string | null, captureMatches: boolean, limitResultCount?: number): FindMatch[]; - /** - * Search the model. - * @param searchString The string used to search. If it is a regular expression, set `isRegex` to true. - * @param searchScope Limit the searching to only search inside these ranges. - * @param isRegex Used to indicate that `searchString` is a regular expression. - * @param matchCase Force the matching to match lower/upper case exactly. - * @param wordSeparators Force the matching to match entire words only. Pass null otherwise. - * @param captureMatches The result will contain the captured groups. - * @param limitResultCount Limit the number of results - * @return The ranges where the matches are. It is empty if no matches have been found. - */ - findMatches(searchString: string, searchScope: IRange | IRange[], isRegex: boolean, matchCase: boolean, wordSeparators: string | null, captureMatches: boolean, limitResultCount?: number): FindMatch[]; - /** - * Search the model for the next match. Loops to the beginning of the model if needed. - * @param searchString The string used to search. If it is a regular expression, set `isRegex` to true. - * @param searchStart Start the searching at the specified position. - * @param isRegex Used to indicate that `searchString` is a regular expression. - * @param matchCase Force the matching to match lower/upper case exactly. - * @param wordSeparators Force the matching to match entire words only. Pass null otherwise. - * @param captureMatches The result will contain the captured groups. - * @return The range where the next match is. It is null if no next match has been found. - */ - findNextMatch(searchString: string, searchStart: IPosition, isRegex: boolean, matchCase: boolean, wordSeparators: string | null, captureMatches: boolean): FindMatch | null; - /** - * Search the model for the previous match. Loops to the end of the model if needed. - * @param searchString The string used to search. If it is a regular expression, set `isRegex` to true. - * @param searchStart Start the searching at the specified position. - * @param isRegex Used to indicate that `searchString` is a regular expression. - * @param matchCase Force the matching to match lower/upper case exactly. - * @param wordSeparators Force the matching to match entire words only. Pass null otherwise. - * @param captureMatches The result will contain the captured groups. - * @return The range where the previous match is. It is null if no previous match has been found. - */ - findPreviousMatch(searchString: string, searchStart: IPosition, isRegex: boolean, matchCase: boolean, wordSeparators: string | null, captureMatches: boolean): FindMatch | null; - /** - * Get the language associated with this model. - */ - getLanguageId(): string; - /** - * Get the word under or besides `position`. - * @param position The position to look for a word. - * @return The word under or besides `position`. Might be null. - */ - getWordAtPosition(position: IPosition): IWordAtPosition | null; - /** - * Get the word under or besides `position` trimmed to `position`.column - * @param position The position to look for a word. - * @return The word under or besides `position`. Will never be null. - */ - getWordUntilPosition(position: IPosition): IWordAtPosition; - /** - * Perform a minimum amount of operations, in order to transform the decorations - * identified by `oldDecorations` to the decorations described by `newDecorations` - * and returns the new identifiers associated with the resulting decorations. - * - * @param oldDecorations Array containing previous decorations identifiers. - * @param newDecorations Array describing what decorations should result after the call. - * @param ownerId Identifies the editor id in which these decorations should appear. If no `ownerId` is provided, the decorations will appear in all editors that attach this model. - * @return An array containing the new decorations identifiers. - */ - deltaDecorations(oldDecorations: string[], newDecorations: IModelDeltaDecoration[], ownerId?: number): string[]; - /** - * Get the options associated with a decoration. - * @param id The decoration id. - * @return The decoration options or null if the decoration was not found. - */ - getDecorationOptions(id: string): IModelDecorationOptions | null; - /** - * Get the range associated with a decoration. - * @param id The decoration id. - * @return The decoration range or null if the decoration was not found. - */ - getDecorationRange(id: string): Range | null; - /** - * Gets all the decorations for the line `lineNumber` as an array. - * @param lineNumber The line number - * @param ownerId If set, it will ignore decorations belonging to other owners. - * @param filterOutValidation If set, it will ignore decorations specific to validation (i.e. warnings, errors). - * @return An array with the decorations - */ - getLineDecorations(lineNumber: number, ownerId?: number, filterOutValidation?: boolean): IModelDecoration[]; - /** - * Gets all the decorations for the lines between `startLineNumber` and `endLineNumber` as an array. - * @param startLineNumber The start line number - * @param endLineNumber The end line number - * @param ownerId If set, it will ignore decorations belonging to other owners. - * @param filterOutValidation If set, it will ignore decorations specific to validation (i.e. warnings, errors). - * @return An array with the decorations - */ - getLinesDecorations(startLineNumber: number, endLineNumber: number, ownerId?: number, filterOutValidation?: boolean): IModelDecoration[]; - /** - * Gets all the decorations in a range as an array. Only `startLineNumber` and `endLineNumber` from `range` are used for filtering. - * So for now it returns all the decorations on the same line as `range`. - * @param range The range to search in - * @param ownerId If set, it will ignore decorations belonging to other owners. - * @param filterOutValidation If set, it will ignore decorations specific to validation (i.e. warnings, errors). - * @param onlyMinimapDecorations If set, it will return only decorations that render in the minimap. - * @param onlyMarginDecorations If set, it will return only decorations that render in the glyph margin. - * @return An array with the decorations - */ - getDecorationsInRange(range: IRange, ownerId?: number, filterOutValidation?: boolean, onlyMinimapDecorations?: boolean, onlyMarginDecorations?: boolean): IModelDecoration[]; - /** - * Gets all the decorations as an array. - * @param ownerId If set, it will ignore decorations belonging to other owners. - * @param filterOutValidation If set, it will ignore decorations specific to validation (i.e. warnings, errors). - */ - getAllDecorations(ownerId?: number, filterOutValidation?: boolean): IModelDecoration[]; - /** - * Gets all decorations that render in the glyph margin as an array. - * @param ownerId If set, it will ignore decorations belonging to other owners. - */ - getAllMarginDecorations(ownerId?: number): IModelDecoration[]; - /** - * Gets all the decorations that should be rendered in the overview ruler as an array. - * @param ownerId If set, it will ignore decorations belonging to other owners. - * @param filterOutValidation If set, it will ignore decorations specific to validation (i.e. warnings, errors). - */ - getOverviewRulerDecorations(ownerId?: number, filterOutValidation?: boolean): IModelDecoration[]; - /** - * Gets all the decorations that contain injected text. - * @param ownerId If set, it will ignore decorations belonging to other owners. - */ - getInjectedTextDecorations(ownerId?: number): IModelDecoration[]; - /** - * Normalize a string containing whitespace according to indentation rules (converts to spaces or to tabs). - */ - normalizeIndentation(str: string): string; - /** - * Change the options of this model. - */ - updateOptions(newOpts: ITextModelUpdateOptions): void; - /** - * Detect the indentation options for this model from its content. - */ - detectIndentation(defaultInsertSpaces: boolean, defaultTabSize: number): void; - /** - * Close the current undo-redo element. - * This offers a way to create an undo/redo stop point. - */ - pushStackElement(): void; - /** - * Open the current undo-redo element. - * This offers a way to remove the current undo/redo stop point. - */ - popStackElement(): void; - /** - * Push edit operations, basically editing the model. This is the preferred way - * of editing the model. The edit operations will land on the undo stack. - * @param beforeCursorState The cursor state before the edit operations. This cursor state will be returned when `undo` or `redo` are invoked. - * @param editOperations The edit operations. - * @param cursorStateComputer A callback that can compute the resulting cursors state after the edit operations have been executed. - * @return The cursor state returned by the `cursorStateComputer`. - */ - pushEditOperations(beforeCursorState: Selection[] | null, editOperations: IIdentifiedSingleEditOperation[], cursorStateComputer: ICursorStateComputer): Selection[] | null; - /** - * Change the end of line sequence. This is the preferred way of - * changing the eol sequence. This will land on the undo stack. - */ - pushEOL(eol: EndOfLineSequence): void; - /** - * Edit the model without adding the edits to the undo stack. - * This can have dire consequences on the undo stack! See @pushEditOperations for the preferred way. - * @param operations The edit operations. - * @return If desired, the inverse edit operations, that, when applied, will bring the model back to the previous state. - */ - applyEdits(operations: IIdentifiedSingleEditOperation[]): void; - applyEdits(operations: IIdentifiedSingleEditOperation[], computeUndoEdits: false): void; - applyEdits(operations: IIdentifiedSingleEditOperation[], computeUndoEdits: true): IValidEditOperation[]; - /** - * Change the end of line sequence without recording in the undo stack. - * This can have dire consequences on the undo stack! See @pushEOL for the preferred way. - */ - setEOL(eol: EndOfLineSequence): void; - /** - * An event emitted when the contents of the model have changed. - * @event - */ - onDidChangeContent(listener: (e: IModelContentChangedEvent) => void): IDisposable; - /** - * An event emitted when decorations of the model have changed. - * @event - */ - readonly onDidChangeDecorations: IEvent; - /** - * An event emitted when the model options have changed. - * @event - */ - readonly onDidChangeOptions: IEvent; - /** - * An event emitted when the language associated with the model has changed. - * @event - */ - readonly onDidChangeLanguage: IEvent; - /** - * An event emitted when the language configuration associated with the model has changed. - * @event - */ - readonly onDidChangeLanguageConfiguration: IEvent; + export class MenuId { + private static readonly _instances; + static readonly CommandPalette: MenuId; + static readonly DebugBreakpointsContext: MenuId; + static readonly DebugCallStackContext: MenuId; + static readonly DebugConsoleContext: MenuId; + static readonly DebugVariablesContext: MenuId; + static readonly NotebookVariablesContext: MenuId; + static readonly DebugHoverContext: MenuId; + static readonly DebugWatchContext: MenuId; + static readonly DebugToolBar: MenuId; + static readonly DebugToolBarStop: MenuId; + static readonly DebugCallStackToolbar: MenuId; + static readonly DebugCreateConfiguration: MenuId; + static readonly EditorContext: MenuId; + static readonly SimpleEditorContext: MenuId; + static readonly EditorContent: MenuId; + static readonly EditorLineNumberContext: MenuId; + static readonly EditorContextCopy: MenuId; + static readonly EditorContextPeek: MenuId; + static readonly EditorContextShare: MenuId; + static readonly EditorTitle: MenuId; + static readonly EditorTitleRun: MenuId; + static readonly EditorTitleContext: MenuId; + static readonly EditorTitleContextShare: MenuId; + static readonly EmptyEditorGroup: MenuId; + static readonly EmptyEditorGroupContext: MenuId; + static readonly EditorTabsBarContext: MenuId; + static readonly EditorTabsBarShowTabsSubmenu: MenuId; + static readonly EditorTabsBarShowTabsZenModeSubmenu: MenuId; + static readonly EditorActionsPositionSubmenu: MenuId; + static readonly ExplorerContext: MenuId; + static readonly ExplorerContextShare: MenuId; + static readonly ExtensionContext: MenuId; + static readonly ExtensionEditorContextMenu: MenuId; + static readonly GlobalActivity: MenuId; + static readonly CommandCenter: MenuId; + static readonly CommandCenterCenter: MenuId; + static readonly LayoutControlMenuSubmenu: MenuId; + static readonly LayoutControlMenu: MenuId; + static readonly MenubarMainMenu: MenuId; + static readonly MenubarAppearanceMenu: MenuId; + static readonly MenubarDebugMenu: MenuId; + static readonly MenubarEditMenu: MenuId; + static readonly MenubarCopy: MenuId; + static readonly MenubarFileMenu: MenuId; + static readonly MenubarGoMenu: MenuId; + static readonly MenubarHelpMenu: MenuId; + static readonly MenubarLayoutMenu: MenuId; + static readonly MenubarNewBreakpointMenu: MenuId; + static readonly PanelAlignmentMenu: MenuId; + static readonly PanelPositionMenu: MenuId; + static readonly ActivityBarPositionMenu: MenuId; + static readonly MenubarPreferencesMenu: MenuId; + static readonly MenubarRecentMenu: MenuId; + static readonly MenubarSelectionMenu: MenuId; + static readonly MenubarShare: MenuId; + static readonly MenubarSwitchEditorMenu: MenuId; + static readonly MenubarSwitchGroupMenu: MenuId; + static readonly MenubarTerminalMenu: MenuId; + static readonly MenubarViewMenu: MenuId; + static readonly MenubarHomeMenu: MenuId; + static readonly OpenEditorsContext: MenuId; + static readonly OpenEditorsContextShare: MenuId; + static readonly ProblemsPanelContext: MenuId; + static readonly SCMInputBox: MenuId; + static readonly SCMChangesContext: MenuId; + static readonly SCMChangeContext: MenuId; + static readonly SCMResourceContext: MenuId; + static readonly SCMResourceContextShare: MenuId; + static readonly SCMResourceFolderContext: MenuId; + static readonly SCMResourceGroupContext: MenuId; + static readonly SCMSourceControl: MenuId; + static readonly SCMSourceControlInline: MenuId; + static readonly SCMSourceControlTitle: MenuId; + static readonly SCMHistoryTitle: MenuId; + static readonly SCMTitle: MenuId; + static readonly SearchContext: MenuId; + static readonly SearchActionMenu: MenuId; + static readonly StatusBarWindowIndicatorMenu: MenuId; + static readonly StatusBarRemoteIndicatorMenu: MenuId; + static readonly StickyScrollContext: MenuId; + static readonly TestItem: MenuId; + static readonly TestItemGutter: MenuId; + static readonly TestProfilesContext: MenuId; + static readonly TestMessageContext: MenuId; + static readonly TestMessageContent: MenuId; + static readonly TestPeekElement: MenuId; + static readonly TestPeekTitle: MenuId; + static readonly TestCallStack: MenuId; + static readonly TouchBarContext: MenuId; + static readonly TitleBarContext: MenuId; + static readonly TitleBarTitleContext: MenuId; + static readonly TunnelContext: MenuId; + static readonly TunnelPrivacy: MenuId; + static readonly TunnelProtocol: MenuId; + static readonly TunnelPortInline: MenuId; + static readonly TunnelTitle: MenuId; + static readonly TunnelLocalAddressInline: MenuId; + static readonly TunnelOriginInline: MenuId; + static readonly ViewItemContext: MenuId; + static readonly ViewContainerTitle: MenuId; + static readonly ViewContainerTitleContext: MenuId; + static readonly ViewTitle: MenuId; + static readonly ViewTitleContext: MenuId; + static readonly CommentEditorActions: MenuId; + static readonly CommentThreadTitle: MenuId; + static readonly CommentThreadActions: MenuId; + static readonly CommentThreadAdditionalActions: MenuId; + static readonly CommentThreadTitleContext: MenuId; + static readonly CommentThreadCommentContext: MenuId; + static readonly CommentTitle: MenuId; + static readonly CommentActions: MenuId; + static readonly CommentsViewThreadActions: MenuId; + static readonly InteractiveToolbar: MenuId; + static readonly InteractiveCellTitle: MenuId; + static readonly InteractiveCellDelete: MenuId; + static readonly InteractiveCellExecute: MenuId; + static readonly InteractiveInputExecute: MenuId; + static readonly InteractiveInputConfig: MenuId; + static readonly ReplInputExecute: MenuId; + static readonly IssueReporter: MenuId; + static readonly NotebookToolbar: MenuId; + static readonly NotebookStickyScrollContext: MenuId; + static readonly NotebookCellTitle: MenuId; + static readonly NotebookCellDelete: MenuId; + static readonly NotebookCellInsert: MenuId; + static readonly NotebookCellBetween: MenuId; + static readonly NotebookCellListTop: MenuId; + static readonly NotebookCellExecute: MenuId; + static readonly NotebookCellExecuteGoTo: MenuId; + static readonly NotebookCellExecutePrimary: MenuId; + static readonly NotebookDiffCellInputTitle: MenuId; + static readonly NotebookDiffDocumentMetadata: MenuId; + static readonly NotebookDiffCellMetadataTitle: MenuId; + static readonly NotebookDiffCellOutputsTitle: MenuId; + static readonly NotebookOutputToolbar: MenuId; + static readonly NotebookOutlineFilter: MenuId; + static readonly NotebookOutlineActionMenu: MenuId; + static readonly NotebookEditorLayoutConfigure: MenuId; + static readonly NotebookKernelSource: MenuId; + static readonly BulkEditTitle: MenuId; + static readonly BulkEditContext: MenuId; + static readonly TimelineItemContext: MenuId; + static readonly TimelineTitle: MenuId; + static readonly TimelineTitleContext: MenuId; + static readonly TimelineFilterSubMenu: MenuId; + static readonly AccountsContext: MenuId; + static readonly SidebarTitle: MenuId; + static readonly PanelTitle: MenuId; + static readonly AuxiliaryBarTitle: MenuId; + static readonly AuxiliaryBarHeader: MenuId; + static readonly TerminalInstanceContext: MenuId; + static readonly TerminalEditorInstanceContext: MenuId; + static readonly TerminalNewDropdownContext: MenuId; + static readonly TerminalTabContext: MenuId; + static readonly TerminalTabEmptyAreaContext: MenuId; + static readonly TerminalStickyScrollContext: MenuId; + static readonly WebviewContext: MenuId; + static readonly InlineCompletionsActions: MenuId; + static readonly InlineEditsActions: MenuId; + static readonly NewFile: MenuId; + static readonly MergeInput1Toolbar: MenuId; + static readonly MergeInput2Toolbar: MenuId; + static readonly MergeBaseToolbar: MenuId; + static readonly MergeInputResultToolbar: MenuId; + static readonly InlineSuggestionToolbar: MenuId; + static readonly InlineEditToolbar: MenuId; + static readonly ChatContext: MenuId; + static readonly ChatCodeBlock: MenuId; + static readonly ChatCompareBlock: MenuId; + static readonly ChatMessageTitle: MenuId; + static readonly ChatMessageFooter: MenuId; + static readonly ChatExecute: MenuId; + static readonly ChatExecuteSecondary: MenuId; + static readonly ChatInput: MenuId; + static readonly ChatInputSide: MenuId; + static readonly ChatEditingWidgetToolbar: MenuId; + static readonly ChatEditingWidgetModifiedFilesToolbar: MenuId; + static readonly ChatInlineResourceAnchorContext: MenuId; + static readonly ChatInlineSymbolAnchorContext: MenuId; + static readonly ChatEditingCodeBlockContext: MenuId; + static readonly ChatCommandCenter: MenuId; + static readonly ChatAttachmentsContext: MenuId; + static readonly AccessibleView: MenuId; + static readonly MultiDiffEditorFileToolbar: MenuId; + static readonly DiffEditorHunkToolbar: MenuId; + static readonly DiffEditorSelectionToolbar: MenuId; + /** + * Create or reuse a `MenuId` with the given identifier + */ + static for(identifier: string): MenuId; + readonly id: string; /** - * An event emitted when the model has been attached to the first editor or detached from the last editor. - * @event + * Create a new `MenuId` with the unique identifier. Will throw if a menu + * with the identifier already exists, use `MenuId.for(ident)` or a unique + * identifier */ - readonly onDidChangeAttached: IEvent; + constructor(identifier: string); + } + + export interface IContextKey { + set(value: T): void; + reset(): void; + get(): T | undefined; + } + + export type ContextKeyValue = null | undefined | boolean | number | string | Array | Record; + + export interface IEditorOverrideServices { + [index: string]: any; + } + + export interface IMarker { + owner: string; + resource: Uri; + severity: MarkerSeverity; + code?: string | { + value: string; + target: Uri; + }; + message: string; + source?: string; + startLineNumber: number; + startColumn: number; + endLineNumber: number; + endColumn: number; + modelVersionId?: number; + relatedInformation?: IRelatedInformation[]; + tags?: MarkerTag[]; + } + + /** + * A structure defining a problem/warning/etc. + */ + export interface IMarkerData { + code?: string | { + value: string; + target: Uri; + }; + severity: MarkerSeverity; + message: string; + source?: string; + startLineNumber: number; + startColumn: number; + endLineNumber: number; + endColumn: number; + modelVersionId?: number; + relatedInformation?: IRelatedInformation[]; + tags?: MarkerTag[]; + } + + /** + * + */ + export interface IRelatedInformation { + resource: Uri; + message: string; + startLineNumber: number; + startColumn: number; + endLineNumber: number; + endColumn: number; + } + + export interface IColorizerOptions { + tabSize?: number; + } + + export interface IColorizerElementOptions extends IColorizerOptions { + theme?: string; + mimeType?: string; + } + + export enum ScrollbarVisibility { + Auto = 1, + Hidden = 2, + Visible = 3 + } + + export interface ThemeIcon { + readonly id: string; + readonly color?: ThemeColor; + } + + export interface ThemeColor { + id: string; + } + + /** + * A single edit operation, that acts as a simple replace. + * i.e. Replace text at `range` with `text` in model. + */ + export interface ISingleEditOperation { /** - * An event emitted right before disposing the model. - * @event + * The range to replace. This can be empty to emulate a simple insert. */ - readonly onWillDispose: IEvent; + range: IRange; /** - * Destroy this model. + * The text to replace with. This can be null to emulate a simple delete. */ - dispose(): void; + text: string | null; /** - * Returns if this model is attached to an editor or not. + * This indicates that this operation has "insert" semantics. + * i.e. forceMoveMarkers = true => if `range` is collapsed, all markers at the position will be moved. */ - isAttachedToEditor(): boolean; + forceMoveMarkers?: boolean; } - export enum PositionAffinity { - /** - * Prefers the left most position. - */ - Left = 0, - /** - * Prefers the right most position. - */ - Right = 1, + /** + * Word inside a model. + */ + export interface IWordAtPosition { /** - * No preference. - */ - None = 2, + * The word. + */ + readonly word: string; /** - * If the given position is on injected text, prefers the position left of it. - */ - LeftOfInjectedText = 3, + * The column where the word starts. + */ + readonly startColumn: number; /** - * If the given position is on injected text, prefers the position right of it. - */ - RightOfInjectedText = 4 + * The column where the word ends. + */ + readonly endColumn: number; } /** @@ -2445,6 +1821,66 @@ declare namespace monaco.editor { height: number; } + /** + * A range of offsets (0-based). + */ + export class OffsetRange implements IOffsetRange { + readonly start: number; + readonly endExclusive: number; + static addRange(range: OffsetRange, sortedRanges: OffsetRange[]): void; + static tryCreate(start: number, endExclusive: number): OffsetRange | undefined; + static ofLength(length: number): OffsetRange; + static ofStartAndLength(start: number, length: number): OffsetRange; + static emptyAt(offset: number): OffsetRange; + constructor(start: number, endExclusive: number); + get isEmpty(): boolean; + delta(offset: number): OffsetRange; + deltaStart(offset: number): OffsetRange; + deltaEnd(offset: number): OffsetRange; + get length(): number; + toString(): string; + equals(other: OffsetRange): boolean; + containsRange(other: OffsetRange): boolean; + contains(offset: number): boolean; + /** + * for all numbers n: range1.contains(n) or range2.contains(n) => range1.join(range2).contains(n) + * The joined range is the smallest range that contains both ranges. + */ + join(other: OffsetRange): OffsetRange; + /** + * for all numbers n: range1.contains(n) and range2.contains(n) <=> range1.intersect(range2).contains(n) + * + * The resulting range is empty if the ranges do not intersect, but touch. + * If the ranges don't even touch, the result is undefined. + */ + intersect(other: OffsetRange): OffsetRange | undefined; + intersectionLength(range: OffsetRange): number; + intersects(other: OffsetRange): boolean; + intersectsOrTouches(other: OffsetRange): boolean; + isBefore(other: OffsetRange): boolean; + isAfter(other: OffsetRange): boolean; + slice(arr: T[]): T[]; + substring(str: string): string; + /** + * Returns the given value if it is contained in this instance, otherwise the closest value that is contained. + * The range must not be empty. + */ + clip(value: number): number; + /** + * Returns `r := value + k * length` such that `r` is contained in this range. + * The range must not be empty. + * + * E.g. `[5, 10).clipCyclic(10) === 5`, `[5, 10).clipCyclic(11) === 6` and `[5, 10).clipCyclic(4) === 9`. + */ + clipCyclic(value: number): number; + map(f: (offset: number) => T): T[]; + forEach(f: (offset: number) => void): void; + } + export interface IOffsetRange { + readonly start: number; + readonly endExclusive: number; + } + /** * A builder and helper for edit operations for a command. */ @@ -2554,6 +1990,15 @@ declare namespace monaco.editor { readonly contentHeightChanged: boolean; } + /** + * @internal + */ + export interface ITriggerEditorOperationEvent { + source: string | null | undefined; + handlerId: string; + payload: any; + } + export interface INewScrollPosition { scrollLeft?: number; scrollTop?: number; @@ -3108,16 +2553,6 @@ declare namespace monaco.editor { positionDelta: number; } - /** - * @internal - */ - export interface PastePayload { - text: string; - pasteOnNewLine: boolean; - multicursorText: string[] | null; - mode: string | null; - } - /** * An event describing that the current language associated with a model has changed. */ @@ -4441,6 +3876,51 @@ declare namespace monaco.editor { readonly minimapCanvasOuterHeight: number; } + /** + * @internal + */ + export interface IEditorLayoutComputerInput { + readonly outerWidth: number; + readonly outerHeight: number; + readonly isDominatedByLongLines: boolean; + readonly lineHeight: number; + readonly lineNumbersDigitCount: number; + readonly typicalHalfwidthCharacterWidth: number; + readonly maxDigitWidth: number; + readonly pixelRatio: number; + readonly glyphMargin: boolean; + readonly lineDecorationsWidth: string | number; + readonly folding: boolean; + readonly minimap: Readonly>; + readonly scrollbar: InternalEditorScrollbarOptions; + readonly lineNumbers: InternalEditorRenderLineNumbersOptions; + readonly lineNumbersMinChars: number; + readonly scrollBeyondLastLine: boolean; + readonly wordWrap: 'wordWrapColumn' | 'on' | 'off' | 'bounded'; + readonly wordWrapColumn: number; + readonly wordWrapMinified: boolean; + readonly accessibilitySupport: AccessibilitySupport; + } + + /** + * @internal + */ + export interface IMinimapLayoutInput { + readonly outerWidth: number; + readonly outerHeight: number; + readonly lineHeight: number; + readonly typicalHalfwidthCharacterWidth: number; + readonly pixelRatio: number; + readonly scrollBeyondLastLine: boolean; + readonly paddingTop: number; + readonly paddingBottom: number; + readonly minimap: Readonly>; + readonly verticalScrollbarWidth: number; + readonly viewLineCount: number; + readonly remainingWidth: number; + readonly isViewportWrapping: boolean; + } + export enum ShowLightbulbIconMode { Off = 'off', OnCode = 'onCode', @@ -6004,6 +5484,17 @@ declare namespace monaco.editor { readonly clipboardEvent?: ClipboardEvent; } + /** + * @internal + */ + export interface PastePayload { + text: string; + pasteOnNewLine: boolean; + multicursorText: string[] | null; + mode: string | null; + clipboardEvent?: ClipboardEvent; + } + /** * Editor aria options. * @internal @@ -6038,6 +5529,11 @@ declare namespace monaco.editor { * @internal */ readonly isSimpleWidget: boolean; + /** + * The context menu ID that should be used to lookup context menu actions. + * @internal + */ + readonly contextMenuId: MenuId; /** * The editor's scoped context key service. * @internal @@ -6236,6 +5732,11 @@ declare namespace monaco.editor { * @event */ readonly onDidChangeHiddenAreas: IEvent; + /** + * An event emitted before an editor + * @internal + */ + readonly onWillTriggerEditorOperationEvent: IEvent; /** * Some editor operations fire multiple events at once. * To allow users to react to multiple events fired by a single operation, @@ -6828,7 +6329,29 @@ declare namespace monaco.editor { */ export enum GlyphMarginLane { Left = 1, - Right = 2 + Center = 2, + Right = 3 + } + + export interface IGlyphMarginLanesModel { + /** + * The number of lanes that should be rendered in the editor. + */ + readonly requiredLanes: number; + /** + * Gets the lanes that should be rendered starting at a given line number. + */ + getLanesAtLine(lineNumber: number): GlyphMarginLane[]; + /** + * Resets the model and ensures it can contain at least `maxLine` lines. + */ + reset(maxLine: number): void; + /** + * Registers that a lane should be visible at the Range in the model. + * @param persist - if true, notes that the lane should always be visible, + * even on lines where there's no specific request for that lane. + */ + push(lane: GlyphMarginLane, range: Range, persist?: boolean): void; } /** @@ -6839,6 +6362,14 @@ declare namespace monaco.editor { Gutter = 2 } + /** + * Section header style. + */ + export enum MinimapSectionHeaderStyle { + Normal = 1, + Underlined = 2 + } + export interface IDecorationOptions { /** * CSS color to render. @@ -6856,7 +6387,12 @@ declare namespace monaco.editor { /** * The position in the glyph margin. */ - position: GlyphMarginLane; + position: GlyphMarginLane; + /** + * Whether the glyph margin lane in {@link position} should be rendered even + * outside of this decoration's range. + */ + persistLane?: boolean; } /** @@ -6877,6 +6413,14 @@ declare namespace monaco.editor { * The position in the minimap. */ position: MinimapPosition; + /** + * If the decoration is for a section header, which header style. + */ + sectionHeaderStyle?: MinimapSectionHeaderStyle | null; + /** + * If the decoration is for a section header, the header text. + */ + sectionHeaderText?: string | null; } /** @@ -6917,6 +6461,10 @@ declare namespace monaco.editor { * Array of MarkdownString to render as the decoration message. */ hoverMessage?: IMarkdownString | IMarkdownString[] | null; + /** + * Array of MarkdownString to render as the line number message. + */ + lineNumberHoverMessage?: IMarkdownString | IMarkdownString[] | null; /** * Should the decoration expand to encompass a whole line. */ @@ -6957,6 +6505,14 @@ declare namespace monaco.editor { * If set, the decoration will be rendered in the lines decorations with this CSS class name. */ linesDecorationsClassName?: string | null; + /** + * Controls the tooltip text of the line decoration. + */ + linesDecorationsTooltip?: string | null; + /** + * If set, the decoration will be rendered on the line number. + */ + lineNumberClassName?: string | null; /** * If set, the decoration will be rendered in the lines decorations with this CSS class name, but only for the first line in case of line wrapping. */ @@ -7011,6 +6567,10 @@ declare namespace monaco.editor { * Sets the text to inject. Must be a single line. */ readonly content: string; + /** + * @internal + */ + readonly tokens?: TokenArray | null; /** * If set, the decoration will be rendered inline with the text with this CSS class name. */ @@ -7215,7 +6775,7 @@ declare namespace monaco.editor { /** * @internal */ - textChange: any; + textChange: any; } /** @@ -7776,11 +7336,11 @@ declare namespace monaco.editor { /** * @internal */ - _applyUndo(changes: any[], eol: EndOfLineSequence, resultingAlternativeVersionId: number, resultingSelection: Selection[] | null): void; + _applyUndo(changes: any[], eol: EndOfLineSequence, resultingAlternativeVersionId: number, resultingSelection: Selection[] | null): void; /** * @internal */ - _applyRedo(changes: any[], eol: EndOfLineSequence, resultingAlternativeVersionId: number, resultingSelection: Selection[] | null): void; + _applyRedo(changes: any[], eol: EndOfLineSequence, resultingAlternativeVersionId: number, resultingSelection: Selection[] | null): void; /** * Undo edit operations until the previous undo/redo point. * The inverse edit operations will be pushed on the redo stack. @@ -7991,9 +7551,15 @@ declare namespace monaco.editor { getLineCharCode(lineNumber: number, index: number): number; getCharCode(offset: number): number; getLineLength(lineNumber: number): number; + getLineMinColumn(lineNumber: number): number; + getLineMaxColumn(lineNumber: number): number; getLineFirstNonWhitespaceColumn(lineNumber: number): number; getLineLastNonWhitespaceColumn(lineNumber: number): number; findMatchesLineByLine(searchRange: Range, searchData: any, captureMatches: boolean, limitResultCount: number): FindMatch[]; + /** + * Get nearest chunk of text after `offset` in the text buffer. + */ + getNearestChunk(offset: number): string; } /** @@ -8027,6 +7593,38 @@ declare namespace monaco.editor { readonly height: number; } + /** + * This class represents a sequence of tokens. + * Conceptually, each token has a length and a metadata number. + * A token array might be used to annotate a string with metadata. + * Use {@link TokenArrayBuilder} to efficiently create a token array. + * + * TODO: Make this class more efficient (e.g. by using a Int32Array). + */ + export class TokenArray { + private readonly _tokenInfo; + static create(tokenInfo: TokenInfo[]): TokenArray; + private constructor(); + forEach(cb: (range: OffsetRange, tokenInfo: TokenInfo) => void): void; + slice(range: OffsetRange): TokenArray; + } + + export type TokenMetadata = number; + + export class TokenInfo { + readonly length: number; + readonly metadata: TokenMetadata; + constructor(length: number, metadata: TokenMetadata); + } + + /** + * TODO: Make this class more efficient (e.g. by using a Int32Array). + */ + export class TokenArrayBuilder { + private readonly _tokens; + add(length: number, metadata: TokenMetadata): void; + build(): TokenArray; + } export const EditorZoom: IEditorZoom; @@ -8057,6 +7655,57 @@ declare namespace monaco.languages { */ readonly pattern: string; } + export class HierarchicalKind { + readonly value: string; + static readonly sep = '.'; + static readonly None: HierarchicalKind; + static readonly Empty: HierarchicalKind; + constructor(value: string); + equals(other: HierarchicalKind): boolean; + contains(other: HierarchicalKind): boolean; + intersects(other: HierarchicalKind): boolean; + append(...parts: string[]): HierarchicalKind; + } + + export interface IDataTransferItem { + asString(): Thenable; + asFile(): IDataTransferFile | undefined; + value: any; + } + + export interface IReadonlyVSDataTransfer extends Iterable { + /** + * Get the total number of entries in this data transfer. + */ + get size(): number; + /** + * Check if this data transfer contains data for `mimeType`. + * + * This uses exact matching and does not support wildcards. + */ + has(mimeType: string): boolean; + /** + * Check if this data transfer contains data matching `pattern`. + * + * This allows matching for wildcards, such as `image/*`. + * + * Use the special `files` mime type to match any file in the data transfer. + */ + matches(pattern: string): boolean; + /** + * Retrieve the first entry for `mimeType`. + * + * Note that if you want to find all entries for a given mime type, use {@link IReadonlyVSDataTransfer.entries} instead. + */ + get(mimeType: string): IDataTransferItem | undefined; + } + + export interface IDataTransferFile { + readonly id: string; + readonly name: string; + readonly uri?: Uri; + data(): Promise; + } export type LanguageSelector = string | LanguageFilter | ReadonlyArray; @@ -8666,6 +8315,48 @@ declare namespace monaco.languages { */ indentation: string; } + /** + * Open ended enum at runtime + */ + export enum LanguageId { + Null = 0, + PlainText = 1 + } + + export interface ILanguageExtensionPoint { + id: string; + extensions?: string[]; + filenames?: string[]; + filenamePatterns?: string[]; + firstLine?: string; + aliases?: string[]; + mimetypes?: string[]; + configuration?: Uri; + /** + * @internal + */ + icon?: ILanguageIcon; + } + + export interface ILanguageSelection { + readonly languageId: string; + readonly onDidChange: IEvent; + } + + export interface ILanguageNameIdPair { + readonly languageName: string; + readonly languageId: string; + } + + export interface ILanguageIcon { + readonly light: Uri; + readonly dark: Uri; + } + + export interface ILanguageIdCodec { + encodeLanguageId(languageId: string): LanguageId; + decodeLanguageId(languageId: LanguageId): string; + } /** * @internal @@ -9126,6 +8817,11 @@ declare namespace monaco.languages { */ readonly triggerKind: InlineCompletionTriggerKind; readonly selectedSuggestionInfo: SelectedSuggestionInfo | undefined; + /** + * @experimental + * @internal + */ + readonly userPrompt?: string | undefined; readonly includeInlineEdits: boolean; readonly includeInlineCompletions: boolean; } @@ -9193,6 +8889,11 @@ declare namespace monaco.languages { export interface InlineCompletionsProvider { provideInlineCompletions(model: editor.ITextModel, position: Position, context: InlineCompletionContext, token: CancellationToken): ProviderResult; + /** + * @experimental + * @internal + */ + provideInlineEditsForRange?(model: editor.ITextModel, range: Range, context: InlineCompletionContext, token: CancellationToken): ProviderResult; /** * Will be called when an item is shown. * @param updatedInsertText Is useful to understand bracket completion. @@ -9247,6 +8948,7 @@ declare namespace monaco.languages { */ export interface CodeActionProvider { displayName?: string; + extensionId?: string; /** * Provide commands for the given document and range. */ @@ -9273,8 +8975,8 @@ declare namespace monaco.languages { * @internal */ export interface DocumentPasteEdit { - readonly label: string; - readonly detail: string; + readonly title: string; + readonly kind: HierarchicalKind; readonly handledMimeType?: string; readonly yieldTo?: readonly DropYieldTo[]; insertText: string | { @@ -9283,6 +8985,27 @@ declare namespace monaco.languages { additionalEdit?: WorkspaceEdit; } + export enum DocumentPasteTriggerKind { + Automatic = 0, + PasteAs = 1 + } + + /** + * @internal + */ + export interface DocumentPasteContext { + readonly only?: HierarchicalKind; + readonly triggerKind: DocumentPasteTriggerKind; + } + + /** + * @internal + */ + export interface DocumentPasteEditsSession { + edits: readonly DocumentPasteEdit[]; + dispose(): void; + } + /** * Represents a parameter of a callable-signature. A parameter can * have a label and a doc-comment. @@ -9996,16 +9719,155 @@ declare namespace monaco.languages { arguments?: any[]; } + /** + * @internal + */ + export interface CommentThreadTemplate { + controllerHandle: number; + label: string; + acceptInputCommand?: Command; + additionalCommands?: Command[]; + deleteCommand?: Command; + } + + /** + * @internal + */ + export interface CommentInfo { + extensionId?: string; + threads: CommentThread[]; + pendingCommentThreads?: PendingCommentThread[]; + commentingRanges: CommentingRanges; + } + + /** + * @internal + */ + export interface CommentingRangeResourceHint { + schemes: readonly string[]; + } + + export enum CommentThreadApplicability { + Current = 0, + Outdated = 1 + } + + /** + * @internal + */ + export interface CommentWidget { + commentThread: CommentThread; + comment?: Comment; + input: string; + onDidChangeInput: IEvent; + } + + /** + * @internal + */ + export interface CommentInput { + value: string; + uri: Uri; + } + export interface CommentThreadRevealOptions { preserveFocus: boolean; focusReply: boolean; } + /** + * @internal + */ + export interface CommentThread { + isDocumentCommentThread(): this is CommentThread; + commentThreadHandle: number; + controllerHandle: number; + extensionId?: string; + threadId: string; + resource: string | null; + range: T | undefined; + label: string | undefined; + contextValue: string | undefined; + comments: ReadonlyArray | undefined; + onDidChangeComments: IEvent; + collapsibleState?: any; + initialCollapsibleState?: any; + onDidChangeInitialCollapsibleState: IEvent; + state?: any; + applicability?: CommentThreadApplicability; + canReply: boolean; + input?: CommentInput; + onDidChangeInput: IEvent; + onDidChangeLabel: IEvent; + onDidChangeCollapsibleState: IEvent; + onDidChangeState: IEvent; + onDidChangeCanReply: IEvent; + isDisposed: boolean; + isTemplate: boolean; + } + + /** + * @internal + */ + export interface AddedCommentThread extends CommentThread { + editorId?: string; + } + + /** + * @internal + */ + export interface CommentingRanges { + readonly resource: Uri; + ranges: IRange[]; + fileComments: boolean; + } + export interface CommentAuthorInformation { name: string; iconPath?: UriComponents; } + /** + * @internal + */ + export interface CommentReaction { + readonly label?: string; + readonly iconPath?: UriComponents; + readonly count?: number; + readonly hasReacted?: boolean; + readonly canEdit?: boolean; + readonly reactors?: readonly string[]; + } + + /** + * @internal + */ + export interface CommentOptions { + /** + * An optional string to show on the comment input box when it's collapsed. + */ + prompt?: string; + /** + * An optional string to show as placeholder in the comment input box when it's focused. + */ + placeHolder?: string; + } + + /** + * @internal + */ + export interface Comment { + readonly uniqueIdInThread: number; + readonly body: string | IMarkdownString; + readonly userName: string; + readonly userIconPath?: UriComponents; + readonly contextValue?: string; + readonly commentReactions?: CommentReaction[]; + readonly label?: string; + readonly mode?: any; + readonly timestamp?: string; + } + export interface PendingCommentThread { range: IRange | undefined; uri: Uri; @@ -10030,7 +9892,7 @@ declare namespace monaco.languages { /** * Added comment threads. */ - readonly added: CommentThread[]; + readonly added: AddedCommentThread[]; /** * Removed comment threads. */ @@ -10134,7 +9996,7 @@ declare namespace monaco.languages { } export type DropYieldTo = { - readonly providerId: string; + readonly kind: HierarchicalKind; } | { readonly mimeType: string; }; @@ -10142,8 +10004,9 @@ declare namespace monaco.languages { /** * @internal */ - export interface DocumentOnDropEdit { - readonly label: string; + export interface DocumentDropEdit { + readonly title: string; + readonly kind: HierarchicalKind | undefined; readonly handledMimeType?: string; readonly yieldTo?: readonly DropYieldTo[]; insertText: string | { @@ -10152,6 +10015,24 @@ declare namespace monaco.languages { additionalEdit?: WorkspaceEdit; } + /** + * @internal + */ + export interface DocumentDropEditsSession { + edits: readonly DocumentDropEdit[]; + dispose(): void; + } + + /** + * @internal + */ + export interface DocumentDropEditProvider { + readonly id?: string; + readonly dropMimeTypes?: readonly string[]; + provideDocumentDropEdits(model: editor.ITextModel, position: IPosition, dataTransfer: IReadonlyVSDataTransfer, token: CancellationToken): ProviderResult; + resolveDocumentDropEdit?(edit: DocumentDropEdit, token: CancellationToken): Promise; + } + export interface DocumentContextItem { readonly uri: Uri; readonly version: number; @@ -10161,9 +10042,34 @@ declare namespace monaco.languages { export interface MappedEditsContext { /** The outer array is sorted by priority - from highest to lowest. The inner arrays contain elements of the same priority. */ readonly documents: DocumentContextItem[][]; + /** + * @internal + */ + readonly conversation?: (ConversationRequest | ConversationResponse)[]; + } + + /** + * @internal + */ + export interface ConversationRequest { + readonly type: 'request'; + readonly message: string; + } + + /** + * @internal + */ + export interface ConversationResponse { + readonly type: 'response'; + readonly message: string; + readonly references?: DocumentContextItem[]; } export interface MappedEditsProvider { + /** + * @internal + */ + readonly displayName: string; /** * Provider maps code blocks from the chat into a workspace edit. * @@ -10198,31 +10104,6 @@ declare namespace monaco.languages { provideInlineEdit(model: editor.ITextModel, context: IInlineEditContext, token: CancellationToken): ProviderResult; freeInlineEdit(edit: T): void; } - - export interface ILanguageExtensionPoint { - id: string; - extensions?: string[]; - filenames?: string[]; - filenamePatterns?: string[]; - firstLine?: string; - aliases?: string[]; - mimetypes?: string[]; - configuration?: Uri; - /** - * @internal - */ - icon?: ILanguageIcon; - } - - export interface ILanguageIcon { - readonly light: Uri; - readonly dark: Uri; - } - - export interface ILanguageSelection { - readonly languageId: string; - readonly onDidChange: IEvent; - } /** * A Monarch language definition */ @@ -10416,34 +10297,18 @@ declare namespace monaco.worker { } /** + * Range of a word inside a model. * @internal */ - export interface IRawModelData { - url: string; - versionId: number; - lines: string[]; - EOL: string; - } - - /** - * @internal - */ - export interface ICommonModel extends ILinkComputerTarget, IDocumentColorComputerTarget, IMirrorModel { - uri: Uri; - version: number; - eol: string; - getValue(): string; - getLinesContent(): string[]; - getLineCount(): number; - getLineContent(lineNumber: number): string; - getLineWords(lineNumber: number, wordDefinition: RegExp): IWordAtPosition[]; - words(wordDefinition: RegExp): Iterable; - getWordUntilPosition(position: IPosition, wordDefinition: RegExp): IWordAtPosition; - getValueInRange(range: IRange): string; - getWordAtPosition(position: IPosition, wordDefinition: RegExp): Range | null; - offsetAt(position: IPosition): number; - positionAt(offset: number): IPosition; - findMatches(regex: RegExp): RegExpMatchArray[]; + export interface IWordRange { + /** + * The index where the word starts. + */ + readonly start: number; + /** + * The index where the word ends. + */ + readonly end: number; } /** From 27c536e0b7f7b1d28e40484a1d77449c0ce0b6a6 Mon Sep 17 00:00:00 2001 From: ricbet Date: Wed, 3 Jan 2024 14:15:46 +0800 Subject: [PATCH 04/10] chore: support esm nls --- build/lib/i18n.js | 25 ++++++++++++++++++++++++- build/lib/i18n.ts | 28 +++++++++++++++++++++++++++- build/lib/nls.js | 28 +++++++++++++++++++--------- build/lib/nls.ts | 29 ++++++++++++++++++++--------- src/vs/editor/common/languages.ts | 2 +- src/vs/editor/common/model.ts | 2 +- src/vs/monaco.d.ts | 4 ++-- 7 files changed, 94 insertions(+), 24 deletions(-) diff --git a/build/lib/i18n.js b/build/lib/i18n.js index 6964616291b..431f8faad49 100644 --- a/build/lib/i18n.js +++ b/build/lib/i18n.js @@ -313,6 +313,21 @@ globalThis._VSCODE_NLS_LANGUAGE=${JSON.stringify(language.id)};`), })); }); } +const commonHeader1 = `/*---------------------------------------------------------\n`; +const commonHeader2 = `* Copyright (c) Microsoft Corporation. All rights reserved.\n`; +const commonHeader3 = `*--------------------------------------------------------*/`; +// 将 nls.js 转换成 nls.json 结构 +// @ts-ignore +function toJsonNlsFile(content, fileHeader) { + return content + .replace(fileHeader, '') + .replace(commonHeader1, '') + .replace(commonHeader2, '') + .replace(commonHeader3, '') + .replace(`define("vs/editor/editor.main.nls", {`, '{') + .replace('});', '}') + .trim(); +} function processNlsFiles(opts) { return (0, event_stream_1.through)(function (file) { const fileName = path.basename(file.path); @@ -327,7 +342,15 @@ function processNlsFiles(opts) { this.emit('error', `Failed to read component file: ${error}`); } } - this.queue(file); + if (file.path.includes('editor.main.nls.js')) { + this.queue(new File({ + path: file.path.replace('.js', '.json'), + contents: Buffer.from(toJsonNlsFile(file.contents.toString(), opts.fileHeader)), + })); + } + else { + this.queue(file); + } }); } const editorProject = 'vscode-editor', workbenchProject = 'vscode-workbench', extensionsProject = 'vscode-extensions', setupProject = 'vscode-setup', serverProject = 'vscode-server'; diff --git a/build/lib/i18n.ts b/build/lib/i18n.ts index cd7e522ad36..33e0c219cfe 100644 --- a/build/lib/i18n.ts +++ b/build/lib/i18n.ts @@ -384,6 +384,22 @@ globalThis._VSCODE_NLS_LANGUAGE=${JSON.stringify(language.id)};`), }); } +const commonHeader1 = `/*---------------------------------------------------------\n`; +const commonHeader2 = `* Copyright (c) Microsoft Corporation. All rights reserved.\n`; +const commonHeader3 = `*--------------------------------------------------------*/`; +// 将 nls.js 转换成 nls.json 结构 +// @ts-ignore +function toJsonNlsFile(content: string, fileHeader: string): string { + return content + .replace(fileHeader, '') + .replace(commonHeader1, '') + .replace(commonHeader2, '') + .replace(commonHeader3, '') + .replace(`define("vs/editor/editor.main.nls", {`, '{') + .replace('});', '}') + .trim(); +} + export function processNlsFiles(opts: { out: string; fileHeader: string; languages: Language[] }): ThroughStream { return through(function (this: ThroughStream, file: File) { const fileName = path.basename(file.path); @@ -397,7 +413,17 @@ export function processNlsFiles(opts: { out: string; fileHeader: string; languag this.emit('error', `Failed to read component file: ${error}`); } } - this.queue(file); + + if (file.path.includes('editor.main.nls.js')) { + this.queue(new File( + { + path: file.path.replace('.js', '.json'), + contents: Buffer.from(toJsonNlsFile(file.contents.toString(), opts.fileHeader)), + } + )) + } else { + this.queue(file); + } }); } diff --git a/build/lib/nls.js b/build/lib/nls.js index 6ddcd46167a..2836d81bdf2 100644 --- a/build/lib/nls.js +++ b/build/lib/nls.js @@ -157,7 +157,7 @@ var _nls; } return node.kind === ts.SyntaxKind.CallExpression ? CollectStepResult.YesAndRecurse : CollectStepResult.NoAndRecurse; } - function analyze(ts, contents, functionName, options = {}) { + function analyze(ts, moduleId, contents, functionName, options = {}) { const filename = 'file.ts'; const serviceHost = new SingleFileServiceHost(ts, Object.assign(clone(options), { noResolve: true }), filename, contents); const service = ts.createLanguageService(serviceHost); @@ -224,7 +224,9 @@ var _nls; .filter(a => a.length > 1) .sort((a, b) => a[0].getStart() - b[0].getStart()) .map(a => ({ - keySpan: { start: ts.getLineAndCharacterOfPosition(sourceFile, a[0].getStart()), end: ts.getLineAndCharacterOfPosition(sourceFile, a[0].getEnd()) }, + pathSpan: { start: ts.getLineAndCharacterOfPosition(sourceFile, a[0].getStart()), end: ts.getLineAndCharacterOfPosition(sourceFile, a[0].getEnd()) }, + path: `"${moduleId}",`, + keySpan: { start: ts.getLineAndCharacterOfPosition(sourceFile, a[1].getStart() - 1), end: ts.getLineAndCharacterOfPosition(sourceFile, a[1].getStart() - 1) }, key: a[0].getText(), valueSpan: { start: ts.getLineAndCharacterOfPosition(sourceFile, a[1].getStart()), end: ts.getLineAndCharacterOfPosition(sourceFile, a[1].getEnd()) }, value: a[1].getText() @@ -233,6 +235,7 @@ var _nls; localizeCalls: localizeCalls.toArray() }; } + _nls.analyze = analyze; class TextModel { lines; lineEndings; @@ -333,9 +336,9 @@ var _nls; // eslint-disable-next-line no-eval return eval(`(${sourceExpression})`); } - function patch(ts, typescript, javascript, sourcemap, options) { - const { localizeCalls } = analyze(ts, typescript, 'localize'); - const { localizeCalls: localize2Calls } = analyze(ts, typescript, 'localize2'); + function patch(ts, moduleId, typescript, javascript, sourcemap, options) { + const { localizeCalls } = analyze(ts, moduleId, typescript, 'localize'); + const { localizeCalls: localize2Calls } = analyze(ts, moduleId, typescript, 'localize2'); if (localizeCalls.length === 0 && localize2Calls.length === 0) { return { javascript, sourcemap }; } @@ -351,16 +354,22 @@ var _nls; }; const localizePatches = lazy(localizeCalls) .map(lc => (options.preserveEnglish ? [ + { range: lc.pathSpan, content: lc.path }, { range: lc.keySpan, content: `${allNLSMessagesIndex++}` } // localize('key', "message") => localize(, "message") ] : [ + { range: lc.pathSpan, content: lc.path }, { range: lc.keySpan, content: `${allNLSMessagesIndex++}` }, // localize('key', "message") => localize(, null) - { range: lc.valueSpan, content: 'null' } + { range: lc.valueSpan, content: lc.value } ])) .flatten() .map(toPatch); const localize2Patches = lazy(localize2Calls) - .map(lc => ({ range: lc.keySpan, content: `${allNLSMessagesIndex++}` } // localize2('key', "message") => localize(, "message") - )) + .map(lc => ([ + { range: lc.pathSpan, content: lc.path }, + { range: lc.keySpan, content: `${allNLSMessagesIndex++}` }, // localize2('key', "message") => localize(, "message") + { range: lc.valueSpan, content: lc.value }, + ])) + .flatten() .map(toPatch); // Sort patches by their start position const patches = localizePatches.concat(localize2Patches).toArray().sort((a, b) => { @@ -384,13 +393,14 @@ var _nls; sourcemap = patchSourcemap(patches, sourcemap, smc); return { javascript, sourcemap, nlsKeys, nlsMessages }; } + _nls.patch = patch; function patchFile(javascriptFile, typescript, options) { const ts = require('typescript'); // hack? const moduleId = javascriptFile.relative .replace(/\.js$/, '') .replace(/\\/g, '/'); - const { javascript, sourcemap, nlsKeys, nlsMessages } = patch(ts, typescript, javascriptFile.contents.toString(), javascriptFile.sourceMap, options); + const { javascript, sourcemap, nlsKeys, nlsMessages } = patch(ts, moduleId, typescript, javascriptFile.contents.toString(), javascriptFile.sourceMap, options); const result = fileFrom(javascriptFile, javascript); result.sourceMap = sourcemap; if (nlsKeys) { diff --git a/build/lib/nls.ts b/build/lib/nls.ts index cac832903a3..92254366f13 100644 --- a/build/lib/nls.ts +++ b/build/lib/nls.ts @@ -148,6 +148,8 @@ module _nls { key: string; valueSpan: ISpan; value: string; + pathSpan: ISpan, + path: string; } interface ILocalizeAnalysisResult { @@ -212,8 +214,9 @@ module _nls { return node.kind === ts.SyntaxKind.CallExpression ? CollectStepResult.YesAndRecurse : CollectStepResult.NoAndRecurse; } - function analyze( + export function analyze( ts: typeof import('typescript'), + moduleId: string, contents: string, functionName: 'localize' | 'localize2', options: ts.CompilerOptions = {} @@ -296,7 +299,9 @@ module _nls { .filter(a => a.length > 1) .sort((a, b) => a[0].getStart() - b[0].getStart()) .map(a => ({ - keySpan: { start: ts.getLineAndCharacterOfPosition(sourceFile, a[0].getStart()), end: ts.getLineAndCharacterOfPosition(sourceFile, a[0].getEnd()) }, + pathSpan: { start: ts.getLineAndCharacterOfPosition(sourceFile, a[0].getStart()), end: ts.getLineAndCharacterOfPosition(sourceFile, a[0].getEnd()) }, + path: `"${moduleId}",`, + keySpan: { start: ts.getLineAndCharacterOfPosition(sourceFile, a[1].getStart() - 1), end: ts.getLineAndCharacterOfPosition(sourceFile, a[1].getStart() - 1) }, key: a[0].getText(), valueSpan: { start: ts.getLineAndCharacterOfPosition(sourceFile, a[1].getStart()), end: ts.getLineAndCharacterOfPosition(sourceFile, a[1].getEnd()) }, value: a[1].getText() @@ -435,9 +440,9 @@ module _nls { return eval(`(${sourceExpression})`); } - function patch(ts: typeof import('typescript'), typescript: string, javascript: string, sourcemap: sm.RawSourceMap, options: { preserveEnglish: boolean }): INlsPatchResult { - const { localizeCalls } = analyze(ts, typescript, 'localize'); - const { localizeCalls: localize2Calls } = analyze(ts, typescript, 'localize2'); + export function patch(ts: typeof import('typescript'), moduleId: string, typescript: string, javascript: string, sourcemap: sm.RawSourceMap, options: { preserveEnglish: boolean }): INlsPatchResult { + const { localizeCalls } = analyze(ts, moduleId, typescript, 'localize'); + const { localizeCalls: localize2Calls } = analyze(ts, moduleId, typescript, 'localize2'); if (localizeCalls.length === 0 && localize2Calls.length === 0) { return { javascript, sourcemap }; @@ -458,18 +463,23 @@ module _nls { const localizePatches = lazy(localizeCalls) .map(lc => ( options.preserveEnglish ? [ + { range: lc.pathSpan, content: lc.path }, { range: lc.keySpan, content: `${allNLSMessagesIndex++}` } // localize('key', "message") => localize(, "message") ] : [ + { range: lc.pathSpan, content: lc.path }, { range: lc.keySpan, content: `${allNLSMessagesIndex++}` }, // localize('key', "message") => localize(, null) - { range: lc.valueSpan, content: 'null' } + { range: lc.valueSpan, content: lc.value } ])) .flatten() .map(toPatch); const localize2Patches = lazy(localize2Calls) - .map(lc => ( - { range: lc.keySpan, content: `${allNLSMessagesIndex++}` } // localize2('key', "message") => localize(, "message") - )) + .map(lc => ([ + { range: lc.pathSpan, content: lc.path }, + { range: lc.keySpan, content: `${allNLSMessagesIndex++}` }, // localize2('key', "message") => localize(, "message") + { range: lc.valueSpan, content: lc.value }, + ])) + .flatten() .map(toPatch); // Sort patches by their start position @@ -503,6 +513,7 @@ module _nls { const { javascript, sourcemap, nlsKeys, nlsMessages } = patch( ts, + moduleId, typescript, javascriptFile.contents.toString(), (javascriptFile).sourceMap, diff --git a/src/vs/editor/common/languages.ts b/src/vs/editor/common/languages.ts index 3c247229750..6e60c84b0c1 100644 --- a/src/vs/editor/common/languages.ts +++ b/src/vs/editor/common/languages.ts @@ -655,7 +655,7 @@ export interface CompletionItemProvider { * * @internal */ - _debugDisplayName: string; + _debugDisplayName?: string; triggerCharacters?: string[]; /** diff --git a/src/vs/editor/common/model.ts b/src/vs/editor/common/model.ts index 640d694083c..abffec3ae76 100644 --- a/src/vs/editor/common/model.ts +++ b/src/vs/editor/common/model.ts @@ -517,7 +517,7 @@ export class TextModelResolvedOptions { readonly tabSize: number; readonly indentSize: number; - private readonly _indentSizeIsTabSize: boolean; + readonly _indentSizeIsTabSize: boolean; readonly insertSpaces: boolean; readonly defaultEOL: DefaultEndOfLine; readonly trimAutoWhitespace: boolean; diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index e7545fd2f4a..2e3d33ecafb 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -6792,7 +6792,7 @@ declare namespace monaco.editor { _textModelResolvedOptionsBrand: void; readonly tabSize: number; readonly indentSize: number; - private readonly _indentSizeIsTabSize; + readonly _indentSizeIsTabSize: boolean; readonly insertSpaces: boolean; readonly defaultEOL: DefaultEndOfLine; readonly trimAutoWhitespace: boolean; @@ -8780,7 +8780,7 @@ declare namespace monaco.languages { * * @internal */ - _debugDisplayName: string; + _debugDisplayName?: string; triggerCharacters?: string[]; /** * Provide completion items for the given position and document. From 810612f0739093f042ba1adb69f639d290e21090 Mon Sep 17 00:00:00 2001 From: "qingyi.xjh" Date: Wed, 20 Nov 2024 15:59:08 +0800 Subject: [PATCH 05/10] fix: worker import error --- build/gulpfile.compile.js | 2 +- build/gulpfile.editor.js | 5 +- build/lib/i18n.js | 25 +-- build/lib/i18n.ts | 26 +-- build/lib/standalone.js | 6 +- build/lib/standalone.ts | 6 +- build/npm/update-localization-extension.js | 1 + src/vs/base/common/worker/simpleWorker.ts | 15 +- .../common/services/editorSimpleWorker.ts | 3 +- src/vs/nls.ts | 165 ++++++++---------- 10 files changed, 93 insertions(+), 161 deletions(-) diff --git a/build/gulpfile.compile.js b/build/gulpfile.compile.js index e40b05f8d39..94e8f6417f4 100644 --- a/build/gulpfile.compile.js +++ b/build/gulpfile.compile.js @@ -20,7 +20,7 @@ function makeCompileBuildTask(disableMangle) { util.rimraf('out-build'), date.writeISODate('out-build'), compilation.compileApiProposalNamesTask, - compilation.compileTask('src', 'out-build', true, { disableMangle }) + compilation.compileTask('src', 'out-build', true, { disableMangle, extractConstEnum: true }) ); } diff --git a/build/gulpfile.editor.js b/build/gulpfile.editor.js index 8f6d8f7c08d..1c363c6457c 100644 --- a/build/gulpfile.editor.js +++ b/build/gulpfile.editor.js @@ -87,8 +87,8 @@ const extractEditorSrcTask = task.define('extract-editor-src', () => { // Disable mangling for the editor, as it complicates debugging & quite a few users rely on private/protected fields. // Disable NLS task to remove english strings to preserve backwards compatibility when we removed the `vs/nls!` AMD plugin. -const compileEditorAMDTask = task.define('compile-editor-amd', compilation.compileTask('out-editor-src', 'out-editor-build', true, { disableMangle: true, preserveEnglish: true }, false)); -const compileEditorEsmTask = task.define('compile-editor-esm-core', compilation.compileTask('out-editor-esm', 'out-monaco-editor-core/esm', true, { disableMangle: true }, true, 1 /** CommonJS */)); +const compileEditorAMDTask = task.define('compile-editor-amd', compilation.compileTask('out-editor-src', 'out-editor-build', true, { disableMangle: true, preserveEnglish: true, extractConstEnum: true }, false)); +const compileEditorEsmTask = task.define('compile-editor-esm-core', compilation.compileTask('out-editor-esm', 'out-monaco-editor-core/esm', true, { disableMangle: true, extractConstEnum: true }, true, 1 /** CommonJS */)); const bundleEditorAMDTask = task.define('bundle-editor-amd', optimize.bundleTask( { @@ -125,7 +125,6 @@ const createESMSourcesAndResourcesTask = task.define('extract-editor-esm', () => 'inlineEntryPoint.1.js.map', 'inlineEntryPoint.0.d.ts', 'inlineEntryPoint.1.d.ts', - 'vs/nls.ts', 'vs/loader.js', 'vs/base/worker/workerMain.ts', ], diff --git a/build/lib/i18n.js b/build/lib/i18n.js index 431f8faad49..6964616291b 100644 --- a/build/lib/i18n.js +++ b/build/lib/i18n.js @@ -313,21 +313,6 @@ globalThis._VSCODE_NLS_LANGUAGE=${JSON.stringify(language.id)};`), })); }); } -const commonHeader1 = `/*---------------------------------------------------------\n`; -const commonHeader2 = `* Copyright (c) Microsoft Corporation. All rights reserved.\n`; -const commonHeader3 = `*--------------------------------------------------------*/`; -// 将 nls.js 转换成 nls.json 结构 -// @ts-ignore -function toJsonNlsFile(content, fileHeader) { - return content - .replace(fileHeader, '') - .replace(commonHeader1, '') - .replace(commonHeader2, '') - .replace(commonHeader3, '') - .replace(`define("vs/editor/editor.main.nls", {`, '{') - .replace('});', '}') - .trim(); -} function processNlsFiles(opts) { return (0, event_stream_1.through)(function (file) { const fileName = path.basename(file.path); @@ -342,15 +327,7 @@ function processNlsFiles(opts) { this.emit('error', `Failed to read component file: ${error}`); } } - if (file.path.includes('editor.main.nls.js')) { - this.queue(new File({ - path: file.path.replace('.js', '.json'), - contents: Buffer.from(toJsonNlsFile(file.contents.toString(), opts.fileHeader)), - })); - } - else { - this.queue(file); - } + this.queue(file); }); } const editorProject = 'vscode-editor', workbenchProject = 'vscode-workbench', extensionsProject = 'vscode-extensions', setupProject = 'vscode-setup', serverProject = 'vscode-server'; diff --git a/build/lib/i18n.ts b/build/lib/i18n.ts index 33e0c219cfe..e71707372be 100644 --- a/build/lib/i18n.ts +++ b/build/lib/i18n.ts @@ -384,21 +384,6 @@ globalThis._VSCODE_NLS_LANGUAGE=${JSON.stringify(language.id)};`), }); } -const commonHeader1 = `/*---------------------------------------------------------\n`; -const commonHeader2 = `* Copyright (c) Microsoft Corporation. All rights reserved.\n`; -const commonHeader3 = `*--------------------------------------------------------*/`; -// 将 nls.js 转换成 nls.json 结构 -// @ts-ignore -function toJsonNlsFile(content: string, fileHeader: string): string { - return content - .replace(fileHeader, '') - .replace(commonHeader1, '') - .replace(commonHeader2, '') - .replace(commonHeader3, '') - .replace(`define("vs/editor/editor.main.nls", {`, '{') - .replace('});', '}') - .trim(); -} export function processNlsFiles(opts: { out: string; fileHeader: string; languages: Language[] }): ThroughStream { return through(function (this: ThroughStream, file: File) { @@ -414,16 +399,7 @@ export function processNlsFiles(opts: { out: string; fileHeader: string; languag } } - if (file.path.includes('editor.main.nls.js')) { - this.queue(new File( - { - path: file.path.replace('.js', '.json'), - contents: Buffer.from(toJsonNlsFile(file.contents.toString(), opts.fileHeader)), - } - )) - } else { - this.queue(file); - } + this.queue(file); }); } diff --git a/build/lib/standalone.js b/build/lib/standalone.js index 3bc083cb507..4d2fcb2492d 100644 --- a/build/lib/standalone.js +++ b/build/lib/standalone.js @@ -174,8 +174,7 @@ function createESMSourcesAndResources2(options) { mode = 1; continue; } - // if (/\/\/ ESM-uncomment-begin/.test(line)) { - if (/\/\/ CJS-comment-begin/.test(line)) { + if (/\/\/ ESM-uncomment-begin/.test(line)) { mode = 2; continue; } @@ -190,8 +189,7 @@ function createESMSourcesAndResources2(options) { continue; } if (mode === 2) { - // if (/\/\/ ESM-uncomment-end/.test(line)) { - if (/\/\/ CJS-comment-end/.test(line)) { + if (/\/\/ ESM-uncomment-end/.test(line)) { mode = 0; continue; } diff --git a/build/lib/standalone.ts b/build/lib/standalone.ts index 76e0a5ed822..75ec232cc06 100644 --- a/build/lib/standalone.ts +++ b/build/lib/standalone.ts @@ -206,8 +206,7 @@ export function createESMSourcesAndResources2(options: IOptions2): void { mode = 1; continue; } - // if (/\/\/ ESM-uncomment-begin/.test(line)) { - if (/\/\/ CJS-comment-begin/.test(line)) { + if (/\/\/ ESM-uncomment-begin/.test(line)) { mode = 2; continue; } @@ -224,8 +223,7 @@ export function createESMSourcesAndResources2(options: IOptions2): void { } if (mode === 2) { - // if (/\/\/ ESM-uncomment-end/.test(line)) { - if (/\/\/ CJS-comment-end/.test(line)) { + if (/\/\/ ESM-uncomment-end/.test(line)) { mode = 0; continue; } diff --git a/build/npm/update-localization-extension.js b/build/npm/update-localization-extension.js index 6274323f747..70db2770509 100644 --- a/build/npm/update-localization-extension.js +++ b/build/npm/update-localization-extension.js @@ -15,6 +15,7 @@ let rimraf = require('rimraf'); let minimist = require('minimist'); function update(options) { + console.log("🚀 ~ update ~ options:", options) let idOrPath = options._; if (!idOrPath) { throw new Error('Argument must be the location of the localization extension.'); diff --git a/src/vs/base/common/worker/simpleWorker.ts b/src/vs/base/common/worker/simpleWorker.ts index b04319bc9a3..337febeef71 100644 --- a/src/vs/base/common/worker/simpleWorker.ts +++ b/src/vs/base/common/worker/simpleWorker.ts @@ -570,13 +570,14 @@ export class SimpleWorkerServer implements IWorkerServer { } const url = FileAccess.asBrowserUri(`${moduleId}.js` as AppResourcePath).toString(true); - return import(`${url}`).then((module: { create: IRequestHandlerFactory }) => { - this._requestHandler = module.create(this); - - if (!this._requestHandler) { - throw new Error(`No RequestHandler!`); - } - }); + console.log("🚀 ~ SimpleWorkerServer ~ initialize ~ url:", url) + // return import(`${url}`).then((module: { create: IRequestHandlerFactory }) => { + // this._requestHandler = module.create(this); + + // if (!this._requestHandler) { + // throw new Error(`No RequestHandler!`); + // } + // }); } } diff --git a/src/vs/editor/common/services/editorSimpleWorker.ts b/src/vs/editor/common/services/editorSimpleWorker.ts index 2432a8f657a..68147c0f792 100644 --- a/src/vs/editor/common/services/editorSimpleWorker.ts +++ b/src/vs/editor/common/services/editorSimpleWorker.ts @@ -559,7 +559,8 @@ export class EditorSimpleWorker extends BaseEditorSimpleWorker { }; const url = FileAccess.asBrowserUri(`${moduleId}.js` as AppResourcePath).toString(true); - import(`${url}`).then(onModuleCallback).catch(reject); + console.log("🚀 ~ EditorSimpleWorker ~ returnnewPromise ~ url:", url) + // import(`${url}`).then(onModuleCallback).catch(reject); }); } diff --git a/src/vs/nls.ts b/src/vs/nls.ts index e730d0a761e..be92138bcb8 100644 --- a/src/vs/nls.ts +++ b/src/vs/nls.ts @@ -3,8 +3,52 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +/* --------------------------------------------------------------------------------------------- + * 本文件用于为 esm 版本的 monaco-editor 提供 nls 多语言支持 + * 不适用于其他版本 (dev/min) + *---------------------------------------------------------------------------------------------*/ +// @ts-ignore +const zhCnBundle = require('../../dev/vs/editor/editor.main.nls.zh-cn.json'); +let defaultLocale: string | undefined; +let CURRENT_LOCALE_DATA: { [prop: string]: string[] } | null = null; +// 标准语种代码,目前仅支持中、英文 +export type LocaleType = 'zh-CN' | 'en-US'; +let initialized = false; +export function setLocale(locale: LocaleType): void { + defaultLocale = locale; +} +export enum PreferenceScope { + Default, + User, +} +const KAITIAN_LANGUAGE_KEY = 'general.language'; +/** + * 提供手动设置语言的方法 #setLocale + * 如果在第一次调用 localize 前没有设置过 locale,则会走这里 fallback 的逻辑 + */ +function initialLocaleBundle() { + // @ts-ignore + if (!global.localStorage || !self.localStorage) { + return; + } + if (!defaultLocale) { + if (localStorage[`${PreferenceScope.User}:${KAITIAN_LANGUAGE_KEY}`]) { + defaultLocale = localStorage[`${PreferenceScope.User}:${KAITIAN_LANGUAGE_KEY}`]; + } else if (localStorage[`${PreferenceScope.Default}:${KAITIAN_LANGUAGE_KEY}`]) { + defaultLocale = localStorage[`${PreferenceScope.Default}:${KAITIAN_LANGUAGE_KEY}`]; + } else { + defaultLocale = 'zh-CN'; + } + } + // 由于目前仅支持中/英文,所以如果locale 为 'zh-cn',则表示已经设置了中文,否则仅使用默认值,无需加载语言包 + if (defaultLocale?.toLowerCase() === 'zh-cn') { + CURRENT_LOCALE_DATA = zhCnBundle; + } + initialized = true; +} + // eslint-disable-next-line local/code-import-patterns -import { getNLSLanguage, getNLSMessages } from './nls.messages.js'; +import { getNLSLanguage } from './nls.messages.js'; // eslint-disable-next-line local/code-import-patterns export { getNLSLanguage, getNLSMessages } from './nls.messages.js'; @@ -27,8 +71,8 @@ function _format(message: string, args: (string | number | boolean | undefined | result = message; } else { result = message.replace(/\{(\d+)\}/g, (match, rest) => { - const index = rest[0]; - const arg = args[index]; + let index = rest[0]; + let arg = args[index]; let result = match; if (typeof arg === 'string') { result = arg; @@ -47,106 +91,43 @@ function _format(message: string, args: (string | number | boolean | undefined | return result; } -/** - * Marks a string to be localized. Returns the localized string. - * - * @param info The {@linkcode ILocalizeInfo} which describes the id and comments associated with the localized string. - * @param message The string to localize - * @param args The arguments to the string - * - * @note `message` can contain `{n}` notation where it is replaced by the nth value in `...args` - * @example `localize({ key: 'sayHello', comment: ['Welcomes user'] }, 'hello {0}', name)` - * - * @returns string The localized string. - */ -export function localize(info: ILocalizeInfo, message: string, ...args: (string | number | boolean | undefined | null)[]): string; +export function loadLocaleBundle(bundle: { [prop: string]: string[] }) { + CURRENT_LOCALE_DATA = bundle; +} /** - * Marks a string to be localized. Returns the localized string. + * 这里的类型注释本质是为了让编译时类型校验能通过 + * @param data + * @param message * - * @param key The key to use for localizing the string - * @param message The string to localize - * @param args The arguments to the string - * - * @note `message` can contain `{n}` notation where it is replaced by the nth value in `...args` - * @example For example, `localize('sayHello', 'hello {0}', name)` - * - * @returns string The localized string. - */ -export function localize(key: string, message: string, ...args: (string | number | boolean | undefined | null)[]): string; - -/** - * @skipMangle + * 在编译后,localize 调用方式为 + * localize('path/to/file', index, defaultMessage, ...args); */ -export function localize(data: ILocalizeInfo | string /* | number when built */, message: string /* | null when built */, ...args: (string | number | boolean | undefined | null)[]): string { - if (typeof data === 'number') { - return _format(lookupMessage(data, message), args); +export function localize(data: string | ILocalizeInfo, message: string, ...args: any[]): string; +export function localize(path: string | ILocalizeInfo, index: number | string, ...args: any[]): string { + // 第一次调用 localize 时如果没有默认语言,或语言包尚未初始化,则走初始化逻辑 + if (!defaultLocale || !initialized) { + initialLocaleBundle(); } - return _format(message, args); -} - -/** - * Only used when built: Looks up the message in the global NLS table. - * This table is being made available as a global through bootstrapping - * depending on the target context. - */ -function lookupMessage(index: number, fallback: string | null): string { - const message = getNLSMessages()?.[index]; - if (typeof message !== 'string') { - if (typeof fallback === 'string') { - return fallback; + if (typeof path === 'string') { + if (!CURRENT_LOCALE_DATA || !CURRENT_LOCALE_DATA[path]) { + const [defaultMessage, ...otherArgs] = args; + return _format(defaultMessage, otherArgs); } - throw new Error(`!!! NLS MISSING: ${index} !!!`); + const dataBundle = CURRENT_LOCALE_DATA[path]; + const [defaultMessage, ...otherArgs] = args; + return _format(dataBundle[index as unknown as number] || defaultMessage, otherArgs); } - return message; + return _format(index as unknown as string, args); } -/** - * Marks a string to be localized. Returns an {@linkcode ILocalizedString} - * which contains the localized string and the original string. - * - * @param info The {@linkcode ILocalizeInfo} which describes the id and comments associated with the localized string. - * @param message The string to localize - * @param args The arguments to the string - * - * @note `message` can contain `{n}` notation where it is replaced by the nth value in `...args` - * @example `localize2({ key: 'sayHello', comment: ['Welcomes user'] }, 'hello {0}', name)` - * - * @returns ILocalizedString which contains the localized string and the original string. - */ -export function localize2(info: ILocalizeInfo, message: string, ...args: (string | number | boolean | undefined | null)[]): ILocalizedString; - -/** - * Marks a string to be localized. Returns an {@linkcode ILocalizedString} - * which contains the localized string and the original string. - * - * @param key The key to use for localizing the string - * @param message The string to localize - * @param args The arguments to the string - * - * @note `message` can contain `{n}` notation where it is replaced by the nth value in `...args` - * @example `localize('sayHello', 'hello {0}', name)` - * - * @returns ILocalizedString which contains the localized string and the original string. - */ -export function localize2(key: string, message: string, ...args: (string | number | boolean | undefined | null)[]): ILocalizedString; - -/** - * @skipMangle - */ -export function localize2(data: ILocalizeInfo | string /* | number when built */, originalMessage: string, ...args: (string | number | boolean | undefined | null)[]): ILocalizedString { - let message: string; - if (typeof data === 'number') { - message = lookupMessage(data, originalMessage); - } else { - message = originalMessage; - } - - const value = _format(message, args); +export function localize2(data: string | ILocalizeInfo, message: string, ...args: any[]): ILocalizedString; +export function localize2(path: string | ILocalizeInfo, index: number | string, ...args: any[]): ILocalizedString { + const res = localize(path, index as string, args); return { - value, - original: originalMessage === message ? value : _format(originalMessage, args) + original: res, + value: res }; } From c56bab7e6a5b7a3d88342325e163b0b5945540d8 Mon Sep 17 00:00:00 2001 From: "qingyi.xjh" Date: Fri, 13 Dec 2024 15:34:04 +0800 Subject: [PATCH 06/10] fix: nls bundle --- build/lib/i18n.js | 45 ++++++++++++++++++- build/lib/i18n.ts | 51 +++++++++++++++++++++- build/lib/nls.js | 41 +++++++++-------- build/lib/nls.ts | 43 ++++++++++-------- build/npm/update-localization-extension.js | 1 - src/vs/nls.ts | 31 ++++++------- 6 files changed, 158 insertions(+), 54 deletions(-) diff --git a/build/lib/i18n.js b/build/lib/i18n.js index 6964616291b..d2fdf271b54 100644 --- a/build/lib/i18n.js +++ b/build/lib/i18n.js @@ -4,7 +4,8 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ Object.defineProperty(exports, "__esModule", { value: true }); -exports.EXTERNAL_EXTENSIONS = exports.XLF = exports.Line = exports.extraLanguages = exports.defaultLanguages = void 0; +exports.EXTERNAL_EXTENSIONS = exports.XLF = exports.Line = exports.NLSKeysFormat = exports.extraLanguages = exports.defaultLanguages = void 0; +exports.processAllNlsFiles = processAllNlsFiles; exports.processNlsFiles = processNlsFiles; exports.getResource = getResource; exports.createXlfFilesForCoreBundle = createXlfFilesForCoreBundle; @@ -74,7 +75,7 @@ var NLSKeysFormat; return Array.isArray(candidate) && Array.isArray(candidate[1]); } NLSKeysFormat.is = is; -})(NLSKeysFormat || (NLSKeysFormat = {})); +})(NLSKeysFormat || (exports.NLSKeysFormat = NLSKeysFormat = {})); class Line { buffer = []; constructor(indent = 0) { @@ -277,6 +278,46 @@ function stripComments(content) { }); return result; } +// 编译所有语言包 +function processAllNlsFiles(base, languages, json) { + const languageDirectory = path.join(REPO_ROOT_PATH, '..', 'vscode-loc', 'i18n'); + if (!fs.existsSync(languageDirectory)) { + log(`No VS Code localization repository found. Looking at ${languageDirectory}`); + log(`To bundle translations please check out the vscode-loc repository as a sibling of the vscode repository.`); + } + const sortedLanguages = sortLanguages(languages); + const files = []; + sortedLanguages.forEach((language) => { + if (process.env['VSCODE_BUILD_VERBOSE']) { + log(`Generating nls bundles for: ${language.id}`); + } + const languageFolderName = language.translationId || language.id; + const i18nFile = path.join(languageDirectory, `vscode-language-pack-${languageFolderName}`, 'translations', 'main.i18n.json'); + let allMessages; + if (fs.existsSync(i18nFile)) { + const content = stripComments(fs.readFileSync(i18nFile, 'utf8')); + allMessages = JSON.parse(content); + } + let nlsIndex = 0; + const nlsResult = {}; + for (const [moduleId, nlsKeys] of json) { + const moduleTranslations = allMessages?.contents[moduleId]; + for (const nlsKey of nlsKeys) { + if (!nlsResult[moduleId]) { + nlsResult[moduleId] = []; + } + nlsResult[moduleId].push(moduleTranslations?.[nlsKey]); + nlsIndex++; + } + } + files.push(new File({ + contents: Buffer.from(JSON.stringify(nlsResult)), + base, + path: `${base}/nls.messages.${language.id}.json` + })); + }); + return files; +} function processCoreBundleFormat(base, fileHeader, languages, json, emitter) { const languageDirectory = path.join(REPO_ROOT_PATH, '..', 'vscode-loc', 'i18n'); if (!fs.existsSync(languageDirectory)) { diff --git a/build/lib/i18n.ts b/build/lib/i18n.ts index e71707372be..41ddeed84fa 100644 --- a/build/lib/i18n.ts +++ b/build/lib/i18n.ts @@ -93,9 +93,9 @@ module BundledFormat { } } -type NLSKeysFormat = [string /* module ID */, string[] /* keys */]; +export type NLSKeysFormat = [string /* module ID */, string[] /* keys */]; -module NLSKeysFormat { +export module NLSKeysFormat { export function is(value: any): value is NLSKeysFormat { if (value === undefined) { return false; @@ -344,6 +344,53 @@ function stripComments(content: string): string { return result; } +// 编译所有语言包 +export function processAllNlsFiles(base: string, languages: Language[], json: NLSKeysFormat) { + const languageDirectory = path.join(REPO_ROOT_PATH, '..', 'vscode-loc', 'i18n'); + if (!fs.existsSync(languageDirectory)) { + log(`No VS Code localization repository found. Looking at ${languageDirectory}`); + log(`To bundle translations please check out the vscode-loc repository as a sibling of the vscode repository.`); + } + const sortedLanguages = sortLanguages(languages); + const files: File[] = []; + + sortedLanguages.forEach((language) => { + if (process.env['VSCODE_BUILD_VERBOSE']) { + log(`Generating nls bundles for: ${language.id}`); + } + + const languageFolderName = language.translationId || language.id; + const i18nFile = path.join(languageDirectory, `vscode-language-pack-${languageFolderName}`, 'translations', 'main.i18n.json'); + let allMessages: I18nFormat | undefined; + if (fs.existsSync(i18nFile)) { + const content = stripComments(fs.readFileSync(i18nFile, 'utf8')); + allMessages = JSON.parse(content); + } + + let nlsIndex = 0; + const nlsResult: { [key in string]: (string | undefined)[] } = {}; + for (const [moduleId, nlsKeys] of json) { + const moduleTranslations = allMessages?.contents[moduleId]; + for (const nlsKey of nlsKeys) { + if (!nlsResult[moduleId]) { + nlsResult[moduleId] = []; + } + + nlsResult[moduleId].push(moduleTranslations?.[nlsKey]); + nlsIndex++; + } + } + + files.push(new File({ + contents: Buffer.from(JSON.stringify(nlsResult)), + base, + path: `${base}/nls.messages.${language.id}.json` + })); + }); + + return files; +} + function processCoreBundleFormat(base: string, fileHeader: string, languages: Language[], json: NLSKeysFormat, emitter: ThroughStream) { const languageDirectory = path.join(REPO_ROOT_PATH, '..', 'vscode-loc', 'i18n'); if (!fs.existsSync(languageDirectory)) { diff --git a/build/lib/nls.js b/build/lib/nls.js index 2836d81bdf2..1e0a4aedeef 100644 --- a/build/lib/nls.js +++ b/build/lib/nls.js @@ -11,6 +11,7 @@ const File = require("vinyl"); const sm = require("source-map"); const path = require("path"); const sort = require("gulp-sort"); +const i18n_1 = require("./i18n"); var CollectStepResult; (function (CollectStepResult) { CollectStepResult[CollectStepResult["Yes"] = 0] = "Yes"; @@ -75,27 +76,33 @@ function nls(options) { base, path: `${base}/nls.metadata.json` }), - new File({ - contents: Buffer.from(JSON.stringify(_nls.allNLSMessages)), - base, - path: `${base}/nls.messages.json` - }), + // new File({ + // contents: Buffer.from(JSON.stringify(_nls.allNLSMessages)), + // base, + // path: `${base}/nls.messages.json` + // }), new File({ contents: Buffer.from(JSON.stringify(_nls.allNLSModulesAndKeys)), base, path: `${base}/nls.keys.json` }), - new File({ - contents: Buffer.from(`/*--------------------------------------------------------- - * Copyright (C) Microsoft Corporation. All rights reserved. - *--------------------------------------------------------*/ -globalThis._VSCODE_NLS_MESSAGES=${JSON.stringify(_nls.allNLSMessages)};`), - base, - path: `${base}/nls.messages.js` - }) + // new File({ + // contents: Buffer.from(`/*--------------------------------------------------------- + // * Copyright (C) Microsoft Corporation. All rights reserved. + // *--------------------------------------------------------*/ + // globalThis._VSCODE_NLS_MESSAGES=${JSON.stringify(_nls.allNLSMessages)};`), + // base, + // path: `${base}/nls.messages.js` + // }) ]) { this.emit('data', file); } + if (i18n_1.NLSKeysFormat.is(_nls.allNLSModulesAndKeys)) { + const nlsFiles = (0, i18n_1.processAllNlsFiles)(base, i18n_1.defaultLanguages, _nls.allNLSModulesAndKeys); + for (const file of nlsFiles) { + this.emit('data', file); + } + } this.emit('end'); })); return (0, event_stream_1.duplex)(input, output); @@ -109,7 +116,6 @@ var _nls; _nls.moduleToNLSMessages = {}; _nls.allNLSMessages = []; _nls.allNLSModulesAndKeys = []; - let allNLSMessagesIndex = 0; function fileFrom(file, contents, path = file.path) { return new File({ contents: Buffer.from(contents), @@ -352,13 +358,14 @@ var _nls; const end = lcFrom(smc.generatedPositionFor(positionFrom(c.range.end))); return { span: { start, end }, content: c.content }; }; + let i = 0; const localizePatches = lazy(localizeCalls) .map(lc => (options.preserveEnglish ? [ { range: lc.pathSpan, content: lc.path }, - { range: lc.keySpan, content: `${allNLSMessagesIndex++}` } // localize('key', "message") => localize(, "message") + { range: lc.keySpan, content: `${i++}` }, // localize('key', "message") => localize(, "message") ] : [ { range: lc.pathSpan, content: lc.path }, - { range: lc.keySpan, content: `${allNLSMessagesIndex++}` }, // localize('key', "message") => localize(, null) + { range: lc.keySpan, content: `${i++}` }, // localize('key', "message") => localize(, null) { range: lc.valueSpan, content: lc.value } ])) .flatten() @@ -366,7 +373,7 @@ var _nls; const localize2Patches = lazy(localize2Calls) .map(lc => ([ { range: lc.pathSpan, content: lc.path }, - { range: lc.keySpan, content: `${allNLSMessagesIndex++}` }, // localize2('key', "message") => localize(, "message") + { range: lc.keySpan, content: `${i++}` }, // localize2('key', "message") => localize(, "message") { range: lc.valueSpan, content: lc.value }, ])) .flatten() diff --git a/build/lib/nls.ts b/build/lib/nls.ts index 92254366f13..13b93d804f1 100644 --- a/build/lib/nls.ts +++ b/build/lib/nls.ts @@ -10,6 +10,7 @@ import * as File from 'vinyl'; import * as sm from 'source-map'; import * as path from 'path'; import * as sort from 'gulp-sort'; +import { defaultLanguages, NLSKeysFormat, processAllNlsFiles } from './i18n'; declare class FileSourceMap extends File { public sourceMap: sm.RawSourceMap; @@ -89,28 +90,35 @@ export function nls(options: { preserveEnglish: boolean }): NodeJS.ReadWriteStre base, path: `${base}/nls.metadata.json` }), - new File({ - contents: Buffer.from(JSON.stringify(_nls.allNLSMessages)), - base, - path: `${base}/nls.messages.json` - }), + // new File({ + // contents: Buffer.from(JSON.stringify(_nls.allNLSMessages)), + // base, + // path: `${base}/nls.messages.json` + // }), new File({ contents: Buffer.from(JSON.stringify(_nls.allNLSModulesAndKeys)), base, path: `${base}/nls.keys.json` }), - new File({ - contents: Buffer.from(`/*--------------------------------------------------------- - * Copyright (C) Microsoft Corporation. All rights reserved. - *--------------------------------------------------------*/ -globalThis._VSCODE_NLS_MESSAGES=${JSON.stringify(_nls.allNLSMessages)};`), - base, - path: `${base}/nls.messages.js` - }) + // new File({ + // contents: Buffer.from(`/*--------------------------------------------------------- + // * Copyright (C) Microsoft Corporation. All rights reserved. + // *--------------------------------------------------------*/ + // globalThis._VSCODE_NLS_MESSAGES=${JSON.stringify(_nls.allNLSMessages)};`), + // base, + // path: `${base}/nls.messages.js` + // }) ]) { this.emit('data', file); } + if (NLSKeysFormat.is(_nls.allNLSModulesAndKeys)) { + const nlsFiles = processAllNlsFiles(base, defaultLanguages, _nls.allNLSModulesAndKeys); + for (const file of nlsFiles) { + this.emit('data', file); + } + } + this.emit('end'); })); @@ -127,7 +135,7 @@ module _nls { export const moduleToNLSMessages: { [name: string /* module ID */]: string[] /* messages */ } = {}; export const allNLSMessages: string[] = []; export const allNLSModulesAndKeys: Array<[string /* module ID */, string[] /* keys */]> = []; - let allNLSMessagesIndex = 0; + // let allNLSMessagesIndex = 0; type ILocalizeKey = string | { key: string }; // key might contain metadata for translators and then is not just a string @@ -460,14 +468,15 @@ module _nls { return { span: { start, end }, content: c.content }; }; + let i = 0; const localizePatches = lazy(localizeCalls) .map(lc => ( options.preserveEnglish ? [ { range: lc.pathSpan, content: lc.path }, - { range: lc.keySpan, content: `${allNLSMessagesIndex++}` } // localize('key', "message") => localize(, "message") + { range: lc.keySpan, content: `${i++}` }, // localize('key', "message") => localize(, "message") ] : [ { range: lc.pathSpan, content: lc.path }, - { range: lc.keySpan, content: `${allNLSMessagesIndex++}` }, // localize('key', "message") => localize(, null) + { range: lc.keySpan, content: `${i++}` }, // localize('key', "message") => localize(, null) { range: lc.valueSpan, content: lc.value } ])) .flatten() @@ -476,7 +485,7 @@ module _nls { const localize2Patches = lazy(localize2Calls) .map(lc => ([ { range: lc.pathSpan, content: lc.path }, - { range: lc.keySpan, content: `${allNLSMessagesIndex++}` }, // localize2('key', "message") => localize(, "message") + { range: lc.keySpan, content: `${i++}` }, // localize2('key', "message") => localize(, "message") { range: lc.valueSpan, content: lc.value }, ])) .flatten() diff --git a/build/npm/update-localization-extension.js b/build/npm/update-localization-extension.js index 70db2770509..6274323f747 100644 --- a/build/npm/update-localization-extension.js +++ b/build/npm/update-localization-extension.js @@ -15,7 +15,6 @@ let rimraf = require('rimraf'); let minimist = require('minimist'); function update(options) { - console.log("🚀 ~ update ~ options:", options) let idOrPath = options._; if (!idOrPath) { throw new Error('Argument must be the location of the localization extension.'); diff --git a/src/vs/nls.ts b/src/vs/nls.ts index be92138bcb8..0901bc62144 100644 --- a/src/vs/nls.ts +++ b/src/vs/nls.ts @@ -7,21 +7,27 @@ * 本文件用于为 esm 版本的 monaco-editor 提供 nls 多语言支持 * 不适用于其他版本 (dev/min) *---------------------------------------------------------------------------------------------*/ +// eslint-disable-next-line local/code-import-patterns +import { getNLSLanguage } from './nls.messages.js'; +// eslint-disable-next-line local/code-import-patterns +export { getNLSLanguage, getNLSMessages } from './nls.messages.js'; + // @ts-ignore -const zhCnBundle = require('../../dev/vs/editor/editor.main.nls.zh-cn.json'); +const zhCnBundle = require('../nls.messages.zh-cn.json'); + let defaultLocale: string | undefined; let CURRENT_LOCALE_DATA: { [prop: string]: string[] } | null = null; +let initialized = false; +const KAITIAN_LANGUAGE_KEY = 'general.language'; // 标准语种代码,目前仅支持中、英文 export type LocaleType = 'zh-CN' | 'en-US'; -let initialized = false; -export function setLocale(locale: LocaleType): void { - defaultLocale = locale; -} export enum PreferenceScope { Default, User, } -const KAITIAN_LANGUAGE_KEY = 'general.language'; +export const setLocale = (locale: LocaleType): void => { + defaultLocale = locale; +} /** * 提供手动设置语言的方法 #setLocale * 如果在第一次调用 localize 前没有设置过 locale,则会走这里 fallback 的逻辑 @@ -33,11 +39,11 @@ function initialLocaleBundle() { } if (!defaultLocale) { if (localStorage[`${PreferenceScope.User}:${KAITIAN_LANGUAGE_KEY}`]) { - defaultLocale = localStorage[`${PreferenceScope.User}:${KAITIAN_LANGUAGE_KEY}`]; + setLocale(localStorage[`${PreferenceScope.User}:${KAITIAN_LANGUAGE_KEY}`]) } else if (localStorage[`${PreferenceScope.Default}:${KAITIAN_LANGUAGE_KEY}`]) { - defaultLocale = localStorage[`${PreferenceScope.Default}:${KAITIAN_LANGUAGE_KEY}`]; + setLocale(localStorage[`${PreferenceScope.Default}:${KAITIAN_LANGUAGE_KEY}`]); } else { - defaultLocale = 'zh-CN'; + setLocale('zh-CN') } } // 由于目前仅支持中/英文,所以如果locale 为 'zh-cn',则表示已经设置了中文,否则仅使用默认值,无需加载语言包 @@ -47,11 +53,6 @@ function initialLocaleBundle() { initialized = true; } -// eslint-disable-next-line local/code-import-patterns -import { getNLSLanguage } from './nls.messages.js'; -// eslint-disable-next-line local/code-import-patterns -export { getNLSLanguage, getNLSMessages } from './nls.messages.js'; - const isPseudo = getNLSLanguage() === 'pseudo' || (typeof document !== 'undefined' && document.location && typeof document.location.hash === 'string' && document.location.hash.indexOf('pseudo=true') >= 0); export interface ILocalizeInfo { @@ -124,7 +125,7 @@ export function localize(path: string | ILocalizeInfo, index: number | string, . export function localize2(data: string | ILocalizeInfo, message: string, ...args: any[]): ILocalizedString; export function localize2(path: string | ILocalizeInfo, index: number | string, ...args: any[]): ILocalizedString { - const res = localize(path, index as string, args); + const res = localize(path, index as string, ...args); return { original: res, value: res From 28bd308ed79a80e3d7f36db451b537cc8c50ae78 Mon Sep 17 00:00:00 2001 From: "qingyi.xjh" Date: Tue, 17 Dec 2024 19:48:45 +0800 Subject: [PATCH 07/10] fix: no initialize in opensumi --- src/vs/editor/standalone/browser/standaloneServices.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/vs/editor/standalone/browser/standaloneServices.ts b/src/vs/editor/standalone/browser/standaloneServices.ts index 0e6637019c1..1adef5e0032 100644 --- a/src/vs/editor/standalone/browser/standaloneServices.ts +++ b/src/vs/editor/standalone/browser/standaloneServices.ts @@ -1184,9 +1184,10 @@ export module StandaloneServices { serviceCollection.set(IInstantiationService, instantiationService); export function get(serviceId: ServiceIdentifier): T { - if (!initialized) { - initialize({}); - } + // we will initialize the services in need on demand on OpenSumi + // if (!initialized) { + // initialize({}); + // } const r = serviceCollection.get(serviceId); if (!r) { throw new Error('Missing service ' + serviceId); From d0d2327bc81dc4675573f8b0e35f116cf0481272 Mon Sep 17 00:00:00 2001 From: "qingyi.xjh" Date: Wed, 18 Dec 2024 10:09:18 +0800 Subject: [PATCH 08/10] chore: no hack --- src/vs/base/browser/settings.ts | 26 ------------- src/vs/base/common/worker/simpleWorker.ts | 15 ++++---- .../contentWidgets/contentWidgets.ts | 14 +++---- .../browser/viewParts/viewLines/viewLine.ts | 2 +- .../editor/common/languages/modesRegistry.ts | 6 +-- .../common/services/editorSimpleWorker.ts | 3 +- .../common/services/languagesRegistry.ts | 37 ++++++++++++------- .../workbench/api/common/extHostTreeViews.ts | 2 +- 8 files changed, 42 insertions(+), 63 deletions(-) delete mode 100644 src/vs/base/browser/settings.ts diff --git a/src/vs/base/browser/settings.ts b/src/vs/base/browser/settings.ts deleted file mode 100644 index 9e76403eb52..00000000000 --- a/src/vs/base/browser/settings.ts +++ /dev/null @@ -1,26 +0,0 @@ -/* eslint-disable header/header */ - -class OverflowContentWidgetsSettings { - private _TOP_PADDING = 22; - private _BOTTOM_PADDING = 22; - - set topPadding(num: number) { - if (Number.isInteger(num)) { - this._TOP_PADDING = num; - } - } - get topPadding() { - return this._TOP_PADDING; - } - - set bottomPadding(num: number) { - if (Number.isInteger(num)) { - this._BOTTOM_PADDING = num; - } - } - get bottomPadding() { - return this._BOTTOM_PADDING; - } -} - -export const overflowWidgetsSettings = new OverflowContentWidgetsSettings(); diff --git a/src/vs/base/common/worker/simpleWorker.ts b/src/vs/base/common/worker/simpleWorker.ts index 337febeef71..b04319bc9a3 100644 --- a/src/vs/base/common/worker/simpleWorker.ts +++ b/src/vs/base/common/worker/simpleWorker.ts @@ -570,14 +570,13 @@ export class SimpleWorkerServer implements IWorkerServer { } const url = FileAccess.asBrowserUri(`${moduleId}.js` as AppResourcePath).toString(true); - console.log("🚀 ~ SimpleWorkerServer ~ initialize ~ url:", url) - // return import(`${url}`).then((module: { create: IRequestHandlerFactory }) => { - // this._requestHandler = module.create(this); - - // if (!this._requestHandler) { - // throw new Error(`No RequestHandler!`); - // } - // }); + return import(`${url}`).then((module: { create: IRequestHandlerFactory }) => { + this._requestHandler = module.create(this); + + if (!this._requestHandler) { + throw new Error(`No RequestHandler!`); + } + }); } } diff --git a/src/vs/editor/browser/viewParts/contentWidgets/contentWidgets.ts b/src/vs/editor/browser/viewParts/contentWidgets/contentWidgets.ts index 9c6eac5248c..be7bd39b7f9 100644 --- a/src/vs/editor/browser/viewParts/contentWidgets/contentWidgets.ts +++ b/src/vs/editor/browser/viewParts/contentWidgets/contentWidgets.ts @@ -16,7 +16,6 @@ import { IDimension } from '../../../common/core/dimension.js'; import { PositionAffinity } from '../../../common/model.js'; import { IPosition, Position } from '../../../common/core/position.js'; import { IViewModel } from '../../../common/viewModel.js'; -import { overflowWidgetsSettings } from '../../../../base/browser/settings.js'; /** * This view part is responsible for rendering the content widgets, which are @@ -307,9 +306,6 @@ class Widget { private _layoutBoxInViewport(anchor: AnchorCoordinate, width: number, height: number, ctx: RenderingContext): IBoxLayoutResult { // Our visible box is split horizontally by the current line => 2 boxes - // 这里获取 domNode 的 clientHeight 可能为 0,会导致下面计算 contentWidget 定位时整体向下偏移了一行 - // 由于获取的是缓存的 height,且 domNode 渲染时机暂时不好修改,所以如果高度为0的话,在这里重新获取一次高度 - const contentHeight = height === 0 ? this.domNode.domNode.clientHeight : height; // a) the box above the line const aboveLineTop = anchor.top; @@ -319,10 +315,10 @@ class Widget { const underLineTop = anchor.top + anchor.height; const heightAvailableUnderLine = ctx.viewportHeight - underLineTop; - const aboveTop = aboveLineTop - contentHeight; - const fitsAbove = (heightAvailableAboveLine >= contentHeight); + const aboveTop = aboveLineTop - height; + const fitsAbove = (heightAvailableAboveLine >= height); const belowTop = underLineTop; - const fitsBelow = (heightAvailableUnderLine >= contentHeight); + const fitsBelow = (heightAvailableUnderLine >= height); // And its left let left = anchor.left; @@ -378,8 +374,8 @@ class Widget { const [left, absoluteAboveLeft] = this._layoutHorizontalSegmentInPage(windowSize, domNodePosition, anchor.left - ctx.scrollLeft + this._contentLeft, width); // Leave some clearance to the top/bottom - const TOP_PADDING = overflowWidgetsSettings.topPadding; - const BOTTOM_PADDING = overflowWidgetsSettings.bottomPadding; + const TOP_PADDING = 22; + const BOTTOM_PADDING = 22; const fitsAbove = (absoluteAboveTop >= TOP_PADDING); const fitsBelow = (absoluteBelowTop + height <= windowSize.height - BOTTOM_PADDING); diff --git a/src/vs/editor/browser/viewParts/viewLines/viewLine.ts b/src/vs/editor/browser/viewParts/viewLines/viewLine.ts index 1250a9f6249..5e555246cea 100644 --- a/src/vs/editor/browser/viewParts/viewLines/viewLine.ts +++ b/src/vs/editor/browser/viewParts/viewLines/viewLine.ts @@ -481,7 +481,7 @@ class RenderedViewLine implements IRenderedViewLine { if (!this.domNode) { return 0; } - if (this._cachedWidth <= 0) { + if (this._cachedWidth === -1) { this._cachedWidth = this._getReadingTarget(this.domNode).offsetWidth; context?.markDidDomLayout(); } diff --git a/src/vs/editor/common/languages/modesRegistry.ts b/src/vs/editor/common/languages/modesRegistry.ts index db8a2e04f4e..871265804d2 100644 --- a/src/vs/editor/common/languages/modesRegistry.ts +++ b/src/vs/editor/common/languages/modesRegistry.ts @@ -20,8 +20,8 @@ export class EditorModesRegistry { private readonly _languages: ILanguageExtensionPoint[]; - private readonly _onDidChangeLanguages = new Emitter(); - public readonly onDidChangeLanguages: Event = this._onDidChangeLanguages.event; + private readonly _onDidChangeLanguages = new Emitter(); + public readonly onDidChangeLanguages: Event = this._onDidChangeLanguages.event; constructor() { this._languages = []; @@ -29,7 +29,7 @@ export class EditorModesRegistry { public registerLanguage(def: ILanguageExtensionPoint): IDisposable { this._languages.push(def); - this._onDidChangeLanguages.fire(def); + this._onDidChangeLanguages.fire(undefined); return { dispose: () => { for (let i = 0, len = this._languages.length; i < len; i++) { diff --git a/src/vs/editor/common/services/editorSimpleWorker.ts b/src/vs/editor/common/services/editorSimpleWorker.ts index 68147c0f792..2432a8f657a 100644 --- a/src/vs/editor/common/services/editorSimpleWorker.ts +++ b/src/vs/editor/common/services/editorSimpleWorker.ts @@ -559,8 +559,7 @@ export class EditorSimpleWorker extends BaseEditorSimpleWorker { }; const url = FileAccess.asBrowserUri(`${moduleId}.js` as AppResourcePath).toString(true); - console.log("🚀 ~ EditorSimpleWorker ~ returnnewPromise ~ url:", url) - // import(`${url}`).then(onModuleCallback).catch(reject); + import(`${url}`).then(onModuleCallback).catch(reject); }); } diff --git a/src/vs/editor/common/services/languagesRegistry.ts b/src/vs/editor/common/services/languagesRegistry.ts index c94f773c6e8..3ea71cff4ee 100644 --- a/src/vs/editor/common/services/languagesRegistry.ts +++ b/src/vs/editor/common/services/languagesRegistry.ts @@ -92,8 +92,8 @@ export class LanguagesRegistry extends Disposable { if (useModesRegistry) { this._initializeFromRegistry(); - this._register(ModesRegistry.onDidChangeLanguages((lang) => { - this._registerLanguage(lang); + this._register(ModesRegistry.onDidChangeLanguages((m) => { + this._initializeFromRegistry(); })); } } @@ -105,7 +105,7 @@ export class LanguagesRegistry extends Disposable { public setDynamicLanguages(def: ILanguageExtensionPoint[]): void { this._dynamicLanguages = def; - this._registerLanguages(this._dynamicLanguages); + this._initializeFromRegistry(); } private _initializeFromRegistry(): void { @@ -115,6 +115,8 @@ export class LanguagesRegistry extends Disposable { this._lowercaseNameMap = {}; clearPlatformLanguageAssociations(); + const desc = ([]).concat(ModesRegistry.getLanguages()).concat(this._dynamicLanguages); + this._registerLanguages(desc); } registerLanguage(desc: ILanguageExtensionPoint): IDisposable { @@ -122,10 +124,28 @@ export class LanguagesRegistry extends Disposable { } _registerLanguages(desc: ILanguageExtensionPoint[]): void { + for (const d of desc) { this._registerLanguage(d); } + // Rebuild fast path maps + this._mimeTypesMap = {}; + this._nameMap = {}; + this._lowercaseNameMap = {}; + Object.keys(this._languages).forEach((langId) => { + const language = this._languages[langId]; + if (language.name) { + this._nameMap[language.name] = language.identifier; + } + language.aliases.forEach((alias) => { + this._lowercaseNameMap[alias.toLowerCase()] = language.identifier; + }); + language.mimetypes.forEach((mimetype) => { + this._mimeTypesMap[mimetype] = language.identifier; + }); + }); + Registry.as(Extensions.Configuration).registerOverrideIdentifiers(this.getRegisteredLanguageIds()); this._onDidChange.fire(); @@ -133,6 +153,7 @@ export class LanguagesRegistry extends Disposable { private _registerLanguage(lang: ILanguageExtensionPoint): void { const langId = lang.id; + let resolvedLanguage: IResolvedLanguage; if (hasOwnProperty.call(this._languages, langId)) { resolvedLanguage = this._languages[langId]; @@ -152,16 +173,6 @@ export class LanguagesRegistry extends Disposable { } this._mergeLanguage(resolvedLanguage, lang); - // Rebuild fast path maps - if (resolvedLanguage.name) { - this._nameMap[resolvedLanguage.name] = resolvedLanguage.identifier; - } - resolvedLanguage.aliases.forEach((alias) => { - this._lowercaseNameMap[alias.toLowerCase()] = resolvedLanguage.identifier; - }); - resolvedLanguage.mimetypes.forEach((mimetype) => { - this._mimeTypesMap[mimetype] = resolvedLanguage.identifier; - }); } private _mergeLanguage(resolvedLanguage: IResolvedLanguage, lang: ILanguageExtensionPoint): void { diff --git a/src/vs/workbench/api/common/extHostTreeViews.ts b/src/vs/workbench/api/common/extHostTreeViews.ts index a5d2fbaeae4..d3c2aae3c12 100644 --- a/src/vs/workbench/api/common/extHostTreeViews.ts +++ b/src/vs/workbench/api/common/extHostTreeViews.ts @@ -385,7 +385,7 @@ class ExtHostTreeView extends Disposable { result.message = true; } return result; - }, 200); + }, 200, true); this._register(onDidChangeData(({ message, elements }) => { if (elements.length) { this.refreshQueue = this.refreshQueue.then(() => { From e84e92384ae1c089b1b4ee9019888054a0008d39 Mon Sep 17 00:00:00 2001 From: "qingyi.xjh" Date: Thu, 19 Dec 2024 16:30:43 +0800 Subject: [PATCH 09/10] chore: upgrade version --- build/monaco/package.json | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/build/monaco/package.json b/build/monaco/package.json index 687af0852aa..9f40ea13781 100644 --- a/build/monaco/package.json +++ b/build/monaco/package.json @@ -1,17 +1,19 @@ { - "name": "monaco-editor-core", - "private": true, - "version": "0.0.0", + "name": "@opensumi/monaco-editor-core", + "version": "0.53.0-patch.1", "description": "A browser based code editor", - "author": "Microsoft Corporation", + "author": "Microsoft Corporation and open source contributors", "license": "MIT", "typings": "./esm/vs/editor/editor.api.d.ts", "module": "./esm/vs/editor/editor.main.js", "repository": { "type": "git", - "url": "https://github.com/microsoft/vscode" + "url": "https://github.com/opensumi/monaco-editor-core" }, "bugs": { - "url": "https://github.com/microsoft/vscode/issues" + "url": "https://github.com/opensumi/monaco-editor-core/issues" + }, + "publishConfig": { + "registry": "https://registry.npmjs.org/" } } From dabde35fc8653064ca52958f51f5d9976cd24a12 Mon Sep 17 00:00:00 2001 From: "qingyi.xjh" Date: Fri, 20 Dec 2024 16:44:15 +0800 Subject: [PATCH 10/10] fix: include js webpack dynamic importimport --- build/monaco/package.json | 2 +- src/vs/base/common/worker/simpleWorker.ts | 5 ++++- src/vs/editor/common/services/editorSimpleWorker.ts | 5 ++++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/build/monaco/package.json b/build/monaco/package.json index 9f40ea13781..1fe9b2bd1f5 100644 --- a/build/monaco/package.json +++ b/build/monaco/package.json @@ -1,6 +1,6 @@ { "name": "@opensumi/monaco-editor-core", - "version": "0.53.0-patch.1", + "version": "0.53.0-patch.2", "description": "A browser based code editor", "author": "Microsoft Corporation and open source contributors", "license": "MIT", diff --git a/src/vs/base/common/worker/simpleWorker.ts b/src/vs/base/common/worker/simpleWorker.ts index b04319bc9a3..e34f4307bc1 100644 --- a/src/vs/base/common/worker/simpleWorker.ts +++ b/src/vs/base/common/worker/simpleWorker.ts @@ -570,7 +570,10 @@ export class SimpleWorkerServer implements IWorkerServer { } const url = FileAccess.asBrowserUri(`${moduleId}.js` as AppResourcePath).toString(true); - return import(`${url}`).then((module: { create: IRequestHandlerFactory }) => { + return import( + /* webpackInclude: /\.js$/ */ + `${url}` + ).then((module: { create: IRequestHandlerFactory }) => { this._requestHandler = module.create(this); if (!this._requestHandler) { diff --git a/src/vs/editor/common/services/editorSimpleWorker.ts b/src/vs/editor/common/services/editorSimpleWorker.ts index 2432a8f657a..67a09efa28f 100644 --- a/src/vs/editor/common/services/editorSimpleWorker.ts +++ b/src/vs/editor/common/services/editorSimpleWorker.ts @@ -559,7 +559,10 @@ export class EditorSimpleWorker extends BaseEditorSimpleWorker { }; const url = FileAccess.asBrowserUri(`${moduleId}.js` as AppResourcePath).toString(true); - import(`${url}`).then(onModuleCallback).catch(reject); + import( + /* webpackInclude: /\.js$/ */ + `${url}` + ).then(onModuleCallback).catch(reject); }); }