mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-11 02:32:35 -05:00
Merge from vscode 7eaf220cafb9d9e901370ffce02229171cbf3ea6
This commit is contained in:
committed by
Anthony Dresser
parent
39d9eed585
commit
a63578e6f7
@@ -8,6 +8,7 @@ import 'vs/css!./media/actions';
|
||||
import * as nls from 'vs/nls';
|
||||
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
||||
import { domEvent } from 'vs/base/browser/event';
|
||||
import { Color } from 'vs/base/common/color';
|
||||
import { Event } from 'vs/base/common/event';
|
||||
import { IDisposable, toDisposable, dispose, Disposable, DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { getDomNodePagePosition, createStyleSheet, createCSSRule, append, $ } from 'vs/base/browser/dom';
|
||||
@@ -123,14 +124,29 @@ class ToggleScreencastModeAction extends Action2 {
|
||||
const onMouseUp = domEvent(container, 'mouseup', true);
|
||||
const onMouseMove = domEvent(container, 'mousemove', true);
|
||||
|
||||
const updateMouseIndicatorColor = () => {
|
||||
mouseMarker.style.borderColor = Color.fromHex(configurationService.getValue<string>('screencastMode.mouseIndicatorColor')).toString();
|
||||
};
|
||||
|
||||
let mouseIndicatorSize: number;
|
||||
const updateMouseIndicatorSize = () => {
|
||||
mouseIndicatorSize = clamp(configurationService.getValue<number>('screencastMode.mouseIndicatorSize') || 20, 20, 100);
|
||||
|
||||
mouseMarker.style.height = `${mouseIndicatorSize}px`;
|
||||
mouseMarker.style.width = `${mouseIndicatorSize}px`;
|
||||
};
|
||||
|
||||
updateMouseIndicatorColor();
|
||||
updateMouseIndicatorSize();
|
||||
|
||||
disposables.add(onMouseDown(e => {
|
||||
mouseMarker.style.top = `${e.clientY - 10}px`;
|
||||
mouseMarker.style.left = `${e.clientX - 10}px`;
|
||||
mouseMarker.style.top = `${e.clientY - mouseIndicatorSize / 2}px`;
|
||||
mouseMarker.style.left = `${e.clientX - mouseIndicatorSize / 2}px`;
|
||||
mouseMarker.style.display = 'block';
|
||||
|
||||
const mouseMoveListener = onMouseMove(e => {
|
||||
mouseMarker.style.top = `${e.clientY - 10}px`;
|
||||
mouseMarker.style.left = `${e.clientX - 10}px`;
|
||||
mouseMarker.style.top = `${e.clientY - mouseIndicatorSize / 2}px`;
|
||||
mouseMarker.style.left = `${e.clientX - mouseIndicatorSize / 2}px`;
|
||||
});
|
||||
|
||||
Event.once(onMouseUp)(() => {
|
||||
@@ -150,8 +166,14 @@ class ToggleScreencastModeAction extends Action2 {
|
||||
keyboardMarker.style.bottom = `${clamp(configurationService.getValue<number>('screencastMode.verticalOffset') || 0, 0, 90)}%`;
|
||||
};
|
||||
|
||||
let keyboardMarkerTimeout: number;
|
||||
const updateKeyboardMarkerTimeout = () => {
|
||||
keyboardMarkerTimeout = clamp(configurationService.getValue<number>('screencastMode.keyboardOverlayTimeout') || 800, 500, 5000);
|
||||
};
|
||||
|
||||
updateKeyboardFontSize();
|
||||
updateKeyboardMarker();
|
||||
updateKeyboardMarkerTimeout();
|
||||
|
||||
disposables.add(configurationService.onDidChangeConfiguration(e => {
|
||||
if (e.affectsConfiguration('screencastMode.verticalOffset')) {
|
||||
@@ -161,6 +183,18 @@ class ToggleScreencastModeAction extends Action2 {
|
||||
if (e.affectsConfiguration('screencastMode.fontSize')) {
|
||||
updateKeyboardFontSize();
|
||||
}
|
||||
|
||||
if (e.affectsConfiguration('screencastMode.keyboardOverlayTimeout')) {
|
||||
updateKeyboardMarkerTimeout();
|
||||
}
|
||||
|
||||
if (e.affectsConfiguration('screencastMode.mouseIndicatorColor')) {
|
||||
updateMouseIndicatorColor();
|
||||
}
|
||||
|
||||
if (e.affectsConfiguration('screencastMode.mouseIndicatorSize')) {
|
||||
updateMouseIndicatorSize();
|
||||
}
|
||||
}));
|
||||
|
||||
const onKeyDown = domEvent(window, 'keydown', true);
|
||||
@@ -190,7 +224,7 @@ class ToggleScreencastModeAction extends Action2 {
|
||||
append(keyboardMarker, key);
|
||||
}
|
||||
|
||||
const promise = timeout(800);
|
||||
const promise = timeout(keyboardMarkerTimeout);
|
||||
keyboardTimeout = toDisposable(() => promise.cancel());
|
||||
|
||||
promise.then(() => {
|
||||
@@ -276,8 +310,30 @@ configurationRegistry.registerConfiguration({
|
||||
},
|
||||
'screencastMode.onlyKeyboardShortcuts': {
|
||||
type: 'boolean',
|
||||
description: nls.localize('screencastMode.onlyKeyboardShortcuts', "Only show keyboard shortcuts in Screencast Mode."),
|
||||
description: nls.localize('screencastMode.onlyKeyboardShortcuts', "Only show keyboard shortcuts in screencast mode."),
|
||||
default: false
|
||||
}
|
||||
},
|
||||
'screencastMode.keyboardOverlayTimeout': {
|
||||
type: 'number',
|
||||
default: 800,
|
||||
minimum: 500,
|
||||
maximum: 5000,
|
||||
description: nls.localize('screencastMode.keyboardOverlayTimeout', "Controls how long (in milliseconds) the keyboard overlay is shown in screencast mode.")
|
||||
},
|
||||
'screencastMode.mouseIndicatorColor': {
|
||||
type: 'string',
|
||||
format: 'color-hex',
|
||||
default: '#FF0000',
|
||||
minLength: 4,
|
||||
maxLength: 9,
|
||||
description: nls.localize('screencastMode.mouseIndicatorColor', "Controls the color in hex (#RGB, #RGBA, #RRGGBB or #RRGGBBAA) of the mouse indicator in screencast mode.")
|
||||
},
|
||||
'screencastMode.mouseIndicatorSize': {
|
||||
type: 'number',
|
||||
default: 20,
|
||||
minimum: 20,
|
||||
maximum: 100,
|
||||
description: nls.localize('screencastMode.mouseIndicatorSize', "Controls the size (in pixels) of the mouse indicator in screencast mode.")
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
@@ -763,7 +763,6 @@ export class MoveFocusedViewAction extends Action {
|
||||
|
||||
registry.registerWorkbenchAction(SyncActionDescriptor.from(MoveFocusedViewAction), 'View: Move Focused View', viewCategory.value, FocusedViewContext.notEqualsTo(''));
|
||||
|
||||
|
||||
// --- Reset View Location with Command
|
||||
export class ResetFocusedViewLocationAction extends Action {
|
||||
static readonly ID = 'workbench.action.resetFocusedViewLocation';
|
||||
|
||||
@@ -9,12 +9,9 @@
|
||||
|
||||
.monaco-workbench .screencast-mouse {
|
||||
position: absolute;
|
||||
border: 2px solid red;
|
||||
border-radius: 20px;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
top: 0;
|
||||
left: 0;
|
||||
border-width: 2px;
|
||||
border-style: solid;
|
||||
border-radius: 50%;
|
||||
z-index: 100000;
|
||||
content: ' ';
|
||||
pointer-events: none;
|
||||
|
||||
@@ -6,17 +6,18 @@
|
||||
import { EditorInput } from 'vs/workbench/common/editor';
|
||||
import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { BaseEditor } from 'vs/workbench/browser/parts/editor/baseEditor';
|
||||
import { EditorPane } from 'vs/workbench/browser/parts/editor/editorPane';
|
||||
import { IConstructorSignature0, IInstantiationService, BrandedService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { insert } from 'vs/base/common/arrays';
|
||||
import { IDisposable, toDisposable } from 'vs/base/common/lifecycle';
|
||||
|
||||
export interface IEditorDescriptor {
|
||||
instantiate(instantiationService: IInstantiationService): BaseEditor;
|
||||
|
||||
getId(): string;
|
||||
getName(): string;
|
||||
|
||||
instantiate(instantiationService: IInstantiationService): EditorPane;
|
||||
|
||||
describes(obj: unknown): boolean;
|
||||
}
|
||||
|
||||
@@ -56,20 +57,20 @@ export interface IEditorRegistry {
|
||||
export class EditorDescriptor implements IEditorDescriptor {
|
||||
|
||||
static create<Services extends BrandedService[]>(
|
||||
ctor: { new(...services: Services): BaseEditor },
|
||||
ctor: { new(...services: Services): EditorPane },
|
||||
id: string,
|
||||
name: string
|
||||
): EditorDescriptor {
|
||||
return new EditorDescriptor(ctor as IConstructorSignature0<BaseEditor>, id, name);
|
||||
return new EditorDescriptor(ctor as IConstructorSignature0<EditorPane>, id, name);
|
||||
}
|
||||
|
||||
constructor(
|
||||
private readonly ctor: IConstructorSignature0<BaseEditor>,
|
||||
private readonly ctor: IConstructorSignature0<EditorPane>,
|
||||
private readonly id: string,
|
||||
private readonly name: string
|
||||
) { }
|
||||
|
||||
instantiate(instantiationService: IInstantiationService): BaseEditor {
|
||||
instantiate(instantiationService: IInstantiationService): EditorPane {
|
||||
return instantiationService.createInstance(this.ctor);
|
||||
}
|
||||
|
||||
@@ -82,7 +83,7 @@ export class EditorDescriptor implements IEditorDescriptor {
|
||||
}
|
||||
|
||||
describes(obj: unknown): boolean {
|
||||
return obj instanceof BaseEditor && obj.getId() === this.id;
|
||||
return obj instanceof EditorPane && obj.getId() === this.id;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1543,6 +1543,11 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
|
||||
setPanelHidden(hidden: boolean, skipLayout?: boolean): void {
|
||||
this.state.panel.hidden = hidden;
|
||||
|
||||
// Return if not initialized fully #105480
|
||||
if (!this.workbenchGrid) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Adjust CSS
|
||||
if (hidden) {
|
||||
addClass(this.container, Classes.PANEL_HIDDEN);
|
||||
@@ -1615,6 +1620,10 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
|
||||
return this.state.windowBorder;
|
||||
}
|
||||
|
||||
getWindowBorderWidth(): number {
|
||||
return this.state.windowBorder ? 2 : 0;
|
||||
}
|
||||
|
||||
getWindowBorderRadius(): string | undefined {
|
||||
return this.state.windowBorder && isMacintosh ? '5px' : undefined;
|
||||
}
|
||||
@@ -1636,7 +1645,7 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
|
||||
this.state.menuBar.visibility = visibility;
|
||||
|
||||
// Layout
|
||||
if (!skipLayout) {
|
||||
if (!skipLayout && this.workbenchGrid) {
|
||||
this.workbenchGrid.setViewVisible(this.titleBarPartView, this.isVisible(Parts.TITLEBAR_PART));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -161,21 +161,27 @@ export class AccountsActionViewItem extends ActivityActionViewItem {
|
||||
const otherCommands = accountsMenu.getActions();
|
||||
const providers = this.authenticationService.getProviderIds();
|
||||
const allSessions = providers.map(async id => {
|
||||
const sessions = await this.authenticationService.getSessions(id);
|
||||
try {
|
||||
const sessions = await this.authenticationService.getSessions(id);
|
||||
|
||||
const groupedSessions: { [label: string]: AuthenticationSession[] } = {};
|
||||
sessions.forEach(session => {
|
||||
if (groupedSessions[session.account.label]) {
|
||||
groupedSessions[session.account.label].push(session);
|
||||
} else {
|
||||
groupedSessions[session.account.label] = [session];
|
||||
}
|
||||
});
|
||||
const groupedSessions: { [label: string]: AuthenticationSession[] } = {};
|
||||
sessions.forEach(session => {
|
||||
if (groupedSessions[session.account.label]) {
|
||||
groupedSessions[session.account.label].push(session);
|
||||
} else {
|
||||
groupedSessions[session.account.label] = [session];
|
||||
}
|
||||
});
|
||||
|
||||
return {
|
||||
providerId: id,
|
||||
sessions: groupedSessions
|
||||
};
|
||||
return {
|
||||
providerId: id,
|
||||
sessions: groupedSessions
|
||||
};
|
||||
} catch {
|
||||
return {
|
||||
providerId: id
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
const result = await Promise.all(allSessions);
|
||||
@@ -183,20 +189,26 @@ export class AccountsActionViewItem extends ActivityActionViewItem {
|
||||
const authenticationSession = this.environmentService.options?.credentialsProvider ? await getCurrentAuthenticationSessionInfo(this.environmentService, this.productService) : undefined;
|
||||
result.forEach(sessionInfo => {
|
||||
const providerDisplayName = this.authenticationService.getLabel(sessionInfo.providerId);
|
||||
Object.keys(sessionInfo.sessions).forEach(accountName => {
|
||||
const hasEmbedderAccountSession = sessionInfo.sessions[accountName].some(session => session.id === (authenticationSession?.id || this.environmentService.options?.authenticationSessionId));
|
||||
const manageExtensionsAction = new Action(`configureSessions${accountName}`, nls.localize('manageTrustedExtensions', "Manage Trusted Extensions"), '', true, _ => {
|
||||
return this.authenticationService.manageTrustedExtensionsForAccount(sessionInfo.providerId, accountName);
|
||||
});
|
||||
const signOutAction = new Action('signOut', nls.localize('signOut', "Sign Out"), '', true, _ => {
|
||||
return this.authenticationService.signOutOfAccount(sessionInfo.providerId, accountName);
|
||||
});
|
||||
|
||||
const actions = hasEmbedderAccountSession ? [manageExtensionsAction] : [manageExtensionsAction, signOutAction];
|
||||
if (sessionInfo.sessions) {
|
||||
Object.keys(sessionInfo.sessions).forEach(accountName => {
|
||||
const hasEmbedderAccountSession = sessionInfo.sessions[accountName].some(session => session.id === (authenticationSession?.id || this.environmentService.options?.authenticationSessionId));
|
||||
const manageExtensionsAction = new Action(`configureSessions${accountName}`, nls.localize('manageTrustedExtensions', "Manage Trusted Extensions"), '', true, _ => {
|
||||
return this.authenticationService.manageTrustedExtensionsForAccount(sessionInfo.providerId, accountName);
|
||||
});
|
||||
const signOutAction = new Action('signOut', nls.localize('signOut', "Sign Out"), '', true, _ => {
|
||||
return this.authenticationService.signOutOfAccount(sessionInfo.providerId, accountName);
|
||||
});
|
||||
|
||||
const menu = new SubmenuAction('activitybar.submenu', `${accountName} (${providerDisplayName})`, actions);
|
||||
const actions = hasEmbedderAccountSession ? [manageExtensionsAction] : [manageExtensionsAction, signOutAction];
|
||||
|
||||
const menu = new SubmenuAction('activitybar.submenu', `${accountName} (${providerDisplayName})`, actions);
|
||||
menus.push(menu);
|
||||
});
|
||||
} else {
|
||||
const menu = new Action('providerUnavailable', nls.localize('authProviderUnavailable', '{0} is currently unavailable', providerDisplayName));
|
||||
menus.push(menu);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
if (menus.length && otherCommands.length) {
|
||||
|
||||
@@ -131,6 +131,8 @@ export class ActivitybarPart extends Part implements IActivityBarService {
|
||||
|
||||
storageKeysSyncRegistryService.registerStorageKey({ key: ActivitybarPart.PINNED_VIEW_CONTAINERS, version: 1 });
|
||||
storageKeysSyncRegistryService.registerStorageKey({ key: ActivitybarPart.HOME_BAR_VISIBILITY_PREFERENCE, version: 1 });
|
||||
storageKeysSyncRegistryService.registerStorageKey({ key: ACCOUNTS_VISIBILITY_PREFERENCE_KEY, version: 1 });
|
||||
|
||||
this.migrateFromOldCachedViewContainersValue();
|
||||
|
||||
for (const cachedViewContainer of this.cachedViewContainers) {
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
import 'vs/css!./media/binaryeditor';
|
||||
import * as nls from 'vs/nls';
|
||||
import { Emitter } from 'vs/base/common/event';
|
||||
import { EditorInput, EditorOptions } from 'vs/workbench/common/editor';
|
||||
import { BaseEditor } from 'vs/workbench/browser/parts/editor/baseEditor';
|
||||
import { EditorInput, EditorOptions, IEditorOpenContext } from 'vs/workbench/common/editor';
|
||||
import { EditorPane } from 'vs/workbench/browser/parts/editor/editorPane';
|
||||
import { BinaryEditorModel } from 'vs/workbench/common/editor/binaryEditorModel';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { DomScrollableElement } from 'vs/base/browser/ui/scrollbar/scrollableElement';
|
||||
@@ -30,7 +30,7 @@ export interface IOpenCallbacks {
|
||||
/*
|
||||
* This class is only intended to be subclassed and not instantiated.
|
||||
*/
|
||||
export abstract class BaseBinaryResourceEditor extends BaseEditor {
|
||||
export abstract class BaseBinaryResourceEditor extends EditorPane {
|
||||
|
||||
private readonly _onMetadataChanged = this._register(new Emitter<void>());
|
||||
readonly onMetadataChanged = this._onMetadataChanged.event;
|
||||
@@ -74,8 +74,8 @@ export abstract class BaseBinaryResourceEditor extends BaseEditor {
|
||||
parent.appendChild(this.scrollbar.getDomNode());
|
||||
}
|
||||
|
||||
async setInput(input: EditorInput, options: EditorOptions | undefined, token: CancellationToken): Promise<void> {
|
||||
await super.setInput(input, options, token);
|
||||
async setInput(input: EditorInput, options: EditorOptions | undefined, context: IEditorOpenContext, token: CancellationToken): Promise<void> {
|
||||
await super.setInput(input, options, context, token);
|
||||
const model = await input.resolve();
|
||||
|
||||
// Check for cancellation
|
||||
|
||||
@@ -4,12 +4,12 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Disposable, DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { EditorInput, EditorOptions, IVisibleEditorPane } from 'vs/workbench/common/editor';
|
||||
import { EditorInput, EditorOptions, IEditorOpenContext, IVisibleEditorPane } from 'vs/workbench/common/editor';
|
||||
import { Dimension, show, hide, addClass } from 'vs/base/browser/dom';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { IEditorRegistry, Extensions as EditorExtensions, IEditorDescriptor } from 'vs/workbench/browser/editor';
|
||||
import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService';
|
||||
import { BaseEditor } from 'vs/workbench/browser/parts/editor/baseEditor';
|
||||
import { EditorPane } from 'vs/workbench/browser/parts/editor/editorPane';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IEditorProgressService, LongRunningOperation } from 'vs/platform/progress/common/progress';
|
||||
import { IEditorGroupView, DEFAULT_EDITOR_MIN_DIMENSIONS, DEFAULT_EDITOR_MAX_DIMENSIONS } from 'vs/workbench/browser/parts/editor/editor';
|
||||
@@ -17,7 +17,7 @@ import { Emitter } from 'vs/base/common/event';
|
||||
import { assertIsDefined } from 'vs/base/common/types';
|
||||
|
||||
export interface IOpenEditorResult {
|
||||
readonly editorPane: BaseEditor;
|
||||
readonly editorPane: EditorPane;
|
||||
readonly editorChanged: boolean;
|
||||
}
|
||||
|
||||
@@ -34,10 +34,10 @@ export class EditorControl extends Disposable {
|
||||
private _onDidSizeConstraintsChange = this._register(new Emitter<{ width: number; height: number; } | undefined>());
|
||||
readonly onDidSizeConstraintsChange = this._onDidSizeConstraintsChange.event;
|
||||
|
||||
private _activeEditorPane: BaseEditor | null = null;
|
||||
private _activeEditorPane: EditorPane | null = null;
|
||||
get activeEditorPane(): IVisibleEditorPane | null { return this._activeEditorPane as IVisibleEditorPane | null; }
|
||||
|
||||
private readonly editorPanes: BaseEditor[] = [];
|
||||
private readonly editorPanes: EditorPane[] = [];
|
||||
|
||||
private readonly activeEditorPaneDisposables = this._register(new DisposableStore());
|
||||
private dimension: Dimension | undefined;
|
||||
@@ -53,7 +53,7 @@ export class EditorControl extends Disposable {
|
||||
super();
|
||||
}
|
||||
|
||||
async openEditor(editor: EditorInput, options?: EditorOptions): Promise<IOpenEditorResult> {
|
||||
async openEditor(editor: EditorInput, options: EditorOptions | undefined, context: IEditorOpenContext): Promise<IOpenEditorResult> {
|
||||
|
||||
// Editor pane
|
||||
const descriptor = Registry.as<IEditorRegistry>(EditorExtensions.Editors).getEditor(editor);
|
||||
@@ -63,11 +63,11 @@ export class EditorControl extends Disposable {
|
||||
const editorPane = this.doShowEditorPane(descriptor);
|
||||
|
||||
// Set input
|
||||
const editorChanged = await this.doSetInput(editorPane, editor, options);
|
||||
const editorChanged = await this.doSetInput(editorPane, editor, options, context);
|
||||
return { editorPane, editorChanged };
|
||||
}
|
||||
|
||||
private doShowEditorPane(descriptor: IEditorDescriptor): BaseEditor {
|
||||
private doShowEditorPane(descriptor: IEditorDescriptor): EditorPane {
|
||||
|
||||
// Return early if the currently active editor pane can handle the input
|
||||
if (this._activeEditorPane && descriptor.describes(this._activeEditorPane)) {
|
||||
@@ -99,7 +99,7 @@ export class EditorControl extends Disposable {
|
||||
return editorPane;
|
||||
}
|
||||
|
||||
private doCreateEditorPane(descriptor: IEditorDescriptor): BaseEditor {
|
||||
private doCreateEditorPane(descriptor: IEditorDescriptor): EditorPane {
|
||||
|
||||
// Instantiate editor
|
||||
const editorPane = this.doInstantiateEditorPane(descriptor);
|
||||
@@ -116,7 +116,7 @@ export class EditorControl extends Disposable {
|
||||
return editorPane;
|
||||
}
|
||||
|
||||
private doInstantiateEditorPane(descriptor: IEditorDescriptor): BaseEditor {
|
||||
private doInstantiateEditorPane(descriptor: IEditorDescriptor): EditorPane {
|
||||
|
||||
// Return early if already instantiated
|
||||
const existingEditorPane = this.editorPanes.find(editorPane => descriptor.describes(editorPane));
|
||||
@@ -131,7 +131,7 @@ export class EditorControl extends Disposable {
|
||||
return editorPane;
|
||||
}
|
||||
|
||||
private doSetActiveEditorPane(editorPane: BaseEditor | null) {
|
||||
private doSetActiveEditorPane(editorPane: EditorPane | null) {
|
||||
this._activeEditorPane = editorPane;
|
||||
|
||||
// Clear out previous active editor pane listeners
|
||||
@@ -147,7 +147,7 @@ export class EditorControl extends Disposable {
|
||||
this._onDidSizeConstraintsChange.fire(undefined);
|
||||
}
|
||||
|
||||
private async doSetInput(editorPane: BaseEditor, editor: EditorInput, options: EditorOptions | undefined): Promise<boolean> {
|
||||
private async doSetInput(editorPane: EditorPane, editor: EditorInput, options: EditorOptions | undefined, context: IEditorOpenContext): Promise<boolean> {
|
||||
|
||||
// If the input did not change, return early and only apply the options
|
||||
// unless the options instruct us to force open it even if it is the same
|
||||
@@ -174,7 +174,7 @@ export class EditorControl extends Disposable {
|
||||
// Call into editor pane
|
||||
const editorWillChange = !inputMatches;
|
||||
try {
|
||||
await editorPane.setInput(editor, options, operation.token);
|
||||
await editorPane.setInput(editor, options, context, operation.token);
|
||||
|
||||
// Focus (unless prevented or another operation is running)
|
||||
if (operation.isCurrent()) {
|
||||
|
||||
@@ -459,7 +459,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
|
||||
const activeElement = document.activeElement;
|
||||
|
||||
// Show active editor
|
||||
await this.doShowEditor(activeEditor, true, options);
|
||||
await this.doShowEditor(activeEditor, { active: true, isNew: false /* restored */ }, options);
|
||||
|
||||
// Set focused now if this is the active group and focus has
|
||||
// not changed meanwhile. This prevents focus from being
|
||||
@@ -954,10 +954,10 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
|
||||
// Update model and make sure to continue to use the editor we get from
|
||||
// the model. It is possible that the editor was already opened and we
|
||||
// want to ensure that we use the existing instance in that case.
|
||||
const openedEditor = this._group.openEditor(editor, openEditorOptions);
|
||||
const { editor: openedEditor, isNew } = this._group.openEditor(editor, openEditorOptions);
|
||||
|
||||
// Show editor
|
||||
const showEditorResult = this.doShowEditor(openedEditor, !!openEditorOptions.active, options);
|
||||
const showEditorResult = this.doShowEditor(openedEditor, { active: !!openEditorOptions.active, isNew }, options);
|
||||
|
||||
// Finally make sure the group is active or restored as instructed
|
||||
if (activateGroup) {
|
||||
@@ -969,14 +969,14 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
|
||||
return showEditorResult;
|
||||
}
|
||||
|
||||
private async doShowEditor(editor: EditorInput, active: boolean, options?: EditorOptions): Promise<IEditorPane | undefined> {
|
||||
private async doShowEditor(editor: EditorInput, context: { active: boolean, isNew: boolean }, options?: EditorOptions): Promise<IEditorPane | undefined> {
|
||||
|
||||
// Show in editor control if the active editor changed
|
||||
let openEditorPromise: Promise<IEditorPane | undefined> | undefined;
|
||||
if (active) {
|
||||
if (context.active) {
|
||||
openEditorPromise = (async () => {
|
||||
try {
|
||||
const result = await this.editorControl.openEditor(editor, options);
|
||||
const result = await this.editorControl.openEditor(editor, options, { newInGroup: context.isNew });
|
||||
|
||||
// Editor change event
|
||||
if (result.editorChanged) {
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Composite } from 'vs/workbench/browser/composite';
|
||||
import { EditorInput, EditorOptions, IEditorPane, GroupIdentifier, IEditorMemento } from 'vs/workbench/common/editor';
|
||||
import { EditorInput, EditorOptions, IEditorPane, GroupIdentifier, IEditorMemento, IEditorOpenContext } from 'vs/workbench/common/editor';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
@@ -41,7 +41,7 @@ import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
*
|
||||
* This class is only intended to be subclassed and not instantiated.
|
||||
*/
|
||||
export abstract class BaseEditor extends Composite implements IEditorPane {
|
||||
export abstract class EditorPane extends Composite implements IEditorPane {
|
||||
|
||||
private static readonly EDITOR_MEMENTOS = new Map<string, EditorMemento<any>>();
|
||||
|
||||
@@ -91,10 +91,12 @@ export abstract class BaseEditor extends Composite implements IEditorPane {
|
||||
* to be different from the previous input that was set using the `input.matches()`
|
||||
* method.
|
||||
*
|
||||
* The provided context gives more information around how the editor was opened.
|
||||
*
|
||||
* The provided cancellation token should be used to test if the operation
|
||||
* was cancelled.
|
||||
*/
|
||||
async setInput(input: EditorInput, options: EditorOptions | undefined, token: CancellationToken): Promise<void> {
|
||||
async setInput(input: EditorInput, options: EditorOptions | undefined, context: IEditorOpenContext, token: CancellationToken): Promise<void> {
|
||||
this._input = input;
|
||||
this._options = options;
|
||||
}
|
||||
@@ -146,10 +148,10 @@ export abstract class BaseEditor extends Composite implements IEditorPane {
|
||||
protected getEditorMemento<T>(editorGroupService: IEditorGroupsService, key: string, limit: number = 10): IEditorMemento<T> {
|
||||
const mementoKey = `${this.getId()}${key}`;
|
||||
|
||||
let editorMemento = BaseEditor.EDITOR_MEMENTOS.get(mementoKey);
|
||||
let editorMemento = EditorPane.EDITOR_MEMENTOS.get(mementoKey);
|
||||
if (!editorMemento) {
|
||||
editorMemento = new EditorMemento(this.getId(), key, this.getMemento(StorageScope.WORKSPACE), limit, editorGroupService);
|
||||
BaseEditor.EDITOR_MEMENTOS.set(mementoKey, editorMemento);
|
||||
EditorPane.EDITOR_MEMENTOS.set(mementoKey, editorMemento);
|
||||
}
|
||||
|
||||
return editorMemento;
|
||||
@@ -158,7 +160,7 @@ export abstract class BaseEditor extends Composite implements IEditorPane {
|
||||
protected saveState(): void {
|
||||
|
||||
// Save all editor memento for this editor type
|
||||
BaseEditor.EDITOR_MEMENTOS.forEach(editorMemento => {
|
||||
EditorPane.EDITOR_MEMENTOS.forEach(editorMemento => {
|
||||
if (editorMemento.id === this.getId()) {
|
||||
editorMemento.saveState();
|
||||
}
|
||||
@@ -26,7 +26,6 @@ import { IEditorService } from 'vs/workbench/services/editor/common/editorServic
|
||||
import { IFileService, FILES_ASSOCIATIONS_CONFIG } from 'vs/platform/files/common/files';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IModeService, ILanguageSelection } from 'vs/editor/common/services/modeService';
|
||||
import { IModelService } from 'vs/editor/common/services/modelService';
|
||||
import { Range } from 'vs/editor/common/core/range';
|
||||
import { Selection } from 'vs/editor/common/core/selection';
|
||||
import { TabFocus } from 'vs/editor/common/config/commonEditorConfig';
|
||||
@@ -43,7 +42,7 @@ import { ICodeEditor, getCodeEditor } from 'vs/editor/browser/editorBrowser';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import { IPreferencesService } from 'vs/workbench/services/preferences/common/preferences';
|
||||
import { IQuickInputService, IQuickPickItem, QuickPickInput } from 'vs/platform/quickinput/common/quickInput';
|
||||
import { getIconClasses } from 'vs/editor/common/services/getIconClasses';
|
||||
import { getIconClassesForModeId } from 'vs/editor/common/services/getIconClasses';
|
||||
import { timeout } from 'vs/base/common/async';
|
||||
import { INotificationHandle, INotificationService, Severity } from 'vs/platform/notification/common/notification';
|
||||
import { Event } from 'vs/base/common/event';
|
||||
@@ -1045,7 +1044,6 @@ export class ChangeModeAction extends Action {
|
||||
actionId: string,
|
||||
actionLabel: string,
|
||||
@IModeService private readonly modeService: IModeService,
|
||||
@IModelService private readonly modelService: IModelService,
|
||||
@IEditorService private readonly editorService: IEditorService,
|
||||
@IConfigurationService private readonly configurationService: IConfigurationService,
|
||||
@IQuickInputService private readonly quickInputService: IQuickInputService,
|
||||
@@ -1072,26 +1070,27 @@ export class ChangeModeAction extends Action {
|
||||
}
|
||||
|
||||
// Compute mode
|
||||
let currentLanguageId: string | undefined;
|
||||
let currentModeId: string | undefined;
|
||||
let modeId: string | undefined;
|
||||
if (textModel) {
|
||||
modeId = textModel.getLanguageIdentifier().language;
|
||||
currentModeId = withNullAsUndefined(this.modeService.getLanguageName(modeId));
|
||||
currentModeId = textModel.getLanguageIdentifier().language;
|
||||
currentLanguageId = withNullAsUndefined(this.modeService.getLanguageName(currentModeId));
|
||||
}
|
||||
|
||||
// All languages are valid picks
|
||||
const languages = this.modeService.getRegisteredLanguageNames();
|
||||
const picks: QuickPickInput[] = languages.sort().map((lang, index) => {
|
||||
const modeId = this.modeService.getModeIdForLanguageName(lang.toLowerCase()) || 'unknown';
|
||||
let description: string;
|
||||
if (currentModeId === lang) {
|
||||
description = nls.localize('languageDescription', "({0}) - Configured Language", this.modeService.getModeIdForLanguageName(lang.toLowerCase()));
|
||||
if (currentLanguageId === lang) {
|
||||
description = nls.localize('languageDescription', "({0}) - Configured Language", modeId);
|
||||
} else {
|
||||
description = nls.localize('languageDescriptionConfigured', "({0})", this.modeService.getModeIdForLanguageName(lang.toLowerCase()));
|
||||
description = nls.localize('languageDescriptionConfigured', "({0})", modeId);
|
||||
}
|
||||
|
||||
return {
|
||||
label: lang,
|
||||
iconClasses: getIconClasses(this.modelService, this.modeService, this.getFakeResource(lang)),
|
||||
iconClasses: getIconClassesForModeId(modeId),
|
||||
description
|
||||
};
|
||||
});
|
||||
@@ -1112,7 +1111,7 @@ export class ChangeModeAction extends Action {
|
||||
picks.unshift(galleryAction);
|
||||
}
|
||||
|
||||
configureModeSettings = { label: nls.localize('configureModeSettings', "Configure '{0}' language based settings...", currentModeId) };
|
||||
configureModeSettings = { label: nls.localize('configureModeSettings', "Configure '{0}' language based settings...", currentLanguageId) };
|
||||
picks.unshift(configureModeSettings);
|
||||
configureModeAssociations = { label: nls.localize('configureAssociationsExt', "Configure File Association for '{0}'...", ext) };
|
||||
picks.unshift(configureModeAssociations);
|
||||
@@ -1147,7 +1146,7 @@ export class ChangeModeAction extends Action {
|
||||
|
||||
// User decided to configure settings for current language
|
||||
if (pick === configureModeSettings) {
|
||||
this.preferencesService.openGlobalSettings(true, { editSetting: `[${withUndefinedAsNull(modeId)}]` });
|
||||
this.preferencesService.openGlobalSettings(true, { editSetting: `[${withUndefinedAsNull(currentModeId)}]` });
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1185,12 +1184,12 @@ export class ChangeModeAction extends Action {
|
||||
|
||||
const languages = this.modeService.getRegisteredLanguageNames();
|
||||
const picks: IQuickPickItem[] = languages.sort().map((lang, index) => {
|
||||
const id = withNullAsUndefined(this.modeService.getModeIdForLanguageName(lang.toLowerCase()));
|
||||
const id = withNullAsUndefined(this.modeService.getModeIdForLanguageName(lang.toLowerCase())) || 'unknown';
|
||||
|
||||
return {
|
||||
id,
|
||||
label: lang,
|
||||
iconClasses: getIconClasses(this.modelService, this.modeService, this.getFakeResource(lang)),
|
||||
iconClasses: getIconClassesForModeId(id),
|
||||
description: (id === currentAssociation) ? nls.localize('currentAssociation', "Current Association") : undefined
|
||||
};
|
||||
});
|
||||
@@ -1221,22 +1220,6 @@ export class ChangeModeAction extends Action {
|
||||
}
|
||||
}, 50 /* quick input is sensitive to being opened so soon after another */);
|
||||
}
|
||||
|
||||
private getFakeResource(lang: string): URI | undefined {
|
||||
let fakeResource: URI | undefined;
|
||||
|
||||
const extensions = this.modeService.getExtensions(lang);
|
||||
if (extensions?.length) {
|
||||
fakeResource = URI.file(extensions[0]);
|
||||
} else {
|
||||
const filenames = this.modeService.getFilenames(lang);
|
||||
if (filenames?.length) {
|
||||
fakeResource = URI.file(filenames[0]);
|
||||
}
|
||||
}
|
||||
|
||||
return fakeResource;
|
||||
}
|
||||
}
|
||||
|
||||
export interface IChangeEOLEntry extends IQuickPickItem {
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
|
||||
import * as DOM from 'vs/base/browser/dom';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { EditorInput, EditorOptions, SideBySideEditorInput, IEditorControl, IEditorPane } from 'vs/workbench/common/editor';
|
||||
import { BaseEditor } from 'vs/workbench/browser/parts/editor/baseEditor';
|
||||
import { EditorInput, EditorOptions, SideBySideEditorInput, IEditorControl, IEditorPane, IEditorOpenContext } from 'vs/workbench/common/editor';
|
||||
import { EditorPane } from 'vs/workbench/browser/parts/editor/editorPane';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||
@@ -19,7 +19,7 @@ import { Event, Relay, Emitter } from 'vs/base/common/event';
|
||||
import { IStorageService } from 'vs/platform/storage/common/storage';
|
||||
import { assertIsDefined } from 'vs/base/common/types';
|
||||
|
||||
export class SideBySideEditor extends BaseEditor {
|
||||
export class SideBySideEditor extends EditorPane {
|
||||
|
||||
static readonly ID: string = 'workbench.editor.sidebysideEditor';
|
||||
|
||||
@@ -33,7 +33,7 @@ export class SideBySideEditor extends BaseEditor {
|
||||
private get minimumSecondaryHeight() { return this.secondaryEditorPane ? this.secondaryEditorPane.minimumHeight : 0; }
|
||||
private get maximumSecondaryHeight() { return this.secondaryEditorPane ? this.secondaryEditorPane.maximumHeight : Number.POSITIVE_INFINITY; }
|
||||
|
||||
// these setters need to exist because this extends from BaseEditor
|
||||
// these setters need to exist because this extends from EditorPane
|
||||
set minimumWidth(value: number) { /* noop */ }
|
||||
set maximumWidth(value: number) { /* noop */ }
|
||||
set minimumHeight(value: number) { /* noop */ }
|
||||
@@ -44,8 +44,8 @@ export class SideBySideEditor extends BaseEditor {
|
||||
get minimumHeight() { return this.minimumPrimaryHeight + this.minimumSecondaryHeight; }
|
||||
get maximumHeight() { return this.maximumPrimaryHeight + this.maximumSecondaryHeight; }
|
||||
|
||||
protected primaryEditorPane?: BaseEditor;
|
||||
protected secondaryEditorPane?: BaseEditor;
|
||||
protected primaryEditorPane?: EditorPane;
|
||||
protected secondaryEditorPane?: EditorPane;
|
||||
|
||||
private primaryEditorContainer: HTMLElement | undefined;
|
||||
private secondaryEditorContainer: HTMLElement | undefined;
|
||||
@@ -94,11 +94,11 @@ export class SideBySideEditor extends BaseEditor {
|
||||
this.updateStyles();
|
||||
}
|
||||
|
||||
async setInput(newInput: EditorInput, options: EditorOptions | undefined, token: CancellationToken): Promise<void> {
|
||||
async setInput(newInput: EditorInput, options: EditorOptions | undefined, context: IEditorOpenContext, token: CancellationToken): Promise<void> {
|
||||
const oldInput = this.input as SideBySideEditorInput;
|
||||
await super.setInput(newInput, options, token);
|
||||
await super.setInput(newInput, options, context, token);
|
||||
|
||||
return this.updateInput(oldInput, (newInput as SideBySideEditorInput), options, token);
|
||||
return this.updateInput(oldInput, (newInput as SideBySideEditorInput), options, context, token);
|
||||
}
|
||||
|
||||
setOptions(options: EditorOptions | undefined): void {
|
||||
@@ -162,13 +162,13 @@ export class SideBySideEditor extends BaseEditor {
|
||||
return this.secondaryEditorPane;
|
||||
}
|
||||
|
||||
private async updateInput(oldInput: SideBySideEditorInput, newInput: SideBySideEditorInput, options: EditorOptions | undefined, token: CancellationToken): Promise<void> {
|
||||
private async updateInput(oldInput: SideBySideEditorInput, newInput: SideBySideEditorInput, options: EditorOptions | undefined, context: IEditorOpenContext, token: CancellationToken): Promise<void> {
|
||||
if (!newInput.matches(oldInput)) {
|
||||
if (oldInput) {
|
||||
this.disposeEditors();
|
||||
}
|
||||
|
||||
return this.setNewInput(newInput, options, token);
|
||||
return this.setNewInput(newInput, options, context, token);
|
||||
}
|
||||
|
||||
if (!this.secondaryEditorPane || !this.primaryEditorPane) {
|
||||
@@ -176,19 +176,19 @@ export class SideBySideEditor extends BaseEditor {
|
||||
}
|
||||
|
||||
await Promise.all([
|
||||
this.secondaryEditorPane.setInput(newInput.secondary, undefined, token),
|
||||
this.primaryEditorPane.setInput(newInput.primary, options, token)
|
||||
this.secondaryEditorPane.setInput(newInput.secondary, undefined, context, token),
|
||||
this.primaryEditorPane.setInput(newInput.primary, options, context, token)
|
||||
]);
|
||||
}
|
||||
|
||||
private setNewInput(newInput: SideBySideEditorInput, options: EditorOptions | undefined, token: CancellationToken): Promise<void> {
|
||||
private setNewInput(newInput: SideBySideEditorInput, options: EditorOptions | undefined, context: IEditorOpenContext, token: CancellationToken): Promise<void> {
|
||||
const secondaryEditor = this.doCreateEditor(newInput.secondary, assertIsDefined(this.secondaryEditorContainer));
|
||||
const primaryEditor = this.doCreateEditor(newInput.primary, assertIsDefined(this.primaryEditorContainer));
|
||||
|
||||
return this.onEditorsCreated(secondaryEditor, primaryEditor, newInput.secondary, newInput.primary, options, token);
|
||||
return this.onEditorsCreated(secondaryEditor, primaryEditor, newInput.secondary, newInput.primary, options, context, token);
|
||||
}
|
||||
|
||||
private doCreateEditor(editorInput: EditorInput, container: HTMLElement): BaseEditor {
|
||||
private doCreateEditor(editorInput: EditorInput, container: HTMLElement): EditorPane {
|
||||
const descriptor = Registry.as<IEditorRegistry>(EditorExtensions.Editors).getEditor(editorInput);
|
||||
if (!descriptor) {
|
||||
throw new Error('No descriptor for editor found');
|
||||
@@ -201,7 +201,7 @@ export class SideBySideEditor extends BaseEditor {
|
||||
return editor;
|
||||
}
|
||||
|
||||
private async onEditorsCreated(secondary: BaseEditor, primary: BaseEditor, secondaryInput: EditorInput, primaryInput: EditorInput, options: EditorOptions | undefined, token: CancellationToken): Promise<void> {
|
||||
private async onEditorsCreated(secondary: EditorPane, primary: EditorPane, secondaryInput: EditorInput, primaryInput: EditorInput, options: EditorOptions | undefined, context: IEditorOpenContext, token: CancellationToken): Promise<void> {
|
||||
this.secondaryEditorPane = secondary;
|
||||
this.primaryEditorPane = primary;
|
||||
|
||||
@@ -213,8 +213,8 @@ export class SideBySideEditor extends BaseEditor {
|
||||
this.onDidCreateEditors.fire(undefined);
|
||||
|
||||
await Promise.all([
|
||||
this.secondaryEditorPane.setInput(secondaryInput, undefined, token),
|
||||
this.primaryEditorPane.setInput(primaryInput, options, token)]
|
||||
this.secondaryEditorPane.setInput(secondaryInput, undefined, context, token),
|
||||
this.primaryEditorPane.setInput(primaryInput, options, context, token)]
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ import { isFunction, isObject, isArray, assertIsDefined } from 'vs/base/common/t
|
||||
import { IDiffEditor } from 'vs/editor/browser/editorBrowser';
|
||||
import { IDiffEditorOptions, IEditorOptions as ICodeEditorOptions } from 'vs/editor/common/config/editorOptions';
|
||||
import { BaseTextEditor, IEditorConfiguration } from 'vs/workbench/browser/parts/editor/textEditor';
|
||||
import { TextEditorOptions, EditorInput, EditorOptions, TEXT_DIFF_EDITOR_ID, IEditorInputFactoryRegistry, Extensions as EditorInputExtensions, ITextDiffEditorPane, IEditorInput } from 'vs/workbench/common/editor';
|
||||
import { TextEditorOptions, EditorInput, EditorOptions, TEXT_DIFF_EDITOR_ID, IEditorInputFactoryRegistry, Extensions as EditorInputExtensions, ITextDiffEditorPane, IEditorInput, IEditorOpenContext } from 'vs/workbench/common/editor';
|
||||
import { DiffEditorInput } from 'vs/workbench/common/editor/diffEditorInput';
|
||||
import { DiffNavigator } from 'vs/editor/browser/widget/diffNavigator';
|
||||
import { DiffEditorWidget } from 'vs/editor/browser/widget/diffEditorWidget';
|
||||
@@ -80,7 +80,7 @@ export class TextDiffEditor extends BaseTextEditor implements ITextDiffEditorPan
|
||||
return this.instantiationService.createInstance(DiffEditorWidget, parent, configuration);
|
||||
}
|
||||
|
||||
async setInput(input: EditorInput, options: EditorOptions | undefined, token: CancellationToken): Promise<void> {
|
||||
async setInput(input: EditorInput, options: EditorOptions | undefined, context: IEditorOpenContext, token: CancellationToken): Promise<void> {
|
||||
|
||||
// Dispose previous diff navigator
|
||||
this.diffNavigatorDisposables.clear();
|
||||
@@ -89,7 +89,7 @@ export class TextDiffEditor extends BaseTextEditor implements ITextDiffEditorPan
|
||||
this.doSaveOrClearTextDiffEditorViewState(this.input);
|
||||
|
||||
// Set input and resolve
|
||||
await super.setInput(input, options, token);
|
||||
await super.setInput(input, options, context, token);
|
||||
|
||||
try {
|
||||
const resolvedModel = await input.resolve();
|
||||
@@ -115,9 +115,9 @@ export class TextDiffEditor extends BaseTextEditor implements ITextDiffEditorPan
|
||||
optionsGotApplied = (<TextEditorOptions>options).apply(diffEditor, ScrollType.Immediate);
|
||||
}
|
||||
|
||||
// Otherwise restore View State
|
||||
// Otherwise restore View State unless disabled via settings
|
||||
let hasPreviousViewState = false;
|
||||
if (!optionsGotApplied) {
|
||||
if (!optionsGotApplied && this.shouldRestoreTextEditorViewState(input, context)) {
|
||||
hasPreviousViewState = this.restoreTextDiffEditorViewState(input, diffEditor);
|
||||
}
|
||||
|
||||
@@ -296,7 +296,7 @@ export class TextDiffEditor extends BaseTextEditor implements ITextDiffEditorPan
|
||||
}
|
||||
|
||||
// Clear view state if input is disposed or we are configured to not storing any state
|
||||
if (input.isDisposed() || (!this.shouldRestoreViewState && (!this.group || !this.group.isOpened(input)))) {
|
||||
if (input.isDisposed() || (!this.shouldRestoreTextEditorViewState(input) && (!this.group || !this.group.isOpened(input)))) {
|
||||
super.clearTextEditorViewState([resource], this.group);
|
||||
}
|
||||
|
||||
|
||||
@@ -10,8 +10,8 @@ import { Event } from 'vs/base/common/event';
|
||||
import { isObject, assertIsDefined, withNullAsUndefined, isFunction } from 'vs/base/common/types';
|
||||
import { Dimension } from 'vs/base/browser/dom';
|
||||
import { CodeEditorWidget } from 'vs/editor/browser/widget/codeEditorWidget';
|
||||
import { EditorInput, EditorOptions, IEditorMemento, ITextEditorPane, TextEditorOptions, IEditorCloseEvent, IEditorInput, computeEditorAriaLabel } from 'vs/workbench/common/editor';
|
||||
import { BaseEditor } from 'vs/workbench/browser/parts/editor/baseEditor';
|
||||
import { EditorInput, EditorOptions, IEditorMemento, ITextEditorPane, TextEditorOptions, IEditorCloseEvent, IEditorInput, computeEditorAriaLabel, IEditorOpenContext, toResource, SideBySideEditor } from 'vs/workbench/common/editor';
|
||||
import { EditorPane } from 'vs/workbench/browser/parts/editor/editorPane';
|
||||
import { IEditorViewState, IEditor, ScrollType } from 'vs/editor/common/editorCommon';
|
||||
import { IStorageService } from 'vs/platform/storage/common/storage';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
@@ -35,7 +35,7 @@ export interface IEditorConfiguration {
|
||||
* The base class of editors that leverage the text editor for the editing experience. This class is only intended to
|
||||
* be subclassed and not instantiated.
|
||||
*/
|
||||
export abstract class BaseTextEditor extends BaseEditor implements ITextEditorPane {
|
||||
export abstract class BaseTextEditor extends EditorPane implements ITextEditorPane {
|
||||
|
||||
static readonly TEXT_EDITOR_VIEW_STATE_PREFERENCE_KEY = 'textEditorViewState';
|
||||
|
||||
@@ -47,9 +47,6 @@ export abstract class BaseTextEditor extends BaseEditor implements ITextEditorPa
|
||||
|
||||
private readonly groupListener = this._register(new MutableDisposable());
|
||||
|
||||
private _shouldRestoreViewState: boolean | undefined;
|
||||
protected get shouldRestoreViewState(): boolean | undefined { return this._shouldRestoreViewState; }
|
||||
|
||||
private _instantiationService: IInstantiationService;
|
||||
protected get instantiationService(): IInstantiationService { return this._instantiationService; }
|
||||
protected set instantiationService(value: IInstantiationService) { this._instantiationService = value; }
|
||||
@@ -69,7 +66,7 @@ export abstract class BaseTextEditor extends BaseEditor implements ITextEditorPa
|
||||
|
||||
this.editorMemento = this.getEditorMemento<IEditorViewState>(editorGroupService, BaseTextEditor.TEXT_EDITOR_VIEW_STATE_PREFERENCE_KEY, 100);
|
||||
|
||||
this._register(this.textResourceConfigurationService.onDidChangeConfiguration(e => {
|
||||
this._register(this.textResourceConfigurationService.onDidChangeConfiguration(() => {
|
||||
const resource = this.getActiveResource();
|
||||
const value = resource ? this.textResourceConfigurationService.getValue<IEditorConfiguration>(resource) : undefined;
|
||||
|
||||
@@ -84,13 +81,9 @@ export abstract class BaseTextEditor extends BaseEditor implements ITextEditorPa
|
||||
this.editorContainer?.setAttribute('aria-label', ariaLabel);
|
||||
this.editorControl?.updateOptions({ ariaLabel });
|
||||
}));
|
||||
|
||||
this.updateRestoreViewStateConfiguration();
|
||||
}
|
||||
|
||||
protected handleConfigurationChangeEvent(configuration?: IEditorConfiguration): void {
|
||||
this.updateRestoreViewStateConfiguration();
|
||||
|
||||
if (this.isVisible()) {
|
||||
this.updateEditorConfiguration(configuration);
|
||||
} else {
|
||||
@@ -98,10 +91,6 @@ export abstract class BaseTextEditor extends BaseEditor implements ITextEditorPa
|
||||
}
|
||||
}
|
||||
|
||||
private updateRestoreViewStateConfiguration(): void {
|
||||
this._shouldRestoreViewState = this.textResourceConfigurationService.getValue(undefined, 'workbench.editor.restoreViewState') ?? true /* default */;
|
||||
}
|
||||
|
||||
private consumePendingConfigurationChangeEvent(): void {
|
||||
if (this.hasPendingConfigurationChange) {
|
||||
this.updateEditorConfiguration();
|
||||
@@ -163,8 +152,8 @@ export abstract class BaseTextEditor extends BaseEditor implements ITextEditorPa
|
||||
return this.instantiationService.createInstance(CodeEditorWidget, parent, configuration, {});
|
||||
}
|
||||
|
||||
async setInput(input: EditorInput, options: EditorOptions | undefined, token: CancellationToken): Promise<void> {
|
||||
await super.setInput(input, options, token);
|
||||
async setInput(input: EditorInput, options: EditorOptions | undefined, context: IEditorOpenContext, token: CancellationToken): Promise<void> {
|
||||
await super.setInput(input, options, context, token);
|
||||
|
||||
// Update editor options after having set the input. We do this because there can be
|
||||
// editor input specific options (e.g. an ARIA label depending on the input showing)
|
||||
@@ -238,6 +227,17 @@ export abstract class BaseTextEditor extends BaseEditor implements ITextEditorPa
|
||||
this.editorMemento.saveEditorState(this.group, resource, editorViewState);
|
||||
}
|
||||
|
||||
protected shouldRestoreTextEditorViewState(editor: IEditorInput, context?: IEditorOpenContext): boolean {
|
||||
|
||||
// new editor: check with workbench.editor.restoreViewState setting
|
||||
if (context?.newInGroup) {
|
||||
return this.textResourceConfigurationService.getValue<boolean>(toResource(editor, { supportSideBySide: SideBySideEditor.PRIMARY }), 'workbench.editor.restoreViewState') === false ? false : true /* restore by default */;
|
||||
}
|
||||
|
||||
// existing editor: always restore viewstate
|
||||
return true;
|
||||
}
|
||||
|
||||
getViewState(): IEditorViewState | undefined {
|
||||
const resource = this.input?.resource;
|
||||
if (resource) {
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
import * as nls from 'vs/nls';
|
||||
import { assertIsDefined, isFunction, withNullAsUndefined } from 'vs/base/common/types';
|
||||
import { ICodeEditor, getCodeEditor, IPasteEvent } from 'vs/editor/browser/editorBrowser';
|
||||
import { TextEditorOptions, EditorInput, EditorOptions } from 'vs/workbench/common/editor';
|
||||
import { TextEditorOptions, EditorInput, EditorOptions, IEditorOpenContext } from 'vs/workbench/common/editor';
|
||||
import { ResourceEditorInput } from 'vs/workbench/common/editor/resourceEditorInput';
|
||||
import { BaseTextEditorModel } from 'vs/workbench/common/editor/textEditorModel';
|
||||
import { UntitledTextEditorInput } from 'vs/workbench/services/untitled/common/untitledTextEditorInput';
|
||||
@@ -54,13 +54,13 @@ export class AbstractTextResourceEditor extends BaseTextEditor {
|
||||
return nls.localize('textEditor', "Text Editor");
|
||||
}
|
||||
|
||||
async setInput(input: EditorInput, options: EditorOptions | undefined, token: CancellationToken): Promise<void> {
|
||||
async setInput(input: EditorInput, options: EditorOptions | undefined, context: IEditorOpenContext, token: CancellationToken): Promise<void> {
|
||||
|
||||
// Remember view settings if input changes
|
||||
this.saveTextResourceEditorViewState(this.input);
|
||||
|
||||
// Set input and resolve
|
||||
await super.setInput(input, options, token);
|
||||
await super.setInput(input, options, context, token);
|
||||
const resolvedModel = await input.resolve();
|
||||
|
||||
// Check for cancellation
|
||||
@@ -85,8 +85,8 @@ export class AbstractTextResourceEditor extends BaseTextEditor {
|
||||
optionsGotApplied = textOptions.apply(textEditor, ScrollType.Immediate);
|
||||
}
|
||||
|
||||
// Otherwise restore View State
|
||||
if (!optionsGotApplied) {
|
||||
// Otherwise restore View State unless disabled via settings
|
||||
if (!optionsGotApplied && this.shouldRestoreTextEditorViewState(input, context)) {
|
||||
this.restoreTextResourceEditorViewState(input, textEditor);
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { listActiveSelectionBackground, listActiveSelectionForeground } from 'vs/platform/theme/common/colorRegistry';
|
||||
import { ICssStyleCollector, IColorTheme, IThemeService, registerThemingParticipant, Themable } from 'vs/platform/theme/common/themeService';
|
||||
import { DraggedEditorGroupIdentifier, DraggedEditorIdentifier, fillResourceDataTransfers, LocalSelectionTransfer } from 'vs/workbench/browser/dnd';
|
||||
import { BaseEditor } from 'vs/workbench/browser/parts/editor/baseEditor';
|
||||
import { EditorPane } from 'vs/workbench/browser/parts/editor/editorPane';
|
||||
import { BreadcrumbsConfig } from 'vs/workbench/browser/parts/editor/breadcrumbs';
|
||||
import { BreadcrumbsControl, IBreadcrumbsControlOptions } from 'vs/workbench/browser/parts/editor/breadcrumbsControl';
|
||||
import { IEditorGroupsAccessor, IEditorGroupView } from 'vs/workbench/browser/parts/editor/editor';
|
||||
@@ -164,7 +164,7 @@ export abstract class TitleControl extends Themable {
|
||||
const activeEditorPane = this.group.activeEditorPane;
|
||||
|
||||
// Check Active Editor
|
||||
if (activeEditorPane instanceof BaseEditor) {
|
||||
if (activeEditorPane instanceof EditorPane) {
|
||||
const result = activeEditorPane.getActionViewItem(action);
|
||||
|
||||
if (result) {
|
||||
@@ -237,7 +237,7 @@ export abstract class TitleControl extends Themable {
|
||||
|
||||
// Editor actions require the editor control to be there, so we retrieve it via service
|
||||
const activeEditorPane = this.group.activeEditorPane;
|
||||
if (activeEditorPane instanceof BaseEditor) {
|
||||
if (activeEditorPane instanceof EditorPane) {
|
||||
const codeEditor = getCodeEditor(activeEditorPane.getControl());
|
||||
const scopedContextKeyService = codeEditor?.invokeWithinContext(accessor => accessor.get(IContextKeyService)) || this.contextKeyService;
|
||||
const titleBarMenu = this.menuService.createMenu(MenuId.EditorTitle, scopedContextKeyService);
|
||||
|
||||
@@ -221,7 +221,7 @@ export function registerNotificationCommands(center: INotificationsCenterControl
|
||||
|
||||
// Commands for Command Palette
|
||||
const category = { value: localize('notifications', "Notifications"), original: 'Notifications' };
|
||||
MenuRegistry.appendMenuItem(MenuId.CommandPalette, { command: { id: SHOW_NOTIFICATIONS_CENTER, title: { value: localize('showNotifications', "Show Notifications"), original: 'Show Notifications' }, category }, when: NotificationsCenterVisibleContext.toNegated() });
|
||||
MenuRegistry.appendMenuItem(MenuId.CommandPalette, { command: { id: SHOW_NOTIFICATIONS_CENTER, title: { value: localize('showNotifications', "Show Notifications"), original: 'Show Notifications' }, category } });
|
||||
MenuRegistry.appendMenuItem(MenuId.CommandPalette, { command: { id: HIDE_NOTIFICATIONS_CENTER, title: { value: localize('hideNotifications', "Hide Notifications"), original: 'Hide Notifications' }, category }, when: NotificationsCenterVisibleContext });
|
||||
MenuRegistry.appendMenuItem(MenuId.CommandPalette, { command: { id: CLEAR_ALL_NOTIFICATIONS, title: { value: localize('clearAllNotifications', "Clear All Notifications"), original: 'Clear All Notifications' }, category } });
|
||||
MenuRegistry.appendMenuItem(MenuId.CommandPalette, { command: { id: FOCUS_NOTIFICATION_TOAST, title: { value: localize('focusNotificationToasts', "Focus Notification Toast"), original: 'Focus Notification Toast' }, category }, when: NotificationsToastsVisibleContext });
|
||||
|
||||
@@ -38,6 +38,26 @@
|
||||
-webkit-margin-after: 0;
|
||||
}
|
||||
|
||||
.monaco-pane-view .pane > .pane-header .description {
|
||||
display: block;
|
||||
font-weight: normal;
|
||||
margin-left: 10px;
|
||||
opacity: 0.6;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
text-transform: none;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.monaco-pane-view .pane > .pane-header .description .codicon {
|
||||
font-size: 9px;
|
||||
margin-left: 2px;
|
||||
}
|
||||
|
||||
.monaco-pane-view .pane > .pane-header:not(.expanded) .description {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.monaco-pane-view .pane.horizontal:not(.expanded) > .pane-header h3.title,
|
||||
.monaco-pane-view .pane.horizontal:not(.expanded) > .pane-header .description {
|
||||
display: none;
|
||||
|
||||
@@ -9,7 +9,7 @@ import { Event, Emitter } from 'vs/base/common/event';
|
||||
import { ColorIdentifier, activeContrastBorder, foreground } from 'vs/platform/theme/common/colorRegistry';
|
||||
import { attachStyler, IColorMapping, attachButtonStyler, attachLinkStyler, attachProgressBarStyler } from 'vs/platform/theme/common/styler';
|
||||
import { SIDE_BAR_DRAG_AND_DROP_BACKGROUND, SIDE_BAR_SECTION_HEADER_FOREGROUND, SIDE_BAR_SECTION_HEADER_BACKGROUND, SIDE_BAR_SECTION_HEADER_BORDER, PANEL_BACKGROUND, SIDE_BAR_BACKGROUND, PANEL_SECTION_HEADER_FOREGROUND, PANEL_SECTION_HEADER_BACKGROUND, PANEL_SECTION_HEADER_BORDER, PANEL_SECTION_DRAG_AND_DROP_BACKGROUND, PANEL_SECTION_BORDER } from 'vs/workbench/common/theme';
|
||||
import { append, $, trackFocus, toggleClass, EventType, isAncestor, Dimension, addDisposableListener, removeClass, addClass, createCSSRule, asCSSUrl, addClasses } from 'vs/base/browser/dom';
|
||||
import { after, append, $, trackFocus, toggleClass, EventType, isAncestor, Dimension, addDisposableListener, removeClass, addClass, createCSSRule, asCSSUrl, addClasses } from 'vs/base/browser/dom';
|
||||
import { IDisposable, combinedDisposable, dispose, toDisposable, Disposable, DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { firstIndex } from 'vs/base/common/arrays';
|
||||
import { IAction, Separator, IActionViewItem } from 'vs/base/common/actions';
|
||||
@@ -184,6 +184,11 @@ export abstract class ViewPane extends Pane implements IView {
|
||||
return this._title;
|
||||
}
|
||||
|
||||
private _titleDescription: string | undefined;
|
||||
public get titleDescription(): string | undefined {
|
||||
return this._titleDescription;
|
||||
}
|
||||
|
||||
private readonly menuActions: ViewMenuActions;
|
||||
private progressBar!: ProgressBar;
|
||||
private progressIndicator!: IProgressIndicator;
|
||||
@@ -192,6 +197,7 @@ export abstract class ViewPane extends Pane implements IView {
|
||||
private readonly showActionsAlways: boolean = false;
|
||||
private headerContainer?: HTMLElement;
|
||||
private titleContainer?: HTMLElement;
|
||||
private titleDescriptionContainer?: HTMLElement;
|
||||
private iconContainer?: HTMLElement;
|
||||
protected twistiesContainer?: HTMLElement;
|
||||
|
||||
@@ -216,6 +222,7 @@ export abstract class ViewPane extends Pane implements IView {
|
||||
|
||||
this.id = options.id;
|
||||
this._title = options.title;
|
||||
this._titleDescription = options.titleDescription;
|
||||
this.showActionsAlways = !!options.showActionsAlways;
|
||||
this.focusedViewContextKey = FocusedViewContext.bindTo(contextKeyService);
|
||||
|
||||
@@ -360,6 +367,11 @@ export abstract class ViewPane extends Pane implements IView {
|
||||
|
||||
const calculatedTitle = this.calculateTitle(title);
|
||||
this.titleContainer = append(container, $('h3.title', undefined, calculatedTitle));
|
||||
|
||||
if (this._titleDescription) {
|
||||
this.setTitleDescription(this._titleDescription);
|
||||
}
|
||||
|
||||
this.iconContainer.title = calculatedTitle;
|
||||
this.iconContainer.setAttribute('aria-label', calculatedTitle);
|
||||
}
|
||||
@@ -379,6 +391,22 @@ export abstract class ViewPane extends Pane implements IView {
|
||||
this._onDidChangeTitleArea.fire();
|
||||
}
|
||||
|
||||
private setTitleDescription(description: string | undefined) {
|
||||
if (this.titleDescriptionContainer) {
|
||||
this.titleDescriptionContainer.textContent = description ?? '';
|
||||
}
|
||||
else if (description && this.titleContainer) {
|
||||
this.titleDescriptionContainer = after(this.titleContainer, $('span.description', undefined, description));
|
||||
}
|
||||
}
|
||||
|
||||
protected updateTitleDescription(description?: string | undefined): void {
|
||||
this.setTitleDescription(description);
|
||||
|
||||
this._titleDescription = description;
|
||||
this._onDidChangeTitleArea.fire();
|
||||
}
|
||||
|
||||
private calculateTitle(title: string): string {
|
||||
const viewContainer = this.viewDescriptorService.getViewContainerByViewId(this.id)!;
|
||||
const model = this.viewDescriptorService.getViewContainerModel(viewContainer);
|
||||
|
||||
@@ -208,10 +208,17 @@ class BrowserMain extends Disposable {
|
||||
const requestService = new BrowserRequestService(remoteAgentService, configurationService, logService);
|
||||
serviceCollection.set(IRequestService, requestService);
|
||||
|
||||
// initialize user data
|
||||
// Userdata Initialize Service
|
||||
const userDataInitializationService = new UserDataInitializationService(environmentService, fileService, storageService, productService, requestService, logService);
|
||||
serviceCollection.set(IUserDataInitializationService, userDataInitializationService);
|
||||
await userDataInitializationService.initializeRequiredResources();
|
||||
|
||||
if (await userDataInitializationService.requiresInitialization()) {
|
||||
// Initialize required resources - settings & global state
|
||||
await userDataInitializationService.initializeRequiredResources();
|
||||
|
||||
// Reload configuration after initializing
|
||||
await configurationService.reloadConfiguration();
|
||||
}
|
||||
|
||||
return { serviceCollection, logService, storageService };
|
||||
}
|
||||
|
||||
@@ -150,8 +150,9 @@ import { workbenchConfigurationNodeBase } from 'vs/workbench/common/configuratio
|
||||
},
|
||||
'workbench.editor.restoreViewState': {
|
||||
'type': 'boolean',
|
||||
'description': nls.localize('restoreViewState', "Restores the last view state (e.g. scroll position) when re-opening files after they have been closed."),
|
||||
'description': nls.localize('restoreViewState', "Restores the last view state (e.g. scroll position) when re-opening textual editors after they have been closed."),
|
||||
'default': true,
|
||||
'scope': ConfigurationScope.LANGUAGE_OVERRIDABLE
|
||||
},
|
||||
'workbench.editor.centeredLayoutAutoResize': {
|
||||
'type': 'boolean',
|
||||
|
||||
Reference in New Issue
Block a user