未验证 提交 5486b1a0 编写于 作者: M Martin Aeschlimann 提交者: GitHub

Merge branch 'master' into aeschli/avoidthemeonbody

......@@ -64,7 +64,7 @@ export class ColorPickerModel {
guessColorPresentation(color: Color, originalText: string): void {
for (let i = 0; i < this.colorPresentations.length; i++) {
if (originalText === this.colorPresentations[i].label) {
if (originalText.toLowerCase() === this.colorPresentations[i].label) {
this.presentationIndex = i;
this._onDidChangePresentation.fire(this.presentation);
break;
......
......@@ -25,6 +25,7 @@ export class MainThreadTheming implements MainThreadThemingShape {
this._themeChangeListener = this._themeService.onDidColorThemeChange(e => {
this._proxy.$onColorThemeChange(this._themeService.getColorTheme().type);
});
this._proxy.$onColorThemeChange(this._themeService.getColorTheme().type);
}
dispose(): void {
......
......@@ -4,9 +4,8 @@
*--------------------------------------------------------------------------------------------*/
import 'vs/css!./media/editorgroupview';
import { EditorGroup, IEditorOpenOptions, EditorCloseEvent, ISerializedEditorGroup, isSerializedEditorGroup } from 'vs/workbench/common/editor/editorGroup';
import { EditorInput, EditorOptions, GroupIdentifier, SideBySideEditorInput, CloseDirection, IEditorCloseEvent, EditorGroupActiveEditorDirtyContext, IEditorPane, EditorGroupEditorsCountContext, SaveReason, IEditorPartOptionsChangeEvent, EditorsOrder, IVisibleEditorPane } from 'vs/workbench/common/editor';
import { EditorInput, EditorOptions, GroupIdentifier, SideBySideEditorInput, CloseDirection, IEditorCloseEvent, EditorGroupActiveEditorDirtyContext, IEditorPane, EditorGroupEditorsCountContext, SaveReason, IEditorPartOptionsChangeEvent, EditorsOrder, IVisibleEditorPane, EditorStickyContext, EditorPinnedContext } from 'vs/workbench/common/editor';
import { Event, Emitter, Relay } from 'vs/base/common/event';
import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
import { addClass, addClasses, Dimension, trackFocus, toggleClass, removeClass, addDisposableListener, EventType, EventHelper, findParentWithClass, clearNode, isAncestor } from 'vs/base/browser/dom';
......@@ -220,8 +219,10 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
private handleGroupContextKeys(contextKeyService: IContextKeyService): void {
const groupActiveEditorDirtyContextKey = EditorGroupActiveEditorDirtyContext.bindTo(contextKeyService);
const groupEditorsCountContext = EditorGroupEditorsCountContext.bindTo(contextKeyService);
const groupActiveEditorPinnedContext = EditorPinnedContext.bindTo(contextKeyService);
const groupActiveEditorStickyContext = EditorStickyContext.bindTo(contextKeyService);
let activeEditorListener = new MutableDisposable();
const activeEditorListener = new MutableDisposable();
const observeActiveEditor = () => {
activeEditorListener.clear();
......@@ -237,11 +238,22 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
// Update group contexts based on group changes
this._register(this.onDidGroupChange(e => {
// Track the active editor and update context key that reflects
// the dirty state of this editor
if (e.kind === GroupChangeKind.EDITOR_ACTIVE) {
observeActiveEditor();
switch (e.kind) {
case GroupChangeKind.EDITOR_ACTIVE:
// Track the active editor and update context key that reflects
// the dirty state of this editor
observeActiveEditor();
break;
case GroupChangeKind.EDITOR_PIN:
if (e.editor && e.editor === this._group.activeEditor) {
groupActiveEditorPinnedContext.set(this._group.isPinned(this._group.activeEditor));
}
break;
case GroupChangeKind.EDITOR_STICKY:
if (e.editor && e.editor === this._group.activeEditor) {
groupActiveEditorStickyContext.set(this._group.isSticky(this._group.activeEditor));
}
break;
}
// Group editors count context
......@@ -464,6 +476,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
// Model Events
this._register(this._group.onDidChangeEditorPinned(editor => this.onDidChangeEditorPinned(editor)));
this._register(this._group.onDidChangeEditorSticky(editor => this.onDidChangeEditorSticky(editor)));
this._register(this._group.onDidOpenEditor(editor => this.onDidOpenEditor(editor)));
this._register(this._group.onDidCloseEditor(editor => this.handleOnDidCloseEditor(editor)));
this._register(this._group.onDidDisposeEditor(editor => this.onDidDisposeEditor(editor)));
......@@ -478,11 +491,13 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
}
private onDidChangeEditorPinned(editor: EditorInput): void {
// Event
this._onDidGroupChange.fire({ kind: GroupChangeKind.EDITOR_PIN, editor });
}
private onDidChangeEditorSticky(editor: EditorInput): void {
this._onDidGroupChange.fire({ kind: GroupChangeKind.EDITOR_STICKY, editor });
}
private onDidOpenEditor(editor: EditorInput): void {
/* __GDPR__
......
......@@ -83,6 +83,9 @@ export class EditorGroup extends Disposable {
private readonly _onDidChangeEditorPinned = this._register(new Emitter<EditorInput>());
readonly onDidChangeEditorPinned = this._onDidChangeEditorPinned.event;
private readonly _onDidChangeEditorSticky = this._register(new Emitter<EditorInput>());
readonly onDidChangeEditorSticky = this._onDidChangeEditorSticky.event;
//#endregion
private _id: GroupIdentifier;
......@@ -560,6 +563,9 @@ export class EditorGroup extends Disposable {
// Adjust sticky index
this.sticky++;
// Event
this._onDidChangeEditorSticky.fire(editor);
}
unstick(candidate: EditorInput): EditorInput | undefined {
......@@ -585,6 +591,9 @@ export class EditorGroup extends Disposable {
// Adjust sticky index
this.sticky--;
// Event
this._onDidChangeEditorSticky.fire(editor);
}
isSticky(candidateOrIndex: EditorInput | number): boolean {
......
......@@ -366,7 +366,7 @@ export class DebugSession implements IDebugSession {
}
}
async dataBreakpointInfo(name: string, variablesReference?: number): Promise<{ dataId: string | null, description: string, canPersist?: boolean }> {
async dataBreakpointInfo(name: string, variablesReference?: number): Promise<{ dataId: string | null, description: string, canPersist?: boolean } | undefined> {
if (!this.raw) {
throw new Error(localize('noDebugAdapter', "No debug adapter, can not send '{0}'", 'data breakpoints info'));
}
......@@ -592,7 +592,7 @@ export class DebugSession implements IDebugSession {
}
const response = await this.raw.loadedSources({});
if (response.body && response.body.sources) {
if (response && response.body && response.body.sources) {
return response.body.sources.map(src => this.getSource(src));
} else {
return [];
......
......@@ -87,7 +87,7 @@ export class Repl extends ViewPane implements IHistoryNavigationWidget {
private replInputContainer!: HTMLElement;
private dimension!: dom.Dimension;
private replInputLineCount = 1;
private model!: ITextModel;
private model: ITextModel | undefined;
private historyNavigationEnablement!: IContextKey<boolean>;
private scopedInstantiationService!: IInstantiationService;
private replElementsChangeListener: IDisposable | undefined;
......@@ -271,7 +271,7 @@ export class Repl extends ViewPane implements IHistoryNavigationWidget {
if (isCodeEditor(activeEditorControl)) {
this.modelChangeListener.dispose();
this.modelChangeListener = activeEditorControl.onDidChangeModelLanguage(() => this.setMode());
if (activeEditorControl.hasModel()) {
if (this.model && activeEditorControl.hasModel()) {
this.model.setMode(activeEditorControl.getModel().getLanguageIdentifier());
}
}
......@@ -397,16 +397,18 @@ export class Repl extends ViewPane implements IHistoryNavigationWidget {
getVisibleContent(): string {
let text = '';
const lineDelimiter = this.textResourcePropertiesService.getEOL(this.model.uri);
const traverseAndAppend = (node: ITreeNode<IReplElement, FuzzyScore>) => {
node.children.forEach(child => {
text += child.element.toString().trimRight() + lineDelimiter;
if (!child.collapsed && child.children.length) {
traverseAndAppend(child);
}
});
};
traverseAndAppend(this.tree.getNode());
if (this.model) {
const lineDelimiter = this.textResourcePropertiesService.getEOL(this.model.uri);
const traverseAndAppend = (node: ITreeNode<IReplElement, FuzzyScore>) => {
node.children.forEach(child => {
text += child.element.toString().trimRight() + lineDelimiter;
if (!child.collapsed && child.children.length) {
traverseAndAppend(child);
}
});
};
traverseAndAppend(this.tree.getNode());
}
return removeAnsiEscapeCodes(text);
}
......
......@@ -194,8 +194,8 @@ export class VariablesView extends ViewPane {
}
if (session && session.capabilities.supportsDataBreakpoints) {
const response = await session.dataBreakpointInfo(variable.name, variable.parent.reference);
const dataid = response.dataId;
if (dataid) {
const dataid = response?.dataId;
if (response && dataid) {
actions.push(new Separator());
actions.push(new Action('debug.breakWhenValueChanges', nls.localize('breakWhenValueChanges', "Break When Value Changes"), undefined, true, () => {
return this.debugService.addDataBreakpoint(response.description, dataid, !!response.canPersist, response.accessTypes);
......
......@@ -214,7 +214,7 @@ export interface IDebugSession extends ITreeElement {
sendBreakpoints(modelUri: uri, bpts: IBreakpoint[], sourceModified: boolean): Promise<void>;
sendFunctionBreakpoints(fbps: IFunctionBreakpoint[]): Promise<void>;
dataBreakpointInfo(name: string, variablesReference?: number): Promise<{ dataId: string | null, description: string, canPersist?: boolean, accessTypes?: DebugProtocol.DataBreakpointAccessType[] }>;
dataBreakpointInfo(name: string, variablesReference?: number): Promise<{ dataId: string | null, description: string, canPersist?: boolean, accessTypes?: DebugProtocol.DataBreakpointAccessType[] } | undefined>;
sendDataBreakpoints(dbps: IDataBreakpoint[]): Promise<void>;
sendExceptionBreakpoints(exbpts: IExceptionBreakpoint[]): Promise<void>;
breakpointsLocations(uri: uri, lineNumber: number): Promise<IPosition[]>;
......
......@@ -144,7 +144,7 @@ export class MockSession implements IDebugSession {
throw new Error('Method not implemented.');
}
dataBreakpointInfo(name: string, variablesReference?: number | undefined): Promise<{ dataId: string | null; description: string; canPersist?: boolean | undefined; }> {
dataBreakpointInfo(name: string, variablesReference?: number | undefined): Promise<{ dataId: string | null; description: string; canPersist?: boolean | undefined; } | undefined> {
throw new Error('Method not implemented.');
}
......
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { ICredentialsService } from 'vs/platform/credentials/common/credentials';
import { IdleValue } from 'vs/base/common/async';
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
type KeytarModule = typeof import('keytar');
export class KeytarCredentialsService implements ICredentialsService {
_serviceBrand: undefined;
private readonly _keytar = new IdleValue<Promise<KeytarModule>>(() => import('keytar'));
async getPassword(service: string, account: string): Promise<string | null> {
const keytar = await this._keytar.value;
return keytar.getPassword(service, account);
}
async setPassword(service: string, account: string, password: string): Promise<void> {
const keytar = await this._keytar.value;
return keytar.setPassword(service, account, password);
}
async deletePassword(service: string, account: string): Promise<boolean> {
const keytar = await this._keytar.value;
return keytar.deletePassword(service, account);
}
async findPassword(service: string): Promise<string | null> {
const keytar = await this._keytar.value;
return keytar.findPassword(service);
}
async findCredentials(service: string): Promise<Array<{ account: string, password: string }>> {
const keytar = await this._keytar.value;
return keytar.findCredentials(service);
}
}
registerSingleton(ICredentialsService, KeytarCredentialsService, true);
......@@ -359,6 +359,7 @@ export const enum GroupChangeKind {
EDITOR_ACTIVE,
EDITOR_LABEL,
EDITOR_PIN,
EDITOR_STICKY,
EDITOR_DIRTY
}
......
......@@ -369,8 +369,9 @@ suite('EditorGroupsService', () => {
let activeEditorChangeCounter = 0;
let editorDidOpenCounter = 0;
let editorCloseCounter1 = 0;
let editorCloseCounter = 0;
let editorPinCounter = 0;
let editorStickyCounter = 0;
const editorGroupChangeListener = group.onDidGroupChange(e => {
if (e.kind === GroupChangeKind.EDITOR_OPEN) {
assert.ok(e.editor);
......@@ -380,16 +381,19 @@ suite('EditorGroupsService', () => {
activeEditorChangeCounter++;
} else if (e.kind === GroupChangeKind.EDITOR_CLOSE) {
assert.ok(e.editor);
editorCloseCounter1++;
editorCloseCounter++;
} else if (e.kind === GroupChangeKind.EDITOR_PIN) {
assert.ok(e.editor);
editorPinCounter++;
} else if (e.kind === GroupChangeKind.EDITOR_STICKY) {
assert.ok(e.editor);
editorStickyCounter++;
}
});
let editorCloseCounter2 = 0;
let editorCloseCounter1 = 0;
const editorCloseListener = group.onDidCloseEditor(() => {
editorCloseCounter2++;
editorCloseCounter1++;
});
let editorWillCloseCounter = 0;
......@@ -440,12 +444,18 @@ suite('EditorGroupsService', () => {
await group.closeEditor(inputInactive);
assert.equal(activeEditorChangeCounter, 3);
assert.equal(editorCloseCounter, 1);
assert.equal(editorCloseCounter1, 1);
assert.equal(editorCloseCounter2, 1);
assert.equal(editorWillCloseCounter, 1);
assert.equal(group.activeEditor, input);
assert.equal(editorStickyCounter, 0);
group.stickEditor(input);
assert.equal(editorStickyCounter, 1);
group.unstickEditor(input);
assert.equal(editorStickyCounter, 2);
editorCloseListener.dispose();
editorWillCloseListener.dispose();
editorWillOpenListener.dispose();
......
......@@ -5,7 +5,7 @@
import { URI, UriComponents } from 'vs/base/common/uri';
import { IEditor } from 'vs/editor/common/editorCommon';
import { ITextEditorOptions, IResourceEditorInput, TextEditorSelectionRevealType } from 'vs/platform/editor/common/editor';
import { ITextEditorOptions, IResourceEditorInput, TextEditorSelectionRevealType, IEditorOptions } from 'vs/platform/editor/common/editor';
import { IEditorInput, IEditorPane, Extensions as EditorExtensions, EditorInput, IEditorCloseEvent, IEditorInputFactoryRegistry, toResource, IEditorIdentifier, GroupIdentifier, EditorsOrder } from 'vs/workbench/common/editor';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
import { IHistoryService } from 'vs/workbench/services/history/common/history';
......@@ -638,10 +638,22 @@ export class HistoryService extends Disposable implements IHistoryService {
if (lastClosedFile) {
(async () => {
const editor = await this.editorService.openEditor({
resource: lastClosedFile.resource,
options: { pinned: true, sticky: lastClosedFile.sticky, index: lastClosedFile.index }
});
let options: IEditorOptions;
if (lastClosedFile.sticky) {
// Sticky: in case the target index is outside of the range of
// sticky editors, we make sure to not provide the index as
// option. Otherwise the index will cause the sticky flag to
// be ignored.
if (!this.editorGroupService.activeGroup.isSticky(lastClosedFile.index)) {
options = { pinned: true, sticky: true };
} else {
options = { pinned: true, sticky: true, index: lastClosedFile.index };
}
} else {
options = { pinned: true, index: lastClosedFile.index };
}
const editor = await this.editorService.openEditor({ resource: lastClosedFile.resource, options });
// Fix for https://github.com/Microsoft/vscode/issues/67882
// If opening of the editor fails, make sure to try the next one
......
......@@ -98,6 +98,7 @@ export class ViewDescriptorService extends Disposable implements IViewDescriptor
super();
storageKeysSyncRegistryService.registerStorageKey({ key: ViewDescriptorService.CACHED_VIEW_POSITIONS, version: 1 });
storageKeysSyncRegistryService.registerStorageKey({ key: ViewDescriptorService.CACHED_VIEW_CONTAINER_LOCATIONS, version: 1 });
this.viewContainerModels = new Map<ViewContainer, { viewContainerModel: ViewContainerModel, disposable: IDisposable; }>();
this.activeViewContextKeys = new Map<string, IContextKey<boolean>>();
this.movableViewContextKeys = new Map<string, IContextKey<boolean>>();
......
......@@ -79,6 +79,8 @@ interface GroupEvents {
closed: EditorCloseEvent[];
pinned: EditorInput[];
unpinned: EditorInput[];
sticky: EditorInput[];
unsticky: EditorInput[];
moved: EditorInput[];
disposed: EditorInput[];
}
......@@ -90,6 +92,8 @@ function groupListener(group: EditorGroup): GroupEvents {
activated: [],
pinned: [],
unpinned: [],
sticky: [],
unsticky: [],
moved: [],
disposed: []
};
......@@ -98,6 +102,7 @@ function groupListener(group: EditorGroup): GroupEvents {
group.onDidCloseEditor(e => groupEvents.closed.push(e));
group.onDidActivateEditor(e => groupEvents.activated.push(e));
group.onDidChangeEditorPinned(e => group.isPinned(e) ? groupEvents.pinned.push(e) : groupEvents.unpinned.push(e));
group.onDidChangeEditorSticky(e => group.isSticky(e) ? groupEvents.sticky.push(e) : groupEvents.unsticky.push(e));
group.onDidMoveEditor(e => groupEvents.moved.push(e));
group.onDidDisposeEditor(e => groupEvents.disposed.push(e));
......@@ -609,6 +614,12 @@ suite('Workbench editor groups', () => {
group.pin(sameInput1);
assert.equal(events.pinned[0], input1);
group.stick(sameInput1);
assert.equal(events.sticky[0], input1);
group.unstick(sameInput1);
assert.equal(events.unsticky[0], input1);
group.moveEditor(sameInput1, 1);
assert.equal(events.moved[0], input1);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册