Merge branch 'main' into joh/vscode-dts
This commit is contained in:
commit
edb91ace89
|
@ -49,7 +49,7 @@ export async function wrapWithAbbreviation(args: any): Promise<boolean> {
|
|||
|
||||
const helper = getEmmetHelper();
|
||||
|
||||
const operationRanges = editor.selections.sort((a, b) => a.start.compareTo(b.start)).map(selection => {
|
||||
const operationRanges = Array.from(editor.selections).sort((a, b) => a.start.compareTo(b.start)).map(selection => {
|
||||
let rangeToReplace: vscode.Range = selection;
|
||||
// wrap around the node if the selection falls inside its open or close tag
|
||||
{
|
||||
|
|
|
@ -8,8 +8,8 @@ import { getHtmlFlatNode, offsetRangeToSelection, validate } from './util';
|
|||
import { getRootNode } from './parseDocument';
|
||||
import { HtmlNode as HtmlFlatNode } from 'EmmetFlatNode';
|
||||
|
||||
let balanceOutStack: Array<vscode.Selection[]> = [];
|
||||
let lastBalancedSelections: vscode.Selection[] = [];
|
||||
let balanceOutStack: Array<readonly vscode.Selection[]> = [];
|
||||
let lastBalancedSelections: readonly vscode.Selection[] = [];
|
||||
|
||||
export function balanceOut() {
|
||||
balance(true);
|
||||
|
@ -31,10 +31,8 @@ function balance(out: boolean) {
|
|||
}
|
||||
|
||||
const rangeFn = out ? getRangeToBalanceOut : getRangeToBalanceIn;
|
||||
let newSelections: vscode.Selection[] = [];
|
||||
editor.selections.forEach(selection => {
|
||||
const range = rangeFn(document, rootNode, selection);
|
||||
newSelections.push(range);
|
||||
let newSelections: readonly vscode.Selection[] = editor.selections.map(selection => {
|
||||
return rangeFn(document, rootNode, selection);
|
||||
});
|
||||
|
||||
// check whether we are starting a balance elsewhere
|
||||
|
@ -122,7 +120,7 @@ function getRangeToBalanceIn(document: vscode.TextDocument, rootNode: HtmlFlatNo
|
|||
return offsetRangeToSelection(document, firstChild.start, firstChild.end);
|
||||
}
|
||||
|
||||
function areSameSelections(a: vscode.Selection[], b: vscode.Selection[]): boolean {
|
||||
function areSameSelections(a: readonly vscode.Selection[], b: readonly vscode.Selection[]): boolean {
|
||||
if (a.length !== b.length) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ export function mergeLines() {
|
|||
}
|
||||
|
||||
return editor.edit(editBuilder => {
|
||||
editor.selections.reverse().forEach(selection => {
|
||||
Array.from(editor.selections).reverse().forEach(selection => {
|
||||
const textEdit = getRangesToReplace(editor.document, selection, rootNode);
|
||||
if (textEdit) {
|
||||
editBuilder.replace(textEdit.range, textEdit.newText);
|
||||
|
|
|
@ -19,7 +19,7 @@ export function removeTag() {
|
|||
return;
|
||||
}
|
||||
|
||||
let finalRangesToRemove = editor.selections.reverse()
|
||||
let finalRangesToRemove = Array.from(editor.selections).reverse()
|
||||
.reduce<vscode.Range[]>((prev, selection) =>
|
||||
prev.concat(getRangesToRemove(editor.document, rootNode, selection)), []);
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ export function splitJoinTag() {
|
|||
}
|
||||
|
||||
return editor.edit(editBuilder => {
|
||||
editor.selections.reverse().forEach(selection => {
|
||||
Array.from(editor.selections).reverse().forEach(selection => {
|
||||
const documentText = document.getText();
|
||||
const offset = document.offsetAt(selection.start);
|
||||
const nodeToUpdate = getHtmlFlatNode(documentText, rootNode, offset, true);
|
||||
|
|
|
@ -28,7 +28,7 @@ export function toggleComment(): Thenable<boolean> | undefined {
|
|||
|
||||
return editor.edit(editBuilder => {
|
||||
let allEdits: vscode.TextEdit[][] = [];
|
||||
editor.selections.reverse().forEach(selection => {
|
||||
Array.from(editor.selections).reverse().forEach(selection => {
|
||||
const edits = isStyleSheet(editor.document.languageId) ? toggleCommentStylesheet(editor.document, selection, <Stylesheet>rootNode) : toggleCommentHTML(editor.document, selection, rootNode!);
|
||||
if (edits.length > 0) {
|
||||
allEdits.push(edits);
|
||||
|
|
|
@ -23,7 +23,7 @@ export function updateImageSize(): Promise<boolean> | undefined {
|
|||
}
|
||||
const editor = window.activeTextEditor;
|
||||
|
||||
const allUpdatesPromise = editor.selections.reverse().map(selection => {
|
||||
const allUpdatesPromise = Array.from(editor.selections).reverse().map(selection => {
|
||||
const position = selection.isReversed ? selection.active : selection.anchor;
|
||||
if (!isStyleSheet(editor.document.languageId)) {
|
||||
return updateImageSizeHTML(editor, position);
|
||||
|
|
|
@ -25,7 +25,7 @@ export async function updateTag(tagName: string | undefined): Promise<boolean |
|
|||
return;
|
||||
}
|
||||
|
||||
const rangesToUpdate = editor.selections.reverse()
|
||||
const rangesToUpdate = Array.from(editor.selections).reverse()
|
||||
.reduce<TagRange[]>((prev, selection) =>
|
||||
prev.concat(getRangesToUpdate(document, selection, rootNode)), []);
|
||||
if (!rangesToUpdate.length) {
|
||||
|
|
|
@ -49,7 +49,7 @@ export function applyLineChanges(original: TextDocument, modified: TextDocument,
|
|||
return result.join('');
|
||||
}
|
||||
|
||||
export function toLineRanges(selections: Selection[], textDocument: TextDocument): Range[] {
|
||||
export function toLineRanges(selections: readonly Selection[], textDocument: TextDocument): Range[] {
|
||||
const lineRanges = selections.map(s => {
|
||||
const startLine = textDocument.lineAt(s.start.line);
|
||||
const endLine = textDocument.lineAt(s.end.line);
|
||||
|
|
|
@ -56,7 +56,9 @@ suite('git smoke test', function () {
|
|||
git = ext!.exports.getAPI(1);
|
||||
|
||||
if (git.repositories.length === 0) {
|
||||
await eventToPromise(git.onDidOpenRepository);
|
||||
const onDidOpenRepository = eventToPromise(git.onDidOpenRepository);
|
||||
await commands.executeCommand('git.openRepository', cwd);
|
||||
await onDidOpenRepository;
|
||||
}
|
||||
|
||||
assert.strictEqual(git.repositories.length, 1);
|
||||
|
|
|
@ -134,6 +134,7 @@ window.addEventListener('message', async event => {
|
|||
root.replaceWith(newContent.querySelector('.markdown-body')!);
|
||||
documentResource = event.data.source;
|
||||
} else {
|
||||
// Compare two elements but skip `data-line`
|
||||
const areEqual = (a: Element, b: Element): boolean => {
|
||||
if (a.isEqualNode(b)) {
|
||||
return true;
|
||||
|
@ -143,6 +144,23 @@ window.addEventListener('message', async event => {
|
|||
return false;
|
||||
}
|
||||
|
||||
const aAttrs = a.attributes;
|
||||
const bAttrs = b.attributes;
|
||||
if (aAttrs.length !== bAttrs.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (let i = 0; i < aAttrs.length; ++i) {
|
||||
const aAttr = aAttrs[i];
|
||||
const bAttr = bAttrs[i];
|
||||
if (aAttr.name !== bAttr.name) {
|
||||
return false;
|
||||
}
|
||||
if (aAttr.value !== bAttr.value && aAttr.name !== 'data-line') {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
const aChildren = Array.from(a.children);
|
||||
const bChildren = Array.from(b.children);
|
||||
|
||||
|
|
|
@ -15,10 +15,13 @@ function workspaceFile(...segments: string[]) {
|
|||
}
|
||||
|
||||
async function getLinksForFile(file: vscode.Uri): Promise<vscode.DocumentLink[]> {
|
||||
return (await vscode.commands.executeCommand<vscode.DocumentLink[]>('vscode.executeLinkProvider', file))!;
|
||||
console.log('getting links', file.toString(), Date.now());
|
||||
const r = (await vscode.commands.executeCommand<vscode.DocumentLink[]>('vscode.executeLinkProvider', file))!;
|
||||
console.log('got links', file.toString(), Date.now());
|
||||
return r;
|
||||
}
|
||||
|
||||
suite('Markdown Document links', () => {
|
||||
suite.skip('Markdown Document links', () => {
|
||||
|
||||
setup(async () => {
|
||||
// the tests make the assumption that link providers are already registered
|
||||
|
@ -94,7 +97,6 @@ suite('Markdown Document links', () => {
|
|||
assert.strictEqual(vscode.window.activeTextEditor!.selection.start.line, 1);
|
||||
});
|
||||
|
||||
|
||||
test('Should navigate to line number within non-md file', async () => {
|
||||
await withFileContents(testFileA, '[b](sub/foo.txt#L3)');
|
||||
|
||||
|
@ -147,15 +149,21 @@ function assertActiveDocumentUri(expectedUri: vscode.Uri) {
|
|||
}
|
||||
|
||||
async function withFileContents(file: vscode.Uri, contents: string): Promise<void> {
|
||||
console.log('openTextDocument', file.toString(), Date.now());
|
||||
const document = await vscode.workspace.openTextDocument(file);
|
||||
console.log('showTextDocument', file.toString(), Date.now());
|
||||
const editor = await vscode.window.showTextDocument(document);
|
||||
console.log('editTextDocument', file.toString(), Date.now());
|
||||
await editor.edit(edit => {
|
||||
edit.replace(new vscode.Range(0, 0, 1000, 0), contents);
|
||||
});
|
||||
console.log('opened done', vscode.window.activeTextEditor?.document.toString(), Date.now());
|
||||
}
|
||||
|
||||
async function executeLink(link: vscode.DocumentLink) {
|
||||
console.log('executeingLink', link.target?.toString(), Date.now());
|
||||
|
||||
const args = JSON.parse(decodeURIComponent(link.target!.query));
|
||||
await vscode.commands.executeCommand(link.target!.path, args);
|
||||
console.log('executedLink', vscode.window.activeTextEditor?.document.toString(), Date.now());
|
||||
}
|
||||
|
||||
|
|
24
src/bootstrap-window.js
vendored
24
src/bootstrap-window.js
vendored
|
@ -45,11 +45,13 @@
|
|||
async function load(modulePaths, resultCallback, options) {
|
||||
const isDev = !!safeProcess.env['VSCODE_DEV'];
|
||||
|
||||
// Error handler (TODO@sandbox non-sandboxed only)
|
||||
// Error handler (node.js enabled renderers only)
|
||||
let showDevtoolsOnError = isDev;
|
||||
safeProcess.on('uncaughtException', function (/** @type {string | Error} */ error) {
|
||||
onUnexpectedError(error, showDevtoolsOnError);
|
||||
});
|
||||
if (!safeProcess.sandboxed) {
|
||||
safeProcess.on('uncaughtException', function (/** @type {string | Error} */ error) {
|
||||
onUnexpectedError(error, showDevtoolsOnError);
|
||||
});
|
||||
}
|
||||
|
||||
// Await window configuration from preload
|
||||
const timeout = setTimeout(() => { console.error(`[resolve window config] Could not resolve window configuration within 10 seconds, but will continue to wait...`); }, 10000);
|
||||
|
@ -83,7 +85,7 @@
|
|||
developerDeveloperKeybindingsDisposable = registerDeveloperKeybindings(disallowReloadKeybinding);
|
||||
}
|
||||
|
||||
// Enable ASAR support (TODO@sandbox non-sandboxed only)
|
||||
// Enable ASAR support (node.js enabled renderers only)
|
||||
if (!safeProcess.sandboxed) {
|
||||
globalThis.MonacoBootstrap.enableASARSupport(configuration.appRoot);
|
||||
}
|
||||
|
@ -100,9 +102,12 @@
|
|||
|
||||
window.document.documentElement.setAttribute('lang', locale);
|
||||
|
||||
// Replace the patched electron fs with the original node fs for all AMD code (TODO@sandbox non-sandboxed only)
|
||||
// Define `fs` as `original-fs` to disable ASAR support
|
||||
// in fs-operations (node.js enabled renderers only)
|
||||
if (!safeProcess.sandboxed) {
|
||||
require.define('fs', [], function () { return require.__$__nodeRequire('original-fs'); });
|
||||
require.define('fs', [], function () {
|
||||
return require.__$__nodeRequire('original-fs');
|
||||
});
|
||||
}
|
||||
|
||||
window['MonacoEnvironment'] = {};
|
||||
|
@ -140,8 +145,9 @@
|
|||
'tas-client-umd': `${baseNodeModulesPath}/tas-client-umd/lib/tas-client-umd.js`
|
||||
};
|
||||
|
||||
// For priviledged renderers, allow to load built-in and other node.js
|
||||
// modules via AMD which has a fallback to using node.js `require`
|
||||
// Allow to load built-in and other node.js modules via AMD
|
||||
// which has a fallback to using node.js `require`
|
||||
// (node.js enabled renderers only)
|
||||
if (!safeProcess.sandboxed) {
|
||||
loaderConfig.amdModulesPattern = /(^vs\/)|(^vscode-textmate$)|(^vscode-oniguruma$)|(^xterm$)|(^xterm-addon-search$)|(^xterm-addon-unicode11$)|(^xterm-addon-webgl$)|(^iconv-lite-umd$)|(^jschardet$)|(^@vscode\/vscode-languagedetection$)|(^tas-client-umd$)/;
|
||||
}
|
||||
|
|
3
src/bootstrap.js
vendored
3
src/bootstrap.js
vendored
|
@ -42,9 +42,6 @@
|
|||
//#region Add support for using node_modules.asar
|
||||
|
||||
/**
|
||||
* TODO@sandbox remove the support for passing in `appRoot` once
|
||||
* sandbox is fully enabled
|
||||
*
|
||||
* @param {string=} appRoot
|
||||
*/
|
||||
function enableASARSupport(appRoot) {
|
||||
|
|
|
@ -34,6 +34,7 @@ export interface IMenuBarOptions {
|
|||
getKeybinding?: (action: IAction) => ResolvedKeybinding | undefined;
|
||||
alwaysOnMnemonics?: boolean;
|
||||
compactMode?: Direction;
|
||||
actionRunner?: IActionRunner;
|
||||
getCompactMenuActions?: () => IAction[]
|
||||
}
|
||||
|
||||
|
@ -109,7 +110,7 @@ export class MenuBar extends Disposable {
|
|||
|
||||
this.menuUpdater = this._register(new RunOnceScheduler(() => this.update(), 200));
|
||||
|
||||
this.actionRunner = this._register(new ActionRunner());
|
||||
this.actionRunner = this.options.actionRunner ?? this._register(new ActionRunner());
|
||||
this._register(this.actionRunner.onBeforeRun(() => {
|
||||
this.setUnfocusedState();
|
||||
}));
|
||||
|
|
|
@ -101,6 +101,7 @@ export class MenuId {
|
|||
static readonly ExplorerContext = new MenuId('ExplorerContext');
|
||||
static readonly ExtensionContext = new MenuId('ExtensionContext');
|
||||
static readonly GlobalActivity = new MenuId('GlobalActivity');
|
||||
static readonly LayoutControlMenu = new MenuId('LayoutControlMenu');
|
||||
static readonly MenubarMainMenu = new MenuId('MenubarMainMenu');
|
||||
static readonly MenubarAppearanceMenu = new MenuId('MenubarAppearanceMenu');
|
||||
static readonly MenubarDebugMenu = new MenuId('MenubarDebugMenu');
|
||||
|
|
|
@ -59,11 +59,15 @@ export class ToggleActivityBarVisibilityAction extends Action2 {
|
|||
category: CATEGORIES.View,
|
||||
f1: true,
|
||||
toggled: ContextKeyExpr.equals('config.workbench.activityBar.visible', true),
|
||||
menu: {
|
||||
menu: [{
|
||||
id: MenuId.MenubarAppearanceMenu,
|
||||
group: '2_workbench_layout',
|
||||
order: 4
|
||||
}
|
||||
}, {
|
||||
id: MenuId.LayoutControlMenu,
|
||||
group: '0_workbench_layout',
|
||||
order: 3
|
||||
}]
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -226,11 +230,15 @@ registerAction2(class extends Action2 {
|
|||
category: CATEGORIES.View,
|
||||
f1: true,
|
||||
toggled: EditorAreaVisibleContext,
|
||||
menu: {
|
||||
menu: [{
|
||||
id: MenuId.MenubarAppearanceMenu,
|
||||
group: '2_workbench_layout',
|
||||
order: 5
|
||||
}
|
||||
}, {
|
||||
id: MenuId.LayoutControlMenu,
|
||||
group: '0_workbench_layout',
|
||||
order: 5
|
||||
}]
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -274,40 +282,53 @@ class ToggleSidebarVisibilityAction extends Action2 {
|
|||
|
||||
registerAction2(ToggleSidebarVisibilityAction);
|
||||
|
||||
MenuRegistry.appendMenuItems([{
|
||||
id: MenuId.ViewContainerTitleContext,
|
||||
item: {
|
||||
group: '3_workbench_layout_move',
|
||||
command: {
|
||||
id: ToggleSidebarVisibilityAction.ID,
|
||||
title: localize('compositePart.hideSideBarLabel', "Hide Side Bar"),
|
||||
},
|
||||
when: ContextKeyExpr.and(SideBarVisibleContext, ContextKeyExpr.equals('viewContainerLocation', ViewContainerLocationToString(ViewContainerLocation.Sidebar))),
|
||||
order: 2
|
||||
MenuRegistry.appendMenuItems([
|
||||
{
|
||||
id: MenuId.ViewContainerTitleContext,
|
||||
item: {
|
||||
group: '3_workbench_layout_move',
|
||||
command: {
|
||||
id: ToggleSidebarVisibilityAction.ID,
|
||||
title: localize('compositePart.hideSideBarLabel', "Hide Side Bar"),
|
||||
},
|
||||
when: ContextKeyExpr.and(SideBarVisibleContext, ContextKeyExpr.equals('viewContainerLocation', ViewContainerLocationToString(ViewContainerLocation.Sidebar))),
|
||||
order: 2
|
||||
}
|
||||
}, {
|
||||
id: MenuId.ViewTitleContext,
|
||||
item: {
|
||||
group: '3_workbench_layout_move',
|
||||
command: {
|
||||
id: ToggleSidebarVisibilityAction.ID,
|
||||
title: localize('compositePart.hideSideBarLabel', "Hide Side Bar"),
|
||||
},
|
||||
when: ContextKeyExpr.and(SideBarVisibleContext, ContextKeyExpr.equals('viewLocation', ViewContainerLocationToString(ViewContainerLocation.Sidebar))),
|
||||
order: 2
|
||||
}
|
||||
}, {
|
||||
id: MenuId.MenubarAppearanceMenu,
|
||||
item: {
|
||||
group: '2_workbench_layout',
|
||||
command: {
|
||||
id: ToggleSidebarVisibilityAction.ID,
|
||||
title: localize({ key: 'miShowSidebar', comment: ['&& denotes a mnemonic'] }, "Show &&Side Bar"),
|
||||
toggled: SideBarVisibleContext
|
||||
},
|
||||
order: 1
|
||||
}
|
||||
}, {
|
||||
id: MenuId.LayoutControlMenu,
|
||||
item: {
|
||||
group: '0_workbench_layout',
|
||||
command: {
|
||||
id: ToggleSidebarVisibilityAction.ID,
|
||||
title: localize('miShowSidebarNoMnnemonic', "Show Side Bar"),
|
||||
toggled: SideBarVisibleContext
|
||||
},
|
||||
order: 0
|
||||
}
|
||||
}
|
||||
}, {
|
||||
id: MenuId.ViewTitleContext,
|
||||
item: {
|
||||
group: '3_workbench_layout_move',
|
||||
command: {
|
||||
id: ToggleSidebarVisibilityAction.ID,
|
||||
title: localize('compositePart.hideSideBarLabel', "Hide Side Bar"),
|
||||
},
|
||||
when: ContextKeyExpr.and(SideBarVisibleContext, ContextKeyExpr.equals('viewLocation', ViewContainerLocationToString(ViewContainerLocation.Sidebar))),
|
||||
order: 2
|
||||
}
|
||||
}, {
|
||||
id: MenuId.MenubarAppearanceMenu,
|
||||
item: {
|
||||
group: '2_workbench_layout',
|
||||
command: {
|
||||
id: ToggleSidebarVisibilityAction.ID,
|
||||
title: localize({ key: 'miShowSidebar', comment: ['&& denotes a mnemonic'] }, "Show &&Side Bar"),
|
||||
toggled: SideBarVisibleContext
|
||||
},
|
||||
order: 1
|
||||
}
|
||||
}]);
|
||||
]);
|
||||
|
||||
// --- Toggle Statusbar Visibility
|
||||
|
||||
|
@ -328,11 +349,15 @@ export class ToggleStatusbarVisibilityAction extends Action2 {
|
|||
category: CATEGORIES.View,
|
||||
f1: true,
|
||||
toggled: ContextKeyExpr.equals('config.workbench.statusBar.visible', true),
|
||||
menu: {
|
||||
menu: [{
|
||||
id: MenuId.MenubarAppearanceMenu,
|
||||
group: '2_workbench_layout',
|
||||
order: 3
|
||||
}
|
||||
}, {
|
||||
id: MenuId.LayoutControlMenu,
|
||||
group: '0_workbench_layout',
|
||||
order: 1
|
||||
}]
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ import { MenuId, MenuRegistry, SyncActionDescriptor } from 'vs/platform/actions/
|
|||
import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { CATEGORIES, Extensions as WorkbenchExtensions, IWorkbenchActionRegistry } from 'vs/workbench/common/actions';
|
||||
import { ActiveAuxiliaryContext, AuxiliaryBarVisibleContext } from 'vs/workbench/common/auxiliarybar';
|
||||
import { AuxiliaryBarVisibleContext } from 'vs/workbench/common/auxiliarybar';
|
||||
import { ViewContainerLocation, ViewContainerLocationToString } from 'vs/workbench/common/views';
|
||||
import { IWorkbenchLayoutService, Parts } from 'vs/workbench/services/layout/browser/layoutService';
|
||||
import { IPaneCompositePartService } from 'vs/workbench/services/panecomposite/browser/panecomposite';
|
||||
|
@ -62,6 +62,19 @@ class FocusAuxiliaryBarAction extends Action {
|
|||
}
|
||||
|
||||
MenuRegistry.appendMenuItems([
|
||||
{
|
||||
id: MenuId.LayoutControlMenu,
|
||||
item: {
|
||||
group: '0_workbench_layout',
|
||||
command: {
|
||||
id: ToggleAuxiliaryBarAction.ID,
|
||||
title: localize({ key: 'miShowAuxiliaryBar', comment: ['&& denotes a mnemonic'] }, "Show Si&&de Panel"),
|
||||
toggled: AuxiliaryBarVisibleContext
|
||||
},
|
||||
when: ContextKeyExpr.equals('config.workbench.experimental.sidePanel.enabled', true),
|
||||
order: 4
|
||||
}
|
||||
},
|
||||
{
|
||||
id: MenuId.MenubarAppearanceMenu,
|
||||
item: {
|
||||
|
@ -69,7 +82,7 @@ MenuRegistry.appendMenuItems([
|
|||
command: {
|
||||
id: ToggleAuxiliaryBarAction.ID,
|
||||
title: localize({ key: 'miShowAuxiliaryBar', comment: ['&& denotes a mnemonic'] }, "Show Si&&de Panel"),
|
||||
toggled: ActiveAuxiliaryContext
|
||||
toggled: AuxiliaryBarVisibleContext
|
||||
},
|
||||
when: ContextKeyExpr.equals('config.workbench.experimental.sidePanel.enabled', true),
|
||||
order: 5
|
||||
|
|
|
@ -298,6 +298,17 @@ MenuRegistry.appendMenuItems([
|
|||
},
|
||||
order: 5
|
||||
}
|
||||
}, {
|
||||
id: MenuId.LayoutControlMenu,
|
||||
item: {
|
||||
group: '0_workbench_layout',
|
||||
command: {
|
||||
id: TogglePanelAction.ID,
|
||||
title: localize({ key: 'miShowPanel', comment: ['&& denotes a mnemonic'] }, "Show &&Panel"),
|
||||
toggled: ActivePanelContext
|
||||
},
|
||||
order: 4
|
||||
}
|
||||
}, {
|
||||
id: MenuId.ViewTitleContext,
|
||||
item: {
|
||||
|
|
|
@ -132,11 +132,34 @@
|
|||
margin-left: auto;
|
||||
}
|
||||
|
||||
.monaco-workbench.mac:not(web) .part.titlebar > .window-controls-container {
|
||||
position: absolute;
|
||||
right: 0px;
|
||||
width: 28px;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.monaco-workbench.mac:not(web) .part.titlebar > .window-controls-container.show-layout-control {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.monaco-workbench.fullscreen .part.titlebar > .window-controls-container {
|
||||
display: none;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.monaco-workbench .part.titlebar > .window-controls-container.show-layout-control {
|
||||
width: 160px;
|
||||
}
|
||||
|
||||
.monaco-workbench .part.titlebar > .window-controls-container > .layout-dropdown-container {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.monaco-workbench .part.titlebar > .window-controls-container.show-layout-control > .layout-dropdown-container {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.monaco-workbench .part.titlebar > .window-controls-container > .window-icon {
|
||||
display: inline-block;
|
||||
line-height: 30px;
|
||||
|
|
|
@ -8,7 +8,7 @@ import { IMenuService, MenuId, IMenu, SubmenuItemAction, registerAction2, Action
|
|||
import { registerThemingParticipant, IThemeService } from 'vs/platform/theme/common/themeService';
|
||||
import { MenuBarVisibility, getTitleBarStyle, IWindowOpenable, getMenuBarVisibility } from 'vs/platform/windows/common/windows';
|
||||
import { ContextKeyExpr, IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { IAction, Action, SubmenuAction, Separator } from 'vs/base/common/actions';
|
||||
import { IAction, Action, SubmenuAction, Separator, IActionRunner, ActionRunner, WorkbenchActionExecutedEvent, WorkbenchActionExecutedClassification } from 'vs/base/common/actions';
|
||||
import { addDisposableListener, Dimension, EventType } from 'vs/base/browser/dom';
|
||||
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
||||
import { isMacintosh, isWeb, isIOS, isNative } from 'vs/base/common/platform';
|
||||
|
@ -38,6 +38,7 @@ import { KeyCode } from 'vs/base/common/keyCodes';
|
|||
import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
|
||||
import { IsMacNativeContext, IsWebContext } from 'vs/platform/contextkey/common/contextkeys';
|
||||
import { ICommandService } from 'vs/platform/commands/common/commands';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
|
||||
export type IOpenRecentAction = IAction & { uri: URI, remoteAuthority?: string };
|
||||
|
||||
|
@ -374,6 +375,7 @@ export class CustomMenubarControl extends MenubarControl {
|
|||
private alwaysOnMnemonics: boolean = false;
|
||||
private focusInsideMenubar: boolean = false;
|
||||
private visible: boolean = true;
|
||||
private actionRunner: IActionRunner;
|
||||
private readonly webNavigationMenu = this._register(this.menuService.createMenu(MenuId.MenubarHomeMenu, this.contextKeyService));
|
||||
|
||||
private readonly _onVisibilityChange: Emitter<boolean>;
|
||||
|
@ -394,6 +396,7 @@ export class CustomMenubarControl extends MenubarControl {
|
|||
@IAccessibilityService accessibilityService: IAccessibilityService,
|
||||
@IThemeService private readonly themeService: IThemeService,
|
||||
@IWorkbenchLayoutService private readonly layoutService: IWorkbenchLayoutService,
|
||||
@ITelemetryService private readonly telemetryService: ITelemetryService,
|
||||
@IHostService hostService: IHostService,
|
||||
@ICommandService commandService: ICommandService
|
||||
) {
|
||||
|
@ -402,6 +405,11 @@ export class CustomMenubarControl extends MenubarControl {
|
|||
this._onVisibilityChange = this._register(new Emitter<boolean>());
|
||||
this._onFocusStateChange = this._register(new Emitter<boolean>());
|
||||
|
||||
this.actionRunner = this._register(new ActionRunner());
|
||||
this.actionRunner.onDidRun(e => {
|
||||
this.telemetryService.publicLog2<WorkbenchActionExecutedEvent, WorkbenchActionExecutedClassification>('workbenchActionExecuted', { id: e.action.id, from: 'menu' });
|
||||
});
|
||||
|
||||
this.workspacesService.getRecentlyOpened().then((recentlyOpened) => {
|
||||
this.recentlyOpened = recentlyOpened;
|
||||
});
|
||||
|
@ -811,6 +819,7 @@ export class CustomMenubarControl extends MenubarControl {
|
|||
enableMnemonics: this.currentEnableMenuBarMnemonics,
|
||||
disableAltFocus: this.currentDisableMenuBarAltFocus,
|
||||
visibility: this.currentMenubarVisibility,
|
||||
actionRunner: this.actionRunner,
|
||||
getKeybinding: (action) => this.keybindingService.lookupKeybinding(action.id),
|
||||
alwaysOnMnemonics: this.alwaysOnMnemonics,
|
||||
compactMode: this.currentCompactMenuMode,
|
||||
|
|
|
@ -12,7 +12,7 @@ import { getZoomFactor } from 'vs/base/browser/browser';
|
|||
import { MenuBarVisibility, getTitleBarStyle, getMenuBarVisibility } from 'vs/platform/windows/common/windows';
|
||||
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
|
||||
import { StandardMouseEvent } from 'vs/base/browser/mouseEvent';
|
||||
import { IAction } from 'vs/base/common/actions';
|
||||
import { IAction, SubmenuAction } from 'vs/base/common/actions';
|
||||
import { IConfigurationService, IConfigurationChangeEvent } from 'vs/platform/configuration/common/configuration';
|
||||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { DisposableStore, dispose } from 'vs/base/common/lifecycle';
|
||||
|
@ -28,14 +28,14 @@ import { trim } from 'vs/base/common/strings';
|
|||
import { EventType, EventHelper, Dimension, isAncestor, append, $, addDisposableListener, runAtThisOrScheduleAtNextAnimationFrame, prepend } from 'vs/base/browser/dom';
|
||||
import { CustomMenubarControl } from 'vs/workbench/browser/parts/titlebar/menubarControl';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { template } from 'vs/base/common/labels';
|
||||
import { mnemonicButtonLabel, template } from 'vs/base/common/labels';
|
||||
import { ILabelService } from 'vs/platform/label/common/label';
|
||||
import { Emitter } from 'vs/base/common/event';
|
||||
import { IStorageService } from 'vs/platform/storage/common/storage';
|
||||
import { Parts, IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService';
|
||||
import { RunOnceScheduler } from 'vs/base/common/async';
|
||||
import { createAndFillInContextMenuActions } from 'vs/platform/actions/browser/menuEntryActionViewItem';
|
||||
import { IMenuService, IMenu, MenuId } from 'vs/platform/actions/common/actions';
|
||||
import { IMenuService, IMenu, MenuId, MenuItemAction } from 'vs/platform/actions/common/actions';
|
||||
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { IHostService } from 'vs/workbench/services/host/browser/host';
|
||||
import { IProductService } from 'vs/platform/product/common/productService';
|
||||
|
@ -43,6 +43,10 @@ import { Schemas } from 'vs/base/common/network';
|
|||
import { withNullAsUndefined } from 'vs/base/common/types';
|
||||
import { Codicon, iconRegistry } from 'vs/base/common/codicons';
|
||||
import { getVirtualWorkspaceLocation } from 'vs/platform/remote/common/remoteHosts';
|
||||
import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar';
|
||||
import { DropdownMenuActionViewItem } from 'vs/base/browser/ui/dropdown/dropdownActionViewItem';
|
||||
import { AnchorAlignment } from 'vs/base/browser/ui/contextview/contextview';
|
||||
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
||||
|
||||
export class TitlebarPart extends Part implements ITitleService {
|
||||
|
||||
|
@ -66,10 +70,13 @@ export class TitlebarPart extends Part implements ITitleService {
|
|||
declare readonly _serviceBrand: undefined;
|
||||
|
||||
protected title!: HTMLElement;
|
||||
|
||||
protected customMenubar: CustomMenubarControl | undefined;
|
||||
protected appIcon: HTMLElement | undefined;
|
||||
private appIconBadge: HTMLElement | undefined;
|
||||
protected menubar?: HTMLElement;
|
||||
protected windowControls: HTMLElement | undefined;
|
||||
private layoutToolbar: ActionBar | undefined;
|
||||
protected lastLayoutDimensions: Dimension | undefined;
|
||||
private titleBarStyle: 'native' | 'custom';
|
||||
|
||||
|
@ -91,12 +98,13 @@ export class TitlebarPart extends Part implements ITitleService {
|
|||
@IWorkbenchEnvironmentService protected readonly environmentService: IWorkbenchEnvironmentService,
|
||||
@IWorkspaceContextService private readonly contextService: IWorkspaceContextService,
|
||||
@IInstantiationService protected readonly instantiationService: IInstantiationService,
|
||||
@IKeybindingService private readonly keybindingService: IKeybindingService,
|
||||
@IThemeService themeService: IThemeService,
|
||||
@ILabelService private readonly labelService: ILabelService,
|
||||
@IStorageService storageService: IStorageService,
|
||||
@IWorkbenchLayoutService layoutService: IWorkbenchLayoutService,
|
||||
@IMenuService menuService: IMenuService,
|
||||
@IContextKeyService contextKeyService: IContextKeyService,
|
||||
@IMenuService private readonly menuService: IMenuService,
|
||||
@IContextKeyService private readonly contextKeyService: IContextKeyService,
|
||||
@IHostService private readonly hostService: IHostService,
|
||||
@IProductService private readonly productService: IProductService,
|
||||
) {
|
||||
|
@ -143,6 +151,10 @@ export class TitlebarPart extends Part implements ITitleService {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (this.titleBarStyle !== 'native' && this.windowControls && event.affectsConfiguration('workbench.experimental.layoutControl.enabled')) {
|
||||
this.windowControls.classList.toggle('show-layout-control', this.layoutControlEnabled);
|
||||
}
|
||||
}
|
||||
|
||||
protected onMenubarVisibilityChanged(visible: boolean): void {
|
||||
|
@ -395,6 +407,53 @@ export class TitlebarPart extends Part implements ITitleService {
|
|||
this.titleUpdater.schedule();
|
||||
}
|
||||
|
||||
if (this.titleBarStyle !== 'native') {
|
||||
this.windowControls = append(this.element, $('div.window-controls-container'));
|
||||
this.windowControls.classList.toggle('show-layout-control', this.layoutControlEnabled);
|
||||
|
||||
const layoutDropdownContainer = append(this.windowControls, $('div.layout-dropdown-container'));
|
||||
this.layoutToolbar = new ActionBar(layoutDropdownContainer,
|
||||
{
|
||||
ariaLabel: localize('layoutMenu', "Configure Layout"),
|
||||
actionViewItemProvider: action => {
|
||||
if (action instanceof SubmenuAction) {
|
||||
return new DropdownMenuActionViewItem(action, action.actions, this.contextMenuService, {
|
||||
classNames: Codicon.editorLayout.classNamesArray,
|
||||
anchorAlignmentProvider: () => AnchorAlignment.RIGHT,
|
||||
keybindingProvider: action => this.keybindingService.lookupKeybinding(action.id)
|
||||
});
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
const menu = this._register(this.menuService.createMenu(MenuId.LayoutControlMenu, this.contextKeyService));
|
||||
const updateLayoutMenu = () => {
|
||||
if (!this.layoutToolbar) {
|
||||
return;
|
||||
}
|
||||
|
||||
const actions: IAction[] = [];
|
||||
const toDispose = createAndFillInContextMenuActions(menu, undefined, { primary: [], secondary: actions });
|
||||
|
||||
this.layoutToolbar.clear();
|
||||
this.layoutToolbar.push(new SubmenuAction('stenir', localize('layoutMenu', "Configure Layout"), actions.map(action => {
|
||||
if (action instanceof MenuItemAction) {
|
||||
(action as IAction).label = mnemonicButtonLabel(typeof action.item.title === 'string'
|
||||
? action.item.title
|
||||
: action.item.title.mnemonicTitle ?? action.item.title.value, true);
|
||||
}
|
||||
return action;
|
||||
})));
|
||||
|
||||
toDispose.dispose();
|
||||
};
|
||||
|
||||
menu.onDidChange(updateLayoutMenu);
|
||||
updateLayoutMenu();
|
||||
}
|
||||
|
||||
// Context menu on title
|
||||
[EventType.CONTEXT_MENU, EventType.MOUSE_DOWN].forEach(event => {
|
||||
this._register(addDisposableListener(this.title, event, e => {
|
||||
|
@ -413,6 +472,10 @@ export class TitlebarPart extends Part implements ITitleService {
|
|||
return;
|
||||
}
|
||||
|
||||
if (e.target && this.layoutToolbar && isAncestor(e.target as HTMLElement, this.layoutToolbar.getContainer())) {
|
||||
return;
|
||||
}
|
||||
|
||||
const active = document.activeElement;
|
||||
setTimeout(() => {
|
||||
if (active instanceof HTMLElement) {
|
||||
|
@ -507,6 +570,10 @@ export class TitlebarPart extends Part implements ITitleService {
|
|||
return getMenuBarVisibility(this.configurationService);
|
||||
}
|
||||
|
||||
private get layoutControlEnabled(): boolean {
|
||||
return this.configurationService.getValue<boolean>('workbench.experimental.layoutControl.enabled');
|
||||
}
|
||||
|
||||
updateLayout(dimension: Dimension): void {
|
||||
this.lastLayoutDimensions = dimension;
|
||||
|
||||
|
|
|
@ -356,6 +356,11 @@ const registry = Registry.as<IConfigurationRegistry>(ConfigurationExtensions.Con
|
|||
// On Mac, the delay is 1500.
|
||||
'default': isMacintosh ? 1500 : 500
|
||||
},
|
||||
'workbench.experimental.layoutControl.enabled': {
|
||||
'type': 'boolean',
|
||||
'default': product.quality !== 'stable',
|
||||
'description': localize('layoutControlEnabled', "Controls whether the layout control button in the custom title bar is enabled."),
|
||||
},
|
||||
'workbench.experimental.sidePanel.enabled': {
|
||||
'type': 'boolean',
|
||||
'default': false,
|
||||
|
|
|
@ -227,12 +227,13 @@ export class ExperimentService extends Disposable implements IExperimentService
|
|||
}
|
||||
|
||||
protected async getExperiments(): Promise<IRawExperiment[] | null> {
|
||||
if (!this.productService.experimentsUrl || this.configurationService.getValue('workbench.enableExperiments') === false) {
|
||||
const experimentsUrl = this.configurationService.getValue<string>('_workbench.experimentsUrl') || this.productService.experimentsUrl;
|
||||
if (!experimentsUrl || this.configurationService.getValue('workbench.enableExperiments') === false) {
|
||||
return [];
|
||||
}
|
||||
|
||||
try {
|
||||
const context = await this.requestService.request({ type: 'GET', url: this.productService.experimentsUrl }, CancellationToken.None);
|
||||
const context = await this.requestService.request({ type: 'GET', url: experimentsUrl }, CancellationToken.None);
|
||||
if (context.res.statusCode !== 200) {
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -258,7 +258,12 @@ export class InteractiveEditor extends EditorPane {
|
|||
cellExecuteToolbar: MenuId.InteractiveCellExecute,
|
||||
cellExecutePrimary: undefined
|
||||
},
|
||||
cellEditorContributions: [],
|
||||
cellEditorContributions: EditorExtensionsRegistry.getSomeEditorContributions([
|
||||
SelectionClipboardContributionID,
|
||||
ContextMenuController.ID,
|
||||
ModesHoverController.ID,
|
||||
MarkerController.ID
|
||||
]),
|
||||
options: this.#notebookOptions
|
||||
});
|
||||
|
||||
|
@ -270,6 +275,9 @@ export class InteractiveEditor extends EditorPane {
|
|||
top: INPUT_EDITOR_PADDING,
|
||||
bottom: INPUT_EDITOR_PADDING
|
||||
},
|
||||
hover: {
|
||||
enabled: true
|
||||
}
|
||||
}
|
||||
}, {
|
||||
...{
|
||||
|
|
|
@ -446,7 +446,7 @@ registerAction2(class ExecuteCellInsertBelow extends NotebookCellAction {
|
|||
constructor() {
|
||||
super({
|
||||
id: EXECUTE_CELL_INSERT_BELOW,
|
||||
precondition: executeThisCellCondition,
|
||||
precondition: ContextKeyExpr.or(executeThisCellCondition, NOTEBOOK_CELL_TYPE.isEqualTo('markup')),
|
||||
title: localize('notebookActions.executeAndInsertBelow', "Execute Notebook Cell and Insert Below"),
|
||||
keybinding: {
|
||||
when: NOTEBOOK_CELL_LIST_FOCUSED,
|
||||
|
@ -460,14 +460,17 @@ registerAction2(class ExecuteCellInsertBelow extends NotebookCellAction {
|
|||
const idx = context.notebookEditor.getCellIndex(context.cell);
|
||||
const modeService = accessor.get(IModeService);
|
||||
const newFocusMode = context.cell.focusMode === CellFocusMode.Editor ? 'editor' : 'container';
|
||||
const executionP = runCell(accessor, context);
|
||||
const newCell = insertCell(modeService, context.notebookEditor, idx, CellKind.Code, 'below');
|
||||
|
||||
const newCell = insertCell(modeService, context.notebookEditor, idx, context.cell.cellKind, 'below');
|
||||
if (newCell) {
|
||||
context.notebookEditor.focusNotebookCell(newCell, newFocusMode);
|
||||
}
|
||||
|
||||
return executionP;
|
||||
if (context.cell.cellKind === CellKind.Markup) {
|
||||
context.cell.updateEditState(CellEditState.Preview, EXECUTE_CELL_INSERT_BELOW);
|
||||
} else {
|
||||
runCell(accessor, context);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -637,7 +637,7 @@ async function webviewPreloads(ctx: PreloadContext) {
|
|||
{
|
||||
let outputContainer = document.getElementById(event.data.cellId);
|
||||
if (!outputContainer) {
|
||||
viewModel.ensureOutputCell(event.data.cellId, -100000);
|
||||
viewModel.ensureOutputCell(event.data.cellId, -100000, true);
|
||||
outputContainer = document.getElementById(event.data.cellId);
|
||||
}
|
||||
outputContainer?.classList.add(...event.data.addedClassNames);
|
||||
|
@ -1032,7 +1032,7 @@ async function webviewPreloads(ctx: PreloadContext) {
|
|||
return;
|
||||
}
|
||||
|
||||
const cellOutput = this.ensureOutputCell(data.cellId, data.cellTop);
|
||||
const cellOutput = this.ensureOutputCell(data.cellId, data.cellTop, false);
|
||||
const outputNode = cellOutput.createOutputElement(data.outputId, data.outputOffset, data.left);
|
||||
outputNode.render(data.content, preloadsAndErrors);
|
||||
|
||||
|
@ -1040,13 +1040,18 @@ async function webviewPreloads(ctx: PreloadContext) {
|
|||
cellOutput.element.style.visibility = data.initiallyHidden ? 'hidden' : 'visible';
|
||||
}
|
||||
|
||||
public ensureOutputCell(cellId: string, cellTop: number): OutputCell {
|
||||
public ensureOutputCell(cellId: string, cellTop: number, skipCellTopUpdateIfExist: boolean): OutputCell {
|
||||
let cell = this._outputCells.get(cellId);
|
||||
let existed = !!cell;
|
||||
if (!cell) {
|
||||
cell = new OutputCell(cellId);
|
||||
this._outputCells.set(cellId, cell);
|
||||
}
|
||||
|
||||
if (existed && skipCellTopUpdateIfExist) {
|
||||
return cell;
|
||||
}
|
||||
|
||||
cell.element.style.top = cellTop + 'px';
|
||||
return cell;
|
||||
}
|
||||
|
|
|
@ -302,6 +302,46 @@ function createObjectValueSuggester(element: SettingsTreeSettingElement): IObjec
|
|||
};
|
||||
}
|
||||
|
||||
function isNonNullableNumericType(type: unknown): type is 'number' | 'integer' {
|
||||
return type === 'number' || type === 'integer';
|
||||
}
|
||||
|
||||
function parseNumericObjectValues(dataElement: SettingsTreeSettingElement, v: Record<string, unknown>): Record<string, unknown> {
|
||||
const newRecord: Record<string, unknown> = {};
|
||||
for (const key in v) {
|
||||
// Set to true/false once we're sure of the answer
|
||||
let keyMatchesNumericProperty: boolean | undefined;
|
||||
const patternProperties = dataElement.setting.objectPatternProperties;
|
||||
const properties = dataElement.setting.objectProperties;
|
||||
const additionalProperties = dataElement.setting.objectAdditionalProperties;
|
||||
|
||||
// Match the current record key against the properties of the object
|
||||
if (properties) {
|
||||
for (const propKey in properties) {
|
||||
if (propKey === key) {
|
||||
keyMatchesNumericProperty = isNonNullableNumericType(properties[propKey].type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (keyMatchesNumericProperty === undefined && patternProperties) {
|
||||
for (const patternKey in patternProperties) {
|
||||
if (key.match(patternKey)) {
|
||||
keyMatchesNumericProperty = isNonNullableNumericType(patternProperties[patternKey].type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (keyMatchesNumericProperty === undefined && additionalProperties && typeof additionalProperties !== 'boolean') {
|
||||
if (isNonNullableNumericType(additionalProperties.type)) {
|
||||
keyMatchesNumericProperty = true;
|
||||
}
|
||||
}
|
||||
newRecord[key] = keyMatchesNumericProperty ? Number(v[key]) : v[key];
|
||||
}
|
||||
return newRecord;
|
||||
}
|
||||
|
||||
function getListDisplayValue(element: SettingsTreeSettingElement): IListDataItem[] {
|
||||
if (!element.value || !isArray(element.value)) {
|
||||
return [];
|
||||
|
@ -1110,18 +1150,6 @@ export class SettingArrayRenderer extends AbstractSettingRenderer implements ITr
|
|||
return template;
|
||||
}
|
||||
|
||||
private onDidChangeList(template: ISettingListItemTemplate, newList: unknown[] | undefined): void {
|
||||
if (!template.context || !newList) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._onDidChangeSetting.fire({
|
||||
key: template.context.setting.key,
|
||||
value: newList,
|
||||
type: template.context.valueType
|
||||
});
|
||||
}
|
||||
|
||||
private computeNewList(template: ISettingListItemTemplate, e: ISettingListChangeEvent<IListDataItem>): string[] | undefined {
|
||||
if (template.context) {
|
||||
let newValue: string[] = [];
|
||||
|
@ -1191,17 +1219,15 @@ export class SettingArrayRenderer extends AbstractSettingRenderer implements ITr
|
|||
template.listWidget.cancelEdit();
|
||||
}));
|
||||
|
||||
template.onChange = (v) => {
|
||||
if (!renderArrayValidations(dataElement, template, v, false)) {
|
||||
let arrToSave;
|
||||
template.onChange = (v: string[] | undefined) => {
|
||||
if (v && !renderArrayValidations(dataElement, template, v, false)) {
|
||||
const itemType = dataElement.setting.arrayItemType;
|
||||
if (v && (itemType === 'number' || itemType === 'integer')) {
|
||||
arrToSave = v.map(a => +a);
|
||||
} else {
|
||||
arrToSave = v;
|
||||
}
|
||||
this.onDidChangeList(template, arrToSave);
|
||||
const arrToSave = isNonNullableNumericType(itemType) ? v.map(a => +a) : v;
|
||||
onChange(arrToSave);
|
||||
} else {
|
||||
// Save the setting unparsed and containing the errors.
|
||||
// renderArrayValidations will render relevant error messages.
|
||||
onChange(v);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1343,8 +1369,14 @@ export class SettingObjectRenderer extends AbstractSettingObjectRenderer impleme
|
|||
}));
|
||||
|
||||
template.onChange = (v: Record<string, unknown> | undefined) => {
|
||||
onChange(v);
|
||||
renderArrayValidations(dataElement, template, v, false);
|
||||
if (v && !renderArrayValidations(dataElement, template, v, false)) {
|
||||
const parsedRecord = parseNumericObjectValues(dataElement, v);
|
||||
onChange(parsedRecord);
|
||||
} else {
|
||||
// Save the setting unparsed and containing the errors.
|
||||
// renderArrayValidations will render relevant error messages.
|
||||
onChange(v);
|
||||
}
|
||||
};
|
||||
renderArrayValidations(dataElement, template, dataElement.value, true);
|
||||
}
|
||||
|
|
|
@ -576,7 +576,7 @@ export function isExcludeSetting(setting: ISetting): boolean {
|
|||
}
|
||||
|
||||
function isObjectRenderableSchema({ type }: IJSONSchema): boolean {
|
||||
return type === 'string' || type === 'boolean';
|
||||
return type === 'string' || type === 'boolean' || type === 'integer' || type === 'number';
|
||||
}
|
||||
|
||||
function isObjectSetting({
|
||||
|
|
|
@ -25,9 +25,9 @@ import { getTitleBarStyle } from 'vs/platform/windows/common/windows';
|
|||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { Codicon } from 'vs/base/common/codicons';
|
||||
import { NativeMenubarControl } from 'vs/workbench/electron-sandbox/parts/titlebar/menubarControl';
|
||||
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
||||
|
||||
export class TitlebarPart extends BrowserTitleBarPart {
|
||||
private windowControls: HTMLElement | undefined;
|
||||
private maxRestoreControl: HTMLElement | undefined;
|
||||
private dragRegion: HTMLElement | undefined;
|
||||
private resizer: HTMLElement | undefined;
|
||||
|
@ -53,6 +53,7 @@ export class TitlebarPart extends BrowserTitleBarPart {
|
|||
@INativeWorkbenchEnvironmentService environmentService: INativeWorkbenchEnvironmentService,
|
||||
@IWorkspaceContextService contextService: IWorkspaceContextService,
|
||||
@IInstantiationService instantiationService: IInstantiationService,
|
||||
@IKeybindingService keybindingService: IKeybindingService,
|
||||
@IThemeService themeService: IThemeService,
|
||||
@ILabelService labelService: ILabelService,
|
||||
@IStorageService storageService: IStorageService,
|
||||
|
@ -63,7 +64,7 @@ export class TitlebarPart extends BrowserTitleBarPart {
|
|||
@IProductService productService: IProductService,
|
||||
@INativeHostService private readonly nativeHostService: INativeHostService
|
||||
) {
|
||||
super(contextMenuService, configurationService, editorService, environmentService, contextService, instantiationService, themeService, labelService, storageService, layoutService, menuService, contextKeyService, hostService, productService);
|
||||
super(contextMenuService, configurationService, editorService, environmentService, contextService, instantiationService, keybindingService, themeService, labelService, storageService, layoutService, menuService, contextKeyService, hostService, productService);
|
||||
|
||||
this.environmentService = environmentService;
|
||||
}
|
||||
|
@ -187,9 +188,7 @@ export class TitlebarPart extends BrowserTitleBarPart {
|
|||
this.dragRegion = prepend(this.element, $('div.titlebar-drag-region'));
|
||||
|
||||
// Window Controls (Native Windows/Linux)
|
||||
if (!isMacintosh) {
|
||||
this.windowControls = append(this.element, $('div.window-controls-container'));
|
||||
|
||||
if (!isMacintosh && this.windowControls) {
|
||||
// Minimize
|
||||
const minimizeIcon = append(this.windowControls, $('div.window-icon.window-minimize' + Codicon.chromeMinimize.cssSelector));
|
||||
this._register(addDisposableListener(minimizeIcon, EventType.CLICK, e => {
|
||||
|
|
|
@ -15,7 +15,7 @@ import { PreferredGroup, SIDE_GROUP } from 'vs/workbench/services/editor/common/
|
|||
/**
|
||||
* Finds the target `IEditorGroup` given the instructions provided
|
||||
* that is best for the editor and matches the preferred group if
|
||||
* posisble.
|
||||
* possible.
|
||||
*/
|
||||
export function findGroup(accessor: ServicesAccessor, editor: IUntypedEditorInput, preferredGroup: PreferredGroup | undefined): [IEditorGroup, EditorActivation | undefined];
|
||||
export function findGroup(accessor: ServicesAccessor, editor: EditorInputWithOptions, preferredGroup: PreferredGroup | undefined): [IEditorGroup, EditorActivation | undefined];
|
||||
|
|
|
@ -38,8 +38,6 @@ export class SharedProcessService extends Disposable implements ISharedProcessSe
|
|||
// as a result. As such, make sure we await the `Restored`
|
||||
// phase before making a connection attempt, but also add a
|
||||
// timeout to be safe against possible deadlocks.
|
||||
// TODO@sandbox revisit this when the shared process connection
|
||||
// is more cruicial.
|
||||
await Promise.race([this.restoredBarrier.wait(), timeout(2000)]);
|
||||
|
||||
// Acquire a message port connected to the shared process
|
||||
|
|
18
src/vscode-dts/vscode.d.ts
vendored
18
src/vscode-dts/vscode.d.ts
vendored
|
@ -1107,13 +1107,13 @@ declare module 'vscode' {
|
|||
/**
|
||||
* The selections in this text editor. The primary selection is always at index 0.
|
||||
*/
|
||||
selections: Selection[];
|
||||
selections: readonly Selection[];
|
||||
|
||||
/**
|
||||
* The current visible ranges in the editor (vertically).
|
||||
* This accounts only for vertical scrolling, and not for horizontal scrolling.
|
||||
*/
|
||||
readonly visibleRanges: Range[];
|
||||
readonly visibleRanges: readonly Range[];
|
||||
|
||||
/**
|
||||
* Text editor options.
|
||||
|
@ -8656,7 +8656,7 @@ declare module 'vscode' {
|
|||
/**
|
||||
* The currently visible editors or an empty array.
|
||||
*/
|
||||
export let visibleTextEditors: TextEditor[];
|
||||
export let visibleTextEditors: readonly TextEditor[];
|
||||
|
||||
/**
|
||||
* An {@link Event} which fires when the {@link window.activeTextEditor active editor}
|
||||
|
@ -8669,7 +8669,7 @@ declare module 'vscode' {
|
|||
* An {@link Event} which fires when the array of {@link window.visibleTextEditors visible editors}
|
||||
* has changed.
|
||||
*/
|
||||
export const onDidChangeVisibleTextEditors: Event<TextEditor[]>;
|
||||
export const onDidChangeVisibleTextEditors: Event<readonly TextEditor[]>;
|
||||
|
||||
/**
|
||||
* An {@link Event} which fires when the selection in an editor has changed.
|
||||
|
@ -9354,7 +9354,7 @@ declare module 'vscode' {
|
|||
/**
|
||||
* Selected elements.
|
||||
*/
|
||||
readonly selection: T[];
|
||||
readonly selection: readonly T[];
|
||||
|
||||
}
|
||||
|
||||
|
@ -9388,7 +9388,7 @@ declare module 'vscode' {
|
|||
/**
|
||||
* Currently selected elements.
|
||||
*/
|
||||
readonly selection: T[];
|
||||
readonly selection: readonly T[];
|
||||
|
||||
/**
|
||||
* Event that is fired when the {@link TreeView.selection selection} has changed
|
||||
|
@ -13387,7 +13387,7 @@ declare module 'vscode' {
|
|||
/**
|
||||
* List of breakpoints.
|
||||
*/
|
||||
export let breakpoints: Breakpoint[];
|
||||
export let breakpoints: readonly Breakpoint[];
|
||||
|
||||
/**
|
||||
* An {@link Event} which fires when the {@link debug.activeDebugSession active debug session}
|
||||
|
@ -14322,7 +14322,7 @@ declare module 'vscode' {
|
|||
* The process of running tests should resolve the children of any test
|
||||
* items who have not yet been resolved.
|
||||
*/
|
||||
readonly include: TestItem[] | undefined;
|
||||
readonly include: readonly TestItem[] | undefined;
|
||||
|
||||
/**
|
||||
* An array of tests the user has marked as excluded from the test included
|
||||
|
@ -14331,7 +14331,7 @@ declare module 'vscode' {
|
|||
* May be omitted if no exclusions were requested. Test controllers should
|
||||
* not run excluded tests or any children of excluded tests.
|
||||
*/
|
||||
readonly exclude: TestItem[] | undefined;
|
||||
readonly exclude: readonly TestItem[] | undefined;
|
||||
|
||||
/**
|
||||
* The profile used for this request. This will always be defined
|
||||
|
|
7
src/vscode-dts/vscode.proposed.d.ts
vendored
7
src/vscode-dts/vscode.proposed.d.ts
vendored
|
@ -752,7 +752,7 @@ declare module 'vscode' {
|
|||
//#endregion
|
||||
|
||||
// eslint-disable-next-line vscode-dts-region-comments
|
||||
//#region @roblourens: new debug session option for simple UI 'managedByParent' (see https://github.com/microsoft/vscode/issues/128588)
|
||||
//#region notebookDebugOptions: @roblourens: new debug session option for simple UI 'managedByParent' (see https://github.com/microsoft/vscode/issues/128588)
|
||||
|
||||
/**
|
||||
* Options for {@link debug.startDebugging starting a debug session}.
|
||||
|
@ -774,8 +774,7 @@ declare module 'vscode' {
|
|||
|
||||
//#endregion
|
||||
|
||||
// eslint-disable-next-line vscode-dts-region-comments
|
||||
// #region scmValidation: @joaomoreno:
|
||||
// #region scmValidation: @joaomoreno
|
||||
|
||||
/**
|
||||
* Represents the validation type of the Source Control input.
|
||||
|
@ -830,7 +829,7 @@ declare module 'vscode' {
|
|||
|
||||
//#endregion
|
||||
|
||||
//#region scmSelectedProvider: @joaomoreno:
|
||||
//#region scmSelectedProvider: @joaomoreno
|
||||
|
||||
export interface SourceControl {
|
||||
|
||||
|
|
Loading…
Reference in a new issue