From e53924d4f544a3cd7301b3f10b256fc6e55af644 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=A4der?= Date: Thu, 15 Feb 2024 11:12:16 +0100 Subject: [PATCH] Upgrade Monaco dependency to 1.83.1 (#13217) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes #12679 Contributed on behalf of STMicroelectronics Signed-off-by: Thomas Mäder --- CHANGELOG.md | 11 +- .../src/generator/frontend-generator.ts | 10 +- dev-packages/cli/src/test-page.ts | 3 +- examples/api-samples/package.json | 4 +- examples/api-tests/src/monaco-api.spec.js | 60 +- examples/api-tests/src/typescript.spec.js | 79 +- packages/bulk-edit/package.json | 4 +- .../bulk-edit-tree/bulk-edit-tree.spec.ts | 2 +- packages/console/package.json | 4 +- .../console/src/browser/console-widget.ts | 1 - .../core/src/browser/context-key-service.ts | 3 +- .../core/src/browser/context-menu-renderer.ts | 4 - packages/core/src/browser/icon-registry.ts | 11 +- .../markdown-rendering/markdown-renderer.ts | 2 +- packages/core/src/browser/style/index.css | 301 +++---- .../markdown-rendering/markdown-string.ts | 9 +- .../core/src/common/quick-pick-service.ts | 42 +- packages/core/src/common/theme.ts | 32 + packages/core/src/common/uri.ts | 6 +- packages/debug/package.json | 4 +- .../src/browser/debug-frontend-module.ts | 5 +- .../src/browser/debug-session-manager.ts | 2 +- .../disassembly-view-instruction-renderer.ts | 16 +- .../disassembly-view-widget.ts | 2 +- .../src/browser/editor/debug-editor-model.ts | 7 +- .../editor/debug-inline-value-decorator.ts | 8 +- packages/editor/src/browser/diff-navigator.ts | 1 - .../editor-generated-preference-schema.ts | 734 +++++++++++------- .../browser/editor-linenumber-contribution.ts | 3 +- .../src/browser/file-upload-service.ts | 10 +- packages/git/package.json | 4 +- packages/keymaps/package.json | 4 +- packages/monaco/package.json | 4 +- .../monaco-markdown-renderer.ts | 28 +- .../src/browser/monaco-bulk-edit-service.ts | 4 +- .../src/browser/monaco-command-registry.ts | 5 +- .../src/browser/monaco-command-service.ts | 41 +- packages/monaco/src/browser/monaco-command.ts | 20 +- .../src/browser/monaco-context-key-service.ts | 13 +- .../monaco/src/browser/monaco-context-menu.ts | 16 +- .../monaco/src/browser/monaco-diff-editor.ts | 17 +- .../browser/monaco-diff-navigator-factory.ts | 34 +- .../src/browser/monaco-editor-provider.ts | 72 +- .../src/browser/monaco-editor-service.ts | 15 +- packages/monaco/src/browser/monaco-editor.ts | 13 +- ...onaco-frontend-application-contribution.ts | 35 - .../src/browser/monaco-frontend-module.ts | 42 +- .../src/browser/monaco-icon-registry.ts | 10 +- packages/monaco/src/browser/monaco-init.ts | 114 +++ .../monaco/src/browser/monaco-keybinding.ts | 6 +- .../src/browser/monaco-quick-input-service.ts | 187 ++--- .../src/browser/monaco-resolved-keybinding.ts | 46 +- .../src/browser/monaco-text-model-service.ts | 2 +- .../monaco/src/browser/monaco-workspace.ts | 20 +- .../src/browser/simple-monaco-editor.ts | 2 +- .../textmate/monaco-textmate-service.ts | 2 +- .../service/notebook-cell-context-manager.ts | 1 - packages/output/package.json | 4 +- .../src/browser/output-editor-factory.ts | 12 +- packages/plugin-ext-vscode/package.json | 4 +- packages/plugin-ext/package.json | 4 +- .../src/common/plugin-api-rpc-model.ts | 2 +- .../plugin-ext/src/common/plugin-api-rpc.ts | 45 +- .../src/hosted/browser/hosted-plugin.ts | 4 +- .../browser/comments/comments-contribution.ts | 10 +- .../data-transfer-type-converters.ts | 10 +- .../src/main/browser/languages-main.ts | 14 +- .../src/main/browser/main-context.ts | 4 +- .../menus/menus-contribution-handler.ts | 2 +- .../browser/plugin-contribution-handler.ts | 2 +- .../src/main/browser/plugin-icon-service.ts | 80 +- .../src/main/browser/quick-open-main.ts | 105 ++- .../plugin-ext/src/main/browser/scm-main.ts | 2 +- .../src/main/browser/text-editors-main.ts | 14 +- .../src/main/browser/theme-icon-override.ts | 32 +- .../plugin-tree-view-node-label-provider.ts | 2 +- .../main/browser/view/plugin-view-registry.ts | 2 +- .../main/browser/view/plugin-view-widget.ts | 1 - .../main/browser/view/tree-view-widget.tsx | 5 +- .../plugin-ext/src/plugin/known-commands.ts | 1 + .../plugin-ext/src/plugin/markdown-string.ts | 6 +- packages/plugin-ext/src/plugin/quick-open.ts | 34 +- .../plugin-ext/src/plugin/terminal-ext.ts | 2 +- .../plugin-ext/src/plugin/type-converters.ts | 51 +- packages/plugin-metrics/package.json | 4 +- packages/plugin/src/theia.d.ts | 8 +- packages/preferences/package.json | 4 +- packages/task/package.json | 4 +- packages/toolbar/package.json | 4 +- yarn.lock | 8 +- 90 files changed, 1408 insertions(+), 1215 deletions(-) create mode 100644 packages/monaco/src/browser/monaco-init.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 4d25f0597802e..fe038a8dfe136 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,13 +4,18 @@ - [Previous Changelogs](https://github.com/eclipse-theia/theia/tree/master/doc/changelogs/) - +- [monaco] Upgrade Monaco dependency to 1.83.1 [#13217](https://github.com/eclipse-theia/theia/pull/13217)- contributed on behalf of STMicroelectronics\ + There are a couple of breaking changes that come with this monaco update + - Moved `ThemaIcon` and `ThemeColor` to the common folder + - Minor typing adjustments in QuickPickService: in parti + - FileUploadService: moved id field from data transfer item to the corresponding file info + - The way we instantiate monaco services has changed completely: if you touch monaco services in your code, please read the description in the + file comment in `monaco-init.ts`. ## v1.46.0 - 01/25/2024 - [plugin] Add prefix to contributed view container ids [#13362](https://github.com/eclipse-theia/theia/pull/13362) - contributed on behalf of STMicroelectronics diff --git a/dev-packages/application-manager/src/generator/frontend-generator.ts b/dev-packages/application-manager/src/generator/frontend-generator.ts index 672b11cbcb43e..ee304fec409a7 100644 --- a/dev-packages/application-manager/src/generator/frontend-generator.ts +++ b/dev-packages/application-manager/src/generator/frontend-generator.ts @@ -108,7 +108,7 @@ ${Array.from(frontendPreloadModules.values(), jsModulePath => `\ } module.exports = (async () => { - const { messagingFrontendModule } = require('@theia/core/lib/${!this.pck.isElectron() + const { messagingFrontendModule } = require('@theia/core/lib/${this.pck.isBrowser() ? 'browser/messaging/messaging-frontend-module' : 'electron-browser/messaging/electron-messaging-frontend-module'}'); const container = new Container(); @@ -117,6 +117,11 @@ module.exports = (async () => { container.load(messagingFrontendOnlyModule);`)} await preload(container); + + ${this.ifMonaco(() => ` + const { MonacoInit } = require('@theia/monaco/lib/browser/monaco-init'); + `)}; + const { FrontendApplication } = require('@theia/core/lib/browser'); const { frontendApplicationModule } = require('@theia/core/lib/browser/frontend-application-module'); const { loggerFrontendModule } = require('@theia/core/lib/browser/logger-frontend-module'); @@ -132,6 +137,9 @@ module.exports = (async () => { try { ${Array.from(frontendModules.values(), jsModulePath => `\ await load(container, ${this.importOrRequire()}('${jsModulePath}'));`).join(EOL)} + ${this.ifMonaco(() => ` + MonacoInit.init(container); + `)}; await start(); } catch (reason) { console.error('Failed to start the frontend application.'); diff --git a/dev-packages/cli/src/test-page.ts b/dev-packages/cli/src/test-page.ts index fe158c48f4882..95d5ba7df5d0e 100644 --- a/dev-packages/cli/src/test-page.ts +++ b/dev-packages/cli/src/test-page.ts @@ -113,7 +113,8 @@ export default async function newTestPage(options: TestPageOptions): Promise { - const simpleKeybinding = new SimpleKeybinding(true, true, true, true, 41 /* KeyCode.KeyK */); - const chordKeybinding = simpleKeybinding.toChord(); - assert.equal(chordKeybinding.parts.length, 1); - assert.equal(chordKeybinding.parts[0], simpleKeybinding); + const chord = new KeyCodeChord(true, true, true, true, 41 /* KeyCode.KeyK */); + const chordKeybinding = chord.toKeybinding(); + assert.equal(chordKeybinding.chords.length, 1); + assert.equal(chordKeybinding.chords[0], chord); const resolvedKeybindings = StandaloneServices.get(IKeybindingService).resolveKeybinding(chordKeybinding); assert.equal(resolvedKeybindings.length, 1); @@ -74,9 +74,8 @@ describe('Monaco API', async function () { const electronAccelerator = resolvedKeybinding.getElectronAccelerator(); const userSettingsLabel = resolvedKeybinding.getUserSettingsLabel(); const WYSIWYG = resolvedKeybinding.isWYSIWYG(); - const chord = resolvedKeybinding.isChord(); - const parts = resolvedKeybinding.getParts(); - const dispatchParts = resolvedKeybinding.getDispatchParts(); + const parts = resolvedKeybinding.getChords(); + const dispatchParts = resolvedKeybinding.getDispatchChords().map(str => str === null ? '' : str); const platform = window.navigator.platform; let expected; @@ -89,14 +88,14 @@ describe('Monaco API', async function () { userSettingsLabel: 'ctrl+shift+alt+cmd+K', WYSIWYG: true, chord: false, - parts: [{ - altKey: true, - ctrlKey: true, - keyAriaLabel: 'K', - keyLabel: 'K', - metaKey: true, - shiftKey: true - }], + parts: [new ResolvedChord( + true, + true, + true, + true, + 'K', + 'K', + )], dispatchParts: [ 'ctrl+shift+alt+meta+K' ] @@ -108,15 +107,14 @@ describe('Monaco API', async function () { electronAccelerator: 'Ctrl+Shift+Alt+K', userSettingsLabel: 'ctrl+shift+alt+K', WYSIWYG: true, - chord: false, - parts: [{ - altKey: true, - ctrlKey: true, - keyAriaLabel: 'K', - keyLabel: 'K', - metaKey: false, - shiftKey: true - }], + parts: [new ResolvedChord( + true, + true, + true, + false, + 'K', + 'K' + )], dispatchParts: [ 'ctrl+shift+alt+K' ] @@ -124,7 +122,7 @@ describe('Monaco API', async function () { } assert.deepStrictEqual({ - label, ariaLabel, electronAccelerator, userSettingsLabel, WYSIWYG, chord, parts, dispatchParts + label, ariaLabel, electronAccelerator, userSettingsLabel, WYSIWYG, parts, dispatchParts }, expected); } else { assert.fail(`resolvedKeybinding must be of ${MonacoResolvedKeybinding.name} type`); @@ -136,7 +134,7 @@ describe('Monaco API', async function () { const didChangeColorMap = new Promise(resolve => { const toDispose = TokenizationRegistry.onDidChange(() => { toDispose.dispose(); - resolve(); + resolve(undefined); }); }); textmateService['themeService'].setCurrentTheme('light'); @@ -175,15 +173,15 @@ describe('Monaco API', async function () { }); it('Supports setting contexts using the command registry', async () => { - const setContext = 'setContext'; + const setContext = '_setContext'; const key = 'monaco-api-test-context'; const firstValue = 'first setting'; const secondValue = 'second setting'; - assert.isFalse(contextKeys.match(`${key} == ${firstValue}`)); + assert.isFalse(contextKeys.match(`${key} == '${firstValue}'`)); await commands.executeCommand(setContext, key, firstValue); - assert.isTrue(contextKeys.match(`${key} == ${firstValue}`)); + assert.isTrue(contextKeys.match(`${key} == '${firstValue}'`)); await commands.executeCommand(setContext, key, secondValue); - assert.isTrue(contextKeys.match(`${key} == ${secondValue}`)); + assert.isTrue(contextKeys.match(`${key} == '${secondValue}'`)); }); it('Supports context key: inQuickOpen', async () => { diff --git a/examples/api-tests/src/typescript.spec.js b/examples/api-tests/src/typescript.spec.js index c399bdbda5f73..4b2cda473bf99 100644 --- a/examples/api-tests/src/typescript.spec.js +++ b/examples/api-tests/src/typescript.spec.js @@ -119,19 +119,28 @@ describe('TypeScript', function () { */ function waitForAnimation(condition, timeout, message) { const success = new Promise(async (resolve, reject) => { + if (timeout === undefined) { + timeout = 100000; + } + + let timedOut = false; + const handle = setTimeout(() => { + console.log(message); + timedOut = true; + }, timeout); + toTearDown.push({ dispose: () => reject(message ?? 'Test terminated before resolution.') }); do { await animationFrame(); - } while (!condition()); - resolve(); + } while (!timedOut && !condition()); + if (timedOut) { + reject(new Error(message ?? 'Wait for animation timed out.')); + } else { + clearTimeout(handle); + resolve(undefined); + } + }); - if (timeout !== undefined) { - const timedOut = new Promise((_, fail) => { - const toClear = setTimeout(() => fail(new Error(message ?? 'Wait for animation timed out.')), timeout); - toTearDown.push({ dispose: () => (fail(new Error(message ?? 'Wait for animation timed out.')), clearTimeout(toClear)) }); - }); - return Promise.race([success, timedOut]); - } return success; } @@ -689,11 +698,10 @@ SPAN { editor.getControl().revealPosition({ lineNumber, column }); assert.equal(currentChar(), ';', 'Failed at assert 1'); - /** @type {import('@theia/monaco-editor-core/src/vs/editor/contrib/codeAction/browser/codeActionCommands').CodeActionController} */ + /** @type {import('@theia/monaco-editor-core/src/vs/editor/contrib/codeAction/browser/codeActionController').CodeActionController} */ const codeActionController = editor.getControl().getContribution('editor.contrib.codeActionController'); const lightBulbNode = () => { - const ui = codeActionController['_ui'].rawValue; - const lightBulb = ui && ui['_lightBulbWidget'].rawValue; + const lightBulb = codeActionController['_lightBulbWidget'].rawValue; return lightBulb && lightBulb['_domNode']; }; const lightBulbVisible = () => { @@ -703,14 +711,14 @@ SPAN { await timeout(1000); // quick fix is always available: need to wait for the error fix to become available. await commands.executeCommand('editor.action.quickFix'); - const codeActionSelector = '.codeActionWidget'; + const codeActionSelector = '.action-widget'; assert.isFalse(!!document.querySelector(codeActionSelector), 'Failed at assert 3 - codeActionWidget should not be visible'); console.log('Waiting for Quick Fix widget to be visible'); await waitForAnimation(() => { const quickFixWidgetVisible = !!document.querySelector(codeActionSelector); if (!quickFixWidgetVisible) { - console.log('...'); + // console.log('...'); return false; } return true; @@ -768,27 +776,13 @@ SPAN { assert.equal(editor.getControl().getModel().getLineLength(lineNumber), originalLength); }); - for (const referenceViewCommand of ['references-view.find', 'references-view.findImplementations']) { - it(referenceViewCommand, async function () { - let steps = 0; - const editor = await openEditor(demoFileUri); - editor.getControl().setPosition({ lineNumber: 24, column: 11 }); - assert.equal(editor.getControl().getModel().getWordAtPosition(editor.getControl().getPosition()).word, 'demoInstance'); - await commands.executeCommand(referenceViewCommand); - const view = await pluginViewRegistry.openView('references-view.tree', { reveal: true }); - const expectedMessage = referenceViewCommand === 'references-view.find' ? '2 results in 1 file' : '1 result in 1 file'; - const getResultText = () => view.node.getElementsByClassName('theia-TreeViewInfo').item(0)?.textContent; - await waitForAnimation(() => getResultText() === expectedMessage, 5000); - assert.equal(getResultText(), expectedMessage); - }); - } it('Can execute code actions', async function () { const editor = await openEditor(demoFileUri); - /** @type {import('@theia/monaco-editor-core/src/vs/editor/contrib/codeAction/browser/codeActionCommands').CodeActionController} */ + /** @type {import('@theia/monaco-editor-core/src/vs/editor/contrib/codeAction/browser/codeActionController').CodeActionController} */ const codeActionController = editor.getControl().getContribution('editor.contrib.codeActionController'); const isActionAvailable = () => { - const lightbulbVisibility = codeActionController['_ui'].rawValue?.['_lightBulbWidget'].rawValue?.['_domNode'].style.visibility; + const lightbulbVisibility = codeActionController['_lightBulbWidget'].rawValue?.['_domNode'].style.visibility; return lightbulbVisibility !== undefined && lightbulbVisibility !== 'hidden'; } assert.isFalse(isActionAvailable()); @@ -798,8 +792,16 @@ SPAN { await waitForAnimation(() => isActionAvailable(), 5000, 'No code action available. (1)'); assert.isTrue(isActionAvailable()); + try { // for some reason, we need to wait a second here, otherwise, we run into some cancellation. + await waitForAnimation(() => false, 1000); + } catch (e) { + } + await commands.executeCommand('editor.action.quickFix'); - await waitForAnimation(() => Boolean(document.querySelector('.context-view-pointerBlock')), 5000, 'No context menu appeared. (1)'); + await waitForAnimation(() => { + const elements = document.querySelector('.action-widget'); + return !!elements; + }, 5000, 'No context menu appeared. (1)'); await animationFrame(); keybindings.dispatchKeyDown('Enter'); @@ -841,4 +843,19 @@ SPAN { assert.isNotNull(editor.getControl().getModel()); await waitForAnimation(() => editor.getControl().getModel().getLineContent(30) === 'import { DefinedInterface } from "./demo-definitions-file";', 5000, 'The named import did not take effect.'); }); + + for (const referenceViewCommand of ['references-view.find', 'references-view.findImplementations']) { + it(referenceViewCommand, async function () { + let steps = 0; + const editor = await openEditor(demoFileUri); + editor.getControl().setPosition({ lineNumber: 24, column: 11 }); + assert.equal(editor.getControl().getModel().getWordAtPosition(editor.getControl().getPosition()).word, 'demoInstance'); + await commands.executeCommand(referenceViewCommand); + const view = await pluginViewRegistry.openView('references-view.tree', { reveal: true }); + const expectedMessage = referenceViewCommand === 'references-view.find' ? '2 results in 1 file' : '1 result in 1 file'; + const getResultText = () => view.node.getElementsByClassName('theia-TreeViewInfo').item(0)?.textContent; + await waitForAnimation(() => getResultText() === expectedMessage, 5000); + assert.equal(getResultText(), expectedMessage); + }); + } }); diff --git a/packages/bulk-edit/package.json b/packages/bulk-edit/package.json index e3fd0d5e14400..19fd04253ff7b 100644 --- a/packages/bulk-edit/package.json +++ b/packages/bulk-edit/package.json @@ -7,7 +7,7 @@ "@theia/editor": "1.46.0", "@theia/filesystem": "1.46.0", "@theia/monaco": "1.46.0", - "@theia/monaco-editor-core": "1.72.3", + "@theia/monaco-editor-core": "1.83.101", "@theia/workspace": "1.46.0" }, "publishConfig": { @@ -48,4 +48,4 @@ "nyc": { "extends": "../../configs/nyc.json" } -} +} \ No newline at end of file diff --git a/packages/bulk-edit/src/browser/bulk-edit-tree/bulk-edit-tree.spec.ts b/packages/bulk-edit/src/browser/bulk-edit-tree/bulk-edit-tree.spec.ts index 49f38561ec75c..3f9e315579e7f 100644 --- a/packages/bulk-edit/src/browser/bulk-edit-tree/bulk-edit-tree.spec.ts +++ b/packages/bulk-edit/src/browser/bulk-edit-tree/bulk-edit-tree.spec.ts @@ -17,7 +17,7 @@ import { enableJSDOM } from '@theia/core/lib/browser/test/jsdom'; import * as chai from 'chai'; import { ResourceTextEdit } from '@theia/monaco-editor-core/esm/vs/editor/browser/services/bulkEditService'; -import { URI as Uri } from 'vscode-uri'; +import { URI as Uri } from '@theia/core/shared/vscode-uri'; let disableJSDOM = enableJSDOM(); diff --git a/packages/console/package.json b/packages/console/package.json index ab7c5abd02a1c..4105ba64b8c84 100644 --- a/packages/console/package.json +++ b/packages/console/package.json @@ -5,7 +5,7 @@ "dependencies": { "@theia/core": "1.46.0", "@theia/monaco": "1.46.0", - "@theia/monaco-editor-core": "1.72.3", + "@theia/monaco-editor-core": "1.83.101", "anser": "^2.0.1" }, "publishConfig": { @@ -46,4 +46,4 @@ "nyc": { "extends": "../../configs/nyc.json" } -} +} \ No newline at end of file diff --git a/packages/console/src/browser/console-widget.ts b/packages/console/src/browser/console-widget.ts index 0f6065fefde09..8948c9b57141b 100644 --- a/packages/console/src/browser/console-widget.ts +++ b/packages/console/src/browser/console-widget.ts @@ -139,7 +139,6 @@ export class ConsoleWidget extends BaseWidget implements StatefulWidget { input.getControl().createContextKey('consoleInputFocus', true); const contentContext = this.contextKeyService.createScoped(this.content.node); contentContext.setContext('consoleContentFocus', true); - this.toDispose.push(contentContext); } protected createInput(node: HTMLElement): Promise { diff --git a/packages/core/src/browser/context-key-service.ts b/packages/core/src/browser/context-key-service.ts index 9ed540beb5394..0bb30ad313df4 100644 --- a/packages/core/src/browser/context-key-service.ts +++ b/packages/core/src/browser/context-key-service.ts @@ -15,7 +15,6 @@ // ***************************************************************************** import { injectable } from 'inversify'; -import { Disposable } from '../common'; import { Emitter, Event } from '../common/event'; export type ContextKeyValue = null | undefined | boolean | number | string @@ -43,7 +42,7 @@ export interface ContextKeyChangeEvent { export const ContextKeyService = Symbol('ContextKeyService'); -export interface ContextMatcher extends Disposable { +export interface ContextMatcher { /** * Whether the expression is satisfied. If `context` provided, the service will attempt to retrieve a context object associated with that element. */ diff --git a/packages/core/src/browser/context-menu-renderer.ts b/packages/core/src/browser/context-menu-renderer.ts index e8f88586f7c35..dd9bad8463373 100644 --- a/packages/core/src/browser/context-menu-renderer.ts +++ b/packages/core/src/browser/context-menu-renderer.ts @@ -26,10 +26,6 @@ export const Coordinate = Symbol('Coordinate'); export type Anchor = MouseEvent | Coordinate; -export function toAnchor(anchor: HTMLElement | Coordinate): Anchor { - return anchor instanceof HTMLElement ? { x: anchor.offsetLeft, y: anchor.offsetTop } : anchor; -} - export function coordinateFromAnchor(anchor: Anchor): Coordinate { const { x, y } = anchor instanceof MouseEvent ? { x: anchor.clientX, y: anchor.clientY } : anchor; return { x, y }; diff --git a/packages/core/src/browser/icon-registry.ts b/packages/core/src/browser/icon-registry.ts index 90c1088012f37..f41728d13046f 100644 --- a/packages/core/src/browser/icon-registry.ts +++ b/packages/core/src/browser/icon-registry.ts @@ -19,6 +19,7 @@ *--------------------------------------------------------------------------------------------*/ // code copied and modified from https://github.com/Microsoft/vscode/blob/main/src/vs/platform/theme/common/iconRegistry.ts +import { ThemeIcon } from '../common/theme'; import { URI } from 'vscode-uri'; export interface IconDefinition { @@ -48,16 +49,6 @@ export interface IconFontSource { readonly location: URI; readonly format: string; } - -export interface ThemeIcon { - readonly id: string; - readonly color?: ThemeColor; -} - -export interface ThemeColor { - id: string; -} - export const IconRegistry = Symbol('IconRegistry'); export interface IconRegistry { /** diff --git a/packages/core/src/browser/markdown-rendering/markdown-renderer.ts b/packages/core/src/browser/markdown-rendering/markdown-renderer.ts index fa9eb5bcf031f..f3a9d93b611f4 100644 --- a/packages/core/src/browser/markdown-rendering/markdown-renderer.ts +++ b/packages/core/src/browser/markdown-rendering/markdown-renderer.ts @@ -24,7 +24,7 @@ import { codicon } from '../widgets'; // #region Copied from Copied from https://github.com/microsoft/vscode/blob/7d9b1c37f8e5ae3772782ba3b09d827eb3fdd833/src/vs/base/browser/formattedTextRenderer.ts export interface ContentActionHandler { - callback: (content: string, event?: MouseEvent) => void; + callback: (content: string, event?: MouseEvent | KeyboardEvent) => void; readonly disposables: DisposableGroup; } diff --git a/packages/core/src/browser/style/index.css b/packages/core/src/browser/style/index.css index bc3e99abe5ffe..e2ba596cb6491 100644 --- a/packages/core/src/browser/style/index.css +++ b/packages/core/src/browser/style/index.css @@ -22,18 +22,18 @@ |----------------------------------------------------------------------------*/ :root { - /* Borders: Width and color (dark to bright) */ + /* Borders: Width and color (dark to bright) */ - --theia-border-width: 1px; - --theia-panel-border-width: 1px; + --theia-border-width: 1px; + --theia-panel-border-width: 1px; - /* UI fonts: Family, size and color (bright to dark) + /* UI fonts: Family, size and color (bright to dark) --------------------------------------------------- The UI font CSS variables are used for the typography all of the Theia user interface elements that are not directly user-generated content. */ - --theia-ui-font-scale-factor: 1.2; + --theia-ui-font-scale-factor: 1.2; --theia-ui-font-size0: calc( var(--theia-ui-font-size1) / var(--theia-ui-font-scale-factor) ); @@ -45,181 +45,186 @@ var(--theia-ui-font-size2) * var(--theia-ui-font-scale-factor) ); --theia-ui-icon-font-size: 14px; /* Ensures px perfect FontAwesome icons */ - --theia-ui-font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + --theia-ui-font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; - /* Content fonts: Family, size and color (bright to dark) + /* Content fonts: Family, size and color (bright to dark) Content font variables are used for typography of user-generated content. */ - --theia-content-font-size: 13px; - --theia-content-line-height: 22px; + --theia-content-font-size: 13px; + --theia-content-line-height: 22px; - --theia-code-font-size: 13px; - --theia-code-line-height: 17px; - --theia-code-padding: 5px; - --theia-code-font-family: Menlo, Monaco, Consolas, "Droid Sans Mono", - "Courier New", monospace, "Droid Sans Fallback"; - --theia-monospace-font-family: monospace; - --theia-ui-padding: 6px; + --theia-code-font-size: 13px; + --theia-code-line-height: 17px; + --theia-code-padding: 5px; + --theia-code-font-family: Menlo, Monaco, Consolas, "Droid Sans Mono", + "Courier New", monospace, "Droid Sans Fallback"; + --theia-monospace-font-family: monospace; + --theia-ui-padding: 6px; - /* Icons */ - --theia-icon-size: 16px; + /* Icons */ + --theia-icon-size: 16px; - /* Scrollbars */ - --theia-scrollbar-width: 10px; - --theia-scrollbar-rail-width: 10px; + /* Scrollbars */ + --theia-scrollbar-width: 10px; + --theia-scrollbar-rail-width: 10px; - /* Statusbar */ - --theia-statusBar-font-size: 12px; + /* Statusbar */ + --theia-statusBar-font-size: 12px; - /* Opacity for disabled mod */ - --theia-mod-disabled-opacity: 0.4; + /* Opacity for disabled mod */ + --theia-mod-disabled-opacity: 0.4; } +html, body { - margin: 0; - padding: 0; - overflow: hidden; - font-family: var(--theia-ui-font-family); - background: var(--theia-editor-background); - color: var(--theia-foreground); - border: 1px solid var(--theia-window-activeBorder); + height: 100vh; +} + +body { + margin: 0; + padding: 0; + overflow: hidden; + font-family: var(--theia-ui-font-family); + background: var(--theia-editor-background); + color: var(--theia-foreground); + border: 1px solid var(--theia-window-activeBorder); } body:window-inactive, body:-moz-window-inactive { - border-color: var(--theia-window-inactiveBorder); + border-color: var(--theia-window-inactiveBorder); } a { - color: var(--theia-textLink-foreground); + color: var(--theia-textLink-foreground); } a:active, a:hover { - color: var(--theia-textLink-activeForeground); + color: var(--theia-textLink-activeForeground); } code { - color: var(--theia-textPreformat-foreground); + color: var(--theia-textPreformat-foreground); } blockquote { - margin: 0 7px 0 5px; - padding: 0px 16px 0px 10px; - background: var(--theia-textBlockQuote-background); - border-left: 5px solid var(--theia-textBlockQuote-border); + margin: 0 7px 0 5px; + padding: 0px 16px 0px 10px; + background: var(--theia-textBlockQuote-background); + border-left: 5px solid var(--theia-textBlockQuote-border); } .theia-input { - background: var(--theia-input-background); - color: var(--theia-input-foreground); - border: var(--theia-border-width) solid var(--theia-input-border); - font-family: var(--theia-ui-font-family); - font-size: var(--theia-ui-font-size1); - line-height: var(--theia-content-line-height); - padding-left: 5px; - border-radius: 2px; + background: var(--theia-input-background); + color: var(--theia-input-foreground); + border: var(--theia-border-width) solid var(--theia-input-border); + font-family: var(--theia-ui-font-family); + font-size: var(--theia-ui-font-size1); + line-height: var(--theia-content-line-height); + padding-left: 5px; + border-radius: 2px; } .theia-input[type="text"] { - text-overflow: ellipsis; - white-space: nowrap; + text-overflow: ellipsis; + white-space: nowrap; } .theia-input::placeholder { - color: var(--theia-input-placeholderForeground); - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; + color: var(--theia-input-placeholderForeground); + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; } .theia-maximized { - position: fixed !important; - top: 0 !important; - bottom: 0 !important; - left: 0 !important; - right: 0 !important; - width: auto !important; - height: auto !important; - z-index: 255 !important; - background: var(--theia-editor-background); + position: fixed !important; + top: 0 !important; + bottom: 0 !important; + left: 0 !important; + right: 0 !important; + width: auto !important; + height: auto !important; + z-index: 255 !important; + background: var(--theia-editor-background); } .theia-visible-menu-maximized { - top: var(--theia-private-menubar-height) !important; + top: var(--theia-private-menubar-height) !important; } .theia-ApplicationShell { - position: absolute; - top: 0; - left: 0; - right: 0; - bottom: 0; - background: var(--theia-editor-background); + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: var(--theia-editor-background); } .theia-preload { - position: absolute; - top: 0; - left: 0; - right: 0; - bottom: 0; - z-index: 50000; - background: var(--theia-editor-background); - background-size: 60px 60px; - background-repeat: no-repeat; - background-attachment: fixed; - background-position: center; - transition: opacity 0.8s; - display: flex; - justify-content: center; - align-items: center; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + z-index: 50000; + background: var(--theia-editor-background); + background-size: 60px 60px; + background-repeat: no-repeat; + background-attachment: fixed; + background-position: center; + transition: opacity 0.8s; + display: flex; + justify-content: center; + align-items: center; } .theia-preload::after { - animation: 1s theia-preload-rotate infinite; + animation: 1s theia-preload-rotate infinite; color: #777; /* color works on both light and dark themes */ content: "\eb19"; /* codicon-load */ - font: normal normal normal 72px/1 codicon; + font: normal normal normal 72px/1 codicon; } @keyframes theia-preload-rotate { - 0% { - transform: rotate(0deg); - } - 100% { - transform: rotate(360deg); - } + 0% { + transform: rotate(0deg); + } + 100% { + transform: rotate(360deg); + } } .theia-preload.theia-hidden { - opacity: 0; + opacity: 0; } .theia-icon { - width: 32px; - height: 18px; - margin: 5px; - margin-left: 8px; + width: 32px; + height: 18px; + margin: 5px; + margin-left: 8px; } .theia-mod-disabled, .theia-mod-disabled:focus { - opacity: var(--theia-mod-disabled-opacity) !important; + opacity: var(--theia-mod-disabled-opacity) !important; } .theia-header { - text-transform: uppercase; - font-size: var(--theia-ui-font-size0); - font-weight: 700; + text-transform: uppercase; + font-size: var(--theia-ui-font-size0); + font-weight: 700; } .p-Widget { - font-size: var(--theia-ui-font-size1); + font-size: var(--theia-ui-font-size1); } .p-Widget.p-mod-hidden { - display: none !important; + display: none !important; } .noselect, @@ -231,91 +236,91 @@ blockquote { -ms-user-select: none; /* Internet Explorer/Edge */ user-select: none; /* Non-prefixed version, currently supported by Chrome and Opera */ - -o-user-select: none; + -o-user-select: none; } :focus { - outline-width: 1px; - outline-style: solid; - outline-offset: -1px; - opacity: 1; - outline-color: var(--theia-focusBorder); + outline-width: 1px; + outline-style: solid; + outline-offset: -1px; + opacity: 1; + outline-color: var(--theia-focusBorder); } ::selection { - background: var(--theia-selection-background); + background: var(--theia-selection-background); } .action-label { - padding: 2px; - border-radius: 5px; - cursor: pointer; + padding: 2px; + border-radius: 5px; + cursor: pointer; } .action-label:hover { - background-color: var(--theia-toolbar-hoverBackground); + background-color: var(--theia-toolbar-hoverBackground); } .theia-button { - border: none; - color: var(--theia-button-foreground); - min-width: 65px; - outline: none; - cursor: pointer; - padding: 4px 9px; - margin-left: calc(var(--theia-ui-padding) * 2); - border-radius: 2px; + border: none; + color: var(--theia-button-foreground); + min-width: 65px; + outline: none; + cursor: pointer; + padding: 4px 9px; + margin-left: calc(var(--theia-ui-padding) * 2); + border-radius: 2px; } .theia-button:focus { - outline: 1px solid var(--theia-focusBorder); - outline-offset: 1px; + outline: 1px solid var(--theia-focusBorder); + outline-offset: 1px; } .theia-button.secondary { - color: var(--theia-secondaryButton-foreground); + color: var(--theia-secondaryButton-foreground); } .theia-button[disabled] { - opacity: 0.6; - color: var(--theia-button-disabledForeground); - background-color: var(--theia-button-disabledBackground); - cursor: default; + opacity: 0.6; + color: var(--theia-button-disabledForeground); + background-color: var(--theia-button-disabledBackground); + cursor: default; } button.secondary[disabled], .theia-button.secondary[disabled] { - color: var(--theia-secondaryButton-disabledForeground); - background-color: var(--theia-secondaryButton-disabledBackground); + color: var(--theia-secondaryButton-disabledForeground); + background-color: var(--theia-secondaryButton-disabledBackground); } .theia-select { - color: var(--dropdown-foreground); - font-size: var(--theia-ui-font-size1); - border-radius: 2px; - border: 1px solid var(--theia-dropdown-border); - background: var(--theia-dropdown-background); - outline: none; - cursor: pointer; + color: var(--dropdown-foreground); + font-size: var(--theia-ui-font-size1); + border-radius: 2px; + border: 1px solid var(--theia-dropdown-border); + background: var(--theia-dropdown-background); + outline: none; + cursor: pointer; } .theia-select option { - background: var(--theia-dropdown-listBackground); + background: var(--theia-dropdown-listBackground); } .theia-transparent-overlay { - background-color: transparent; - position: absolute; - top: 0; - left: 0; - height: 100%; - width: 100%; - z-index: 999; + background-color: transparent; + position: absolute; + top: 0; + left: 0; + height: 100%; + width: 100%; + z-index: 999; } .theia-cursor-no-drop, .theia-cursor-no-drop:active { - cursor: no-drop; + cursor: no-drop; } /*----------------------------------------------------------------------------- diff --git a/packages/core/src/common/markdown-rendering/markdown-string.ts b/packages/core/src/common/markdown-rendering/markdown-string.ts index 9f857181685a1..19d93e94132a1 100644 --- a/packages/core/src/common/markdown-rendering/markdown-string.ts +++ b/packages/core/src/common/markdown-rendering/markdown-string.ts @@ -19,9 +19,13 @@ import { UriComponents } from '../uri'; import { escapeIcons } from './icon-utilities'; import { isObject, isString } from '../types'; +export interface MarkdownStringTrustedOptions { + readonly enabledCommands: readonly string[]; +} + export interface MarkdownString { readonly value: string; - readonly isTrusted?: boolean; + readonly isTrusted?: boolean | MarkdownStringTrustedOptions; readonly supportThemeIcons?: boolean; readonly supportHtml?: boolean; readonly baseUri?: UriComponents; @@ -45,9 +49,8 @@ export namespace MarkdownString { // Copied from https://github.com/microsoft/vscode/blob/7d9b1c37f8e5ae3772782ba3b09d827eb3fdd833/src/vs/base/common/htmlContent.ts export class MarkdownStringImpl implements MarkdownString { - public value: string; - public isTrusted?: boolean; + public isTrusted?: boolean | MarkdownStringTrustedOptions; public supportThemeIcons?: boolean; public supportHtml?: boolean; public baseUri?: UriComponents; diff --git a/packages/core/src/common/quick-pick-service.ts b/packages/core/src/common/quick-pick-service.ts index ef832dbd6611f..935b6a3c80963 100644 --- a/packages/core/src/common/quick-pick-service.ts +++ b/packages/core/src/common/quick-pick-service.ts @@ -14,7 +14,6 @@ // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 // ***************************************************************************** -import URI from './uri'; import * as fuzzy from 'fuzzy'; import { Event } from './event'; import { KeySequence } from './keys'; @@ -54,11 +53,11 @@ export interface QuickPickItem { description?: string; detail?: string; keySequence?: KeySequence; - iconPath?: URI | Uri | { light?: URI | Uri; dark: URI | Uri } | { id: string }; + iconPath?: { light?: Uri; dark: Uri }; iconClasses?: string[]; alwaysShow?: boolean; highlights?: QuickPickItemHighlights; - buttons?: readonly QuickInputButton[]; + buttons?: QuickInputButton[]; execute?: () => void; } @@ -95,7 +94,7 @@ export interface QuickPickValue extends QuickPickItem { } export interface QuickInputButton { - iconPath?: URI | Uri | { light?: URI | Uri; dark: URI | Uri } | { id: string }; + iconPath?: { light?: Uri; dark: Uri }; iconClass?: string; tooltip?: string; /** @@ -104,32 +103,6 @@ export interface QuickInputButton { alwaysVisible?: boolean; } -export interface NormalizedQuickInputButton extends QuickInputButton { - iconPath?: { light?: Uri, dark: Uri }; -} - -export namespace QuickInputButton { - export function normalize(button: undefined): undefined; - export function normalize(button: QuickInputButton): NormalizedQuickInputButton; - export function normalize(button?: QuickInputButton): NormalizedQuickInputButton | undefined { - if (!button) { - return button; - } - let iconPath: NormalizedQuickInputButton['iconPath'] = undefined; - if (button.iconPath instanceof URI) { - iconPath = { dark: button.iconPath['codeUri'] }; - } else if (button.iconPath && 'dark' in button.iconPath) { - const dark = Uri.isUri(button.iconPath.dark) ? button.iconPath.dark : button.iconPath.dark['codeUri']; - const light = Uri.isUri(button.iconPath.light) ? button.iconPath.light : button.iconPath.light?.['codeUri']; - iconPath = { dark, light }; - } - return { - ...button, - iconPath, - }; - } -} - export interface QuickInputButtonHandle extends QuickInputButton { handle: number; // index of where the button is in buttons array if QuickInputButton or -1 if QuickInputButtons.Back } @@ -281,8 +254,13 @@ export interface QuickInputService { open(filter: string): void; createInputBox(): InputBox; input(options?: InputOptions, token?: CancellationToken): Promise; - pick>(picks: Promise[]> | QuickPickInput[], options?: O, token?: CancellationToken): - Promise<(O extends { canPickMany: true } ? T[] : T) | undefined>; + pick(picks: Promise[]> | QuickPickInput[], + options?: PickOptions & { canPickMany: true }, token?: CancellationToken): Promise; + pick(picks: Promise[]> | QuickPickInput[], + options?: PickOptions & { canPickMany: false }, token?: CancellationToken): Promise; + pick(picks: Promise[]> | QuickPickInput[], + options?: Omit, 'canPickMany'>, token?: CancellationToken): Promise; + showQuickPick(items: Array, options?: QuickPickOptions): Promise; hide(): void; /** diff --git a/packages/core/src/common/theme.ts b/packages/core/src/common/theme.ts index e6b5e737c8e16..8350011737611 100644 --- a/packages/core/src/common/theme.ts +++ b/packages/core/src/common/theme.ts @@ -14,6 +14,8 @@ // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 // ***************************************************************************** +import { URI } from 'vscode-uri'; + export type ThemeType = 'light' | 'dark' | 'hc' | 'hcLight'; export interface Theme { @@ -34,3 +36,33 @@ export interface ThemeChangeEvent { readonly newTheme: Theme; readonly oldTheme?: Theme; } + +export interface ThemeColor { + id: string; +} + +export interface ThemeIcon { + readonly id: string; + readonly color?: ThemeColor; +} + +export interface IconDefinition { + font?: IconFontContribution; // undefined for the default font (codicon) + fontCharacter: string; +} + +export interface IconFontContribution { + readonly id: string; + readonly definition: IconFontDefinition; +} + +export interface IconFontDefinition { + readonly weight?: string; + readonly style?: string; + readonly src: IconFontSource[]; +} + +export interface IconFontSource { + readonly location: URI; + readonly format: string; +} diff --git a/packages/core/src/common/uri.ts b/packages/core/src/common/uri.ts index fe24bc2e54339..5816c57cae48f 100644 --- a/packages/core/src/common/uri.ts +++ b/packages/core/src/common/uri.ts @@ -19,8 +19,10 @@ import { Path } from './path'; export class URI { - public static fromComponents(components: UriComponents): URI { - return new URI(Uri.revive(components)); + public static fromComponents(components: UriComponents): URI; + public static fromComponents(components: undefined): undefined; + public static fromComponents(components: UriComponents | undefined): URI | undefined { + return components ? new URI(Uri.revive(components)) : undefined; } public static fromFilePath(path: string): URI { diff --git a/packages/debug/package.json b/packages/debug/package.json index fb0dfc1a1b135..dde55cb6baa24 100644 --- a/packages/debug/package.json +++ b/packages/debug/package.json @@ -9,7 +9,7 @@ "@theia/filesystem": "1.46.0", "@theia/markers": "1.46.0", "@theia/monaco": "1.46.0", - "@theia/monaco-editor-core": "1.72.3", + "@theia/monaco-editor-core": "1.83.101", "@theia/output": "1.46.0", "@theia/process": "1.46.0", "@theia/task": "1.46.0", @@ -61,4 +61,4 @@ "nyc": { "extends": "../../configs/nyc.json" } -} +} \ No newline at end of file diff --git a/packages/debug/src/browser/debug-frontend-module.ts b/packages/debug/src/browser/debug-frontend-module.ts index d00eb179a8a9f..05a6e80031ed9 100644 --- a/packages/debug/src/browser/debug-frontend-module.ts +++ b/packages/debug/src/browser/debug-frontend-module.ts @@ -49,7 +49,6 @@ import { CommandContribution } from '@theia/core/lib/common/command'; import { TabBarToolbarContribution } from '@theia/core/lib/browser/shell/tab-bar-toolbar'; import { ColorContribution } from '@theia/core/lib/browser/color-application-contribution'; import { DebugWatchManager } from './debug-watch-manager'; -import { MonacoEditorService } from '@theia/monaco/lib/browser/monaco-editor-service'; import { DebugBreakpointWidget } from './editor/debug-breakpoint-widget'; import { DebugInlineValueDecorator } from './editor/debug-inline-value-decorator'; import { JsonSchemaContribution } from '@theia/core/lib/browser/json-schema-store'; @@ -61,6 +60,8 @@ import { DebugViewModel } from './view/debug-view-model'; import { DebugToolBar } from './view/debug-toolbar-widget'; import { DebugSessionWidget } from './view/debug-session-widget'; import { bindDisassemblyView } from './disassembly-view/disassembly-view-contribution'; +import { StandaloneServices } from '@theia/monaco-editor-core/esm/vs/editor/standalone/browser/standaloneServices'; +import { ICodeEditorService } from '@theia/monaco-editor-core/esm/vs/editor/browser/services/codeEditorService'; export default new ContainerModule((bind: interfaces.Bind) => { bindContributionProvider(bind, DebugContribution); @@ -78,7 +79,7 @@ export default new ContainerModule((bind: interfaces.Bind) => { DebugEditorModel.createModel(container, editor) )).inSingletonScope(); bind(DebugEditorService).toSelf().inSingletonScope().onActivation((context, service) => { - context.container.get(MonacoEditorService).registerDecorationType('Debug breakpoint placeholder', DebugBreakpointWidget.PLACEHOLDER_DECORATION, {}); + StandaloneServices.get(ICodeEditorService).registerDecorationType('Debug breakpoint placeholder', DebugBreakpointWidget.PLACEHOLDER_DECORATION, {}); return service; }); diff --git a/packages/debug/src/browser/debug-session-manager.ts b/packages/debug/src/browser/debug-session-manager.ts index 583a0d8af86f6..788db2c5c9009 100644 --- a/packages/debug/src/browser/debug-session-manager.ts +++ b/packages/debug/src/browser/debug-session-manager.ts @@ -179,7 +179,7 @@ export class DebugSessionManager { } isCurrentEditorFrame(uri: URI | string | monaco.Uri): boolean { - return this.currentFrame?.source?.uri.toString() === (uri instanceof URI ? uri : new URI(uri)).toString(); + return this.currentFrame?.source?.uri.toString() === (uri instanceof URI ? uri : new URI(uri.toString())).toString(); } protected async saveAll(): Promise { diff --git a/packages/debug/src/browser/disassembly-view/disassembly-view-instruction-renderer.ts b/packages/debug/src/browser/disassembly-view/disassembly-view-instruction-renderer.ts index 1fb92dfd9fd23..e43eea44d9a02 100644 --- a/packages/debug/src/browser/disassembly-view/disassembly-view-instruction-renderer.ts +++ b/packages/debug/src/browser/disassembly-view/disassembly-view-instruction-renderer.ts @@ -110,8 +110,8 @@ export class InstructionRenderer extends Disposable implements ITableRenderer= 1 && lineNumber <= textModel.getLineCount()) { const lineContent = textModel.getLineContent(lineNumber); - sourceSB.appendASCIIString(` ${lineNumber}: `); - sourceSB.appendASCIIString(lineContent + '\n'); + sourceSB.appendString(` ${lineNumber}: `); + sourceSB.appendString(lineContent + '\n'); if (instruction.endLine && lineNumber < instruction.endLine) { lineNumber++; @@ -129,27 +129,27 @@ export class InstructionRenderer extends Disposable implements ITableRenderer DebugEditorModel; @@ -94,9 +94,6 @@ export class DebugEditorModel implements Disposable { @inject(DebugInlineValueDecorator) readonly inlineValueDecorator: DebugInlineValueDecorator; - @inject(MonacoConfigurationService) - readonly configurationService: IConfigurationService; - @inject(DebugSessionManager) protected readonly sessionManager: DebugSessionManager; @@ -156,7 +153,7 @@ export class DebugEditorModel implements Disposable { resource: model.uri, overrideIdentifier: model.getLanguageId(), }; - const { enabled, delay, sticky } = this.configurationService.getValue('editor.hover', overrides); + const { enabled, delay, sticky } = StandaloneServices.get(IConfigurationService).getValue('editor.hover', overrides); codeEditor.updateOptions({ hover: { enabled, diff --git a/packages/debug/src/browser/editor/debug-inline-value-decorator.ts b/packages/debug/src/browser/editor/debug-inline-value-decorator.ts index 92c7a77ca58fa..00b27fd05eaa2 100644 --- a/packages/debug/src/browser/editor/debug-inline-value-decorator.ts +++ b/packages/debug/src/browser/editor/debug-inline-value-decorator.ts @@ -31,11 +31,11 @@ import { InlineValueContext } from '@theia/monaco-editor-core/esm/vs/editor/comm import { ITextModel } from '@theia/monaco-editor-core/esm/vs/editor/common/model'; import { ILanguageFeaturesService } from '@theia/monaco-editor-core/esm/vs/editor/common/services/languageFeatures'; import { StandaloneServices } from '@theia/monaco-editor-core/esm/vs/editor/standalone/browser/standaloneServices'; -import { MonacoEditorService } from '@theia/monaco/lib/browser/monaco-editor-service'; import { DebugVariable, ExpressionContainer, ExpressionItem } from '../console/debug-console-items'; import { DebugPreferences } from '../debug-preferences'; import { DebugStackFrame } from '../model/debug-stack-frame'; import { DebugEditorModel } from './debug-editor-model'; +import { ICodeEditorService } from '@theia/monaco-editor-core/esm/vs/editor/browser/services/codeEditorService'; // https://github.com/theia-ide/vscode/blob/standalone/0.19.x/src/vs/workbench/contrib/debug/browser/debugEditorContribution.ts#L40-L43 export const INLINE_VALUE_DECORATION_KEY = 'inlinevaluedecoration'; @@ -59,10 +59,6 @@ class InlineSegment { @injectable() export class DebugInlineValueDecorator implements FrontendApplicationContribution { - - @inject(MonacoEditorService) - protected readonly editorService: MonacoEditorService; - @inject(DebugPreferences) protected readonly preferences: DebugPreferences; @@ -70,7 +66,7 @@ export class DebugInlineValueDecorator implements FrontendApplicationContributio protected wordToLineNumbersMap: Map | undefined = new Map(); onStart(): void { - this.editorService.registerDecorationType('Inline debug decorations', INLINE_VALUE_DECORATION_KEY, {}); + StandaloneServices.get(ICodeEditorService).registerDecorationType('Inline debug decorations', INLINE_VALUE_DECORATION_KEY, {}); this.enabled = !!this.preferences['debug.inlineValues']; this.preferences.onPreferenceChanged(({ preferenceName, newValue }) => { if (preferenceName === 'debug.inlineValues' && !!newValue !== this.enabled) { diff --git a/packages/editor/src/browser/diff-navigator.ts b/packages/editor/src/browser/diff-navigator.ts index 71679f9dea2bf..b9517831a8691 100644 --- a/packages/editor/src/browser/diff-navigator.ts +++ b/packages/editor/src/browser/diff-navigator.ts @@ -17,7 +17,6 @@ import { TextEditor } from './editor'; export interface DiffNavigator { - canNavigate(): boolean; hasNext(): boolean; hasPrevious(): boolean; next(): void; diff --git a/packages/editor/src/browser/editor-generated-preference-schema.ts b/packages/editor/src/browser/editor-generated-preference-schema.ts index 37d5749bee459..4f00af0a3071f 100644 --- a/packages/editor/src/browser/editor-generated-preference-schema.ts +++ b/packages/editor/src/browser/editor-generated-preference-schema.ts @@ -30,43 +30,54 @@ export const editorGeneratedPreferenceProperties: PreferenceSchema['properties'] "type": "number", "default": 4, "minimum": 1, - "markdownDescription": nls.localizeByDefault('The number of spaces a tab is equal to. This setting is overridden based on the file contents when {0} is on.', '`#editor.detectIndentation#`'), - "scope": "language-overridable", + "markdownDescription": nls.localize("theia/editor/editor.tabSize", "The number of spaces a tab is equal to. This setting is overridden based on the file contents when `#editor.detectIndentation#` is on."), + "restricted": false + }, + "editor.indentSize": { + "anyOf": [ + { + "type": "string", + "enum": [ + "tabSize" + ] + }, + { + "type": "number", + "minimum": 1 + } + ], + "default": "tabSize", + "markdownDescription": nls.localizeByDefault("The number of spaces used for indentation or `\"tabSize\"` to use the value from `#editor.tabSize#`. This setting is overridden based on the file contents when `#editor.detectIndentation#` is on."), "restricted": false }, "editor.insertSpaces": { "type": "boolean", "default": true, - "markdownDescription": nls.localizeByDefault('Insert spaces when pressing `Tab`. This setting is overridden based on the file contents when {0} is on.', `#editor.detectIndentation#`), - "scope": "language-overridable", + "markdownDescription": nls.localize("theia/editor/editor.insertSpaces", "Insert spaces when pressing `Tab`. This setting is overridden based on the file contents when `#editor.detectIndentation#` is on."), "restricted": false }, "editor.detectIndentation": { "type": "boolean", "default": true, - "markdownDescription": nls.localizeByDefault('Controls whether {0} and {1} will be automatically detected when a file is opened based on the file contents.', '`#editor.tabSize#`', '`#editor.insertSpaces#`'), - "scope": "language-overridable", + "markdownDescription": nls.localize("theia/editor/editor.detectIndentation", "Controls whether `#editor.tabSize#` and `#editor.insertSpaces#` will be automatically detected when a file is opened based on the file contents."), "restricted": false }, "editor.trimAutoWhitespace": { "type": "boolean", "default": true, "description": nls.localizeByDefault("Remove trailing auto inserted whitespace."), - "scope": "language-overridable", "restricted": false }, "editor.largeFileOptimizations": { "type": "boolean", "default": true, "description": nls.localizeByDefault("Special handling for large files to disable certain memory intensive features."), - "scope": "language-overridable", "restricted": false }, "editor.wordBasedSuggestions": { "type": "boolean", "default": true, "description": nls.localizeByDefault("Controls whether completions should be computed based on words in the document."), - "scope": "language-overridable", "restricted": false }, "editor.wordBasedSuggestionsMode": { @@ -82,7 +93,6 @@ export const editorGeneratedPreferenceProperties: PreferenceSchema['properties'] nls.localizeByDefault("Suggest words from all open documents.") ], "description": nls.localizeByDefault("Controls from which documents word based completions are computed."), - "scope": "language-overridable", "restricted": false }, "editor.semanticHighlighting.enabled": { @@ -98,21 +108,42 @@ export const editorGeneratedPreferenceProperties: PreferenceSchema['properties'] ], "default": "configuredByTheme", "description": nls.localizeByDefault("Controls whether the semanticHighlighting is shown for the languages that support it."), - "scope": "language-overridable", "restricted": false }, "editor.stablePeek": { "type": "boolean", "default": false, - "markdownDescription": nls.localizeByDefault('Keep peek editors open even when double-clicking their content or when hitting `Escape`.'), - "scope": "language-overridable", + "markdownDescription": nls.localizeByDefault("Keep peek editors open even when double-clicking their content or when hitting `Escape`."), "restricted": false }, "editor.maxTokenizationLineLength": { "type": "integer", "default": 20000, "description": nls.localizeByDefault("Lines above this length will not be tokenized for performance reasons"), - "scope": "language-overridable", + "restricted": false + }, + "editor.experimental.asyncTokenization": { + "type": "boolean", + "default": false, + "description": nls.localizeByDefault("Controls whether the tokenization should happen asynchronously on a web worker."), + "tags": [ + "experimental" + ], + "restricted": false + }, + "editor.experimental.asyncTokenizationLogging": { + "type": "boolean", + "default": false, + "description": nls.localizeByDefault("Controls whether async tokenization should be logged. For debugging only."), + "restricted": false + }, + "editor.experimental.asyncTokenizationVerification": { + "type": "boolean", + "default": false, + "description": nls.localizeByDefault("Controls whether async tokenization should be verified against legacy background tokenization. Might slow down tokenization. For debugging only."), + "tags": [ + "experimental" + ], "restricted": false }, "editor.language.brackets": { @@ -135,7 +166,6 @@ export const editorGeneratedPreferenceProperties: PreferenceSchema['properties'] } ] }, - "scope": "language-overridable", "restricted": false }, "editor.language.colorizedBracketPairs": { @@ -158,56 +188,60 @@ export const editorGeneratedPreferenceProperties: PreferenceSchema['properties'] } ] }, - "scope": "language-overridable", "restricted": false }, "diffEditor.maxComputationTime": { "type": "number", "default": 5000, "description": nls.localizeByDefault("Timeout in milliseconds after which diff computation is cancelled. Use 0 for no timeout."), - "scope": "language-overridable", "restricted": false }, "diffEditor.maxFileSize": { "type": "number", "default": 50, "description": nls.localizeByDefault("Maximum file size in MB for which to compute diffs. Use 0 for no limit."), - "scope": "language-overridable", "restricted": false }, "diffEditor.renderSideBySide": { "type": "boolean", "default": true, "description": nls.localizeByDefault("Controls whether the diff editor shows the diff side by side or inline."), - "scope": "language-overridable", + "restricted": false + }, + "diffEditor.renderSideBySideInlineBreakpoint": { + "type": "number", + "default": 900, + "description": nls.localizeByDefault("If the diff editor width is smaller than this value, the inline view is used."), + "restricted": false + }, + "diffEditor.useInlineViewWhenSpaceIsLimited": { + "type": "boolean", + "default": true, + "description": nls.localizeByDefault("If enabled and the editor width is too small, the inline view is used."), "restricted": false }, "diffEditor.renderMarginRevertIcon": { "type": "boolean", "default": true, "description": nls.localizeByDefault("When enabled, the diff editor shows arrows in its glyph margin to revert changes."), - "scope": "language-overridable", "restricted": false }, "diffEditor.ignoreTrimWhitespace": { "type": "boolean", "default": true, "description": nls.localizeByDefault("When enabled, the diff editor ignores changes in leading or trailing whitespace."), - "scope": "language-overridable", "restricted": false }, "diffEditor.renderIndicators": { "type": "boolean", "default": true, "description": nls.localizeByDefault("Controls whether the diff editor shows +/- indicators for added/removed changes."), - "scope": "language-overridable", "restricted": false }, "diffEditor.codeLens": { "type": "boolean", "default": false, "description": nls.localizeByDefault("Controls whether the editor shows CodeLens."), - "scope": "language-overridable", "restricted": false }, "diffEditor.wordWrap": { @@ -221,30 +255,69 @@ export const editorGeneratedPreferenceProperties: PreferenceSchema['properties'] "markdownEnumDescriptions": [ nls.localizeByDefault("Lines will never wrap."), nls.localizeByDefault("Lines will wrap at the viewport width."), - nls.localizeByDefault('Lines will wrap according to the {0} setting.', '`#editor.wordWrap#`') + nls.localize("theia/editor/diffEditor.wordWrap2", "Lines will wrap according to the `#editor.wordWrap#` setting.") ], - "scope": "language-overridable", "restricted": false }, "diffEditor.diffAlgorithm": { "type": "string", "enum": [ - "smart", - "experimental" + "legacy", + "advanced" ], - "default": "smart", + "default": "advanced", "markdownEnumDescriptions": [ nls.localizeByDefault("Uses the legacy diffing algorithm."), nls.localizeByDefault("Uses the advanced diffing algorithm.") ], - "scope": "language-overridable", + "tags": [ + "experimental" + ], + "restricted": false + }, + "diffEditor.hideUnchangedRegions.enabled": { + "type": "boolean", + "default": false, + "markdownDescription": nls.localizeByDefault("Controls whether the diff editor shows unchanged regions."), + "restricted": false + }, + "diffEditor.hideUnchangedRegions.revealLineCount": { + "type": "integer", + "default": 20, + "markdownDescription": nls.localizeByDefault("Controls how many lines are used for unchanged regions."), + "minimum": 1, + "restricted": false + }, + "diffEditor.hideUnchangedRegions.minimumLineCount": { + "type": "integer", + "default": 3, + "markdownDescription": nls.localizeByDefault("Controls how many lines are used as a minimum for unchanged regions."), + "minimum": 1, + "restricted": false + }, + "diffEditor.hideUnchangedRegions.contextLineCount": { + "type": "integer", + "default": 3, + "markdownDescription": nls.localizeByDefault("Controls how many lines are used as context when comparing unchanged regions."), + "minimum": 1, + "restricted": false + }, + "diffEditor.experimental.showMoves": { + "type": "boolean", + "default": false, + "markdownDescription": nls.localizeByDefault("Controls whether the diff editor should show detected code moves."), + "restricted": false + }, + "diffEditor.experimental.showEmptyDecorations": { + "type": "boolean", + "default": true, + "description": nls.localizeByDefault("Controls whether the diff editor shows empty decorations to see where characters got inserted or deleted."), "restricted": false }, "editor.acceptSuggestionOnCommitCharacter": { - "markdownDescription": nls.localizeByDefault('Controls whether suggestions should be accepted on commit characters. For example, in JavaScript, the semi-colon (`;`) can be a commit character that accepts a suggestion and types that character.'), + "markdownDescription": nls.localizeByDefault("Controls whether suggestions should be accepted on commit characters. For example, in JavaScript, the semi-colon (`;`) can be a commit character that accepts a suggestion and types that character."), "type": "boolean", "default": true, - "scope": "language-overridable", "restricted": false }, "editor.acceptSuggestionOnEnter": { @@ -261,7 +334,6 @@ export const editorGeneratedPreferenceProperties: PreferenceSchema['properties'] "off" ], "default": "on", - "scope": "language-overridable", "restricted": false }, "editor.accessibilitySupport": { @@ -272,22 +344,26 @@ export const editorGeneratedPreferenceProperties: PreferenceSchema['properties'] "off" ], "enumDescriptions": [ - nls.localizeByDefault('Use platform APIs to detect when a Screen Reader is attached.'), - nls.localizeByDefault("Optimize for usage with a Screen Reader."), - nls.localizeByDefault("Assume a screen reader is not attached.") + nls.localize("theia/editor/editor.accessibilitySupport0", "Use platform APIs to detect when a Screen Reader is attached"), + nls.localize("theia/editor/editor.accessibilitySupport1", "Optimize for usage with a Screen Reader"), + nls.localize("theia/editor/editor.accessibilitySupport2", "Assume a screen reader is not attached") ], "default": "auto", + "tags": [ + "accessibility" + ], "description": nls.localizeByDefault("Controls if the UI should run in a mode where it is optimized for screen readers."), - "scope": "language-overridable", "restricted": false }, "editor.accessibilityPageSize": { "description": nls.localizeByDefault("Controls the number of lines in the editor that can be read out by a screen reader at once. When we detect a screen reader we automatically set the default to be 500. Warning: this has a performance implication for numbers larger than the default."), + "tags": [ + "accessibility" + ], "type": "integer", "default": 10, "minimum": 1, "maximum": 1073741824, - "scope": "language-overridable", "restricted": false }, "editor.autoClosingBrackets": { @@ -306,7 +382,33 @@ export const editorGeneratedPreferenceProperties: PreferenceSchema['properties'] "never" ], "default": "languageDefined", - "scope": "language-overridable", + "restricted": false + }, + "editor.autoClosingComments": { + "enumDescriptions": [ + "", + nls.localizeByDefault("Use language configurations to determine when to autoclose comments."), + nls.localizeByDefault("Autoclose comments only when the cursor is to the left of whitespace."), + "" + ], + "description": nls.localizeByDefault("Controls whether the editor should automatically close comments after the user adds an opening comment."), + "type": "string", + "enum": [ + "always", + "languageDefined", + "beforeWhitespace", + "never" + ], + "default": "languageDefined", + "restricted": false + }, + "editor.screenReaderAnnounceInlineSuggestion": { + "description": nls.localizeByDefault("Control whether inline suggestions are announced by a screen reader."), + "tags": [ + "accessibility" + ], + "type": "boolean", + "default": true, "restricted": false }, "editor.autoClosingDelete": { @@ -323,7 +425,6 @@ export const editorGeneratedPreferenceProperties: PreferenceSchema['properties'] "never" ], "default": "auto", - "scope": "language-overridable", "restricted": false }, "editor.autoClosingOvertype": { @@ -340,7 +441,6 @@ export const editorGeneratedPreferenceProperties: PreferenceSchema['properties'] "never" ], "default": "auto", - "scope": "language-overridable", "restricted": false }, "editor.autoClosingQuotes": { @@ -359,7 +459,6 @@ export const editorGeneratedPreferenceProperties: PreferenceSchema['properties'] "never" ], "default": "languageDefined", - "scope": "language-overridable", "restricted": false }, "editor.autoIndent": { @@ -380,7 +479,6 @@ export const editorGeneratedPreferenceProperties: PreferenceSchema['properties'] "full" ], "default": "full", - "scope": "language-overridable", "restricted": false }, "editor.autoSurround": { @@ -399,21 +497,18 @@ export const editorGeneratedPreferenceProperties: PreferenceSchema['properties'] "never" ], "default": "languageDefined", - "scope": "language-overridable", "restricted": false }, "editor.bracketPairColorization.enabled": { "type": "boolean", "default": true, - "markdownDescription": nls.localizeByDefault('Controls whether bracket pair colorization is enabled or not. Use {0} to override the bracket highlight colors.', '`#workbench.colorCustomizations#`'), - "scope": "language-overridable", + "markdownDescription": nls.localize("theia/editor/editor.bracketPairColorization.enabled", "Controls whether bracket pair colorization is enabled or not. Use `#workbench.colorCustomizations#` to override the bracket highlight colors."), "restricted": false }, "editor.bracketPairColorization.independentColorPoolPerBracketType": { "type": "boolean", "default": false, "description": nls.localizeByDefault("Controls whether each bracket type has its own independent color pool."), - "scope": "language-overridable", "restricted": false }, "editor.guides.bracketPairs": { @@ -433,7 +528,6 @@ export const editorGeneratedPreferenceProperties: PreferenceSchema['properties'] ], "default": false, "description": nls.localizeByDefault("Controls whether bracket pair guides are enabled or not."), - "scope": "language-overridable", "restricted": false }, "editor.guides.bracketPairsHorizontal": { @@ -453,21 +547,18 @@ export const editorGeneratedPreferenceProperties: PreferenceSchema['properties'] ], "default": "active", "description": nls.localizeByDefault("Controls whether horizontal bracket pair guides are enabled or not."), - "scope": "language-overridable", "restricted": false }, "editor.guides.highlightActiveBracketPair": { "type": "boolean", "default": true, "description": nls.localizeByDefault("Controls whether the editor should highlight the active bracket pair."), - "scope": "language-overridable", "restricted": false }, "editor.guides.indentation": { "type": "boolean", "default": true, "description": nls.localizeByDefault("Controls whether the editor should render indent guides."), - "scope": "language-overridable", "restricted": false }, "editor.guides.highlightActiveIndentation": { @@ -487,21 +578,18 @@ export const editorGeneratedPreferenceProperties: PreferenceSchema['properties'] ], "default": true, "description": nls.localizeByDefault("Controls whether the editor should highlight the active indent guide."), - "scope": "language-overridable", "restricted": false }, "editor.codeLens": { "description": nls.localizeByDefault("Controls whether the editor shows CodeLens."), "type": "boolean", "default": true, - "scope": "language-overridable", "restricted": false }, "editor.codeLensFontFamily": { "description": nls.localizeByDefault("Controls the font family for CodeLens."), "type": "string", "default": "", - "scope": "language-overridable", "restricted": false }, "editor.codeLensFontSize": { @@ -509,43 +597,45 @@ export const editorGeneratedPreferenceProperties: PreferenceSchema['properties'] "default": 0, "minimum": 0, "maximum": 100, - "markdownDescription": nls.localizeByDefault('Controls the font size in pixels for CodeLens. When set to 0, 90% of `#editor.fontSize#` is used.'), - "scope": "language-overridable", + "markdownDescription": nls.localizeByDefault("Controls the font size in pixels for CodeLens. When set to 0, 90% of `#editor.fontSize#` is used."), "restricted": false }, "editor.colorDecorators": { "description": nls.localizeByDefault("Controls whether the editor should render the inline color decorators and color picker."), "type": "boolean", "default": true, - "scope": "language-overridable", + "restricted": false + }, + "editor.colorDecoratorsLimit": { + "markdownDescription": nls.localizeByDefault("Controls the max number of color decorators that can be rendered in an editor at once."), + "type": "integer", + "default": 500, + "minimum": 1, + "maximum": 1000000, "restricted": false }, "editor.columnSelection": { "description": nls.localizeByDefault("Enable that the selection with the mouse and keys is doing column selection."), "type": "boolean", "default": false, - "scope": "language-overridable", "restricted": false }, "editor.comments.insertSpace": { "type": "boolean", "default": true, "description": nls.localizeByDefault("Controls whether a space character is inserted when commenting."), - "scope": "language-overridable", "restricted": false }, "editor.comments.ignoreEmptyLines": { "type": "boolean", "default": true, "description": nls.localizeByDefault("Controls if empty lines should be ignored with toggle, add or remove actions for line comments."), - "scope": "language-overridable", "restricted": false }, "editor.copyWithSyntaxHighlighting": { "description": nls.localizeByDefault("Controls whether syntax highlighting should be copied into the clipboard."), "type": "boolean", "default": true, - "scope": "language-overridable", "restricted": false }, "editor.cursorBlinking": { @@ -559,14 +649,22 @@ export const editorGeneratedPreferenceProperties: PreferenceSchema['properties'] "solid" ], "default": "blink", - "scope": "language-overridable", "restricted": false }, "editor.cursorSmoothCaretAnimation": { + "enumDescriptions": [ + nls.localizeByDefault("Smooth caret animation is disabled."), + nls.localizeByDefault("Smooth caret animation is enabled only when the user moves the cursor with an explicit gesture."), + nls.localizeByDefault("Smooth caret animation is always enabled.") + ], "description": nls.localizeByDefault("Controls whether the smooth caret animation should be enabled."), - "type": "boolean", - "default": false, - "scope": "language-overridable", + "type": "string", + "enum": [ + "off", + "explicit", + "on" + ], + "default": "off", "restricted": false }, "editor.cursorStyle": { @@ -581,16 +679,14 @@ export const editorGeneratedPreferenceProperties: PreferenceSchema['properties'] "underline-thin" ], "default": "line", - "scope": "language-overridable", "restricted": false }, "editor.cursorSurroundingLines": { - "description": nls.localizeByDefault('Controls the minimal number of visible leading lines (minimum 0) and trailing lines (minimum 1) surrounding the cursor. Known as \'scrollOff\' or \'scrollOffset\' in some other editors.'), + "description": nls.localizeByDefault("Controls the minimal number of visible leading lines (minimum 0) and trailing lines (minimum 1) surrounding the cursor. Known as 'scrollOff' or 'scrollOffset' in some other editors."), "type": "integer", "default": 0, "minimum": 0, "maximum": 1073741824, - "scope": "language-overridable", "restricted": false }, "editor.cursorSurroundingLinesStyle": { @@ -598,14 +694,13 @@ export const editorGeneratedPreferenceProperties: PreferenceSchema['properties'] nls.localizeByDefault("`cursorSurroundingLines` is enforced only when triggered via the keyboard or API."), nls.localizeByDefault("`cursorSurroundingLines` is enforced always.") ], - "description": nls.localizeByDefault("Controls when `#cursorSurroundingLines#` should be enforced."), + "markdownDescription": nls.localizeByDefault("Controls when `#cursorSurroundingLines#` should be enforced."), "type": "string", "enum": [ "default", "all" ], "default": "default", - "scope": "language-overridable", "restricted": false }, "editor.cursorWidth": { @@ -614,42 +709,66 @@ export const editorGeneratedPreferenceProperties: PreferenceSchema['properties'] "default": 0, "minimum": 0, "maximum": 1073741824, - "scope": "language-overridable", "restricted": false }, "editor.dragAndDrop": { "description": nls.localizeByDefault("Controls whether the editor should allow moving selections via drag and drop."), "type": "boolean", "default": true, - "scope": "language-overridable", "restricted": false }, "editor.dropIntoEditor.enabled": { "type": "boolean", "default": true, "markdownDescription": nls.localizeByDefault("Controls whether you can drag and drop a file into a text editor by holding down `shift` (instead of opening the file in an editor)."), - "scope": "language-overridable", + "restricted": false + }, + "editor.dropIntoEditor.showDropSelector": { + "type": "string", + "markdownDescription": nls.localizeByDefault("Controls if a widget is shown when dropping files into the editor. This widget lets you control how the file is dropped."), + "enum": [ + "afterDrop", + "never" + ], + "enumDescriptions": [ + nls.localizeByDefault("Show the drop selector widget after a file is dropped into the editor."), + nls.localizeByDefault("Never show the drop selector widget. Instead the default drop provider is always used.") + ], + "default": "afterDrop", "restricted": false }, "editor.emptySelectionClipboard": { "description": nls.localizeByDefault("Controls whether copying without a selection copies the current line."), "type": "boolean", "default": true, - "scope": "language-overridable", + "restricted": false + }, + "editor.experimentalWhitespaceRendering": { + "enumDescriptions": [ + nls.localizeByDefault("Use a new rendering method with svgs."), + nls.localizeByDefault("Use a new rendering method with font characters."), + nls.localizeByDefault("Use the stable rendering method.") + ], + "description": nls.localizeByDefault("Controls whether whitespace is rendered with a new, experimental method."), + "type": "string", + "enum": [ + "svg", + "font", + "off" + ], + "default": "svg", "restricted": false }, "editor.fastScrollSensitivity": { "markdownDescription": nls.localizeByDefault("Scrolling speed multiplier when pressing `Alt`."), "type": "number", "default": 5, - "scope": "language-overridable", "restricted": false }, "editor.find.cursorMoveOnType": { "type": "boolean", "default": true, "description": nls.localizeByDefault("Controls whether the cursor should jump to find matches while typing."), - "scope": "language-overridable", "restricted": false }, "editor.find.seedSearchStringFromSelection": { @@ -666,7 +785,6 @@ export const editorGeneratedPreferenceProperties: PreferenceSchema['properties'] nls.localizeByDefault("Only seed search string from the editor selection.") ], "description": nls.localizeByDefault("Controls whether the search string in the Find Widget is seeded from the editor selection."), - "scope": "language-overridable", "restricted": false }, "editor.find.autoFindInSelection": { @@ -678,33 +796,29 @@ export const editorGeneratedPreferenceProperties: PreferenceSchema['properties'] ], "default": "never", "enumDescriptions": [ - nls.localizeByDefault('Never turn on Find in Selection automatically (default).'), - nls.localizeByDefault('Always turn on Find in Selection automatically.'), - nls.localizeByDefault('Turn on Find in Selection automatically when multiple lines of content are selected.'), + nls.localizeByDefault("Never turn on Find in Selection automatically (default)."), + nls.localizeByDefault("Always turn on Find in Selection automatically."), + nls.localizeByDefault("Turn on Find in Selection automatically when multiple lines of content are selected.") ], - "description": nls.localizeByDefault('Controls the condition for turning on Find in Selection automatically.'), - "scope": "language-overridable", + "description": nls.localizeByDefault("Controls the condition for turning on Find in Selection automatically."), "restricted": false }, "editor.find.addExtraSpaceOnTop": { "type": "boolean", "default": true, "description": nls.localizeByDefault("Controls whether the Find Widget should add extra lines on top of the editor. When true, you can scroll beyond the first line when the Find Widget is visible."), - "scope": "language-overridable", "restricted": false }, "editor.find.loop": { "type": "boolean", "default": true, "description": nls.localizeByDefault("Controls whether the search automatically restarts from the beginning (or the end) when no further matches can be found."), - "scope": "language-overridable", "restricted": false }, "editor.folding": { "description": nls.localizeByDefault("Controls whether the editor has code folding enabled."), "type": "boolean", "default": true, - "scope": "language-overridable", "restricted": false }, "editor.foldingStrategy": { @@ -719,21 +833,18 @@ export const editorGeneratedPreferenceProperties: PreferenceSchema['properties'] "indentation" ], "default": "auto", - "scope": "language-overridable", "restricted": false }, "editor.foldingHighlight": { "description": nls.localizeByDefault("Controls whether the editor should highlight folded ranges."), "type": "boolean", "default": true, - "scope": "language-overridable", "restricted": false }, "editor.foldingImportsByDefault": { "description": nls.localizeByDefault("Controls whether the editor automatically collapses import ranges."), "type": "boolean", "default": false, - "scope": "language-overridable", "restricted": false }, "editor.foldingMaximumRegions": { @@ -742,21 +853,18 @@ export const editorGeneratedPreferenceProperties: PreferenceSchema['properties'] "default": 5000, "minimum": 10, "maximum": 65000, - "scope": "language-overridable", "restricted": false }, "editor.unfoldOnClickAfterEndOfLine": { "description": nls.localizeByDefault("Controls whether clicking on the empty content after a folded line will unfold the line."), "type": "boolean", "default": false, - "scope": "language-overridable", "restricted": false }, "editor.fontFamily": { "description": nls.localizeByDefault("Controls the font family."), "type": "string", "default": isOSX ? 'Menlo, Monaco, \'Courier New\', monospace' : isWindows ? 'Consolas, \'Courier New\', monospace' : '\'Droid Sans Mono\', \'monospace\', monospace', - "scope": "language-overridable", "restricted": false }, "editor.fontLigatures": { @@ -772,7 +880,6 @@ export const editorGeneratedPreferenceProperties: PreferenceSchema['properties'] ], "description": nls.localizeByDefault("Configures font ligatures or font features. Can be either a boolean to enable/disable ligatures or a string for the value of the CSS 'font-feature-settings' property."), "default": false, - "scope": "language-overridable", "restricted": false }, "editor.fontSize": { @@ -781,7 +888,6 @@ export const editorGeneratedPreferenceProperties: PreferenceSchema['properties'] "maximum": 100, "default": isOSX ? 12 : 14, "description": nls.localizeByDefault("Controls the font size in pixels."), - "scope": "language-overridable", "restricted": false }, "editor.fontWeight": { @@ -814,34 +920,44 @@ export const editorGeneratedPreferenceProperties: PreferenceSchema['properties'] ], "default": "normal", "description": nls.localizeByDefault("Controls the font weight. Accepts \"normal\" and \"bold\" keywords or numbers between 1 and 1000."), - "scope": "language-overridable", + "restricted": false + }, + "editor.fontVariations": { + "anyOf": [ + { + "type": "boolean", + "description": nls.localizeByDefault("Enables/Disables the translation from font-weight to font-variation-settings. Change this to a string for fine-grained control of the 'font-variation-settings' CSS property.") + }, + { + "type": "string", + "description": nls.localizeByDefault("Explicit 'font-variation-settings' CSS property. A boolean can be passed instead if one only needs to translate font-weight to font-variation-settings.") + } + ], + "description": nls.localizeByDefault("Configures font variations. Can be either a boolean to enable/disable the translation from font-weight to font-variation-settings or a string for the value of the CSS 'font-variation-settings' property."), + "default": false, "restricted": false }, "editor.formatOnPaste": { "description": nls.localizeByDefault("Controls whether the editor should automatically format the pasted content. A formatter must be available and the formatter should be able to format a range in a document."), "type": "boolean", "default": false, - "scope": "language-overridable", "restricted": false }, "editor.formatOnType": { "description": nls.localizeByDefault("Controls whether the editor should automatically format the line after typing."), "type": "boolean", "default": false, - "scope": "language-overridable", "restricted": false }, "editor.glyphMargin": { "description": nls.localizeByDefault("Controls whether the editor should render the vertical glyph margin. Glyph margin is mostly used for debugging."), "type": "boolean", "default": true, - "scope": "language-overridable", "restricted": false }, "editor.gotoLocation.multiple": { "deprecationMessage": "This setting is deprecated, please use separate settings like 'editor.editor.gotoLocation.multipleDefinitions' or 'editor.editor.gotoLocation.multipleImplementations' instead.", "default": null, - "scope": "language-overridable", "restricted": false }, "editor.gotoLocation.multipleDefinitions": { @@ -856,9 +972,8 @@ export const editorGeneratedPreferenceProperties: PreferenceSchema['properties'] "enumDescriptions": [ nls.localizeByDefault("Show Peek view of the results (default)"), nls.localizeByDefault("Go to the primary result and show a Peek view"), - nls.localizeByDefault('Go to the primary result and enable Peek-less navigation to others') + nls.localizeByDefault("Go to the primary result and enable Peek-less navigation to others") ], - "scope": "language-overridable", "restricted": false }, "editor.gotoLocation.multipleTypeDefinitions": { @@ -873,9 +988,8 @@ export const editorGeneratedPreferenceProperties: PreferenceSchema['properties'] "enumDescriptions": [ nls.localizeByDefault("Show Peek view of the results (default)"), nls.localizeByDefault("Go to the primary result and show a Peek view"), - nls.localizeByDefault('Go to the primary result and enable Peek-less navigation to others') + nls.localizeByDefault("Go to the primary result and enable Peek-less navigation to others") ], - "scope": "language-overridable", "restricted": false }, "editor.gotoLocation.multipleDeclarations": { @@ -890,9 +1004,8 @@ export const editorGeneratedPreferenceProperties: PreferenceSchema['properties'] "enumDescriptions": [ nls.localizeByDefault("Show Peek view of the results (default)"), nls.localizeByDefault("Go to the primary result and show a Peek view"), - nls.localizeByDefault('Go to the primary result and enable Peek-less navigation to others') + nls.localizeByDefault("Go to the primary result and enable Peek-less navigation to others") ], - "scope": "language-overridable", "restricted": false }, "editor.gotoLocation.multipleImplementations": { @@ -907,9 +1020,8 @@ export const editorGeneratedPreferenceProperties: PreferenceSchema['properties'] "enumDescriptions": [ nls.localizeByDefault("Show Peek view of the results (default)"), nls.localizeByDefault("Go to the primary result and show a Peek view"), - nls.localizeByDefault('Go to the primary result and enable Peek-less navigation to others') + nls.localizeByDefault("Go to the primary result and enable Peek-less navigation to others") ], - "scope": "language-overridable", "restricted": false }, "editor.gotoLocation.multipleReferences": { @@ -924,9 +1036,8 @@ export const editorGeneratedPreferenceProperties: PreferenceSchema['properties'] "enumDescriptions": [ nls.localizeByDefault("Show Peek view of the results (default)"), nls.localizeByDefault("Go to the primary result and show a Peek view"), - nls.localizeByDefault('Go to the primary result and enable Peek-less navigation to others') + nls.localizeByDefault("Go to the primary result and enable Peek-less navigation to others") ], - "scope": "language-overridable", "restricted": false }, "editor.gotoLocation.alternativeDefinitionCommand": { @@ -947,7 +1058,6 @@ export const editorGeneratedPreferenceProperties: PreferenceSchema['properties'] "editor.action.revealDefinition" ], "description": nls.localizeByDefault("Alternative command id that is being executed when the result of 'Go to Definition' is the current location."), - "scope": "language-overridable", "restricted": false }, "editor.gotoLocation.alternativeTypeDefinitionCommand": { @@ -968,7 +1078,6 @@ export const editorGeneratedPreferenceProperties: PreferenceSchema['properties'] "editor.action.revealDefinition" ], "description": nls.localizeByDefault("Alternative command id that is being executed when the result of 'Go to Type Definition' is the current location."), - "scope": "language-overridable", "restricted": false }, "editor.gotoLocation.alternativeDeclarationCommand": { @@ -989,7 +1098,6 @@ export const editorGeneratedPreferenceProperties: PreferenceSchema['properties'] "editor.action.revealDefinition" ], "description": nls.localizeByDefault("Alternative command id that is being executed when the result of 'Go to Declaration' is the current location."), - "scope": "language-overridable", "restricted": false }, "editor.gotoLocation.alternativeImplementationCommand": { @@ -1010,7 +1118,6 @@ export const editorGeneratedPreferenceProperties: PreferenceSchema['properties'] "editor.action.revealDefinition" ], "description": nls.localizeByDefault("Alternative command id that is being executed when the result of 'Go to Implementation' is the current location."), - "scope": "language-overridable", "restricted": false }, "editor.gotoLocation.alternativeReferenceCommand": { @@ -1031,21 +1138,18 @@ export const editorGeneratedPreferenceProperties: PreferenceSchema['properties'] "editor.action.revealDefinition" ], "description": nls.localizeByDefault("Alternative command id that is being executed when the result of 'Go to Reference' is the current location."), - "scope": "language-overridable", "restricted": false }, "editor.hideCursorInOverviewRuler": { "description": nls.localizeByDefault("Controls whether the cursor should be hidden in the overview ruler."), "type": "boolean", "default": false, - "scope": "language-overridable", "restricted": false }, "editor.hover.enabled": { "type": "boolean", "default": true, "description": nls.localizeByDefault("Controls whether the hover is shown."), - "scope": "language-overridable", "restricted": false }, "editor.hover.delay": { @@ -1054,49 +1158,69 @@ export const editorGeneratedPreferenceProperties: PreferenceSchema['properties'] "minimum": 0, "maximum": 10000, "description": nls.localizeByDefault("Controls the delay in milliseconds after which the hover is shown."), - "scope": "language-overridable", "restricted": false }, "editor.hover.sticky": { "type": "boolean", "default": true, "description": nls.localizeByDefault("Controls whether the hover should remain visible when mouse is moved over it."), - "scope": "language-overridable", + "restricted": false + }, + "editor.hover.hidingDelay": { + "type": "integer", + "minimum": 0, + "default": 300, + "description": nls.localize("theia/editor/editor.hover.hidingDelay", "Controls the delay in milliseconds after thich the hover is hidden. Requires `editor.hover.sticky` to be enabled."), "restricted": false }, "editor.hover.above": { "type": "boolean", "default": true, "description": nls.localizeByDefault("Prefer showing hovers above the line, if there's space."), - "scope": "language-overridable", "restricted": false }, "editor.inlineSuggest.enabled": { "type": "boolean", "default": true, "description": nls.localizeByDefault("Controls whether to automatically show inline suggestions in the editor."), - "scope": "language-overridable", + "restricted": false + }, + "editor.inlineSuggest.showToolbar": { + "type": "string", + "default": "onHover", + "enum": [ + "always", + "onHover" + ], + "enumDescriptions": [ + nls.localizeByDefault("Show the inline suggestion toolbar whenever an inline suggestion is shown."), + nls.localizeByDefault("Show the inline suggestion toolbar when hovering over an inline suggestion.") + ], + "description": nls.localizeByDefault("Controls when to show the inline suggestion toolbar."), + "restricted": false + }, + "editor.inlineSuggest.suppressSuggestions": { + "type": "boolean", + "default": false, + "description": nls.localizeByDefault("Controls how inline suggestions interact with the suggest widget. If enabled, the suggest widget is not shown automatically when inline suggestions are available."), "restricted": false }, "editor.letterSpacing": { "description": nls.localizeByDefault("Controls the letter spacing in pixels."), "type": "number", "default": 0, - "scope": "language-overridable", "restricted": false }, "editor.lightbulb.enabled": { "type": "boolean", "default": true, - "description": nls.localizeByDefault('Enables the Code Action lightbulb in the editor.'), - "scope": "language-overridable", + "description": nls.localizeByDefault("Enables the Code Action lightbulb in the editor."), "restricted": false }, "editor.lineHeight": { "markdownDescription": nls.localizeByDefault("Controls the line height. \n - Use 0 to automatically compute the line height from the font size.\n - Values between 0 and 8 will be used as a multiplier with the font size.\n - Values greater than or equal to 8 will be used as effective values."), "type": "number", "default": 0, - "scope": "language-overridable", "restricted": false }, "editor.lineNumbers": { @@ -1115,21 +1239,18 @@ export const editorGeneratedPreferenceProperties: PreferenceSchema['properties'] ], "default": "on", "description": nls.localizeByDefault("Controls the display of line numbers."), - "scope": "language-overridable", "restricted": false }, "editor.linkedEditing": { - "description": nls.localizeByDefault('Controls whether the editor has linked editing enabled. Depending on the language, related symbols such as HTML tags, are updated while editing.'), + "description": nls.localizeByDefault("Controls whether the editor has linked editing enabled. Depending on the language, related symbols such as HTML tags, are updated while editing."), "type": "boolean", "default": false, - "scope": "language-overridable", "restricted": false }, "editor.links": { "description": nls.localizeByDefault("Controls whether the editor should detect links and make them clickable."), "type": "boolean", "default": true, - "scope": "language-overridable", "restricted": false }, "editor.matchBrackets": { @@ -1141,21 +1262,18 @@ export const editorGeneratedPreferenceProperties: PreferenceSchema['properties'] "never" ], "default": "always", - "scope": "language-overridable", "restricted": false }, "editor.minimap.enabled": { "type": "boolean", "default": true, "description": nls.localizeByDefault("Controls whether the minimap is shown."), - "scope": "language-overridable", "restricted": false }, "editor.minimap.autohide": { "type": "boolean", "default": false, "description": nls.localizeByDefault("Controls whether the minimap is hidden automatically."), - "scope": "language-overridable", "restricted": false }, "editor.minimap.size": { @@ -1172,7 +1290,6 @@ export const editorGeneratedPreferenceProperties: PreferenceSchema['properties'] ], "default": "proportional", "description": nls.localizeByDefault("Controls the size of the minimap."), - "scope": "language-overridable", "restricted": false }, "editor.minimap.side": { @@ -1183,7 +1300,6 @@ export const editorGeneratedPreferenceProperties: PreferenceSchema['properties'] ], "default": "right", "description": nls.localizeByDefault("Controls the side where to render the minimap."), - "scope": "language-overridable", "restricted": false }, "editor.minimap.showSlider": { @@ -1194,7 +1310,6 @@ export const editorGeneratedPreferenceProperties: PreferenceSchema['properties'] ], "default": "mouseover", "description": nls.localizeByDefault("Controls when the minimap slider is shown."), - "scope": "language-overridable", "restricted": false }, "editor.minimap.scale": { @@ -1208,42 +1323,36 @@ export const editorGeneratedPreferenceProperties: PreferenceSchema['properties'] 3 ], "description": nls.localizeByDefault("Scale of content drawn in the minimap: 1, 2 or 3."), - "scope": "language-overridable", "restricted": false }, "editor.minimap.renderCharacters": { "type": "boolean", "default": true, "description": nls.localizeByDefault("Render the actual characters on a line as opposed to color blocks."), - "scope": "language-overridable", "restricted": false }, "editor.minimap.maxColumn": { "type": "number", "default": 120, "description": nls.localizeByDefault("Limit the width of the minimap to render at most a certain number of columns."), - "scope": "language-overridable", "restricted": false }, "editor.mouseWheelScrollSensitivity": { "markdownDescription": nls.localizeByDefault("A multiplier to be used on the `deltaX` and `deltaY` of mouse wheel scroll events."), "type": "number", "default": 1, - "scope": "language-overridable", "restricted": false }, "editor.mouseWheelZoom": { "markdownDescription": nls.localizeByDefault("Zoom the font of the editor when using mouse wheel and holding `Ctrl`."), "type": "boolean", "default": false, - "scope": "language-overridable", "restricted": false }, "editor.multiCursorMergeOverlapping": { "description": nls.localizeByDefault("Merge multiple cursors when they are overlapping."), "type": "boolean", "default": true, - "scope": "language-overridable", "restricted": false }, "editor.multiCursorModifier": { @@ -1258,7 +1367,6 @@ export const editorGeneratedPreferenceProperties: PreferenceSchema['properties'] "alt" ], "default": "alt", - "scope": "language-overridable", "restricted": false }, "editor.multiCursorPaste": { @@ -1273,21 +1381,26 @@ export const editorGeneratedPreferenceProperties: PreferenceSchema['properties'] "full" ], "default": "spread", - "scope": "language-overridable", + "restricted": false + }, + "editor.multiCursorLimit": { + "markdownDescription": nls.localizeByDefault("Controls the max number of cursors that can be in an active editor at once."), + "type": "integer", + "default": 10000, + "minimum": 1, + "maximum": 100000, "restricted": false }, "editor.occurrencesHighlight": { "description": nls.localizeByDefault("Controls whether the editor should highlight semantic symbol occurrences."), "type": "boolean", "default": true, - "scope": "language-overridable", "restricted": false }, "editor.overviewRulerBorder": { "description": nls.localizeByDefault("Controls whether a border should be drawn around the overview ruler."), "type": "boolean", "default": true, - "scope": "language-overridable", "restricted": false }, "editor.padding.top": { @@ -1296,7 +1409,6 @@ export const editorGeneratedPreferenceProperties: PreferenceSchema['properties'] "minimum": 0, "maximum": 1000, "description": nls.localizeByDefault("Controls the amount of space between the top edge of the editor and the first line."), - "scope": "language-overridable", "restricted": false }, "editor.padding.bottom": { @@ -1305,21 +1417,38 @@ export const editorGeneratedPreferenceProperties: PreferenceSchema['properties'] "minimum": 0, "maximum": 1000, "description": nls.localizeByDefault("Controls the amount of space between the bottom edge of the editor and the last line."), - "scope": "language-overridable", + "restricted": false + }, + "editor.pasteAs.enabled": { + "type": "boolean", + "default": true, + "markdownDescription": nls.localizeByDefault("Controls whether you can paste content in different ways."), + "restricted": false + }, + "editor.pasteAs.showPasteSelector": { + "type": "string", + "markdownDescription": nls.localizeByDefault("Controls if a widget is shown when pasting content in to the editor. This widget lets you control how the file is pasted."), + "enum": [ + "afterPaste", + "never" + ], + "enumDescriptions": [ + nls.localizeByDefault("Show the paste selector widget after content is pasted into the editor."), + nls.localizeByDefault("Never show the paste selector widget. Instead the default pasting behavior is always used.") + ], + "default": "afterPaste", "restricted": false }, "editor.parameterHints.enabled": { "type": "boolean", "default": true, "description": nls.localizeByDefault("Enables a pop-up that shows parameter documentation and type information as you type."), - "scope": "language-overridable", "restricted": false }, "editor.parameterHints.cycle": { "type": "boolean", - "default": false, + "default": true, "description": nls.localizeByDefault("Controls whether the parameter hints menu cycles or closes when reaching the end of the list."), - "scope": "language-overridable", "restricted": false }, "editor.peekWidgetDefaultFocus": { @@ -1334,14 +1463,12 @@ export const editorGeneratedPreferenceProperties: PreferenceSchema['properties'] "editor" ], "default": "tree", - "scope": "language-overridable", "restricted": false }, "editor.definitionLinkOpensInPeek": { "description": nls.localizeByDefault("Controls whether the Go to Definition mouse gesture always opens the peek widget."), "type": "boolean", "default": false, - "scope": "language-overridable", "restricted": false }, "editor.quickSuggestions": { @@ -1421,7 +1548,6 @@ export const editorGeneratedPreferenceProperties: PreferenceSchema['properties'] "strings": "off" }, "markdownDescription": nls.localize("theia/editor/editor.quickSuggestions", "Controls whether suggestions should automatically show up while typing. This can be controlled for typing in comments, strings, and other code. Quick suggestion can be configured to show as ghost text or with the suggest widget. Also be aware of the '#editor.suggestOnTriggerCharacters#'-setting which controls if suggestions are triggered by special characters."), - "scope": "language-overridable", "restricted": false }, "editor.quickSuggestionsDelay": { @@ -1430,7 +1556,6 @@ export const editorGeneratedPreferenceProperties: PreferenceSchema['properties'] "default": 10, "minimum": 0, "maximum": 1073741824, - "scope": "language-overridable", "restricted": false }, "editor.renameOnType": { @@ -1438,7 +1563,6 @@ export const editorGeneratedPreferenceProperties: PreferenceSchema['properties'] "markdownDeprecationMessage": "Deprecated, use `editor.linkedEditing` instead.", "type": "boolean", "default": false, - "scope": "language-overridable", "restricted": false, "deprecationMessage": "Deprecated, use `editor.linkedEditing` instead." }, @@ -1446,14 +1570,17 @@ export const editorGeneratedPreferenceProperties: PreferenceSchema['properties'] "description": nls.localizeByDefault("Controls whether the editor should render control characters."), "restricted": true, "type": "boolean", - "default": true, - "scope": "language-overridable" + "default": true }, "editor.renderFinalNewline": { "description": nls.localizeByDefault("Render last line number when the file ends with a newline."), - "type": "boolean", - "default": true, - "scope": "language-overridable", + "type": "string", + "enum": [ + "off", + "on", + "dimmed" + ], + "default": "on", "restricted": false }, "editor.renderLineHighlight": { @@ -1472,14 +1599,12 @@ export const editorGeneratedPreferenceProperties: PreferenceSchema['properties'] "all" ], "default": "line", - "scope": "language-overridable", "restricted": false }, "editor.renderLineHighlightOnlyWhenFocus": { "description": nls.localizeByDefault("Controls if the editor should render the current line highlight only when the editor is focused."), "type": "boolean", "default": false, - "scope": "language-overridable", "restricted": false }, "editor.renderWhitespace": { @@ -1500,14 +1625,12 @@ export const editorGeneratedPreferenceProperties: PreferenceSchema['properties'] "all" ], "default": "selection", - "scope": "language-overridable", "restricted": false }, "editor.roundedSelection": { "description": nls.localizeByDefault("Controls whether selections should have rounded corners."), "type": "boolean", "default": true, - "scope": "language-overridable", "restricted": false }, "editor.rulers": { @@ -1538,7 +1661,6 @@ export const editorGeneratedPreferenceProperties: PreferenceSchema['properties'] }, "default": [], "description": nls.localizeByDefault("Render vertical rulers after a certain number of monospace characters. Use multiple values for multiple rulers. No rulers are drawn if array is empty."), - "scope": "language-overridable", "restricted": false }, "editor.scrollbar.vertical": { @@ -1555,7 +1677,6 @@ export const editorGeneratedPreferenceProperties: PreferenceSchema['properties'] ], "default": "auto", "description": nls.localizeByDefault("Controls the visibility of the vertical scrollbar."), - "scope": "language-overridable", "restricted": false }, "editor.scrollbar.horizontal": { @@ -1572,28 +1693,24 @@ export const editorGeneratedPreferenceProperties: PreferenceSchema['properties'] ], "default": "auto", "description": nls.localizeByDefault("Controls the visibility of the horizontal scrollbar."), - "scope": "language-overridable", "restricted": false }, "editor.scrollbar.verticalScrollbarSize": { "type": "number", "default": 14, "description": nls.localizeByDefault("The width of the vertical scrollbar."), - "scope": "language-overridable", "restricted": false }, "editor.scrollbar.horizontalScrollbarSize": { "type": "number", "default": 12, "description": nls.localizeByDefault("The height of the horizontal scrollbar."), - "scope": "language-overridable", "restricted": false }, "editor.scrollbar.scrollByPage": { "type": "boolean", "default": false, "description": nls.localizeByDefault("Controls whether clicks scroll by page or jump to click position."), - "scope": "language-overridable", "restricted": false }, "editor.scrollBeyondLastColumn": { @@ -1602,34 +1719,24 @@ export const editorGeneratedPreferenceProperties: PreferenceSchema['properties'] "default": 4, "minimum": 0, "maximum": 1073741824, - "scope": "language-overridable", "restricted": false }, "editor.scrollBeyondLastLine": { "description": nls.localizeByDefault("Controls whether the editor will scroll beyond the last line."), "type": "boolean", "default": true, - "scope": "language-overridable", "restricted": false }, "editor.scrollPredominantAxis": { "description": nls.localizeByDefault("Scroll only along the predominant axis when scrolling both vertically and horizontally at the same time. Prevents horizontal drift when scrolling vertically on a trackpad."), "type": "boolean", "default": true, - "scope": "language-overridable", "restricted": false }, - "editor.selectionClipboard": { - "type": "boolean", - "default": true, - "description": nls.localizeByDefault("Controls whether the Linux primary clipboard should be supported."), - "included": !isOSX && !isWindows - }, "editor.selectionHighlight": { "description": nls.localizeByDefault("Controls whether the editor should highlight matches similar to the selection."), "type": "boolean", "default": true, - "scope": "language-overridable", "restricted": false }, "editor.showFoldingControls": { @@ -1646,14 +1753,12 @@ export const editorGeneratedPreferenceProperties: PreferenceSchema['properties'] "mouseover" ], "default": "mouseover", - "scope": "language-overridable", "restricted": false }, "editor.showUnused": { "description": nls.localizeByDefault("Controls fading out of unused code."), "type": "boolean", "default": true, - "scope": "language-overridable", "restricted": false }, "editor.snippetSuggestions": { @@ -1672,28 +1777,30 @@ export const editorGeneratedPreferenceProperties: PreferenceSchema['properties'] "none" ], "default": "inline", - "scope": "language-overridable", "restricted": false }, "editor.smartSelect.selectLeadingAndTrailingWhitespace": { "description": nls.localizeByDefault("Whether leading and trailing whitespace should always be selected."), "default": true, "type": "boolean", - "scope": "language-overridable", + "restricted": false + }, + "editor.smartSelect.selectSubwords": { + "description": nls.localizeByDefault("Whether subwords (like 'foo' in 'fooBar' or 'foo_bar') should be selected."), + "default": true, + "type": "boolean", "restricted": false }, "editor.smoothScrolling": { "description": nls.localizeByDefault("Controls whether the editor will scroll using an animation."), "type": "boolean", "default": false, - "scope": "language-overridable", "restricted": false }, "editor.stickyScroll.enabled": { "type": "boolean", "default": false, "description": nls.localizeByDefault("Shows the nested current scopes during the scroll at the top of the editor."), - "scope": "language-overridable", "restricted": false }, "editor.stickyScroll.maxLineCount": { @@ -1702,14 +1809,29 @@ export const editorGeneratedPreferenceProperties: PreferenceSchema['properties'] "minimum": 1, "maximum": 10, "description": nls.localizeByDefault("Defines the maximum number of sticky lines to show."), - "scope": "language-overridable", + "restricted": false + }, + "editor.stickyScroll.defaultModel": { + "type": "string", + "enum": [ + "outlineModel", + "foldingProviderModel", + "indentationModel" + ], + "default": "outlineModel", + "description": nls.localizeByDefault("Defines the model to use for determining which lines to stick. If the outline model does not exist, it will fall back on the folding provider model which falls back on the indentation model. This order is respected in all three cases."), + "restricted": false + }, + "editor.stickyScroll.scrollWithEditor": { + "type": "boolean", + "default": true, + "description": nls.localize("theia/editor/editor.stickyScroll.scrollWithEditor", "Enable scrolling of the sticky scroll widget with the editor's horizontal scrollbar."), "restricted": false }, "editor.stickyTabStops": { "description": nls.localizeByDefault("Emulate selection behavior of tab characters when using spaces for indentation. Selection will stick to tab stops."), "type": "boolean", "default": false, - "scope": "language-overridable", "restricted": false }, "editor.suggest.insertMode": { @@ -1724,312 +1846,286 @@ export const editorGeneratedPreferenceProperties: PreferenceSchema['properties'] ], "default": "insert", "description": nls.localizeByDefault("Controls whether words are overwritten when accepting completions. Note that this depends on extensions opting into this feature."), - "scope": "language-overridable", "restricted": false }, "editor.suggest.filterGraceful": { "type": "boolean", "default": true, "description": nls.localizeByDefault("Controls whether filtering and sorting suggestions accounts for small typos."), - "scope": "language-overridable", "restricted": false }, "editor.suggest.localityBonus": { "type": "boolean", "default": false, "description": nls.localizeByDefault("Controls whether sorting favors words that appear close to the cursor."), - "scope": "language-overridable", "restricted": false }, "editor.suggest.shareSuggestSelections": { "type": "boolean", "default": false, "markdownDescription": nls.localizeByDefault("Controls whether remembered suggestion selections are shared between multiple workspaces and windows (needs `#editor.suggestSelection#`)."), - "scope": "language-overridable", + "restricted": false + }, + "editor.suggest.selectionMode": { + "type": "string", + "enum": [ + "always", + "never", + "whenTriggerCharacter", + "whenQuickSuggestion" + ], + "enumDescriptions": [ + nls.localizeByDefault("Always select a suggestion when automatically triggering IntelliSense."), + nls.localizeByDefault("Never select a suggestion when automatically triggering IntelliSense."), + nls.localizeByDefault("Select a suggestion only when triggering IntelliSense from a trigger character."), + nls.localizeByDefault("Select a suggestion only when triggering IntelliSense as you type.") + ], + "default": "always", + "markdownDescription": nls.localizeByDefault("Controls whether a suggestion is selected when the widget shows. Note that this only applies to automatically triggered suggestions (`#editor.quickSuggestions#` and `#editor.suggestOnTriggerCharacters#`) and that a suggestion is always selected when explicitly invoked, e.g via `Ctrl+Space`."), "restricted": false }, "editor.suggest.snippetsPreventQuickSuggestions": { "type": "boolean", - "default": true, + "default": false, "description": nls.localizeByDefault("Controls whether an active snippet prevents quick suggestions."), - "scope": "language-overridable", "restricted": false }, "editor.suggest.showIcons": { "type": "boolean", "default": true, "description": nls.localizeByDefault("Controls whether to show or hide icons in suggestions."), - "scope": "language-overridable", "restricted": false }, "editor.suggest.showStatusBar": { "type": "boolean", "default": false, "description": nls.localizeByDefault("Controls the visibility of the status bar at the bottom of the suggest widget."), - "scope": "language-overridable", "restricted": false }, "editor.suggest.preview": { "type": "boolean", "default": false, "description": nls.localizeByDefault("Controls whether to preview the suggestion outcome in the editor."), - "scope": "language-overridable", "restricted": false }, "editor.suggest.showInlineDetails": { "type": "boolean", "default": true, - "description": nls.localizeByDefault('Controls whether suggest details show inline with the label or only in the details widget.'), - "scope": "language-overridable", + "description": nls.localizeByDefault("Controls whether suggest details show inline with the label or only in the details widget."), "restricted": false }, "editor.suggest.maxVisibleSuggestions": { "type": "number", "deprecationMessage": "This setting is deprecated. The suggest widget can now be resized.", "default": 0, - "scope": "language-overridable", "restricted": false }, "editor.suggest.filteredTypes": { "type": "object", "deprecationMessage": "This setting is deprecated, please use separate settings like 'editor.suggest.showKeywords' or 'editor.suggest.showSnippets' instead.", "default": {}, - "scope": "language-overridable", "restricted": false }, "editor.suggest.showMethods": { "type": "boolean", "default": true, "markdownDescription": nls.localizeByDefault("When enabled IntelliSense shows `method`-suggestions."), - "scope": "language-overridable", "restricted": false }, "editor.suggest.showFunctions": { "type": "boolean", "default": true, "markdownDescription": nls.localizeByDefault("When enabled IntelliSense shows `function`-suggestions."), - "scope": "language-overridable", "restricted": false }, "editor.suggest.showConstructors": { "type": "boolean", "default": true, "markdownDescription": nls.localizeByDefault("When enabled IntelliSense shows `constructor`-suggestions."), - "scope": "language-overridable", "restricted": false }, "editor.suggest.showDeprecated": { "type": "boolean", "default": true, "markdownDescription": nls.localizeByDefault("When enabled IntelliSense shows `deprecated`-suggestions."), - "scope": "language-overridable", "restricted": false }, "editor.suggest.matchOnWordStartOnly": { "type": "boolean", "default": true, - "markdownDescription": nls.localize("theia/editor/editor.suggest.matchOnWordStartOnly", "When enabled IntelliSense filtering requires that the first character matches on a word start, e.g `c` on `Console` or `WebContext` but _not_ on `description`. When disabled IntelliSense will show more results but still sorts them by match quality."), - "scope": "language-overridable", + "markdownDescription": nls.localizeByDefault("When enabled IntelliSense filtering requires that the first character matches on a word start. For example, `c` on `Console` or `WebContext` but _not_ on `description`. When disabled IntelliSense will show more results but still sorts them by match quality."), "restricted": false }, "editor.suggest.showFields": { "type": "boolean", "default": true, "markdownDescription": nls.localizeByDefault("When enabled IntelliSense shows `field`-suggestions."), - "scope": "language-overridable", "restricted": false }, "editor.suggest.showVariables": { "type": "boolean", "default": true, "markdownDescription": nls.localizeByDefault("When enabled IntelliSense shows `variable`-suggestions."), - "scope": "language-overridable", "restricted": false }, "editor.suggest.showClasses": { "type": "boolean", "default": true, "markdownDescription": nls.localizeByDefault("When enabled IntelliSense shows `class`-suggestions."), - "scope": "language-overridable", "restricted": false }, "editor.suggest.showStructs": { "type": "boolean", "default": true, "markdownDescription": nls.localizeByDefault("When enabled IntelliSense shows `struct`-suggestions."), - "scope": "language-overridable", "restricted": false }, "editor.suggest.showInterfaces": { "type": "boolean", "default": true, "markdownDescription": nls.localizeByDefault("When enabled IntelliSense shows `interface`-suggestions."), - "scope": "language-overridable", "restricted": false }, "editor.suggest.showModules": { "type": "boolean", "default": true, "markdownDescription": nls.localizeByDefault("When enabled IntelliSense shows `module`-suggestions."), - "scope": "language-overridable", "restricted": false }, "editor.suggest.showProperties": { "type": "boolean", "default": true, "markdownDescription": nls.localizeByDefault("When enabled IntelliSense shows `property`-suggestions."), - "scope": "language-overridable", "restricted": false }, "editor.suggest.showEvents": { "type": "boolean", "default": true, "markdownDescription": nls.localizeByDefault("When enabled IntelliSense shows `event`-suggestions."), - "scope": "language-overridable", "restricted": false }, "editor.suggest.showOperators": { "type": "boolean", "default": true, "markdownDescription": nls.localizeByDefault("When enabled IntelliSense shows `operator`-suggestions."), - "scope": "language-overridable", "restricted": false }, "editor.suggest.showUnits": { "type": "boolean", "default": true, "markdownDescription": nls.localizeByDefault("When enabled IntelliSense shows `unit`-suggestions."), - "scope": "language-overridable", "restricted": false }, "editor.suggest.showValues": { "type": "boolean", "default": true, "markdownDescription": nls.localizeByDefault("When enabled IntelliSense shows `value`-suggestions."), - "scope": "language-overridable", "restricted": false }, "editor.suggest.showConstants": { "type": "boolean", "default": true, "markdownDescription": nls.localizeByDefault("When enabled IntelliSense shows `constant`-suggestions."), - "scope": "language-overridable", "restricted": false }, "editor.suggest.showEnums": { "type": "boolean", "default": true, "markdownDescription": nls.localizeByDefault("When enabled IntelliSense shows `enum`-suggestions."), - "scope": "language-overridable", "restricted": false }, "editor.suggest.showEnumMembers": { "type": "boolean", "default": true, "markdownDescription": nls.localizeByDefault("When enabled IntelliSense shows `enumMember`-suggestions."), - "scope": "language-overridable", "restricted": false }, "editor.suggest.showKeywords": { "type": "boolean", "default": true, "markdownDescription": nls.localizeByDefault("When enabled IntelliSense shows `keyword`-suggestions."), - "scope": "language-overridable", "restricted": false }, "editor.suggest.showWords": { "type": "boolean", "default": true, "markdownDescription": nls.localizeByDefault("When enabled IntelliSense shows `text`-suggestions."), - "scope": "language-overridable", "restricted": false }, "editor.suggest.showColors": { "type": "boolean", "default": true, "markdownDescription": nls.localizeByDefault("When enabled IntelliSense shows `color`-suggestions."), - "scope": "language-overridable", "restricted": false }, "editor.suggest.showFiles": { "type": "boolean", "default": true, "markdownDescription": nls.localizeByDefault("When enabled IntelliSense shows `file`-suggestions."), - "scope": "language-overridable", "restricted": false }, "editor.suggest.showReferences": { "type": "boolean", "default": true, "markdownDescription": nls.localizeByDefault("When enabled IntelliSense shows `reference`-suggestions."), - "scope": "language-overridable", "restricted": false }, "editor.suggest.showCustomcolors": { "type": "boolean", "default": true, "markdownDescription": nls.localizeByDefault("When enabled IntelliSense shows `customcolor`-suggestions."), - "scope": "language-overridable", "restricted": false }, "editor.suggest.showFolders": { "type": "boolean", "default": true, "markdownDescription": nls.localizeByDefault("When enabled IntelliSense shows `folder`-suggestions."), - "scope": "language-overridable", "restricted": false }, "editor.suggest.showTypeParameters": { "type": "boolean", "default": true, "markdownDescription": nls.localizeByDefault("When enabled IntelliSense shows `typeParameter`-suggestions."), - "scope": "language-overridable", "restricted": false }, "editor.suggest.showSnippets": { "type": "boolean", "default": true, "markdownDescription": nls.localizeByDefault("When enabled IntelliSense shows `snippet`-suggestions."), - "scope": "language-overridable", "restricted": false }, "editor.suggest.showUsers": { "type": "boolean", "default": true, "markdownDescription": nls.localizeByDefault("When enabled IntelliSense shows `user`-suggestions."), - "scope": "language-overridable", "restricted": false }, "editor.suggest.showIssues": { "type": "boolean", "default": true, "markdownDescription": nls.localizeByDefault("When enabled IntelliSense shows `issues`-suggestions."), - "scope": "language-overridable", "restricted": false }, "editor.suggestFontSize": { - "markdownDescription": nls.localizeByDefault('Font size for the suggest widget. When set to {0}, the value of {1} is used.', '`0`', '`#editor.fontSize#`'), + "markdownDescription": nls.localize("theia/editor/editor.suggestFontSize", "Font size for the suggest widget. When set to `0`, the value of `#editor.fontSize#` is used."), "type": "integer", "default": 0, "minimum": 0, "maximum": 1000, - "scope": "language-overridable", "restricted": false }, "editor.suggestLineHeight": { - "markdownDescription": nls.localizeByDefault('Line height for the suggest widget. When set to {0}, the value of {1} is used. The minimum value is 8.', '`0`', '`#editor.lineHeight#`'), + "markdownDescription": nls.localize("theia/editor/editor.suggestLineHeight", "Line height for the suggest widget. When set to `0`, the value of `#editor.lineHeight#` is used. The minimum value is 8."), "type": "integer", "default": 0, "minimum": 0, "maximum": 1000, - "scope": "language-overridable", "restricted": false }, "editor.suggestOnTriggerCharacters": { "description": nls.localizeByDefault("Controls whether suggestions should automatically show up when typing trigger characters."), "type": "boolean", "default": true, - "scope": "language-overridable", "restricted": false }, "editor.suggestSelection": { @@ -2046,7 +2142,6 @@ export const editorGeneratedPreferenceProperties: PreferenceSchema['properties'] "recentlyUsedByPrefix" ], "default": "first", - "scope": "language-overridable", "restricted": false }, "editor.tabCompletion": { @@ -2063,7 +2158,6 @@ export const editorGeneratedPreferenceProperties: PreferenceSchema['properties'] "onlySnippets" ], "default": "off", - "scope": "language-overridable", "restricted": false }, "editor.unicodeHighlight.nonBasicASCII": { @@ -2078,22 +2172,19 @@ export const editorGeneratedPreferenceProperties: PreferenceSchema['properties'] "inUntrustedWorkspace" ], "default": "inUntrustedWorkspace", - "description": nls.localizeByDefault("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."), - "scope": "language-overridable" + "description": nls.localizeByDefault("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.") }, "editor.unicodeHighlight.invisibleCharacters": { "restricted": true, "type": "boolean", "default": true, - "description": nls.localizeByDefault("Controls whether characters that just reserve space or have no width at all are highlighted."), - "scope": "language-overridable" + "description": nls.localizeByDefault("Controls whether characters that just reserve space or have no width at all are highlighted.") }, "editor.unicodeHighlight.ambiguousCharacters": { "restricted": true, "type": "boolean", "default": true, - "description": nls.localizeByDefault("Controls whether characters are highlighted that can be confused with basic ASCII characters, except those that are common in the current user locale."), - "scope": "language-overridable" + "description": nls.localizeByDefault("Controls whether characters are highlighted that can be confused with basic ASCII characters, except those that are common in the current user locale.") }, "editor.unicodeHighlight.includeComments": { "restricted": true, @@ -2107,8 +2198,7 @@ export const editorGeneratedPreferenceProperties: PreferenceSchema['properties'] "inUntrustedWorkspace" ], "default": "inUntrustedWorkspace", - "description": nls.localizeByDefault('Controls whether characters in comments should also be subject to Unicode highlighting.'), - "scope": "language-overridable" + "description": nls.localizeByDefault("Controls whether characters in comments should also be subject to Unicode highlighting.") }, "editor.unicodeHighlight.includeStrings": { "restricted": true, @@ -2122,8 +2212,7 @@ export const editorGeneratedPreferenceProperties: PreferenceSchema['properties'] "inUntrustedWorkspace" ], "default": true, - "description": nls.localizeByDefault('Controls whether characters in strings should also be subject to Unicode highlighting.'), - "scope": "language-overridable" + "description": nls.localizeByDefault("Controls whether characters in strings should also be subject to Unicode highlighting.") }, "editor.unicodeHighlight.allowedCharacters": { "restricted": true, @@ -2132,8 +2221,7 @@ export const editorGeneratedPreferenceProperties: PreferenceSchema['properties'] "description": nls.localizeByDefault("Defines allowed characters that are not being highlighted."), "additionalProperties": { "type": "boolean" - }, - "scope": "language-overridable" + } }, "editor.unicodeHighlight.allowedLocales": { "restricted": true, @@ -2145,8 +2233,7 @@ export const editorGeneratedPreferenceProperties: PreferenceSchema['properties'] "_os": true, "_vscode": true }, - "description": nls.localizeByDefault("Unicode characters that are common in allowed locales are not being highlighted."), - "scope": "language-overridable" + "description": nls.localizeByDefault("Unicode characters that are common in allowed locales are not being highlighted.") }, "editor.unusualLineTerminators": { "enumDescriptions": [ @@ -2162,21 +2249,32 @@ export const editorGeneratedPreferenceProperties: PreferenceSchema['properties'] "prompt" ], "default": "prompt", - "scope": "language-overridable", "restricted": false }, "editor.useTabStops": { "description": nls.localizeByDefault("Inserting and deleting whitespace follows tab stops."), "type": "boolean", "default": true, - "scope": "language-overridable", + "restricted": false + }, + "editor.wordBreak": { + "markdownEnumDescriptions": [ + nls.localizeByDefault("Use the default line break rule."), + nls.localizeByDefault("Word breaks should not be used for Chinese/Japanese/Korean (CJK) text. Non-CJK text behavior is the same as for normal.") + ], + "description": nls.localizeByDefault("Controls the word break rules used for Chinese/Japanese/Korean (CJK) text."), + "type": "string", + "enum": [ + "normal", + "keepAll" + ], + "default": "normal", "restricted": false }, "editor.wordSeparators": { "description": nls.localizeByDefault("Characters that will be used as word separators when doing word related navigations or operations."), "type": "string", "default": "`~!@#$%^&*()-=+[{]}\\|;:'\",.<>/?", - "scope": "language-overridable", "restricted": false }, "editor.wordWrap": { @@ -2195,7 +2293,6 @@ export const editorGeneratedPreferenceProperties: PreferenceSchema['properties'] "bounded" ], "default": "off", - "scope": "language-overridable", "restricted": false }, "editor.wordWrapColumn": { @@ -2204,17 +2301,9 @@ export const editorGeneratedPreferenceProperties: PreferenceSchema['properties'] "default": 80, "minimum": 1, "maximum": 1073741824, - "scope": "language-overridable", "restricted": false }, "editor.wrappingIndent": { - "enumDescriptions": [ - nls.localizeByDefault("No indentation. Wrapped lines begin at column 1."), - nls.localizeByDefault("Wrapped lines get the same indentation as the parent."), - nls.localizeByDefault("Wrapped lines get +1 indentation toward the parent."), - nls.localizeByDefault("Wrapped lines get +2 indentation toward the parent.") - ], - "description": nls.localizeByDefault("Controls the indentation of wrapped lines."), "type": "string", "enum": [ "none", @@ -2222,8 +2311,14 @@ export const editorGeneratedPreferenceProperties: PreferenceSchema['properties'] "indent", "deepIndent" ], + "enumDescriptions": [ + nls.localizeByDefault("No indentation. Wrapped lines begin at column 1."), + nls.localizeByDefault("Wrapped lines get the same indentation as the parent."), + nls.localizeByDefault("Wrapped lines get +1 indentation toward the parent."), + nls.localizeByDefault("Wrapped lines get +2 indentation toward the parent.") + ], + "description": nls.localizeByDefault("Controls the indentation of wrapped lines."), "default": "same", - "scope": "language-overridable", "restricted": false }, "editor.wrappingStrategy": { @@ -2231,21 +2326,19 @@ export const editorGeneratedPreferenceProperties: PreferenceSchema['properties'] nls.localizeByDefault("Assumes that all characters are of the same width. This is a fast algorithm that works correctly for monospace fonts and certain scripts (like Latin characters) where glyphs are of equal width."), nls.localizeByDefault("Delegates wrapping points computation to the browser. This is a slow algorithm, that might cause freezes for large files, but it works correctly in all cases.") ], - "description": nls.localizeByDefault('Controls the algorithm that computes wrapping points. Note that when in accessibility mode, advanced will be used for the best experience.'), "type": "string", "enum": [ "simple", "advanced" ], "default": "simple", - "scope": "language-overridable", + "description": nls.localizeByDefault("Controls the algorithm that computes wrapping points. Note that when in accessibility mode, advanced will be used for the best experience."), "restricted": false }, "editor.showDeprecated": { "description": nls.localizeByDefault("Controls strikethrough deprecated variables."), "type": "boolean", "default": true, - "scope": "language-overridable", "restricted": false }, "editor.inlayHints.enabled": { @@ -2264,49 +2357,85 @@ export const editorGeneratedPreferenceProperties: PreferenceSchema['properties'] nls.localize("theia/editor/editor.inlayHints.enabled2", "Inlay hints are hidden by default and show when holding Ctrl+Alt"), nls.localizeByDefault("Inlay hints are disabled") ], - "scope": "language-overridable", "restricted": false }, "editor.inlayHints.fontSize": { "type": "number", "default": 0, - "markdownDescription": nls.localizeByDefault('Controls font size of inlay hints in the editor. As default the {0} is used when the configured value is less than {1} or greater than the editor font size.', '`#editor.fontSize#`'), - "scope": "language-overridable", + "markdownDescription": nls.localize("theia/editor/editor.inlayHints.fontSize", "Controls font size of inlay hints in the editor. As default the `#editor.fontSize#` is used when the configured value is less than `5` or greater than the editor font size."), "restricted": false }, "editor.inlayHints.fontFamily": { "type": "string", "default": "", - "markdownDescription": nls.localizeByDefault('Controls font family of inlay hints in the editor. When set to empty, the {0} is used.', '`#editor.fontFamily#`'), - "scope": "language-overridable", + "markdownDescription": nls.localize("theia/editor/editor.inlayHints.fontFamily", "Controls font family of inlay hints in the editor. When set to empty, the `#editor.fontFamily#` is used."), "restricted": false }, "editor.inlayHints.padding": { "type": "boolean", "default": false, "description": nls.localizeByDefault("Enables the padding around the inlay hints in the editor."), - "scope": "language-overridable", + "restricted": false + }, + "editor.tabFocusMode": { + "markdownDescription": nls.localizeByDefault("Controls whether the editor receives tabs or defers them to the workbench for navigation."), + "type": "boolean", + "default": false, + "restricted": false + }, + "editor.defaultColorDecorators": { + "markdownDescription": nls.localizeByDefault("Controls whether inline color decorations should be shown using the default document color provider"), + "type": "boolean", + "default": false, + "restricted": false + }, + "editor.colorDecoratorsActivatedOn": { + "enumDescriptions": [ + nls.localizeByDefault("Make the color picker appear both on click and hover of the color decorator"), + nls.localizeByDefault("Make the color picker appear on hover of the color decorator"), + nls.localizeByDefault("Make the color picker appear on click of the color decorator") + ], + "description": nls.localizeByDefault("Controls the condition to make a color picker appear from a color decorator"), + "type": "string", + "enum": [ + "clickAndHover", + "hover", + "click" + ], + "default": "clickAndHover", + "restricted": false + }, + "editor.inlineCompletionsAccessibilityVerbose": { + "description": nls.localizeByDefault("Controls whether the accessibility hint should be provided to screen reader users when an inline completion is shown."), + "type": "boolean", + "default": false, "restricted": false }, "editor.codeActionWidget.showHeaders": { "type": "boolean", - "description": nls.localize("theia/editor/editor.codeActionWidget.showHeaders", "Enable/disable showing group headers in the code action menu."), + "description": nls.localizeByDefault("Enable/disable showing group headers in the Code Action menu."), "default": true, - "scope": "language-overridable", "restricted": false }, - "editor.experimental.pasteActions.enabled": { + "editor.codeActionWidget.includeNearbyQuickfixes": { "type": "boolean", - "description": nls.localize('theia/editor/editor.experimental.pasteActions.enabled', "Enable/disable running edits from extensions on paste."), + "description": nls.localize("theia/editor/editor.codeActionWidget.includeNearbyQuickfixes", "Enable/disable showing nearest quickfix within a line when not currently on a diagnostic."), "default": false, - "scope": "language-overridable", + "restricted": false + }, + "editor.experimental.dropIntoEditor.defaultProvider": { + "type": "object", + "description": nls.localizeByDefault("Configures the default drop provider to use for content of a given mime type."), + "default": {}, + "additionalProperties": { + "type": "string" + }, "restricted": false }, "editor.rename.enablePreview": { "description": nls.localizeByDefault("Enable/disable the ability to preview changes before renaming"), "default": true, "type": "boolean", - "scope": "language-overridable", "restricted": false }, "editor.find.globalFindClipboard": { @@ -2314,6 +2443,12 @@ export const editorGeneratedPreferenceProperties: PreferenceSchema['properties'] "default": false, "description": nls.localizeByDefault("Controls whether the Find Widget should read or modify the shared find clipboard on macOS."), "included": isOSX + }, + "editor.selectionClipboard": { + "type": "boolean", + "default": true, + "description": nls.localizeByDefault("Controls whether the Linux primary clipboard should be supported."), + "included": !isOSX && !isWindows } }; @@ -2321,6 +2456,7 @@ type QuickSuggestionValues = boolean | 'on' | 'inline' | 'off'; export interface GeneratedEditorPreferences { 'editor.tabSize': number; + 'editor.indentSize': 'tabSize' | number; 'editor.insertSpaces': boolean; 'editor.detectIndentation': boolean; 'editor.trimAutoWhitespace': boolean; @@ -2330,22 +2466,35 @@ export interface GeneratedEditorPreferences { 'editor.semanticHighlighting.enabled': true | false | 'configuredByTheme'; 'editor.stablePeek': boolean; 'editor.maxTokenizationLineLength': number; + 'editor.experimental.asyncTokenization': boolean; + 'editor.experimental.asyncTokenizationLogging': boolean; + 'editor.experimental.asyncTokenizationVerification': boolean; 'editor.language.brackets': Array<[string, string]> | null | 'null'; 'editor.language.colorizedBracketPairs': Array<[string, string]> | null; 'diffEditor.maxComputationTime': number; 'diffEditor.maxFileSize': number; 'diffEditor.renderSideBySide': boolean; + 'diffEditor.renderSideBySideInlineBreakpoint': number; + 'diffEditor.useInlineViewWhenSpaceIsLimited': boolean; 'diffEditor.renderMarginRevertIcon': boolean; 'diffEditor.ignoreTrimWhitespace': boolean; 'diffEditor.renderIndicators': boolean; 'diffEditor.codeLens': boolean; 'diffEditor.wordWrap': 'off' | 'on' | 'inherit'; - 'diffEditor.diffAlgorithm': 'smart' | 'experimental'; + 'diffEditor.diffAlgorithm': 'legacy' | 'advanced'; + 'diffEditor.hideUnchangedRegions.enabled': boolean; + 'diffEditor.hideUnchangedRegions.revealLineCount': number; + 'diffEditor.hideUnchangedRegions.minimumLineCount': number; + 'diffEditor.hideUnchangedRegions.contextLineCount': number; + 'diffEditor.experimental.showMoves': boolean; + 'diffEditor.experimental.showEmptyDecorations': boolean; 'editor.acceptSuggestionOnCommitCharacter': boolean; 'editor.acceptSuggestionOnEnter': 'on' | 'smart' | 'off'; 'editor.accessibilitySupport': 'auto' | 'on' | 'off'; 'editor.accessibilityPageSize': number; 'editor.autoClosingBrackets': 'always' | 'languageDefined' | 'beforeWhitespace' | 'never'; + 'editor.autoClosingComments': 'always' | 'languageDefined' | 'beforeWhitespace' | 'never'; + 'editor.screenReaderAnnounceInlineSuggestion': boolean; 'editor.autoClosingDelete': 'always' | 'auto' | 'never'; 'editor.autoClosingOvertype': 'always' | 'auto' | 'never'; 'editor.autoClosingQuotes': 'always' | 'languageDefined' | 'beforeWhitespace' | 'never'; @@ -2362,19 +2511,22 @@ export interface GeneratedEditorPreferences { 'editor.codeLensFontFamily': string; 'editor.codeLensFontSize': number; 'editor.colorDecorators': boolean; + 'editor.colorDecoratorsLimit': number; 'editor.columnSelection': boolean; 'editor.comments.insertSpace': boolean; 'editor.comments.ignoreEmptyLines': boolean; 'editor.copyWithSyntaxHighlighting': boolean; 'editor.cursorBlinking': 'blink' | 'smooth' | 'phase' | 'expand' | 'solid'; - 'editor.cursorSmoothCaretAnimation': boolean; + 'editor.cursorSmoothCaretAnimation': 'off' | 'explicit' | 'on'; 'editor.cursorStyle': 'line' | 'block' | 'underline' | 'line-thin' | 'block-outline' | 'underline-thin'; 'editor.cursorSurroundingLines': number; 'editor.cursorSurroundingLinesStyle': 'default' | 'all'; 'editor.cursorWidth': number; 'editor.dragAndDrop': boolean; 'editor.dropIntoEditor.enabled': boolean; + 'editor.dropIntoEditor.showDropSelector': 'afterDrop' | 'never'; 'editor.emptySelectionClipboard': boolean; + 'editor.experimentalWhitespaceRendering': 'svg' | 'font' | 'off'; 'editor.fastScrollSensitivity': number; 'editor.find.cursorMoveOnType': boolean; 'editor.find.seedSearchStringFromSelection': 'never' | 'always' | 'selection'; @@ -2409,8 +2561,11 @@ export interface GeneratedEditorPreferences { 'editor.hover.enabled': boolean; 'editor.hover.delay': number; 'editor.hover.sticky': boolean; + 'editor.hover.hidingDelay': number; 'editor.hover.above': boolean; 'editor.inlineSuggest.enabled': boolean; + 'editor.inlineSuggest.showToolbar': 'always' | 'onHover'; + 'editor.inlineSuggest.suppressSuggestions': boolean; 'editor.letterSpacing': number; 'editor.lightbulb.enabled': boolean; 'editor.lineHeight': number; @@ -2431,10 +2586,13 @@ export interface GeneratedEditorPreferences { 'editor.multiCursorMergeOverlapping': boolean; 'editor.multiCursorModifier': 'ctrlCmd' | 'alt'; 'editor.multiCursorPaste': 'spread' | 'full'; + 'editor.multiCursorLimit': number; 'editor.occurrencesHighlight': boolean; 'editor.overviewRulerBorder': boolean; 'editor.padding.top': number; 'editor.padding.bottom': number; + 'editor.pasteAs.enabled': boolean; + 'editor.pasteAs.showPasteSelector': 'afterPaste' | 'never'; 'editor.parameterHints.enabled': boolean; 'editor.parameterHints.cycle': boolean; 'editor.peekWidgetDefaultFocus': 'tree' | 'editor'; @@ -2443,7 +2601,7 @@ export interface GeneratedEditorPreferences { 'editor.quickSuggestionsDelay': number; 'editor.renameOnType': boolean; 'editor.renderControlCharacters': boolean; - 'editor.renderFinalNewline': boolean; + 'editor.renderFinalNewline': 'off' | 'on' | 'dimmed'; 'editor.renderLineHighlight': 'none' | 'gutter' | 'line' | 'all'; 'editor.renderLineHighlightOnlyWhenFocus': boolean; 'editor.renderWhitespace': 'none' | 'boundary' | 'selection' | 'trailing' | 'all'; @@ -2457,20 +2615,23 @@ export interface GeneratedEditorPreferences { 'editor.scrollBeyondLastColumn': number; 'editor.scrollBeyondLastLine': boolean; 'editor.scrollPredominantAxis': boolean; - 'editor.selectionClipboard': boolean; 'editor.selectionHighlight': boolean; 'editor.showFoldingControls': 'always' | 'never' | 'mouseover'; 'editor.showUnused': boolean; 'editor.snippetSuggestions': 'top' | 'bottom' | 'inline' | 'none'; 'editor.smartSelect.selectLeadingAndTrailingWhitespace': boolean; + 'editor.smartSelect.selectSubwords': boolean; 'editor.smoothScrolling': boolean; 'editor.stickyScroll.enabled': boolean; 'editor.stickyScroll.maxLineCount': number; + 'editor.stickyScroll.defaultModel': 'outlineModel' | 'foldingProviderModel' | 'indentationModel'; + 'editor.stickyScroll.scrollWithEditor': boolean; 'editor.stickyTabStops': boolean; 'editor.suggest.insertMode': 'insert' | 'replace'; 'editor.suggest.filterGraceful': boolean; 'editor.suggest.localityBonus': boolean; 'editor.suggest.shareSuggestSelections': boolean; + 'editor.suggest.selectionMode': 'always' | 'never' | 'whenTriggerCharacter' | 'whenQuickSuggestion'; 'editor.suggest.snippetsPreventQuickSuggestions': boolean; 'editor.suggest.showIcons': boolean; 'editor.suggest.showStatusBar': boolean; @@ -2522,6 +2683,7 @@ export interface GeneratedEditorPreferences { 'editor.unicodeHighlight.allowedLocales': Record; 'editor.unusualLineTerminators': 'auto' | 'off' | 'prompt'; 'editor.useTabStops': boolean; + 'editor.wordBreak': 'normal' | 'keepAll'; 'editor.wordSeparators': string; 'editor.wordWrap': 'off' | 'on' | 'wordWrapColumn' | 'bounded'; 'editor.wordWrapColumn': number; @@ -2532,8 +2694,14 @@ export interface GeneratedEditorPreferences { 'editor.inlayHints.fontSize': number; 'editor.inlayHints.fontFamily': string; 'editor.inlayHints.padding': boolean; + 'editor.tabFocusMode': boolean; + 'editor.defaultColorDecorators': boolean; + 'editor.colorDecoratorsActivatedOn': 'clickAndHover' | 'hover' | 'click'; + 'editor.inlineCompletionsAccessibilityVerbose': boolean; 'editor.codeActionWidget.showHeaders': boolean; - 'editor.experimental.pasteActions.enabled': boolean; + 'editor.codeActionWidget.includeNearbyQuickfixes': boolean; + 'editor.experimental.dropIntoEditor.defaultProvider': null; 'editor.rename.enablePreview': boolean; 'editor.find.globalFindClipboard': boolean; + 'editor.selectionClipboard': boolean; } diff --git a/packages/editor/src/browser/editor-linenumber-contribution.ts b/packages/editor/src/browser/editor-linenumber-contribution.ts index 8dae394c8de72..3f42f64aeb0d0 100644 --- a/packages/editor/src/browser/editor-linenumber-contribution.ts +++ b/packages/editor/src/browser/editor-linenumber-contribution.ts @@ -69,8 +69,7 @@ export class EditorLineNumberContribution implements FrontendApplicationContribu menuPath: EDITOR_LINENUMBER_CONTEXT_MENU, anchor: event.event, args, - contextKeyService, - onHide: () => contextKeyService.dispose() + contextKeyService }); }); } diff --git a/packages/filesystem/src/browser/file-upload-service.ts b/packages/filesystem/src/browser/file-upload-service.ts index 66fdf2838dfeb..76db7ea89927b 100644 --- a/packages/filesystem/src/browser/file-upload-service.ts +++ b/packages/filesystem/src/browser/file-upload-service.ts @@ -33,13 +33,11 @@ import { nls } from '@theia/core/lib/common/nls'; export const HTTP_UPLOAD_URL: string = new Endpoint({ path: HTTP_FILE_UPLOAD_PATH }).getRestUrl().toString(true); -export interface CustomDataTransfer { - values(): Iterable -} +export type CustomDataTransfer = Iterable; export interface CustomDataTransferItem { - readonly id: string; asFile(): { + readonly id: string; readonly name: string; data(): Promise; } | undefined @@ -420,10 +418,10 @@ export class FileUploadService { } protected async indexCustomDataTransfer(targetUri: URI, dataTransfer: CustomDataTransfer, context: FileUploadService.Context): Promise { - for (const item of dataTransfer.values()) { + for (const [_, item] of dataTransfer) { const fileInfo = item.asFile(); if (fileInfo) { - await this.indexFile(targetUri, new File([await fileInfo.data()], item.id), context); + await this.indexFile(targetUri, new File([await fileInfo.data()], fileInfo.id), context); } } } diff --git a/packages/git/package.json b/packages/git/package.json index b787f26e88726..d24200fd36d67 100644 --- a/packages/git/package.json +++ b/packages/git/package.json @@ -6,7 +6,7 @@ "@theia/core": "1.46.0", "@theia/editor": "1.46.0", "@theia/filesystem": "1.46.0", - "@theia/monaco-editor-core": "1.72.3", + "@theia/monaco-editor-core": "1.83.101", "@theia/navigator": "1.46.0", "@theia/scm": "1.46.0", "@theia/scm-extra": "1.46.0", @@ -73,4 +73,4 @@ "nyc": { "extends": "../../configs/nyc.json" } -} +} \ No newline at end of file diff --git a/packages/keymaps/package.json b/packages/keymaps/package.json index c878bab03c9c3..fb3bf6f6a5847 100644 --- a/packages/keymaps/package.json +++ b/packages/keymaps/package.json @@ -5,7 +5,7 @@ "dependencies": { "@theia/core": "1.46.0", "@theia/monaco": "1.46.0", - "@theia/monaco-editor-core": "1.72.3", + "@theia/monaco-editor-core": "1.83.101", "@theia/preferences": "1.46.0", "@theia/userstorage": "1.46.0", "jsonc-parser": "^2.2.0" @@ -48,4 +48,4 @@ "nyc": { "extends": "../../configs/nyc.json" } -} +} \ No newline at end of file diff --git a/packages/monaco/package.json b/packages/monaco/package.json index 8937cb1aa6dbb..ff0fa606435e0 100644 --- a/packages/monaco/package.json +++ b/packages/monaco/package.json @@ -7,7 +7,7 @@ "@theia/editor": "1.46.0", "@theia/filesystem": "1.46.0", "@theia/markers": "1.46.0", - "@theia/monaco-editor-core": "1.72.3", + "@theia/monaco-editor-core": "1.83.101", "@theia/outline-view": "1.46.0", "@theia/workspace": "1.46.0", "fast-plist": "^0.1.2", @@ -55,4 +55,4 @@ "nyc": { "extends": "../../configs/nyc.json" } -} +} \ No newline at end of file diff --git a/packages/monaco/src/browser/markdown-renderer/monaco-markdown-renderer.ts b/packages/monaco/src/browser/markdown-renderer/monaco-markdown-renderer.ts index 5f2852d94cba6..dd46b027c06d8 100644 --- a/packages/monaco/src/browser/markdown-renderer/monaco-markdown-renderer.ts +++ b/packages/monaco/src/browser/markdown-renderer/monaco-markdown-renderer.ts @@ -16,14 +16,11 @@ import { inject, injectable, postConstruct } from '@theia/core/shared/inversify'; import { ILanguageService } from '@theia/monaco-editor-core/esm/vs/editor/common/languages/language'; -import { MarkdownRenderer as CodeMarkdownRenderer } from '@theia/monaco-editor-core/esm/vs/editor/contrib/markdownRenderer/browser/markdownRenderer'; +import { MarkdownRenderer as CodeMarkdownRenderer, IMarkdownRendererOptions } from '@theia/monaco-editor-core/esm/vs/editor/contrib/markdownRenderer/browser/markdownRenderer'; import { StandaloneServices } from '@theia/monaco-editor-core/esm/vs/editor/standalone/browser/standaloneServices'; -import { MonacoCommandServiceFactory } from '../monaco-command-service'; -import { MonacoEditorService } from '../monaco-editor-service'; import * as monaco from '@theia/monaco-editor-core'; -import { OpenerService as MonacoOpenerService } from '@theia/monaco-editor-core/esm/vs/editor/browser/services/openerService'; import { OpenerService, PreferenceService, WidgetOpenerOptions, open } from '@theia/core/lib/browser'; -import { OpenExternalOptions, OpenInternalOptions } from '@theia/monaco-editor-core/esm/vs/platform/opener/common/opener'; +import { IOpenerService, OpenExternalOptions, OpenInternalOptions } from '@theia/monaco-editor-core/esm/vs/platform/opener/common/opener'; import { HttpOpenHandlerOptions } from '@theia/core/lib/browser/http-open-handler'; import { URI } from '@theia/core/lib/common/uri'; import { MarkdownRenderer, MarkdownRenderOptions, MarkdownRenderResult } from '@theia/core/lib/browser/markdown-rendering/markdown-renderer'; @@ -34,8 +31,6 @@ import { DisposableCollection, DisposableGroup } from '@theia/core'; @injectable() export class MonacoMarkdownRenderer implements MarkdownRenderer { - @inject(MonacoEditorService) protected readonly codeEditorService: MonacoEditorService; - @inject(MonacoCommandServiceFactory) protected readonly commandServiceFactory: MonacoCommandServiceFactory; @inject(OpenerService) protected readonly openerService: OpenerService; @inject(PreferenceService) protected readonly preferences: PreferenceService; @@ -72,21 +67,18 @@ export class MonacoMarkdownRenderer implements MarkdownRenderer { @postConstruct() protected init(): void { const languages = StandaloneServices.get(ILanguageService); - const openerService = new MonacoOpenerService(this.codeEditorService, this.commandServiceFactory()); + const openerService = StandaloneServices.get(IOpenerService); openerService.registerOpener({ open: (u, options) => this.interceptOpen(u, options) }); - const getPreference = () => this.preferences.get('editor.fontFamily'); - const rendererOptions = new Proxy(Object.create(null), { // eslint-disable-line no-null/no-null - get(_, field): string | undefined { - if (field === 'codeBlockFontFamily') { - return getPreference(); - } else { - return undefined; - } + const that = this; + const prefs = new class implements IMarkdownRendererOptions { + get codeBlockFontFamily(): string | undefined { + return that.preferences.get('editor.fontFamily'); } - }); - this.delegate = new CodeMarkdownRenderer(rendererOptions, languages, openerService); + }; + + this.delegate = new CodeMarkdownRenderer(prefs, languages, openerService); } protected async interceptOpen(monacoUri: monaco.Uri | string, monacoOptions?: OpenInternalOptions | OpenExternalOptions): Promise { diff --git a/packages/monaco/src/browser/monaco-bulk-edit-service.ts b/packages/monaco/src/browser/monaco-bulk-edit-service.ts index f1d614c63bccf..a5f7accc1b2d3 100644 --- a/packages/monaco/src/browser/monaco-bulk-edit-service.ts +++ b/packages/monaco/src/browser/monaco-bulk-edit-service.ts @@ -31,12 +31,12 @@ export class MonacoBulkEditService implements IBulkEditService { private _previewHandler?: IBulkEditPreviewHandler; - async apply(editsIn: ResourceEdit[] | WorkspaceEdit, options?: IBulkEditOptions): Promise { + async apply(editsIn: ResourceEdit[] | WorkspaceEdit, options?: IBulkEditOptions): Promise { const edits = Array.isArray(editsIn) ? editsIn : ResourceEdit.convert(editsIn); if (this._previewHandler && (options?.showPreview || edits.some(value => value.metadata?.needsConfirmation))) { editsIn = await this._previewHandler(edits, options); - return { ariaSummary: '', success: true }; + return { ariaSummary: '', isApplied: true }; } else { return this.workspace.applyBulkEdit(edits, options); } diff --git a/packages/monaco/src/browser/monaco-command-registry.ts b/packages/monaco/src/browser/monaco-command-registry.ts index e9b76e454b373..540425850460f 100644 --- a/packages/monaco/src/browser/monaco-command-registry.ts +++ b/packages/monaco/src/browser/monaco-command-registry.ts @@ -36,7 +36,10 @@ export class MonacoCommandRegistry { @inject(SelectionService) protected readonly selectionService: SelectionService; - validate(command: string): string | undefined { + validate(command: string | undefined): string | undefined { + if (!command) { + return undefined; + } return this.commands.commandIds.indexOf(command) !== -1 ? command : undefined; } diff --git a/packages/monaco/src/browser/monaco-command-service.ts b/packages/monaco/src/browser/monaco-command-service.ts index 7334eff649435..b6da221068cf6 100644 --- a/packages/monaco/src/browser/monaco-command-service.ts +++ b/packages/monaco/src/browser/monaco-command-service.ts @@ -14,18 +14,14 @@ // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 // ***************************************************************************** -import { inject, injectable } from '@theia/core/shared/inversify'; +import { inject, injectable, postConstruct } from '@theia/core/shared/inversify'; import { CommandRegistry } from '@theia/core/lib/common/command'; import { Emitter } from '@theia/core/lib/common/event'; import { Disposable, DisposableCollection } from '@theia/core/lib/common/disposable'; import { ICommandEvent, ICommandService } from '@theia/monaco-editor-core/esm/vs/platform/commands/common/commands'; -import { StandaloneCommandService } from '@theia/monaco-editor-core/esm/vs/editor/standalone/browser/standaloneServices'; +import { StandaloneCommandService, StandaloneServices } from '@theia/monaco-editor-core/esm/vs/editor/standalone/browser/standaloneServices'; import * as monaco from '@theia/monaco-editor-core'; - -export const MonacoCommandServiceFactory = Symbol('MonacoCommandServiceFactory'); -export interface MonacoCommandServiceFactory { - (): MonacoCommandService; -} +import { IInstantiationService } from '@theia/monaco-editor-core/esm/vs/platform/instantiation/common/instantiation'; @injectable() export class MonacoCommandService implements ICommandService, Disposable { @@ -38,7 +34,6 @@ export class MonacoCommandService implements ICommandService, Disposable { ); protected delegate: StandaloneCommandService | undefined; - protected readonly delegateListeners = new DisposableCollection(); constructor( @inject(CommandRegistry) protected readonly commandRegistry: CommandRegistry @@ -47,6 +42,19 @@ export class MonacoCommandService implements ICommandService, Disposable { this.toDispose.push(this.commandRegistry.onDidExecuteCommand(e => this.onDidExecuteCommandEmitter.fire(e))); } + @postConstruct() + init(): void { + this.delegate = new StandaloneCommandService(StandaloneServices.get(IInstantiationService)); + if (this.delegate) { + this.toDispose.push(this.delegate.onWillExecuteCommand(event => + this.onWillExecuteCommandEmitter.fire(event) + )); + this.toDispose.push(this.delegate.onDidExecuteCommand(event => + this.onDidExecuteCommandEmitter.fire(event) + )); + } + } + dispose(): void { this.toDispose.dispose(); } @@ -59,23 +67,6 @@ export class MonacoCommandService implements ICommandService, Disposable { return this.onDidExecuteCommandEmitter.event; } - setDelegate(delegate: StandaloneCommandService | undefined): void { - if (this.toDispose.disposed) { - return; - } - this.delegateListeners.dispose(); - this.toDispose.push(this.delegateListeners); - this.delegate = delegate; - if (this.delegate) { - this.delegateListeners.push(this.delegate.onWillExecuteCommand(event => - this.onWillExecuteCommandEmitter.fire(event) - )); - this.delegateListeners.push(this.delegate.onDidExecuteCommand(event => - this.onDidExecuteCommandEmitter.fire(event) - )); - } - } - // eslint-disable-next-line @typescript-eslint/no-explicit-any async executeCommand(commandId: any, ...args: any[]): Promise { try { diff --git a/packages/monaco/src/browser/monaco-command.ts b/packages/monaco/src/browser/monaco-command.ts index 323f4408a655f..2b8e13fe188e1 100644 --- a/packages/monaco/src/browser/monaco-command.ts +++ b/packages/monaco/src/browser/monaco-command.ts @@ -21,16 +21,15 @@ import { CommonCommands, QuickInputService, ApplicationShell } from '@theia/core import { EditorCommands, EditorManager, EditorWidget } from '@theia/editor/lib/browser'; import { MonacoEditor } from './monaco-editor'; import { MonacoCommandRegistry, MonacoEditorCommandHandler } from './monaco-command-registry'; -import { MonacoEditorService } from './monaco-editor-service'; -import { MonacoTextModelService } from './monaco-text-model-service'; import { ProtocolToMonacoConverter } from './protocol-to-monaco-converter'; import { nls } from '@theia/core/lib/common/nls'; -import { ContextKeyService as VSCodeContextKeyService } from '@theia/monaco-editor-core/esm/vs/platform/contextkey/browser/contextKeyService'; import { EditorExtensionsRegistry } from '@theia/monaco-editor-core/esm/vs/editor/browser/editorExtensions'; import { CommandsRegistry, ICommandService } from '@theia/monaco-editor-core/esm/vs/platform/commands/common/commands'; import * as monaco from '@theia/monaco-editor-core'; import { EndOfLineSequence } from '@theia/monaco-editor-core/esm/vs/editor/common/model'; import { StandaloneServices } from '@theia/monaco-editor-core/esm/vs/editor/standalone/browser/standaloneServices'; +import { IInstantiationService } from '@theia/monaco-editor-core/esm/vs/platform/instantiation/common/instantiation'; +import { ICodeEditorService } from '@theia/monaco-editor-core/esm/vs/editor/browser/services/codeEditorService'; export namespace MonacoCommands { @@ -67,15 +66,6 @@ export class MonacoEditorCommandHandlers implements CommandContribution { @inject(QuickInputService) @optional() protected readonly quickInputService: QuickInputService; - @inject(MonacoEditorService) - protected readonly codeEditorService: MonacoEditorService; - - @inject(MonacoTextModelService) - protected readonly textModelService: MonacoTextModelService; - - @inject(VSCodeContextKeyService) - protected readonly contextKeyService: VSCodeContextKeyService; - @inject(ApplicationShell) protected readonly shell: ApplicationShell; @@ -135,10 +125,10 @@ export class MonacoEditorCommandHandlers implements CommandContribution { * and execute them using the instantiation service of the current editor. */ protected registerMonacoCommands(): void { - const editorActions = new Map(EditorExtensionsRegistry.getEditorActions().map(({ id, label, alias }) => [id, { label, alias }])); + const editorActions = new Map([...EditorExtensionsRegistry.getEditorActions()].map(({ id, label, alias }) => [id, { label, alias }])); - const { codeEditorService } = this; - const globalInstantiationService = StandaloneServices.initialize({}); + const codeEditorService = StandaloneServices.get(ICodeEditorService); + const globalInstantiationService = StandaloneServices.get(IInstantiationService); const monacoCommands = CommandsRegistry.getCommands(); for (const id of monacoCommands.keys()) { if (MonacoCommands.EXCLUDE_ACTIONS.has(id)) { diff --git a/packages/monaco/src/browser/monaco-context-key-service.ts b/packages/monaco/src/browser/monaco-context-key-service.ts index 6450f4240d2d1..3de29a0826c4c 100644 --- a/packages/monaco/src/browser/monaco-context-key-service.ts +++ b/packages/monaco/src/browser/monaco-context-key-service.ts @@ -14,22 +14,24 @@ // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 // ***************************************************************************** -import { injectable, inject, postConstruct } from '@theia/core/shared/inversify'; +import { injectable, postConstruct } from '@theia/core/shared/inversify'; import { ContextKeyService as TheiaContextKeyService, ContextKey, ContextKeyChangeEvent, ScopedValueStore, ContextMatcher, ContextKeyValue } from '@theia/core/lib/browser/context-key-service'; import { Emitter } from '@theia/core'; -import { AbstractContextKeyService, ContextKeyService as VSCodeContextKeyService } from '@theia/monaco-editor-core/esm/vs/platform/contextkey/browser/contextKeyService'; +import { AbstractContextKeyService } from '@theia/monaco-editor-core/esm/vs/platform/contextkey/browser/contextKeyService'; import { ContextKeyExpr, ContextKeyExpression, IContext, IContextKeyService } from '@theia/monaco-editor-core/esm/vs/platform/contextkey/common/contextkey'; +import { StandaloneServices } from '@theia/monaco-editor-core/esm/vs/editor/standalone/browser/standaloneServices'; @injectable() export class MonacoContextKeyService implements TheiaContextKeyService { protected readonly onDidChangeEmitter = new Emitter(); readonly onDidChange = this.onDidChangeEmitter.event; - @inject(VSCodeContextKeyService) - protected readonly contextKeyService: VSCodeContextKeyService; + get contextKeyService(): AbstractContextKeyService { + return StandaloneServices.get(IContextKeyService) as AbstractContextKeyService; + } @postConstruct() protected init(): void { @@ -125,8 +127,7 @@ export class MonacoContextKeyService implements TheiaContextKeyService { return parsed.evaluate(ctx); } return true; - }, - dispose: () => delegate.dispose(), + } }; } diff --git a/packages/monaco/src/browser/monaco-context-menu.ts b/packages/monaco/src/browser/monaco-context-menu.ts index 5049414bf83b9..681909b0a4a0b 100644 --- a/packages/monaco/src/browser/monaco-context-menu.ts +++ b/packages/monaco/src/browser/monaco-context-menu.ts @@ -17,13 +17,14 @@ import { injectable, inject } from '@theia/core/shared/inversify'; import { MenuPath } from '@theia/core/lib/common/menu'; import { EDITOR_CONTEXT_MENU } from '@theia/editor/lib/browser'; -import { ContextMenuRenderer, toAnchor } from '@theia/core/lib/browser'; +import { Anchor, ContextMenuRenderer, Coordinate } from '@theia/core/lib/browser'; import { Menu } from '@theia/core/shared/@phosphor/widgets'; import { CommandRegistry } from '@theia/core/shared/@phosphor/commands'; import { IContextMenuService } from '@theia/monaco-editor-core/esm/vs/platform/contextview/browser/contextView'; import { IContextMenuDelegate } from '@theia/monaco-editor-core/esm/vs/base/browser/contextmenu'; import { MenuItemAction } from '@theia/monaco-editor-core/esm/vs/platform/actions/common/actions'; import { Event, Emitter } from '@theia/monaco-editor-core/esm/vs/base/common/event'; +import { StandardMouseEvent } from '@theia/monaco-editor-core/esm/vs/base/browser/mouseEvent'; @injectable() export class MonacoContextMenuService implements IContextMenuService { @@ -38,11 +39,20 @@ export class MonacoContextMenuService implements IContextMenuService { return this.onDidShowContextMenuEmitter.event; }; - constructor(@inject(ContextMenuRenderer) protected readonly contextMenuRenderer: ContextMenuRenderer) { + @inject(ContextMenuRenderer) protected readonly contextMenuRenderer: ContextMenuRenderer; + + toAnchor(anchor: HTMLElement | Coordinate | StandardMouseEvent): Anchor { + if (anchor instanceof HTMLElement) { + return { x: anchor.offsetLeft, y: anchor.offsetTop }; + } else if (anchor instanceof StandardMouseEvent) { + return { x: anchor.posx, y: anchor.posy }; + } else { + return anchor; + } } showContextMenu(delegate: IContextMenuDelegate): void { - const anchor = toAnchor(delegate.getAnchor()); + const anchor = this.toAnchor(delegate.getAnchor()); const actions = delegate.getActions(); const onHide = () => { delegate.onHide?.(false); diff --git a/packages/monaco/src/browser/monaco-diff-editor.ts b/packages/monaco/src/browser/monaco-diff-editor.ts index fa001542240d4..b631ebb8f95da 100644 --- a/packages/monaco/src/browser/monaco-diff-editor.ts +++ b/packages/monaco/src/browser/monaco-diff-editor.ts @@ -23,16 +23,15 @@ import { MonacoDiffNavigatorFactory } from './monaco-diff-navigator-factory'; import { DiffUris } from '@theia/core/lib/browser/diff-uris'; import * as monaco from '@theia/monaco-editor-core'; import { IDiffEditorConstructionOptions } from '@theia/monaco-editor-core/esm/vs/editor/browser/editorBrowser'; -import { IDiffNavigatorOptions } from '@theia/monaco-editor-core/esm/vs/editor/standalone/browser/standaloneEditor'; -import { StandaloneDiffEditor } from '@theia/monaco-editor-core/esm/vs/editor/standalone/browser/standaloneCodeEditor'; +import { StandaloneDiffEditor2 } from '@theia/monaco-editor-core/esm/vs/editor/standalone/browser/standaloneCodeEditor'; export namespace MonacoDiffEditor { - export interface IOptions extends MonacoEditor.ICommonOptions, IDiffEditorConstructionOptions, IDiffNavigatorOptions { + export interface IOptions extends MonacoEditor.ICommonOptions, IDiffEditorConstructionOptions { } } export class MonacoDiffEditor extends MonacoEditor { - protected _diffEditor: monaco.editor.IStandaloneDiffEditor; + protected _diffEditor: StandaloneDiffEditor2; protected _diffNavigator: DiffNavigator; constructor( @@ -43,18 +42,18 @@ export class MonacoDiffEditor extends MonacoEditor { services: MonacoEditorServices, protected readonly diffNavigatorFactory: MonacoDiffNavigatorFactory, options?: MonacoDiffEditor.IOptions, - override?: EditorServiceOverrides, + override?: EditorServiceOverrides ) { super(uri, modifiedModel, node, services, options, override); this.documents.add(originalModel); const original = originalModel.textEditorModel; const modified = modifiedModel.textEditorModel; - this._diffNavigator = diffNavigatorFactory.createdDiffNavigator(this._diffEditor, options); + this._diffNavigator = diffNavigatorFactory.createdDiffNavigator(this._diffEditor); this._diffEditor.setModel({ original, modified }); } get diffEditor(): monaco.editor.IStandaloneDiffEditor { - return this._diffEditor; + return this._diffEditor as unknown as monaco.editor.IStandaloneDiffEditor; } get diffNavigator(): DiffNavigator { @@ -68,8 +67,8 @@ export class MonacoDiffEditor extends MonacoEditor { * Incomparable enums prevent TypeScript from believing that public IStandaloneDiffEditor is satisfied by private StandaloneDiffEditor */ this._diffEditor = instantiator - .createInstance(StandaloneDiffEditor, this.node, { ...options, fixedOverflowWidgets: true }) as unknown as monaco.editor.IStandaloneDiffEditor; - this.editor = this._diffEditor.getModifiedEditor(); + .createInstance(StandaloneDiffEditor2, this.node, { ...options, fixedOverflowWidgets: true }); + this.editor = this._diffEditor.getModifiedEditor() as unknown as monaco.editor.IStandaloneCodeEditor; return this._diffEditor; } diff --git a/packages/monaco/src/browser/monaco-diff-navigator-factory.ts b/packages/monaco/src/browser/monaco-diff-navigator-factory.ts index 906057465ed0e..639037c304800 100644 --- a/packages/monaco/src/browser/monaco-diff-navigator-factory.ts +++ b/packages/monaco/src/browser/monaco-diff-navigator-factory.ts @@ -16,46 +16,24 @@ import { injectable } from '@theia/core/shared/inversify'; import { DiffNavigator } from '@theia/editor/lib/browser'; -import * as monaco from '@theia/monaco-editor-core'; -import { DiffNavigator as MonacoDiffNavigator } from '@theia/monaco-editor-core/esm/vs/editor/browser/widget/diffNavigator'; -import { IStandaloneDiffEditor } from '@theia/monaco-editor-core/esm/vs/editor/standalone/browser/standaloneCodeEditor'; +import { StandaloneDiffEditor2 } from '@theia/monaco-editor-core/esm/vs/editor/standalone/browser/standaloneCodeEditor'; @injectable() export class MonacoDiffNavigatorFactory { static nullNavigator = { - canNavigate: () => false, hasNext: () => false, hasPrevious: () => false, next: () => { }, previous: () => { }, }; - createdDiffNavigator(editor: IStandaloneDiffEditor | monaco.editor.IStandaloneDiffEditor, options?: monaco.editor.IDiffNavigatorOptions): DiffNavigator { - const navigator = new MonacoDiffNavigator(editor as IStandaloneDiffEditor, options); - const ensureInitialized = (fwd: boolean) => { - if (navigator['nextIdx'] < 0) { - navigator['_initIdx'](fwd); - } - }; + createdDiffNavigator(editor: StandaloneDiffEditor2): DiffNavigator { return { - canNavigate: () => navigator.canNavigate(), - hasNext: () => { - if (navigator.canNavigate()) { - ensureInitialized(true); - return navigator['nextIdx'] + 1 < navigator['ranges'].length; - } - return false; - }, - hasPrevious: () => { - if (navigator.canNavigate()) { - ensureInitialized(false); - return navigator['nextIdx'] > 0; - } - return false; - }, - next: () => navigator.next(), - previous: () => navigator.previous(), + hasNext: () => true, + hasPrevious: () => true, + next: () => editor.goToDiff('next'), + previous: () => editor.goToDiff('previous') }; } } diff --git a/packages/monaco/src/browser/monaco-editor-provider.ts b/packages/monaco/src/browser/monaco-editor-provider.ts index e939ee5f2cc6c..0b928dc71ddd7 100644 --- a/packages/monaco/src/browser/monaco-editor-provider.ts +++ b/packages/monaco/src/browser/monaco-editor-provider.ts @@ -21,16 +21,11 @@ import { DiffUris } from '@theia/core/lib/browser/diff-uris'; import { inject, injectable, named } from '@theia/core/shared/inversify'; import { DisposableCollection, deepClone, Disposable } from '@theia/core/lib/common'; import { TextDocumentSaveReason } from '@theia/core/shared/vscode-languageserver-protocol'; -import { MonacoCommandServiceFactory } from './monaco-command-service'; -import { MonacoContextMenuService } from './monaco-context-menu'; import { MonacoDiffEditor } from './monaco-diff-editor'; import { MonacoDiffNavigatorFactory } from './monaco-diff-navigator-factory'; import { EditorServiceOverrides, MonacoEditor, MonacoEditorServices } from './monaco-editor'; import { MonacoEditorModel, WillSaveMonacoModelEvent } from './monaco-editor-model'; -import { MonacoEditorService } from './monaco-editor-service'; -import { MonacoTextModelService } from './monaco-text-model-service'; import { MonacoWorkspace } from './monaco-workspace'; -import { MonacoBulkEditService } from './monaco-bulk-edit-service'; import { ApplicationServer } from '@theia/core/lib/common/application-protocol'; import { ContributionProvider } from '@theia/core'; import { KeybindingRegistry, OpenerService, open, WidgetOpenerOptions, FormatType } from '@theia/core/lib/browser'; @@ -39,23 +34,16 @@ import { HttpOpenHandlerOptions } from '@theia/core/lib/browser/http-open-handle import { MonacoToProtocolConverter } from './monaco-to-protocol-converter'; import { ProtocolToMonacoConverter } from './protocol-to-monaco-converter'; import { FileSystemPreferences } from '@theia/filesystem/lib/browser'; -import { MonacoQuickInputImplementation } from './monaco-quick-input-service'; -import { ContextKeyService } from '@theia/monaco-editor-core/esm/vs/platform/contextkey/browser/contextKeyService'; import * as monaco from '@theia/monaco-editor-core'; -import { OpenerService as MonacoOpenerService } from '@theia/monaco-editor-core/esm/vs/editor/browser/services/openerService'; -import { StandaloneCommandService, StandaloneServices } from '@theia/monaco-editor-core/esm/vs/editor/standalone/browser/standaloneServices'; +import { StandaloneServices } from '@theia/monaco-editor-core/esm/vs/editor/standalone/browser/standaloneServices'; import { IOpenerService, OpenExternalOptions, OpenInternalOptions } from '@theia/monaco-editor-core/esm/vs/platform/opener/common/opener'; -import { SimpleKeybinding } from '@theia/monaco-editor-core/esm/vs/base/common/keybindings'; -import { ICodeEditorService } from '@theia/monaco-editor-core/esm/vs/editor/browser/services/codeEditorService'; -import { IInstantiationService } from '@theia/monaco-editor-core/esm/vs/platform/instantiation/common/instantiation'; import { IKeybindingService } from '@theia/monaco-editor-core/esm/vs/platform/keybinding/common/keybinding'; import { timeoutReject } from '@theia/core/lib/common/promise-util'; -import { ITextModelService } from '@theia/monaco-editor-core/esm/vs/editor/common/services/resolverService'; import { IContextMenuService } from '@theia/monaco-editor-core/esm/vs/platform/contextview/browser/contextView'; -import { IBulkEditService } from '@theia/monaco-editor-core/esm/vs/editor/browser/services/bulkEditService'; +import { KeyCodeChord } from '@theia/monaco-editor-core/esm/vs/base/common/keybindings'; import { IContextKeyService } from '@theia/monaco-editor-core/esm/vs/platform/contextkey/common/contextkey'; -import { IQuickInputService } from '@theia/monaco-editor-core/esm/vs/platform/quickinput/common/quickInput'; -import { ICommandService } from '@theia/monaco-editor-core/esm/vs/platform/commands/common/commands'; +import { ITextModelService } from '@theia/monaco-editor-core/esm/vs/editor/common/services/resolverService'; +import { IReference } from '@theia/monaco-editor-core/esm/vs/base/common/lifecycle'; export const MonacoEditorFactory = Symbol('MonacoEditorFactory'); export interface MonacoEditorFactory { @@ -70,9 +58,6 @@ export class MonacoEditorProvider { @named(MonacoEditorFactory) protected readonly factories: ContributionProvider; - @inject(MonacoBulkEditService) - protected readonly bulkEditService: MonacoBulkEditService; - @inject(MonacoEditorServices) protected readonly services: MonacoEditorServices; @@ -85,9 +70,6 @@ export class MonacoEditorProvider { @inject(FileSystemPreferences) protected readonly filePreferences: FileSystemPreferences; - @inject(MonacoQuickInputImplementation) - protected readonly quickInputService: MonacoQuickInputImplementation; - protected _current: MonacoEditor | undefined; /** * Returns the last focused MonacoEditor. @@ -99,26 +81,18 @@ export class MonacoEditorProvider { } constructor( - @inject(MonacoEditorService) protected readonly codeEditorService: MonacoEditorService, - @inject(MonacoTextModelService) protected readonly textModelService: MonacoTextModelService, - @inject(MonacoContextMenuService) protected readonly contextMenuService: MonacoContextMenuService, @inject(MonacoToProtocolConverter) protected readonly m2p: MonacoToProtocolConverter, @inject(ProtocolToMonacoConverter) protected readonly p2m: ProtocolToMonacoConverter, @inject(MonacoWorkspace) protected readonly workspace: MonacoWorkspace, - @inject(MonacoCommandServiceFactory) protected readonly commandServiceFactory: MonacoCommandServiceFactory, @inject(EditorPreferences) protected readonly editorPreferences: EditorPreferences, @inject(MonacoDiffNavigatorFactory) protected readonly diffNavigatorFactory: MonacoDiffNavigatorFactory, /** @deprecated since 1.6.0 */ @inject(ApplicationServer) protected readonly applicationServer: ApplicationServer, - @inject(ContextKeyService) protected readonly contextKeyService: ContextKeyService ) { - StandaloneServices.initialize({ - [ICodeEditorService.toString()]: codeEditorService, - }); } protected async getModel(uri: URI, toDispose: DisposableCollection): Promise { - const reference = await this.textModelService.createModelReference(uri); + const reference = await StandaloneServices.get(ITextModelService).createModelReference(monaco.Uri.from(uri.toComponents())) as IReference; // if document is invalid makes sure that all events from underlying resource are processed before throwing invalid model if (!reference.object.valid) { await reference.object.sync(); @@ -139,34 +113,20 @@ export class MonacoEditorProvider { protected async doCreateEditor(uri: URI, factory: ( override: EditorServiceOverrides, toDispose: DisposableCollection) => Promise ): Promise { - const commandService = this.commandServiceFactory(); const domNode = document.createElement('div'); - const contextKeyService = this.contextKeyService.createScoped(domNode); - const { codeEditorService, textModelService, contextMenuService } = this; - const workspaceEditService = this.bulkEditService; - const toDispose = new DisposableCollection(commandService); - const openerService = new MonacoOpenerService(codeEditorService, commandService); - openerService.registerOpener({ + const contextKeyService = StandaloneServices.get(IContextKeyService).createScoped(domNode); + StandaloneServices.get(IOpenerService).registerOpener({ open: (u, options) => this.interceptOpen(u, options) }); const overrides: EditorServiceOverrides = [ - [ICodeEditorService, codeEditorService], - [ITextModelService, textModelService], - [IContextMenuService, contextMenuService], - [IBulkEditService, workspaceEditService], [IContextKeyService, contextKeyService], - [IOpenerService, openerService], - [IQuickInputService, this.quickInputService], - [ICommandService, commandService] ]; + const toDispose = new DisposableCollection(); const editor = await factory(overrides, toDispose); editor.onDispose(() => toDispose.dispose()); this.injectKeybindingResolver(editor); - const standaloneCommandService = new StandaloneCommandService(StandaloneServices.get(IInstantiationService)); - commandService.setDelegate(standaloneCommandService); - toDispose.push(editor.onFocusChanged(focused => { if (focused) { this._current = editor; @@ -212,16 +172,16 @@ export class MonacoEditorProvider { protected injectKeybindingResolver(editor: MonacoEditor): void { const keybindingService = StandaloneServices.get(IKeybindingService); - keybindingService.resolveKeybinding = keybinding => [new MonacoResolvedKeybinding(MonacoResolvedKeybinding.keySequence(keybinding), this.keybindingRegistry)]; + keybindingService.resolveKeybinding = keybinding => [new MonacoResolvedKeybinding(MonacoResolvedKeybinding.keySequence(keybinding.chords), this.keybindingRegistry)]; keybindingService.resolveKeyboardEvent = keyboardEvent => { - const keybinding = new SimpleKeybinding( + const keybinding = new KeyCodeChord( keyboardEvent.ctrlKey, keyboardEvent.shiftKey, keyboardEvent.altKey, keyboardEvent.metaKey, keyboardEvent.keyCode - ).toChord(); - return new MonacoResolvedKeybinding(MonacoResolvedKeybinding.keySequence(keybinding), this.keybindingRegistry); + ); + return new MonacoResolvedKeybinding(MonacoResolvedKeybinding.keySequence([keybinding]), this.keybindingRegistry); }; } @@ -403,10 +363,10 @@ export class MonacoEditorProvider { const overrides = override ? Array.from(override) : []; overrides.push([IContextMenuService, { showContextMenu: () => {/** no op! */ } }]); const document = new MonacoEditorModel({ - uri, - readContents: async () => '', - dispose: () => { } - }, this.m2p, this.p2m); + uri, + readContents: async () => '', + dispose: () => { } + }, this.m2p, this.p2m); toDispose.push(document); const model = (await document.load()).textEditorModel; return new MonacoEditor( diff --git a/packages/monaco/src/browser/monaco-editor-service.ts b/packages/monaco/src/browser/monaco-editor-service.ts index e6cee47621571..85c57658b2e1b 100644 --- a/packages/monaco/src/browser/monaco-editor-service.ts +++ b/packages/monaco/src/browser/monaco-editor-service.ts @@ -22,15 +22,20 @@ import { MonacoEditor } from './monaco-editor'; import { MonacoToProtocolConverter } from './monaco-to-protocol-converter'; import { MonacoEditorModel } from './monaco-editor-model'; import { IResourceEditorInput, ITextResourceEditorInput } from '@theia/monaco-editor-core/esm/vs/platform/editor/common/editor'; -import { StandaloneServices } from '@theia/monaco-editor-core/esm/vs/editor/standalone/browser/standaloneServices'; -import { IStandaloneThemeService } from '@theia/monaco-editor-core/esm/vs/editor/standalone/common/standaloneTheme'; import { StandaloneCodeEditorService } from '@theia/monaco-editor-core/esm/vs/editor/standalone/browser/standaloneCodeEditorService'; import { StandaloneCodeEditor } from '@theia/monaco-editor-core/esm/vs/editor/standalone/browser/standaloneCodeEditor'; import { ICodeEditor } from '@theia/monaco-editor-core/esm/vs/editor/browser/editorBrowser'; -import { ContextKeyService as VSCodeContextKeyService } from '@theia/monaco-editor-core/esm/vs/platform/contextkey/browser/contextKeyService'; +import { IContextKeyService } from '@theia/monaco-editor-core/esm/vs/platform/contextkey/common/contextkey'; +import { IThemeService } from '@theia/monaco-editor-core/esm/vs/platform/theme/common/themeService'; decorate(injectable(), StandaloneCodeEditorService); +export const VSCodeContextKeyService = Symbol('VSCodeContextKeyService'); +export const VSCodeThemeService = Symbol('VSCodeThemeService'); + +export const MonacoEditorServiceFactory = Symbol('MonacoEditorServiceFactory'); +export type MonacoEditorServiceFactoryType = (contextKeyService: IContextKeyService, themeService: IThemeService) => MonacoEditorService; + @injectable() export class MonacoEditorService extends StandaloneCodeEditorService { @@ -51,8 +56,8 @@ export class MonacoEditorService extends StandaloneCodeEditorService { @inject(PreferenceService) protected readonly preferencesService: PreferenceService; - constructor(@inject(VSCodeContextKeyService) contextKeyService: VSCodeContextKeyService) { - super(contextKeyService, StandaloneServices.get(IStandaloneThemeService)); + constructor(@inject(VSCodeContextKeyService) contextKeyService: IContextKeyService, @inject(VSCodeThemeService) themeService: IThemeService) { + super(contextKeyService, themeService); } /** diff --git a/packages/monaco/src/browser/monaco-editor.ts b/packages/monaco/src/browser/monaco-editor.ts index 3bee47b20feff..be9029fb2bde3 100644 --- a/packages/monaco/src/browser/monaco-editor.ts +++ b/packages/monaco/src/browser/monaco-editor.ts @@ -35,7 +35,8 @@ import { EditorDecoration, EditorMouseEvent, EncodingMode, - EditorDecorationOptions + EditorDecorationOptions, + MouseTargetType } from '@theia/editor/lib/browser'; import { MonacoEditorModel } from './monaco-editor-model'; import { MonacoToProtocolConverter } from './monaco-to-protocol-converter'; @@ -46,9 +47,9 @@ import * as monaco from '@theia/monaco-editor-core'; import { StandaloneServices } from '@theia/monaco-editor-core/esm/vs/editor/standalone/browser/standaloneServices'; import { ILanguageService } from '@theia/monaco-editor-core/esm/vs/editor/common/languages/language'; import { IInstantiationService, ServiceIdentifier } from '@theia/monaco-editor-core/esm/vs/platform/instantiation/common/instantiation'; -import { ICodeEditor } from '@theia/monaco-editor-core/esm/vs/editor/browser/editorBrowser'; -import { ServiceCollection } from '@theia/monaco-editor-core/esm/vs/platform/instantiation/common/serviceCollection'; +import { ICodeEditor, IMouseTargetMargin } from '@theia/monaco-editor-core/esm/vs/editor/browser/editorBrowser'; import { IStandaloneEditorConstructionOptions, StandaloneEditor } from '@theia/monaco-editor-core/esm/vs/editor/standalone/browser/standaloneCodeEditor'; +import { ServiceCollection } from '@theia/monaco-editor-core/esm/vs/platform/instantiation/common/serviceCollection'; export type ServicePair = [ServiceIdentifier, T]; @@ -151,7 +152,7 @@ export class MonacoEditor extends MonacoEditorServices implements TextEditor { } protected getInstantiatorWithOverrides(override?: EditorServiceOverrides): IInstantiationService { - const instantiator = StandaloneServices.initialize({}); + const instantiator = StandaloneServices.get(IInstantiationService); if (override) { const overrideServices = new ServiceCollection(...override); return instantiator.createChild(overrideServices); @@ -185,12 +186,12 @@ export class MonacoEditor extends MonacoEditorServices implements TextEditor { const { element, position, range } = e.target; this.onMouseDownEmitter.fire({ target: { - ...e.target, + type: e.target.type as unknown as MouseTargetType, element: element || undefined, mouseColumn: this.m2p.asPosition(undefined, e.target.mouseColumn).character, range: range && this.m2p.asRange(range) || undefined, position: position && this.m2p.asPosition(position.lineNumber, position.column) || undefined, - detail: (e.target as monaco.editor.IMouseTargetMargin).detail || {}, + detail: (e.target as unknown as IMouseTargetMargin).detail || {}, }, event: e.event.browserEvent }); diff --git a/packages/monaco/src/browser/monaco-frontend-application-contribution.ts b/packages/monaco/src/browser/monaco-frontend-application-contribution.ts index 4d8ccb9511129..6d9b4251d5b41 100644 --- a/packages/monaco/src/browser/monaco-frontend-application-contribution.ts +++ b/packages/monaco/src/browser/monaco-frontend-application-contribution.ts @@ -20,15 +20,7 @@ import { MonacoSnippetSuggestProvider } from './monaco-snippet-suggest-provider' import * as monaco from '@theia/monaco-editor-core'; import { setSnippetSuggestSupport } from '@theia/monaco-editor-core/esm/vs/editor/contrib/suggest/browser/suggest'; import { CompletionItemProvider } from '@theia/monaco-editor-core/esm/vs/editor/common/languages'; -import { MonacoEditorService } from './monaco-editor-service'; import { MonacoTextModelService } from './monaco-text-model-service'; -import { ContextKeyService as VSCodeContextKeyService } from '@theia/monaco-editor-core/esm/vs/platform/contextkey/browser/contextKeyService'; -import { StandaloneServices } from '@theia/monaco-editor-core/esm/vs/editor/standalone/browser/standaloneServices'; -import { ICodeEditorService } from '@theia/monaco-editor-core/esm/vs/editor/browser/services/codeEditorService'; -import { ITextModelService } from '@theia/monaco-editor-core/esm/vs/editor/common/services/resolverService'; -import { IContextKeyService } from '@theia/monaco-editor-core/esm/vs/platform/contextkey/common/contextkey'; -import { IContextMenuService } from '@theia/monaco-editor-core/esm/vs/platform/contextview/browser/contextView'; -import { MonacoContextMenuService } from './monaco-context-menu'; import { MonacoThemingService } from './monaco-theming-service'; import { isHighContrast } from '@theia/core/lib/common/theme'; import { editorOptionsRegistry, IEditorOption } from '@theia/monaco-editor-core/esm/vs/editor/common/config/editorOptions'; @@ -36,28 +28,12 @@ import { MAX_SAFE_INTEGER } from '@theia/core'; import { editorGeneratedPreferenceProperties } from '@theia/editor/lib/browser/editor-generated-preference-schema'; import { WorkspaceFileService } from '@theia/workspace/lib/common/workspace-file-service'; -let theiaDidInitialize = false; -const originalInitialize = StandaloneServices.initialize; -StandaloneServices.initialize = overrides => { - if (!theiaDidInitialize) { - console.warn('Monaco was initialized before overrides were installed by Theia\'s initialization.' - + ' Please check the lifecycle of services that use Monaco and ensure that Monaco entities are not instantiated before Theia is initialized.', new Error()); - } - return originalInitialize(overrides); -}; - @injectable() export class MonacoFrontendApplicationContribution implements FrontendApplicationContribution, StylingParticipant { - @inject(MonacoEditorService) - protected readonly codeEditorService: MonacoEditorService; - @inject(MonacoTextModelService) protected readonly textModelService: MonacoTextModelService; - @inject(VSCodeContextKeyService) - protected readonly contextKeyService: VSCodeContextKeyService; - @inject(MonacoSnippetSuggestProvider) protected readonly snippetSuggestProvider: MonacoSnippetSuggestProvider; @@ -67,9 +43,6 @@ export class MonacoFrontendApplicationContribution implements FrontendApplicatio @inject(QuickAccessRegistry) protected readonly quickAccessRegistry: QuickAccessRegistry; - @inject(MonacoContextMenuService) - protected readonly contextMenuService: MonacoContextMenuService; - @inject(MonacoThemingService) protected readonly monacoThemingService: MonacoThemingService; @inject(WorkspaceFileService) protected readonly workspaceFileService: WorkspaceFileService; @@ -77,14 +50,6 @@ export class MonacoFrontendApplicationContribution implements FrontendApplicatio @postConstruct() protected init(): void { this.addAdditionalPreferenceValidations(); - const { codeEditorService, textModelService, contextKeyService, contextMenuService } = this; - theiaDidInitialize = true; - StandaloneServices.initialize({ - [ICodeEditorService.toString()]: codeEditorService, - [ITextModelService.toString()]: textModelService, - [IContextKeyService.toString()]: contextKeyService, - [IContextMenuService.toString()]: contextMenuService, - }); // Monaco registers certain quick access providers (e.g. QuickCommandAccess) at import time, but we want to use our own. this.quickAccessRegistry.clear(); diff --git a/packages/monaco/src/browser/monaco-frontend-module.ts b/packages/monaco/src/browser/monaco-frontend-module.ts index 6a717c3f4dab5..0bee7f59228b4 100644 --- a/packages/monaco/src/browser/monaco-frontend-module.ts +++ b/packages/monaco/src/browser/monaco-frontend-module.ts @@ -31,7 +31,7 @@ Object.assign(MonacoNls, { }); import '../../src/browser/style/index.css'; -import { ContainerModule, decorate, injectable, interfaces } from '@theia/core/shared/inversify'; +import { ContainerModule, interfaces } from '@theia/core/shared/inversify'; import { MenuContribution, CommandContribution, quickInputServicePath } from '@theia/core/lib/common'; import { FrontendApplicationContribution, KeybindingContribution, @@ -45,12 +45,12 @@ import { MonacoEditorCommandHandlers } from './monaco-command'; import { MonacoKeybindingContribution } from './monaco-keybinding'; import { MonacoLanguages } from './monaco-languages'; import { MonacoWorkspace } from './monaco-workspace'; -import { MonacoEditorService } from './monaco-editor-service'; +import { MonacoEditorService, MonacoEditorServiceFactory, VSCodeContextKeyService, VSCodeThemeService } from './monaco-editor-service'; import { MonacoTextModelService, MonacoEditorModelFactory } from './monaco-text-model-service'; import { MonacoContextMenuService } from './monaco-context-menu'; import { MonacoOutlineContribution } from './monaco-outline-contribution'; import { MonacoStatusBarContribution } from './monaco-status-bar-contribution'; -import { MonacoCommandService, MonacoCommandServiceFactory } from './monaco-command-service'; +import { MonacoCommandService } from './monaco-command-service'; import { MonacoCommandRegistry } from './monaco-command-registry'; import { MonacoDiffNavigatorFactory } from './monaco-diff-navigator-factory'; import { MonacoFrontendApplicationContribution } from './monaco-frontend-application-contribution'; @@ -80,16 +80,15 @@ import { GotoLineQuickAccessContribution } from './monaco-gotoline-quick-access' import { GotoSymbolQuickAccessContribution } from './monaco-gotosymbol-quick-access'; import { QuickAccessContribution, QuickAccessRegistry } from '@theia/core/lib/browser/quick-input/quick-access'; import { MonacoQuickAccessRegistry } from './monaco-quick-access-registry'; -import { ContextKeyService as VSCodeContextKeyService } from '@theia/monaco-editor-core/esm/vs/platform/contextkey/browser/contextKeyService'; import { ConfigurationTarget, IConfigurationChangeEvent, IConfigurationService } from '@theia/monaco-editor-core/esm/vs/platform/configuration/common/configuration'; -import { StandaloneConfigurationService, StandaloneServices } from '@theia/monaco-editor-core/esm/vs/editor/standalone/browser/standaloneServices'; +import { StandaloneConfigurationService } from '@theia/monaco-editor-core/esm/vs/editor/standalone/browser/standaloneServices'; import { Configuration } from '@theia/monaco-editor-core/esm/vs/platform/configuration/common/configurationModels'; import { MarkdownRenderer } from '@theia/core/lib/browser/markdown-rendering/markdown-renderer'; import { MonacoMarkdownRenderer } from './markdown-renderer/monaco-markdown-renderer'; import { ThemeService } from '@theia/core/lib/browser/theming'; import { ThemeServiceWithDB } from './monaco-indexed-db'; - -decorate(injectable(), VSCodeContextKeyService); +import { IContextKeyService } from '@theia/monaco-editor-core/esm/vs/platform/contextkey/common/contextkey'; +import { IThemeService } from '@theia/monaco-editor-core/esm/vs/platform/theme/common/themeService'; export default new ContainerModule((bind, unbind, isBound, rebind) => { bind(MonacoThemingService).toSelf().inSingletonScope(); @@ -114,15 +113,16 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => { bind(MonacoWorkspace).toSelf().inSingletonScope(); - bind(MonacoConfigurationService).toDynamicValue(({ container }) => - createMonacoConfigurationService(container) - ).inSingletonScope(); - bind(VSCodeContextKeyService).toDynamicValue(({ container }) => - new VSCodeContextKeyService(container.get(MonacoConfigurationService)) - ).inSingletonScope(); + bind(MonacoConfigurationService).toDynamicValue(({ container }) => createMonacoConfigurationService(container)).inSingletonScope(); bind(MonacoBulkEditService).toSelf().inSingletonScope(); - bind(MonacoEditorService).toSelf().inSingletonScope(); + bind(MonacoEditorServiceFactory).toFactory((context: interfaces.Context) => (contextKeyService: IContextKeyService, themeService: IThemeService) => { + const child = context.container.createChild(); + child.bind(VSCodeContextKeyService).toConstantValue(contextKeyService); + child.bind(VSCodeThemeService).toConstantValue(themeService); + child.bind(MonacoEditorService).toSelf().inSingletonScope(); + return child.get(MonacoEditorService); + }); bind(MonacoTextModelService).toSelf().inSingletonScope(); bind(MonacoContextMenuService).toSelf().inSingletonScope(); bind(MonacoEditorServices).toSelf().inSingletonScope(); @@ -130,7 +130,6 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => { bindContributionProvider(bind, MonacoEditorFactory); bindContributionProvider(bind, MonacoEditorModelFactory); bind(MonacoCommandService).toSelf().inTransientScope(); - bind(MonacoCommandServiceFactory).toAutoFactory(MonacoCommandService); bind(TextEditorProvider).toProvider(context => uri => context.container.get(MonacoEditorProvider).get(uri) @@ -198,7 +197,7 @@ export const MonacoConfigurationService = Symbol('MonacoConfigurationService'); export function createMonacoConfigurationService(container: interfaces.Container): IConfigurationService { const preferences = container.get(PreferenceService); const preferenceSchemaProvider = container.get(PreferenceSchemaProvider); - const service = StandaloneServices.get(IConfigurationService) as StandaloneConfigurationService; + const service = new StandaloneConfigurationService(); const _configuration: Configuration = service['_configuration']; _configuration.getValue = (section, overrides) => { @@ -216,6 +215,14 @@ export function createMonacoConfigurationService(container: interfaces.Container return proxy; }; + /* + * Since we never read values from the underlying service, writing to it doesn't make sense. The standalone editor writes to the configuration when being created, + * which makes sense in the standalone case where there is no preference infrastructure in place. Those writes degrade the performance, however, so we patch the + * service to an empty implementation. + */ + // eslint-disable-next-line @typescript-eslint/no-explicit-any + service.updateValues = (values: [string, any][]) => Promise.resolve(); + const toTarget = (scope: PreferenceScope): ConfigurationTarget => { switch (scope) { case PreferenceScope.Default: return ConfigurationTarget.DEFAULT; @@ -246,11 +253,12 @@ export function createMonacoConfigurationService(container: interfaces.Container overrides.push([override, [...values]]); } service['_onDidChangeConfiguration'].fire({ + sourceConfig: {}, change: { keys: [...context.keys], overrides }, - affectedKeys: [...context.affectedKeys], + affectedKeys: context.affectedKeys, source, affectsConfiguration: (prefix, options) => { if (!context.affectedKeys.has(prefix)) { diff --git a/packages/monaco/src/browser/monaco-icon-registry.ts b/packages/monaco/src/browser/monaco-icon-registry.ts index 48cadadcdf118..0df38bf51aa25 100644 --- a/packages/monaco/src/browser/monaco-icon-registry.ts +++ b/packages/monaco/src/browser/monaco-icon-registry.ts @@ -15,9 +15,9 @@ // ***************************************************************************** import { injectable } from '@theia/core/shared/inversify'; -import { ThemeIcon } from '@theia/monaco-editor-core/esm/vs/platform/theme/common/themeService'; import { IconRegistry } from '@theia/core/lib/browser/icon-registry'; -import { IconDefinition, IconFontDefinition, getIconRegistry } from '@theia/monaco-editor-core/esm/vs/platform/theme/common/iconRegistry'; +import { getIconRegistry } from '@theia/monaco-editor-core/esm/vs/platform/theme/common/iconRegistry'; +import { IconDefinition, IconFontDefinition, ThemeIcon } from '@theia/core/lib/common/theme'; @injectable() export class MonacoIconRegistry implements IconRegistry { @@ -33,7 +33,8 @@ export class MonacoIconRegistry implements IconRegistry { } registerIconFont(id: string, definition: IconFontDefinition): IconFontDefinition { - return this.iconRegistry.registerIconFont(id, definition); + // need to cast because of vscode issue https://github.com/microsoft/vscode/issues/190584 + return this.iconRegistry.registerIconFont(id, definition) as IconFontDefinition; } deregisterIconFont(id: string): void { @@ -41,7 +42,8 @@ export class MonacoIconRegistry implements IconRegistry { } getIconFont(id: string): IconFontDefinition | undefined { - return this.iconRegistry.getIconFont(id); + // need to cast because of vscode issue https://github.com/microsoft/vscode/issues/190584 + return this.iconRegistry.getIconFont(id) as IconFontDefinition; } } diff --git a/packages/monaco/src/browser/monaco-init.ts b/packages/monaco/src/browser/monaco-init.ts new file mode 100644 index 0000000000000..1fa6c367b0f40 --- /dev/null +++ b/packages/monaco/src/browser/monaco-init.ts @@ -0,0 +1,114 @@ +// ***************************************************************************** +// Copyright (C) 2023 STMicroelectronics and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0. +// +// This Source Code may also be made available under the following Secondary +// Licenses when the conditions for such availability set forth in the Eclipse +// Public License v. 2.0 are satisfied: GNU General Public License, version 2 +// with the GNU Classpath Exception which is available at +// https://www.gnu.org/software/classpath/license.html. +// +// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 +// ***************************************************************************** + +/* + * The code in this file is responsible for overriding service implementations in the Monaco editor with our own Theia-based implementations. + * Since we only get a single chance to call `StandaloneServies.initialize()` with our overrides, we need to make sure that intialize is called before the first call to + * `StandaloneServices.get()` or `StandaloneServies.initialize()`. As we do not control the mechanics of Inversify instance constructions, the approach here is to call + * `MonacoInit.init()` from the `index.js` file after all container modules are loaded, but before the first object is fetched from it. + * `StandaloneServices.initialize()` is called with service descriptors, not service instances. This lets us finish all overrides before any inversify object is constructed and + * might call `initialize()` while being constructed. + * The service descriptors require a constructor function, so we declare dummy class for each Monaco service we override. But instead of returning an instance of the dummy class, + * we fetch the implementation of the monaco service from the inversify container. + * The inversify-constructed services must not call StandaloneServices.get() or StandaloneServices.initialize() from their constructors. Calling `get`()` in postConstruct mehtods + * is allowed. + */ + +import { Container } from '@theia/core/shared/inversify'; +import { ICodeEditorService } from '@theia/monaco-editor-core/esm/vs/editor/browser/services/codeEditorService'; +import { StandaloneServices } from '@theia/monaco-editor-core/esm/vs/editor/standalone/browser/standaloneServices'; +import { SyncDescriptor } from '@theia/monaco-editor-core/esm/vs/platform/instantiation/common/descriptors'; +import { MonacoEditorServiceFactory, MonacoEditorServiceFactoryType } from './monaco-editor-service'; +import { IConfigurationService } from '@theia/monaco-editor-core/esm/vs/platform/configuration/common/configuration'; +import { ITextModelService } from '@theia/monaco-editor-core/esm/vs/editor/common/services/resolverService'; +import { MonacoConfigurationService } from './monaco-frontend-module'; +import { MonacoTextModelService } from './monaco-text-model-service'; +import { MonacoContextMenuService } from './monaco-context-menu'; +import { IContextMenuService } from '@theia/monaco-editor-core/esm/vs/platform/contextview/browser/contextView'; +import { IContextKeyService } from '@theia/monaco-editor-core/esm/vs/platform/contextkey/common/contextkey'; +import { IThemeService } from '@theia/monaco-editor-core/esm/vs/platform/theme/common/themeService'; +import { MonacoBulkEditService } from './monaco-bulk-edit-service'; +import { MonacoCommandService } from './monaco-command-service'; +import { IBulkEditService } from '@theia/monaco-editor-core/esm/vs/editor/browser/services/bulkEditService'; +import { ICommandService } from '@theia/monaco-editor-core/esm/vs/platform/commands/common/commands'; +import { MonacoQuickInputImplementation } from './monaco-quick-input-service'; +import { IQuickInputService } from '@theia/monaco-editor-core/esm/vs/platform/quickinput/common/quickInput'; + +class MonacoEditorServiceConstructor { + /** + * MonacoEditorService needs other Monaco services as constructor parameters, so we need to do use a factory for constructing the service. If we want the singleton instance, + * we need to fetch it from the `StandaloneServices` class instead of injecting it. + * @param container + * @param contextKeyService + * @param themeService + */ + constructor(container: Container, + @IContextKeyService contextKeyService: IContextKeyService, + @IThemeService themeService: IThemeService) { + + return container.get(MonacoEditorServiceFactory)(contextKeyService, themeService); + }; +} + +class MonacoConfigurationServiceConstructor { + constructor(container: Container) { + return container.get(MonacoConfigurationService); + } +} + +class MonacoTextModelServiceConstructor { + constructor(container: Container) { + return container.get(MonacoTextModelService); + } +} + +class MonacoContextMenuServiceConstructor { + constructor(container: Container) { + return container.get(MonacoContextMenuService); + } +} + +class MonacoBulkEditServiceConstructor { + constructor(container: Container) { + return container.get(MonacoBulkEditService); + } +} + +class MonacoCommandServiceConstructor { + constructor(container: Container) { + return container.get(MonacoCommandService); + } +} + +class MonacoQuickInputImplementationConstructor { + constructor(container: Container) { + return container.get(MonacoQuickInputImplementation); + } +} + +export namespace MonacoInit { + export function init(container: Container): void { + StandaloneServices.initialize({ + [ICodeEditorService.toString()]: new SyncDescriptor(MonacoEditorServiceConstructor, [container]), + [IConfigurationService.toString()]: new SyncDescriptor(MonacoConfigurationServiceConstructor, [container]), + [ITextModelService.toString()]: new SyncDescriptor(MonacoTextModelServiceConstructor, [container]), + [IContextMenuService.toString()]: new SyncDescriptor(MonacoContextMenuServiceConstructor, [container]), + [IBulkEditService.toString()]: new SyncDescriptor(MonacoBulkEditServiceConstructor, [container]), + [ICommandService.toString()]: new SyncDescriptor(MonacoCommandServiceConstructor, [container]), + [IQuickInputService.toString()]: new SyncDescriptor(MonacoQuickInputImplementationConstructor, [container]), + }); + } +} diff --git a/packages/monaco/src/browser/monaco-keybinding.ts b/packages/monaco/src/browser/monaco-keybinding.ts index ec7e0bcf902d1..cc80a06470d09 100644 --- a/packages/monaco/src/browser/monaco-keybinding.ts +++ b/packages/monaco/src/browser/monaco-keybinding.ts @@ -45,14 +45,14 @@ export class MonacoKeybindingContribution implements KeybindingContribution { registerKeybindings(registry: KeybindingRegistry): void { const defaultKeybindings = KeybindingsRegistry.getDefaultKeybindings(); for (const item of defaultKeybindings) { - const command = this.commands.validate(item.command); - if (command) { + const command = this.commands.validate(item.command || undefined); + if (command && item.keybinding) { const when = (item.when && item.when.serialize()) ?? undefined; let keybinding; if (item.command === MonacoCommands.GO_TO_DEFINITION && !environment.electron.is()) { keybinding = 'ctrlcmd+f11'; } else { - keybinding = MonacoResolvedKeybinding.toKeybinding(item.keybinding); + keybinding = MonacoResolvedKeybinding.toKeybinding(item.keybinding.chords); } registry.registerKeybinding({ command, keybinding, when }); } diff --git a/packages/monaco/src/browser/monaco-quick-input-service.ts b/packages/monaco/src/browser/monaco-quick-input-service.ts index 408d3c09aafb8..580142ad4d418 100644 --- a/packages/monaco/src/browser/monaco-quick-input-service.ts +++ b/packages/monaco/src/browser/monaco-quick-input-service.ts @@ -16,21 +16,21 @@ import { ApplicationShell, - InputBox, InputOptions, KeybindingRegistry, NormalizedQuickInputButton, PickOptions, + InputBox, InputOptions, KeybindingRegistry, PickOptions, QuickInputButton, QuickInputHideReason, QuickInputService, QuickPick, QuickPickItem, - QuickPickItemButtonEvent, QuickPickItemHighlights, QuickPickOptions, QuickPickSeparator, codiconArray + QuickPickItemButtonEvent, QuickPickItemHighlights, QuickPickOptions, QuickPickSeparator } from '@theia/core/lib/browser'; import { injectable, inject, postConstruct } from '@theia/core/shared/inversify'; import { IInputBox, IInputOptions, IKeyMods, IPickOptions, IQuickInput, IQuickInputButton, - IQuickInputService, IQuickNavigateConfiguration, IQuickPick, IQuickPickItem, IQuickPickItemButtonEvent, IQuickPickSeparator, QuickPickInput + IQuickInputService, IQuickNavigateConfiguration, IQuickPick, IQuickPickItem, IQuickPickItemButtonEvent, IQuickPickSeparator, IQuickWidget, QuickPickInput } from '@theia/monaco-editor-core/esm/vs/platform/quickinput/common/quickInput'; -import { IQuickInputOptions, IQuickInputStyles, QuickInputController } from '@theia/monaco-editor-core/esm/vs/base/parts/quickinput/browser/quickInput'; +import { IQuickInputOptions, IQuickInputStyles } from '@theia/monaco-editor-core/esm/vs/platform/quickinput/browser/quickInput'; +import { QuickInputController } from '@theia/monaco-editor-core/esm/vs/platform/quickinput/browser/quickInputController'; import { MonacoResolvedKeybinding } from './monaco-resolved-keybinding'; import { IQuickAccessController } from '@theia/monaco-editor-core/esm/vs/platform/quickinput/common/quickAccess'; import { QuickAccessController } from '@theia/monaco-editor-core/esm/vs/platform/quickinput/browser/quickAccess'; -import { ContextKeyService as VSCodeContextKeyService } from '@theia/monaco-editor-core/esm/vs/platform/contextkey/browser/contextKeyService'; -import { IContextKey } from '@theia/monaco-editor-core/esm/vs/platform/contextkey/common/contextkey'; +import { IContextKey, IContextKeyService } from '@theia/monaco-editor-core/esm/vs/platform/contextkey/common/contextkey'; import { IListOptions, List } from '@theia/monaco-editor-core/esm/vs/base/browser/ui/list/listWidget'; import * as monaco from '@theia/monaco-editor-core'; import { ResolvedKeybinding } from '@theia/monaco-editor-core/esm/vs/base/common/keybindings'; @@ -38,11 +38,18 @@ import { IInstantiationService } from '@theia/monaco-editor-core/esm/vs/platform import { StandaloneServices } from '@theia/monaco-editor-core/esm/vs/editor/standalone/browser/standaloneServices'; import { IMatch } from '@theia/monaco-editor-core/esm/vs/base/common/filters'; import { IListRenderer, IListVirtualDelegate } from '@theia/monaco-editor-core/esm/vs/base/browser/ui/list/list'; -import { Event } from '@theia/core'; +import { CancellationToken, Event } from '@theia/core'; import { MonacoColorRegistry } from './monaco-color-registry'; import { ThemeService } from '@theia/core/lib/browser/theming'; import { IStandaloneThemeService } from '@theia/monaco-editor-core/esm/vs/editor/standalone/common/standaloneTheme'; -import { ThemeIcon } from '@theia/monaco-editor-core/esm/vs/platform/theme/common/themeService'; +import { + activeContrastBorder, asCssVariable, pickerGroupBorder, pickerGroupForeground, quickInputBackground, quickInputForeground, quickInputListFocusBackground, + quickInputListFocusForeground, quickInputListFocusIconForeground, quickInputTitleBackground, widgetBorder, widgetShadow +} from '@theia/monaco-editor-core/esm/vs/platform/theme/common/colorRegistry'; + +import { + defaultButtonStyles, defaultCountBadgeStyles, defaultInputBoxStyles, defaultKeybindingLabelStyles, defaultProgressBarStyles, defaultToggleStyles, getListStyles +} from '@theia/monaco-editor-core/esm/vs/platform/theme/browser/defaultStyles'; // Copied from @vscode/src/vs/base/parts/quickInput/browser/quickInputList.ts export interface IListElement { @@ -62,6 +69,7 @@ export interface IListElement { @injectable() export class MonacoQuickInputImplementation implements IQuickInputService { + declare readonly _serviceBrand: undefined; controller: QuickInputController; @@ -76,9 +84,6 @@ export class MonacoQuickInputImplementation implements IQuickInputService { @inject(ThemeService) protected readonly themeService: ThemeService; - @inject(VSCodeContextKeyService) - protected readonly contextKeyService: VSCodeContextKeyService; - protected container: HTMLElement; private quickInputList: List; @@ -93,25 +98,29 @@ export class MonacoQuickInputImplementation implements IQuickInputService { this.initContainer(); this.initController(); this.quickAccess = new QuickAccessController(this, StandaloneServices.get(IInstantiationService)); - this.inQuickOpen = this.contextKeyService.createKey('inQuickOpen', false); + this.inQuickOpen = StandaloneServices.get(IContextKeyService).createKey('inQuickOpen', false); this.controller.onShow(() => { this.container.style.top = this.shell.mainPanel.node.getBoundingClientRect().top + 'px'; this.inQuickOpen.set(true); }); this.controller.onHide(() => this.inQuickOpen.set(false)); - this.themeService.initialized.then(() => this.controller.applyStyles(this.getStyles())); + this.themeService.initialized.then(() => this.controller.applyStyles(this.computeStyles())); // Hook into the theming service of Monaco to ensure that the updates are ready. - StandaloneServices.get(IStandaloneThemeService).onDidColorThemeChange(() => this.controller.applyStyles(this.getStyles())); + StandaloneServices.get(IStandaloneThemeService).onDidColorThemeChange(() => this.controller.applyStyles(this.computeStyles())); window.addEventListener('resize', () => this.updateLayout()); } setContextKey(key: string | undefined): void { if (key) { - this.contextKeyService.createKey(key, undefined); + StandaloneServices.get(IContextKeyService).createKey(key, undefined); } } + createQuickWidget(): IQuickWidget { + return this.controller.createQuickWidget(); + } + createQuickPick(): IQuickPick { return this.controller.createQuickPick(); } @@ -184,7 +193,7 @@ export class MonacoQuickInputImplementation implements IQuickInputService { } private initController(): void { - this.controller = new QuickInputController(this.getOptions()); + this.controller = new QuickInputController(this.getOptions(), StandaloneServices.get(IStandaloneThemeService)); this.updateLayout(); } @@ -202,73 +211,53 @@ export class MonacoQuickInputImplementation implements IQuickInputService { const options: IQuickInputOptions = { idPrefix: 'quickInput_', container: this.container, - styles: { widget: {}, list: {}, inputBox: {}, countBadge: {}, button: {}, progressBar: {}, keybindingLabel: {}, }, + styles: this.computeStyles(), ignoreFocusOut: () => false, - isScreenReaderOptimized: () => false, // TODO change to true once support is added. backKeybindingLabel: () => undefined, setContextKey: (id?: string) => this.setContextKey(id), returnFocus: () => this.container.focus(), createList: ( user: string, container: HTMLElement, delegate: IListVirtualDelegate, renderers: IListRenderer[], listOptions: IListOptions ): List => this.quickInputList = new List(user, container, delegate, renderers, listOptions), + linkOpenerDelegate: () => { + // @monaco-uplift: not sure what to do here + } }; return options; } // @monaco-uplift // Keep the styles up to date with https://github.com/microsoft/vscode/blob/7888ff3a6b104e9e2e3d0f7890ca92dd0828215f/src/vs/platform/quickinput/browser/quickInput.ts#L171. - private getStyles(): IQuickInputStyles { + private computeStyles(): IQuickInputStyles { return { widget: { - quickInputBackground: this.colorRegistry.getColor('quickInput.background'), - quickInputForeground: this.colorRegistry.getColor('quickInput.foreground'), - quickInputTitleBackground: this.colorRegistry.getColor('quickInputTitle.background') - }, - list: { - listBackground: this.colorRegistry.getColor('quickInput.background'), - listInactiveFocusForeground: this.colorRegistry.getColor('quickInputList.focusForeground'), - listInactiveSelectionIconForeground: this.colorRegistry.getColor('quickInputList.focusIconForeground'), - listInactiveFocusBackground: this.colorRegistry.getColor('quickInputList.focusBackground'), - listFocusOutline: this.colorRegistry.getColor('activeContrastBorder'), - listInactiveFocusOutline: this.colorRegistry.getColor('activeContrastBorder'), - pickerGroupBorder: this.colorRegistry.getColor('pickerGroup.border'), - pickerGroupForeground: this.colorRegistry.getColor('pickerGroup.foreground') - }, - inputBox: { - inputForeground: this.colorRegistry.getColor('inputForeground'), - inputBackground: this.colorRegistry.getColor('inputBackground'), - inputBorder: this.colorRegistry.getColor('inputBorder'), - inputValidationInfoBackground: this.colorRegistry.getColor('inputValidation.infoBackground'), - inputValidationInfoForeground: this.colorRegistry.getColor('inputValidation.infoForeground'), - inputValidationInfoBorder: this.colorRegistry.getColor('inputValidation.infoBorder'), - inputValidationWarningBackground: this.colorRegistry.getColor('inputValidation.warningBackground'), - inputValidationWarningForeground: this.colorRegistry.getColor('inputValidation.warningForeground'), - inputValidationWarningBorder: this.colorRegistry.getColor('inputValidation.warningBorder'), - inputValidationErrorBackground: this.colorRegistry.getColor('inputValidation.errorBackground'), - inputValidationErrorForeground: this.colorRegistry.getColor('inputValidation.errorForeground'), - inputValidationErrorBorder: this.colorRegistry.getColor('inputValidation.errorBorder'), - }, - countBadge: { - badgeBackground: this.colorRegistry.getColor('badge.background'), - badgeForeground: this.colorRegistry.getColor('badge.foreground'), - badgeBorder: this.colorRegistry.getColor('contrastBorder') - }, - button: { - buttonForeground: this.colorRegistry.getColor('button.foreground'), - buttonBackground: this.colorRegistry.getColor('button.background'), - buttonHoverBackground: this.colorRegistry.getColor('button.hoverBackground'), - buttonBorder: this.colorRegistry.getColor('contrastBorder') - }, - progressBar: { - progressBarBackground: this.colorRegistry.getColor('progressBar.background') - }, - keybindingLabel: { - keybindingLabelBackground: this.colorRegistry.getColor('keybindingLabe.background'), - keybindingLabelForeground: this.colorRegistry.getColor('keybindingLabel.foreground'), - keybindingLabelBorder: this.colorRegistry.getColor('keybindingLabel.border'), - keybindingLabelBottomBorder: this.colorRegistry.getColor('keybindingLabel.bottomBorder'), - keybindingLabelShadow: this.colorRegistry.getColor('widget.shadow') + quickInputBackground: asCssVariable(quickInputBackground), + quickInputForeground: asCssVariable(quickInputForeground), + quickInputTitleBackground: asCssVariable(quickInputTitleBackground), + widgetBorder: asCssVariable(widgetBorder), + widgetShadow: asCssVariable(widgetShadow), }, + inputBox: defaultInputBoxStyles, + toggle: defaultToggleStyles, + countBadge: defaultCountBadgeStyles, + button: defaultButtonStyles, + progressBar: defaultProgressBarStyles, + keybindingLabel: defaultKeybindingLabelStyles, + list: getListStyles({ + listBackground: quickInputBackground, + listFocusBackground: quickInputListFocusBackground, + listFocusForeground: quickInputListFocusForeground, + // Look like focused when inactive. + listInactiveFocusForeground: quickInputListFocusForeground, + listInactiveSelectionIconForeground: quickInputListFocusIconForeground, + listInactiveFocusBackground: quickInputListFocusBackground, + listFocusOutline: activeContrastBorder, + listInactiveFocusOutline: activeContrastBorder, + }), + pickerGroup: { + pickerGroupBorder: asCssVariable(pickerGroupBorder), + pickerGroupForeground: asCssVariable(pickerGroupForeground), + } }; } } @@ -282,7 +271,8 @@ export class MonacoQuickInputService implements QuickInputService { protected readonly keybindingRegistry: KeybindingRegistry; get backButton(): QuickInputButton { - return this.monacoService.backButton; + // need to cast because of vscode issue https://github.com/microsoft/vscode/issues/190584 + return this.monacoService.backButton as QuickInputButton; } get onShow(): Event { return this.monacoService.onShow; } @@ -293,7 +283,8 @@ export class MonacoQuickInputService implements QuickInputService { } createInputBox(): InputBox { - return this.monacoService.createInputBox(); + // need to cast because of vscode issue https://github.com/microsoft/vscode/issues/190584 + return this.monacoService.createInputBox() as InputBox; } input(options?: InputOptions, token?: monaco.CancellationToken): Promise { @@ -309,39 +300,9 @@ export class MonacoQuickInputService implements QuickInputService { } async pick = PickOptions>( - picks: Promise[]> | QuickPickInput[], options?: O, token?: monaco.CancellationToken - ): Promise<(O extends { canPickMany: true; } ? T[] : T) | undefined> { - type M = T & { buttons?: NormalizedQuickInputButton[] }; - type R = (O extends { canPickMany: true; } ? T[] : T); - - const monacoPicks: Promise[]> = new Promise(async resolve => { - const updatedPicks = (await picks).map(pick => { - if (pick.type !== 'separator') { - const icon = pick.iconPath; - // @monaco-uplift - // Other kind of icons (URI and URI dark/light) shall be supported once monaco editor has been upgraded to at least 1.81. - // see https://github.com/eclipse-theia/theia/pull/12945#issue-1913645228 - if (ThemeIcon.isThemeIcon(icon)) { - const codicon = codiconArray(icon.id); - if (pick.iconClasses) { - pick.iconClasses.push(...codicon); - } else { - pick.iconClasses = codicon; - } - } - pick.buttons &&= pick.buttons.map(QuickInputButton.normalize); - } - return pick as M; - }); - resolve(updatedPicks); - }); - const monacoOptions = options as IPickOptions; - const picked = await this.monacoService.pick(monacoPicks, monacoOptions, token); - if (!picked) { return picked; } - if (options?.canPickMany) { - return (Array.isArray(picked) ? picked : [picked]) as R; - } - return Array.isArray(picked) ? picked[0] : picked; + picks: Promise[]> | QuickPickInput[], options?: O, token?: CancellationToken + ): Promise { + return this.monacoService.pick(picks, options, token); } showQuickPick(items: Array, options?: QuickPickOptions): Promise { @@ -394,7 +355,8 @@ export class MonacoQuickInputService implements QuickInputService { }); wrapped.onDidTriggerButton((button: IQuickInputButton) => { if (options.onDidTriggerButton) { - options.onDidTriggerButton(button); + // need to cast because of vscode issue https://github.com/microsoft/vscode/issues/190584 + options.onDidTriggerButton(button as QuickInputButton); } }); wrapped.onDidTriggerItemButton((event: QuickPickItemButtonEvent) => { @@ -577,7 +539,14 @@ class MonacoQuickPick extends MonacoQuickInput implemen } get items(): readonly (T | QuickPickSeparator)[] { - return this.wrapped.items.map(item => QuickPickSeparator.is(item) ? item : item.item); + // need to cast because of vscode issue https://github.com/microsoft/vscode/issues/190584 + return this.wrapped.items.map(item => { + if (item instanceof MonacoQuickPickItem) { + return item.item; + } else { + return item; + } + }); } set items(itemList: readonly (T | QuickPickSeparator)[]) { @@ -610,12 +579,14 @@ class MonacoQuickPick extends MonacoQuickInput implemen readonly onDidAccept: Event<{ inBackground: boolean }> = this.wrapped.onDidAccept; readonly onDidChangeValue: Event = this.wrapped.onDidChangeValue; - readonly onDidTriggerButton: Event = this.wrapped.onDidTriggerButton; + + // need to cast because of vscode issue https://github.com/microsoft/vscode/issues/190584 + readonly onDidTriggerButton: Event = this.wrapped.onDidTriggerButton as Event; readonly onDidTriggerItemButton: Event> = Event.map(this.wrapped.onDidTriggerItemButton, (evt: IQuickPickItemButtonEvent>) => ({ item: evt.item.item, button: evt.button - })); + })) as Event>; readonly onDidChangeActive: Event = Event.map( this.wrapped.onDidChangeActive, (items: MonacoQuickPickItem[]) => items.map(item => item.item)); @@ -630,7 +601,7 @@ class MonacoQuickPick extends MonacoQuickInput implemen const monacoReferences: MonacoQuickPickItem[] = []; for (const item of items) { for (const wrappedItem of source) { - if (!QuickPickSeparator.is(wrappedItem) && wrappedItem.item === item) { + if (wrappedItem instanceof MonacoQuickPickItem && wrappedItem.item === item) { monacoReferences.push(wrappedItem); } } @@ -663,7 +634,7 @@ export class MonacoQuickPickItem implements IQuickPickI this.detail = item.detail; this.keybinding = item.keySequence ? new MonacoResolvedKeybinding(item.keySequence, kbRegistry) : undefined; this.iconClasses = item.iconClasses; - this.buttons = item.buttons?.map(QuickInputButton.normalize); + this.buttons = item.buttons; this.alwaysShow = item.alwaysShow; this.highlights = item.highlights; } diff --git a/packages/monaco/src/browser/monaco-resolved-keybinding.ts b/packages/monaco/src/browser/monaco-resolved-keybinding.ts index 526af0b90c390..347b85d96b373 100644 --- a/packages/monaco/src/browser/monaco-resolved-keybinding.ts +++ b/packages/monaco/src/browser/monaco-resolved-keybinding.ts @@ -16,7 +16,7 @@ import { KeyCode as MonacoKeyCode } from '@theia/monaco-editor-core/esm/vs/base/common/keyCodes'; import { - ChordKeybinding, KeybindingModifier, ResolvedKeybinding, ResolvedKeybindingPart, ScanCodeBinding, SimpleKeybinding + ResolvedKeybinding, ResolvedChord, SingleModifierChord, KeyCodeChord, Chord } from '@theia/monaco-editor-core/esm/vs/base/common/keybindings'; import { ElectronAcceleratorLabelProvider, UILabelProvider, UserSettingsLabelProvider } from '@theia/monaco-editor-core/esm/vs/base/common/keybindingLabels'; import { USLayoutResolvedKeybinding } from '@theia/monaco-editor-core/esm/vs/platform/keybinding/common/usLayoutResolvedKeybinding'; @@ -28,15 +28,15 @@ import { KEY_CODE_MAP } from './monaco-keycode-map'; export class MonacoResolvedKeybinding extends ResolvedKeybinding { - protected readonly parts: ResolvedKeybindingPart[]; + protected readonly chords: ResolvedChord[]; constructor(protected readonly keySequence: KeySequence, keybindingService: KeybindingRegistry) { super(); - this.parts = keySequence.map(keyCode => { + this.chords = keySequence.map(keyCode => { // eslint-disable-next-line no-null/no-null const keyLabel = keyCode.key ? keybindingService.acceleratorForKey(keyCode.key) : null; const keyAriaLabel = keyLabel; - return new ResolvedKeybindingPart( + return new ResolvedChord( keyCode.ctrl, keyCode.shift, keyCode.alt, @@ -48,43 +48,43 @@ export class MonacoResolvedKeybinding extends ResolvedKeybinding { } getLabel(): string | null { - return UILabelProvider.toLabel(MonacoPlatform.OS, this.parts, p => p.keyLabel); + return UILabelProvider.toLabel(MonacoPlatform.OS, this.chords, p => p.keyLabel); } getAriaLabel(): string | null { - return UILabelProvider.toLabel(MonacoPlatform.OS, this.parts, p => p.keyAriaLabel); + return UILabelProvider.toLabel(MonacoPlatform.OS, this.chords, p => p.keyAriaLabel); } getElectronAccelerator(): string | null { - if (this.isChord()) { + if (this.hasMultipleChords()) { // Electron cannot handle chords // eslint-disable-next-line no-null/no-null return null; } - return ElectronAcceleratorLabelProvider.toLabel(MonacoPlatform.OS, this.parts, p => p.keyLabel); + return ElectronAcceleratorLabelProvider.toLabel(MonacoPlatform.OS, this.chords, p => p.keyLabel); } getUserSettingsLabel(): string | null { - return UserSettingsLabelProvider.toLabel(MonacoPlatform.OS, this.parts, p => p.keyLabel); + return UserSettingsLabelProvider.toLabel(MonacoPlatform.OS, this.chords, p => p.keyLabel); } isWYSIWYG(): boolean { return true; } - isChord(): boolean { - return this.parts.length > 1; + hasMultipleChords(): boolean { + return this.chords.length > 1; } - getDispatchParts(): (string | null)[] { + getDispatchChords(): (string | null)[] { return this.keySequence.map(keyCode => USLayoutResolvedKeybinding.getDispatchStr(this.toKeybinding(keyCode))); } - getSingleModifierDispatchParts(): (KeybindingModifier | null)[] { + getSingleModifierDispatchChords(): (SingleModifierChord | null)[] { return this.keySequence.map(keybinding => this.getSingleModifierDispatchPart(keybinding)); } - protected getSingleModifierDispatchPart(code: KeyCode): KeybindingModifier | null { + protected getSingleModifierDispatchPart(code: KeyCode): SingleModifierChord | null { if (code.key?.keyCode === undefined) { return null; // eslint-disable-line no-null/no-null } @@ -103,8 +103,8 @@ export class MonacoResolvedKeybinding extends ResolvedKeybinding { return null; // eslint-disable-line no-null/no-null } - private toKeybinding(keyCode: KeyCode): SimpleKeybinding { - return new SimpleKeybinding( + private toKeybinding(keyCode: KeyCode): KeyCodeChord { + return new KeyCodeChord( keyCode.ctrl, keyCode.shift, keyCode.alt, @@ -113,16 +113,16 @@ export class MonacoResolvedKeybinding extends ResolvedKeybinding { ); } - public getParts(): ResolvedKeybindingPart[] { - return this.parts; + public getChords(): ResolvedChord[] { + return this.chords; } - static toKeybinding(keybindings: Array): string { + static toKeybinding(keybindings: Array): string { return keybindings.map(binding => this.keyCode(binding)).join(' '); } - static keyCode(keybinding: SimpleKeybinding | ScanCodeBinding): KeyCode { - const keyCode = keybinding instanceof SimpleKeybinding ? keybinding.keyCode : USLayoutResolvedKeybinding['_scanCodeToKeyCode'](keybinding.scanCode); + static keyCode(keybinding: Chord): KeyCode { + const keyCode = keybinding instanceof KeyCodeChord ? keybinding.keyCode : USLayoutResolvedKeybinding['_scanCodeToKeyCode'](keybinding.scanCode); const sequence: Keystroke = { first: Key.getKey(this.monaco2BrowserKeyCode(keyCode & 0xff)), modifiers: [] @@ -146,8 +146,8 @@ export class MonacoResolvedKeybinding extends ResolvedKeybinding { return KeyCode.createKeyCode(sequence); } - static keySequence(keybinding: ChordKeybinding): KeySequence { - return keybinding.parts.map(part => this.keyCode(part)); + static keySequence(keybinding: Chord[]): KeySequence { + return keybinding.map(part => this.keyCode(part)); } private static monaco2BrowserKeyCode(keyCode: MonacoKeyCode): number { diff --git a/packages/monaco/src/browser/monaco-text-model-service.ts b/packages/monaco/src/browser/monaco-text-model-service.ts index d4440b4d80946..bd1ecf07c5a97 100644 --- a/packages/monaco/src/browser/monaco-text-model-service.ts +++ b/packages/monaco/src/browser/monaco-text-model-service.ts @@ -194,6 +194,6 @@ export class MonacoTextModelService implements ITextModelService { } canHandleResource(resource: monaco.Uri): boolean { - return this.fileService.canHandleResource(new URI(resource)); + return this.fileService.canHandleResource(URI.fromComponents(resource)); } } diff --git a/packages/monaco/src/browser/monaco-workspace.ts b/packages/monaco/src/browser/monaco-workspace.ts index b832a74b89a0a..394c1b52a368e 100644 --- a/packages/monaco/src/browser/monaco-workspace.ts +++ b/packages/monaco/src/browser/monaco-workspace.ts @@ -230,7 +230,7 @@ export class MonacoWorkspace { }); } - async applyBulkEdit(edits: ResourceEdit[], options?: IBulkEditOptions): Promise { + async applyBulkEdit(edits: ResourceEdit[], options?: IBulkEditOptions): Promise { try { let totalEdits = 0; let totalFiles = 0; @@ -264,12 +264,12 @@ export class MonacoWorkspace { } const ariaSummary = this.getAriaSummary(totalEdits, totalFiles); - return { ariaSummary, success: true }; + return { ariaSummary, isApplied: true }; } catch (e) { console.error('Failed to apply Resource edits:', e); return { ariaSummary: `Error applying Resource edits: ${e.toString()}`, - success: false + isApplied: false }; } } @@ -369,27 +369,27 @@ export class MonacoWorkspace { const options = edit.options || {}; if (edit.newResource && edit.oldResource) { // rename - if (options.overwrite === undefined && options.ignoreIfExists && await this.fileService.exists(new URI(edit.newResource))) { + if (options.overwrite === undefined && options.ignoreIfExists && await this.fileService.exists(URI.fromComponents(edit.newResource))) { return; // not overwriting, but ignoring, and the target file exists } - await this.fileService.move(new URI(edit.oldResource), new URI(edit.newResource), { overwrite: options.overwrite }); + await this.fileService.move(URI.fromComponents(edit.oldResource), URI.fromComponents(edit.newResource), { overwrite: options.overwrite }); } else if (!edit.newResource && edit.oldResource) { // delete file - if (await this.fileService.exists(new URI(edit.oldResource))) { + if (await this.fileService.exists(URI.fromComponents(edit.oldResource))) { let useTrash = this.filePreferences['files.enableTrash']; - if (useTrash && !(this.fileService.hasCapability(new URI(edit.oldResource), FileSystemProviderCapabilities.Trash))) { + if (useTrash && !(this.fileService.hasCapability(URI.fromComponents(edit.oldResource), FileSystemProviderCapabilities.Trash))) { useTrash = false; // not supported by provider } - await this.fileService.delete(new URI(edit.oldResource), { useTrash, recursive: options.recursive }); + await this.fileService.delete(URI.fromComponents(edit.oldResource), { useTrash, recursive: options.recursive }); } else if (!options.ignoreIfNotExists) { throw new Error(`${edit.oldResource} does not exist and can not be deleted`); } } else if (edit.newResource && !edit.oldResource) { // create file - if (options.overwrite === undefined && options.ignoreIfExists && await this.fileService.exists(new URI(edit.newResource))) { + if (options.overwrite === undefined && options.ignoreIfExists && await this.fileService.exists(URI.fromComponents(edit.newResource))) { return; // not overwriting, but ignoring, and the target file exists } - await this.fileService.create(new URI(edit.newResource), undefined, { overwrite: options.overwrite }); + await this.fileService.create(URI.fromComponents(edit.newResource), undefined, { overwrite: options.overwrite }); } } } diff --git a/packages/monaco/src/browser/simple-monaco-editor.ts b/packages/monaco/src/browser/simple-monaco-editor.ts index 61096e5437796..eda4874ada840 100644 --- a/packages/monaco/src/browser/simple-monaco-editor.ts +++ b/packages/monaco/src/browser/simple-monaco-editor.ts @@ -136,7 +136,7 @@ export class SimpleMonacoEditor extends MonacoEditorServices implements Disposab } protected getInstantiatorWithOverrides(override?: EditorServiceOverrides): IInstantiationService { - const instantiator = StandaloneServices.initialize({}); + const instantiator = StandaloneServices.get(IInstantiationService); if (override) { const overrideServices = new ServiceCollection(...override); return instantiator.createChild(overrideServices); diff --git a/packages/monaco/src/browser/textmate/monaco-textmate-service.ts b/packages/monaco/src/browser/textmate/monaco-textmate-service.ts index 0f0eeca3b923a..2f4b8220e62d0 100644 --- a/packages/monaco/src/browser/textmate/monaco-textmate-service.ts +++ b/packages/monaco/src/browser/textmate/monaco-textmate-service.ts @@ -178,7 +178,7 @@ export class MonacoTextmateService implements FrontendApplicationContribution { protected waitForLanguage(language: string, cb: () => {}): Disposable { const languageService = StandaloneServices.get(ILanguageService) as LanguageService; - if (languageService['_encounteredLanguages'].has(language)) { + if (languageService['_requestedBasicLanguages'].has(language)) { cb(); return Disposable.NULL; } diff --git a/packages/notebook/src/browser/service/notebook-cell-context-manager.ts b/packages/notebook/src/browser/service/notebook-cell-context-manager.ts index 200e3e2f4dff9..d49a2bc861cd1 100644 --- a/packages/notebook/src/browser/service/notebook-cell-context-manager.ts +++ b/packages/notebook/src/browser/service/notebook-cell-context-manager.ts @@ -67,7 +67,6 @@ export class NotebookCellContextManager implements NotebookCellContextManager, D dispose(): void { this.toDispose.dispose(); - this.currentStore?.dispose(); this.onDidChangeContextEmitter.dispose(); } } diff --git a/packages/output/package.json b/packages/output/package.json index fa994e74ac7f5..000281e99cabd 100644 --- a/packages/output/package.json +++ b/packages/output/package.json @@ -6,7 +6,7 @@ "@theia/core": "1.46.0", "@theia/editor": "1.46.0", "@theia/monaco": "1.46.0", - "@theia/monaco-editor-core": "1.72.3", + "@theia/monaco-editor-core": "1.83.101", "@types/p-queue": "^2.3.1", "p-queue": "^2.4.2" }, @@ -48,4 +48,4 @@ "nyc": { "extends": "../../configs/nyc.json" } -} +} \ No newline at end of file diff --git a/packages/output/src/browser/output-editor-factory.ts b/packages/output/src/browser/output-editor-factory.ts index 4c1706ec68e81..c78803da024a7 100644 --- a/packages/output/src/browser/output-editor-factory.ts +++ b/packages/output/src/browser/output-editor-factory.ts @@ -35,10 +35,10 @@ export class OutputEditorFactory implements MonacoEditorFactory { readonly scheme: string = OutputUri.SCHEME; - create(model: MonacoEditorModel, defaultsOptions: MonacoEditor.IOptions, defaultOverrides: EditorServiceOverrides): MonacoEditor { + create(model: MonacoEditorModel, defaultsOptions: MonacoEditor.IOptions): MonacoEditor { const uri = new URI(model.uri); const options = this.createOptions(model, defaultsOptions); - const overrides = this.createOverrides(model, defaultOverrides); + const overrides = this.createOverrides(model); return new MonacoEditor(uri, model, document.createElement('div'), this.services, options, overrides); } @@ -62,13 +62,7 @@ export class OutputEditorFactory implements MonacoEditorFactory { }; } - protected *createOverrides(model: MonacoEditorModel, defaultOverrides: EditorServiceOverrides): EditorServiceOverrides { + protected *createOverrides(model: MonacoEditorModel): EditorServiceOverrides { yield [IContextMenuService, this.contextMenuService]; - for (const [identifier, provider] of defaultOverrides) { - if (identifier !== IContextMenuService) { - yield [identifier, provider]; - } - } } - } diff --git a/packages/plugin-ext-vscode/package.json b/packages/plugin-ext-vscode/package.json index 8958523bb232d..ccdd5870dabd6 100644 --- a/packages/plugin-ext-vscode/package.json +++ b/packages/plugin-ext-vscode/package.json @@ -8,7 +8,7 @@ "@theia/editor": "1.46.0", "@theia/filesystem": "1.46.0", "@theia/monaco": "1.46.0", - "@theia/monaco-editor-core": "1.72.3", + "@theia/monaco-editor-core": "1.83.101", "@theia/navigator": "1.46.0", "@theia/plugin": "1.46.0", "@theia/plugin-ext": "1.46.0", @@ -58,4 +58,4 @@ "nyc": { "extends": "../../configs/nyc.json" } -} +} \ No newline at end of file diff --git a/packages/plugin-ext/package.json b/packages/plugin-ext/package.json index bdaa99e2df2d5..f1ccdb48d1986 100644 --- a/packages/plugin-ext/package.json +++ b/packages/plugin-ext/package.json @@ -17,7 +17,7 @@ "@theia/markers": "1.46.0", "@theia/messages": "1.46.0", "@theia/monaco": "1.46.0", - "@theia/monaco-editor-core": "1.72.3", + "@theia/monaco-editor-core": "1.83.101", "@theia/navigator": "1.46.0", "@theia/notebook": "1.46.0", "@theia/output": "1.46.0", @@ -97,4 +97,4 @@ "nyc": { "extends": "../../configs/nyc.json" } -} +} \ No newline at end of file diff --git a/packages/plugin-ext/src/common/plugin-api-rpc-model.ts b/packages/plugin-ext/src/common/plugin-api-rpc-model.ts index 2c3ed04df81b9..38fb3fbffec78 100644 --- a/packages/plugin-ext/src/common/plugin-api-rpc-model.ts +++ b/packages/plugin-ext/src/common/plugin-api-rpc-model.ts @@ -335,12 +335,12 @@ export interface DocumentDropEditProviderMetadata { } export interface DataTransferFileDTO { + readonly id: string; readonly name: string; readonly uri?: UriComponents; } export interface DataTransferItemDTO { - readonly id: string; readonly asString: string; readonly fileData: DataTransferFileDTO | undefined; readonly uriListData?: ReadonlyArray; diff --git a/packages/plugin-ext/src/common/plugin-api-rpc.ts b/packages/plugin-ext/src/common/plugin-api-rpc.ts index 0364b384cf4a0..30bd564c9a560 100644 --- a/packages/plugin-ext/src/common/plugin-api-rpc.ts +++ b/packages/plugin-ext/src/common/plugin-api-rpc.ts @@ -114,7 +114,7 @@ import type { import { SerializableEnvironmentVariableCollection } from '@theia/terminal/lib/common/shell-terminal-protocol'; import { ThemeType } from '@theia/core/lib/common/theme'; import { Disposable } from '@theia/core/lib/common/disposable'; -import { isString, isObject, PickOptions, QuickInputButtonHandle } from '@theia/core/lib/common'; +import { isString, isObject, QuickInputButtonHandle } from '@theia/core/lib/common'; import { Severity } from '@theia/core/lib/common/severity'; import { DebugConfiguration, DebugSessionOptions } from '@theia/debug/lib/common/debug-configuration'; import * as notebookCommon from '@theia/notebook/lib/common'; @@ -482,8 +482,6 @@ export interface StatusBarMessageRegistryMain { $dispose(id: string): void; } -export type Item = string | theia.QuickPickItem; - export interface QuickOpenExt { $onItemSelected(handle: number): void; $validateInput(input: string): Promise | undefined; @@ -501,7 +499,6 @@ export interface QuickOpenExt { token?: theia.CancellationToken): Promise | undefined>; showQuickPick(itemsOrItemsPromise: string[] | Promise, options?: theia.QuickPickOptions, token?: theia.CancellationToken): Promise; showQuickPick(itemsOrItemsPromise: Array | Promise>, options?: theia.QuickPickOptions, token?: theia.CancellationToken): Promise; - showQuickPick(itemsOrItemsPromise: Item[] | Promise, options?: theia.QuickPickOptions, token?: theia.CancellationToken): Promise; showInput(options?: theia.InputBoxOptions, token?: theia.CancellationToken): PromiseLike; // showWorkspaceFolderPick(options?: theia.WorkspaceFolderPickOptions, token?: theia.CancellationToken): Promise @@ -621,22 +618,36 @@ export interface WorkspaceFolderPickOptionsMain { ignoreFocusOut?: boolean; } -export type TransferQuickPickItems = TransferQuickPickItemValue | TransferQuickPickSeparator; - -export interface TransferQuickPickItemValue extends theia.QuickPickItem { +export interface TransferQuickPickItem { handle: number; - type?: 'item' + kind: 'item' | 'separator', + label: string; + iconPath?: UriComponents | { light: UriComponents; dark: UriComponents } | ThemeIcon; + description?: string; + detail?: string; + picked?: boolean; + alwaysShow?: boolean; + buttons?: readonly TransferQuickInputButton[]; } -export interface TransferQuickPickSeparator extends theia.QuickPickItem { - handle: number; - type: 'separator'; +export interface TransferQuickPickOptions { + title?: string; + placeHolder?: string; + matchOnDescription?: boolean; + matchOnDetail?: boolean; + matchOnLabel?: boolean; + autoFocusOnList?: boolean; + ignoreFocusLost?: boolean; + canPickMany?: boolean; + contextKey?: string; + activeItem?: Promise | T; + onDidFocus?: (entry: T) => void; } -export interface TransferQuickInputButton extends theia.QuickInputButton { - iconPath: theia.Uri | { light: theia.Uri, dark: theia.Uri } | ThemeIcon; - iconClass?: string; +export interface TransferQuickInputButton { handle?: number; + readonly iconPath: UriComponents | { light: UriComponents; dark: UriComponents } | ThemeIcon; + readonly tooltip?: string | undefined; } export type TransferQuickInput = TransferQuickPick | TransferInputBox; @@ -655,7 +666,7 @@ export interface TransferQuickPick extends BaseTransferQuickInput { value?: string; placeholder?: string; buttons?: TransferQuickInputButton[]; - items?: TransferQuickPickItems[]; + items?: TransferQuickPickItem[]; activeItems?: ReadonlyArray; selectedItems?: ReadonlyArray; canSelectMany?: boolean; @@ -685,8 +696,8 @@ export interface IInputBoxOptions { } export interface QuickOpenMain { - $show(instance: number, options: PickOptions, token: CancellationToken): Promise; - $setItems(instance: number, items: TransferQuickPickItems[]): Promise; + $show(instance: number, options: TransferQuickPickOptions, token: CancellationToken): Promise; + $setItems(instance: number, items: TransferQuickPickItem[]): Promise; $setError(instance: number, error: Error): Promise; $input(options: theia.InputBoxOptions, validateInput: boolean, token: CancellationToken): Promise; $createOrUpdate(params: TransferQuickInput): Promise; diff --git a/packages/plugin-ext/src/hosted/browser/hosted-plugin.ts b/packages/plugin-ext/src/hosted/browser/hosted-plugin.ts index 64e35536a529c..c298d7df1195b 100644 --- a/packages/plugin-ext/src/hosted/browser/hosted-plugin.ts +++ b/packages/plugin-ext/src/hosted/browser/hosted-plugin.ts @@ -189,10 +189,10 @@ export class HostedPluginSupport extends AbstractHostedPluginSupport this.updateStoragePath()); const languageService = (StandaloneServices.get(ILanguageService) as LanguageService); - for (const language of languageService['_encounteredLanguages'] as Set) { + for (const language of languageService['_requestedBasicLanguages'] as Set) { this.activateByLanguage(language); } - languageService.onDidEncounterLanguage(language => this.activateByLanguage(language)); + languageService.onDidRequestBasicLanguageFeatures(language => this.activateByLanguage(language)); this.commands.onWillExecuteCommand(event => this.ensureCommandHandlerRegistration(event)); this.debugSessionManager.onWillStartDebugSession(event => this.ensureDebugActivation(event)); this.debugSessionManager.onWillResolveDebugConfiguration(event => this.ensureDebugActivation(event, 'onDebugResolve', event.debugType)); diff --git a/packages/plugin-ext/src/main/browser/comments/comments-contribution.ts b/packages/plugin-ext/src/main/browser/comments/comments-contribution.ts index a26c302bcf97a..ee144563b105d 100644 --- a/packages/plugin-ext/src/main/browser/comments/comments-contribution.ts +++ b/packages/plugin-ext/src/main/browser/comments/comments-contribution.ts @@ -26,6 +26,7 @@ import { CommandRegistry, DisposableCollection, MenuModelRegistry } from '@theia import { URI } from '@theia/core/shared/vscode-uri'; import { CommentsContextKeyService } from './comments-context-key-service'; import { ContextKeyService } from '@theia/core/lib/browser/context-key-service'; +import { Uri } from '@theia/plugin'; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. @@ -64,14 +65,16 @@ export class CommentsContribution { if (editor instanceof MonacoDiffEditor) { const originalEditorModel = editor.diffEditor.getOriginalEditor().getModel(); if (originalEditorModel) { - const originalComments = await this.commentService.getComments(originalEditorModel.uri); + // need to cast because of vscode issue https://github.com/microsoft/vscode/issues/190584 + const originalComments = await this.commentService.getComments(originalEditorModel.uri as Uri); if (originalComments) { this.rangeDecorator.update(editor.diffEditor.getOriginalEditor(), originalComments.filter(c => !!c)); } } const modifiedEditorModel = editor.diffEditor.getModifiedEditor().getModel(); if (modifiedEditorModel) { - const modifiedComments = await this.commentService.getComments(modifiedEditorModel.uri); + // need to cast because of vscode issue https://github.com/microsoft/vscode/issues/190584 + const modifiedComments = await this.commentService.getComments(modifiedEditorModel.uri as Uri); if (modifiedComments) { this.rangeDecorator.update(editor.diffEditor.getModifiedEditor(), modifiedComments.filter(c => !!c)); } @@ -164,7 +167,8 @@ export class CommentsContribution { const editorModel = this.editor && this.editor.getModel(); const editorURI = this.editor && editorModel && editorModel.uri; if (editorURI) { - const comments = await this.commentService.getComments(editorURI); + // need to cast because of vscode issue https://github.com/microsoft/vscode/issues/190584 + const comments = await this.commentService.getComments(editorURI as Uri); this.setComments(comments.filter(c => !!c)); } } diff --git a/packages/plugin-ext/src/main/browser/data-transfer/data-transfer-type-converters.ts b/packages/plugin-ext/src/main/browser/data-transfer/data-transfer-type-converters.ts index b3c5c175ed473..c2e281e31f816 100644 --- a/packages/plugin-ext/src/main/browser/data-transfer/data-transfer-type-converters.ts +++ b/packages/plugin-ext/src/main/browser/data-transfer/data-transfer-type-converters.ts @@ -14,7 +14,7 @@ // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 // ***************************************************************************** -import { IDataTransferItem, VSDataTransfer } from '@theia/monaco-editor-core/esm/vs/base/common/dataTransfer'; +import { IDataTransferItem, IReadonlyVSDataTransfer } from '@theia/monaco-editor-core/esm/vs/base/common/dataTransfer'; import { DataTransferDTO, DataTransferItemDTO } from '../../../common/plugin-api-rpc-model'; import { URI } from '../../../plugin/types-impl'; @@ -24,7 +24,6 @@ export namespace DataTransferItem { if (mime === 'text/uri-list') { return { - id: item.id, asString: '', fileData: undefined, uriListData: serializeUriList(stringValue), @@ -33,9 +32,8 @@ export namespace DataTransferItem { const fileValue = item.asFile(); return { - id: item.id, asString: stringValue, - fileData: fileValue ? { name: fileValue.name, uri: fileValue.uri } : undefined, + fileData: fileValue ? { id: fileValue.id, name: fileValue.name, uri: fileValue.uri } : undefined, }; } @@ -57,10 +55,10 @@ export namespace DataTransferItem { } export namespace DataTransfer { - export async function toDataTransferDTO(value: VSDataTransfer): Promise { + export async function toDataTransferDTO(value: IReadonlyVSDataTransfer): Promise { return { items: await Promise.all( - Array.from(value.entries()) + Array.from(value) .map( async ([mime, item]) => [mime, await DataTransferItem.from(mime, item)] ) diff --git a/packages/plugin-ext/src/main/browser/languages-main.ts b/packages/plugin-ext/src/main/browser/languages-main.ts index 6b6dcbbe6d5fb..99347fd5356d5 100644 --- a/packages/plugin-ext/src/main/browser/languages-main.ts +++ b/packages/plugin-ext/src/main/browser/languages-main.ts @@ -42,7 +42,7 @@ import { injectable, inject } from '@theia/core/shared/inversify'; import { SerializedDocumentFilter, MarkerData, Range, RelatedInformation, MarkerSeverity, DocumentLink, WorkspaceSymbolParams, CodeAction, CompletionDto, - CodeActionProviderDocumentation, InlayHint, InlayHintLabelPart, CodeActionContext, DocumentDropEditProviderMetadata + CodeActionProviderDocumentation, InlayHint, InlayHintLabelPart, CodeActionContext, DocumentDropEditProviderMetadata, SignatureHelpContext } from '../../common/plugin-api-rpc-model'; import { RPCProtocol } from '../../common/rpc-protocol'; import { MonacoLanguages, WorkspaceSymbolProvider } from '@theia/monaco/lib/browser/monaco-languages'; @@ -84,7 +84,7 @@ import { import { ITextModel } from '@theia/monaco-editor-core/esm/vs/editor/common/model'; import { CodeActionTriggerKind, SnippetString } from '../../plugin/types-impl'; import { DataTransfer } from './data-transfer/data-transfer-type-converters'; -import { VSDataTransfer } from '@theia/monaco-editor-core/esm/vs/base/common/dataTransfer'; +import { IReadonlyVSDataTransfer } from '@theia/monaco-editor-core/esm/vs/base/common/dataTransfer'; import { FileUploadService } from '@theia/filesystem/lib/browser/file-upload-service'; /** @@ -647,7 +647,9 @@ export class LanguagesMainImpl implements LanguagesMain, Disposable { protected async provideSignatureHelp(handle: number, model: monaco.editor.ITextModel, position: monaco.Position, token: monaco.CancellationToken, context: monaco.languages.SignatureHelpContext): Promise> { - const value = await this.proxy.$provideSignatureHelp(handle, model.uri, position, context, token); + + // need to cast because of vscode issue https://github.com/microsoft/vscode/issues/190584 + const value = await this.proxy.$provideSignatureHelp(handle, model.uri, position, context as SignatureHelpContext, token); if (!value) { return undefined; } @@ -749,7 +751,7 @@ export class LanguagesMainImpl implements LanguagesMain, Disposable { } protected async provideDocumentDropEdits(handle: number, model: ITextModel, position: monaco.IPosition, - dataTransfer: VSDataTransfer, token: CancellationToken): Promise { + dataTransfer: IReadonlyVSDataTransfer, token: CancellationToken): Promise { await this.fileUploadService.upload(new URI(), { source: dataTransfer, leaveInTemp: true }); const edit = await this.proxy.$provideDocumentDropEdits(handle, model.uri, position, await DataTransfer.toDataTransferDTO(dataTransfer), token); if (edit) { @@ -759,6 +761,7 @@ export class LanguagesMainImpl implements LanguagesMain, Disposable { // yieldTo: edit.yieldTo?.map(yTo => { // return 'mimeType' in yTo ? yTo : { providerId: DocumentOnDropEditAdapter.toInternalProviderId(yTo.extensionId, yTo.providerId) }; // }), + label: 'no label', insertText: edit.insertText instanceof SnippetString ? { snippet: edit.insertText.value } : edit.insertText, additionalEdit: toMonacoWorkspaceEdit(edit?.additionalEdit) }; @@ -888,7 +891,8 @@ export class LanguagesMainImpl implements LanguagesMain, Disposable { }; }, resolveInlayHint: async (hint, token): Promise => { - const dto: InlayHintDto = hint; + // need to cast because of vscode issue https://github.com/microsoft/vscode/issues/190584 + const dto: InlayHintDto = hint as InlayHintDto; if (typeof dto.cacheId !== 'number') { return hint; } diff --git a/packages/plugin-ext/src/main/browser/main-context.ts b/packages/plugin-ext/src/main/browser/main-context.ts index a7728f3816015..2755e258d5053 100644 --- a/packages/plugin-ext/src/main/browser/main-context.ts +++ b/packages/plugin-ext/src/main/browser/main-context.ts @@ -45,7 +45,6 @@ import { EditorModelService } from './text-editor-model-service'; import { OpenerService } from '@theia/core/lib/browser/opener-service'; import { ApplicationShell } from '@theia/core/lib/browser/shell/application-shell'; import { MonacoBulkEditService } from '@theia/monaco/lib/browser/monaco-bulk-edit-service'; -import { MonacoEditorService } from '@theia/monaco/lib/browser/monaco-editor-service'; import { MainFileSystemEventService } from './main-file-system-event-service'; import { LabelServiceMainImpl } from './label-service-main'; import { TimelineMainImpl } from './timeline-main'; @@ -115,8 +114,7 @@ export function setUpPluginApi(rpc: RPCProtocol, container: interfaces.Container rpc.set(PLUGIN_RPC_CONTEXT.NOTEBOOK_KERNELS_MAIN, new NotebookKernelsMainImpl(rpc, container)); const bulkEditService = container.get(MonacoBulkEditService); - const monacoEditorService = container.get(MonacoEditorService); - const editorsMain = new TextEditorsMainImpl(editorsAndDocuments, documentsMain, rpc, bulkEditService, monacoEditorService); + const editorsMain = new TextEditorsMainImpl(editorsAndDocuments, documentsMain, rpc, bulkEditService); rpc.set(PLUGIN_RPC_CONTEXT.TEXT_EDITORS_MAIN, editorsMain); // start listening only after all clients are subscribed to events diff --git a/packages/plugin-ext/src/main/browser/menus/menus-contribution-handler.ts b/packages/plugin-ext/src/main/browser/menus/menus-contribution-handler.ts index 4c23f436a7b8e..9410875ce1f1c 100644 --- a/packages/plugin-ext/src/main/browser/menus/menus-contribution-handler.ts +++ b/packages/plugin-ext/src/main/browser/menus/menus-contribution-handler.ts @@ -31,7 +31,7 @@ import { PluginMenuCommandAdapter, ReferenceCountingSet } from './plugin-menu-co import { ContextKeyExpr } from '@theia/monaco-editor-core/esm/vs/platform/contextkey/common/contextkey'; import { ContextKeyService } from '@theia/core/lib/browser/context-key-service'; import { PluginSharedStyle } from '../plugin-shared-style'; -import { ThemeIcon } from '@theia/monaco-editor-core/esm/vs/platform/theme/common/themeService'; +import { ThemeIcon } from '@theia/monaco-editor-core/esm/vs/base/common/themables'; @injectable() export class MenusContributionPointHandler { diff --git a/packages/plugin-ext/src/main/browser/plugin-contribution-handler.ts b/packages/plugin-ext/src/main/browser/plugin-contribution-handler.ts index edd4584b67d73..96d02bbec2f60 100644 --- a/packages/plugin-ext/src/main/browser/plugin-contribution-handler.ts +++ b/packages/plugin-ext/src/main/browser/plugin-contribution-handler.ts @@ -47,13 +47,13 @@ import { PluginIconService } from './plugin-icon-service'; import { PluginIconThemeService } from './plugin-icon-theme-service'; import { ContributionProvider } from '@theia/core/lib/common'; import * as monaco from '@theia/monaco-editor-core'; -import { ThemeIcon } from '@theia/monaco-editor-core/esm/vs/platform/theme/common/themeService'; import { ContributedTerminalProfileStore, TerminalProfileStore } from '@theia/terminal/lib/browser/terminal-profile-service'; import { TerminalWidget } from '@theia/terminal/lib/browser/base/terminal-widget'; import { TerminalService } from '@theia/terminal/lib/browser/base/terminal-service'; import { PluginTerminalRegistry } from './plugin-terminal-registry'; import { ContextKeyService } from '@theia/core/lib/browser/context-key-service'; import { LanguageService } from '@theia/core/lib/browser/language-service'; +import { ThemeIcon } from '@theia/monaco-editor-core/esm/vs/base/common/themables'; @injectable() export class PluginContributionHandler { diff --git a/packages/plugin-ext/src/main/browser/plugin-icon-service.ts b/packages/plugin-ext/src/main/browser/plugin-icon-service.ts index caef198ea31c0..18ad070c67a99 100644 --- a/packages/plugin-ext/src/main/browser/plugin-icon-service.ts +++ b/packages/plugin-ext/src/main/browser/plugin-icon-service.ts @@ -14,18 +14,13 @@ // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 // ***************************************************************************** -import { asCSSPropertyValue } from '@theia/monaco-editor-core/esm/vs/base/browser/dom'; import { Endpoint } from '@theia/core/lib/browser'; import { Disposable, DisposableCollection } from '@theia/core/lib/common/disposable'; -import { getIconRegistry } from '@theia/monaco-editor-core/esm/vs/platform/theme/common/iconRegistry'; import { inject, injectable } from '@theia/core/shared/inversify'; import { URI } from '@theia/core/shared/vscode-uri'; -import { IconFontDefinition, IconContribution as Icon } from '@theia/core/lib/browser/icon-registry'; import { MonacoIconRegistry } from '@theia/monaco/lib/browser/monaco-icon-registry'; import * as path from 'path'; import { IconContribution, DeployedPlugin, IconDefinition } from '../../common/plugin-protocol'; -import { IThemeService } from '@theia/monaco-editor-core/esm/vs/platform/theme/common/themeService'; -import { UnthemedProductIconTheme } from '@theia/monaco-editor-core/esm/vs/platform/theme/browser/iconsStyleSheet'; @injectable() export class PluginIconService implements Disposable { @@ -45,29 +40,19 @@ export class PluginIconService implements Disposable { } else { this.registerRegularIcon(contribution, defaultIcon.id); } - this.updateStyle(contribution); return Disposable.NULL; } - updateStyle(contribution: IconContribution): void { - this.updateStyleElement(); - const css = this.getCSS(contribution); - if (css) { - this.styleElement.innerText = css; - } - const toRemoveStyleElement = Disposable.create(() => this.styleElement.remove()); - this.toDispose.push(toRemoveStyleElement); - } - dispose(): void { this.toDispose.dispose(); } protected registerFontIcon(contribution: IconContribution, defaultIcon: IconDefinition): void { - const location = defaultIcon.location; - const format = getFileExtension(location); - const fontId = getFontId(contribution.extensionId, location); - const definition = this.iconRegistry.registerIconFont(fontId, { src: [{ location: URI.file(location), format }] }); + const location = this.toPluginUrl(contribution.extensionId, getIconRelativePath(URI.parse(defaultIcon.location).path)); + const format = getFileExtension(location.path); + const fontId = getFontId(contribution.extensionId, location.path); + + const definition = this.iconRegistry.registerIconFont(fontId, { src: [{ location: location, format }] }); this.iconRegistry.registerIcon(contribution.id, { fontCharacter: defaultIcon.fontCharacter, font: { @@ -81,59 +66,10 @@ export class PluginIconService implements Disposable { this.iconRegistry.registerIcon(contribution.id, { id: defaultIconId }, contribution.description); } - protected updateStyleElement(): void { - if (!this.styleElement) { - const styleElement = document.createElement('style'); - styleElement.type = 'text/css'; - styleElement.media = 'screen'; - styleElement.id = 'contributedIconsStyles'; - document.head.appendChild(styleElement); - this.styleElement = styleElement; - } - } - protected getCSS(iconContribution: IconContribution, themeService?: IThemeService): string | undefined { - const iconRegistry = getIconRegistry(); - const productIconTheme = themeService ? themeService.getProductIconTheme() : new UnthemedProductIconTheme(); - const usedFontIds: { [id: string]: IconFontDefinition } = {}; - const formatIconRule = (contribution: Icon): string | undefined => { - const definition = productIconTheme.getIcon(contribution); - if (!definition) { - return undefined; - } - const fontContribution = definition.font; - if (fontContribution) { - usedFontIds[fontContribution.id] = fontContribution.definition; - return `.codicon-${contribution.id}:before { content: '${definition.fontCharacter}'; font-family: ${asCSSPropertyValue(iconContribution.extensionId)}; }`; - } - // default font (codicon) - return `.codicon-${contribution.id}:before { content: '${definition.fontCharacter}'; }`; - }; - - const rules = []; - for (const contribution of iconRegistry.getIcons()) { - const rule = formatIconRule(contribution); - if (rule) { - rules.push(rule); - } - } - for (const id in usedFontIds) { - if (id) { - const definition = usedFontIds[id]; - const fontWeight = definition.weight ? `font-weight: ${definition.weight};` : ''; - const fontStyle = definition.style ? `font-style: ${definition.style};` : ''; - const src = definition.src.map(icon => - `${this.toPluginUrl(iconContribution.extensionId, getIconRelativePath(icon.location.path))} format('${icon.format}')`) - .join(', '); - rules.push(`@font-face { src: ${src}; font-family: ${asCSSPropertyValue(iconContribution.extensionId)};${fontWeight}${fontStyle} font-display: block; }`); - } - } - return rules.join('\n'); - } - - protected toPluginUrl(id: string, relativePath: string): string { - return `url('${new Endpoint({ + protected toPluginUrl(id: string, relativePath: string): URI { + return URI.from(new Endpoint({ path: `hostedPlugin/${this.formatExtensionId(id)}/${encodeURIComponent(relativePath)}` - }).getRestUrl().toString()}')`; + }).getRestUrl().toComponents()); } protected formatExtensionId(id: string): string { diff --git a/packages/plugin-ext/src/main/browser/quick-open-main.ts b/packages/plugin-ext/src/main/browser/quick-open-main.ts index c65d81296886e..33777f26b0996 100644 --- a/packages/plugin-ext/src/main/browser/quick-open-main.ts +++ b/packages/plugin-ext/src/main/browser/quick-open-main.ts @@ -23,39 +23,47 @@ import { QuickOpenMain, MAIN_RPC_CONTEXT, TransferInputBox, - TransferQuickPickItems, + TransferQuickPickItem, TransferQuickInput, TransferQuickInputButton, - TransferQuickPickItemValue + TransferQuickPickOptions } from '../../common/plugin-api-rpc'; import { InputOptions, - PickOptions, + QuickInput, QuickInputButton, QuickInputButtonHandle, - QuickInputService + QuickInputService, + QuickPickItem, + codiconArray } from '@theia/core/lib/browser'; import { DisposableCollection, Disposable } from '@theia/core/lib/common/disposable'; import { CancellationToken } from '@theia/core/lib/common/cancellation'; import { MonacoQuickInputService } from '@theia/monaco/lib/browser/monaco-quick-input-service'; import { QuickInputButtons } from '../../plugin/types-impl'; -import { getIconPathOrClass } from '../../plugin/quick-open'; import * as monaco from '@theia/monaco-editor-core'; -import { IQuickPickItem, IQuickInput } from '@theia/monaco-editor-core/esm/vs/base/parts/quickinput/common/quickInput'; -import { ThemeIcon } from '@theia/monaco-editor-core/esm/vs/platform/theme/common/themeService'; +import { UriComponents } from '../../common/uri-components'; +import { URI } from '@theia/core/shared/vscode-uri'; +import { ThemeIcon } from '@theia/monaco-editor-core/esm/vs/base/common/themables'; +import { isUriComponents } from '@theia/monaco-editor-core/esm/vs/base/common/uri'; export interface QuickInputSession { - input: IQuickInput; - handlesToItems: Map; + input: QuickInput; + handlesToItems: Map; } +interface IconPath { + dark: URI, + light?: URI +}; + export class QuickOpenMainImpl implements QuickOpenMain, Disposable { private quickInputService: QuickInputService; private proxy: QuickOpenExt; private delegate: MonacoQuickInputService; private readonly items: Record = {}; @@ -71,33 +79,74 @@ export class QuickOpenMainImpl implements QuickOpenMain, Disposable { this.toDispose.dispose(); } - async $show(instance: number, options: PickOptions, token: CancellationToken): Promise { - const contents = new Promise((resolve, reject) => { + async $show(instance: number, options: TransferQuickPickOptions, token: CancellationToken): Promise { + const contents = new Promise((resolve, reject) => { this.items[instance] = { resolve, reject }; }); - options = { + const activeItem = await options.activeItem; + const transformedOptions = { ...options, onDidFocus: (el: any) => { if (el) { - this.proxy.$onItemSelected((el).handle); + this.proxy.$onItemSelected(Number.parseInt((el).id!)); } - } + }, + activeItem: activeItem ? this.toQuickPickItem(activeItem) : undefined }; - const result = await this.delegate.pick(contents, options, token); + const result = await this.delegate.pick(contents, transformedOptions, token); if (Array.isArray(result)) { - return result.map(({ handle }) => handle); + return result.map(({ id }) => Number.parseInt(id!)); } else if (result) { - return result.handle; + return Number.parseInt(result.id!); } return undefined; } - $setItems(instance: number, items: TransferQuickPickItems[]): Promise { + private normalizeIconPath(path: UriComponents | { light: UriComponents; dark: UriComponents } | ThemeIcon | undefined): { + iconPath?: IconPath + iconClasses?: string[] + } { + let iconClasses; + if (ThemeIcon.isThemeIcon(path)) { + const codicon = codiconArray(path.id); + iconClasses = codicon; + } + let iconPath; + if (isUriComponents(path)) { + iconPath = { dark: URI.from(path) }; + } else if (path && 'dark' in path) { + iconPath = { dark: URI.from(path.dark), light: URI.from(path.light) }; + } + return { + iconPath, + iconClasses + }; + } + + private toQuickPickItem(item: undefined): undefined; + private toQuickPickItem(item: TransferQuickPickItem): QuickPickItem + private toQuickPickItem(item: TransferQuickPickItem | undefined): QuickPickItem | undefined { + if (!item) { + return undefined; + } + return { + ...this.normalizeIconPath(item.iconPath), + type: 'item', + id: item.handle.toString(), + label: item.label, + description: item.description, + detail: item.detail, + alwaysShow: item.alwaysShow, + buttons: item.buttons ? this.convertToQuickInputButtons(item.buttons) : undefined + }; + } + + $setItems(instance: number, items: TransferQuickPickItem[]): Promise { if (this.items[instance]) { - this.items[instance].resolve(items); + this.items[instance].resolve(items.map(item => this.toQuickPickItem(item))); delete this.items[instance]; } return Promise.resolve(); @@ -201,17 +250,17 @@ export class QuickOpenMainImpl implements QuickOpenMain, Disposable { quickPick.onDidAccept(() => { this.proxy.$acceptOnDidAccept(sessionId); }); - quickPick.onDidChangeActive((items: Array) => { - this.proxy.$onDidChangeActive(sessionId, items.map(item => (item as TransferQuickPickItems).handle)); + quickPick.onDidChangeActive((items: QuickPickItem[]) => { + this.proxy.$onDidChangeActive(sessionId, items.map(item => Number.parseInt(item.id!))); }); - quickPick.onDidChangeSelection((items: Array) => { - this.proxy.$onDidChangeSelection(sessionId, items.map(item => (item as TransferQuickPickItems).handle)); + quickPick.onDidChangeSelection((items: QuickPickItem[]) => { + this.proxy.$onDidChangeSelection(sessionId, items.map(item => Number.parseInt(item.id!))); }); quickPick.onDidTriggerButton((button: QuickInputButtonHandle) => { this.proxy.$acceptOnDidTriggerButton(sessionId, button); }); quickPick.onDidTriggerItemButton(e => { - this.proxy.$onDidTriggerItemButton(sessionId, (e.item as TransferQuickPickItems).handle, (e.button as TransferQuickPickItems).handle); + this.proxy.$onDidTriggerItemButton(sessionId, Number.parseInt(e.item.id!), (e.button as TransferQuickPickItem).handle); }); quickPick.onDidChangeValue((value: string) => { this.proxy.$acceptDidChangeValue(sessionId, value); @@ -260,7 +309,7 @@ export class QuickOpenMainImpl implements QuickOpenMain, Disposable { } } else if (param === 'items') { handlesToItems.clear(); - params[param].forEach((item: TransferQuickPickItems) => { + params[param].forEach((item: TransferQuickPickItem) => { handlesToItems.set(item.handle, item); }); (input as any)[param] = params[param]; @@ -314,9 +363,9 @@ export class QuickOpenMainImpl implements QuickOpenMain, Disposable { return Promise.resolve(undefined); } - private convertToQuickInputButtons(buttons: Array): Array { + private convertToQuickInputButtons(buttons: readonly TransferQuickInputButton[]): QuickInputButton[] { return buttons.map((button, i) => ({ - ...getIconPathOrClass(button), + ...this.normalizeIconPath(button.iconPath), tooltip: button.tooltip, handle: button === QuickInputButtons.Back ? -1 : i, } as QuickInputButton)); diff --git a/packages/plugin-ext/src/main/browser/scm-main.ts b/packages/plugin-ext/src/main/browser/scm-main.ts index 68af564e04111..ade01b4bc59d4 100644 --- a/packages/plugin-ext/src/main/browser/scm-main.ts +++ b/packages/plugin-ext/src/main/browser/scm-main.ts @@ -41,8 +41,8 @@ import { Splice } from '../../common/arrays'; import { UriComponents } from '../../common/uri-components'; import { ColorRegistry } from '@theia/core/lib/browser/color-registry'; import { PluginSharedStyle } from './plugin-shared-style'; -import { ThemeIcon } from '@theia/monaco-editor-core/esm/vs/platform/theme/common/themeService'; import { IconUrl } from '../../common'; +import { ThemeIcon } from '@theia/monaco-editor-core/esm/vs/base/common/themables'; export class PluginScmResourceGroup implements ScmResourceGroup { diff --git a/packages/plugin-ext/src/main/browser/text-editors-main.ts b/packages/plugin-ext/src/main/browser/text-editors-main.ts index 879a709a04c45..eab1b28fdb123 100644 --- a/packages/plugin-ext/src/main/browser/text-editors-main.ts +++ b/packages/plugin-ext/src/main/browser/text-editors-main.ts @@ -40,12 +40,13 @@ import { TextEditorMain } from './text-editor-main'; import { disposed } from '../../common/errors'; import { toMonacoWorkspaceEdit } from './languages-main'; import { MonacoBulkEditService } from '@theia/monaco/lib/browser/monaco-bulk-edit-service'; -import { MonacoEditorService } from '@theia/monaco/lib/browser/monaco-editor-service'; import { theiaUritoUriComponents, UriComponents } from '../../common/uri-components'; import { Endpoint } from '@theia/core/lib/browser/endpoint'; import * as monaco from '@theia/monaco-editor-core'; import { ResourceEdit } from '@theia/monaco-editor-core/esm/vs/editor/browser/services/bulkEditService'; import { IDecorationRenderOptions } from '@theia/monaco-editor-core/esm/vs/editor/common/editorCommon'; +import { StandaloneServices } from '@theia/monaco-editor-core/esm/vs/editor/standalone/browser/standaloneServices'; +import { ICodeEditorService } from '@theia/monaco-editor-core/esm/vs/editor/browser/services/codeEditorService'; export class TextEditorsMainImpl implements TextEditorsMain, Disposable { @@ -59,7 +60,6 @@ export class TextEditorsMainImpl implements TextEditorsMain, Disposable { private readonly documents: DocumentsMain, rpc: RPCProtocol, private readonly bulkEditService: MonacoBulkEditService, - private readonly monacoEditorService: MonacoEditorService, ) { this.proxy = rpc.getProxy(MAIN_RPC_CONTEXT.TEXT_EDITORS_EXT); this.toDispose.push(editorsAndDocuments); @@ -131,8 +131,8 @@ export class TextEditorsMainImpl implements TextEditorsMain, Disposable { const workspaceEdit = toMonacoWorkspaceEdit(dto); try { const edits = ResourceEdit.convert(workspaceEdit); - const { success } = await this.bulkEditService.apply(edits, { respectAutoSaveConfig: metadata?.isRefactoring }); - return success; + const { isApplied } = await this.bulkEditService.apply(edits, { respectAutoSaveConfig: metadata?.isRefactoring }); + return isApplied; } catch { return false; } @@ -145,9 +145,9 @@ export class TextEditorsMainImpl implements TextEditorsMain, Disposable { return Promise.resolve(this.editorsAndDocuments.getEditor(id)!.insertSnippet(template, ranges, opts)); } - $registerTextEditorDecorationType(key: string, options: DecorationRenderOptions | IDecorationRenderOptions): void { + $registerTextEditorDecorationType(key: string, options: DecorationRenderOptions): void { this.injectRemoteUris(options); - this.monacoEditorService.registerDecorationType('Plugin decoration', key, options as IDecorationRenderOptions); + StandaloneServices.get(ICodeEditorService).registerDecorationType('Plugin decoration', key, options as IDecorationRenderOptions); this.toDispose.push(Disposable.create(() => this.$removeTextEditorDecorationType(key))); } @@ -177,7 +177,7 @@ export class TextEditorsMainImpl implements TextEditorsMain, Disposable { } $removeTextEditorDecorationType(key: string): void { - this.monacoEditorService.removeDecorationType(key); + StandaloneServices.get(ICodeEditorService).removeDecorationType(key); } $tryHideEditor(id: string): Promise { diff --git a/packages/plugin-ext/src/main/browser/theme-icon-override.ts b/packages/plugin-ext/src/main/browser/theme-icon-override.ts index 5ac10215ddb86..d22f101520463 100644 --- a/packages/plugin-ext/src/main/browser/theme-icon-override.ts +++ b/packages/plugin-ext/src/main/browser/theme-icon-override.ts @@ -14,7 +14,7 @@ // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 // ***************************************************************************** -import { ThemeIcon } from '@theia/monaco-editor-core/esm/vs/platform/theme/common/themeService'; +import { getIconRegistry } from '@theia/monaco-editor-core/esm/vs/platform/theme/common/iconRegistry'; // @monaco-uplift // Keep this up-to-date with the table at https://code.visualstudio.com/api/references/icons-in-labels#icon-listing @@ -27,11 +27,12 @@ const codeIconMap: Record = { 'callhierarchy-outgoing': 'call-outgoing', 'callstack-view-icon': 'debug-alt', 'callstack-view-session': 'bug', + 'chat-editor-label-icon': 'comment-discussion', 'comments-view-icon': 'comment-discussion', 'debug-breakpoint': 'debug-breakpoint', 'debug-breakpoint-conditional': 'debug-breakpoint-conditional', 'debug-breakpoint-conditional-disabled': 'debug-breakpoint-conditional-disabled', - 'debug-breakpoint-conditional-verified': 'debug-breakpoint-conditional-unverified', + 'debug-breakpoint-conditional-unverified': 'debug-breakpoint-conditional-unverified', 'debug-breakpoint-data': 'debug-breakpoint-data', 'debug-breakpoint-data-disabled': 'debug-breakpoint-data-disabled', 'debug-breakpoint-data-unverified': 'debug-breakpoint-data-unverified', @@ -173,9 +174,11 @@ const codeIconMap: Record = { 'remote-explorer-view-icon': 'remote-explorer', 'review-comment-collapse': 'chevron-up', 'run-view-icon': 'debug-alt', + 'runtime-extensions-editor-label-icon': ' extensions', 'search-clear-results': 'clear-all', 'search-collapse-results': 'collapse-all', 'search-details': 'ellipsis', + 'search-editor-label-icon': 'search', 'search-expand-results': 'expand-all', 'search-hide-replace': 'chevron-right', 'search-new-editor': 'new-file', @@ -190,6 +193,7 @@ const codeIconMap: Record = { 'settings-add': 'add', 'settings-discard': 'discard', 'settings-edit': 'edit', + 'settings-editor-label-icon': 'settings', 'settings-folder-dropdown': 'triangle-down', 'settings-group-collapsed': 'chevron-right', 'settings-group-expanded': 'chevron-down', @@ -229,24 +233,14 @@ const codeIconMap: Record = { 'watch-expressions-add-function-breakpoint': 'add', 'watch-expressions-remove-all': 'close-all', 'watch-view-icon': 'debug-alt', - 'widget-close': 'close' + 'widget-close': 'close', + 'workspace-trust-editor-label-icon': ' shield' }; -const originalAsCSSSelector = ThemeIcon.asCSSSelector; -const originalAsClassName = ThemeIcon.asClassName; -const originalAsClassNameArray = ThemeIcon.asClassNameArray; +const registry = getIconRegistry(); -function buildMappedIcon(icon: ThemeIcon): ThemeIcon { - const id = codeIconMap[icon.id] ?? icon.id; - const newIcon: ThemeIcon = { - ...icon, - id - }; - return newIcon; +for (const key in codeIconMap) { + if (codeIconMap.hasOwnProperty(key)) { + registry.registerIcon(key, { id: codeIconMap[key] }, key); + } } - -Object.assign(ThemeIcon, { - asCSSSelector: (icon: ThemeIcon) => originalAsCSSSelector(buildMappedIcon(icon)), - asClassName: (icon: ThemeIcon) => originalAsClassName(buildMappedIcon(icon)), - asClassNameArray: (icon: ThemeIcon) => originalAsClassNameArray(buildMappedIcon(icon)) -}); diff --git a/packages/plugin-ext/src/main/browser/view/plugin-tree-view-node-label-provider.ts b/packages/plugin-ext/src/main/browser/view/plugin-tree-view-node-label-provider.ts index 011ee0638e937..c5670f830cbe2 100644 --- a/packages/plugin-ext/src/main/browser/view/plugin-tree-view-node-label-provider.ts +++ b/packages/plugin-ext/src/main/browser/view/plugin-tree-view-node-label-provider.ts @@ -20,7 +20,7 @@ import { LabelProviderContribution, LabelProvider, URIIconReference } from '@the import { TreeLabelProvider } from '@theia/core/lib/browser/tree/tree-label-provider'; import { TreeViewNode } from './tree-view-widget'; import { TreeNode } from '@theia/core/lib/browser/tree/tree'; -import { ThemeIcon } from '@theia/monaco-editor-core/esm/vs/platform/theme/common/themeService'; +import { ThemeIcon } from '@theia/monaco-editor-core/esm/vs/base/common/themables'; @injectable() export class PluginTreeViewNodeLabelProvider implements LabelProviderContribution { diff --git a/packages/plugin-ext/src/main/browser/view/plugin-view-registry.ts b/packages/plugin-ext/src/main/browser/view/plugin-view-registry.ts index 9698c259428f8..f11ad8383cfc7 100644 --- a/packages/plugin-ext/src/main/browser/view/plugin-view-registry.ts +++ b/packages/plugin-ext/src/main/browser/view/plugin-view-registry.ts @@ -40,7 +40,6 @@ import { DebugConsoleContribution } from '@theia/debug/lib/browser/console/debug import { TreeViewWidget } from './tree-view-widget'; import { SEARCH_VIEW_CONTAINER_ID } from '@theia/search-in-workspace/lib/browser/search-in-workspace-factory'; import { TEST_VIEW_CONTAINER_ID } from '@theia/test/lib/browser/view/test-view-contribution'; -import { ThemeIcon } from '@theia/monaco-editor-core/esm/vs/platform/theme/common/themeService'; import { WebviewView, WebviewViewResolver } from '../webview-views/webview-views'; import { WebviewWidget, WebviewWidgetIdentifier } from '../webview/webview'; import { CancellationToken } from '@theia/core/lib/common/cancellation'; @@ -48,6 +47,7 @@ import { v4 } from 'uuid'; import { nls } from '@theia/core'; import { TheiaDockPanel } from '@theia/core/lib/browser/shell/theia-dock-panel'; import { Deferred } from '@theia/core/lib/common/promise-util'; +import { ThemeIcon } from '@theia/monaco-editor-core/esm/vs/base/common/themables'; export const PLUGIN_VIEW_FACTORY_ID = 'plugin-view'; export const PLUGIN_VIEW_CONTAINER_FACTORY_ID = 'plugin-view-container'; diff --git a/packages/plugin-ext/src/main/browser/view/plugin-view-widget.ts b/packages/plugin-ext/src/main/browser/view/plugin-view-widget.ts index cf8d1c1a47de4..a7c755d6516d5 100644 --- a/packages/plugin-ext/src/main/browser/view/plugin-view-widget.ts +++ b/packages/plugin-ext/src/main/browser/view/plugin-view-widget.ts @@ -75,7 +75,6 @@ export class PluginViewWidget extends Panel implements StatefulWidget, Descripti this.id = this.options.id; const localContext = this.contextKeyService.createScoped(this.node); localContext.setContext('view', this.options.viewId); - this.toDispose.push(localContext); } get onDidChangeDescription(): Event { diff --git a/packages/plugin-ext/src/main/browser/view/tree-view-widget.tsx b/packages/plugin-ext/src/main/browser/view/tree-view-widget.tsx index f1f47f3aafa47..4524a90359991 100644 --- a/packages/plugin-ext/src/main/browser/view/tree-view-widget.tsx +++ b/packages/plugin-ext/src/main/browser/view/tree-view-widget.tsx @@ -669,7 +669,7 @@ export class TreeViewWidget extends TreeViewWelcomeWidget { this.model.proxy!.$dragStarted(this.options.id, selectedNodes.map(selected => selected.id), CancellationToken.None).then(maybeUris => { if (maybeUris) { - this.applicationShell.addAdditionalDraggedEditorUris(maybeUris.map(URI.fromComponents)); + this.applicationShell.addAdditionalDraggedEditorUris(maybeUris.map(uri => URI.fromComponents(uri))); } }); } @@ -921,8 +921,7 @@ export class TreeViewWidget extends TreeViewWelcomeWidget { menuPath: contextMenuPath, anchor: { x, y }, args, - contextKeyService, - onHide: () => contextKeyService.dispose(), + contextKeyService }), 10); } } diff --git a/packages/plugin-ext/src/plugin/known-commands.ts b/packages/plugin-ext/src/plugin/known-commands.ts index 26233eeaa35a1..e8bf476056d14 100755 --- a/packages/plugin-ext/src/plugin/known-commands.ts +++ b/packages/plugin-ext/src/plugin/known-commands.ts @@ -261,6 +261,7 @@ export namespace KnownCommands { mappings['closeReferenceSearch'] = ['closeReferenceSearch', CONVERT_VSCODE_TO_MONACO]; mappings['goToNextReference'] = ['goToNextReference', CONVERT_VSCODE_TO_MONACO]; mappings['goToPreviousReference'] = ['goToPreviousReference', CONVERT_VSCODE_TO_MONACO]; + mappings['setContext'] = ['_setContext', CONVERT_VSCODE_TO_MONACO]; // eslint-disable-next-line @typescript-eslint/no-explicit-any const CONVERT_MONACO_TO_VSCODE = (args: any | undefined) => { diff --git a/packages/plugin-ext/src/plugin/markdown-string.ts b/packages/plugin-ext/src/plugin/markdown-string.ts index 51dff7c905859..217cb9f1c8a98 100644 --- a/packages/plugin-ext/src/plugin/markdown-string.ts +++ b/packages/plugin-ext/src/plugin/markdown-string.ts @@ -15,7 +15,7 @@ // ***************************************************************************** import { Mutable } from '@theia/core'; -import { MarkdownStringImpl as BaseMarkdownString, MarkdownString as MarkdownStringInterface } from '@theia/core/lib/common/markdown-rendering'; +import { MarkdownStringImpl as BaseMarkdownString, MarkdownString as MarkdownStringInterface, MarkdownStringTrustedOptions } from '@theia/core/lib/common/markdown-rendering'; import * as pluginAPI from '@theia/plugin'; import { es5ClassCompat } from '../common/types'; import { URI } from './types-impl'; @@ -49,11 +49,11 @@ export class MarkdownString implements pluginAPI.MarkdownString { this.#delegate.value = value; } - get isTrusted(): boolean | undefined { + get isTrusted(): boolean | MarkdownStringTrustedOptions | undefined { return this.#delegate.isTrusted; } - set isTrusted(value: boolean | undefined) { + set isTrusted(value: boolean | MarkdownStringTrustedOptions | undefined) { this.#delegate.isTrusted = value; } diff --git a/packages/plugin-ext/src/plugin/quick-open.ts b/packages/plugin-ext/src/plugin/quick-open.ts index 56523f0932507..c5ca8c39c830b 100644 --- a/packages/plugin-ext/src/plugin/quick-open.ts +++ b/packages/plugin-ext/src/plugin/quick-open.ts @@ -16,7 +16,7 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ import { QuickOpenExt, PLUGIN_RPC_CONTEXT as Ext, QuickOpenMain, TransferInputBox, Plugin, - Item, TransferQuickInputButton, TransferQuickPickItems, TransferQuickInput + TransferQuickInputButton, TransferQuickInput, TransferQuickPickItem } from '../common/plugin-api-rpc'; import * as theia from '@theia/plugin'; import { CancellationToken } from '@theia/core/lib/common/cancellation'; @@ -31,7 +31,7 @@ import { PluginPackage } from '../common/plugin-protocol'; import { QuickInputButtonHandle } from '@theia/core/lib/browser'; import { MaybePromise } from '@theia/core/lib/common/types'; import Severity from '@theia/monaco-editor-core/esm/vs/base/common/severity'; -import { ThemeIcon as MonacoThemeIcon } from '@theia/monaco-editor-core/esm/vs/platform/theme/common/themeService'; +import { ThemeIcon as MonacoThemeIcon } from '@theia/monaco-editor-core/esm/vs/base/common/themables'; const canceledName = 'Canceled'; /** @@ -63,21 +63,7 @@ export function getDarkIconUri(iconPath: URI | { light: URI; dark: URI; }): URI return typeof iconPath === 'object' && 'dark' in iconPath ? iconPath.dark : iconPath; } -export function getIconPathOrClass(button: theia.QuickInputButton): { iconPath: { dark: URI; light?: URI | undefined; } | undefined; iconClass: string | undefined; } { - const iconPathOrIconClass = getIconUris(button.iconPath); - let iconPath: { dark: URI; light?: URI | undefined } | undefined; - let iconClass: string | undefined; - if ('id' in iconPathOrIconClass) { - iconClass = MonacoThemeIcon.asClassName(iconPathOrIconClass); - } else { - iconPath = iconPathOrIconClass; - } - - return { - iconPath, - iconClass - }; -} +type Item = theia.QuickPickItem | string; export class QuickOpenExtImpl implements QuickOpenExt { private proxy: QuickOpenMain; @@ -91,13 +77,13 @@ export class QuickOpenExtImpl implements QuickOpenExt { } /* eslint-disable max-len */ - showQuickPick(itemsOrItemsPromise: Array | Promise>, options: theia.QuickPickOptions & { canPickMany: true; }, token?: theia.CancellationToken): Promise | undefined>; + showQuickPick(itemsOrItemsPromise: theia.QuickPickItem[] | Promise, options: theia.QuickPickOptions & { canPickMany: true; }, token?: theia.CancellationToken): Promise | undefined>; showQuickPick(itemsOrItemsPromise: string[] | Promise, options?: theia.QuickPickOptions, token?: theia.CancellationToken): Promise; - showQuickPick(itemsOrItemsPromise: Array | Promise>, options?: theia.QuickPickOptions, token?: theia.CancellationToken): Promise; + showQuickPick(itemsOrItemsPromise: theia.QuickPickItem[] | Promise, options?: theia.QuickPickOptions, token?: theia.CancellationToken): Promise; showQuickPick(itemsOrItemsPromise: Item[] | Promise, options?: theia.QuickPickOptions, token: theia.CancellationToken = CancellationToken.None): Promise { this.onDidSelectItem = undefined; - const itemsPromise = >Promise.resolve(itemsOrItemsPromise); + const itemsPromise = Promise.resolve(itemsOrItemsPromise); const instance = ++this._instances; @@ -118,7 +104,7 @@ export class QuickOpenExtImpl implements QuickOpenExt { return undefined; } return itemsPromise.then(async items => { - const pickItems: Array = convertToTransferQuickPickItems(items); + const pickItems = convertToTransferQuickPickItems(items); if (options && typeof options.onDidSelectItem === 'function') { this.onDidSelectItem = handle => { @@ -646,14 +632,14 @@ export class QuickPickExt extends QuickInputExt i this._itemsToHandles.set(item, i); }); - const pickItems: TransferQuickPickItems[] = []; + const pickItems: TransferQuickPickItem[] = []; for (let handle = 0; handle < items.length; handle++) { const item = items[handle]; if (item.kind === QuickPickItemKind.Separator) { - pickItems.push({ type: 'separator', label: item.label, handle }); + pickItems.push({ kind: 'separator', label: item.label, handle }); } else { pickItems.push({ - kind: item.kind, + kind: 'item', label: item.label, iconPath: item.iconPath ? getIconUris(item.iconPath) : undefined, description: item.description, diff --git a/packages/plugin-ext/src/plugin/terminal-ext.ts b/packages/plugin-ext/src/plugin/terminal-ext.ts index 79219e4103157..d4833476c9186 100644 --- a/packages/plugin-ext/src/plugin/terminal-ext.ts +++ b/packages/plugin-ext/src/plugin/terminal-ext.ts @@ -26,7 +26,7 @@ import * as Converter from './type-converters'; import { Disposable, EnvironmentVariableMutatorType, TerminalExitReason, ThemeIcon } from './types-impl'; import { NO_ROOT_URI, SerializableEnvironmentVariableCollection } from '@theia/terminal/lib/common/shell-terminal-protocol'; import { ProvidedTerminalLink } from '../common/plugin-api-rpc-model'; -import { ThemeIcon as MonacoThemeIcon } from '@theia/monaco-editor-core/esm/vs/platform/theme/common/themeService'; +import { ThemeIcon as MonacoThemeIcon } from '@theia/monaco-editor-core/esm/vs/base/common/themables'; export function getIconUris(iconPath: theia.TerminalOptions['iconPath']): { id: string } | undefined { if (ThemeIcon.is(iconPath)) { diff --git a/packages/plugin-ext/src/plugin/type-converters.ts b/packages/plugin-ext/src/plugin/type-converters.ts index ba0d8140c3435..7c040d7df115f 100644 --- a/packages/plugin-ext/src/plugin/type-converters.ts +++ b/packages/plugin-ext/src/plugin/type-converters.ts @@ -35,6 +35,7 @@ import { CellRange, isTextStreamMime } from '@theia/notebook/lib/common'; import { MarkdownString as MarkdownStringDTO } from '@theia/core/lib/common/markdown-rendering'; import { TestItemDTO, TestMessageDTO } from '../common/test-types'; +import { ThemeIcon } from '@theia/monaco-editor-core/esm/vs/base/common/themables'; const SIDE_GROUP = -2; const ACTIVE_GROUP = -1; @@ -1212,23 +1213,57 @@ export function fromColorPresentation(colorPresentation: theia.ColorPresentation }; } -export function convertToTransferQuickPickItems(items: rpc.Item[]): rpc.TransferQuickPickItems[] { - return items.map((item, index) => { +export function convertIconPath(iconPath: types.URI | { light: types.URI; dark: types.URI } | theia.ThemeIcon | undefined): + UriComponents | { light: UriComponents; dark: UriComponents } | ThemeIcon | undefined { + if (!iconPath) { + return undefined; + } + if (iconPath instanceof types.URI) { + return iconPath.toJSON(); + } else if ('dark' in iconPath) { + return { + dark: iconPath.dark.toJSON(), + light: iconPath.light?.toJSON() + }; + } else if (ThemeIcon.isThemeIcon(iconPath)) { + return { + id: iconPath.id, + color: iconPath.color ? { id: iconPath.color.id } : undefined + }; + } else { + return undefined; + } +} + +export function convertQuickInputButton(button: theia.QuickInputButton, index: number): rpc.TransferQuickInputButton { + const iconPath = convertIconPath(button.iconPath); + if (!iconPath) { + throw new Error(`Could not convert icon path: '${button.iconPath}'`); + } + return { + handle: index, + iconPath: iconPath, + tooltip: button.tooltip + }; +} + +export function convertToTransferQuickPickItems(items: (theia.QuickPickItem | string)[]): rpc.TransferQuickPickItem[] { + return items.map((item, index) => { if (typeof item === 'string') { - return { type: 'item', label: item, handle: index }; + return { kind: 'item', label: item, handle: index }; } else if (item.kind === QuickPickItemKind.Separator) { - return { type: 'separator', label: item.label, handle: index }; + return { kind: 'separator', label: item.label, handle: index }; } else { const { label, description, iconPath, detail, picked, alwaysShow, buttons } = item; return { - type: 'item', + kind: 'item', label, description, - iconPath, + iconPath: convertIconPath(iconPath), detail, picked, alwaysShow, - buttons, + buttons: buttons ? buttons.map(convertQuickInputButton) : undefined, handle: index, }; } @@ -1403,7 +1438,7 @@ export namespace DataTransferItem { return { name: file.name, uri: URI.revive(file.uri), - data: () => resolveFileData(item.id), + data: () => resolveFileData(file.id), }; } }(''); diff --git a/packages/plugin-metrics/package.json b/packages/plugin-metrics/package.json index 1f63607b7cd5b..64fe79fd285d1 100644 --- a/packages/plugin-metrics/package.json +++ b/packages/plugin-metrics/package.json @@ -5,7 +5,7 @@ "dependencies": { "@theia/core": "1.46.0", "@theia/metrics": "1.46.0", - "@theia/monaco-editor-core": "1.72.3", + "@theia/monaco-editor-core": "1.83.101", "@theia/plugin": "1.46.0", "@theia/plugin-ext": "1.46.0" }, @@ -48,4 +48,4 @@ "nyc": { "extends": "../../configs/nyc.json" } -} +} \ No newline at end of file diff --git a/packages/plugin/src/theia.d.ts b/packages/plugin/src/theia.d.ts index e1cbea324ebed..f187bfffd0b5e 100644 --- a/packages/plugin/src/theia.d.ts +++ b/packages/plugin/src/theia.d.ts @@ -3,7 +3,7 @@ // // This program and the accompanying materials are made available under the // terms of the Eclipse Public License v. 2.0 which is available at -// http://www.eclipse.org/legal/epl-2.0. +// http://www.eclipse.org/legal/epl-2.0.g // // This Source Code may also be made available under the following Secondary // Licenses when the conditions for such availability set forth in the Eclipse @@ -682,8 +682,12 @@ export module '@theia/plugin' { /** * Indicates that this markdown string is from a trusted source. Only *trusted* * markdown supports links that execute commands, e.g. `[Run it](command:myCommandId)`. + * + * Defaults to `false` (commands are disabled). + * + * If this is an object, only the set of commands listed in `enabledCommands` are allowed. */ - isTrusted?: boolean; + isTrusted?: boolean | { readonly enabledCommands: readonly string[] }; /** * Indicates that this markdown string can contain {@link ThemeIcon ThemeIcons}, e.g. `$(zap)`. diff --git a/packages/preferences/package.json b/packages/preferences/package.json index 32d66867944f6..e64681fedd75b 100644 --- a/packages/preferences/package.json +++ b/packages/preferences/package.json @@ -7,7 +7,7 @@ "@theia/editor": "1.46.0", "@theia/filesystem": "1.46.0", "@theia/monaco": "1.46.0", - "@theia/monaco-editor-core": "1.72.3", + "@theia/monaco-editor-core": "1.83.101", "@theia/userstorage": "1.46.0", "@theia/workspace": "1.46.0", "async-mutex": "^0.3.1", @@ -53,4 +53,4 @@ "nyc": { "extends": "../../configs/nyc.json" } -} +} \ No newline at end of file diff --git a/packages/task/package.json b/packages/task/package.json index e86a3ecfa0a33..ce7ef70fa32c0 100644 --- a/packages/task/package.json +++ b/packages/task/package.json @@ -8,7 +8,7 @@ "@theia/filesystem": "1.46.0", "@theia/markers": "1.46.0", "@theia/monaco": "1.46.0", - "@theia/monaco-editor-core": "1.72.3", + "@theia/monaco-editor-core": "1.83.101", "@theia/process": "1.46.0", "@theia/terminal": "1.46.0", "@theia/userstorage": "1.46.0", @@ -57,4 +57,4 @@ "nyc": { "extends": "../../configs/nyc.json" } -} +} \ No newline at end of file diff --git a/packages/toolbar/package.json b/packages/toolbar/package.json index 03ae12987d1a7..38eb066cf8513 100644 --- a/packages/toolbar/package.json +++ b/packages/toolbar/package.json @@ -32,7 +32,7 @@ "@theia/file-search": "1.46.0", "@theia/filesystem": "1.46.0", "@theia/monaco": "1.46.0", - "@theia/monaco-editor-core": "1.72.3", + "@theia/monaco-editor-core": "1.83.101", "@theia/search-in-workspace": "1.46.0", "@theia/userstorage": "1.46.0", "@theia/workspace": "1.46.0", @@ -48,4 +48,4 @@ "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 43bec804e016e..7306b5d7bfec2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1707,10 +1707,10 @@ dependencies: defer-to-connect "^2.0.0" -"@theia/monaco-editor-core@1.72.3": - version "1.72.3" - resolved "https://registry.yarnpkg.com/@theia/monaco-editor-core/-/monaco-editor-core-1.72.3.tgz#911d674c6e0c490442a355cfaa52beec919a025e" - integrity sha512-2FK5m0G5oxiqCv0ZrjucMx5fVgQ9Jqv0CgxGvSzDc4wRrauBdeBoX90J99BEIOJ8Jp3W0++GoRBdh0yQNIGL2g== +"@theia/monaco-editor-core@1.83.101": + version "1.83.101" + resolved "https://registry.yarnpkg.com/@theia/monaco-editor-core/-/monaco-editor-core-1.83.101.tgz#a0577396fb4c69540536df2d7fed2de4399c4fde" + integrity sha512-UaAi6CEvain/qbGD3o6Ufe8plLyzAVQ53p9Ke+MoBYDhb391+r+MuK++JtITqIrXqoa8OCjbt8wQxEFSNNO0Mw== "@tootallnate/once@1", "@tootallnate/once@^1.1.2": version "1.1.2"