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 739c37fc677..1c363c6457c 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, 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( { @@ -110,6 +111,20 @@ 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/loader.js', 'vs/base/worker/workerMain.ts', ], @@ -345,6 +360,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 +378,53 @@ gulp.task('editor-distro', util.rimraf('out-editor-min') ), extractEditorSrcTask, + monacodtsTask, task.parallel( task.series( compileEditorAMDTask, bundleEditorAMDTask, - minifyEditorAMDTask + // minifyEditorAMDTask ), task.series( createESMSourcesAndResourcesTask, - compileEditorESMTask, + 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/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/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/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 cd7e522ad36..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)) { @@ -384,6 +431,7 @@ globalThis._VSCODE_NLS_LANGUAGE=${JSON.stringify(language.id)};`), }); } + 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,6 +445,7 @@ export function processNlsFiles(opts: { out: string; fileHeader: string; languag this.emit('error', `Failed to read component file: ${error}`); } } + this.queue(file); }); } 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/nls.js b/build/lib/nls.js index 6ddcd46167a..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), @@ -157,7 +163,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 +230,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 +241,7 @@ var _nls; localizeCalls: localizeCalls.toArray() }; } + _nls.analyze = analyze; class TextModel { lines; lineEndings; @@ -333,9 +342,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 }; } @@ -349,18 +358,25 @@ 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.keySpan, content: `${allNLSMessagesIndex++}` } // localize('key', "message") => localize(, "message") + { range: lc.pathSpan, content: lc.path }, + { range: lc.keySpan, content: `${i++}` }, // localize('key', "message") => localize(, "message") ] : [ - { range: lc.keySpan, content: `${allNLSMessagesIndex++}` }, // localize('key', "message") => localize(, null) - { range: lc.valueSpan, content: 'null' } + { range: lc.pathSpan, content: lc.path }, + { range: lc.keySpan, content: `${i++}` }, // localize('key', "message") => localize(, 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: `${i++}` }, // 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 +400,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..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 @@ -148,6 +156,8 @@ module _nls { key: string; valueSpan: ISpan; value: string; + pathSpan: ISpan, + path: string; } interface ILocalizeAnalysisResult { @@ -212,8 +222,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 +307,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 +448,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 }; @@ -455,21 +468,27 @@ module _nls { return { span: { start, end }, content: c.content }; }; + let i = 0; const localizePatches = lazy(localizeCalls) .map(lc => ( options.preserveEnglish ? [ - { range: lc.keySpan, content: `${allNLSMessagesIndex++}` } // localize('key', "message") => localize(, "message") + { range: lc.pathSpan, content: lc.path }, + { range: lc.keySpan, content: `${i++}` }, // localize('key', "message") => localize(, "message") ] : [ - { range: lc.keySpan, content: `${allNLSMessagesIndex++}` }, // localize('key', "message") => localize(, null) - { range: lc.valueSpan, content: 'null' } + { range: lc.pathSpan, content: lc.path }, + { range: lc.keySpan, content: `${i++}` }, // localize('key', "message") => localize(, 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: `${i++}` }, // localize2('key', "message") => localize(, "message") + { range: lc.valueSpan, content: lc.value }, + ])) + .flatten() .map(toPatch); // Sort patches by their start position @@ -503,6 +522,7 @@ module _nls { const { javascript, sourcemap, nlsKeys, nlsMessages } = patch( ts, + moduleId, typescript, javascriptFile.contents.toString(), (javascriptFile).sourceMap, diff --git a/build/lib/standalone.js b/build/lib/standalone.js index 16ae1e2b2d8..4d2fcb2492d 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)}`); diff --git a/build/lib/standalone.ts b/build/lib/standalone.ts index 8736583fb09..75ec232cc06 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; 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..757ed825132 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 @@ -104,25 +104,29 @@ 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 #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 +#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 +#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;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 +#includeAll(vs/editor/common/tokens/tokenArray): #include(vs/editor/common/config/editorZoom): EditorZoom, IEditorZoom //compatibility: @@ -133,17 +137,23 @@ 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;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 +#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; } 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/build/monaco/package.json b/build/monaco/package.json index 687af0852aa..1fe9b2bd1f5 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.2", "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/" } } 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/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/languages.ts b/src/vs/editor/common/languages.ts index 68bb4cd7fb3..6e60c84b0c1 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; @@ -95,9 +94,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. @@ -659,7 +655,7 @@ export interface CompletionItemProvider { * * @internal */ - _debugDisplayName: string; + _debugDisplayName?: string; triggerCharacters?: string[]; /** @@ -900,9 +896,6 @@ export interface DocumentPasteEdit { additionalEdit?: WorkspaceEdit; } -/** - * @internal - */ export enum DocumentPasteTriggerKind { Automatic = 0, PasteAs = 1, @@ -1860,9 +1853,6 @@ export enum CommentThreadState { Resolved = 1 } -/** - * @internal - */ export enum CommentThreadApplicability { Current = 0, Outdated = 1 @@ -2244,9 +2234,6 @@ export enum ExternalUriOpenerPriority { Preferred = 3, } -/** - * @internal - */ export type DropYieldTo = { readonly kind: HierarchicalKind } | { readonly mimeType: 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/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); }); } 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/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); diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index f26d9206020..2e3d33ecafb 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. */ @@ -1445,6 +1464,207 @@ declare namespace monaco.editor { readonly description: ILocalizedString | string; } + 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; + /** + * 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 + */ + constructor(identifier: string); + } + export interface IContextKey { set(value: T): void; reset(): void; @@ -1523,6 +1743,11 @@ declare namespace monaco.editor { Visible = 3 } + export interface ThemeIcon { + readonly id: string; + readonly color?: ThemeColor; + } + export interface ThemeColor { id: string; } @@ -1566,4679 +1791,5839 @@ declare namespace monaco.editor { } /** - * Vertical Lane in the overview ruler of the editor. + * A change */ - export enum OverviewRulerLane { - Left = 1, - Center = 2, - Right = 4, - Full = 7 + export interface IChange { + readonly originalStartLineNumber: number; + readonly originalEndLineNumber: number; + readonly modifiedStartLineNumber: number; + readonly modifiedEndLineNumber: number; } /** - * Vertical Lane in the glyph margin of the editor. + * A character level change. */ - export enum GlyphMarginLane { - Left = 1, - Center = 2, - Right = 3 + export interface ICharChange extends IChange { + readonly originalStartColumn: number; + readonly originalEndColumn: number; + readonly modifiedStartColumn: number; + readonly modifiedEndColumn: number; } - export interface IGlyphMarginLanesModel { + /** + * A line change + */ + export interface ILineChange extends IChange { + readonly charChanges: ICharChange[] | undefined; + } + export interface IDimension { + width: number; + 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; /** - * The number of lanes that should be rendered in the editor. + * 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. */ - readonly requiredLanes: number; + join(other: OffsetRange): OffsetRange; /** - * Gets the lanes that should be rendered starting at a given line number. + * 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. */ - getLanesAtLine(lineNumber: number): GlyphMarginLane[]; + 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; /** - * Resets the model and ensures it can contain at least `maxLine` lines. + * Returns the given value if it is contained in this instance, otherwise the closest value that is contained. + * The range must not be empty. */ - reset(maxLine: number): void; + clip(value: number): number; /** - * 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. + * 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`. */ - push(lane: GlyphMarginLane, range: Range, persist?: boolean): void; + clipCyclic(value: number): number; + map(f: (offset: number) => T): T[]; + forEach(f: (offset: number) => void): void; } - - /** - * Position in the minimap to render the decoration. - */ - export enum MinimapPosition { - Inline = 1, - Gutter = 2 + export interface IOffsetRange { + readonly start: number; + readonly endExclusive: number; } /** - * Section header style. + * A builder and helper for edit operations for a command. */ - 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; + export interface IEditOperationBuilder { /** - * CSS color to render. - * e.g.: rgba(100, 100, 100, 0.5) or a color from the color registry + * Add a new edit operation (a replace operation). + * @param range The range to replace (delete). May be empty to represent a simple insert. + * @param text The text to replace with. May be null to represent a simple delete. */ - darkColor?: string | ThemeColor; - } - - export interface IModelDecorationGlyphMarginOptions { + addEditOperation(range: IRange, text: string | null, forceMoveMarkers?: boolean): void; /** - * The position in the glyph margin. + * Add a new edit operation (a replace operation). + * The inverse edits will be accessible in `ICursorStateComputerData.getInverseEditOperations()` + * @param range The range to replace (delete). May be empty to represent a simple insert. + * @param text The text to replace with. May be null to represent a simple delete. */ - position: GlyphMarginLane; + addTrackedEditOperation(range: IRange, text: string | null, forceMoveMarkers?: boolean): void; /** - * Whether the glyph margin lane in {@link position} should be rendered even - * outside of this decoration's range. + * Track `selection` when applying edit operations. + * A best effort will be made to not grow/expand the selection. + * An empty selection will clamp to a nearby character. + * @param selection The selection to track. + * @param trackPreviousOnEmpty If set, and the selection is empty, indicates whether the selection + * should clamp to the previous or the next character. + * @return A unique identifier. */ - persistLane?: boolean; + trackSelection(selection: Selection, trackPreviousOnEmpty?: boolean): string; } /** - * Options for rendering a model decoration in the overview ruler. + * A helper for computing cursor state after a command. */ - export interface IModelDecorationOverviewRulerOptions extends IDecorationOptions { + export interface ICursorStateComputerData { /** - * The position in the overview ruler. + * Get the inverse edit operations of the added edit operations. */ - position: OverviewRulerLane; + getInverseEditOperations(): IValidEditOperation[]; + /** + * Get a previously tracked selection. + * @param id The unique identifier returned by `trackSelection`. + * @return The selection. + */ + getTrackedSelection(id: string): Selection; } /** - * Options for rendering a model decoration in the minimap. + * A command that modifies text / cursor state on a model. */ - export interface IModelDecorationMinimapOptions extends IDecorationOptions { + export interface ICommand { /** - * The position in the minimap. + * Signal that this command is inserting automatic whitespace that should be trimmed if possible. + * @internal */ - position: MinimapPosition; + readonly insertsAutoWhitespace?: boolean; /** - * If the decoration is for a section header, which header style. + * Get the edit operations needed to execute this command. + * @param model The model the command will execute on. + * @param builder A helper to collect the needed edit operations and to track selections. */ - sectionHeaderStyle?: MinimapSectionHeaderStyle | null; + getEditOperations(model: ITextModel, builder: IEditOperationBuilder): void; /** - * If the decoration is for a section header, the header text. + * Compute the cursor state after the edit operations were applied. + * @param model The model the command has executed on. + * @param helper A helper to get inverse edit operations and to get previously tracked selections. + * @return The cursor state after the command executed. */ - sectionHeaderText?: string | null; + computeCursorState(model: ITextModel, helper: ICursorStateComputerData): Selection; } /** - * Options for a model decoration. + * A model for the diff editor. */ - 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; + export interface IDiffEditorModel { /** - * If set, the decoration will be rendered on the line number. + * Original model. */ - lineNumberClassName?: string | null; + original: ITextModel; /** - * 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. + * Modified model. */ - firstLineDecorationClassName?: string | null; + modified: ITextModel; + } + + export interface IDiffEditorViewModel extends IDisposable { + readonly model: IDiffEditorModel; + waitForDiff(): Promise; + } + + /** + * An event describing that an editor has had its model reset (i.e. `editor.setModel()`). + */ + export interface IModelChangedEvent { /** - * If set, the decoration will be rendered in the margin (covering its full width) with this CSS class name. + * The `uri` of the previous model or null. */ - marginClassName?: string | null; + readonly oldModelUrl: Uri | 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. + * The `uri` of the new model or null. */ - inlineClassName?: string | null; - /** - * If there is an `inlineClassName` which affects letter spacing. - */ - inlineClassNameAffectsLetterSpacing?: boolean; + readonly newModelUrl: Uri | null; + } + + export interface IContentSizeChangedEvent { + readonly contentWidth: number; + readonly contentHeight: number; + readonly contentWidthChanged: boolean; + readonly contentHeightChanged: boolean; + } + + /** + * @internal + */ + export interface ITriggerEditorOperationEvent { + source: string | null | undefined; + handlerId: string; + payload: any; + } + + export interface INewScrollPosition { + scrollLeft?: number; + scrollTop?: number; + } + + export interface IEditorAction { + readonly id: string; + readonly label: string; + readonly alias: string; + readonly metadata: ICommandMetadata | undefined; + isSupported(): boolean; + run(args?: unknown): Promise; + } + + export type IEditorModel = ITextModel | IDiffEditorModel | IDiffEditorViewModel; + + /** + * A (serializable) state of the cursors. + */ + export interface ICursorState { + inSelectionMode: boolean; + selectionStart: IPosition; + position: IPosition; + } + + /** + * A (serializable) state of the view. + */ + export interface IViewState { + /** written by previous versions */ + scrollTop?: number; + /** written by previous versions */ + scrollTopWithoutViewZones?: number; + scrollLeft: number; + firstPosition: IPosition; + firstPositionDeltaTop: number; + } + + /** + * A (serializable) state of the code editor. + */ + export interface ICodeEditorViewState { + cursorState: ICursorState[]; + viewState: IViewState; + contributionsState: { + [id: string]: any; + }; + } + + /** + * (Serializable) View state for the diff editor. + */ + export interface IDiffEditorViewState { + original: ICodeEditorViewState | null; + modified: ICodeEditorViewState | null; + modelState?: unknown; + } + + /** + * An editor view state. + */ + export type IEditorViewState = ICodeEditorViewState | IDiffEditorViewState; + + export enum ScrollType { + Smooth = 0, + Immediate = 1 + } + + /** + * An editor. + */ + export interface IEditor { /** - * If set, the decoration will be rendered before the text with this CSS class name. + * An event emitted when the editor has been disposed. + * @event */ - beforeContentClassName?: string | null; + onDidDispose(listener: () => void): IDisposable; /** - * If set, the decoration will be rendered after the text with this CSS class name. + * Dispose the editor. */ - afterContentClassName?: string | null; + dispose(): void; /** - * If set, text will be injected in the view after the range. + * Get a unique id for this editor instance. */ - after?: InjectedTextOptions | null; + getId(): string; /** - * If set, text will be injected in the view before the range. + * Get the editor type. Please see `EditorType`. + * This is to avoid an instanceof check */ - before?: InjectedTextOptions | null; - } - - /** - * Configures text that is injected into the view without changing the underlying document. - */ - export interface InjectedTextOptions { + getEditorType(): string; /** - * Sets the text to inject. Must be a single line. + * Update the editor's options after the editor has been created. */ - readonly content: string; + updateOptions(newOptions: IEditorOptions): void; /** - * If set, the decoration will be rendered inline with the text with this CSS class name. + * Indicates that the editor becomes visible. + * @internal */ - readonly inlineClassName?: string | null; + onVisible(): void; /** - * If there is an `inlineClassName` which affects letter spacing. + * Indicates that the editor becomes hidden. + * @internal */ - readonly inlineClassNameAffectsLetterSpacing?: boolean; + onHide(): void; /** - * This field allows to attach data to this injected text. - * The data can be read when injected texts at a given position are queried. + * Instructs the editor to remeasure its container. This method should + * be called when the container of the editor gets resized. + * + * If a dimension is passed in, the passed in value will be used. + * + * By default, this will also render the editor immediately. + * If you prefer to delay rendering to the next animation frame, use postponeRendering == true. */ - readonly attachedData?: unknown; + layout(dimension?: IDimension, postponeRendering?: boolean): void; /** - * 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 { + * Brings browser focus to the editor text + */ + focus(): void; /** - * Range that this decoration covers. + * Returns true if the text inside this editor is focused (i.e. cursor is blinking). */ - range: IRange; + hasTextFocus(): boolean; /** - * Options associated with this decoration. + * Returns all actions associated with this editor. */ - options: IModelDecorationOptions; - } - - /** - * A decoration in the model. - */ - export interface IModelDecoration { + getSupportedActions(): IEditorAction[]; /** - * Identifier for a decoration. + * Saves current view state of the editor in a serializable object. */ - readonly id: string; + saveViewState(): IEditorViewState | null; /** - * Identifier for a decoration's owner. + * Restores the view state of the editor from a serializable object generated by `saveViewState`. */ - readonly ownerId: number; + restoreViewState(state: IEditorViewState | null): void; /** - * Range that this decoration covers. + * Given a position, returns a column number that takes tab-widths into account. */ - readonly range: Range; + getVisibleColumnFromPosition(position: IPosition): number; /** - * Options associated with this decoration. + * Given a position, returns a column number that takes tab-widths into account. + * @internal */ - readonly options: IModelDecorationOptions; - } - - /** - * End of line character preference. - */ - export enum EndOfLinePreference { + getStatusbarColumn(position: IPosition): number; /** - * Use the end of line character identified in the text buffer. + * Returns the primary position of the cursor. */ - TextDefined = 0, + getPosition(): Position | null; /** - * Use line feed (\n) as the end of line character. + * Set the primary position of the cursor. This will remove any secondary cursors. + * @param position New primary cursor's position + * @param source Source of the call that caused the position */ - LF = 1, + setPosition(position: IPosition, source?: string): void; /** - * Use carriage return and line feed (\r\n) as the end of line character. + * Scroll vertically as necessary and reveal a line. */ - CRLF = 2 - } - - /** - * The default end of line to use when instantiating models. - */ - export enum DefaultEndOfLine { + revealLine(lineNumber: number, scrollType?: ScrollType): void; /** - * Use line feed (\n) as the end of line character. + * Scroll vertically as necessary and reveal a line centered vertically. */ - LF = 1, + revealLineInCenter(lineNumber: number, scrollType?: ScrollType): void; /** - * Use carriage return and line feed (\r\n) as the end of line character. + * Scroll vertically as necessary and reveal a line centered vertically only if it lies outside the viewport. */ - CRLF = 2 - } - - /** - * End of line character preference. - */ - export enum EndOfLineSequence { + revealLineInCenterIfOutsideViewport(lineNumber: number, scrollType?: ScrollType): void; /** - * Use line feed (\n) as the end of line character. + * Scroll vertically as necessary and reveal a line close to the top of the viewport, + * optimized for viewing a code definition. */ - LF = 0, + revealLineNearTop(lineNumber: number, scrollType?: ScrollType): void; /** - * Use carriage return and line feed (\r\n) as the end of line character. + * Scroll vertically or horizontally as necessary and reveal a position. */ - CRLF = 1 - } - - /** - * A single edit operation, that has an identifier. - */ - export interface IIdentifiedSingleEditOperation extends ISingleEditOperation { - } - - export interface IValidEditOperation { + revealPosition(position: IPosition, scrollType?: ScrollType): void; /** - * The range to replace. This can be empty to emulate a simple insert. + * Scroll vertically or horizontally as necessary and reveal a position centered vertically. */ - range: Range; + revealPositionInCenter(position: IPosition, scrollType?: ScrollType): void; /** - * The text to replace with. This can be empty to emulate a simple delete. + * Scroll vertically or horizontally as necessary and reveal a position centered vertically only if it lies outside the viewport. */ - text: string; - } - - /** - * A callback that can compute the cursor state after applying a series of edit operations. - */ - export interface ICursorStateComputer { + revealPositionInCenterIfOutsideViewport(position: IPosition, scrollType?: ScrollType): void; /** - * A callback that can compute the resulting cursors state after some edit operations have been executed. + * Scroll vertically or horizontally as necessary and reveal a position close to the top of the viewport, + * optimized for viewing a code definition. */ - (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 { + revealPositionNearTop(position: IPosition, scrollType?: ScrollType): void; /** - * Gets the resource associated with this editor model. + * Returns the primary selection of the editor. */ - readonly uri: Uri; + getSelection(): Selection | null; /** - * A unique identifier associated with this model. + * Returns all the selections of the editor. */ - readonly id: string; + getSelections(): Selection[] | null; /** - * Get the resolved options for this model. + * Set the primary selection of the editor. This will remove any secondary cursors. + * @param selection The new selection + * @param source Source of the call that caused the selection */ - getOptions(): TextModelResolvedOptions; + setSelection(selection: IRange, source?: string): void; /** - * Get the current version id of the model. - * Anytime a change happens to the model (even undo/redo), - * the version id is incremented. + * Set the primary selection of the editor. This will remove any secondary cursors. + * @param selection The new selection + * @param source Source of the call that caused the selection */ - getVersionId(): number; + setSelection(selection: Range, source?: string): void; /** - * 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. + * Set the primary selection of the editor. This will remove any secondary cursors. + * @param selection The new selection + * @param source Source of the call that caused the selection */ - getAlternativeVersionId(): number; + setSelection(selection: ISelection, source?: string): void; /** - * Replace the entire text buffer value contained in this model. + * Set the primary selection of the editor. This will remove any secondary cursors. + * @param selection The new selection + * @param source Source of the call that caused the selection */ - setValue(newValue: string | ITextSnapshot): void; + setSelection(selection: Selection, source?: string): 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. + * Set the selections for all the cursors of the editor. + * Cursors will be removed or added, as necessary. + * @param selections The new selection + * @param source Source of the call that caused the selection */ - getValue(eol?: EndOfLinePreference, preserveBOM?: boolean): string; + setSelections(selections: readonly ISelection[], source?: string): void; /** - * 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). + * Scroll vertically as necessary and reveal lines. */ - createSnapshot(preserveBOM?: boolean): ITextSnapshot; + revealLines(startLineNumber: number, endLineNumber: number, scrollType?: ScrollType): void; /** - * Get the length of the text stored in this model. + * Scroll vertically as necessary and reveal lines centered vertically. */ - getValueLength(eol?: EndOfLinePreference, preserveBOM?: boolean): number; + revealLinesInCenter(lineNumber: number, endLineNumber: number, scrollType?: ScrollType): void; /** - * 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. + * Scroll vertically as necessary and reveal lines centered vertically only if it lies outside the viewport. */ - getValueInRange(range: IRange, eol?: EndOfLinePreference): string; + revealLinesInCenterIfOutsideViewport(lineNumber: number, endLineNumber: number, scrollType?: ScrollType): void; /** - * Get the length of text in a certain range. - * @param range The range describing what text length to get. - * @return The text length. + * Scroll vertically as necessary and reveal lines close to the top of the viewport, + * optimized for viewing a code definition. */ - getValueLengthInRange(range: IRange, eol?: EndOfLinePreference): number; + revealLinesNearTop(lineNumber: number, endLineNumber: number, scrollType?: ScrollType): void; /** - * Get the character count of text in a certain range. - * @param range The range describing what text length to get. + * Scroll vertically or horizontally as necessary and reveal a range. */ - getCharacterCountInRange(range: IRange, eol?: EndOfLinePreference): number; + revealRange(range: IRange, scrollType?: ScrollType): void; /** - * Get the number of lines in the model. + * Scroll vertically or horizontally as necessary and reveal a range centered vertically. */ - getLineCount(): number; + revealRangeInCenter(range: IRange, scrollType?: ScrollType): void; /** - * Get the text for a certain line. + * Scroll vertically or horizontally as necessary and reveal a range at the top of the viewport. */ - getLineContent(lineNumber: number): string; + revealRangeAtTop(range: IRange, scrollType?: ScrollType): void; /** - * Get the text length for a certain line. + * Scroll vertically or horizontally as necessary and reveal a range centered vertically only if it lies outside the viewport. */ - getLineLength(lineNumber: number): number; + revealRangeInCenterIfOutsideViewport(range: IRange, scrollType?: ScrollType): void; /** - * Get the text for all lines. + * Scroll vertically or horizontally as necessary and reveal a range close to the top of the viewport, + * optimized for viewing a code definition. */ - getLinesContent(): string[]; + revealRangeNearTop(range: IRange, scrollType?: ScrollType): void; /** - * Get the end of line sequence predominantly used in the text buffer. - * @return EOL char sequence (e.g.: '\n' or '\r\n'). + * Scroll vertically or horizontally as necessary and reveal a range close to the top of the viewport, + * optimized for viewing a code definition. Only if it lies outside the viewport. */ - getEOL(): string; + revealRangeNearTopIfOutsideViewport(range: IRange, scrollType?: ScrollType): void; /** - * Get the end of line sequence predominantly used in the text buffer. + * Directly trigger a handler or an editor action. + * @param source The source of the call. + * @param handlerId The id of the handler or the id of a contribution. + * @param payload Extra data to be sent to the handler. */ - getEndOfLineSequence(): EndOfLineSequence; + trigger(source: string | null | undefined, handlerId: string, payload: any): void; /** - * Get the minimum legal column for line at `lineNumber` + * Gets the current model attached to this editor. */ - getLineMinColumn(lineNumber: number): number; + getModel(): IEditorModel | null; /** - * Get the maximum legal column for line at `lineNumber` + * Sets the current model attached to this editor. + * If the previous model was created by the editor via the value key in the options + * literal object, it will be destroyed. Otherwise, if the previous model was set + * via setModel, or the model key in the options literal object, the previous model + * will not be destroyed. + * It is safe to call setModel(null) to simply detach the current model from the editor. */ - getLineMaxColumn(lineNumber: number): number; + setModel(model: IEditorModel | null): void; /** - * Returns the column before the first non whitespace character for line at `lineNumber`. - * Returns 0 if line is empty or contains only whitespace. + * Create a collection of decorations. All decorations added through this collection + * will get the ownerId of the editor (meaning they will not show up in other editors). + * These decorations will be automatically cleared when the editor's model changes. */ - getLineFirstNonWhitespaceColumn(lineNumber: number): number; + createDecorationsCollection(decorations?: IModelDeltaDecoration[]): IEditorDecorationsCollection; /** - * Returns the column after the last non whitespace character for line at `lineNumber`. - * Returns 0 if line is empty or contains only whitespace. + * 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 */ - getLineLastNonWhitespaceColumn(lineNumber: number): number; + changeDecorations(callback: (changeAccessor: IModelDecorationsChangeAccessor) => any): any; + } + + /** + * A diff editor. + * + * @internal + */ + export interface IDiffEditor extends IEditor { /** - * Create a valid position. + * Type the getModel() of IEditor. */ - validatePosition(position: IPosition): Position; + getModel(): IDiffEditorModel | null; /** - * 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. + * Get the `original` editor. */ - modifyPosition(position: IPosition, offset: number): Position; + getOriginalEditor(): IEditor; /** - * Create a valid range. + * Get the `modified` editor. */ - validateRange(range: IRange): Range; + getModifiedEditor(): IEditor; + } + + /** + * @internal + */ + export interface ICompositeCodeEditor { /** - * 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. + * An event that signals that the active editor has changed */ - getOffsetAt(position: IPosition): number; + readonly onDidChangeActiveEditor: IEvent; /** - * Converts a zero-based offset to a position. - * - * @param offset A zero-based offset. - * @return A valid [position](#Position). + * The active code editor iff any */ - getPositionAt(offset: number): Position; + readonly activeCodeEditor: IEditor | undefined; + } + + /** + * A collection of decorations + */ + export interface IEditorDecorationsCollection { /** - * Get a range covering the entire model. + * An event emitted when decorations change in the editor, + * but the change is not caused by us setting or clearing the collection. */ - getFullModelRange(): Range; + onDidChange: IEvent; /** - * Returns if the model was disposed or not. + * Get the decorations count. */ - isDisposed(): boolean; + length: number; /** - * 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. + * Get the range for a decoration. */ - findMatches(searchString: string, searchOnlyEditableRange: boolean, isRegex: boolean, matchCase: boolean, wordSeparators: string | null, captureMatches: boolean, limitResultCount?: number): FindMatch[]; + getRange(index: number): Range | null; /** - * 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. + * Get all ranges for decorations. */ - findMatches(searchString: string, searchScope: IRange | IRange[], isRegex: boolean, matchCase: boolean, wordSeparators: string | null, captureMatches: boolean, limitResultCount?: number): FindMatch[]; + getRanges(): Range[]; /** - * 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. + * Determine if a decoration is in this collection. */ - findNextMatch(searchString: string, searchStart: IPosition, isRegex: boolean, matchCase: boolean, wordSeparators: string | null, captureMatches: boolean): FindMatch | null; + has(decoration: IModelDecoration): boolean; /** - * 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. + * Replace all previous decorations with `newDecorations`. */ - findPreviousMatch(searchString: string, searchStart: IPosition, isRegex: boolean, matchCase: boolean, wordSeparators: string | null, captureMatches: boolean): FindMatch | null; + set(newDecorations: readonly IModelDeltaDecoration[]): string[]; /** - * Get the language associated with this model. + * Append `newDecorations` to this collection. */ - getLanguageId(): string; + append(newDecorations: readonly IModelDeltaDecoration[]): 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. + * Remove all previous decorations. */ - getWordAtPosition(position: IPosition): IWordAtPosition | null; + clear(): void; + } + + /** + * An editor contribution that gets created every time a new editor gets created and gets disposed when the editor gets disposed. + */ + export interface IEditorContribution { /** - * 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. + * Dispose this contribution. */ - getWordUntilPosition(position: IPosition): IWordAtPosition; + dispose(): 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. - * @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. + * Store view state. */ - deltaDecorations(oldDecorations: string[], newDecorations: IModelDeltaDecoration[], ownerId?: number): string[]; + saveViewState?(): any; /** - * Get the options associated with a decoration. - * @param id The decoration id. - * @return The decoration options or null if the decoration was not found. + * Restore view state. */ - getDecorationOptions(id: string): IModelDecorationOptions | null; + 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 { /** - * Get the range associated with a decoration. - * @param id The decoration id. - * @return The decoration range or null if the decoration was not found. + * Dispose this contribution. */ - getDecorationRange(id: string): Range | null; + 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; /** - * 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 + * @deprecated */ - getLineDecorations(lineNumber: number, ownerId?: number, filterOutValidation?: boolean): IModelDecoration[]; + before?: IContentDecorationRenderOptions; /** - * 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 + * @deprecated */ - getLinesDecorations(startLineNumber: number, endLineNumber: number, ownerId?: number, filterOutValidation?: boolean): IModelDecoration[]; + after?: IContentDecorationRenderOptions; /** - * 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 + * @deprecated */ - getDecorationsInRange(range: IRange, ownerId?: number, filterOutValidation?: boolean, onlyMinimapDecorations?: boolean, onlyMarginDecorations?: boolean): IModelDecoration[]; + beforeInjectedText?: IContentDecorationRenderOptions & { + affectsLetterSpacing?: boolean; + }; /** - * 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). + * @deprecated */ - getAllDecorations(ownerId?: number, filterOutValidation?: boolean): IModelDecoration[]; + 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 { /** - * Gets all decorations that render in the glyph margin as an array. - * @param ownerId If set, it will ignore decorations belonging to other owners. + * @deprecated */ - getAllMarginDecorations(ownerId?: number): IModelDecoration[]; + before?: IContentDecorationRenderOptions; /** - * 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). + * @deprecated */ - getOverviewRulerDecorations(ownerId?: number, filterOutValidation?: boolean): IModelDecoration[]; + 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`. + */ + export const EditorType: { + ICodeEditor: string; + 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; + } + + /** + * An event describing that the current language associated with a model has changed. + */ + export interface IModelLanguageChangedEvent { /** - * Gets all the decorations that contain injected text. - * @param ownerId If set, it will ignore decorations belonging to other owners. + * Previous language */ - getInjectedTextDecorations(ownerId?: number): IModelDecoration[]; + readonly oldLanguage: string; /** - * Normalize a string containing whitespace according to indentation rules (converts to spaces or to tabs). + * New language */ - normalizeIndentation(str: string): string; + readonly newLanguage: string; /** - * Change the options of this model. + * Source of the call that caused the event. */ - updateOptions(newOpts: ITextModelUpdateOptions): void; + readonly source: string; + } + + /** + * An event describing that the language configuration associated with a model has changed. + */ + export interface IModelLanguageConfigurationChangedEvent { + } + + export interface IModelContentChange { /** - * Detect the indentation options for this model from its content. + * The range that got replaced. */ - detectIndentation(defaultInsertSpaces: boolean, defaultTabSize: number): void; + readonly range: IRange; /** - * Close the current undo-redo element. - * This offers a way to create an undo/redo stop point. + * The offset of the range that got replaced. */ - pushStackElement(): void; + readonly rangeOffset: number; /** - * Open the current undo-redo element. - * This offers a way to remove the current undo/redo stop point. + * The length of the range that got replaced. */ - popStackElement(): void; + readonly rangeLength: number; /** - * 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`. + * The new text for the range. */ - pushEditOperations(beforeCursorState: Selection[] | null, editOperations: IIdentifiedSingleEditOperation[], cursorStateComputer: ICursorStateComputer): Selection[] | null; + readonly text: string; + } + + /** + * An event describing a change in the text of a model. + */ + export interface IModelContentChangedEvent { /** - * Change the end of line sequence. This is the preferred way of - * changing the eol sequence. This will land on the undo stack. + * The changes are ordered from the end of the document to the beginning, so they should be safe to apply in sequence. */ - pushEOL(eol: EndOfLineSequence): void; + readonly changes: IModelContentChange[]; /** - * 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. + * The (new) end-of-line character. */ - applyEdits(operations: IIdentifiedSingleEditOperation[]): void; - applyEdits(operations: IIdentifiedSingleEditOperation[], computeUndoEdits: false): void; - applyEdits(operations: IIdentifiedSingleEditOperation[], computeUndoEdits: true): IValidEditOperation[]; + readonly eol: string; /** - * 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. + * The new version id the model has transitioned to. */ - setEOL(eol: EndOfLineSequence): void; + readonly versionId: number; /** - * An event emitted when the contents of the model have changed. - * @event + * Flag that indicates that this event was generated while undoing. */ - onDidChangeContent(listener: (e: IModelContentChangedEvent) => void): IDisposable; + readonly isUndoing: boolean; /** - * An event emitted when decorations of the model have changed. - * @event + * Flag that indicates that this event was generated while redoing. */ - readonly onDidChangeDecorations: IEvent; + readonly isRedoing: boolean; /** - * 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 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. + * Flag that indicates that all decorations were lost with this edit. + * The model has been reset to a new value. */ - dispose(): void; + readonly isFlush: boolean; /** - * Returns if this model is attached to an editor or not. + * Flag that indicates that this event describes an eol change. */ - isAttachedToEditor(): boolean; + readonly isEolChange: boolean; } - 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 + /** + * An event describing that model decorations have changed. + */ + export interface IModelDecorationsChangedEvent { + readonly affectsMinimap: boolean; + readonly affectsOverviewRuler: boolean; + readonly affectsGlyphMargin: boolean; + readonly affectsLineNumber: boolean; } /** - * A change + * An event describing that some ranges of lines have been tokenized (their tokens have changed). + * @internal */ - export interface IChange { - readonly originalStartLineNumber: number; - readonly originalEndLineNumber: number; - readonly modifiedStartLineNumber: number; - readonly modifiedEndLineNumber: number; + 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; + readonly insertSpaces: boolean; + readonly trimAutoWhitespace: boolean; } /** - * A character level change. + * Configuration options for auto closing quotes and brackets */ - export interface ICharChange extends IChange { - readonly originalStartColumn: number; - readonly originalEndColumn: number; - readonly modifiedStartColumn: number; - readonly modifiedEndColumn: number; - } + export type EditorAutoClosingStrategy = 'always' | 'languageDefined' | 'beforeWhitespace' | 'never'; /** - * A line change + * Configuration options for auto wrapping quotes and brackets */ - export interface ILineChange extends IChange { - readonly charChanges: ICharChange[] | undefined; - } - export interface IDimension { - width: number; - height: number; + export type EditorAutoSurroundStrategy = 'languageDefined' | 'quotes' | 'brackets' | 'never'; + + /** + * Configuration options for typing over closing quotes or brackets + */ + export type EditorAutoClosingEditStrategy = 'always' | 'auto' | 'never'; + + /** + * Configuration options for auto indentation in the editor + */ + export enum EditorAutoIndentStrategy { + None = 0, + Keep = 1, + Brackets = 2, + Advanced = 3, + Full = 4 } /** - * A builder and helper for edit operations for a command. + * Configuration options for the editor. */ - export interface IEditOperationBuilder { + export interface IEditorOptions { /** - * Add a new edit operation (a replace operation). - * @param range The range to replace (delete). May be empty to represent a simple insert. - * @param text The text to replace with. May be null to represent a simple delete. + * This editor is used inside a diff editor. */ - addEditOperation(range: IRange, text: string | null, forceMoveMarkers?: boolean): void; + inDiffEditor?: boolean; /** - * Add a new edit operation (a replace operation). - * The inverse edits will be accessible in `ICursorStateComputerData.getInverseEditOperations()` - * @param range The range to replace (delete). May be empty to represent a simple insert. - * @param text The text to replace with. May be null to represent a simple delete. + * The aria label for the editor's textarea (when it is focused). */ - addTrackedEditOperation(range: IRange, text: string | null, forceMoveMarkers?: boolean): void; + ariaLabel?: string; /** - * Track `selection` when applying edit operations. - * A best effort will be made to not grow/expand the selection. - * An empty selection will clamp to a nearby character. - * @param selection The selection to track. - * @param trackPreviousOnEmpty If set, and the selection is empty, indicates whether the selection - * should clamp to the previous or the next character. - * @return A unique identifier. + * Whether the aria-required attribute should be set on the editors textarea. */ - trackSelection(selection: Selection, trackPreviousOnEmpty?: boolean): string; - } - - /** - * A helper for computing cursor state after a command. - */ - export interface ICursorStateComputerData { + ariaRequired?: boolean; /** - * Get the inverse edit operations of the added edit operations. + * Control whether a screen reader announces inline suggestion content immediately. */ - getInverseEditOperations(): IValidEditOperation[]; + screenReaderAnnounceInlineSuggestion?: boolean; /** - * Get a previously tracked selection. - * @param id The unique identifier returned by `trackSelection`. - * @return The selection. + * The `tabindex` property of the editor's textarea */ - getTrackedSelection(id: string): Selection; - } - - /** - * A command that modifies text / cursor state on a model. - */ - export interface ICommand { + tabIndex?: number; /** - * Get the edit operations needed to execute this command. - * @param model The model the command will execute on. - * @param builder A helper to collect the needed edit operations and to track selections. + * Render vertical lines at the specified columns. + * Defaults to empty array. */ - getEditOperations(model: ITextModel, builder: IEditOperationBuilder): void; + rulers?: (number | IRulerOption)[]; /** - * Compute the cursor state after the edit operations were applied. - * @param model The model the command has executed on. - * @param helper A helper to get inverse edit operations and to get previously tracked selections. - * @return The cursor state after the command executed. + * Locales used for segmenting lines into words when doing word related navigations or operations. + * + * Specify the BCP 47 language tag of the word you wish to recognize (e.g., ja, zh-CN, zh-Hant-TW, etc.). + * Defaults to empty array */ - computeCursorState(model: ITextModel, helper: ICursorStateComputerData): Selection; - } - - /** - * A model for the diff editor. - */ - export interface IDiffEditorModel { + wordSegmenterLocales?: string | string[]; /** - * Original model. + * A string containing the word separators used when doing word navigation. + * Defaults to `~!@#$%^&*()-=+[{]}\\|;:\'",.<>/? */ - original: ITextModel; + wordSeparators?: string; /** - * Modified model. + * Enable Linux primary clipboard. + * Defaults to true. */ - modified: ITextModel; - } - - export interface IDiffEditorViewModel extends IDisposable { - readonly model: IDiffEditorModel; - waitForDiff(): Promise; - } - - /** - * An event describing that an editor has had its model reset (i.e. `editor.setModel()`). - */ - export interface IModelChangedEvent { + selectionClipboard?: boolean; /** - * The `uri` of the previous model or null. + * Control the rendering of line numbers. + * If it is a function, it will be invoked when rendering a line number and the return value will be rendered. + * Otherwise, if it is a truthy, line numbers will be rendered normally (equivalent of using an identity function). + * Otherwise, line numbers will not be rendered. + * Defaults to `on`. */ - readonly oldModelUrl: Uri | null; + lineNumbers?: LineNumbersType; /** - * The `uri` of the new model or null. + * Controls the minimal number of visible leading and trailing lines surrounding the cursor. + * Defaults to 0. + */ + cursorSurroundingLines?: number; + /** + * Controls when `cursorSurroundingLines` should be enforced + * Defaults to `default`, `cursorSurroundingLines` is not enforced when cursor position is changed + * by mouse. + */ + cursorSurroundingLinesStyle?: 'default' | 'all'; + /** + * Render last line number when the file ends with a newline. + * Defaults to 'on' for Windows and macOS and 'dimmed' for Linux. + */ + renderFinalNewline?: 'on' | 'off' | 'dimmed'; + /** + * Remove unusual line terminators like LINE SEPARATOR (LS), PARAGRAPH SEPARATOR (PS). + * Defaults to 'prompt'. */ - readonly newModelUrl: Uri | null; - } - - export interface IContentSizeChangedEvent { - readonly contentWidth: number; - readonly contentHeight: number; - readonly contentWidthChanged: boolean; - readonly contentHeightChanged: boolean; - } - - export interface INewScrollPosition { - scrollLeft?: number; - scrollTop?: number; - } - - export interface IEditorAction { - readonly id: string; - readonly label: string; - readonly alias: string; - readonly metadata: ICommandMetadata | undefined; - isSupported(): boolean; - run(args?: unknown): Promise; - } - - export type IEditorModel = ITextModel | IDiffEditorModel | IDiffEditorViewModel; - - /** - * A (serializable) state of the cursors. - */ - export interface ICursorState { - inSelectionMode: boolean; - selectionStart: IPosition; - position: IPosition; - } - - /** - * A (serializable) state of the view. - */ - export interface IViewState { - /** written by previous versions */ - scrollTop?: number; - /** written by previous versions */ - scrollTopWithoutViewZones?: number; - scrollLeft: number; - firstPosition: IPosition; - firstPositionDeltaTop: number; - } - - /** - * A (serializable) state of the code editor. - */ - export interface ICodeEditorViewState { - cursorState: ICursorState[]; - viewState: IViewState; - contributionsState: { - [id: string]: any; - }; - } - - /** - * (Serializable) View state for the diff editor. - */ - export interface IDiffEditorViewState { - original: ICodeEditorViewState | null; - modified: ICodeEditorViewState | null; - modelState?: unknown; - } - - /** - * An editor view state. - */ - export type IEditorViewState = ICodeEditorViewState | IDiffEditorViewState; - - export enum ScrollType { - Smooth = 0, - Immediate = 1 - } - - /** - * An editor. - */ - export interface IEditor { + unusualLineTerminators?: 'auto' | 'off' | 'prompt'; /** - * An event emitted when the editor has been disposed. - * @event + * Should the corresponding line be selected when clicking on the line number? + * Defaults to true. */ - onDidDispose(listener: () => void): IDisposable; + selectOnLineNumbers?: boolean; /** - * Dispose the editor. + * Control the width of line numbers, by reserving horizontal space for rendering at least an amount of digits. + * Defaults to 5. */ - dispose(): void; + lineNumbersMinChars?: number; /** - * Get a unique id for this editor instance. + * Enable the rendering of the glyph margin. + * Defaults to true in vscode and to false in monaco-editor. */ - getId(): string; + glyphMargin?: boolean; /** - * Get the editor type. Please see `EditorType`. - * This is to avoid an instanceof check + * The width reserved for line decorations (in px). + * Line decorations are placed between line numbers and the editor content. + * You can pass in a string in the format floating point followed by "ch". e.g. 1.3ch. + * Defaults to 10. */ - getEditorType(): string; + lineDecorationsWidth?: number | string; /** - * Update the editor's options after the editor has been created. + * When revealing the cursor, a virtual padding (px) is added to the cursor, turning it into a rectangle. + * This virtual padding ensures that the cursor gets revealed before hitting the edge of the viewport. + * Defaults to 30 (px). */ - updateOptions(newOptions: IEditorOptions): void; + revealHorizontalRightPadding?: number; /** - * Instructs the editor to remeasure its container. This method should - * be called when the container of the editor gets resized. - * - * If a dimension is passed in, the passed in value will be used. - * - * By default, this will also render the editor immediately. - * If you prefer to delay rendering to the next animation frame, use postponeRendering == true. + * Render the editor selection with rounded borders. + * Defaults to true. */ - layout(dimension?: IDimension, postponeRendering?: boolean): void; + roundedSelection?: boolean; /** - * Brings browser focus to the editor text + * Class name to be added to the editor. */ - focus(): void; + extraEditorClassName?: string; /** - * Returns true if the text inside this editor is focused (i.e. cursor is blinking). + * Should the editor be read only. See also `domReadOnly`. + * Defaults to false. */ - hasTextFocus(): boolean; + readOnly?: boolean; /** - * Returns all actions associated with this editor. + * The message to display when the editor is readonly. */ - getSupportedActions(): IEditorAction[]; + readOnlyMessage?: IMarkdownString; /** - * Saves current view state of the editor in a serializable object. + * Should the textarea used for input use the DOM `readonly` attribute. + * Defaults to false. */ - saveViewState(): IEditorViewState | null; + domReadOnly?: boolean; /** - * Restores the view state of the editor from a serializable object generated by `saveViewState`. + * Enable linked editing. + * Defaults to false. */ - restoreViewState(state: IEditorViewState | null): void; + linkedEditing?: boolean; /** - * Given a position, returns a column number that takes tab-widths into account. + * deprecated, use linkedEditing instead */ - getVisibleColumnFromPosition(position: IPosition): number; + renameOnType?: boolean; /** - * Returns the primary position of the cursor. + * Should the editor render validation decorations. + * Defaults to editable. */ - getPosition(): Position | null; + renderValidationDecorations?: 'editable' | 'on' | 'off'; /** - * Set the primary position of the cursor. This will remove any secondary cursors. - * @param position New primary cursor's position - * @param source Source of the call that caused the position + * Control the behavior and rendering of the scrollbars. */ - setPosition(position: IPosition, source?: string): void; + scrollbar?: IEditorScrollbarOptions; /** - * Scroll vertically as necessary and reveal a line. + * Control the behavior of sticky scroll options */ - revealLine(lineNumber: number, scrollType?: ScrollType): void; + stickyScroll?: IEditorStickyScrollOptions; /** - * Scroll vertically as necessary and reveal a line centered vertically. + * Control the behavior and rendering of the minimap. */ - revealLineInCenter(lineNumber: number, scrollType?: ScrollType): void; + minimap?: IEditorMinimapOptions; /** - * Scroll vertically as necessary and reveal a line centered vertically only if it lies outside the viewport. + * Control the behavior of the find widget. */ - revealLineInCenterIfOutsideViewport(lineNumber: number, scrollType?: ScrollType): void; + find?: IEditorFindOptions; /** - * Scroll vertically as necessary and reveal a line close to the top of the viewport, - * optimized for viewing a code definition. + * Display overflow widgets as `fixed`. + * Defaults to `false`. */ - revealLineNearTop(lineNumber: number, scrollType?: ScrollType): void; + fixedOverflowWidgets?: boolean; /** - * Scroll vertically or horizontally as necessary and reveal a position. + * The number of vertical lanes the overview ruler should render. + * Defaults to 3. */ - revealPosition(position: IPosition, scrollType?: ScrollType): void; + overviewRulerLanes?: number; /** - * Scroll vertically or horizontally as necessary and reveal a position centered vertically. + * Controls if a border should be drawn around the overview ruler. + * Defaults to `true`. */ - revealPositionInCenter(position: IPosition, scrollType?: ScrollType): void; + overviewRulerBorder?: boolean; /** - * Scroll vertically or horizontally as necessary and reveal a position centered vertically only if it lies outside the viewport. + * Control the cursor animation style, possible values are 'blink', 'smooth', 'phase', 'expand' and 'solid'. + * Defaults to 'blink'. */ - revealPositionInCenterIfOutsideViewport(position: IPosition, scrollType?: ScrollType): void; + cursorBlinking?: 'blink' | 'smooth' | 'phase' | 'expand' | 'solid'; /** - * Scroll vertically or horizontally as necessary and reveal a position close to the top of the viewport, - * optimized for viewing a code definition. + * Zoom the font in the editor when using the mouse wheel in combination with holding Ctrl. + * Defaults to false. */ - revealPositionNearTop(position: IPosition, scrollType?: ScrollType): void; + mouseWheelZoom?: boolean; /** - * Returns the primary selection of the editor. + * Control the mouse pointer style, either 'text' or 'default' or 'copy' + * Defaults to 'text' */ - getSelection(): Selection | null; + mouseStyle?: 'text' | 'default' | 'copy'; /** - * Returns all the selections of the editor. + * Enable smooth caret animation. + * Defaults to 'off'. */ - getSelections(): Selection[] | null; + cursorSmoothCaretAnimation?: 'off' | 'explicit' | 'on'; /** - * Set the primary selection of the editor. This will remove any secondary cursors. - * @param selection The new selection - * @param source Source of the call that caused the selection + * Control the cursor style, either 'block' or 'line'. + * Defaults to 'line'. */ - setSelection(selection: IRange, source?: string): void; + cursorStyle?: 'line' | 'block' | 'underline' | 'line-thin' | 'block-outline' | 'underline-thin'; /** - * Set the primary selection of the editor. This will remove any secondary cursors. - * @param selection The new selection - * @param source Source of the call that caused the selection + * Control the width of the cursor when cursorStyle is set to 'line' */ - setSelection(selection: Range, source?: string): void; + cursorWidth?: number; /** - * Set the primary selection of the editor. This will remove any secondary cursors. - * @param selection The new selection - * @param source Source of the call that caused the selection + * Enable font ligatures. + * Defaults to false. */ - setSelection(selection: ISelection, source?: string): void; + fontLigatures?: boolean | string; /** - * Set the primary selection of the editor. This will remove any secondary cursors. - * @param selection The new selection - * @param source Source of the call that caused the selection + * Enable font variations. + * Defaults to false. */ - setSelection(selection: Selection, source?: string): void; + fontVariations?: boolean | string; /** - * Set the selections for all the cursors of the editor. - * Cursors will be removed or added, as necessary. - * @param selections The new selection - * @param source Source of the call that caused the selection + * Controls whether to use default color decorations or not using the default document color provider */ - setSelections(selections: readonly ISelection[], source?: string): void; + defaultColorDecorators?: boolean; /** - * Scroll vertically as necessary and reveal lines. + * Disable the use of `transform: translate3d(0px, 0px, 0px)` for the editor margin and lines layers. + * The usage of `transform: translate3d(0px, 0px, 0px)` acts as a hint for browsers to create an extra layer. + * Defaults to false. */ - revealLines(startLineNumber: number, endLineNumber: number, scrollType?: ScrollType): void; + disableLayerHinting?: boolean; /** - * Scroll vertically as necessary and reveal lines centered vertically. + * Disable the optimizations for monospace fonts. + * Defaults to false. */ - revealLinesInCenter(lineNumber: number, endLineNumber: number, scrollType?: ScrollType): void; + disableMonospaceOptimizations?: boolean; /** - * Scroll vertically as necessary and reveal lines centered vertically only if it lies outside the viewport. + * Should the cursor be hidden in the overview ruler. + * Defaults to false. */ - revealLinesInCenterIfOutsideViewport(lineNumber: number, endLineNumber: number, scrollType?: ScrollType): void; + hideCursorInOverviewRuler?: boolean; /** - * Scroll vertically as necessary and reveal lines close to the top of the viewport, - * optimized for viewing a code definition. + * Enable that scrolling can go one screen size after the last line. + * Defaults to true. */ - revealLinesNearTop(lineNumber: number, endLineNumber: number, scrollType?: ScrollType): void; + scrollBeyondLastLine?: boolean; /** - * Scroll vertically or horizontally as necessary and reveal a range. + * Enable that scrolling can go beyond the last column by a number of columns. + * Defaults to 5. */ - revealRange(range: IRange, scrollType?: ScrollType): void; + scrollBeyondLastColumn?: number; /** - * Scroll vertically or horizontally as necessary and reveal a range centered vertically. + * Enable that the editor animates scrolling to a position. + * Defaults to false. */ - revealRangeInCenter(range: IRange, scrollType?: ScrollType): void; + smoothScrolling?: boolean; /** - * Scroll vertically or horizontally as necessary and reveal a range at the top of the viewport. + * Enable that the editor will install a ResizeObserver to check if its container dom node size has changed. + * Defaults to false. */ - revealRangeAtTop(range: IRange, scrollType?: ScrollType): void; + automaticLayout?: boolean; /** - * Scroll vertically or horizontally as necessary and reveal a range centered vertically only if it lies outside the viewport. + * Control the wrapping of the editor. + * When `wordWrap` = "off", the lines will never wrap. + * When `wordWrap` = "on", the lines will wrap at the viewport width. + * When `wordWrap` = "wordWrapColumn", the lines will wrap at `wordWrapColumn`. + * When `wordWrap` = "bounded", the lines will wrap at min(viewport width, wordWrapColumn). + * Defaults to "off". */ - revealRangeInCenterIfOutsideViewport(range: IRange, scrollType?: ScrollType): void; + wordWrap?: 'off' | 'on' | 'wordWrapColumn' | 'bounded'; /** - * Scroll vertically or horizontally as necessary and reveal a range close to the top of the viewport, - * optimized for viewing a code definition. + * Override the `wordWrap` setting. */ - revealRangeNearTop(range: IRange, scrollType?: ScrollType): void; + wordWrapOverride1?: 'off' | 'on' | 'inherit'; /** - * Scroll vertically or horizontally as necessary and reveal a range close to the top of the viewport, - * optimized for viewing a code definition. Only if it lies outside the viewport. + * Override the `wordWrapOverride1` setting. */ - revealRangeNearTopIfOutsideViewport(range: IRange, scrollType?: ScrollType): void; + wordWrapOverride2?: 'off' | 'on' | 'inherit'; /** - * Directly trigger a handler or an editor action. - * @param source The source of the call. - * @param handlerId The id of the handler or the id of a contribution. - * @param payload Extra data to be sent to the handler. + * Control the wrapping of the editor. + * When `wordWrap` = "off", the lines will never wrap. + * When `wordWrap` = "on", the lines will wrap at the viewport width. + * When `wordWrap` = "wordWrapColumn", the lines will wrap at `wordWrapColumn`. + * When `wordWrap` = "bounded", the lines will wrap at min(viewport width, wordWrapColumn). + * Defaults to 80. */ - trigger(source: string | null | undefined, handlerId: string, payload: any): void; + wordWrapColumn?: number; /** - * Gets the current model attached to this editor. + * Control indentation of wrapped lines. Can be: 'none', 'same', 'indent' or 'deepIndent'. + * Defaults to 'same' in vscode and to 'none' in monaco-editor. */ - getModel(): IEditorModel | null; + wrappingIndent?: 'none' | 'same' | 'indent' | 'deepIndent'; /** - * Sets the current model attached to this editor. - * If the previous model was created by the editor via the value key in the options - * literal object, it will be destroyed. Otherwise, if the previous model was set - * via setModel, or the model key in the options literal object, the previous model - * will not be destroyed. - * It is safe to call setModel(null) to simply detach the current model from the editor. + * Controls the wrapping strategy to use. + * Defaults to 'simple'. */ - setModel(model: IEditorModel | null): void; + wrappingStrategy?: 'simple' | 'advanced'; /** - * Create a collection of decorations. All decorations added through this collection - * will get the ownerId of the editor (meaning they will not show up in other editors). - * These decorations will be automatically cleared when the editor's model changes. + * Configure word wrapping characters. A break will be introduced before these characters. */ - createDecorationsCollection(decorations?: IModelDeltaDecoration[]): IEditorDecorationsCollection; - } - - /** - * A collection of decorations - */ - export interface IEditorDecorationsCollection { + wordWrapBreakBeforeCharacters?: string; /** - * An event emitted when decorations change in the editor, - * but the change is not caused by us setting or clearing the collection. + * Configure word wrapping characters. A break will be introduced after these characters. */ - onDidChange: IEvent; + wordWrapBreakAfterCharacters?: string; /** - * Get the decorations count. + * Sets whether line breaks appear wherever the text would otherwise overflow its content box. + * When wordBreak = 'normal', Use the default line break rule. + * When wordBreak = 'keepAll', Word breaks should not be used for Chinese/Japanese/Korean (CJK) text. Non-CJK text behavior is the same as for normal. */ - length: number; + wordBreak?: 'normal' | 'keepAll'; /** - * Get the range for a decoration. + * Performance guard: Stop rendering a line after x characters. + * Defaults to 10000. + * Use -1 to never stop rendering */ - getRange(index: number): Range | null; + stopRenderingLineAfter?: number; /** - * Get all ranges for decorations. + * Configure the editor's hover. */ - getRanges(): Range[]; + hover?: IEditorHoverOptions; /** - * Determine if a decoration is in this collection. + * Enable detecting links and making them clickable. + * Defaults to true. */ - has(decoration: IModelDecoration): boolean; + links?: boolean; /** - * Replace all previous decorations with `newDecorations`. + * Enable inline color decorators and color picker rendering. */ - set(newDecorations: readonly IModelDeltaDecoration[]): string[]; + colorDecorators?: boolean; /** - * Append `newDecorations` to this collection. + * Controls what is the condition to spawn a color picker from a color dectorator */ - append(newDecorations: readonly IModelDeltaDecoration[]): string[]; + colorDecoratorsActivatedOn?: 'clickAndHover' | 'click' | 'hover'; /** - * Remove all previous decorations. + * Controls the max number of color decorators that can be rendered in an editor at once. */ - clear(): void; - } - - /** - * An editor contribution that gets created every time a new editor gets created and gets disposed when the editor gets disposed. - */ - export interface IEditorContribution { + colorDecoratorsLimit?: number; /** - * Dispose this contribution. + * Control the behaviour of comments in the editor. */ - dispose(): void; + comments?: IEditorCommentsOptions; /** - * Store view state. + * Enable custom contextmenu. + * Defaults to true. */ - saveViewState?(): any; + contextmenu?: boolean; /** - * Restore view state. + * A multiplier to be used on the `deltaX` and `deltaY` of mouse wheel scroll events. + * Defaults to 1. */ - restoreViewState?(state: any): void; - } - - /** - * The type of the `IEditor`. - */ - export const EditorType: { - ICodeEditor: string; - IDiffEditor: string; - }; - - /** - * An event describing that the current language associated with a model has changed. - */ - export interface IModelLanguageChangedEvent { + mouseWheelScrollSensitivity?: number; /** - * Previous language + * FastScrolling mulitplier speed when pressing `Alt` + * Defaults to 5. */ - readonly oldLanguage: string; + fastScrollSensitivity?: number; /** - * New language + * Enable that the editor scrolls only the predominant axis. Prevents horizontal drift when scrolling vertically on a trackpad. + * Defaults to true. */ - readonly newLanguage: string; + scrollPredominantAxis?: boolean; /** - * Source of the call that caused the event. + * Enable that the selection with the mouse and keys is doing column selection. + * Defaults to false. */ - readonly source: string; - } - - /** - * An event describing that the language configuration associated with a model has changed. - */ - export interface IModelLanguageConfigurationChangedEvent { - } - - export interface IModelContentChange { + columnSelection?: boolean; /** - * The range that got replaced. + * The modifier to be used to add multiple cursors with the mouse. + * Defaults to 'alt' */ - readonly range: IRange; + multiCursorModifier?: 'ctrlCmd' | 'alt'; /** - * The offset of the range that got replaced. + * Merge overlapping selections. + * Defaults to true */ - readonly rangeOffset: number; + multiCursorMergeOverlapping?: boolean; /** - * The length of the range that got replaced. + * Configure the behaviour when pasting a text with the line count equal to the cursor count. + * Defaults to 'spread'. */ - readonly rangeLength: number; + multiCursorPaste?: 'spread' | 'full'; /** - * The new text for the range. + * Controls the max number of text cursors that can be in an active editor at once. */ - readonly text: string; - } - - /** - * An event describing a change in the text of a model. - */ - export interface IModelContentChangedEvent { + multiCursorLimit?: number; /** - * The changes are ordered from the end of the document to the beginning, so they should be safe to apply in sequence. + * Configure the editor's accessibility support. + * Defaults to 'auto'. It is best to leave this to 'auto'. */ - readonly changes: IModelContentChange[]; + accessibilitySupport?: 'auto' | 'off' | 'on'; /** - * The (new) end-of-line character. + * Controls the number of lines in the editor that can be read out by a screen reader */ - readonly eol: string; + accessibilityPageSize?: number; /** - * The new version id the model has transitioned to. + * Suggest options. */ - readonly versionId: number; + suggest?: ISuggestOptions; + inlineSuggest?: IInlineSuggestOptions; /** - * Flag that indicates that this event was generated while undoing. + * Smart select options. */ - readonly isUndoing: boolean; + smartSelect?: ISmartSelectOptions; /** - * Flag that indicates that this event was generated while redoing. + * */ - readonly isRedoing: boolean; + gotoLocation?: IGotoLocationOptions; /** - * Flag that indicates that all decorations were lost with this edit. - * The model has been reset to a new value. + * Enable quick suggestions (shadow suggestions) + * Defaults to true. */ - readonly isFlush: boolean; + quickSuggestions?: boolean | IQuickSuggestionsOptions; /** - * Flag that indicates that this event describes an eol change. + * Quick suggestions show delay (in ms) + * Defaults to 10 (ms) */ - readonly isEolChange: boolean; - } - - /** - * An event describing that model decorations have changed. - */ - export interface IModelDecorationsChangedEvent { - readonly affectsMinimap: boolean; - readonly affectsOverviewRuler: boolean; - readonly affectsGlyphMargin: boolean; - readonly affectsLineNumber: boolean; - } - - export interface IModelOptionsChangedEvent { - readonly tabSize: boolean; - readonly indentSize: boolean; - readonly insertSpaces: boolean; - readonly trimAutoWhitespace: boolean; - } - - /** - * Describes the reason the cursor has changed its position. - */ - export enum CursorChangeReason { + quickSuggestionsDelay?: number; /** - * Unknown or not set. + * Controls the spacing around the editor. */ - NotSet = 0, + padding?: IEditorPaddingOptions; /** - * A `model.setValue()` was called. + * Parameter hint options. */ - ContentFlush = 1, + parameterHints?: IEditorParameterHintOptions; /** - * The `model` has been changed outside of this cursor and the cursor recovers its position from associated markers. + * Options for auto closing brackets. + * Defaults to language defined behavior. */ - RecoverFromMarkers = 2, + autoClosingBrackets?: EditorAutoClosingStrategy; /** - * There was an explicit user gesture. + * Options for auto closing comments. + * Defaults to language defined behavior. */ - Explicit = 3, + autoClosingComments?: EditorAutoClosingStrategy; /** - * There was a Paste. - */ - Paste = 4, - /** - * There was an Undo. + * Options for auto closing quotes. + * Defaults to language defined behavior. */ - Undo = 5, + autoClosingQuotes?: EditorAutoClosingStrategy; /** - * There was a Redo. + * Options for pressing backspace near quotes or bracket pairs. */ - Redo = 6 - } - - /** - * An event describing that the cursor position has changed. - */ - export interface ICursorPositionChangedEvent { + autoClosingDelete?: EditorAutoClosingEditStrategy; /** - * Primary cursor's position. + * Options for typing over closing quotes or brackets. */ - readonly position: Position; + autoClosingOvertype?: EditorAutoClosingEditStrategy; /** - * Secondary cursors' position. + * Options for auto surrounding. + * Defaults to always allowing auto surrounding. */ - readonly secondaryPositions: Position[]; + autoSurround?: EditorAutoSurroundStrategy; /** - * Reason. + * Controls whether the editor should automatically adjust the indentation when users type, paste, move or indent lines. + * Defaults to advanced. */ - readonly reason: CursorChangeReason; + autoIndent?: 'none' | 'keep' | 'brackets' | 'advanced' | 'full'; /** - * Source of the call that caused the event. + * Emulate selection behaviour of tab characters when using spaces for indentation. + * This means selection will stick to tab stops. */ - readonly source: string; - } - - /** - * An event describing that the cursor selection has changed. - */ - export interface ICursorSelectionChangedEvent { + stickyTabStops?: boolean; /** - * The primary selection. + * Enable format on type. + * Defaults to false. */ - readonly selection: Selection; + formatOnType?: boolean; /** - * The secondary selections. + * Enable format on paste. + * Defaults to false. */ - readonly secondarySelections: Selection[]; + formatOnPaste?: boolean; /** - * The model version id. + * Controls if the editor should allow to move selections via drag and drop. + * Defaults to false. */ - readonly modelVersionId: number; + dragAndDrop?: boolean; /** - * The old selections. + * Enable the suggestion box to pop-up on trigger characters. + * Defaults to true. */ - readonly oldSelections: Selection[] | null; + suggestOnTriggerCharacters?: boolean; /** - * The model version id the that `oldSelections` refer to. + * Accept suggestions on ENTER. + * Defaults to 'on'. */ - readonly oldModelVersionId: number; + acceptSuggestionOnEnter?: 'on' | 'smart' | 'off'; /** - * Source of the call that caused the event. + * Accept suggestions on provider defined characters. + * Defaults to true. */ - readonly source: string; + acceptSuggestionOnCommitCharacter?: boolean; /** - * Reason. + * Enable snippet suggestions. Default to 'true'. */ - readonly reason: CursorChangeReason; - } - - export enum AccessibilitySupport { + snippetSuggestions?: 'top' | 'bottom' | 'inline' | 'none'; /** - * This should be the browser case where it is not known if a screen reader is attached or no. + * Copying without a selection copies the current line. */ - Unknown = 0, - Disabled = 1, - Enabled = 2 - } - - /** - * Configuration options for auto closing quotes and brackets - */ - export type EditorAutoClosingStrategy = 'always' | 'languageDefined' | 'beforeWhitespace' | 'never'; - - /** - * Configuration options for auto wrapping quotes and brackets - */ - export type EditorAutoSurroundStrategy = 'languageDefined' | 'quotes' | 'brackets' | 'never'; - - /** - * Configuration options for typing over closing quotes or brackets - */ - export type EditorAutoClosingEditStrategy = 'always' | 'auto' | 'never'; - - /** - * Configuration options for auto indentation in the editor - */ - export enum EditorAutoIndentStrategy { - None = 0, - Keep = 1, - Brackets = 2, - Advanced = 3, - Full = 4 - } - - /** - * Configuration options for the editor. - */ - export interface IEditorOptions { + emptySelectionClipboard?: boolean; /** - * This editor is used inside a diff editor. + * Syntax highlighting is copied. */ - inDiffEditor?: boolean; + copyWithSyntaxHighlighting?: boolean; /** - * The aria label for the editor's textarea (when it is focused). + * The history mode for suggestions. */ - ariaLabel?: string; + suggestSelection?: 'first' | 'recentlyUsed' | 'recentlyUsedByPrefix'; /** - * Whether the aria-required attribute should be set on the editors textarea. + * The font size for the suggest widget. + * Defaults to the editor font size. */ - ariaRequired?: boolean; + suggestFontSize?: number; /** - * Control whether a screen reader announces inline suggestion content immediately. + * The line height for the suggest widget. + * Defaults to the editor line height. */ - screenReaderAnnounceInlineSuggestion?: boolean; + suggestLineHeight?: number; /** - * The `tabindex` property of the editor's textarea + * Enable tab completion. */ - tabIndex?: number; + tabCompletion?: 'on' | 'off' | 'onlySnippets'; /** - * Render vertical lines at the specified columns. - * Defaults to empty array. + * Enable selection highlight. + * Defaults to true. */ - rulers?: (number | IRulerOption)[]; + selectionHighlight?: boolean; /** - * Locales used for segmenting lines into words when doing word related navigations or operations. - * - * Specify the BCP 47 language tag of the word you wish to recognize (e.g., ja, zh-CN, zh-Hant-TW, etc.). - * Defaults to empty array + * Enable semantic occurrences highlight. + * Defaults to 'singleFile'. + * 'off' disables occurrence highlighting + * 'singleFile' triggers occurrence highlighting in the current document + * 'multiFile' triggers occurrence highlighting across valid open documents */ - wordSegmenterLocales?: string | string[]; + occurrencesHighlight?: 'off' | 'singleFile' | 'multiFile'; /** - * A string containing the word separators used when doing word navigation. - * Defaults to `~!@#$%^&*()-=+[{]}\\|;:\'",.<>/? + * Controls delay for occurrences highlighting + * Defaults to 250. + * Minimum value is 0 + * Maximum value is 2000 */ - wordSeparators?: string; + occurrencesHighlightDelay?: number; /** - * Enable Linux primary clipboard. + * Show code lens * Defaults to true. */ - selectionClipboard?: boolean; - /** - * Control the rendering of line numbers. - * If it is a function, it will be invoked when rendering a line number and the return value will be rendered. - * Otherwise, if it is a truthy, line numbers will be rendered normally (equivalent of using an identity function). - * Otherwise, line numbers will not be rendered. - * Defaults to `on`. - */ - lineNumbers?: LineNumbersType; - /** - * Controls the minimal number of visible leading and trailing lines surrounding the cursor. - * Defaults to 0. - */ - cursorSurroundingLines?: number; - /** - * Controls when `cursorSurroundingLines` should be enforced - * Defaults to `default`, `cursorSurroundingLines` is not enforced when cursor position is changed - * by mouse. - */ - cursorSurroundingLinesStyle?: 'default' | 'all'; - /** - * Render last line number when the file ends with a newline. - * Defaults to 'on' for Windows and macOS and 'dimmed' for Linux. - */ - renderFinalNewline?: 'on' | 'off' | 'dimmed'; + codeLens?: boolean; /** - * Remove unusual line terminators like LINE SEPARATOR (LS), PARAGRAPH SEPARATOR (PS). - * Defaults to 'prompt'. + * Code lens font family. Defaults to editor font family. */ - unusualLineTerminators?: 'auto' | 'off' | 'prompt'; + codeLensFontFamily?: string; /** - * Should the corresponding line be selected when clicking on the line number? - * Defaults to true. + * Code lens font size. Default to 90% of the editor font size */ - selectOnLineNumbers?: boolean; + codeLensFontSize?: number; /** - * Control the width of line numbers, by reserving horizontal space for rendering at least an amount of digits. - * Defaults to 5. + * Control the behavior and rendering of the code action lightbulb. */ - lineNumbersMinChars?: number; + lightbulb?: IEditorLightbulbOptions; /** - * Enable the rendering of the glyph margin. - * Defaults to true in vscode and to false in monaco-editor. + * Timeout for running code actions on save. */ - glyphMargin?: boolean; + codeActionsOnSaveTimeout?: number; /** - * The width reserved for line decorations (in px). - * Line decorations are placed between line numbers and the editor content. - * You can pass in a string in the format floating point followed by "ch". e.g. 1.3ch. - * Defaults to 10. + * Enable code folding. + * Defaults to true. */ - lineDecorationsWidth?: number | string; + folding?: boolean; /** - * When revealing the cursor, a virtual padding (px) is added to the cursor, turning it into a rectangle. - * This virtual padding ensures that the cursor gets revealed before hitting the edge of the viewport. - * Defaults to 30 (px). + * Selects the folding strategy. 'auto' uses the strategies contributed for the current document, 'indentation' uses the indentation based folding strategy. + * Defaults to 'auto'. */ - revealHorizontalRightPadding?: number; + foldingStrategy?: 'auto' | 'indentation'; /** - * Render the editor selection with rounded borders. + * Enable highlight for folded regions. * Defaults to true. */ - roundedSelection?: boolean; + foldingHighlight?: boolean; /** - * Class name to be added to the editor. + * Auto fold imports folding regions. + * Defaults to true. */ - extraEditorClassName?: string; + foldingImportsByDefault?: boolean; /** - * Should the editor be read only. See also `domReadOnly`. - * Defaults to false. + * Maximum number of foldable regions. + * Defaults to 5000. */ - readOnly?: boolean; + foldingMaximumRegions?: number; /** - * The message to display when the editor is readonly. + * Controls whether the fold actions in the gutter stay always visible or hide unless the mouse is over the gutter. + * Defaults to 'mouseover'. */ - readOnlyMessage?: IMarkdownString; + showFoldingControls?: 'always' | 'never' | 'mouseover'; /** - * Should the textarea used for input use the DOM `readonly` attribute. + * Controls whether clicking on the empty content after a folded line will unfold the line. * Defaults to false. */ - domReadOnly?: boolean; + unfoldOnClickAfterEndOfLine?: boolean; /** - * Enable linked editing. - * Defaults to false. + * Enable highlighting of matching brackets. + * Defaults to 'always'. */ - linkedEditing?: boolean; + matchBrackets?: 'never' | 'near' | 'always'; /** - * deprecated, use linkedEditing instead + * Enable experimental rendering using WebGPU. + * Defaults to 'off'. */ - renameOnType?: boolean; + experimentalGpuAcceleration?: 'on' | 'off'; /** - * Should the editor render validation decorations. - * Defaults to editable. + * Enable experimental whitespace rendering. + * Defaults to 'svg'. */ - renderValidationDecorations?: 'editable' | 'on' | 'off'; + experimentalWhitespaceRendering?: 'svg' | 'font' | 'off'; /** - * Control the behavior and rendering of the scrollbars. + * Enable rendering of whitespace. + * Defaults to 'selection'. */ - scrollbar?: IEditorScrollbarOptions; + renderWhitespace?: 'none' | 'boundary' | 'selection' | 'trailing' | 'all'; /** - * Control the behavior of sticky scroll options + * Enable rendering of control characters. + * Defaults to true. */ - stickyScroll?: IEditorStickyScrollOptions; + renderControlCharacters?: boolean; /** - * Control the behavior and rendering of the minimap. + * Enable rendering of current line highlight. + * Defaults to all. */ - minimap?: IEditorMinimapOptions; + renderLineHighlight?: 'none' | 'gutter' | 'line' | 'all'; /** - * Control the behavior of the find widget. + * Control if the current line highlight should be rendered only the editor is focused. + * Defaults to false. */ - find?: IEditorFindOptions; + renderLineHighlightOnlyWhenFocus?: boolean; /** - * Display overflow widgets as `fixed`. - * Defaults to `false`. + * Inserting and deleting whitespace follows tab stops. */ - fixedOverflowWidgets?: boolean; + useTabStops?: boolean; /** - * The number of vertical lanes the overview ruler should render. - * Defaults to 3. + * The font family */ - overviewRulerLanes?: number; + fontFamily?: string; /** - * Controls if a border should be drawn around the overview ruler. - * Defaults to `true`. + * The font weight */ - overviewRulerBorder?: boolean; + fontWeight?: string; /** - * Control the cursor animation style, possible values are 'blink', 'smooth', 'phase', 'expand' and 'solid'. - * Defaults to 'blink'. + * The font size */ - cursorBlinking?: 'blink' | 'smooth' | 'phase' | 'expand' | 'solid'; + fontSize?: number; /** - * Zoom the font in the editor when using the mouse wheel in combination with holding Ctrl. - * Defaults to false. + * The line height */ - mouseWheelZoom?: boolean; + lineHeight?: number; /** - * Control the mouse pointer style, either 'text' or 'default' or 'copy' - * Defaults to 'text' + * The letter spacing */ - mouseStyle?: 'text' | 'default' | 'copy'; + letterSpacing?: number; /** - * Enable smooth caret animation. - * Defaults to 'off'. + * Controls fading out of unused variables. */ - cursorSmoothCaretAnimation?: 'off' | 'explicit' | 'on'; + showUnused?: boolean; /** - * Control the cursor style, either 'block' or 'line'. - * Defaults to 'line'. + * Controls whether to focus the inline editor in the peek widget by default. + * Defaults to false. */ - cursorStyle?: 'line' | 'block' | 'underline' | 'line-thin' | 'block-outline' | 'underline-thin'; + peekWidgetDefaultFocus?: 'tree' | 'editor'; /** - * Control the width of the cursor when cursorStyle is set to 'line' - */ - cursorWidth?: number; + * Sets a placeholder for the editor. + * If set, the placeholder is shown if the editor is empty. + */ + placeholder?: string | undefined; /** - * Enable font ligatures. + * Controls whether the definition link opens element in the peek widget. * Defaults to false. */ - fontLigatures?: boolean | string; + definitionLinkOpensInPeek?: boolean; /** - * Enable font variations. - * Defaults to false. + * Controls strikethrough deprecated variables. */ - fontVariations?: boolean | string; + showDeprecated?: boolean; /** - * Controls whether to use default color decorations or not using the default document color provider + * Controls whether suggestions allow matches in the middle of the word instead of only at the beginning */ - defaultColorDecorators?: boolean; + matchOnWordStartOnly?: boolean; /** - * Disable the use of `transform: translate3d(0px, 0px, 0px)` for the editor margin and lines layers. - * The usage of `transform: translate3d(0px, 0px, 0px)` acts as a hint for browsers to create an extra layer. - * Defaults to false. + * Control the behavior and rendering of the inline hints. */ - disableLayerHinting?: boolean; + inlayHints?: IEditorInlayHintsOptions; /** - * Disable the optimizations for monospace fonts. - * Defaults to false. + * Control if the editor should use shadow DOM. */ - disableMonospaceOptimizations?: boolean; + useShadowDOM?: boolean; /** - * Should the cursor be hidden in the overview ruler. - * Defaults to false. - */ - hideCursorInOverviewRuler?: boolean; + * Controls the behavior of editor guides. + */ + guides?: IGuidesOptions; /** - * Enable that scrolling can go one screen size after the last line. - * Defaults to true. + * Controls the behavior of the unicode highlight feature + * (by default, ambiguous and invisible characters are highlighted). */ - scrollBeyondLastLine?: boolean; + unicodeHighlight?: IUnicodeHighlightOptions; /** - * Enable that scrolling can go beyond the last column by a number of columns. - * Defaults to 5. - */ - scrollBeyondLastColumn?: number; + * Configures bracket pair colorization (disabled by default). + */ + bracketPairColorization?: IBracketPairColorizationOptions; /** - * Enable that the editor animates scrolling to a position. - * Defaults to false. + * Controls dropping into the editor from an external source. + * + * When enabled, this shows a preview of the drop location and triggers an `onDropIntoEditor` event. */ - smoothScrolling?: boolean; + dropIntoEditor?: IDropIntoEditorOptions; /** - * Enable that the editor will install a ResizeObserver to check if its container dom node size has changed. - * Defaults to false. + * Sets whether the new experimental edit context should be used instead of the text area. */ - automaticLayout?: boolean; + experimentalEditContextEnabled?: boolean; /** - * Control the wrapping of the editor. - * When `wordWrap` = "off", the lines will never wrap. - * When `wordWrap` = "on", the lines will wrap at the viewport width. - * When `wordWrap` = "wordWrapColumn", the lines will wrap at `wordWrapColumn`. - * When `wordWrap` = "bounded", the lines will wrap at min(viewport width, wordWrapColumn). - * Defaults to "off". + * Controls support for changing how content is pasted into the editor. */ - wordWrap?: 'off' | 'on' | 'wordWrapColumn' | 'bounded'; + pasteAs?: IPasteAsOptions; /** - * Override the `wordWrap` setting. + * Controls whether the editor / terminal receives tabs or defers them to the workbench for navigation. */ - wordWrapOverride1?: 'off' | 'on' | 'inherit'; + tabFocusMode?: boolean; /** - * Override the `wordWrapOverride1` setting. + * Controls whether the accessibility hint should be provided to screen reader users when an inline completion is shown. */ - wordWrapOverride2?: 'off' | 'on' | 'inherit'; + inlineCompletionsAccessibilityVerbose?: boolean; + } + + export interface IDiffEditorBaseOptions { /** - * Control the wrapping of the editor. - * When `wordWrap` = "off", the lines will never wrap. - * When `wordWrap` = "on", the lines will wrap at the viewport width. - * When `wordWrap` = "wordWrapColumn", the lines will wrap at `wordWrapColumn`. - * When `wordWrap` = "bounded", the lines will wrap at min(viewport width, wordWrapColumn). - * Defaults to 80. + * Allow the user to resize the diff editor split view. + * Defaults to true. */ - wordWrapColumn?: number; + enableSplitViewResizing?: boolean; /** - * Control indentation of wrapped lines. Can be: 'none', 'same', 'indent' or 'deepIndent'. - * Defaults to 'same' in vscode and to 'none' in monaco-editor. + * The default ratio when rendering side-by-side editors. + * Must be a number between 0 and 1, min sizes apply. + * Defaults to 0.5 */ - wrappingIndent?: 'none' | 'same' | 'indent' | 'deepIndent'; + splitViewDefaultRatio?: number; /** - * Controls the wrapping strategy to use. - * Defaults to 'simple'. + * Render the differences in two side-by-side editors. + * Defaults to true. */ - wrappingStrategy?: 'simple' | 'advanced'; + renderSideBySide?: boolean; /** - * Configure word wrapping characters. A break will be introduced before these characters. + * When `renderSideBySide` is enabled, `useInlineViewWhenSpaceIsLimited` is set, + * and the diff editor has a width less than `renderSideBySideInlineBreakpoint`, the inline view is used. */ - wordWrapBreakBeforeCharacters?: string; + renderSideBySideInlineBreakpoint?: number | undefined; /** - * Configure word wrapping characters. A break will be introduced after these characters. + * When `renderSideBySide` is enabled, `useInlineViewWhenSpaceIsLimited` is set, + * and the diff editor has a width less than `renderSideBySideInlineBreakpoint`, the inline view is used. */ - wordWrapBreakAfterCharacters?: string; + useInlineViewWhenSpaceIsLimited?: boolean; /** - * Sets whether line breaks appear wherever the text would otherwise overflow its content box. - * When wordBreak = 'normal', Use the default line break rule. - * When wordBreak = 'keepAll', Word breaks should not be used for Chinese/Japanese/Korean (CJK) text. Non-CJK text behavior is the same as for normal. - */ - wordBreak?: 'normal' | 'keepAll'; + * If set, the diff editor is optimized for small views. + * Defaults to `false`. + */ + compactMode?: boolean; /** - * Performance guard: Stop rendering a line after x characters. - * Defaults to 10000. - * Use -1 to never stop rendering + * Timeout in milliseconds after which diff computation is cancelled. + * Defaults to 5000. */ - stopRenderingLineAfter?: number; + maxComputationTime?: number; /** - * Configure the editor's hover. + * Maximum supported file size in MB. + * Defaults to 50. */ - hover?: IEditorHoverOptions; + maxFileSize?: number; /** - * Enable detecting links and making them clickable. + * Compute the diff by ignoring leading/trailing whitespace * Defaults to true. */ - links?: boolean; + ignoreTrimWhitespace?: boolean; /** - * Enable inline color decorators and color picker rendering. + * Render +/- indicators for added/deleted changes. + * Defaults to true. */ - colorDecorators?: boolean; + renderIndicators?: boolean; /** - * Controls what is the condition to spawn a color picker from a color dectorator + * Shows icons in the glyph margin to revert changes. + * Default to true. */ - colorDecoratorsActivatedOn?: 'clickAndHover' | 'click' | 'hover'; + renderMarginRevertIcon?: boolean; /** - * Controls the max number of color decorators that can be rendered in an editor at once. - */ - colorDecoratorsLimit?: number; + * Indicates if the gutter menu should be rendered. + */ + renderGutterMenu?: boolean; /** - * Control the behaviour of comments in the editor. + * Original model should be editable? + * Defaults to false. */ - comments?: IEditorCommentsOptions; + originalEditable?: boolean; /** - * Enable custom contextmenu. - * Defaults to true. + * Should the diff editor enable code lens? + * Defaults to false. */ - contextmenu?: boolean; + diffCodeLens?: boolean; /** - * A multiplier to be used on the `deltaX` and `deltaY` of mouse wheel scroll events. - * Defaults to 1. + * Is the diff editor should render overview ruler + * Defaults to true */ - mouseWheelScrollSensitivity?: number; + renderOverviewRuler?: boolean; /** - * FastScrolling mulitplier speed when pressing `Alt` - * Defaults to 5. + * Control the wrapping of the diff editor. */ - fastScrollSensitivity?: number; + diffWordWrap?: 'off' | 'on' | 'inherit'; /** - * Enable that the editor scrolls only the predominant axis. Prevents horizontal drift when scrolling vertically on a trackpad. - * Defaults to true. - */ - scrollPredominantAxis?: boolean; - /** - * Enable that the selection with the mouse and keys is doing column selection. - * Defaults to false. - */ - columnSelection?: boolean; + * Diff Algorithm + */ + diffAlgorithm?: 'legacy' | 'advanced'; /** - * The modifier to be used to add multiple cursors with the mouse. - * Defaults to 'alt' + * Whether the diff editor aria label should be verbose. */ - multiCursorModifier?: 'ctrlCmd' | 'alt'; + accessibilityVerbose?: boolean; + experimental?: { + /** + * Defaults to false. + */ + showMoves?: boolean; + showEmptyDecorations?: boolean; + /** + * Only applies when `renderSideBySide` is set to false. + */ + useTrueInlineView?: boolean; + }; /** - * Merge overlapping selections. - * Defaults to true + * Is the diff editor inside another editor + * Defaults to false */ - multiCursorMergeOverlapping?: boolean; + isInEmbeddedEditor?: boolean; /** - * Configure the behaviour when pasting a text with the line count equal to the cursor count. - * Defaults to 'spread'. + * If the diff editor should only show the difference review mode. */ - multiCursorPaste?: 'spread' | 'full'; + onlyShowAccessibleDiffViewer?: boolean; + hideUnchangedRegions?: { + enabled?: boolean; + revealLineCount?: number; + minimumLineCount?: number; + contextLineCount?: number; + }; + } + + /** + * Configuration options for the diff editor. + */ + export interface IDiffEditorOptions extends IEditorOptions, IDiffEditorBaseOptions { + } + + /** + * An event describing that the configuration of the editor has changed. + */ + export class ConfigurationChangedEvent { + private readonly _values; /** - * Controls the max number of text cursors that can be in an active editor at once. + * @internal */ - multiCursorLimit?: number; + constructor(values: boolean[]); + hasChanged(id: EditorOption): boolean; + } + + /** + * All computed editor options. + */ + export interface IComputedEditorOptions { + 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; /** - * Configure the editor's accessibility support. - * Defaults to 'auto'. It is best to leave this to 'auto'. + * @internal */ - accessibilitySupport?: 'auto' | 'off' | 'on'; + readonly schema: any | { + [path: string]: any; + } | undefined; /** - * Controls the number of lines in the editor that can be read out by a screen reader + * @internal */ - accessibilityPageSize?: number; + validate(input: any): V; /** - * Suggest options. + * @internal */ - suggest?: ISuggestOptions; - inlineSuggest?: IInlineSuggestOptions; + compute(env: IEnvironmentalOptions, options: IComputedEditorOptions, value: V): V; /** - * Smart select options. - */ - smartSelect?: ISmartSelectOptions; + * Might modify `value`. + */ + applyUpdate(value: V | undefined, update: V): ApplyUpdateResult; + } + + export class ApplyUpdateResult { + readonly newValue: T; + readonly didChange: boolean; + constructor(newValue: T, didChange: boolean); + } + + /** + * Configuration options for editor comments + */ + export interface IEditorCommentsOptions { /** - * + * Insert a space after the line comment token and inside the block comments tokens. + * Defaults to true. */ - gotoLocation?: IGotoLocationOptions; + insertSpace?: boolean; /** - * Enable quick suggestions (shadow suggestions) + * Ignore empty lines when inserting line comments. * Defaults to true. */ - quickSuggestions?: boolean | IQuickSuggestionsOptions; + ignoreEmptyLines?: boolean; + } + + /** + * The kind of animation in which the editor's cursor should be rendered. + */ + export enum TextEditorCursorBlinkingStyle { /** - * Quick suggestions show delay (in ms) - * Defaults to 10 (ms) + * Hidden */ - quickSuggestionsDelay?: number; + Hidden = 0, /** - * Controls the spacing around the editor. + * Blinking */ - padding?: IEditorPaddingOptions; + Blink = 1, /** - * Parameter hint options. + * Blinking with smooth fading */ - parameterHints?: IEditorParameterHintOptions; + Smooth = 2, /** - * Options for auto closing brackets. - * Defaults to language defined behavior. + * Blinking with prolonged filled state and smooth fading */ - autoClosingBrackets?: EditorAutoClosingStrategy; + Phase = 3, /** - * Options for auto closing comments. - * Defaults to language defined behavior. + * Expand collapse animation on the y axis */ - autoClosingComments?: EditorAutoClosingStrategy; + Expand = 4, /** - * Options for auto closing quotes. - * Defaults to language defined behavior. + * No-Blinking */ - autoClosingQuotes?: EditorAutoClosingStrategy; + Solid = 5 + } + + /** + * The style in which the editor's cursor should be rendered. + */ + export enum TextEditorCursorStyle { /** - * Options for pressing backspace near quotes or bracket pairs. + * As a vertical line (sitting between two characters). */ - autoClosingDelete?: EditorAutoClosingEditStrategy; + Line = 1, /** - * Options for typing over closing quotes or brackets. + * As a block (sitting on top of a character). */ - autoClosingOvertype?: EditorAutoClosingEditStrategy; + Block = 2, /** - * Options for auto surrounding. - * Defaults to always allowing auto surrounding. + * As a horizontal line (sitting under a character). */ - autoSurround?: EditorAutoSurroundStrategy; + Underline = 3, /** - * Controls whether the editor should automatically adjust the indentation when users type, paste, move or indent lines. - * Defaults to advanced. + * As a thin vertical line (sitting between two characters). */ - autoIndent?: 'none' | 'keep' | 'brackets' | 'advanced' | 'full'; + LineThin = 4, /** - * Emulate selection behaviour of tab characters when using spaces for indentation. - * This means selection will stick to tab stops. + * As an outlined block (sitting on top of a character). */ - stickyTabStops?: boolean; + BlockOutline = 5, /** - * Enable format on type. - * Defaults to false. + * As a thin horizontal line (sitting under a character). */ - formatOnType?: boolean; + UnderlineThin = 6 + } + + /** + * Configuration options for editor find widget + */ + export interface IEditorFindOptions { /** - * Enable format on paste. - * Defaults to false. + * Controls whether the cursor should move to find matches while typing. + */ + cursorMoveOnType?: boolean; + /** + * Controls if we seed search string in the Find Widget with editor selection. */ - formatOnPaste?: boolean; + seedSearchStringFromSelection?: 'never' | 'always' | 'selection'; /** - * Controls if the editor should allow to move selections via drag and drop. - * Defaults to false. + * Controls if Find in Selection flag is turned on in the editor. */ - dragAndDrop?: boolean; + autoFindInSelection?: 'never' | 'always' | 'multiline'; + addExtraSpaceOnTop?: boolean; /** - * Enable the suggestion box to pop-up on trigger characters. - * Defaults to true. + * @internal + * Controls if the Find Widget should read or modify the shared find clipboard on macOS */ - suggestOnTriggerCharacters?: boolean; + globalFindClipboard?: boolean; /** - * Accept suggestions on ENTER. - * Defaults to 'on'. + * Controls whether the search result and diff result automatically restarts from the beginning (or the end) when no further matches can be found */ - acceptSuggestionOnEnter?: 'on' | 'smart' | 'off'; + loop?: boolean; + } + + export type GoToLocationValues = 'peek' | 'gotoAndPeek' | 'goto'; + + /** + * Configuration options for go to location + */ + export interface IGotoLocationOptions { + multiple?: GoToLocationValues; + multipleDefinitions?: GoToLocationValues; + multipleTypeDefinitions?: GoToLocationValues; + multipleDeclarations?: GoToLocationValues; + multipleImplementations?: GoToLocationValues; + multipleReferences?: GoToLocationValues; + multipleTests?: GoToLocationValues; + alternativeDefinitionCommand?: string; + alternativeTypeDefinitionCommand?: string; + alternativeDeclarationCommand?: string; + alternativeImplementationCommand?: string; + alternativeReferenceCommand?: string; + alternativeTestsCommand?: string; + } + + /** + * Configuration options for editor hover + */ + export interface IEditorHoverOptions { /** - * Accept suggestions on provider defined characters. + * Enable the hover. * Defaults to true. */ - acceptSuggestionOnCommitCharacter?: boolean; + enabled?: boolean; /** - * Enable snippet suggestions. Default to 'true'. + * Delay for showing the hover. + * Defaults to 300. */ - snippetSuggestions?: 'top' | 'bottom' | 'inline' | 'none'; + delay?: number; /** - * Copying without a selection copies the current line. + * Is the hover sticky such that it can be clicked and its contents selected? + * Defaults to true. */ - emptySelectionClipboard?: boolean; + sticky?: boolean; /** - * Syntax highlighting is copied. + * Controls how long the hover is visible after you hovered out of it. + * Require sticky setting to be true. */ - copyWithSyntaxHighlighting?: boolean; + hidingDelay?: number; /** - * The history mode for suggestions. - */ - suggestSelection?: 'first' | 'recentlyUsed' | 'recentlyUsedByPrefix'; + * Should the hover be shown above the line if possible? + * Defaults to false. + */ + above?: boolean; + } + + /** + * A description for the overview ruler position. + */ + export interface OverviewRulerPosition { /** - * The font size for the suggest widget. - * Defaults to the editor font size. + * Width of the overview ruler */ - suggestFontSize?: number; + readonly width: number; /** - * The line height for the suggest widget. - * Defaults to the editor line height. + * Height of the overview ruler */ - suggestLineHeight?: number; + readonly height: number; /** - * Enable tab completion. + * Top position for the overview ruler */ - tabCompletion?: 'on' | 'off' | 'onlySnippets'; + readonly top: number; /** - * Enable selection highlight. - * Defaults to true. + * Right position for the overview ruler */ - selectionHighlight?: boolean; + readonly right: number; + } + + export enum RenderMinimap { + None = 0, + Text = 1, + Blocks = 2 + } + + /** + * The internal layout details of the editor. + */ + export interface EditorLayoutInfo { /** - * Enable semantic occurrences highlight. - * Defaults to 'singleFile'. - * 'off' disables occurrence highlighting - * 'singleFile' triggers occurrence highlighting in the current document - * 'multiFile' triggers occurrence highlighting across valid open documents + * Full editor width. */ - occurrencesHighlight?: 'off' | 'singleFile' | 'multiFile'; + readonly width: number; /** - * Controls delay for occurrences highlighting - * Defaults to 250. - * Minimum value is 0 - * Maximum value is 2000 + * Full editor height. */ - occurrencesHighlightDelay?: number; + readonly height: number; /** - * Show code lens - * Defaults to true. + * Left position for the glyph margin. */ - codeLens?: boolean; + readonly glyphMarginLeft: number; /** - * Code lens font family. Defaults to editor font family. + * The width of the glyph margin. */ - codeLensFontFamily?: string; + readonly glyphMarginWidth: number; /** - * Code lens font size. Default to 90% of the editor font size + * The number of decoration lanes to render in the glyph margin. */ - codeLensFontSize?: number; + readonly glyphMarginDecorationLaneCount: number; /** - * Control the behavior and rendering of the code action lightbulb. + * Left position for the line numbers. */ - lightbulb?: IEditorLightbulbOptions; + readonly lineNumbersLeft: number; /** - * Timeout for running code actions on save. + * The width of the line numbers. */ - codeActionsOnSaveTimeout?: number; + readonly lineNumbersWidth: number; /** - * Enable code folding. - * Defaults to true. + * Left position for the line decorations. */ - folding?: boolean; + readonly decorationsLeft: number; /** - * Selects the folding strategy. 'auto' uses the strategies contributed for the current document, 'indentation' uses the indentation based folding strategy. - * Defaults to 'auto'. + * The width of the line decorations. */ - foldingStrategy?: 'auto' | 'indentation'; + readonly decorationsWidth: number; /** - * Enable highlight for folded regions. - * Defaults to true. + * Left position for the content (actual text) */ - foldingHighlight?: boolean; + readonly contentLeft: number; /** - * Auto fold imports folding regions. - * Defaults to true. + * The width of the content (actual text) */ - foldingImportsByDefault?: boolean; + readonly contentWidth: number; /** - * Maximum number of foldable regions. - * Defaults to 5000. + * Layout information for the minimap */ - foldingMaximumRegions?: number; + readonly minimap: EditorMinimapLayoutInfo; /** - * Controls whether the fold actions in the gutter stay always visible or hide unless the mouse is over the gutter. - * Defaults to 'mouseover'. + * The number of columns (of typical characters) fitting on a viewport line. */ - showFoldingControls?: 'always' | 'never' | 'mouseover'; + readonly viewportColumn: number; + readonly isWordWrapMinified: boolean; + readonly isViewportWrapping: boolean; + readonly wrappingColumn: number; /** - * Controls whether clicking on the empty content after a folded line will unfold the line. - * Defaults to false. + * The width of the vertical scrollbar. */ - unfoldOnClickAfterEndOfLine?: boolean; + readonly verticalScrollbarWidth: number; /** - * Enable highlighting of matching brackets. - * Defaults to 'always'. + * The height of the horizontal scrollbar. */ - matchBrackets?: 'never' | 'near' | 'always'; + readonly horizontalScrollbarHeight: number; /** - * Enable experimental rendering using WebGPU. - * Defaults to 'off'. + * The position of the overview ruler. */ - experimentalGpuAcceleration?: 'on' | 'off'; + readonly overviewRuler: OverviewRulerPosition; + } + + /** + * The internal layout details of the editor. + */ + export interface EditorMinimapLayoutInfo { + readonly renderMinimap: RenderMinimap; + readonly minimapLeft: number; + readonly minimapWidth: number; + readonly minimapHeightIsEditorHeight: boolean; + readonly minimapIsSampling: boolean; + readonly minimapScale: number; + readonly minimapLineHeight: number; + readonly minimapCanvasInnerWidth: number; + readonly minimapCanvasInnerHeight: number; + readonly minimapCanvasOuterWidth: number; + 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', + On = 'on' + } + + /** + * Configuration options for editor lightbulb + */ + export interface IEditorLightbulbOptions { /** - * Enable experimental whitespace rendering. - * Defaults to 'svg'. + * Enable the lightbulb code action. + * The three possible values are `off`, `on` and `onCode` and the default is `onCode`. + * `off` disables the code action menu. + * `on` shows the code action menu on code and on empty lines. + * `onCode` shows the code action menu on code only. */ - experimentalWhitespaceRendering?: 'svg' | 'font' | 'off'; + enabled?: ShowLightbulbIconMode; + } + + export interface IEditorStickyScrollOptions { /** - * Enable rendering of whitespace. - * Defaults to 'selection'. + * Enable the sticky scroll */ - renderWhitespace?: 'none' | 'boundary' | 'selection' | 'trailing' | 'all'; + enabled?: boolean; /** - * Enable rendering of control characters. - * Defaults to true. + * Maximum number of sticky lines to show */ - renderControlCharacters?: boolean; + maxLineCount?: number; /** - * Enable rendering of current line highlight. - * Defaults to all. + * Model to choose for sticky scroll by default */ - renderLineHighlight?: 'none' | 'gutter' | 'line' | 'all'; + defaultModel?: 'outlineModel' | 'foldingProviderModel' | 'indentationModel'; /** - * Control if the current line highlight should be rendered only the editor is focused. - * Defaults to false. + * Define whether to scroll sticky scroll with editor horizontal scrollbae */ - renderLineHighlightOnlyWhenFocus?: boolean; + scrollWithEditor?: boolean; + } + + /** + * Configuration options for editor inlayHints + */ + export interface IEditorInlayHintsOptions { /** - * Inserting and deleting whitespace follows tab stops. + * Enable the inline hints. + * Defaults to true. */ - useTabStops?: boolean; + enabled?: 'on' | 'off' | 'offUnlessPressed' | 'onUnlessPressed'; /** - * The font family + * Font size of inline hints. + * Default to 90% of the editor font size. + */ + fontSize?: number; + /** + * Font family of inline hints. + * Defaults to editor font family. */ fontFamily?: string; /** - * The font weight + * Enables the padding around the inlay hint. + * Defaults to false. */ - fontWeight?: string; + padding?: boolean; /** - * The font size + * Maximum length for inlay hints per line + * Set to 0 to have an unlimited length. */ - fontSize?: number; + maximumLength?: number; + } + + /** + * Configuration options for editor minimap + */ + export interface IEditorMinimapOptions { /** - * The line height + * Enable the rendering of the minimap. + * Defaults to true. */ - lineHeight?: number; + enabled?: boolean; /** - * The letter spacing + * Control the rendering of minimap. */ - letterSpacing?: number; + autohide?: boolean; /** - * Controls fading out of unused variables. + * Control the side of the minimap in editor. + * Defaults to 'right'. */ - showUnused?: boolean; + side?: 'right' | 'left'; /** - * Controls whether to focus the inline editor in the peek widget by default. - * Defaults to false. + * Control the minimap rendering mode. + * Defaults to 'actual'. */ - peekWidgetDefaultFocus?: 'tree' | 'editor'; + size?: 'proportional' | 'fill' | 'fit'; /** - * Sets a placeholder for the editor. - * If set, the placeholder is shown if the editor is empty. - */ - placeholder?: string | undefined; - /** - * Controls whether the definition link opens element in the peek widget. - * Defaults to false. - */ - definitionLinkOpensInPeek?: boolean; - /** - * Controls strikethrough deprecated variables. + * Control the rendering of the minimap slider. + * Defaults to 'mouseover'. */ - showDeprecated?: boolean; + showSlider?: 'always' | 'mouseover'; /** - * Controls whether suggestions allow matches in the middle of the word instead of only at the beginning + * Render the actual text on a line (as opposed to color blocks). + * Defaults to true. */ - matchOnWordStartOnly?: boolean; + renderCharacters?: boolean; /** - * Control the behavior and rendering of the inline hints. + * Limit the width of the minimap to render at most a certain number of columns. + * Defaults to 120. */ - inlayHints?: IEditorInlayHintsOptions; + maxColumn?: number; /** - * Control if the editor should use shadow DOM. + * Relative size of the font in the minimap. Defaults to 1. */ - useShadowDOM?: boolean; - /** - * Controls the behavior of editor guides. - */ - guides?: IGuidesOptions; + scale?: number; /** - * Controls the behavior of the unicode highlight feature - * (by default, ambiguous and invisible characters are highlighted). + * Whether to show named regions as section headers. Defaults to true. */ - unicodeHighlight?: IUnicodeHighlightOptions; - /** - * Configures bracket pair colorization (disabled by default). - */ - bracketPairColorization?: IBracketPairColorizationOptions; + showRegionSectionHeaders?: boolean; /** - * Controls dropping into the editor from an external source. - * - * When enabled, this shows a preview of the drop location and triggers an `onDropIntoEditor` event. + * Whether to show MARK: comments as section headers. Defaults to true. */ - dropIntoEditor?: IDropIntoEditorOptions; + showMarkSectionHeaders?: boolean; /** - * Sets whether the new experimental edit context should be used instead of the text area. + * Font size of section headers. Defaults to 9. */ - experimentalEditContextEnabled?: boolean; + sectionHeaderFontSize?: number; /** - * Controls support for changing how content is pasted into the editor. + * Spacing between the section header characters (in CSS px). Defaults to 1. */ - pasteAs?: IPasteAsOptions; + sectionHeaderLetterSpacing?: number; + } + + /** + * Configuration options for editor padding + */ + export interface IEditorPaddingOptions { /** - * Controls whether the editor / terminal receives tabs or defers them to the workbench for navigation. + * Spacing between top edge of editor and first line. */ - tabFocusMode?: boolean; + top?: number; /** - * Controls whether the accessibility hint should be provided to screen reader users when an inline completion is shown. + * Spacing between bottom edge of editor and last line. */ - inlineCompletionsAccessibilityVerbose?: boolean; + bottom?: number; } - export interface IDiffEditorBaseOptions { + /** + * Configuration options for parameter hints + */ + export interface IEditorParameterHintOptions { /** - * Allow the user to resize the diff editor split view. + * Enable parameter hints. * Defaults to true. */ - enableSplitViewResizing?: boolean; + enabled?: boolean; /** - * The default ratio when rendering side-by-side editors. - * Must be a number between 0 and 1, min sizes apply. - * Defaults to 0.5 + * Enable cycling of parameter hints. + * Defaults to false. */ - splitViewDefaultRatio?: number; + cycle?: boolean; + } + + export type QuickSuggestionsValue = 'on' | 'inline' | 'off'; + + /** + * Configuration options for quick suggestions + */ + export interface IQuickSuggestionsOptions { + other?: boolean | QuickSuggestionsValue; + comments?: boolean | QuickSuggestionsValue; + strings?: boolean | QuickSuggestionsValue; + } + + export interface InternalQuickSuggestionsOptions { + readonly other: QuickSuggestionsValue; + readonly comments: QuickSuggestionsValue; + readonly strings: QuickSuggestionsValue; + } + + export type LineNumbersType = 'on' | 'off' | 'relative' | 'interval' | ((lineNumber: number) => string); + + export enum RenderLineNumbersType { + Off = 0, + On = 1, + Relative = 2, + Interval = 3, + Custom = 4 + } + + export interface InternalEditorRenderLineNumbersOptions { + readonly renderType: RenderLineNumbersType; + readonly renderFn: ((lineNumber: number) => string) | null; + } + + export interface IRulerOption { + readonly column: number; + readonly color: string | null; + } + + /** + * Configuration options for editor scrollbars + */ + export interface IEditorScrollbarOptions { /** - * Render the differences in two side-by-side editors. - * Defaults to true. + * The size of arrows (if displayed). + * Defaults to 11. + * **NOTE**: This option cannot be updated using `updateOptions()` */ - renderSideBySide?: boolean; + arrowSize?: number; /** - * When `renderSideBySide` is enabled, `useInlineViewWhenSpaceIsLimited` is set, - * and the diff editor has a width less than `renderSideBySideInlineBreakpoint`, the inline view is used. + * Render vertical scrollbar. + * Defaults to 'auto'. */ - renderSideBySideInlineBreakpoint?: number | undefined; + vertical?: 'auto' | 'visible' | 'hidden'; /** - * When `renderSideBySide` is enabled, `useInlineViewWhenSpaceIsLimited` is set, - * and the diff editor has a width less than `renderSideBySideInlineBreakpoint`, the inline view is used. + * Render horizontal scrollbar. + * Defaults to 'auto'. */ - useInlineViewWhenSpaceIsLimited?: boolean; + horizontal?: 'auto' | 'visible' | 'hidden'; /** - * If set, the diff editor is optimized for small views. - * Defaults to `false`. - */ - compactMode?: boolean; + * Cast horizontal and vertical shadows when the content is scrolled. + * Defaults to true. + * **NOTE**: This option cannot be updated using `updateOptions()` + */ + useShadows?: boolean; /** - * Timeout in milliseconds after which diff computation is cancelled. - * Defaults to 5000. + * Render arrows at the top and bottom of the vertical scrollbar. + * Defaults to false. + * **NOTE**: This option cannot be updated using `updateOptions()` */ - maxComputationTime?: number; + verticalHasArrows?: boolean; /** - * Maximum supported file size in MB. - * Defaults to 50. + * Render arrows at the left and right of the horizontal scrollbar. + * Defaults to false. + * **NOTE**: This option cannot be updated using `updateOptions()` */ - maxFileSize?: number; + horizontalHasArrows?: boolean; /** - * Compute the diff by ignoring leading/trailing whitespace + * Listen to mouse wheel events and react to them by scrolling. * Defaults to true. */ - ignoreTrimWhitespace?: boolean; + handleMouseWheel?: boolean; /** - * Render +/- indicators for added/deleted changes. + * Always consume mouse wheel events (always call preventDefault() and stopPropagation() on the browser events). * Defaults to true. + * **NOTE**: This option cannot be updated using `updateOptions()` */ - renderIndicators?: boolean; + alwaysConsumeMouseWheel?: boolean; /** - * Shows icons in the glyph margin to revert changes. - * Default to true. + * Height in pixels for the horizontal scrollbar. + * Defaults to 10 (px). */ - renderMarginRevertIcon?: boolean; + horizontalScrollbarSize?: number; /** - * Indicates if the gutter menu should be rendered. - */ - renderGutterMenu?: boolean; + * Width in pixels for the vertical scrollbar. + * Defaults to 10 (px). + */ + verticalScrollbarSize?: number; /** - * Original model should be editable? + * Width in pixels for the vertical slider. + * Defaults to `verticalScrollbarSize`. + * **NOTE**: This option cannot be updated using `updateOptions()` + */ + verticalSliderSize?: number; + /** + * Height in pixels for the horizontal slider. + * Defaults to `horizontalScrollbarSize`. + * **NOTE**: This option cannot be updated using `updateOptions()` + */ + horizontalSliderSize?: number; + /** + * Scroll gutter clicks move by page vs jump to position. * Defaults to false. */ - originalEditable?: boolean; + scrollByPage?: boolean; /** - * Should the diff editor enable code lens? + * When set, the horizontal scrollbar will not increase content height. * Defaults to false. */ - diffCodeLens?: boolean; + ignoreHorizontalScrollbarInContentHeight?: boolean; + } + + export interface InternalEditorScrollbarOptions { + readonly arrowSize: number; + readonly vertical: ScrollbarVisibility; + readonly horizontal: ScrollbarVisibility; + readonly useShadows: boolean; + readonly verticalHasArrows: boolean; + readonly horizontalHasArrows: boolean; + readonly handleMouseWheel: boolean; + readonly alwaysConsumeMouseWheel: boolean; + readonly horizontalScrollbarSize: number; + readonly horizontalSliderSize: number; + readonly verticalScrollbarSize: number; + readonly verticalSliderSize: number; + readonly scrollByPage: boolean; + readonly ignoreHorizontalScrollbarInContentHeight: boolean; + } + + export type InUntrustedWorkspace = 'inUntrustedWorkspace'; + + /** + * Configuration options for unicode highlighting. + */ + export interface IUnicodeHighlightOptions { /** - * Is the diff editor should render overview ruler - * Defaults to true + * Controls whether all non-basic ASCII characters are highlighted. Only characters between U+0020 and U+007E, tab, line-feed and carriage-return are considered basic ASCII. */ - renderOverviewRuler?: boolean; + nonBasicASCII?: boolean | InUntrustedWorkspace; /** - * Control the wrapping of the diff editor. + * Controls whether characters that just reserve space or have no width at all are highlighted. */ - diffWordWrap?: 'off' | 'on' | 'inherit'; + invisibleCharacters?: boolean; /** - * Diff Algorithm - */ - diffAlgorithm?: 'legacy' | 'advanced'; + * Controls whether characters are highlighted that can be confused with basic ASCII characters, except those that are common in the current user locale. + */ + ambiguousCharacters?: boolean; /** - * Whether the diff editor aria label should be verbose. + * Controls whether characters in comments should also be subject to unicode highlighting. */ - accessibilityVerbose?: boolean; - experimental?: { - /** - * Defaults to false. - */ - showMoves?: boolean; - showEmptyDecorations?: boolean; - /** - * Only applies when `renderSideBySide` is set to false. - */ - useTrueInlineView?: boolean; - }; + includeComments?: boolean | InUntrustedWorkspace; /** - * Is the diff editor inside another editor - * Defaults to false + * Controls whether characters in strings should also be subject to unicode highlighting. */ - isInEmbeddedEditor?: boolean; + includeStrings?: boolean | InUntrustedWorkspace; /** - * If the diff editor should only show the difference review mode. + * Defines allowed characters that are not being highlighted. */ - onlyShowAccessibleDiffViewer?: boolean; - hideUnchangedRegions?: { - enabled?: boolean; - revealLineCount?: number; - minimumLineCount?: number; - contextLineCount?: number; - }; - } - - /** - * Configuration options for the diff editor. - */ - export interface IDiffEditorOptions extends IEditorOptions, IDiffEditorBaseOptions { - } - - /** - * An event describing that the configuration of the editor has changed. - */ - export class ConfigurationChangedEvent { - hasChanged(id: EditorOption): boolean; - } - - /** - * All computed editor options. - */ - export interface IComputedEditorOptions { - get(id: T): FindComputedEditorOptionValueById; + allowedCharacters?: Record; + /** + * Unicode characters that are common in allowed locales are not being highlighted. + */ + allowedLocales?: Record; } - export interface IEditorOption { - readonly id: K; - readonly name: string; - defaultValue: V; + export interface IInlineSuggestOptions { /** - * Might modify `value`. + * Enable or disable the rendering of automatic inline completions. */ - applyUpdate(value: V | undefined, update: V): ApplyUpdateResult; + enabled?: boolean; + /** + * Configures the mode. + * Use `prefix` to only show ghost text if the text to replace is a prefix of the suggestion text. + * Use `subword` to only show ghost text if the replace text is a subword of the suggestion text. + * Use `subwordSmart` to only show ghost text if the replace text is a subword of the suggestion text, but the subword must start after the cursor position. + * Defaults to `prefix`. + */ + mode?: 'prefix' | 'subword' | 'subwordSmart'; + showToolbar?: 'always' | 'onHover' | 'never'; + syntaxHighlightingEnabled?: boolean; + suppressSuggestions?: boolean; + /** + * Does not clear active inline suggestions when the editor loses focus. + */ + keepOnBlur?: boolean; + /** + * Font family for inline suggestions. + */ + fontFamily?: string | 'default'; + edits?: { + experimental?: { + enabled?: boolean; + }; + }; } - export class ApplyUpdateResult { - readonly newValue: T; - readonly didChange: boolean; - constructor(newValue: T, didChange: boolean); + export interface IBracketPairColorizationOptions { + /** + * Enable or disable bracket pair colorization. + */ + enabled?: boolean; + /** + * Use independent color pool per bracket type. + */ + independentColorPoolPerBracketType?: boolean; } - /** - * Configuration options for editor comments - */ - export interface IEditorCommentsOptions { + export interface IGuidesOptions { /** - * Insert a space after the line comment token and inside the block comments tokens. + * Enable rendering of bracket pair guides. + * Defaults to false. + */ + bracketPairs?: boolean | 'active'; + /** + * Enable rendering of vertical bracket pair guides. + * Defaults to 'active'. + */ + bracketPairsHorizontal?: boolean | 'active'; + /** + * Enable highlighting of the active bracket pair. + * Defaults to true. + */ + highlightActiveBracketPair?: boolean; + /** + * Enable rendering of indent guides. * Defaults to true. */ - insertSpace?: boolean; + indentation?: boolean; /** - * Ignore empty lines when inserting line comments. + * Enable highlighting of the active indent guide. * Defaults to true. */ - ignoreEmptyLines?: boolean; + highlightActiveIndentation?: boolean | 'always'; } /** - * The kind of animation in which the editor's cursor should be rendered. + * Configuration options for editor suggest widget */ - export enum TextEditorCursorBlinkingStyle { + export interface ISuggestOptions { /** - * Hidden + * Overwrite word ends on accept. Default to false. */ - Hidden = 0, + insertMode?: 'insert' | 'replace'; /** - * Blinking + * Enable graceful matching. Defaults to true. */ - Blink = 1, + filterGraceful?: boolean; /** - * Blinking with smooth fading + * Prevent quick suggestions when a snippet is active. Defaults to true. */ - Smooth = 2, + snippetsPreventQuickSuggestions?: boolean; /** - * Blinking with prolonged filled state and smooth fading + * Favors words that appear close to the cursor. */ - Phase = 3, + localityBonus?: boolean; /** - * Expand collapse animation on the y axis + * Enable using global storage for remembering suggestions. */ - Expand = 4, + shareSuggestSelections?: boolean; /** - * No-Blinking + * Select suggestions when triggered via quick suggest or trigger characters */ - Solid = 5 - } - - /** - * The style in which the editor's cursor should be rendered. - */ - export enum TextEditorCursorStyle { + selectionMode?: 'always' | 'never' | 'whenTriggerCharacter' | 'whenQuickSuggestion'; /** - * As a vertical line (sitting between two characters). + * Enable or disable icons in suggestions. Defaults to true. */ - Line = 1, + showIcons?: boolean; /** - * As a block (sitting on top of a character). + * Enable or disable the suggest status bar. */ - Block = 2, + showStatusBar?: boolean; /** - * As a horizontal line (sitting under a character). + * Enable or disable the rendering of the suggestion preview. */ - Underline = 3, + preview?: boolean; /** - * As a thin vertical line (sitting between two characters). - */ - LineThin = 4, + * Configures the mode of the preview. + */ + previewMode?: 'prefix' | 'subword' | 'subwordSmart'; /** - * As an outlined block (sitting on top of a character). + * Show details inline with the label. Defaults to true. */ - BlockOutline = 5, + showInlineDetails?: boolean; /** - * As a thin horizontal line (sitting under a character). + * Show method-suggestions. */ - UnderlineThin = 6 - } - - /** - * Configuration options for editor find widget - */ - export interface IEditorFindOptions { - /** - * Controls whether the cursor should move to find matches while typing. - */ - cursorMoveOnType?: boolean; + showMethods?: boolean; /** - * Controls if we seed search string in the Find Widget with editor selection. + * Show function-suggestions. */ - seedSearchStringFromSelection?: 'never' | 'always' | 'selection'; + showFunctions?: boolean; /** - * Controls if Find in Selection flag is turned on in the editor. + * Show constructor-suggestions. */ - autoFindInSelection?: 'never' | 'always' | 'multiline'; - addExtraSpaceOnTop?: boolean; + showConstructors?: boolean; /** - * Controls whether the search result and diff result automatically restarts from the beginning (or the end) when no further matches can be found + * Show deprecated-suggestions. */ - loop?: boolean; - } - - export type GoToLocationValues = 'peek' | 'gotoAndPeek' | 'goto'; - - /** - * Configuration options for go to location - */ - export interface IGotoLocationOptions { - multiple?: GoToLocationValues; - multipleDefinitions?: GoToLocationValues; - multipleTypeDefinitions?: GoToLocationValues; - multipleDeclarations?: GoToLocationValues; - multipleImplementations?: GoToLocationValues; - multipleReferences?: GoToLocationValues; - multipleTests?: GoToLocationValues; - alternativeDefinitionCommand?: string; - alternativeTypeDefinitionCommand?: string; - alternativeDeclarationCommand?: string; - alternativeImplementationCommand?: string; - alternativeReferenceCommand?: string; - alternativeTestsCommand?: string; - } - - /** - * Configuration options for editor hover - */ - export interface IEditorHoverOptions { + showDeprecated?: boolean; /** - * Enable the hover. - * Defaults to true. + * Controls whether suggestions allow matches in the middle of the word instead of only at the beginning */ - enabled?: boolean; + matchOnWordStartOnly?: boolean; /** - * Delay for showing the hover. - * Defaults to 300. + * Show field-suggestions. */ - delay?: number; + showFields?: boolean; /** - * Is the hover sticky such that it can be clicked and its contents selected? - * Defaults to true. + * Show variable-suggestions. */ - sticky?: boolean; + showVariables?: boolean; /** - * Controls how long the hover is visible after you hovered out of it. - * Require sticky setting to be true. + * Show class-suggestions. */ - hidingDelay?: number; + showClasses?: boolean; /** - * Should the hover be shown above the line if possible? - * Defaults to false. + * Show struct-suggestions. */ - above?: boolean; - } - - /** - * A description for the overview ruler position. - */ - export interface OverviewRulerPosition { + showStructs?: boolean; /** - * Width of the overview ruler + * Show interface-suggestions. */ - readonly width: number; + showInterfaces?: boolean; /** - * Height of the overview ruler + * Show module-suggestions. */ - readonly height: number; + showModules?: boolean; /** - * Top position for the overview ruler + * Show property-suggestions. */ - readonly top: number; + showProperties?: boolean; /** - * Right position for the overview ruler + * Show event-suggestions. */ - readonly right: number; - } - - export enum RenderMinimap { - None = 0, - Text = 1, - Blocks = 2 - } - - /** - * The internal layout details of the editor. - */ - export interface EditorLayoutInfo { + showEvents?: boolean; /** - * Full editor width. + * Show operator-suggestions. */ - readonly width: number; + showOperators?: boolean; /** - * Full editor height. + * Show unit-suggestions. */ - readonly height: number; + showUnits?: boolean; /** - * Left position for the glyph margin. + * Show value-suggestions. */ - readonly glyphMarginLeft: number; + showValues?: boolean; /** - * The width of the glyph margin. + * Show constant-suggestions. */ - readonly glyphMarginWidth: number; + showConstants?: boolean; /** - * The number of decoration lanes to render in the glyph margin. + * Show enum-suggestions. */ - readonly glyphMarginDecorationLaneCount: number; + showEnums?: boolean; /** - * Left position for the line numbers. + * Show enumMember-suggestions. */ - readonly lineNumbersLeft: number; + showEnumMembers?: boolean; /** - * The width of the line numbers. + * Show keyword-suggestions. */ - readonly lineNumbersWidth: number; + showKeywords?: boolean; /** - * Left position for the line decorations. + * Show text-suggestions. */ - readonly decorationsLeft: number; + showWords?: boolean; /** - * The width of the line decorations. + * Show color-suggestions. */ - readonly decorationsWidth: number; + showColors?: boolean; /** - * Left position for the content (actual text) + * Show file-suggestions. */ - readonly contentLeft: number; + showFiles?: boolean; /** - * The width of the content (actual text) + * Show reference-suggestions. */ - readonly contentWidth: number; + showReferences?: boolean; /** - * Layout information for the minimap + * Show folder-suggestions. */ - readonly minimap: EditorMinimapLayoutInfo; + showFolders?: boolean; /** - * The number of columns (of typical characters) fitting on a viewport line. + * Show typeParameter-suggestions. */ - readonly viewportColumn: number; - readonly isWordWrapMinified: boolean; - readonly isViewportWrapping: boolean; - readonly wrappingColumn: number; + showTypeParameters?: boolean; /** - * The width of the vertical scrollbar. + * Show issue-suggestions. */ - readonly verticalScrollbarWidth: number; + showIssues?: boolean; /** - * The height of the horizontal scrollbar. + * Show user-suggestions. */ - readonly horizontalScrollbarHeight: number; + showUsers?: boolean; /** - * The position of the overview ruler. + * Show snippet-suggestions. */ - readonly overviewRuler: OverviewRulerPosition; - } - - /** - * The internal layout details of the editor. - */ - export interface EditorMinimapLayoutInfo { - readonly renderMinimap: RenderMinimap; - readonly minimapLeft: number; - readonly minimapWidth: number; - readonly minimapHeightIsEditorHeight: boolean; - readonly minimapIsSampling: boolean; - readonly minimapScale: number; - readonly minimapLineHeight: number; - readonly minimapCanvasInnerWidth: number; - readonly minimapCanvasInnerHeight: number; - readonly minimapCanvasOuterWidth: number; - readonly minimapCanvasOuterHeight: number; + showSnippets?: boolean; } - export enum ShowLightbulbIconMode { - Off = 'off', - OnCode = 'onCode', - On = 'on' + export interface ISmartSelectOptions { + selectLeadingAndTrailingWhitespace?: boolean; + selectSubwords?: boolean; } /** - * Configuration options for editor lightbulb + * Describes how to indent wrapped lines. */ - export interface IEditorLightbulbOptions { - /** - * Enable the lightbulb code action. - * The three possible values are `off`, `on` and `onCode` and the default is `onCode`. - * `off` disables the code action menu. - * `on` shows the code action menu on code and on empty lines. - * `onCode` shows the code action menu on code only. - */ - enabled?: ShowLightbulbIconMode; - } - - export interface IEditorStickyScrollOptions { + export enum WrappingIndent { /** - * Enable the sticky scroll + * No indentation => wrapped lines begin at column 1. */ - enabled?: boolean; + None = 0, /** - * Maximum number of sticky lines to show + * Same => wrapped lines get the same indentation as the parent. */ - maxLineCount?: number; + Same = 1, /** - * Model to choose for sticky scroll by default + * Indent => wrapped lines get +1 indentation toward the parent. */ - defaultModel?: 'outlineModel' | 'foldingProviderModel' | 'indentationModel'; + Indent = 2, /** - * Define whether to scroll sticky scroll with editor horizontal scrollbae + * DeepIndent => wrapped lines get +2 indentation toward the parent. */ - scrollWithEditor?: boolean; + DeepIndent = 3 + } + + export interface EditorWrappingInfo { + readonly isDominatedByLongLines: boolean; + readonly isWordWrapMinified: boolean; + readonly isViewportWrapping: boolean; + readonly wrappingColumn: number; } /** - * Configuration options for editor inlayHints + * Configuration options for editor drop into behavior */ - export interface IEditorInlayHintsOptions { + export interface IDropIntoEditorOptions { /** - * Enable the inline hints. + * Enable dropping into editor. * Defaults to true. */ - enabled?: 'on' | 'off' | 'offUnlessPressed' | 'onUnlessPressed'; - /** - * Font size of inline hints. - * Default to 90% of the editor font size. - */ - fontSize?: number; - /** - * Font family of inline hints. - * Defaults to editor font family. - */ - fontFamily?: string; - /** - * Enables the padding around the inlay hint. - * Defaults to false. - */ - padding?: boolean; + enabled?: boolean; /** - * Maximum length for inlay hints per line - * Set to 0 to have an unlimited length. + * Controls if a widget is shown after a drop. + * Defaults to 'afterDrop'. */ - maximumLength?: number; + showDropSelector?: 'afterDrop' | 'never'; } /** - * Configuration options for editor minimap + * Configuration options for editor pasting as into behavior */ - export interface IEditorMinimapOptions { + export interface IPasteAsOptions { /** - * Enable the rendering of the minimap. + * Enable paste as functionality in editors. * Defaults to true. */ enabled?: boolean; /** - * Control the rendering of minimap. - */ - autohide?: boolean; - /** - * Control the side of the minimap in editor. - * Defaults to 'right'. - */ - side?: 'right' | 'left'; - /** - * Control the minimap rendering mode. - * Defaults to 'actual'. - */ - size?: 'proportional' | 'fill' | 'fit'; - /** - * Control the rendering of the minimap slider. - * Defaults to 'mouseover'. - */ - showSlider?: 'always' | 'mouseover'; - /** - * Render the actual text on a line (as opposed to color blocks). - * Defaults to true. - */ - renderCharacters?: boolean; - /** - * Limit the width of the minimap to render at most a certain number of columns. - * Defaults to 120. - */ - maxColumn?: number; - /** - * Relative size of the font in the minimap. Defaults to 1. - */ - scale?: number; - /** - * Whether to show named regions as section headers. Defaults to true. - */ - showRegionSectionHeaders?: boolean; - /** - * Whether to show MARK: comments as section headers. Defaults to true. - */ - showMarkSectionHeaders?: boolean; - /** - * Font size of section headers. Defaults to 9. - */ - sectionHeaderFontSize?: number; - /** - * Spacing between the section header characters (in CSS px). Defaults to 1. + * Controls if a widget is shown after a drop. + * Defaults to 'afterPaste'. */ - sectionHeaderLetterSpacing?: number; + showPasteSelector?: 'afterPaste' | 'never'; } - /** - * Configuration options for editor padding - */ - export interface IEditorPaddingOptions { + export enum EditorOption { + acceptSuggestionOnCommitCharacter = 0, + acceptSuggestionOnEnter = 1, + accessibilitySupport = 2, + accessibilityPageSize = 3, + ariaLabel = 4, + ariaRequired = 5, + autoClosingBrackets = 6, + autoClosingComments = 7, + screenReaderAnnounceInlineSuggestion = 8, + autoClosingDelete = 9, + autoClosingOvertype = 10, + autoClosingQuotes = 11, + autoIndent = 12, + automaticLayout = 13, + autoSurround = 14, + bracketPairColorization = 15, + guides = 16, + codeLens = 17, + codeLensFontFamily = 18, + codeLensFontSize = 19, + colorDecorators = 20, + colorDecoratorsLimit = 21, + columnSelection = 22, + comments = 23, + contextmenu = 24, + copyWithSyntaxHighlighting = 25, + cursorBlinking = 26, + cursorSmoothCaretAnimation = 27, + cursorStyle = 28, + cursorSurroundingLines = 29, + cursorSurroundingLinesStyle = 30, + cursorWidth = 31, + disableLayerHinting = 32, + disableMonospaceOptimizations = 33, + domReadOnly = 34, + dragAndDrop = 35, + dropIntoEditor = 36, + experimentalEditContextEnabled = 37, + emptySelectionClipboard = 38, + experimentalGpuAcceleration = 39, + experimentalWhitespaceRendering = 40, + extraEditorClassName = 41, + fastScrollSensitivity = 42, + find = 43, + fixedOverflowWidgets = 44, + folding = 45, + foldingStrategy = 46, + foldingHighlight = 47, + foldingImportsByDefault = 48, + foldingMaximumRegions = 49, + unfoldOnClickAfterEndOfLine = 50, + fontFamily = 51, + fontInfo = 52, + fontLigatures = 53, + fontSize = 54, + fontWeight = 55, + fontVariations = 56, + formatOnPaste = 57, + formatOnType = 58, + glyphMargin = 59, + gotoLocation = 60, + hideCursorInOverviewRuler = 61, + hover = 62, + inDiffEditor = 63, + inlineSuggest = 64, + letterSpacing = 65, + lightbulb = 66, + lineDecorationsWidth = 67, + lineHeight = 68, + lineNumbers = 69, + lineNumbersMinChars = 70, + linkedEditing = 71, + links = 72, + matchBrackets = 73, + minimap = 74, + mouseStyle = 75, + mouseWheelScrollSensitivity = 76, + mouseWheelZoom = 77, + multiCursorMergeOverlapping = 78, + multiCursorModifier = 79, + multiCursorPaste = 80, + multiCursorLimit = 81, + occurrencesHighlight = 82, + occurrencesHighlightDelay = 83, + overviewRulerBorder = 84, + overviewRulerLanes = 85, + padding = 86, + pasteAs = 87, + parameterHints = 88, + peekWidgetDefaultFocus = 89, + placeholder = 90, + definitionLinkOpensInPeek = 91, + quickSuggestions = 92, + quickSuggestionsDelay = 93, + readOnly = 94, + readOnlyMessage = 95, + renameOnType = 96, + renderControlCharacters = 97, + renderFinalNewline = 98, + renderLineHighlight = 99, + renderLineHighlightOnlyWhenFocus = 100, + renderValidationDecorations = 101, + renderWhitespace = 102, + revealHorizontalRightPadding = 103, + roundedSelection = 104, + rulers = 105, + scrollbar = 106, + scrollBeyondLastColumn = 107, + scrollBeyondLastLine = 108, + scrollPredominantAxis = 109, + selectionClipboard = 110, + selectionHighlight = 111, + selectOnLineNumbers = 112, + showFoldingControls = 113, + showUnused = 114, + snippetSuggestions = 115, + smartSelect = 116, + smoothScrolling = 117, + stickyScroll = 118, + stickyTabStops = 119, + stopRenderingLineAfter = 120, + suggest = 121, + suggestFontSize = 122, + suggestLineHeight = 123, + suggestOnTriggerCharacters = 124, + suggestSelection = 125, + tabCompletion = 126, + tabIndex = 127, + unicodeHighlighting = 128, + unusualLineTerminators = 129, + useShadowDOM = 130, + useTabStops = 131, + wordBreak = 132, + wordSegmenterLocales = 133, + wordSeparators = 134, + wordWrap = 135, + wordWrapBreakAfterCharacters = 136, + wordWrapBreakBeforeCharacters = 137, + wordWrapColumn = 138, + wordWrapOverride1 = 139, + wordWrapOverride2 = 140, + wrappingIndent = 141, + wrappingStrategy = 142, + showDeprecated = 143, + inlayHints = 144, + editorClassName = 145, + pixelRatio = 146, + tabFocusMode = 147, + layoutInfo = 148, + wrappingInfo = 149, + defaultColorDecorators = 150, + colorDecoratorsActivatedOn = 151, + inlineCompletionsAccessibilityVerbose = 152 + } + + export const EditorOptions: { + acceptSuggestionOnCommitCharacter: IEditorOption; + acceptSuggestionOnEnter: IEditorOption; + accessibilitySupport: IEditorOption; + accessibilityPageSize: IEditorOption; + ariaLabel: IEditorOption; + ariaRequired: IEditorOption; + screenReaderAnnounceInlineSuggestion: IEditorOption; + autoClosingBrackets: IEditorOption; + autoClosingComments: IEditorOption; + autoClosingDelete: IEditorOption; + autoClosingOvertype: IEditorOption; + autoClosingQuotes: IEditorOption; + autoIndent: IEditorOption; + automaticLayout: IEditorOption; + autoSurround: IEditorOption; + bracketPairColorization: IEditorOption>>; + bracketPairGuides: IEditorOption>>; + stickyTabStops: IEditorOption; + codeLens: IEditorOption; + codeLensFontFamily: IEditorOption; + codeLensFontSize: IEditorOption; + colorDecorators: IEditorOption; + colorDecoratorActivatedOn: IEditorOption; + colorDecoratorsLimit: IEditorOption; + columnSelection: IEditorOption; + comments: IEditorOption>>; + contextmenu: IEditorOption; + copyWithSyntaxHighlighting: IEditorOption; + cursorBlinking: IEditorOption; + cursorSmoothCaretAnimation: IEditorOption; + cursorStyle: IEditorOption; + cursorSurroundingLines: IEditorOption; + cursorSurroundingLinesStyle: IEditorOption; + cursorWidth: IEditorOption; + disableLayerHinting: IEditorOption; + disableMonospaceOptimizations: IEditorOption; + domReadOnly: IEditorOption; + dragAndDrop: IEditorOption; + emptySelectionClipboard: IEditorOption; + dropIntoEditor: IEditorOption>>; + experimentalEditContextEnabled: IEditorOption; + stickyScroll: IEditorOption>>; + experimentalGpuAcceleration: IEditorOption; + experimentalWhitespaceRendering: IEditorOption; + extraEditorClassName: IEditorOption; + fastScrollSensitivity: IEditorOption; + find: IEditorOption>>; + fixedOverflowWidgets: IEditorOption; + folding: IEditorOption; + foldingStrategy: IEditorOption; + foldingHighlight: IEditorOption; + foldingImportsByDefault: IEditorOption; + foldingMaximumRegions: IEditorOption; + unfoldOnClickAfterEndOfLine: IEditorOption; + fontFamily: IEditorOption; + fontInfo: IEditorOption; + fontLigatures2: IEditorOption; + fontSize: IEditorOption; + fontWeight: IEditorOption; + fontVariations: IEditorOption; + formatOnPaste: IEditorOption; + formatOnType: IEditorOption; + glyphMargin: IEditorOption; + gotoLocation: IEditorOption>>; + hideCursorInOverviewRuler: IEditorOption; + hover: IEditorOption>>; + inDiffEditor: IEditorOption; + letterSpacing: IEditorOption; + lightbulb: IEditorOption>>; + lineDecorationsWidth: IEditorOption; + lineHeight: IEditorOption; + lineNumbers: IEditorOption; + lineNumbersMinChars: IEditorOption; + linkedEditing: IEditorOption; + links: IEditorOption; + matchBrackets: IEditorOption; + minimap: IEditorOption>>; + mouseStyle: IEditorOption; + mouseWheelScrollSensitivity: IEditorOption; + mouseWheelZoom: IEditorOption; + multiCursorMergeOverlapping: IEditorOption; + multiCursorModifier: IEditorOption; + multiCursorPaste: IEditorOption; + multiCursorLimit: IEditorOption; + occurrencesHighlight: IEditorOption; + occurrencesHighlightDelay: IEditorOption; + overviewRulerBorder: IEditorOption; + overviewRulerLanes: IEditorOption; + padding: IEditorOption>>; + pasteAs: IEditorOption>>; + parameterHints: IEditorOption>>; + peekWidgetDefaultFocus: IEditorOption; + placeholder: IEditorOption; + definitionLinkOpensInPeek: IEditorOption; + quickSuggestions: IEditorOption; + quickSuggestionsDelay: IEditorOption; + readOnly: IEditorOption; + readOnlyMessage: IEditorOption; + renameOnType: IEditorOption; + renderControlCharacters: IEditorOption; + renderFinalNewline: IEditorOption; + renderLineHighlight: IEditorOption; + renderLineHighlightOnlyWhenFocus: IEditorOption; + renderValidationDecorations: IEditorOption; + renderWhitespace: IEditorOption; + revealHorizontalRightPadding: IEditorOption; + roundedSelection: IEditorOption; + rulers: IEditorOption; + scrollbar: IEditorOption; + scrollBeyondLastColumn: IEditorOption; + scrollBeyondLastLine: IEditorOption; + scrollPredominantAxis: IEditorOption; + selectionClipboard: IEditorOption; + selectionHighlight: IEditorOption; + selectOnLineNumbers: IEditorOption; + showFoldingControls: IEditorOption; + showUnused: IEditorOption; + showDeprecated: IEditorOption; + inlayHints: IEditorOption>>; + snippetSuggestions: IEditorOption; + smartSelect: IEditorOption>>; + smoothScrolling: IEditorOption; + stopRenderingLineAfter: IEditorOption; + suggest: IEditorOption>>; + inlineSuggest: IEditorOption>>; + inlineCompletionsAccessibilityVerbose: IEditorOption; + suggestFontSize: IEditorOption; + suggestLineHeight: IEditorOption; + suggestOnTriggerCharacters: IEditorOption; + suggestSelection: IEditorOption; + tabCompletion: IEditorOption; + tabIndex: IEditorOption; + unicodeHighlight: IEditorOption; + unusualLineTerminators: IEditorOption; + useShadowDOM: IEditorOption; + useTabStops: IEditorOption; + wordBreak: IEditorOption; + wordSegmenterLocales: IEditorOption; + wordSeparators: IEditorOption; + wordWrap: IEditorOption; + wordWrapBreakAfterCharacters: IEditorOption; + wordWrapBreakBeforeCharacters: IEditorOption; + wordWrapColumn: IEditorOption; + wordWrapOverride1: IEditorOption; + wordWrapOverride2: IEditorOption; + editorClassName: IEditorOption; + defaultColorDecorators: IEditorOption; + pixelRatio: IEditorOption; + tabFocusMode: IEditorOption; + layoutInfo: IEditorOption; + wrappingInfo: IEditorOption; + wrappingIndent: IEditorOption; + wrappingStrategy: IEditorOption; + }; + + type EditorOptionsType = typeof EditorOptions; + + type FindEditorOptionsKeyById = { + [K in keyof EditorOptionsType]: EditorOptionsType[K]['id'] extends T ? K : never; + }[keyof EditorOptionsType]; + + type ComputedEditorOptionValue> = T extends IEditorOption ? R : never; + + export type FindComputedEditorOptionValueById = NonNullable]>>; + + export interface IEditorConstructionOptions extends IEditorOptions { + /** + * The initial editor dimension (to avoid measuring the container). + */ + dimension?: IDimension; + /** + * Place overflow widgets inside an external DOM node. + * Defaults to an internal DOM node. + */ + overflowWidgetsDomNode?: HTMLElement; + } + + /** + * 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; + } + + /** + * 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; + /** + * If the `afterColumn` has multiple view columns, the affinity specifies which one to use. Defaults to `none`. + */ + afterColumnAffinity?: PositionAffinity; + /** + * Render the zone even when its line is hidden. + */ + showInHiddenAreas?: boolean; + /** + * Tiebreaker that is used when multiple view zones want to be after the same line. + * Defaults to `afterColumn` otherwise 10000; + */ + ordinal?: number; + /** + * Suppress mouse down events. + * If set, the editor will attach a mouse down listener to the view zone and .preventDefault on it. + * Defaults to false + */ + suppressMouseDown?: boolean; + /** + * The height in lines of the view zone. + * If specified, `heightInPx` will be used instead of this. + * If neither `heightInPx` nor `heightInLines` is specified, a default of `heightInLines` = 1 will be chosen. + */ + heightInLines?: number; + /** + * The height in px of the view zone. + * If this is set, the editor will give preference to it rather than `heightInLines` above. + * If neither `heightInPx` nor `heightInLines` is specified, a default of `heightInLines` = 1 will be chosen. + */ + heightInPx?: number; + /** + * The minimum width in px of the view zone. + * If this is set, the editor will ensure that the scroll width is >= than this value. + */ + minWidthInPx?: number; + /** + * The dom node of the view zone + */ + domNode: HTMLElement; + /** + * An optional dom node for the view zone that will be placed in the margin area. + */ + marginDomNode?: HTMLElement | null; + /** + * Callback which gives the relative top of the view zone as it appears (taking scrolling into account). + */ + onDomNodeTop?: (top: number) => void; + /** + * Callback which gives the height in pixels of the view zone. + */ + onComputedHeight?: (height: number) => void; + } + + /** + * An accessor that allows for zones to be added or removed. + */ + export interface IViewZoneChangeAccessor { + /** + * Create a new view zone. + * @param zone Zone to create + * @return A unique identifier to the view zone. + */ + addZone(zone: IViewZone): string; + /** + * Remove a zone + * @param id A unique identifier to the view zone, as returned by the `addZone` call. + */ + removeZone(id: string): void; + /** + * Change a zone's position. + * The editor will rescan the `afterLineNumber` and `afterColumn` properties of a view zone. + */ + layoutZone(id: string): void; + } + + /** + * A positioning preference for rendering content widgets. + */ + export enum ContentWidgetPositionPreference { + /** + * Place the content widget exactly at a position + */ + EXACT = 0, + /** + * Place the content widget above a position + */ + ABOVE = 1, + /** + * Place the content widget below a position + */ + BELOW = 2 + } + + /** + * A position for rendering content widgets. + */ + export interface IContentWidgetPosition { + /** + * Desired position which serves as an anchor for placing the content widget. + * The widget will be placed above, at, or below the specified position, based on the + * provided preference. The widget will always touch this position. + * + * Given sufficient horizontal space, the widget will be placed to the right of the + * passed in position. This can be tweaked by providing a `secondaryPosition`. + * + * @see preference + * @see secondaryPosition + */ + position: IPosition | null; + /** + * Optionally, a secondary position can be provided to further define the placing of + * the content widget. The secondary position must have the same line number as the + * primary position. If possible, the widget will be placed such that it also touches + * the secondary position. + */ + secondaryPosition?: IPosition | null; + /** + * Placement preference for position, in order of preference. + */ + preference: ContentWidgetPositionPreference[]; + /** + * Placement preference when multiple view positions refer to the same (model) position. + * This plays a role when injected text is involved. + */ + positionAffinity?: PositionAffinity; + } + + /** + * A content widget renders inline with the text and can be easily placed 'near' an editor position. + */ + export interface IContentWidget { + /** + * Render this content widget in a location where it could overflow the editor's view dom node. + */ + allowEditorOverflow?: boolean; + /** + * Call preventDefault() on mousedown events that target the content widget. + */ + suppressMouseDown?: boolean; + /** + * Get a unique identifier of the content widget. + */ + getId(): string; + /** + * Get the dom node of the content widget. + */ + getDomNode(): HTMLElement; + /** + * Get the placement of the content widget. + * If null is returned, the content widget will be placed off screen. + */ + getPosition(): IContentWidgetPosition | null; + /** + * Optional function that is invoked before rendering + * the content widget. If a dimension is returned the editor will + * attempt to use it. + */ + beforeRender?(): IDimension | null; + /** + * Optional function that is invoked after rendering the content + * widget. Is being invoked with the selected position preference + * or `null` if not rendered. + */ + afterRender?(position: ContentWidgetPositionPreference | null): void; + } + + /** + * A positioning preference for rendering overlay widgets. + */ + export enum OverlayWidgetPositionPreference { + /** + * Position the overlay widget in the top right corner + */ + TOP_RIGHT_CORNER = 0, + /** + * Position the overlay widget in the bottom right corner + */ + BOTTOM_RIGHT_CORNER = 1, + /** + * Position the overlay widget in the top center + */ + TOP_CENTER = 2 + } + + /** + * Represents editor-relative coordinates of an overlay widget. + */ + export interface IOverlayWidgetPositionCoordinates { + /** + * The top position for the overlay widget, relative to the editor. + */ + top: number; + /** + * The left position for the overlay widget, relative to the editor. + */ + left: number; + } + + /** + * A position for rendering overlay widgets. + */ + export interface IOverlayWidgetPosition { + /** + * The position preference for the overlay widget. + */ + preference: OverlayWidgetPositionPreference | IOverlayWidgetPositionCoordinates | null; + /** + * When set, stacks with other overlay widgets with the same preference, + * in an order determined by the ordinal value. + */ + stackOridinal?: number; + } + + /** + * An overlay widgets renders on top of the text. + */ + export interface IOverlayWidget { + /** + * Event fired when the widget layout changes. + */ + onDidLayout?: IEvent; + /** + * Render this overlay widget in a location where it could overflow the editor's view dom node. + */ + allowEditorOverflow?: boolean; + /** + * Get a unique identifier of the overlay widget. + */ + getId(): string; + /** + * Get the dom node of the overlay widget. + */ + getDomNode(): HTMLElement; + /** + * Get the placement of the overlay widget. + * If null is returned, the overlay widget is responsible to place itself. + */ + getPosition(): IOverlayWidgetPosition | null; + /** + * The editor will ensure that the scroll width is >= than this value. + */ + getMinContentWidthInPx?(): number; + } + + /** + * A glyph margin widget renders in the editor glyph margin. + */ + export interface IGlyphMarginWidget { + /** + * Get a unique identifier of the glyph widget. + */ + getId(): string; + /** + * Get the dom node of the glyph widget. + */ + getDomNode(): HTMLElement; + /** + * Get the placement of the glyph widget. + */ + getPosition(): IGlyphMarginWidgetPosition; + } + + /** + * A position for rendering glyph margin widgets. + */ + export interface IGlyphMarginWidgetPosition { + /** + * The glyph margin lane where the widget should be shown. + */ + lane: GlyphMarginLane; + /** + * The priority order of the widget, used for determining which widget + * to render when there are multiple. + */ + zIndex: number; + /** + * The editor range that this widget applies to. + */ + range: IRange; + } + + /** + * Type of hit element with the mouse in the editor. + */ + export enum MouseTargetType { + /** + * Mouse is on top of an unknown element. + */ + UNKNOWN = 0, + /** + * Mouse is on top of the textarea used for input. + */ + TEXTAREA = 1, + /** + * Mouse is on top of the glyph margin + */ + GUTTER_GLYPH_MARGIN = 2, + /** + * Mouse is on top of the line numbers + */ + GUTTER_LINE_NUMBERS = 3, + /** + * Mouse is on top of the line decorations + */ + GUTTER_LINE_DECORATIONS = 4, + /** + * Mouse is on top of the whitespace left in the gutter by a view zone. + */ + GUTTER_VIEW_ZONE = 5, + /** + * Mouse is on top of text in the content. + */ + CONTENT_TEXT = 6, + /** + * Mouse is on top of empty space in the content (e.g. after line text or below last line) + */ + CONTENT_EMPTY = 7, + /** + * Mouse is on top of a view zone in the content. + */ + CONTENT_VIEW_ZONE = 8, + /** + * Mouse is on top of a content widget. + */ + CONTENT_WIDGET = 9, + /** + * Mouse is on top of the decorations overview ruler. + */ + OVERVIEW_RULER = 10, + /** + * Mouse is on top of a scrollbar. + */ + SCROLLBAR = 11, + /** + * Mouse is on top of an overlay widget. + */ + OVERLAY_WIDGET = 12, + /** + * Mouse is outside of the editor. + */ + OUTSIDE_EDITOR = 13 + } + + export interface IBaseMouseTarget { + /** + * The target element + */ + readonly element: HTMLElement | null; + /** + * The 'approximate' editor position + */ + readonly position: Position | null; + /** + * Desired mouse column (e.g. when position.column gets clamped to text length -- clicking after text on a line). + */ + readonly mouseColumn: number; + /** + * The 'approximate' editor range + */ + readonly range: Range | null; + } + + export interface IMouseTargetUnknown extends IBaseMouseTarget { + readonly type: MouseTargetType.UNKNOWN; + } + + export interface IMouseTargetTextarea extends IBaseMouseTarget { + readonly type: MouseTargetType.TEXTAREA; + readonly position: null; + readonly range: null; + } + + export interface IMouseTargetMarginData { + readonly isAfterLines: boolean; + readonly glyphMarginLeft: number; + readonly glyphMarginWidth: number; + readonly glyphMarginLane?: GlyphMarginLane; + readonly lineNumbersWidth: number; + readonly offsetX: number; + } + + export interface IMouseTargetMargin extends IBaseMouseTarget { + readonly type: MouseTargetType.GUTTER_GLYPH_MARGIN | MouseTargetType.GUTTER_LINE_NUMBERS | MouseTargetType.GUTTER_LINE_DECORATIONS; + readonly position: Position; + readonly range: Range; + readonly detail: IMouseTargetMarginData; + } + + export interface IMouseTargetViewZoneData { + readonly viewZoneId: string; + readonly positionBefore: Position | null; + readonly positionAfter: Position | null; + readonly position: Position; + readonly afterLineNumber: number; + } + + export interface IMouseTargetViewZone extends IBaseMouseTarget { + readonly type: MouseTargetType.GUTTER_VIEW_ZONE | MouseTargetType.CONTENT_VIEW_ZONE; + readonly position: Position; + readonly range: Range; + readonly detail: IMouseTargetViewZoneData; + } + + export interface IMouseTargetContentTextData { + readonly mightBeForeignElement: boolean; + /** + * @internal + */ + readonly injectedText: any | null; + } + + export interface IMouseTargetContentText extends IBaseMouseTarget { + readonly type: MouseTargetType.CONTENT_TEXT; + readonly position: Position; + readonly range: Range; + readonly detail: IMouseTargetContentTextData; + } + + export interface IMouseTargetContentEmptyData { + readonly isAfterLines: boolean; + readonly horizontalDistanceToText?: number; + } + + export interface IMouseTargetContentEmpty extends IBaseMouseTarget { + readonly type: MouseTargetType.CONTENT_EMPTY; + readonly position: Position; + readonly range: Range; + readonly detail: IMouseTargetContentEmptyData; + } + + export interface IMouseTargetContentWidget extends IBaseMouseTarget { + readonly type: MouseTargetType.CONTENT_WIDGET; + readonly position: null; + readonly range: null; + readonly detail: string; + } + + export interface IMouseTargetOverlayWidget extends IBaseMouseTarget { + readonly type: MouseTargetType.OVERLAY_WIDGET; + readonly position: null; + readonly range: null; + readonly detail: string; + } + + export interface IMouseTargetScrollbar extends IBaseMouseTarget { + readonly type: MouseTargetType.SCROLLBAR; + readonly position: Position; + readonly range: Range; + } + + export interface IMouseTargetOverviewRuler extends IBaseMouseTarget { + readonly type: MouseTargetType.OVERVIEW_RULER; + } + + export interface IMouseTargetOutsideEditor extends IBaseMouseTarget { + readonly type: MouseTargetType.OUTSIDE_EDITOR; + readonly outsidePosition: 'above' | 'below' | 'left' | 'right'; + readonly outsideDistance: number; + } + + /** + * Target hit with the mouse in the editor. + */ + export type IMouseTarget = (IMouseTargetUnknown | IMouseTargetTextarea | IMouseTargetMargin | IMouseTargetViewZone | IMouseTargetContentText | IMouseTargetContentEmpty | IMouseTargetContentWidget | IMouseTargetOverlayWidget | IMouseTargetScrollbar | IMouseTargetOverviewRuler | IMouseTargetOutsideEditor); + + /** + * A mouse event originating from the editor. + */ + export interface IEditorMouseEvent { + readonly event: IMouseEvent; + readonly target: IMouseTarget; + } + + export interface IPartialEditorMouseEvent { + readonly event: IMouseEvent; + readonly target: IMouseTarget | null; + } + + /** + * A paste event originating from the editor. + */ + export interface IPasteEvent { + readonly range: Range; + readonly languageId: string | null; + readonly clipboardEvent?: ClipboardEvent; + } + + /** + * @internal + */ + export interface PastePayload { + text: string; + pasteOnNewLine: boolean; + multicursorText: string[] | null; + mode: string | null; + 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. + * Defaults to an internal DOM node. + */ + overflowWidgetsDomNode?: HTMLElement; + /** + * Aria label for original editor. + */ + originalAriaLabel?: string; + /** + * Aria label for modified editor. + */ + modifiedAriaLabel?: string; + } + + /** + * 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 context menu ID that should be used to lookup context menu actions. + * @internal + */ + readonly contextMenuId: MenuId; + /** + * The editor's scoped context key service. + * @internal + */ + readonly contextKeyService: any; + /** + * An event emitted when the content of the current model has changed. + * @event + */ + readonly onDidChangeModelContent: IEvent; + /** + * An event emitted when the language of the current model has changed. + * @event + */ + readonly onDidChangeModelLanguage: IEvent; + /** + * An event emitted when the language configuration of the current model has changed. + * @event + */ + readonly onDidChangeModelLanguageConfiguration: IEvent; + /** + * An event emitted when the options of the current model has changed. + * @event + */ + readonly onDidChangeModelOptions: IEvent; + /** + * An event emitted when the configuration of the editor has changed. (e.g. `editor.updateOptions()`) + * @event + */ + readonly onDidChangeConfiguration: IEvent; /** - * Spacing between top edge of editor and first line. + * An event emitted when the cursor position has changed. + * @event */ - top?: number; + readonly onDidChangeCursorPosition: IEvent; /** - * Spacing between bottom edge of editor and last line. + * An event emitted when the cursor selection has changed. + * @event */ - bottom?: number; - } - - /** - * Configuration options for parameter hints - */ - export interface IEditorParameterHintOptions { + readonly onDidChangeCursorSelection: IEvent; /** - * Enable parameter hints. - * Defaults to true. + * An event emitted when the model of this editor is about to change (e.g. from `editor.setModel()`). + * @event */ - enabled?: boolean; + readonly onWillChangeModel: IEvent; /** - * Enable cycling of parameter hints. - * Defaults to false. + * An event emitted when the model of this editor has changed (e.g. `editor.setModel()`). + * @event */ - cycle?: boolean; - } - - export type QuickSuggestionsValue = 'on' | 'inline' | 'off'; - - /** - * Configuration options for quick suggestions - */ - export interface IQuickSuggestionsOptions { - other?: boolean | QuickSuggestionsValue; - comments?: boolean | QuickSuggestionsValue; - strings?: boolean | QuickSuggestionsValue; - } - - export interface InternalQuickSuggestionsOptions { - readonly other: QuickSuggestionsValue; - readonly comments: QuickSuggestionsValue; - readonly strings: QuickSuggestionsValue; - } - - export type LineNumbersType = 'on' | 'off' | 'relative' | 'interval' | ((lineNumber: number) => string); - - export enum RenderLineNumbersType { - Off = 0, - On = 1, - Relative = 2, - Interval = 3, - Custom = 4 - } - - export interface InternalEditorRenderLineNumbersOptions { - readonly renderType: RenderLineNumbersType; - readonly renderFn: ((lineNumber: number) => string) | null; - } - - export interface IRulerOption { - readonly column: number; - readonly color: string | null; - } - - /** - * Configuration options for editor scrollbars - */ - export interface IEditorScrollbarOptions { + readonly onDidChangeModel: IEvent; /** - * The size of arrows (if displayed). - * Defaults to 11. - * **NOTE**: This option cannot be updated using `updateOptions()` + * An event emitted when the decorations of the current model have changed. + * @event */ - arrowSize?: number; + readonly onDidChangeModelDecorations: IEvent; /** - * Render vertical scrollbar. - * Defaults to 'auto'. + * An event emitted when the tokens of the current model have changed. + * @internal */ - vertical?: 'auto' | 'visible' | 'hidden'; + readonly onDidChangeModelTokens: IEvent; /** - * Render horizontal scrollbar. - * Defaults to 'auto'. + * An event emitted when the text inside this editor gained focus (i.e. cursor starts blinking). + * @event */ - horizontal?: 'auto' | 'visible' | 'hidden'; + readonly onDidFocusEditorText: IEvent; /** - * Cast horizontal and vertical shadows when the content is scrolled. - * Defaults to true. - * **NOTE**: This option cannot be updated using `updateOptions()` + * An event emitted when the text inside this editor lost focus (i.e. cursor stops blinking). + * @event */ - useShadows?: boolean; + readonly onDidBlurEditorText: IEvent; /** - * Render arrows at the top and bottom of the vertical scrollbar. - * Defaults to false. - * **NOTE**: This option cannot be updated using `updateOptions()` + * An event emitted when the text inside this editor or an editor widget gained focus. + * @event */ - verticalHasArrows?: boolean; + readonly onDidFocusEditorWidget: IEvent; /** - * Render arrows at the left and right of the horizontal scrollbar. - * Defaults to false. - * **NOTE**: This option cannot be updated using `updateOptions()` + * An event emitted when the text inside this editor or an editor widget lost focus. + * @event */ - horizontalHasArrows?: boolean; + readonly onDidBlurEditorWidget: IEvent; /** - * Listen to mouse wheel events and react to them by scrolling. - * Defaults to true. + * An event emitted before interpreting typed characters (on the keyboard). + * @event + * @internal */ - handleMouseWheel?: boolean; + readonly onWillType: IEvent; /** - * Always consume mouse wheel events (always call preventDefault() and stopPropagation() on the browser events). - * Defaults to true. - * **NOTE**: This option cannot be updated using `updateOptions()` + * An event emitted after interpreting typed characters (on the keyboard). + * @event + * @internal */ - alwaysConsumeMouseWheel?: boolean; + readonly onDidType: IEvent; /** - * Height in pixels for the horizontal scrollbar. - * Defaults to 10 (px). + * An event emitted after composition has started. */ - horizontalScrollbarSize?: number; + readonly onDidCompositionStart: IEvent; /** - * Width in pixels for the vertical scrollbar. - * Defaults to 10 (px). + * An event emitted after composition has ended. */ - verticalScrollbarSize?: number; + readonly onDidCompositionEnd: IEvent; /** - * Width in pixels for the vertical slider. - * Defaults to `verticalScrollbarSize`. - * **NOTE**: This option cannot be updated using `updateOptions()` + * An event emitted when editing failed because the editor is read-only. + * @event */ - verticalSliderSize?: number; + readonly onDidAttemptReadOnlyEdit: IEvent; /** - * Height in pixels for the horizontal slider. - * Defaults to `horizontalScrollbarSize`. - * **NOTE**: This option cannot be updated using `updateOptions()` + * An event emitted when users paste text in the editor. + * @event */ - horizontalSliderSize?: number; + readonly onDidPaste: IEvent; /** - * Scroll gutter clicks move by page vs jump to position. - * Defaults to false. + * An event emitted on a "mouseup". + * @event */ - scrollByPage?: boolean; + readonly onMouseUp: IEvent; /** - * When set, the horizontal scrollbar will not increase content height. - * Defaults to false. + * An event emitted on a "mousedown". + * @event */ - ignoreHorizontalScrollbarInContentHeight?: boolean; - } - - export interface InternalEditorScrollbarOptions { - readonly arrowSize: number; - readonly vertical: ScrollbarVisibility; - readonly horizontal: ScrollbarVisibility; - readonly useShadows: boolean; - readonly verticalHasArrows: boolean; - readonly horizontalHasArrows: boolean; - readonly handleMouseWheel: boolean; - readonly alwaysConsumeMouseWheel: boolean; - readonly horizontalScrollbarSize: number; - readonly horizontalSliderSize: number; - readonly verticalScrollbarSize: number; - readonly verticalSliderSize: number; - readonly scrollByPage: boolean; - readonly ignoreHorizontalScrollbarInContentHeight: boolean; - } - - export type InUntrustedWorkspace = 'inUntrustedWorkspace'; - - /** - * Configuration options for unicode highlighting. - */ - export interface IUnicodeHighlightOptions { + readonly onMouseDown: IEvent; /** - * Controls whether all non-basic ASCII characters are highlighted. Only characters between U+0020 and U+007E, tab, line-feed and carriage-return are considered basic ASCII. + * An event emitted on a "mousedrag". + * @internal + * @event */ - nonBasicASCII?: boolean | InUntrustedWorkspace; + 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 + */ + readonly onContextMenu: IEvent; + /** + * An event emitted on a "mousemove". + * @event + */ + readonly onMouseMove: IEvent; + /** + * An event emitted on a "mouseleave". + * @event + */ + readonly onMouseLeave: IEvent; + /** + * An event emitted on a "mousewheel" + * @event + * @internal + */ + readonly onMouseWheel: IEvent; + /** + * An event emitted on a "keyup". + * @event + */ + readonly onKeyUp: IEvent; + /** + * An event emitted on a "keydown". + * @event + */ + readonly onKeyDown: IEvent; + /** + * An event emitted when the layout of the editor has changed. + * @event + */ + readonly onDidLayoutChange: IEvent; + /** + * An event emitted when the content width or content height in the editor has changed. + * @event + */ + readonly onDidContentSizeChange: IEvent; + /** + * An event emitted when the scroll in the editor has changed. + * @event + */ + readonly onDidScrollChange: IEvent; + /** + * An event emitted when hidden areas change in the editor (e.g. due to folding). + * @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, + * the editor fires a begin update before the operation and an end update after the operation. + * Whenever the editor fires `onBeginUpdate`, it will also fire `onEndUpdate` once the operation finishes. + * Note that not all operations are bracketed by `onBeginUpdate` and `onEndUpdate`. + */ + readonly onBeginUpdate: IEvent; + /** + * Fires after the editor completes the operation it fired `onBeginUpdate` for. + */ + readonly onEndUpdate: IEvent; /** - * Controls whether characters that just reserve space or have no width at all are highlighted. + * Saves current view state of the editor in a serializable object. */ - invisibleCharacters?: boolean; + saveViewState(): ICodeEditorViewState | null; /** - * Controls whether characters are highlighted that can be confused with basic ASCII characters, except those that are common in the current user locale. + * Restores the view state of the editor from a serializable object generated by `saveViewState`. */ - ambiguousCharacters?: boolean; + restoreViewState(state: ICodeEditorViewState | null): void; /** - * Controls whether characters in comments should also be subject to unicode highlighting. + * Returns true if the text inside this editor or an editor widget has focus. */ - includeComments?: boolean | InUntrustedWorkspace; + hasWidgetFocus(): boolean; /** - * Controls whether characters in strings should also be subject to unicode highlighting. + * Get a contribution of this editor. + * @id Unique identifier of the contribution. + * @return The contribution or null if contribution not found. */ - includeStrings?: boolean | InUntrustedWorkspace; + getContribution(id: string): T | null; /** - * Defines allowed characters that are not being highlighted. + * Execute `fn` with the editor's services. + * @internal */ - allowedCharacters?: Record; + invokeWithinContext(fn: (accessor: any) => T): T; /** - * Unicode characters that are common in allowed locales are not being highlighted. + * Type the getModel() of IEditor. */ - allowedLocales?: Record; - } - - export interface IInlineSuggestOptions { - /** - * Enable or disable the rendering of automatic inline completions. - */ - enabled?: boolean; + getModel(): ITextModel | null; /** - * Configures the mode. - * Use `prefix` to only show ghost text if the text to replace is a prefix of the suggestion text. - * Use `subword` to only show ghost text if the replace text is a subword of the suggestion text. - * Use `subwordSmart` to only show ghost text if the replace text is a subword of the suggestion text, but the subword must start after the cursor position. - * Defaults to `prefix`. - */ - mode?: 'prefix' | 'subword' | 'subwordSmart'; - showToolbar?: 'always' | 'onHover' | 'never'; - syntaxHighlightingEnabled?: boolean; - suppressSuggestions?: boolean; + * Sets the current model attached to this editor. + * If the previous model was created by the editor via the value key in the options + * literal object, it will be destroyed. Otherwise, if the previous model was set + * via setModel, or the model key in the options literal object, the previous model + * will not be destroyed. + * It is safe to call setModel(null) to simply detach the current model from the editor. + */ + setModel(model: ITextModel | null): void; /** - * Does not clear active inline suggestions when the editor loses focus. + * Gets all the editor computed options. */ - keepOnBlur?: boolean; + getOptions(): IComputedEditorOptions; /** - * Font family for inline suggestions. + * Gets a specific editor option. */ - fontFamily?: string | 'default'; - edits?: { - experimental?: { - enabled?: boolean; - }; - }; - } - - export interface IBracketPairColorizationOptions { + getOption(id: T): FindComputedEditorOptionValueById; /** - * Enable or disable bracket pair colorization. - */ - enabled?: boolean; + * Returns the editor's configuration (without any validation or defaults). + */ + getRawOptions(): IEditorOptions; /** - * Use independent color pool per bracket type. - */ - independentColorPoolPerBracketType?: boolean; - } - - export interface IGuidesOptions { + * @internal + */ + getOverflowWidgetsDomNode(): HTMLElement | undefined; /** - * Enable rendering of bracket pair guides. - * Defaults to false. - */ - bracketPairs?: boolean | 'active'; + * @internal + */ + getConfiguredWordAtPosition(position: Position): IWordAtPosition | null; /** - * Enable rendering of vertical bracket pair guides. - * Defaults to 'active'. + * Get value of the current model attached to this editor. + * @see {@link ITextModel.getValue} */ - bracketPairsHorizontal?: boolean | 'active'; + getValue(options?: { + preserveBOM: boolean; + lineEnding: string; + }): string; /** - * Enable highlighting of the active bracket pair. - * Defaults to true. - */ - highlightActiveBracketPair?: boolean; + * Set the value of the current model attached to this editor. + * @see {@link ITextModel.setValue} + */ + setValue(newValue: string): void; /** - * Enable rendering of indent guides. - * Defaults to true. + * Get the width of the editor's content. + * This is information that is "erased" when computing `scrollWidth = Math.max(contentWidth, width)` */ - indentation?: boolean; + getContentWidth(): number; /** - * Enable highlighting of the active indent guide. - * Defaults to true. + * Get the scrollWidth of the editor's viewport. */ - highlightActiveIndentation?: boolean | 'always'; - } - - /** - * Configuration options for editor suggest widget - */ - export interface ISuggestOptions { + getScrollWidth(): number; /** - * Overwrite word ends on accept. Default to false. + * Get the scrollLeft of the editor's viewport. */ - insertMode?: 'insert' | 'replace'; + getScrollLeft(): number; /** - * Enable graceful matching. Defaults to true. + * Get the height of the editor's content. + * This is information that is "erased" when computing `scrollHeight = Math.max(contentHeight, height)` */ - filterGraceful?: boolean; + getContentHeight(): number; /** - * Prevent quick suggestions when a snippet is active. Defaults to true. + * Get the scrollHeight of the editor's viewport. */ - snippetsPreventQuickSuggestions?: boolean; + getScrollHeight(): number; /** - * Favors words that appear close to the cursor. + * Get the scrollTop of the editor's viewport. */ - localityBonus?: boolean; + getScrollTop(): number; /** - * Enable using global storage for remembering suggestions. + * Change the scrollLeft of the editor's viewport. */ - shareSuggestSelections?: boolean; + setScrollLeft(newScrollLeft: number, scrollType?: ScrollType): void; /** - * Select suggestions when triggered via quick suggest or trigger characters + * Change the scrollTop of the editor's viewport. */ - selectionMode?: 'always' | 'never' | 'whenTriggerCharacter' | 'whenQuickSuggestion'; + setScrollTop(newScrollTop: number, scrollType?: ScrollType): void; /** - * Enable or disable icons in suggestions. Defaults to true. + * Change the scroll position of the editor's viewport. */ - showIcons?: boolean; + setScrollPosition(position: INewScrollPosition, scrollType?: ScrollType): void; /** - * Enable or disable the suggest status bar. + * Check if the editor is currently scrolling towards a different scroll position. */ - showStatusBar?: boolean; + hasPendingScrollAnimation(): boolean; /** - * Enable or disable the rendering of the suggestion preview. + * Get an action that is a contribution to this editor. + * @id Unique identifier of the contribution. + * @return The action or null if action not found. */ - preview?: boolean; + getAction(id: string): IEditorAction | null; /** - * Configures the mode of the preview. - */ - previewMode?: 'prefix' | 'subword' | 'subwordSmart'; + * Execute a command on the editor. + * The edits will land on the undo-redo stack, but no "undo stop" will be pushed. + * @param source The source of the call. + * @param command The command to execute + */ + executeCommand(source: string | null | undefined, command: ICommand): void; /** - * Show details inline with the label. Defaults to true. + * Create an "undo stop" in the undo-redo stack. */ - showInlineDetails?: boolean; + pushUndoStop(): boolean; /** - * Show method-suggestions. + * Remove the "undo stop" in the undo-redo stack. */ - showMethods?: boolean; + popUndoStop(): boolean; /** - * Show function-suggestions. + * Execute edits on the editor. + * The edits will land on the undo-redo stack, but no "undo stop" will be pushed. + * @param source The source of the call. + * @param edits The edits to execute. + * @param endCursorState Cursor state after the edits were applied. */ - showFunctions?: boolean; + executeEdits(source: string | null | undefined, edits: IIdentifiedSingleEditOperation[], endCursorState?: ICursorStateComputer | Selection[]): boolean; /** - * Show constructor-suggestions. + * Execute multiple (concomitant) commands on the editor. + * @param source The source of the call. + * @param command The commands to execute */ - showConstructors?: boolean; + executeCommands(source: string | null | undefined, commands: (ICommand | null)[]): void; /** - * Show deprecated-suggestions. + * @internal */ - showDeprecated?: boolean; + _getViewModel(): any | null; /** - * Controls whether suggestions allow matches in the middle of the word instead of only at the beginning + * Get all the decorations on a line (filtering out decorations from other editors). */ - matchOnWordStartOnly?: boolean; + getLineDecorations(lineNumber: number): IModelDecoration[] | null; /** - * Show field-suggestions. + * Get all the decorations for a range (filtering out decorations from other editors). */ - showFields?: boolean; + getDecorationsInRange(range: Range): IModelDecoration[] | null; /** - * Show variable-suggestions. + * All decorations added through this call will get the ownerId of this editor. + * @deprecated Use `createDecorationsCollection` + * @see createDecorationsCollection */ - showVariables?: boolean; + deltaDecorations(oldDecorations: string[], newDecorations: IModelDeltaDecoration[]): string[]; /** - * Show class-suggestions. + * Remove previously added decorations. */ - showClasses?: boolean; + removeDecorations(decorationIds: string[]): void; /** - * Show struct-suggestions. + * @internal */ - showStructs?: boolean; + setDecorationsByType(description: string, decorationTypeKey: string, ranges: IDecorationOptions[]): void; /** - * Show interface-suggestions. + * @internal */ - showInterfaces?: boolean; + setDecorationsByTypeFast(decorationTypeKey: string, ranges: IRange[]): void; /** - * Show module-suggestions. + * @internal */ - showModules?: boolean; + removeDecorationsByType(decorationTypeKey: string): void; /** - * Show property-suggestions. + * Get the layout info for the editor. */ - showProperties?: boolean; + getLayoutInfo(): EditorLayoutInfo; /** - * Show event-suggestions. + * Returns the ranges that are currently visible. + * Does not account for horizontal scrolling. */ - showEvents?: boolean; + getVisibleRanges(): Range[]; /** - * Show operator-suggestions. + * @internal */ - showOperators?: boolean; + getVisibleRangesPlusViewportAboveBelow(): Range[]; /** - * Show unit-suggestions. + * Get the view zones. + * @internal */ - showUnits?: boolean; + getWhitespaces(): IEditorWhitespace[]; /** - * Show value-suggestions. + * Get the vertical position (top offset) for the line's top w.r.t. to the first line. */ - showValues?: boolean; + getTopForLineNumber(lineNumber: number, includeViewZones?: boolean): number; /** - * Show constant-suggestions. + * Get the vertical position (top offset) for the line's bottom w.r.t. to the first line. */ - showConstants?: boolean; + getBottomForLineNumber(lineNumber: number): number; /** - * Show enum-suggestions. + * Get the vertical position (top offset) for the position w.r.t. to the first line. */ - showEnums?: boolean; + getTopForPosition(lineNumber: number, column: number): number; /** - * Show enumMember-suggestions. + * Set the model ranges that will be hidden in the view. + * Hidden areas are stored per source. + * @internal */ - showEnumMembers?: boolean; + setHiddenAreas(ranges: IRange[], source?: unknown): void; /** - * Show keyword-suggestions. + * Sets the editor aria options, primarily the active descendent. + * @internal */ - showKeywords?: boolean; + setAriaOptions(options: IEditorAriaOptions): void; /** - * Show text-suggestions. + * Write the screen reader content to be the current selection */ - showWords?: boolean; + writeScreenReaderContent(reason: string): void; /** - * Show color-suggestions. + * @internal */ - showColors?: boolean; + getTelemetryData(): { + [key: string]: any; + } | undefined; /** - * Show file-suggestions. + * Returns the editor's container dom node */ - showFiles?: boolean; + getContainerDomNode(): HTMLElement; /** - * Show reference-suggestions. + * Returns the editor's dom node */ - showReferences?: boolean; + getDomNode(): HTMLElement | null; /** - * Show folder-suggestions. + * Add a content widget. Widgets must have unique ids, otherwise they will be overwritten. */ - showFolders?: boolean; + addContentWidget(widget: IContentWidget): void; /** - * Show typeParameter-suggestions. + * Layout/Reposition a content widget. This is a ping to the editor to call widget.getPosition() + * and update appropriately. */ - showTypeParameters?: boolean; + layoutContentWidget(widget: IContentWidget): void; /** - * Show issue-suggestions. + * Remove a content widget. */ - showIssues?: boolean; + removeContentWidget(widget: IContentWidget): void; /** - * Show user-suggestions. + * Add an overlay widget. Widgets must have unique ids, otherwise they will be overwritten. */ - showUsers?: boolean; + addOverlayWidget(widget: IOverlayWidget): void; /** - * Show snippet-suggestions. + * Layout/Reposition an overlay widget. This is a ping to the editor to call widget.getPosition() + * and update appropriately. */ - showSnippets?: boolean; - } - - export interface ISmartSelectOptions { - selectLeadingAndTrailingWhitespace?: boolean; - selectSubwords?: boolean; - } - - /** - * Describes how to indent wrapped lines. - */ - export enum WrappingIndent { + layoutOverlayWidget(widget: IOverlayWidget): void; /** - * No indentation => wrapped lines begin at column 1. + * Remove an overlay widget. */ - None = 0, + removeOverlayWidget(widget: IOverlayWidget): void; /** - * Same => wrapped lines get the same indentation as the parent. + * Add a glyph margin widget. Widgets must have unique ids, otherwise they will be overwritten. */ - Same = 1, + addGlyphMarginWidget(widget: IGlyphMarginWidget): void; /** - * Indent => wrapped lines get +1 indentation toward the parent. + * Layout/Reposition a glyph margin widget. This is a ping to the editor to call widget.getPosition() + * and update appropriately. */ - Indent = 2, + layoutGlyphMarginWidget(widget: IGlyphMarginWidget): void; /** - * DeepIndent => wrapped lines get +2 indentation toward the parent. + * Remove a glyph margin widget. */ - DeepIndent = 3 - } - - export interface EditorWrappingInfo { - readonly isDominatedByLongLines: boolean; - readonly isWordWrapMinified: boolean; - readonly isViewportWrapping: boolean; - readonly wrappingColumn: number; - } - - /** - * Configuration options for editor drop into behavior - */ - export interface IDropIntoEditorOptions { + removeGlyphMarginWidget(widget: IGlyphMarginWidget): void; /** - * Enable dropping into editor. - * Defaults to true. + * Change the view zones. View zones are lost when a new model is attached to the editor. */ - enabled?: boolean; + changeViewZones(callback: (accessor: IViewZoneChangeAccessor) => void): void; /** - * Controls if a widget is shown after a drop. - * Defaults to 'afterDrop'. + * Get the horizontal position (left offset) for the column w.r.t to the beginning of the line. + * This method works only if the line `lineNumber` is currently rendered (in the editor's viewport). + * Use this method with caution. */ - showDropSelector?: 'afterDrop' | 'never'; - } - - /** - * Configuration options for editor pasting as into behavior - */ - export interface IPasteAsOptions { + getOffsetForColumn(lineNumber: number, column: number): number; /** - * Enable paste as functionality in editors. - * Defaults to true. + * Force an editor render now. */ - enabled?: boolean; + render(forceRedraw?: boolean): void; /** - * Controls if a widget is shown after a drop. - * Defaults to 'afterPaste'. + * Get the hit test target at coordinates `clientX` and `clientY`. + * The coordinates are relative to the top-left of the viewport. + * + * @returns Hit test target or null if the coordinates fall outside the editor or the editor has no model. */ - showPasteSelector?: 'afterPaste' | 'never'; - } - - export enum EditorOption { - acceptSuggestionOnCommitCharacter = 0, - acceptSuggestionOnEnter = 1, - accessibilitySupport = 2, - accessibilityPageSize = 3, - ariaLabel = 4, - ariaRequired = 5, - autoClosingBrackets = 6, - autoClosingComments = 7, - screenReaderAnnounceInlineSuggestion = 8, - autoClosingDelete = 9, - autoClosingOvertype = 10, - autoClosingQuotes = 11, - autoIndent = 12, - automaticLayout = 13, - autoSurround = 14, - bracketPairColorization = 15, - guides = 16, - codeLens = 17, - codeLensFontFamily = 18, - codeLensFontSize = 19, - colorDecorators = 20, - colorDecoratorsLimit = 21, - columnSelection = 22, - comments = 23, - contextmenu = 24, - copyWithSyntaxHighlighting = 25, - cursorBlinking = 26, - cursorSmoothCaretAnimation = 27, - cursorStyle = 28, - cursorSurroundingLines = 29, - cursorSurroundingLinesStyle = 30, - cursorWidth = 31, - disableLayerHinting = 32, - disableMonospaceOptimizations = 33, - domReadOnly = 34, - dragAndDrop = 35, - dropIntoEditor = 36, - experimentalEditContextEnabled = 37, - emptySelectionClipboard = 38, - experimentalGpuAcceleration = 39, - experimentalWhitespaceRendering = 40, - extraEditorClassName = 41, - fastScrollSensitivity = 42, - find = 43, - fixedOverflowWidgets = 44, - folding = 45, - foldingStrategy = 46, - foldingHighlight = 47, - foldingImportsByDefault = 48, - foldingMaximumRegions = 49, - unfoldOnClickAfterEndOfLine = 50, - fontFamily = 51, - fontInfo = 52, - fontLigatures = 53, - fontSize = 54, - fontWeight = 55, - fontVariations = 56, - formatOnPaste = 57, - formatOnType = 58, - glyphMargin = 59, - gotoLocation = 60, - hideCursorInOverviewRuler = 61, - hover = 62, - inDiffEditor = 63, - inlineSuggest = 64, - letterSpacing = 65, - lightbulb = 66, - lineDecorationsWidth = 67, - lineHeight = 68, - lineNumbers = 69, - lineNumbersMinChars = 70, - linkedEditing = 71, - links = 72, - matchBrackets = 73, - minimap = 74, - mouseStyle = 75, - mouseWheelScrollSensitivity = 76, - mouseWheelZoom = 77, - multiCursorMergeOverlapping = 78, - multiCursorModifier = 79, - multiCursorPaste = 80, - multiCursorLimit = 81, - occurrencesHighlight = 82, - occurrencesHighlightDelay = 83, - overviewRulerBorder = 84, - overviewRulerLanes = 85, - padding = 86, - pasteAs = 87, - parameterHints = 88, - peekWidgetDefaultFocus = 89, - placeholder = 90, - definitionLinkOpensInPeek = 91, - quickSuggestions = 92, - quickSuggestionsDelay = 93, - readOnly = 94, - readOnlyMessage = 95, - renameOnType = 96, - renderControlCharacters = 97, - renderFinalNewline = 98, - renderLineHighlight = 99, - renderLineHighlightOnlyWhenFocus = 100, - renderValidationDecorations = 101, - renderWhitespace = 102, - revealHorizontalRightPadding = 103, - roundedSelection = 104, - rulers = 105, - scrollbar = 106, - scrollBeyondLastColumn = 107, - scrollBeyondLastLine = 108, - scrollPredominantAxis = 109, - selectionClipboard = 110, - selectionHighlight = 111, - selectOnLineNumbers = 112, - showFoldingControls = 113, - showUnused = 114, - snippetSuggestions = 115, - smartSelect = 116, - smoothScrolling = 117, - stickyScroll = 118, - stickyTabStops = 119, - stopRenderingLineAfter = 120, - suggest = 121, - suggestFontSize = 122, - suggestLineHeight = 123, - suggestOnTriggerCharacters = 124, - suggestSelection = 125, - tabCompletion = 126, - tabIndex = 127, - unicodeHighlighting = 128, - unusualLineTerminators = 129, - useShadowDOM = 130, - useTabStops = 131, - wordBreak = 132, - wordSegmenterLocales = 133, - wordSeparators = 134, - wordWrap = 135, - wordWrapBreakAfterCharacters = 136, - wordWrapBreakBeforeCharacters = 137, - wordWrapColumn = 138, - wordWrapOverride1 = 139, - wordWrapOverride2 = 140, - wrappingIndent = 141, - wrappingStrategy = 142, - showDeprecated = 143, - inlayHints = 144, - editorClassName = 145, - pixelRatio = 146, - tabFocusMode = 147, - layoutInfo = 148, - wrappingInfo = 149, - defaultColorDecorators = 150, - colorDecoratorsActivatedOn = 151, - inlineCompletionsAccessibilityVerbose = 152 + getTargetAtClientPoint(clientX: number, clientY: number): IMouseTarget | null; + /** + * 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; + } | null; + /** + * 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. + * This is the best place to compute data for the viewport (such as tokens). + */ + handleInitialized?(): void; } - export const EditorOptions: { - acceptSuggestionOnCommitCharacter: IEditorOption; - acceptSuggestionOnEnter: IEditorOption; - accessibilitySupport: IEditorOption; - accessibilityPageSize: IEditorOption; - ariaLabel: IEditorOption; - ariaRequired: IEditorOption; - screenReaderAnnounceInlineSuggestion: IEditorOption; - autoClosingBrackets: IEditorOption; - autoClosingComments: IEditorOption; - autoClosingDelete: IEditorOption; - autoClosingOvertype: IEditorOption; - autoClosingQuotes: IEditorOption; - autoIndent: IEditorOption; - automaticLayout: IEditorOption; - autoSurround: IEditorOption; - bracketPairColorization: IEditorOption>>; - bracketPairGuides: IEditorOption>>; - stickyTabStops: IEditorOption; - codeLens: IEditorOption; - codeLensFontFamily: IEditorOption; - codeLensFontSize: IEditorOption; - colorDecorators: IEditorOption; - colorDecoratorActivatedOn: IEditorOption; - colorDecoratorsLimit: IEditorOption; - columnSelection: IEditorOption; - comments: IEditorOption>>; - contextmenu: IEditorOption; - copyWithSyntaxHighlighting: IEditorOption; - cursorBlinking: IEditorOption; - cursorSmoothCaretAnimation: IEditorOption; - cursorStyle: IEditorOption; - cursorSurroundingLines: IEditorOption; - cursorSurroundingLinesStyle: IEditorOption; - cursorWidth: IEditorOption; - disableLayerHinting: IEditorOption; - disableMonospaceOptimizations: IEditorOption; - domReadOnly: IEditorOption; - dragAndDrop: IEditorOption; - emptySelectionClipboard: IEditorOption; - dropIntoEditor: IEditorOption>>; - experimentalEditContextEnabled: IEditorOption; - stickyScroll: IEditorOption>>; - experimentalGpuAcceleration: IEditorOption; - experimentalWhitespaceRendering: IEditorOption; - extraEditorClassName: IEditorOption; - fastScrollSensitivity: IEditorOption; - find: IEditorOption>>; - fixedOverflowWidgets: IEditorOption; - folding: IEditorOption; - foldingStrategy: IEditorOption; - foldingHighlight: IEditorOption; - foldingImportsByDefault: IEditorOption; - foldingMaximumRegions: IEditorOption; - unfoldOnClickAfterEndOfLine: IEditorOption; - fontFamily: IEditorOption; - fontInfo: IEditorOption; - fontLigatures2: IEditorOption; - fontSize: IEditorOption; - fontWeight: IEditorOption; - fontVariations: IEditorOption; - formatOnPaste: IEditorOption; - formatOnType: IEditorOption; - glyphMargin: IEditorOption; - gotoLocation: IEditorOption>>; - hideCursorInOverviewRuler: IEditorOption; - hover: IEditorOption>>; - inDiffEditor: IEditorOption; - letterSpacing: IEditorOption; - lightbulb: IEditorOption>>; - lineDecorationsWidth: IEditorOption; - lineHeight: IEditorOption; - lineNumbers: IEditorOption; - lineNumbersMinChars: IEditorOption; - linkedEditing: IEditorOption; - links: IEditorOption; - matchBrackets: IEditorOption; - minimap: IEditorOption>>; - mouseStyle: IEditorOption; - mouseWheelScrollSensitivity: IEditorOption; - mouseWheelZoom: IEditorOption; - multiCursorMergeOverlapping: IEditorOption; - multiCursorModifier: IEditorOption; - multiCursorPaste: IEditorOption; - multiCursorLimit: IEditorOption; - occurrencesHighlight: IEditorOption; - occurrencesHighlightDelay: IEditorOption; - overviewRulerBorder: IEditorOption; - overviewRulerLanes: IEditorOption; - padding: IEditorOption>>; - pasteAs: IEditorOption>>; - parameterHints: IEditorOption>>; - peekWidgetDefaultFocus: IEditorOption; - placeholder: IEditorOption; - definitionLinkOpensInPeek: IEditorOption; - quickSuggestions: IEditorOption; - quickSuggestionsDelay: IEditorOption; - readOnly: IEditorOption; - readOnlyMessage: IEditorOption; - renameOnType: IEditorOption; - renderControlCharacters: IEditorOption; - renderFinalNewline: IEditorOption; - renderLineHighlight: IEditorOption; - renderLineHighlightOnlyWhenFocus: IEditorOption; - renderValidationDecorations: IEditorOption; - renderWhitespace: IEditorOption; - revealHorizontalRightPadding: IEditorOption; - roundedSelection: IEditorOption; - rulers: IEditorOption; - scrollbar: IEditorOption; - scrollBeyondLastColumn: IEditorOption; - scrollBeyondLastLine: IEditorOption; - scrollPredominantAxis: IEditorOption; - selectionClipboard: IEditorOption; - selectionHighlight: IEditorOption; - selectOnLineNumbers: IEditorOption; - showFoldingControls: IEditorOption; - showUnused: IEditorOption; - showDeprecated: IEditorOption; - inlayHints: IEditorOption>>; - snippetSuggestions: IEditorOption; - smartSelect: IEditorOption>>; - smoothScrolling: IEditorOption; - stopRenderingLineAfter: IEditorOption; - suggest: IEditorOption>>; - inlineSuggest: IEditorOption>>; - inlineCompletionsAccessibilityVerbose: IEditorOption; - suggestFontSize: IEditorOption; - suggestLineHeight: IEditorOption; - suggestOnTriggerCharacters: IEditorOption; - suggestSelection: IEditorOption; - tabCompletion: IEditorOption; - tabIndex: IEditorOption; - unicodeHighlight: IEditorOption; - unusualLineTerminators: IEditorOption; - useShadowDOM: IEditorOption; - useTabStops: IEditorOption; - wordBreak: IEditorOption; - wordSegmenterLocales: IEditorOption; - wordSeparators: IEditorOption; - wordWrap: IEditorOption; - wordWrapBreakAfterCharacters: IEditorOption; - wordWrapBreakBeforeCharacters: IEditorOption; - wordWrapColumn: IEditorOption; - wordWrapOverride1: IEditorOption; - wordWrapOverride2: IEditorOption; - editorClassName: IEditorOption; - defaultColorDecorators: IEditorOption; - pixelRatio: IEditorOption; - tabFocusMode: IEditorOption; - layoutInfo: IEditorOption; - wrappingInfo: IEditorOption; - wrappingIndent: IEditorOption; - wrappingStrategy: IEditorOption; - }; + /** + * @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} + */ + getContainerDomNode(): HTMLElement; + /** + * An event emitted when the diff information computed by this diff editor has been updated. + * @event + */ + readonly onDidUpdateDiff: IEvent; + /** + * An event emitted when the diff model is changed (i.e. the diff editor shows new content). + * @event + */ + readonly onDidChangeModel: IEvent; + /** + * Saves current view state of the editor in a serializable object. + */ + saveViewState(): IDiffEditorViewState | null; + /** + * Restores the view state of the editor from a serializable object generated by `saveViewState`. + */ + restoreViewState(state: IDiffEditorViewState | null): void; + /** + * Type the getModel() of IEditor. + */ + getModel(): IDiffEditorModel | null; + createViewModel(model: IDiffEditorModel): IDiffEditorViewModel; + /** + * Sets the current model attached to this editor. + * If the previous model was created by the editor via the value key in the options + * literal object, it will be destroyed. Otherwise, if the previous model was set + * via setModel, or the model key in the options literal object, the previous model + * will not be destroyed. + * It is safe to call setModel(null) to simply detach the current model from the editor. + */ + setModel(model: IDiffEditorModel | IDiffEditorViewModel | null): void; + /** + * Get the `original` editor. + */ + getOriginalEditor(): ICodeEditor; + /** + * Get the `modified` editor. + */ + getModifiedEditor(): ICodeEditor; + /** + * 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.) + */ + revealFirstDiff(): unknown; + accessibleDiffViewerNext(): void; + accessibleDiffViewerPrev(): void; + handleInitialized(): void; + } - type EditorOptionsType = typeof EditorOptions; + 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; + } - type FindEditorOptionsKeyById = { - [K in keyof EditorOptionsType]: EditorOptionsType[K]['id'] extends T ? K : never; - }[keyof EditorOptionsType]; + 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; + } - type ComputedEditorOptionValue> = T extends IEditorOption ? R : never; + /** + * Vertical Lane in the overview ruler of the editor. + */ + export enum OverviewRulerLane { + Left = 1, + Center = 2, + Right = 4, + Full = 7 + } - export type FindComputedEditorOptionValueById = NonNullable]>>; + /** + * Vertical Lane in the glyph margin of the editor. + */ + export enum GlyphMarginLane { + Left = 1, + Center = 2, + Right = 3 + } - export interface IEditorConstructionOptions extends IEditorOptions { + export interface IGlyphMarginLanesModel { /** - * The initial editor dimension (to avoid measuring the container). + * The number of lanes that should be rendered in the editor. */ - dimension?: IDimension; + readonly requiredLanes: number; /** - * Place overflow widgets inside an external DOM node. - * Defaults to an internal DOM node. + * Gets the lanes that should be rendered starting at a given line number. */ - overflowWidgetsDomNode?: HTMLElement; + 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; } /** - * A view zone is a full horizontal rectangle that 'pushes' text down. - * The editor reserves space for view zones when rendering. + * Position in the minimap to render the decoration. */ - export interface IViewZone { + export enum MinimapPosition { + Inline = 1, + Gutter = 2 + } + + /** + * Section header style. + */ + export enum MinimapSectionHeaderStyle { + Normal = 1, + Underlined = 2 + } + + export interface IDecorationOptions { /** - * The line number after which this zone should appear. - * Use 0 to place a view zone before the first line number. + * CSS color to render. + * e.g.: rgba(100, 100, 100, 0.5) or a color from the color registry */ - afterLineNumber: number; + color: string | ThemeColor | undefined; /** - * The column after which this zone should appear. - * If not set, the maxLineColumn of `afterLineNumber` will be used. - * This is relevant for wrapped lines. + * CSS color to render. + * e.g.: rgba(100, 100, 100, 0.5) or a color from the color registry */ - afterColumn?: number; + darkColor?: string | ThemeColor; + } + + export interface IModelDecorationGlyphMarginOptions { /** - * If the `afterColumn` has multiple view columns, the affinity specifies which one to use. Defaults to `none`. - */ - afterColumnAffinity?: PositionAffinity; + * The position in the glyph margin. + */ + position: GlyphMarginLane; /** - * Render the zone even when its line is hidden. + * Whether the glyph margin lane in {@link position} should be rendered even + * outside of this decoration's range. */ - showInHiddenAreas?: boolean; + persistLane?: boolean; + } + + /** + * Options for rendering a model decoration in the overview ruler. + */ + export interface IModelDecorationOverviewRulerOptions extends IDecorationOptions { /** - * Tiebreaker that is used when multiple view zones want to be after the same line. - * Defaults to `afterColumn` otherwise 10000; + * The position in the overview ruler. */ - ordinal?: number; + position: OverviewRulerLane; + } + + /** + * Options for rendering a model decoration in the minimap. + */ + export interface IModelDecorationMinimapOptions extends IDecorationOptions { /** - * Suppress mouse down events. - * If set, the editor will attach a mouse down listener to the view zone and .preventDefault on it. - * Defaults to false + * The position in the minimap. */ - suppressMouseDown?: boolean; + position: MinimapPosition; /** - * The height in lines of the view zone. - * If specified, `heightInPx` will be used instead of this. - * If neither `heightInPx` nor `heightInLines` is specified, a default of `heightInLines` = 1 will be chosen. + * 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 { + /** + * 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; + /** + * 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; + /** + * 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. */ - heightInLines?: number; + zIndex?: number; /** - * The height in px of the view zone. - * If this is set, the editor will give preference to it rather than `heightInLines` above. - * If neither `heightInPx` nor `heightInLines` is specified, a default of `heightInLines` = 1 will be chosen. + * If set, render this decoration in the overview ruler. */ - heightInPx?: number; + overviewRuler?: IModelDecorationOverviewRulerOptions | null; /** - * The minimum width in px of the view zone. - * If this is set, the editor will ensure that the scroll width is >= than this value. + * If set, render this decoration in the minimap. */ - minWidthInPx?: number; + minimap?: IModelDecorationMinimapOptions | null; /** - * The dom node of the view zone + * If set, the decoration will be rendered in the glyph margin with this CSS class name. */ - domNode: HTMLElement; + glyphMarginClassName?: string | null; /** - * An optional dom node for the view zone that will be placed in the margin area. + * If set and the decoration has {@link glyphMarginClassName} set, render this decoration + * with the specified {@link IModelDecorationGlyphMarginOptions} in the glyph margin. */ - marginDomNode?: HTMLElement | null; + glyphMargin?: IModelDecorationGlyphMarginOptions | null; /** - * Callback which gives the relative top of the view zone as it appears (taking scrolling into account). + * If set, the decoration will be rendered in the lines decorations with this CSS class name. */ - onDomNodeTop?: (top: number) => void; + linesDecorationsClassName?: string | null; /** - * Callback which gives the height in pixels of the view zone. + * Controls the tooltip text of the line decoration. */ - onComputedHeight?: (height: number) => void; - } - - /** - * An accessor that allows for zones to be added or removed. - */ - export interface IViewZoneChangeAccessor { + linesDecorationsTooltip?: string | null; /** - * Create a new view zone. - * @param zone Zone to create - * @return A unique identifier to the view zone. + * If set, the decoration will be rendered on the line number. */ - addZone(zone: IViewZone): string; + lineNumberClassName?: string | null; /** - * Remove a zone - * @param id A unique identifier to the view zone, as returned by the `addZone` call. + * 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. */ - removeZone(id: string): void; + firstLineDecorationClassName?: string | null; /** - * Change a zone's position. - * The editor will rescan the `afterLineNumber` and `afterColumn` properties of a view zone. + * If set, the decoration will be rendered in the margin (covering its full width) with this CSS class name. */ - layoutZone(id: string): void; - } - - /** - * A positioning preference for rendering content widgets. - */ - export enum ContentWidgetPositionPreference { + marginClassName?: string | null; /** - * Place the content widget exactly at a position + * 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. */ - EXACT = 0, + inlineClassName?: string | null; /** - * Place the content widget above a position + * If there is an `inlineClassName` which affects letter spacing. */ - ABOVE = 1, + inlineClassNameAffectsLetterSpacing?: boolean; /** - * Place the content widget below a position + * If set, the decoration will be rendered before the text with this CSS class name. */ - BELOW = 2 - } - - /** - * A position for rendering content widgets. - */ - export interface IContentWidgetPosition { + beforeContentClassName?: string | null; /** - * Desired position which serves as an anchor for placing the content widget. - * The widget will be placed above, at, or below the specified position, based on the - * provided preference. The widget will always touch this position. - * - * Given sufficient horizontal space, the widget will be placed to the right of the - * passed in position. This can be tweaked by providing a `secondaryPosition`. - * - * @see preference - * @see secondaryPosition + * If set, the decoration will be rendered after the text with this CSS class name. */ - position: IPosition | null; + afterContentClassName?: string | null; /** - * Optionally, a secondary position can be provided to further define the placing of - * the content widget. The secondary position must have the same line number as the - * primary position. If possible, the widget will be placed such that it also touches - * the secondary position. + * If set, text will be injected in the view after the range. */ - secondaryPosition?: IPosition | null; + after?: InjectedTextOptions | null; /** - * Placement preference for position, in order of preference. + * If set, text will be injected in the view before the range. */ - preference: ContentWidgetPositionPreference[]; + before?: InjectedTextOptions | null; /** - * Placement preference when multiple view positions refer to the same (model) position. - * This plays a role when injected text is involved. + * If set, this decoration will not be rendered for comment tokens. + * @internal */ - positionAffinity?: PositionAffinity; + hideInCommentTokens?: boolean | null; + /** + * If set, this decoration will not be rendered for string tokens. + * @internal + */ + hideInStringTokens?: boolean | null; } /** - * A content widget renders inline with the text and can be easily placed 'near' an editor position. - */ - export interface IContentWidget { - /** - * Render this content widget in a location where it could overflow the editor's view dom node. - */ - allowEditorOverflow?: boolean; + * Configures text that is injected into the view without changing the underlying document. + */ + export interface InjectedTextOptions { /** - * Call preventDefault() on mousedown events that target the content widget. + * Sets the text to inject. Must be a single line. */ - suppressMouseDown?: boolean; + readonly content: string; /** - * Get a unique identifier of the content widget. - */ - getId(): string; + * @internal + */ + readonly tokens?: TokenArray | null; /** - * Get the dom node of the content widget. + * If set, the decoration will be rendered inline with the text with this CSS class name. */ - getDomNode(): HTMLElement; + readonly inlineClassName?: string | null; /** - * Get the placement of the content widget. - * If null is returned, the content widget will be placed off screen. + * If there is an `inlineClassName` which affects letter spacing. */ - getPosition(): IContentWidgetPosition | null; + readonly inlineClassNameAffectsLetterSpacing?: boolean; /** - * Optional function that is invoked before rendering - * the content widget. If a dimension is returned the editor will - * attempt to use it. + * This field allows to attach data to this injected text. + * The data can be read when injected texts at a given position are queried. */ - beforeRender?(): IDimension | null; + readonly attachedData?: unknown; /** - * Optional function that is invoked after rendering the content - * widget. Is being invoked with the selected position preference - * or `null` if not rendered. - */ - afterRender?(position: ContentWidgetPositionPreference | null): void; + * 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 } /** - * A positioning preference for rendering overlay widgets. + * New model decorations. */ - export enum OverlayWidgetPositionPreference { - /** - * Position the overlay widget in the top right corner - */ - TOP_RIGHT_CORNER = 0, + export interface IModelDeltaDecoration { /** - * Position the overlay widget in the bottom right corner + * Range that this decoration covers. */ - BOTTOM_RIGHT_CORNER = 1, + range: IRange; /** - * Position the overlay widget in the top center + * Options associated with this decoration. */ - TOP_CENTER = 2 + options: IModelDecorationOptions; } /** - * Represents editor-relative coordinates of an overlay widget. + * A decoration in the model. */ - export interface IOverlayWidgetPositionCoordinates { + export interface IModelDecoration { /** - * The top position for the overlay widget, relative to the editor. + * Identifier for a decoration. */ - top: number; + readonly id: string; /** - * The left position for the overlay widget, relative to the editor. + * Identifier for a decoration's owner. */ - left: number; - } - - /** - * A position for rendering overlay widgets. - */ - export interface IOverlayWidgetPosition { + readonly ownerId: number; /** - * The position preference for the overlay widget. + * Range that this decoration covers. */ - preference: OverlayWidgetPositionPreference | IOverlayWidgetPositionCoordinates | null; + readonly range: Range; /** - * When set, stacks with other overlay widgets with the same preference, - * in an order determined by the ordinal value. + * Options associated with this decoration. */ - stackOridinal?: number; + readonly options: IModelDecorationOptions; } /** - * An overlay widgets renders on top of the text. + * An accessor that can add, change or remove model decorations. + * @internal */ - export interface IOverlayWidget { - /** - * Event fired when the widget layout changes. - */ - onDidLayout?: IEvent; + export interface IModelDecorationsChangeAccessor { /** - * Render this overlay widget in a location where it could overflow the editor's view dom node. + * 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. */ - allowEditorOverflow?: boolean; + addDecoration(range: IRange, options: IModelDecorationOptions): string; /** - * Get a unique identifier of the overlay widget. + * 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. */ - getId(): string; + changeDecoration(id: string, newRange: IRange): void; /** - * Get the dom node of the overlay widget. + * 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. */ - getDomNode(): HTMLElement; + changeDecorationOptions(id: string, newOptions: IModelDecorationOptions): void; /** - * Get the placement of the overlay widget. - * If null is returned, the overlay widget is responsible to place itself. + * Remove an existing decoration. + * @param id The unique identifier associated with the decoration. */ - getPosition(): IOverlayWidgetPosition | null; + removeDecoration(id: string): void; /** - * The editor will ensure that the scroll width is >= than this value. + * 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. */ - getMinContentWidthInPx?(): number; + deltaDecorations(oldDecorations: readonly string[], newDecorations: readonly IModelDeltaDecoration[]): string[]; } /** - * A glyph margin widget renders in the editor glyph margin. + * End of line character preference. */ - export interface IGlyphMarginWidget { + export enum EndOfLinePreference { /** - * Get a unique identifier of the glyph widget. + * Use the end of line character identified in the text buffer. */ - getId(): string; + TextDefined = 0, /** - * Get the dom node of the glyph widget. + * Use line feed (\n) as the end of line character. */ - getDomNode(): HTMLElement; + LF = 1, /** - * Get the placement of the glyph widget. + * Use carriage return and line feed (\r\n) as the end of line character. */ - getPosition(): IGlyphMarginWidgetPosition; + CRLF = 2 } /** - * A position for rendering glyph margin widgets. + * The default end of line to use when instantiating models. */ - export interface IGlyphMarginWidgetPosition { - /** - * The glyph margin lane where the widget should be shown. - */ - lane: GlyphMarginLane; + export enum DefaultEndOfLine { /** - * The priority order of the widget, used for determining which widget - * to render when there are multiple. + * Use line feed (\n) as the end of line character. */ - zIndex: number; + LF = 1, /** - * The editor range that this widget applies to. + * Use carriage return and line feed (\r\n) as the end of line character. */ - range: IRange; + CRLF = 2 } /** - * Type of hit element with the mouse in the editor. + * End of line character preference. */ - export enum MouseTargetType { - /** - * Mouse is on top of an unknown element. - */ - UNKNOWN = 0, - /** - * Mouse is on top of the textarea used for input. - */ - TEXTAREA = 1, - /** - * Mouse is on top of the glyph margin - */ - GUTTER_GLYPH_MARGIN = 2, + export enum EndOfLineSequence { /** - * Mouse is on top of the line numbers + * Use line feed (\n) as the end of line character. */ - GUTTER_LINE_NUMBERS = 3, + LF = 0, /** - * Mouse is on top of the line decorations + * Use carriage return and line feed (\r\n) as the end of line character. */ - GUTTER_LINE_DECORATIONS = 4, + CRLF = 1 + } + + /** + * An identifier for a single edit operation. + * @internal + */ + export interface ISingleEditOperationIdentifier { /** - * Mouse is on top of the whitespace left in the gutter by a view zone. + * Identifier major */ - GUTTER_VIEW_ZONE = 5, + major: number; /** - * Mouse is on top of text in the content. + * Identifier minor */ - CONTENT_TEXT = 6, + minor: number; + } + + /** + * A single edit operation, that has an identifier. + */ + export interface IIdentifiedSingleEditOperation extends ISingleEditOperation { /** - * Mouse is on top of empty space in the content (e.g. after line text or below last line) + * An identifier associated with this single edit operation. + * @internal */ - CONTENT_EMPTY = 7, + identifier?: ISingleEditOperationIdentifier | null; /** - * Mouse is on top of a view zone in the content. + * This indicates that this operation is inserting automatic whitespace + * that can be removed on next model edit operation if `config.trimAutoWhitespace` is true. + * @internal */ - CONTENT_VIEW_ZONE = 8, + isAutoWhitespaceEdit?: boolean; /** - * Mouse is on top of a content widget. + * This indicates that this operation is in a set of operations that are tracked and should not be "simplified". + * @internal */ - CONTENT_WIDGET = 9, + _isTracked?: boolean; + } + + export interface IValidEditOperation { /** - * Mouse is on top of the decorations overview ruler. + * An identifier associated with this single edit operation. + * @internal */ - OVERVIEW_RULER = 10, + identifier: ISingleEditOperationIdentifier | null; /** - * Mouse is on top of a scrollbar. + * The range to replace. This can be empty to emulate a simple insert. */ - SCROLLBAR = 11, + range: Range; /** - * Mouse is on top of an overlay widget. + * The text to replace with. This can be empty to emulate a simple delete. */ - OVERLAY_WIDGET = 12, + text: string; /** - * Mouse is outside of the editor. + * @internal */ - OUTSIDE_EDITOR = 13 + textChange: any; } - export interface IBaseMouseTarget { + /** + * A callback that can compute the cursor state after applying a series of edit operations. + */ + export interface ICursorStateComputer { /** - * The target element + * A callback that can compute the resulting cursors state after some edit operations have been executed. */ - readonly element: HTMLElement | null; + (inverseEditOperations: IValidEditOperation[]): Selection[] | null; + } + + export class TextModelResolvedOptions { + _textModelResolvedOptionsBrand: void; + readonly tabSize: number; + readonly indentSize: number; + readonly _indentSizeIsTabSize: boolean; + readonly insertSpaces: boolean; + readonly defaultEOL: DefaultEndOfLine; + readonly trimAutoWhitespace: boolean; + readonly bracketPairColorizationOptions: BracketPairColorizationOptions; + get originalIndentSize(): number | 'tabSize'; /** - * The 'approximate' editor position + * @internal */ - readonly position: Position | null; + constructor(src: { + tabSize: number; + indentSize: number | 'tabSize'; + insertSpaces: boolean; + defaultEOL: DefaultEndOfLine; + trimAutoWhitespace: boolean; + bracketPairColorizationOptions: BracketPairColorizationOptions; + }); /** - * Desired mouse column (e.g. when position.column gets clamped to text length -- clicking after text on a line). + * @internal */ - readonly mouseColumn: number; + equals(other: TextModelResolvedOptions): boolean; /** - * The 'approximate' editor range + * @internal */ - readonly range: Range | null; - } - - export interface IMouseTargetUnknown extends IBaseMouseTarget { - readonly type: MouseTargetType.UNKNOWN; - } - - export interface IMouseTargetTextarea extends IBaseMouseTarget { - readonly type: MouseTargetType.TEXTAREA; - readonly position: null; - readonly range: null; - } - - export interface IMouseTargetMarginData { - readonly isAfterLines: boolean; - readonly glyphMarginLeft: number; - readonly glyphMarginWidth: number; - readonly glyphMarginLane?: GlyphMarginLane; - readonly lineNumbersWidth: number; - readonly offsetX: number; - } - - export interface IMouseTargetMargin extends IBaseMouseTarget { - readonly type: MouseTargetType.GUTTER_GLYPH_MARGIN | MouseTargetType.GUTTER_LINE_NUMBERS | MouseTargetType.GUTTER_LINE_DECORATIONS; - readonly position: Position; - readonly range: Range; - readonly detail: IMouseTargetMarginData; - } - - export interface IMouseTargetViewZoneData { - readonly viewZoneId: string; - readonly positionBefore: Position | null; - readonly positionAfter: Position | null; - readonly position: Position; - readonly afterLineNumber: number; - } - - export interface IMouseTargetViewZone extends IBaseMouseTarget { - readonly type: MouseTargetType.GUTTER_VIEW_ZONE | MouseTargetType.CONTENT_VIEW_ZONE; - readonly position: Position; - readonly range: Range; - readonly detail: IMouseTargetViewZoneData; + createChangeEvent(newOpts: TextModelResolvedOptions): IModelOptionsChangedEvent; } - export interface IMouseTargetContentTextData { - readonly mightBeForeignElement: boolean; - } - - export interface IMouseTargetContentText extends IBaseMouseTarget { - readonly type: MouseTargetType.CONTENT_TEXT; - readonly position: Position; - readonly range: Range; - readonly detail: IMouseTargetContentTextData; - } - - export interface IMouseTargetContentEmptyData { - readonly isAfterLines: boolean; - readonly horizontalDistanceToText?: number; - } - - export interface IMouseTargetContentEmpty extends IBaseMouseTarget { - readonly type: MouseTargetType.CONTENT_EMPTY; - readonly position: Position; - readonly range: Range; - readonly detail: IMouseTargetContentEmptyData; + /** + * @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 IMouseTargetContentWidget extends IBaseMouseTarget { - readonly type: MouseTargetType.CONTENT_WIDGET; - readonly position: null; - readonly range: null; - readonly detail: string; + export interface BracketPairColorizationOptions { + enabled: boolean; + independentColorPoolPerBracketType: boolean; } - export interface IMouseTargetOverlayWidget extends IBaseMouseTarget { - readonly type: MouseTargetType.OVERLAY_WIDGET; - readonly position: null; - readonly range: null; - readonly detail: string; + export interface ITextModelUpdateOptions { + tabSize?: number; + indentSize?: number | 'tabSize'; + insertSpaces?: boolean; + trimAutoWhitespace?: boolean; + bracketColorizationOptions?: BracketPairColorizationOptions; } - export interface IMouseTargetScrollbar extends IBaseMouseTarget { - readonly type: MouseTargetType.SCROLLBAR; - readonly position: Position; + export class FindMatch { + _findMatchBrand: void; readonly range: Range; - } - - export interface IMouseTargetOverviewRuler extends IBaseMouseTarget { - readonly type: MouseTargetType.OVERVIEW_RULER; - } - - export interface IMouseTargetOutsideEditor extends IBaseMouseTarget { - readonly type: MouseTargetType.OUTSIDE_EDITOR; - readonly outsidePosition: 'above' | 'below' | 'left' | 'right'; - readonly outsideDistance: number; + readonly matches: string[] | null; + /** + * @internal + */ + constructor(range: Range, matches: string[] | null); } /** - * Target hit with the mouse in the editor. + * 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 type IMouseTarget = (IMouseTargetUnknown | IMouseTargetTextarea | IMouseTargetMargin | IMouseTargetViewZone | IMouseTargetContentText | IMouseTargetContentEmpty | IMouseTargetContentWidget | IMouseTargetOverlayWidget | IMouseTargetScrollbar | IMouseTargetOverviewRuler | IMouseTargetOutsideEditor); + export enum TrackedRangeStickiness { + AlwaysGrowsWhenTypingAtEdges = 0, + NeverGrowsWhenTypingAtEdges = 1, + GrowsOnlyWhenTypingBefore = 2, + GrowsOnlyWhenTypingAfter = 3 + } /** - * A mouse event originating from the editor. + * Text snapshot that works like an iterator. + * Will try to return chunks of roughly ~64KB size. + * Will return null when finished. */ - export interface IEditorMouseEvent { - readonly event: IMouseEvent; - readonly target: IMouseTarget; - } - - export interface IPartialEditorMouseEvent { - readonly event: IMouseEvent; - readonly target: IMouseTarget | null; + export interface ITextSnapshot { + read(): string | null; } /** - * A paste event originating from the editor. + * A model. */ - export interface IPasteEvent { - readonly range: Range; - readonly languageId: string | null; - readonly clipboardEvent?: ClipboardEvent; - } - - export interface IDiffEditorConstructionOptions extends IDiffEditorOptions, IEditorConstructionOptions { - /** - * Place overflow widgets inside an external DOM node. - * Defaults to an internal DOM node. - */ - overflowWidgetsDomNode?: HTMLElement; - /** - * Aria label for original editor. - */ - originalAriaLabel?: string; + export interface ITextModel { /** - * Aria label for modified editor. + * Gets the resource associated with this editor model. */ - modifiedAriaLabel?: string; - } - - /** - * A rich code editor. - */ - export interface ICodeEditor extends IEditor { + readonly uri: Uri; /** - * An event emitted when the content of the current model has changed. - * @event + * A unique identifier associated with this model. */ - readonly onDidChangeModelContent: IEvent; + readonly id: string; /** - * An event emitted when the language of the current model has changed. - * @event + * This model is constructed for a simple widget code editor. + * @internal */ - readonly onDidChangeModelLanguage: IEvent; + readonly isForSimpleWidget: boolean; /** - * An event emitted when the language configuration of the current model has changed. - * @event + * If true, the text model might contain RTL. + * If false, the text model **contains only** contain LTR. + * @internal */ - readonly onDidChangeModelLanguageConfiguration: IEvent; + mightContainRTL(): boolean; /** - * An event emitted when the options of the current model has changed. - * @event + * If true, the text model might contain LINE SEPARATOR (LS), PARAGRAPH SEPARATOR (PS). + * If false, the text model definitely does not contain these. + * @internal */ - readonly onDidChangeModelOptions: IEvent; + mightContainUnusualLineTerminators(): boolean; /** - * An event emitted when the configuration of the editor has changed. (e.g. `editor.updateOptions()`) - * @event + * @internal */ - readonly onDidChangeConfiguration: IEvent; + removeUnusualLineTerminators(selections?: Selection[]): void; /** - * An event emitted when the cursor position has changed. - * @event + * If true, the text model might contain non basic ASCII. + * If false, the text model **contains only** basic ASCII. + * @internal */ - readonly onDidChangeCursorPosition: IEvent; + mightContainNonBasicASCII(): boolean; /** - * An event emitted when the cursor selection has changed. - * @event + * Get the resolved options for this model. */ - readonly onDidChangeCursorSelection: IEvent; + getOptions(): TextModelResolvedOptions; /** - * An event emitted when the model of this editor is about to change (e.g. from `editor.setModel()`). - * @event + * Get the formatting options for this model. + * @internal */ - readonly onWillChangeModel: IEvent; + getFormattingOptions(): languages.FormattingOptions; /** - * An event emitted when the model of this editor has changed (e.g. `editor.setModel()`). - * @event + * Get the current version id of the model. + * Anytime a change happens to the model (even undo/redo), + * the version id is incremented. */ - readonly onDidChangeModel: IEvent; + getVersionId(): number; /** - * An event emitted when the decorations of the current model have changed. - * @event + * 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. */ - readonly onDidChangeModelDecorations: IEvent; + getAlternativeVersionId(): number; /** - * An event emitted when the text inside this editor gained focus (i.e. cursor starts blinking). - * @event + * Replace the entire text buffer value contained in this model. */ - readonly onDidFocusEditorText: IEvent; + setValue(newValue: string | ITextSnapshot): void; /** - * An event emitted when the text inside this editor lost focus (i.e. cursor stops blinking). - * @event + * 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. */ - readonly onDidBlurEditorText: IEvent; + getValue(eol?: EndOfLinePreference, preserveBOM?: boolean): string; /** - * An event emitted when the text inside this editor or an editor widget gained focus. - * @event + * 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). */ - readonly onDidFocusEditorWidget: IEvent; + createSnapshot(preserveBOM?: boolean): ITextSnapshot; /** - * An event emitted when the text inside this editor or an editor widget lost focus. - * @event + * Get the length of the text stored in this model. */ - readonly onDidBlurEditorWidget: IEvent; + getValueLength(eol?: EndOfLinePreference, preserveBOM?: boolean): number; /** - * An event emitted after composition has started. + * Check if the raw text stored in this model equals another raw text. + * @internal */ - readonly onDidCompositionStart: IEvent; + equalsTextBuffer(other: ITextBuffer): boolean; /** - * An event emitted after composition has ended. + * Get the underling text buffer. + * @internal */ - readonly onDidCompositionEnd: IEvent; + getTextBuffer(): ITextBuffer; /** - * An event emitted when editing failed because the editor is read-only. - * @event + * 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. */ - readonly onDidAttemptReadOnlyEdit: IEvent; + getValueInRange(range: IRange, eol?: EndOfLinePreference): string; /** - * An event emitted when users paste text in the editor. - * @event + * Get the length of text in a certain range. + * @param range The range describing what text length to get. + * @return The text length. */ - readonly onDidPaste: IEvent; + getValueLengthInRange(range: IRange, eol?: EndOfLinePreference): number; /** - * An event emitted on a "mouseup". - * @event + * Get the character count of text in a certain range. + * @param range The range describing what text length to get. */ - readonly onMouseUp: IEvent; + getCharacterCountInRange(range: IRange, eol?: EndOfLinePreference): number; /** - * An event emitted on a "mousedown". - * @event + * 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 */ - readonly onMouseDown: IEvent; + isDominatedByLongLines(): boolean; /** - * An event emitted on a "contextmenu". - * @event + * Get the number of lines in the model. */ - readonly onContextMenu: IEvent; + getLineCount(): number; /** - * An event emitted on a "mousemove". - * @event + * Get the text for a certain line. */ - readonly onMouseMove: IEvent; + getLineContent(lineNumber: number): string; /** - * An event emitted on a "mouseleave". - * @event + * Get the text length for a certain line. */ - readonly onMouseLeave: IEvent; + getLineLength(lineNumber: number): number; /** - * An event emitted on a "keyup". - * @event + * Get the text for all lines. */ - readonly onKeyUp: IEvent; + getLinesContent(): string[]; /** - * An event emitted on a "keydown". - * @event + * Get the end of line sequence predominantly used in the text buffer. + * @return EOL char sequence (e.g.: '\n' or '\r\n'). */ - readonly onKeyDown: IEvent; + getEOL(): string; /** - * An event emitted when the layout of the editor has changed. - * @event + * Get the end of line sequence predominantly used in the text buffer. */ - readonly onDidLayoutChange: IEvent; + getEndOfLineSequence(): EndOfLineSequence; /** - * An event emitted when the content width or content height in the editor has changed. - * @event + * Get the minimum legal column for line at `lineNumber` */ - readonly onDidContentSizeChange: IEvent; + getLineMinColumn(lineNumber: number): number; /** - * An event emitted when the scroll in the editor has changed. - * @event + * Get the maximum legal column for line at `lineNumber` */ - readonly onDidScrollChange: IEvent; + getLineMaxColumn(lineNumber: number): number; /** - * An event emitted when hidden areas change in the editor (e.g. due to folding). - * @event + * Returns the column before the first non whitespace character for line at `lineNumber`. + * Returns 0 if line is empty or contains only whitespace. */ - readonly onDidChangeHiddenAreas: IEvent; + getLineFirstNonWhitespaceColumn(lineNumber: number): number; /** - * Some editor operations fire multiple events at once. - * To allow users to react to multiple events fired by a single operation, - * the editor fires a begin update before the operation and an end update after the operation. - * Whenever the editor fires `onBeginUpdate`, it will also fire `onEndUpdate` once the operation finishes. - * Note that not all operations are bracketed by `onBeginUpdate` and `onEndUpdate`. - */ - readonly onBeginUpdate: IEvent; + * 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; /** - * Fires after the editor completes the operation it fired `onBeginUpdate` for. - */ - readonly onEndUpdate: IEvent; + * Create a valid position. + */ + validatePosition(position: IPosition): Position; /** - * Saves current view state of the editor in a serializable object. + * 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. */ - saveViewState(): ICodeEditorViewState | null; + modifyPosition(position: IPosition, offset: number): Position; /** - * Restores the view state of the editor from a serializable object generated by `saveViewState`. + * Create a valid range. */ - restoreViewState(state: ICodeEditorViewState | null): void; + validateRange(range: IRange): Range; /** - * Returns true if the text inside this editor or an editor widget has focus. + * 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. */ - hasWidgetFocus(): boolean; + getOffsetAt(position: IPosition): number; /** - * Get a contribution of this editor. - * @id Unique identifier of the contribution. - * @return The contribution or null if contribution not found. + * Converts a zero-based offset to a position. + * + * @param offset A zero-based offset. + * @return A valid [position](#Position). */ - getContribution(id: string): T | null; + getPositionAt(offset: number): Position; /** - * Type the getModel() of IEditor. + * Get a range covering the entire model. */ - getModel(): ITextModel | null; + getFullModelRange(): Range; /** - * Sets the current model attached to this editor. - * If the previous model was created by the editor via the value key in the options - * literal object, it will be destroyed. Otherwise, if the previous model was set - * via setModel, or the model key in the options literal object, the previous model - * will not be destroyed. - * It is safe to call setModel(null) to simply detach the current model from the editor. + * Returns if the model was disposed or not. */ - setModel(model: ITextModel | null): void; + isDisposed(): boolean; /** - * Gets all the editor computed options. + * This model is so large that it would not be a good idea to sync it over + * to web workers or other places. + * @internal */ - getOptions(): IComputedEditorOptions; + isTooLargeForSyncing(): boolean; /** - * Gets a specific editor option. + * The file is so large, that even tokenization is disabled. + * @internal */ - getOption(id: T): FindComputedEditorOptionValueById; + isTooLargeForTokenization(): boolean; /** - * Returns the editor's configuration (without any validation or defaults). + * 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 */ - getRawOptions(): IEditorOptions; + isTooLargeForHeapOperation(): boolean; /** - * Get value of the current model attached to this editor. - * @see {@link ITextModel.getValue} + * 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. */ - getValue(options?: { - preserveBOM: boolean; - lineEnding: string; - }): string; + findMatches(searchString: string, searchOnlyEditableRange: boolean, isRegex: boolean, matchCase: boolean, wordSeparators: string | null, captureMatches: boolean, limitResultCount?: number): FindMatch[]; /** - * Set the value of the current model attached to this editor. - * @see {@link ITextModel.setValue} + * 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. */ - setValue(newValue: string): void; + findMatches(searchString: string, searchScope: IRange | IRange[], isRegex: boolean, matchCase: boolean, wordSeparators: string | null, captureMatches: boolean, limitResultCount?: number): FindMatch[]; /** - * Get the width of the editor's content. - * This is information that is "erased" when computing `scrollWidth = Math.max(contentWidth, width)` + * 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. */ - getContentWidth(): number; + findNextMatch(searchString: string, searchStart: IPosition, isRegex: boolean, matchCase: boolean, wordSeparators: string | null, captureMatches: boolean): FindMatch | null; /** - * Get the scrollWidth of the editor's viewport. + * 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. */ - getScrollWidth(): number; + findPreviousMatch(searchString: string, searchStart: IPosition, isRegex: boolean, matchCase: boolean, wordSeparators: string | null, captureMatches: boolean): FindMatch | null; /** - * Get the scrollLeft of the editor's viewport. + * Get the language associated with this model. */ - getScrollLeft(): number; + getLanguageId(): string; /** - * Get the height of the editor's content. - * This is information that is "erased" when computing `scrollHeight = Math.max(contentHeight, height)` + * 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 */ - getContentHeight(): number; + setLanguage(languageId: string, source?: string): void; /** - * Get the scrollHeight of the editor's viewport. + * 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 */ - getScrollHeight(): number; + setLanguage(languageSelection: languages.ILanguageSelection, source?: string): void; /** - * Get the scrollTop of the editor's viewport. + * Returns the real (inner-most) language mode at a given position. + * The result might be inaccurate. Use `forceTokenization` to ensure accurate tokens. + * @internal */ - getScrollTop(): number; + getLanguageIdAtPosition(lineNumber: number, column: number): string; /** - * Change the scrollLeft of the editor's viewport. + * 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. */ - setScrollLeft(newScrollLeft: number, scrollType?: ScrollType): void; + getWordAtPosition(position: IPosition): IWordAtPosition | null; /** - * Change the scrollTop of the editor's viewport. + * 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. */ - setScrollTop(newScrollTop: number, scrollType?: ScrollType): void; + getWordUntilPosition(position: IPosition): IWordAtPosition; /** - * Change the scroll position of the editor's viewport. + * 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 */ - setScrollPosition(position: INewScrollPosition, scrollType?: ScrollType): void; + changeDecorations(callback: (changeAccessor: IModelDecorationsChangeAccessor) => T, ownerId?: number): T | null; /** - * Check if the editor is currently scrolling towards a different scroll position. + * 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. */ - hasPendingScrollAnimation(): boolean; + deltaDecorations(oldDecorations: string[], newDecorations: IModelDeltaDecoration[], ownerId?: number): string[]; /** - * Get an action that is a contribution to this editor. - * @id Unique identifier of the contribution. - * @return The action or null if action not found. + * Remove all decorations that have been added with this specific ownerId. + * @param ownerId The owner id to search for. + * @internal */ - getAction(id: string): IEditorAction | null; + removeAllDecorationsWithOwnerId(ownerId: number): void; /** - * Execute a command on the editor. - * The edits will land on the undo-redo stack, but no "undo stop" will be pushed. - * @param source The source of the call. - * @param command The command to execute + * Get the options associated with a decoration. + * @param id The decoration id. + * @return The decoration options or null if the decoration was not found. */ - executeCommand(source: string | null | undefined, command: ICommand): void; + getDecorationOptions(id: string): IModelDecorationOptions | null; /** - * Create an "undo stop" in the undo-redo stack. + * Get the range associated with a decoration. + * @param id The decoration id. + * @return The decoration range or null if the decoration was not found. */ - pushUndoStop(): boolean; + getDecorationRange(id: string): Range | null; /** - * Remove the "undo stop" in the undo-redo stack. + * 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 */ - popUndoStop(): boolean; + getLineDecorations(lineNumber: number, ownerId?: number, filterOutValidation?: boolean): IModelDecoration[]; /** - * Execute edits on the editor. - * The edits will land on the undo-redo stack, but no "undo stop" will be pushed. - * @param source The source of the call. - * @param edits The edits to execute. - * @param endCursorState Cursor state after the edits were applied. + * 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 */ - executeEdits(source: string | null | undefined, edits: IIdentifiedSingleEditOperation[], endCursorState?: ICursorStateComputer | Selection[]): boolean; + getLinesDecorations(startLineNumber: number, endLineNumber: number, ownerId?: number, filterOutValidation?: boolean): IModelDecoration[]; /** - * Execute multiple (concomitant) commands on the editor. - * @param source The source of the call. - * @param command The commands to execute + * 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 */ - executeCommands(source: string | null | undefined, commands: (ICommand | null)[]): void; + getDecorationsInRange(range: IRange, ownerId?: number, filterOutValidation?: boolean, onlyMinimapDecorations?: boolean, onlyMarginDecorations?: boolean): IModelDecoration[]; /** - * Get all the decorations on a line (filtering out decorations from other editors). + * 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). */ - getLineDecorations(lineNumber: number): IModelDecoration[] | null; + getAllDecorations(ownerId?: number, filterOutValidation?: boolean): IModelDecoration[]; /** - * Get all the decorations for a range (filtering out decorations from other editors). + * Gets all decorations that render in the glyph margin as an array. + * @param ownerId If set, it will ignore decorations belonging to other owners. */ - getDecorationsInRange(range: Range): IModelDecoration[] | null; + getAllMarginDecorations(ownerId?: number): IModelDecoration[]; /** - * All decorations added through this call will get the ownerId of this editor. - * @deprecated Use `createDecorationsCollection` - * @see createDecorationsCollection + * 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). */ - deltaDecorations(oldDecorations: string[], newDecorations: IModelDeltaDecoration[]): string[]; + getOverviewRulerDecorations(ownerId?: number, filterOutValidation?: boolean): IModelDecoration[]; /** - * Remove previously added decorations. + * Gets all the decorations that contain injected text. + * @param ownerId If set, it will ignore decorations belonging to other owners. */ - removeDecorations(decorationIds: string[]): void; + getInjectedTextDecorations(ownerId?: number): IModelDecoration[]; /** - * Get the layout info for the editor. + * @internal */ - getLayoutInfo(): EditorLayoutInfo; + _getTrackedRange(id: string): Range | null; /** - * Returns the ranges that are currently visible. - * Does not account for horizontal scrolling. + * @internal */ - getVisibleRanges(): Range[]; + _setTrackedRange(id: string | null, newRange: null, newStickiness: TrackedRangeStickiness): null; /** - * Get the vertical position (top offset) for the line's top w.r.t. to the first line. + * @internal */ - getTopForLineNumber(lineNumber: number, includeViewZones?: boolean): number; + _setTrackedRange(id: string | null, newRange: Range, newStickiness: TrackedRangeStickiness): string; /** - * Get the vertical position (top offset) for the line's bottom w.r.t. to the first line. + * Normalize a string containing whitespace according to indentation rules (converts to spaces or to tabs). */ - getBottomForLineNumber(lineNumber: number): number; + normalizeIndentation(str: string): string; /** - * Get the vertical position (top offset) for the position w.r.t. to the first line. + * Change the options of this model. */ - getTopForPosition(lineNumber: number, column: number): number; + updateOptions(newOpts: ITextModelUpdateOptions): void; /** - * Write the screen reader content to be the current selection + * Detect the indentation options for this model from its content. */ - writeScreenReaderContent(reason: string): void; + detectIndentation(defaultInsertSpaces: boolean, defaultTabSize: number): void; /** - * Returns the editor's container dom node + * Close the current undo-redo element. + * This offers a way to create an undo/redo stop point. */ - getContainerDomNode(): HTMLElement; + pushStackElement(): void; /** - * Returns the editor's dom node + * Open the current undo-redo element. + * This offers a way to remove the current undo/redo stop point. */ - getDomNode(): HTMLElement | null; + popStackElement(): void; /** - * Add a content widget. Widgets must have unique ids, otherwise they will be overwritten. + * 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`. */ - addContentWidget(widget: IContentWidget): void; + pushEditOperations(beforeCursorState: Selection[] | null, editOperations: IIdentifiedSingleEditOperation[], cursorStateComputer: ICursorStateComputer): Selection[] | null; /** - * Layout/Reposition a content widget. This is a ping to the editor to call widget.getPosition() - * and update appropriately. + * @internal */ - layoutContentWidget(widget: IContentWidget): void; + pushEditOperations(beforeCursorState: Selection[] | null, editOperations: IIdentifiedSingleEditOperation[], cursorStateComputer: ICursorStateComputer, group?: any): Selection[] | null; /** - * Remove a content widget. + * Change the end of line sequence. This is the preferred way of + * changing the eol sequence. This will land on the undo stack. */ - removeContentWidget(widget: IContentWidget): void; + pushEOL(eol: EndOfLineSequence): void; /** - * Add an overlay widget. Widgets must have unique ids, otherwise they will be overwritten. + * 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. */ - addOverlayWidget(widget: IOverlayWidget): void; + applyEdits(operations: IIdentifiedSingleEditOperation[]): void; + applyEdits(operations: IIdentifiedSingleEditOperation[], computeUndoEdits: false): void; + applyEdits(operations: IIdentifiedSingleEditOperation[], computeUndoEdits: true): IValidEditOperation[]; /** - * Layout/Reposition an overlay widget. This is a ping to the editor to call widget.getPosition() - * and update appropriately. + * 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. */ - layoutOverlayWidget(widget: IOverlayWidget): void; + setEOL(eol: EndOfLineSequence): void; /** - * Remove an overlay widget. + * @internal */ - removeOverlayWidget(widget: IOverlayWidget): void; + _applyUndo(changes: any[], eol: EndOfLineSequence, resultingAlternativeVersionId: number, resultingSelection: Selection[] | null): void; /** - * Add a glyph margin widget. Widgets must have unique ids, otherwise they will be overwritten. + * @internal */ - addGlyphMarginWidget(widget: IGlyphMarginWidget): void; + _applyRedo(changes: any[], eol: EndOfLineSequence, resultingAlternativeVersionId: number, resultingSelection: Selection[] | null): void; /** - * Layout/Reposition a glyph margin widget. This is a ping to the editor to call widget.getPosition() - * and update appropriately. + * Undo edit operations until the previous undo/redo point. + * The inverse edit operations will be pushed on the redo stack. + * @internal */ - layoutGlyphMarginWidget(widget: IGlyphMarginWidget): void; + undo(): void | Promise; /** - * Remove a glyph margin widget. + * Is there anything in the undo stack? + * @internal */ - removeGlyphMarginWidget(widget: IGlyphMarginWidget): void; + canUndo(): boolean; /** - * Change the view zones. View zones are lost when a new model is attached to the editor. + * Redo edit operations until the next undo/redo point. + * The inverse edit operations will be pushed on the undo stack. + * @internal */ - changeViewZones(callback: (accessor: IViewZoneChangeAccessor) => void): void; + redo(): void | Promise; /** - * Get the horizontal position (left offset) for the column w.r.t to the beginning of the line. - * This method works only if the line `lineNumber` is currently rendered (in the editor's viewport). - * Use this method with caution. + * Is there anything in the redo stack? + * @internal */ - getOffsetForColumn(lineNumber: number, column: number): number; + canRedo(): boolean; /** - * Force an editor render now. + * @deprecated Please use `onDidChangeContent` instead. + * An event emitted when the contents of the model have changed. + * @internal + * @event */ - render(forceRedraw?: boolean): void; + readonly onDidChangeContentOrInjectedText: IEvent; /** - * Get the hit test target at coordinates `clientX` and `clientY`. - * The coordinates are relative to the top-left of the viewport. - * - * @returns Hit test target or null if the coordinates fall outside the editor or the editor has no model. + * An event emitted when the contents of the model have changed. + * @event */ - getTargetAtClientPoint(clientX: number, clientY: number): IMouseTarget | null; + onDidChangeContent(listener: (e: IModelContentChangedEvent) => void): IDisposable; /** - * 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. + * An event emitted when decorations of the model have changed. + * @event */ - getScrolledVisiblePosition(position: IPosition): { - top: number; - left: number; - height: number; - } | null; + readonly onDidChangeDecorations: IEvent; /** - * Apply the same font settings as the editor to `target`. + * An event emitted when the model options have changed. + * @event */ - applyFontInfo(target: HTMLElement): void; - setBanner(bannerDomNode: HTMLElement | null, height: number): void; + readonly onDidChangeOptions: IEvent; /** - * Is called when the model has been set, view state was restored and options are updated. - * This is the best place to compute data for the viewport (such as tokens). + * An event emitted when the language associated with the model has changed. + * @event */ - handleInitialized?(): void; - } - - /** - * A rich diff editor. - */ - export interface IDiffEditor extends IEditor { + readonly onDidChangeLanguage: IEvent; /** - * @see {@link ICodeEditor.getContainerDomNode} + * An event emitted when the language configuration associated with the model has changed. + * @event */ - getContainerDomNode(): HTMLElement; + readonly onDidChangeLanguageConfiguration: IEvent; /** - * An event emitted when the diff information computed by this diff editor has been updated. + * An event emitted when the tokens associated with the model have changed. * @event + * @internal */ - readonly onDidUpdateDiff: IEvent; + readonly onDidChangeTokens: IEvent; /** - * An event emitted when the diff model is changed (i.e. the diff editor shows new content). + * An event emitted when the model has been attached to the first editor or detached from the last editor. * @event */ - readonly onDidChangeModel: IEvent; + readonly onDidChangeAttached: IEvent; /** - * Saves current view state of the editor in a serializable object. + * An event emitted right before disposing the model. + * @event */ - saveViewState(): IDiffEditorViewState | null; + readonly onWillDispose: IEvent; /** - * Restores the view state of the editor from a serializable object generated by `saveViewState`. + * Destroy this model. */ - restoreViewState(state: IDiffEditorViewState | null): void; + dispose(): void; /** - * Type the getModel() of IEditor. + * @internal */ - getModel(): IDiffEditorModel | null; - createViewModel(model: IDiffEditorModel): IDiffEditorViewModel; + onBeforeAttached(): IAttachedView; /** - * Sets the current model attached to this editor. - * If the previous model was created by the editor via the value key in the options - * literal object, it will be destroyed. Otherwise, if the previous model was set - * via setModel, or the model key in the options literal object, the previous model - * will not be destroyed. - * It is safe to call setModel(null) to simply detach the current model from the editor. + * @internal */ - setModel(model: IDiffEditorModel | IDiffEditorViewModel | null): void; + onBeforeDetached(view: IAttachedView): void; /** - * Get the `original` editor. + * Returns if this model is attached to an editor or not. */ - getOriginalEditor(): ICodeEditor; + isAttachedToEditor(): boolean; /** - * Get the `modified` editor. + * Returns the count of editors this model is attached to. + * @internal */ - getModifiedEditor(): ICodeEditor; + getAttachedEditorCount(): number; /** - * Get the computed diff information. + * 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 */ - getLineChanges(): ILineChange[] | null; + normalizePosition(position: Position, affinity: PositionAffinity): Position; /** - * Update the editor's options after the editor has been created. + * 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 */ - updateOptions(newOptions: IDiffEditorOptions): void; + readonly tokenization: any; + } + + /** + * @internal + */ + export interface IAttachedView { /** - * Jumps to the next or previous diff. + * @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. */ - goToDiff(target: 'next' | 'previous'): void; + setVisibleLines(visibleLines: { + startLineNumber: number; + endLineNumber: number; + }[], stabilized: boolean): void; + } + + export enum PositionAffinity { /** - * Scrolls to the first diff. - * (Waits until the diff computation finished.) + * 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; + 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. */ - revealFirstDiff(): unknown; - accessibleDiffViewerNext(): void; - accessibleDiffViewerPrev(): void; - handleInitialized(): void; + getNearestChunk(offset: number): string; } - 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 + */ + export interface ITextBuffer extends IReadonlyTextBuffer, IDisposable { + setEOL(newEOL: '\r\n' | '\n'): void; + applyEdits(rawOperations: any[], recordTrimAutoWhitespace: boolean, computeUndoEdits: boolean): any; } - 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; + /** + * @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. + */ + Unknown = 0, + Disabled = 1, + Enabled = 2 + } + + export interface IEditorWhitespace { + readonly id: string; + readonly afterLineNumber: number; + 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; @@ -6270,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; @@ -6858,6 +8294,97 @@ 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; + } + /** + * 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 + */ + 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. @@ -6914,33 +8441,120 @@ declare namespace monaco.languages { provideHover(model: editor.ITextModel, position: Position, token: CancellationToken, context?: HoverContext): ProviderResult; } - export interface HoverContext { - /** - * Hover verbosity request - */ - verbosityRequest?: HoverVerbosityRequest; + export interface HoverContext { + /** + * Hover verbosity request + */ + verbosityRequest?: HoverVerbosityRequest; + } + + export interface HoverVerbosityRequest { + /** + * The delta by which to increase/decrease the hover verbosity level + */ + verbosityDelta: number; + /** + * The previous hover for the same position + */ + previousHover: THover; + } + + export enum HoverVerbosityAction { + /** + * Increase the verbosity of the hover + */ + Increase = 0, + /** + * Decrease the verbosity of the hover + */ + 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; } - export interface HoverVerbosityRequest { - /** - * The delta by which to increase/decrease the hover verbosity level - */ - verbosityDelta: number; - /** - * The previous hover for the same position - */ - previousHover: THover; + /** + * Provide inline value through a variable lookup. + * @internal + */ + export interface InlineValueVariableLookup { + type: 'variable'; + range: IRange; + variableName?: string; + caseSensitiveLookup: boolean; } - export enum HoverVerbosityAction { + /** + * 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 { /** - * Increase the verbosity of the hover */ - Increase = 0, + onDidChangeInlineValues?: IEvent | undefined; /** - * Decrease the verbosity of the hover + * 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. */ - Decrease = 1 + provideInlineValues(model: editor.ITextModel, viewPort: Range, context: InlineValueContext, token: CancellationToken): ProviderResult; } export enum CompletionItemKind { @@ -7086,12 +8700,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 +8774,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. @@ -7184,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; } @@ -7251,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. @@ -7298,6 +8941,71 @@ 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; + extensionId?: 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 title: string; + readonly kind: HierarchicalKind; + readonly handledMimeType?: string; + readonly yieldTo?: readonly DropYieldTo[]; + insertText: string | { + readonly snippet: string; + }; + 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. @@ -7690,6 +9398,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 +9414,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 +9435,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 +9450,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 +9570,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 +9635,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 +9653,10 @@ declare namespace monaco.languages { folder?: boolean; skipTrashBin?: boolean; maxSize?: number; + /** + * @internal + */ + contents?: Promise; } export interface IWorkspaceFileEdit { @@ -7976,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; @@ -7999,6 +9881,28 @@ declare namespace monaco.languages { cursor: IPosition; } + /** + * @internal + */ + export interface CommentThreadChangedEvent { + /** + * Pending comment threads. + */ + readonly pending: PendingCommentThread[]; + /** + * Added comment threads. + */ + readonly added: AddedCommentThread[]; + /** + * Removed comment threads. + */ + readonly removed: CommentThread[]; + /** + * Changed comment threads. + */ + readonly changed: CommentThread[]; + } + export interface CodeLens { range: IRange; id?: string; @@ -8083,6 +9987,52 @@ 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 kind: HierarchicalKind; + } | { + readonly mimeType: string; + }; + + /** + * @internal + */ + export interface DocumentDropEdit { + readonly title: string; + readonly kind: HierarchicalKind | undefined; + readonly handledMimeType?: string; + readonly yieldTo?: readonly DropYieldTo[]; + insertText: string | { + readonly snippet: string; + }; + 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; @@ -8092,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. * @@ -8129,17 +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; - } /** * A Monarch language definition */ @@ -8276,12 +10240,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 +10296,28 @@ declare namespace monaco.worker { getMirrorModels(): IMirrorModel[]; } + /** + * Range of a word inside a model. + * @internal + */ + export interface IWordRange { + /** + * The index where the word starts. + */ + readonly start: number; + /** + * The index where the word ends. + */ + readonly end: number; + } + + /** + * @internal + */ + export interface IForeignModuleFactory { + (ctx: IWorkerContext, createData: any): any; + } + } //dtsv=3 diff --git a/src/vs/nls.ts b/src/vs/nls.ts index e730d0a761e..0901bc62144 100644 --- a/src/vs/nls.ts +++ b/src/vs/nls.ts @@ -3,11 +3,56 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +/* --------------------------------------------------------------------------------------------- + * 本文件用于为 esm 版本的 monaco-editor 提供 nls 多语言支持 + * 不适用于其他版本 (dev/min) + *---------------------------------------------------------------------------------------------*/ // 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'; +// @ts-ignore +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'; +export enum PreferenceScope { + Default, + User, +} +export const setLocale = (locale: LocaleType): void => { + defaultLocale = locale; +} +/** + * 提供手动设置语言的方法 #setLocale + * 如果在第一次调用 localize 前没有设置过 locale,则会走这里 fallback 的逻辑 + */ +function initialLocaleBundle() { + // @ts-ignore + if (!global.localStorage || !self.localStorage) { + return; + } + if (!defaultLocale) { + if (localStorage[`${PreferenceScope.User}:${KAITIAN_LANGUAGE_KEY}`]) { + setLocale(localStorage[`${PreferenceScope.User}:${KAITIAN_LANGUAGE_KEY}`]) + } else if (localStorage[`${PreferenceScope.Default}:${KAITIAN_LANGUAGE_KEY}`]) { + setLocale(localStorage[`${PreferenceScope.Default}:${KAITIAN_LANGUAGE_KEY}`]); + } else { + setLocale('zh-CN') + } + } + // 由于目前仅支持中/英文,所以如果locale 为 'zh-cn',则表示已经设置了中文,否则仅使用默认值,无需加载语言包 + if (defaultLocale?.toLowerCase() === 'zh-cn') { + CURRENT_LOCALE_DATA = zhCnBundle; + } + initialized = true; +} + const isPseudo = getNLSLanguage() === 'pseudo' || (typeof document !== 'undefined' && document.location && typeof document.location.hash === 'string' && document.location.hash.indexOf('pseudo=true') >= 0); export interface ILocalizeInfo { @@ -27,8 +72,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 +92,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 }; }