mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-15 10:58:31 -05:00
Initial VS Code 1.19 source merge (#571)
* Initial 1.19 xcopy * Fix yarn build * Fix numerous build breaks * Next batch of build break fixes * More build break fixes * Runtime breaks * Additional post merge fixes * Fix windows setup file * Fix test failures. * Update license header blocks to refer to source eula
This commit is contained in:
@@ -6,24 +6,19 @@
|
||||
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { IAction } from 'vs/base/common/actions';
|
||||
import { KeybindingsRegistry } from 'vs/platform/keybinding/common/keybindingsRegistry';
|
||||
import { IPartService } from 'vs/workbench/services/part/common/partService';
|
||||
import { ICommandHandler, CommandsRegistry } from 'vs/platform/commands/common/commands';
|
||||
import { SyncActionDescriptor, MenuRegistry, MenuId } from 'vs/platform/actions/common/actions';
|
||||
import { IMessageService } from 'vs/platform/message/common/message';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import Severity from 'vs/base/common/severity';
|
||||
import { IDisposable, combinedDisposable } from 'vs/base/common/lifecycle';
|
||||
import { ILifecycleService, LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle';
|
||||
|
||||
export const Extensions = {
|
||||
WorkbenchActions: 'workbench.contributions.actions'
|
||||
};
|
||||
|
||||
export interface IActionProvider {
|
||||
getActions(): IAction[];
|
||||
}
|
||||
|
||||
export interface IWorkbenchActionRegistry {
|
||||
|
||||
/**
|
||||
@@ -62,13 +57,20 @@ Registry.add(Extensions.WorkbenchActions, new class implements IWorkbenchActionR
|
||||
|
||||
// menu item
|
||||
// TODO@Rob slightly weird if-check required because of
|
||||
// https://github.com/Microsoft/vscode/blob/master/src/vs/workbench/parts/search/browser/search.contribution.ts#L266
|
||||
// https://github.com/Microsoft/vscode/blob/master/src/vs/workbench/parts/search/electron-browser/search.contribution.ts#L266
|
||||
if (descriptor.label) {
|
||||
|
||||
let idx = alias.indexOf(': ');
|
||||
let categoryOriginal;
|
||||
if (idx > 0) {
|
||||
categoryOriginal = alias.substr(0, idx);
|
||||
alias = alias.substr(idx + 2);
|
||||
}
|
||||
|
||||
const command = {
|
||||
id: descriptor.id,
|
||||
title: { value: descriptor.label, original: alias },
|
||||
category
|
||||
category: category && { value: category, original: categoryOriginal }
|
||||
};
|
||||
|
||||
MenuRegistry.addCommand(command);
|
||||
@@ -86,15 +88,15 @@ Registry.add(Extensions.WorkbenchActions, new class implements IWorkbenchActionR
|
||||
return (accessor, args) => {
|
||||
const messageService = accessor.get(IMessageService);
|
||||
const instantiationService = accessor.get(IInstantiationService);
|
||||
const partService = accessor.get(IPartService);
|
||||
const lifecycleService = accessor.get(ILifecycleService);
|
||||
|
||||
TPromise.as(this._triggerAndDisposeAction(instantiationService, partService, descriptor, args)).done(null, (err) => {
|
||||
TPromise.as(this._triggerAndDisposeAction(instantiationService, lifecycleService, descriptor, args)).then(null, (err) => {
|
||||
messageService.show(Severity.Error, err);
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
private _triggerAndDisposeAction(instantitationService: IInstantiationService, partService: IPartService, descriptor: SyncActionDescriptor, args: any): TPromise<any> {
|
||||
private _triggerAndDisposeAction(instantitationService: IInstantiationService, lifecycleService: ILifecycleService, descriptor: SyncActionDescriptor, args: any): Thenable<void> {
|
||||
const actionInstance = instantitationService.createInstance(descriptor.syncDescriptor);
|
||||
actionInstance.label = descriptor.label || actionInstance.label;
|
||||
|
||||
@@ -108,7 +110,7 @@ Registry.add(Extensions.WorkbenchActions, new class implements IWorkbenchActionR
|
||||
const from = args && args.from || 'keybinding';
|
||||
|
||||
// run action when workbench is created
|
||||
return partService.joinCreation().then(() => {
|
||||
return lifecycleService.when(LifecyclePhase.Running).then(() => {
|
||||
try {
|
||||
return TPromise.as(actionInstance.run(undefined, { from })).then(() => {
|
||||
actionInstance.dispose();
|
||||
|
||||
@@ -4,8 +4,9 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import { Registry, BaseRegistry } from 'vs/platform/registry/common/platform';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { IInstantiationService, IConstructorSignature0 } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { ILifecycleService, LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle';
|
||||
|
||||
// --- Workbench Contribution Registry
|
||||
|
||||
@@ -13,11 +14,7 @@ import { IInstantiationService, IConstructorSignature0 } from 'vs/platform/insta
|
||||
* A workbench contribution that will be loaded when the workbench starts and disposed when the workbench shuts down.
|
||||
*/
|
||||
export interface IWorkbenchContribution {
|
||||
|
||||
/**
|
||||
* The unique identifier of this workbench contribution.
|
||||
*/
|
||||
getId(): string;
|
||||
// Marker Interface
|
||||
}
|
||||
|
||||
export namespace Extensions {
|
||||
@@ -31,29 +28,73 @@ export interface IWorkbenchContributionsRegistry {
|
||||
/**
|
||||
* Registers a workbench contribution to the platform that will be loaded when the workbench starts and disposed when
|
||||
* the workbench shuts down.
|
||||
*
|
||||
* @param phase the lifecycle phase when to instantiate the contribution.
|
||||
*/
|
||||
registerWorkbenchContribution(contribution: IWorkbenchContributionSignature): void;
|
||||
registerWorkbenchContribution(contribution: IWorkbenchContributionSignature, phase: LifecyclePhase): void;
|
||||
|
||||
/**
|
||||
* Returns all workbench contributions that are known to the platform.
|
||||
* Starts the registry by providing the required services.
|
||||
*/
|
||||
getWorkbenchContributions(): IWorkbenchContribution[];
|
||||
|
||||
setInstantiationService(service: IInstantiationService): void;
|
||||
start(instantiationService: IInstantiationService, lifecycleService: ILifecycleService): void;
|
||||
}
|
||||
|
||||
class WorkbenchContributionsRegistry extends BaseRegistry<IWorkbenchContribution> implements IWorkbenchContributionsRegistry {
|
||||
export class WorkbenchContributionsRegistry implements IWorkbenchContributionsRegistry {
|
||||
private instantiationService: IInstantiationService;
|
||||
private lifecycleService: ILifecycleService;
|
||||
|
||||
public registerWorkbenchContribution(ctor: IWorkbenchContributionSignature): void {
|
||||
super._register(ctor);
|
||||
private toBeInstantiated: Map<LifecyclePhase, IConstructorSignature0<IWorkbenchContribution>[]> = new Map<LifecyclePhase, IConstructorSignature0<IWorkbenchContribution>[]>();
|
||||
|
||||
public registerWorkbenchContribution(ctor: IWorkbenchContributionSignature, phase: LifecyclePhase = LifecyclePhase.Starting): void {
|
||||
|
||||
// Instantiate directly if we are already matching the provided phase
|
||||
if (this.instantiationService && this.lifecycleService && this.lifecycleService.phase >= phase) {
|
||||
this.instantiationService.createInstance(ctor);
|
||||
}
|
||||
|
||||
// Otherwise keep contributions by lifecycle phase
|
||||
else {
|
||||
let toBeInstantiated = this.toBeInstantiated.get(phase);
|
||||
if (!toBeInstantiated) {
|
||||
toBeInstantiated = [];
|
||||
this.toBeInstantiated.set(phase, toBeInstantiated);
|
||||
}
|
||||
|
||||
toBeInstantiated.push(ctor);
|
||||
}
|
||||
}
|
||||
|
||||
public getWorkbenchContributions(): IWorkbenchContribution[] {
|
||||
return super._getInstances();
|
||||
public start(instantiationService: IInstantiationService, lifecycleService: ILifecycleService): void {
|
||||
this.instantiationService = instantiationService;
|
||||
this.lifecycleService = lifecycleService;
|
||||
|
||||
[LifecyclePhase.Starting, LifecyclePhase.Restoring, LifecyclePhase.Running, LifecyclePhase.Eventually].forEach(phase => {
|
||||
this.instantiateByPhase(instantiationService, lifecycleService, phase);
|
||||
});
|
||||
}
|
||||
|
||||
public setWorkbenchContributions(contributions: IWorkbenchContribution[]): void {
|
||||
super._setInstances(contributions);
|
||||
private instantiateByPhase(instantiationService: IInstantiationService, lifecycleService: ILifecycleService, phase: LifecyclePhase): void {
|
||||
|
||||
// Instantiate contributions directly when phase is already reached
|
||||
if (lifecycleService.phase >= phase) {
|
||||
this.doInstantiateByPhase(instantiationService, phase);
|
||||
}
|
||||
|
||||
// Otherwise wait for phase to be reached
|
||||
else {
|
||||
lifecycleService.when(phase).then(() => {
|
||||
this.doInstantiateByPhase(instantiationService, phase);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private doInstantiateByPhase(instantiationService: IInstantiationService, phase: LifecyclePhase): void {
|
||||
const toBeInstantiated = this.toBeInstantiated.get(phase);
|
||||
if (toBeInstantiated) {
|
||||
while (toBeInstantiated.length > 0) {
|
||||
instantiationService.createInstance(toBeInstantiated.shift());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -276,7 +276,7 @@ export interface IEditorOpeningEvent {
|
||||
prevent(callback: () => TPromise<IBaseEditor>): void;
|
||||
}
|
||||
|
||||
export class EditorOpeningEvent {
|
||||
export class EditorOpeningEvent implements IEditorOpeningEvent {
|
||||
private override: () => TPromise<IBaseEditor>;
|
||||
|
||||
constructor(private _input: IEditorInput, private _options: IEditorOptions, private _position: Position) {
|
||||
@@ -755,6 +755,7 @@ export interface IEditorStacksModel {
|
||||
|
||||
next(jumpGroups: boolean, cycleAtEnd?: boolean): IEditorIdentifier;
|
||||
previous(jumpGroups: boolean, cycleAtStart?: boolean): IEditorIdentifier;
|
||||
last(): IEditorIdentifier;
|
||||
|
||||
isOpen(resource: URI): boolean;
|
||||
|
||||
@@ -792,7 +793,7 @@ export interface IEditorContext extends IEditorIdentifier {
|
||||
}
|
||||
|
||||
export interface IEditorCloseEvent extends IEditorIdentifier {
|
||||
pinned: boolean;
|
||||
replaced: boolean;
|
||||
index: number;
|
||||
}
|
||||
|
||||
@@ -808,23 +809,11 @@ export const EditorOpenPositioning = {
|
||||
export const OPEN_POSITIONING_CONFIG = 'workbench.editor.openPositioning';
|
||||
|
||||
export interface IWorkbenchEditorConfiguration {
|
||||
/* __GDPR__FRAGMENT__
|
||||
"IWorkbenchEditorConfiguration" : {
|
||||
"showTabs" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
|
||||
"tabCloseButton": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
|
||||
"showIcons": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
|
||||
"enablePreview": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
|
||||
"enablePreviewFromQuickOpen": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
|
||||
"closeOnFileDelete": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
|
||||
"openPositioning": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
|
||||
"revealIfOpen": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
|
||||
"swipeToNavigate": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
|
||||
}
|
||||
*/
|
||||
workbench: {
|
||||
editor: {
|
||||
showTabs: boolean;
|
||||
tabCloseButton: 'left' | 'right' | 'off';
|
||||
tabSizing: 'fit' | 'shrink';
|
||||
showIcons: boolean;
|
||||
enablePreview: boolean;
|
||||
enablePreviewFromQuickOpen: boolean;
|
||||
@@ -833,7 +822,8 @@ export interface IWorkbenchEditorConfiguration {
|
||||
revealIfOpen: boolean;
|
||||
swipeToNavigate: boolean,
|
||||
labelFormat: 'default' | 'short' | 'medium' | 'long';
|
||||
}
|
||||
},
|
||||
iconTheme: string;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,8 @@ import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { EditorModel } from 'vs/workbench/common/editor';
|
||||
import URI from 'vs/base/common/uri';
|
||||
import { IFileService } from 'vs/platform/files/common/files';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import { DataUri } from 'vs/workbench/common/resources';
|
||||
|
||||
/**
|
||||
* An editor model that just represents a resource that can be loaded.
|
||||
@@ -17,6 +19,7 @@ export class BinaryEditorModel extends EditorModel {
|
||||
private resource: URI;
|
||||
private size: number;
|
||||
private etag: string;
|
||||
private mime: string;
|
||||
|
||||
constructor(
|
||||
resource: URI,
|
||||
@@ -25,8 +28,17 @@ export class BinaryEditorModel extends EditorModel {
|
||||
) {
|
||||
super();
|
||||
|
||||
this.name = name;
|
||||
this.resource = resource;
|
||||
this.name = name;
|
||||
|
||||
if (resource.scheme === Schemas.data) {
|
||||
const metadata = DataUri.parseMetaData(resource);
|
||||
if (metadata.has(DataUri.META_DATA_SIZE)) {
|
||||
this.size = Number(metadata.get(DataUri.META_DATA_SIZE));
|
||||
}
|
||||
|
||||
this.mime = metadata.get(DataUri.META_DATA_MIME);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -44,25 +56,38 @@ export class BinaryEditorModel extends EditorModel {
|
||||
}
|
||||
|
||||
/**
|
||||
* The size of the binary file if known.
|
||||
* The size of the binary resource if known.
|
||||
*/
|
||||
public getSize(): number {
|
||||
return this.size;
|
||||
}
|
||||
|
||||
/**
|
||||
* The etag of the binary file if known.
|
||||
* The mime of the binary resource if known.
|
||||
*/
|
||||
public getMime(): string {
|
||||
return this.mime;
|
||||
}
|
||||
|
||||
/**
|
||||
* The etag of the binary resource if known.
|
||||
*/
|
||||
public getETag(): string {
|
||||
return this.etag;
|
||||
}
|
||||
|
||||
public load(): TPromise<EditorModel> {
|
||||
return this.fileService.resolveFile(this.resource).then(stat => {
|
||||
this.etag = stat.etag;
|
||||
this.size = stat.size;
|
||||
|
||||
return this;
|
||||
});
|
||||
// Make sure to resolve up to date stat for file resources
|
||||
if (this.fileService.canHandleResource(this.resource)) {
|
||||
return this.fileService.resolveFile(this.resource).then(stat => {
|
||||
this.etag = stat.etag;
|
||||
this.size = stat.size;
|
||||
|
||||
return this;
|
||||
});
|
||||
}
|
||||
|
||||
return TPromise.wrap(this);
|
||||
}
|
||||
}
|
||||
86
src/vs/workbench/common/editor/dataUriEditorInput.ts
Normal file
86
src/vs/workbench/common/editor/dataUriEditorInput.ts
Normal file
@@ -0,0 +1,86 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { EditorInput } from 'vs/workbench/common/editor';
|
||||
import URI from 'vs/base/common/uri';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { BinaryEditorModel } from 'vs/workbench/common/editor/binaryEditorModel';
|
||||
import { DataUri } from 'vs/workbench/common/resources';
|
||||
|
||||
/**
|
||||
* An editor input to present data URIs in a binary editor. Data URIs have the form of:
|
||||
* data:[mime type];[meta data <key=value>;...];base64,[base64 encoded value]
|
||||
*/
|
||||
export class DataUriEditorInput extends EditorInput {
|
||||
|
||||
static ID: string = 'workbench.editors.dataUriEditorInput';
|
||||
|
||||
private resource: URI;
|
||||
private name: string;
|
||||
private description: string;
|
||||
|
||||
constructor(
|
||||
name: string,
|
||||
description: string,
|
||||
resource: URI,
|
||||
@IInstantiationService private instantiationService: IInstantiationService
|
||||
) {
|
||||
super();
|
||||
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
this.resource = resource;
|
||||
|
||||
if (!this.name || !this.description) {
|
||||
const metadata = DataUri.parseMetaData(this.resource);
|
||||
|
||||
if (!this.name) {
|
||||
this.name = metadata.get(DataUri.META_DATA_LABEL);
|
||||
}
|
||||
|
||||
if (!this.description) {
|
||||
this.description = metadata.get(DataUri.META_DATA_DESCRIPTION);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public getResource(): URI {
|
||||
return this.resource;
|
||||
}
|
||||
|
||||
public getTypeId(): string {
|
||||
return DataUriEditorInput.ID;
|
||||
}
|
||||
|
||||
public getName(): string {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public getDescription(): string {
|
||||
return this.description;
|
||||
}
|
||||
|
||||
public resolve(refresh?: boolean): TPromise<BinaryEditorModel> {
|
||||
return this.instantiationService.createInstance(BinaryEditorModel, this.resource, this.getName()).load().then(m => m as BinaryEditorModel);
|
||||
}
|
||||
|
||||
public matches(otherInput: any): boolean {
|
||||
if (super.matches(otherInput) === true) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (otherInput instanceof DataUriEditorInput) {
|
||||
const otherDataUriEditorInput = <DataUriEditorInput>otherInput;
|
||||
|
||||
// Compare by resource
|
||||
return otherDataUriEditorInput.resource.toString() === this.resource.toString();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -16,7 +16,7 @@ import { TextDiffEditorModel } from 'vs/workbench/common/editor/textDiffEditorMo
|
||||
*/
|
||||
export class DiffEditorInput extends SideBySideEditorInput {
|
||||
|
||||
public static ID = 'workbench.editors.diffEditorInput';
|
||||
public static readonly ID = 'workbench.editors.diffEditorInput';
|
||||
|
||||
private cachedModel: DiffEditorModel;
|
||||
|
||||
|
||||
@@ -346,8 +346,8 @@ export class EditorGroup implements IEditorGroup {
|
||||
}));
|
||||
}
|
||||
|
||||
public replaceEditor(toReplace: EditorInput, replaceWidth: EditorInput, replaceIndex: number, openNext = true): void {
|
||||
const event = this.doCloseEditor(toReplace, openNext); // optimization to prevent multiple setActive() in one call
|
||||
private replaceEditor(toReplace: EditorInput, replaceWidth: EditorInput, replaceIndex: number, openNext = true): void {
|
||||
const event = this.doCloseEditor(toReplace, openNext, true); // optimization to prevent multiple setActive() in one call
|
||||
|
||||
// We want to first add the new editor into our model before emitting the close event because
|
||||
// firing the close event can trigger a dispose on the same editor that is now being added.
|
||||
@@ -360,14 +360,14 @@ export class EditorGroup implements IEditorGroup {
|
||||
}
|
||||
|
||||
public closeEditor(editor: EditorInput, openNext = true): void {
|
||||
const event = this.doCloseEditor(editor, openNext);
|
||||
const event = this.doCloseEditor(editor, openNext, false);
|
||||
|
||||
if (event) {
|
||||
this.fireEvent(this._onEditorClosed, event, true);
|
||||
}
|
||||
}
|
||||
|
||||
private doCloseEditor(editor: EditorInput, openNext = true): EditorCloseEvent {
|
||||
private doCloseEditor(editor: EditorInput, openNext: boolean, replaced: boolean): EditorCloseEvent {
|
||||
const index = this.indexOf(editor);
|
||||
if (index === -1) {
|
||||
return null; // not found
|
||||
@@ -388,17 +388,15 @@ export class EditorGroup implements IEditorGroup {
|
||||
}
|
||||
|
||||
// Preview Editor closed
|
||||
let pinned = true;
|
||||
if (this.matches(this.preview, editor)) {
|
||||
this.preview = null;
|
||||
pinned = false;
|
||||
}
|
||||
|
||||
// Remove from arrays
|
||||
this.splice(index, true);
|
||||
|
||||
// Event
|
||||
return { editor, pinned, index, group: this };
|
||||
return { editor, replaced, index, group: this };
|
||||
}
|
||||
|
||||
public closeEditors(except: EditorInput, direction?: Direction): void {
|
||||
@@ -721,7 +719,7 @@ interface ISerializedEditorStacksModel {
|
||||
|
||||
export class EditorStacksModel implements IEditorStacksModel {
|
||||
|
||||
private static STORAGE_KEY = 'editorStacks.model';
|
||||
private static readonly STORAGE_KEY = 'editorStacks.model';
|
||||
|
||||
private toDispose: IDisposable[];
|
||||
private loaded: boolean;
|
||||
@@ -1098,6 +1096,16 @@ export class EditorStacksModel implements IEditorStacksModel {
|
||||
return { group: lastGroup, editor: lastGroup.getEditor(lastGroup.count - 1) };
|
||||
}
|
||||
|
||||
public last(): IEditorIdentifier {
|
||||
this.ensureLoaded();
|
||||
|
||||
if (!this.activeGroup) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return { group: this.activeGroup, editor: this.activeGroup.getEditor(this.activeGroup.count - 1) };
|
||||
}
|
||||
|
||||
private save(): void {
|
||||
const serialized = this.serialize();
|
||||
|
||||
|
||||
@@ -1,116 +0,0 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import URI from 'vs/base/common/uri';
|
||||
import Event, { Emitter } from 'vs/base/common/event';
|
||||
import * as editorCommon from 'vs/editor/common/editorCommon';
|
||||
import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { IRange } from 'vs/editor/common/core/range';
|
||||
import { CursorChangeReason, ICursorPositionChangedEvent } from 'vs/editor/common/controller/cursorEvents';
|
||||
import { ModelDecorationOptions } from 'vs/editor/common/model/textModelWithDecorations';
|
||||
|
||||
export interface IRangeHighlightDecoration {
|
||||
resource: URI;
|
||||
range: IRange;
|
||||
isWholeLine?: boolean;
|
||||
}
|
||||
|
||||
export class RangeHighlightDecorations implements IDisposable {
|
||||
|
||||
private rangeHighlightDecorationId: string = null;
|
||||
private editor: editorCommon.ICommonCodeEditor = null;
|
||||
private editorDisposables: IDisposable[] = [];
|
||||
|
||||
private _onHighlightRemoved: Emitter<void> = new Emitter<void>();
|
||||
public readonly onHighlghtRemoved: Event<void> = this._onHighlightRemoved.event;
|
||||
|
||||
constructor( @IWorkbenchEditorService private editorService: IWorkbenchEditorService) {
|
||||
}
|
||||
|
||||
public removeHighlightRange() {
|
||||
if (this.editor && this.editor.getModel() && this.rangeHighlightDecorationId) {
|
||||
this.editor.deltaDecorations([this.rangeHighlightDecorationId], []);
|
||||
this._onHighlightRemoved.fire();
|
||||
}
|
||||
this.rangeHighlightDecorationId = null;
|
||||
}
|
||||
|
||||
public highlightRange(range: IRangeHighlightDecoration, editor?: editorCommon.ICommonCodeEditor) {
|
||||
editor = editor ? editor : this.getEditor(range);
|
||||
if (editor) {
|
||||
this.doHighlightRange(editor, range);
|
||||
}
|
||||
}
|
||||
|
||||
private doHighlightRange(editor: editorCommon.ICommonCodeEditor, selectionRange: IRangeHighlightDecoration) {
|
||||
this.removeHighlightRange();
|
||||
editor.changeDecorations((changeAccessor: editorCommon.IModelDecorationsChangeAccessor) => {
|
||||
this.rangeHighlightDecorationId = changeAccessor.addDecoration(selectionRange.range, this.createRangeHighlightDecoration(selectionRange.isWholeLine));
|
||||
});
|
||||
this.setEditor(editor);
|
||||
}
|
||||
|
||||
private getEditor(resourceRange: IRangeHighlightDecoration): editorCommon.ICommonCodeEditor {
|
||||
const activeInput = this.editorService.getActiveEditorInput();
|
||||
const resource = activeInput && activeInput.getResource();
|
||||
if (resource) {
|
||||
if (resource.toString() === resourceRange.resource.toString()) {
|
||||
return <editorCommon.ICommonCodeEditor>this.editorService.getActiveEditor().getControl();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private setEditor(editor: editorCommon.ICommonCodeEditor) {
|
||||
if (this.editor !== editor) {
|
||||
this.disposeEditorListeners();
|
||||
this.editor = editor;
|
||||
this.editorDisposables.push(this.editor.onDidChangeCursorPosition((e: ICursorPositionChangedEvent) => {
|
||||
if (
|
||||
e.reason === CursorChangeReason.NotSet
|
||||
|| e.reason === CursorChangeReason.Explicit
|
||||
|| e.reason === CursorChangeReason.Undo
|
||||
|| e.reason === CursorChangeReason.Redo
|
||||
) {
|
||||
this.removeHighlightRange();
|
||||
}
|
||||
}));
|
||||
this.editorDisposables.push(this.editor.onDidChangeModel(() => { this.removeHighlightRange(); }));
|
||||
this.editorDisposables.push(this.editor.onDidDispose(() => {
|
||||
this.removeHighlightRange();
|
||||
this.editor = null;
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
private disposeEditorListeners() {
|
||||
this.editorDisposables.forEach(disposable => disposable.dispose());
|
||||
this.editorDisposables = [];
|
||||
}
|
||||
|
||||
private static _WHOLE_LINE_RANGE_HIGHLIGHT = ModelDecorationOptions.register({
|
||||
stickiness: editorCommon.TrackedRangeStickiness.NeverGrowsWhenTypingAtEdges,
|
||||
className: 'rangeHighlight',
|
||||
isWholeLine: true
|
||||
});
|
||||
|
||||
private static _RANGE_HIGHLIGHT = ModelDecorationOptions.register({
|
||||
stickiness: editorCommon.TrackedRangeStickiness.NeverGrowsWhenTypingAtEdges,
|
||||
className: 'rangeHighlight'
|
||||
});
|
||||
|
||||
private createRangeHighlightDecoration(isWholeLine: boolean = true): ModelDecorationOptions {
|
||||
return (isWholeLine ? RangeHighlightDecorations._WHOLE_LINE_RANGE_HIGHLIGHT : RangeHighlightDecorations._RANGE_HIGHLIGHT);
|
||||
}
|
||||
|
||||
public dispose() {
|
||||
if (this.editor && this.editor.getModel()) {
|
||||
this.removeHighlightRange();
|
||||
this.disposeEditorListeners();
|
||||
this.editor = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -70,11 +70,7 @@ export abstract class BaseTextEditorModel extends EditorModel implements ITextEd
|
||||
protected createTextEditorModel(value: string | IRawTextSource, resource?: URI, modeId?: string): TPromise<EditorModel> {
|
||||
const firstLineText = this.getFirstLineText(value);
|
||||
const mode = this.getOrCreateMode(this.modeService, modeId, firstLineText);
|
||||
|
||||
// To avoid flickering, give the mode at most 50ms to load. If the mode doesn't load in 50ms, proceed creating the model with a mode promise
|
||||
return TPromise.any<any>([TPromise.timeout(50), mode]).then(() => {
|
||||
return this.doCreateTextEditorModel(value, mode, resource);
|
||||
});
|
||||
return TPromise.as(this.doCreateTextEditorModel(value, mode, resource));
|
||||
}
|
||||
|
||||
private doCreateTextEditorModel(value: string | IRawTextSource, mode: TPromise<IMode>, resource: URI): EditorModel {
|
||||
@@ -166,4 +162,4 @@ export abstract class BaseTextEditorModel extends EditorModel implements ITextEd
|
||||
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -269,11 +269,8 @@ export class UntitledEditorInput extends EditorInput implements IEncodingSupport
|
||||
return true;
|
||||
}
|
||||
|
||||
// {{SQL CARBON EDIT}}
|
||||
let isUntitledInput: boolean = otherInput instanceof UntitledEditorInput;
|
||||
let isQueryInput: boolean = otherInput && otherInput.sql && otherInput.sql instanceof UntitledEditorInput;
|
||||
if (isUntitledInput || isQueryInput) {
|
||||
const otherUntitledEditorInput = isUntitledInput ? <UntitledEditorInput>otherInput : <UntitledEditorInput>otherInput.sql;
|
||||
if (otherInput instanceof UntitledEditorInput) {
|
||||
const otherUntitledEditorInput = <UntitledEditorInput>otherInput;
|
||||
|
||||
// Otherwise compare by properties
|
||||
return otherUntitledEditorInput.resource.toString() === this.resource.toString();
|
||||
|
||||
@@ -11,7 +11,7 @@ import { BaseTextEditorModel } from 'vs/workbench/common/editor/textEditorModel'
|
||||
import URI from 'vs/base/common/uri';
|
||||
import { PLAINTEXT_MODE_ID } from 'vs/editor/common/modes/modesRegistry';
|
||||
import { EndOfLinePreference } from 'vs/editor/common/editorCommon';
|
||||
import { IFilesConfiguration, CONTENT_CHANGE_EVENT_BUFFER_DELAY } from 'vs/platform/files/common/files';
|
||||
import { CONTENT_CHANGE_EVENT_BUFFER_DELAY } from 'vs/platform/files/common/files';
|
||||
import { IModeService } from 'vs/editor/common/services/modeService';
|
||||
import { IModelService } from 'vs/editor/common/services/modelService';
|
||||
import { IMode } from 'vs/editor/common/modes';
|
||||
@@ -98,8 +98,7 @@ export class UntitledEditorModel extends BaseTextEditorModel implements IEncodin
|
||||
}
|
||||
|
||||
private onConfigurationChange(): void {
|
||||
const configuration = this.configurationService.getConfiguration<IFilesConfiguration>(this.resource);
|
||||
const configuredEncoding = configuration && configuration.files && configuration.files.encoding;
|
||||
const configuredEncoding = this.configurationService.getValue<string>(this.resource, 'files.encoding');
|
||||
|
||||
if (this.configuredEncoding !== configuredEncoding) {
|
||||
this.configuredEncoding = configuredEncoding;
|
||||
@@ -185,10 +184,8 @@ export class UntitledEditorModel extends BaseTextEditorModel implements IEncodin
|
||||
this.setDirty(this.hasAssociatedFilePath || !!backupContent);
|
||||
|
||||
return this.doLoad(backupContent || this.initialValue || '').then(model => {
|
||||
const configuration = this.configurationService.getConfiguration<IFilesConfiguration>(this.resource);
|
||||
|
||||
// Encoding
|
||||
this.configuredEncoding = configuration && configuration.files && configuration.files.encoding;
|
||||
this.configuredEncoding = this.configurationService.getValue<string>(this.resource, 'files.encoding');
|
||||
|
||||
// Listen to content changes
|
||||
this.toDispose.push(this.textEditorModel.onDidChangeContent(() => this.onModelContentChanged()));
|
||||
|
||||
@@ -32,7 +32,7 @@ export class Memento {
|
||||
private static globalMementos: { [id: string]: ScopedMemento } = {};
|
||||
private static workspaceMementos: { [id: string]: ScopedMemento } = {};
|
||||
|
||||
private static COMMON_PREFIX = 'memento/';
|
||||
private static readonly COMMON_PREFIX = 'memento/';
|
||||
|
||||
private id: string;
|
||||
|
||||
|
||||
@@ -6,13 +6,7 @@
|
||||
'use strict';
|
||||
|
||||
import URI from 'vs/base/common/uri';
|
||||
import objects = require('vs/base/common/objects');
|
||||
import paths = require('vs/base/common/paths');
|
||||
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
|
||||
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
|
||||
import Event, { Emitter } from 'vs/base/common/event';
|
||||
import { IConfigurationService, IConfigurationChangeEvent } from 'vs/platform/configuration/common/configuration';
|
||||
import { ParsedExpression, IExpression, parse } from 'vs/base/common/glob';
|
||||
import { basename } from 'vs/base/common/paths';
|
||||
import { RawContextKey, IContextKeyService, IContextKey } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { IModeService } from 'vs/editor/common/services/modeService';
|
||||
@@ -63,114 +57,36 @@ export class ResourceContextKey implements IContextKey<URI> {
|
||||
}
|
||||
}
|
||||
|
||||
export class ResourceGlobMatcher {
|
||||
/**
|
||||
* Data URI related helpers.
|
||||
*/
|
||||
export namespace DataUri {
|
||||
|
||||
private static readonly NO_ROOT: string = null;
|
||||
export const META_DATA_LABEL = 'label';
|
||||
export const META_DATA_DESCRIPTION = 'description';
|
||||
export const META_DATA_SIZE = 'size';
|
||||
export const META_DATA_MIME = 'mime';
|
||||
|
||||
private _onExpressionChange: Emitter<void>;
|
||||
private toUnbind: IDisposable[];
|
||||
private mapRootToParsedExpression: Map<string, ParsedExpression>;
|
||||
private mapRootToExpressionConfig: Map<string, IExpression>;
|
||||
export function parseMetaData(dataUri: URI): Map<string, string> {
|
||||
const metadata = new Map<string, string>();
|
||||
|
||||
constructor(
|
||||
private globFn: (root?: URI) => IExpression,
|
||||
private shouldUpdate: (event: IConfigurationChangeEvent) => boolean,
|
||||
@IWorkspaceContextService private contextService: IWorkspaceContextService,
|
||||
@IConfigurationService private configurationService: IConfigurationService
|
||||
) {
|
||||
this.toUnbind = [];
|
||||
|
||||
this.mapRootToParsedExpression = new Map<string, ParsedExpression>();
|
||||
this.mapRootToExpressionConfig = new Map<string, IExpression>();
|
||||
|
||||
this._onExpressionChange = new Emitter<void>();
|
||||
this.toUnbind.push(this._onExpressionChange);
|
||||
|
||||
this.updateExcludes(false);
|
||||
|
||||
this.registerListeners();
|
||||
}
|
||||
|
||||
public get onExpressionChange(): Event<void> {
|
||||
return this._onExpressionChange.event;
|
||||
}
|
||||
|
||||
private registerListeners(): void {
|
||||
this.toUnbind.push(this.configurationService.onDidChangeConfiguration(e => {
|
||||
if (this.shouldUpdate(e)) {
|
||||
this.updateExcludes(true);
|
||||
}
|
||||
}));
|
||||
this.toUnbind.push(this.contextService.onDidChangeWorkspaceFolders(() => this.updateExcludes(true)));
|
||||
}
|
||||
|
||||
private updateExcludes(fromEvent: boolean): void {
|
||||
let changed = false;
|
||||
|
||||
// Add excludes per workspaces that got added
|
||||
this.contextService.getWorkspace().folders.forEach(folder => {
|
||||
const rootExcludes = this.globFn(folder.uri);
|
||||
if (!this.mapRootToExpressionConfig.has(folder.uri.toString()) || !objects.equals(this.mapRootToExpressionConfig.get(folder.uri.toString()), rootExcludes)) {
|
||||
changed = true;
|
||||
|
||||
this.mapRootToParsedExpression.set(folder.uri.toString(), parse(rootExcludes));
|
||||
this.mapRootToExpressionConfig.set(folder.uri.toString(), objects.clone(rootExcludes));
|
||||
// Given a URI of: data:image/png;size:2313;label:SomeLabel;description:SomeDescription;base64,77+9UE5...
|
||||
// the metadata is: size:2313;label:SomeLabel;description:SomeDescription
|
||||
const meta = dataUri.path.substring(dataUri.path.indexOf(';') + 1, dataUri.path.lastIndexOf(';'));
|
||||
meta.split(';').forEach(property => {
|
||||
const [key, value] = property.split(':');
|
||||
if (key && value) {
|
||||
metadata.set(key, value);
|
||||
}
|
||||
});
|
||||
|
||||
// Remove excludes per workspace no longer present
|
||||
this.mapRootToExpressionConfig.forEach((value, root) => {
|
||||
if (root === ResourceGlobMatcher.NO_ROOT) {
|
||||
return; // always keep this one
|
||||
}
|
||||
|
||||
if (!this.contextService.getWorkspaceFolder(URI.parse(root))) {
|
||||
this.mapRootToParsedExpression.delete(root);
|
||||
this.mapRootToExpressionConfig.delete(root);
|
||||
|
||||
changed = true;
|
||||
}
|
||||
});
|
||||
|
||||
// Always set for resources outside root as well
|
||||
const globalExcludes = this.globFn();
|
||||
if (!this.mapRootToExpressionConfig.has(ResourceGlobMatcher.NO_ROOT) || !objects.equals(this.mapRootToExpressionConfig.get(ResourceGlobMatcher.NO_ROOT), globalExcludes)) {
|
||||
changed = true;
|
||||
|
||||
this.mapRootToParsedExpression.set(ResourceGlobMatcher.NO_ROOT, parse(globalExcludes));
|
||||
this.mapRootToExpressionConfig.set(ResourceGlobMatcher.NO_ROOT, objects.clone(globalExcludes));
|
||||
// Given a URI of: data:image/png;size:2313;label:SomeLabel;description:SomeDescription;base64,77+9UE5...
|
||||
// the mime is: image/png
|
||||
const mime = dataUri.path.substring(0, dataUri.path.indexOf(';'));
|
||||
if (mime) {
|
||||
metadata.set(META_DATA_MIME, mime);
|
||||
}
|
||||
|
||||
if (fromEvent && changed) {
|
||||
this._onExpressionChange.fire();
|
||||
}
|
||||
}
|
||||
|
||||
public matches(resource: URI): boolean {
|
||||
const folder = this.contextService.getWorkspaceFolder(resource);
|
||||
|
||||
let expressionForRoot: ParsedExpression;
|
||||
if (folder && this.mapRootToParsedExpression.has(folder.uri.toString())) {
|
||||
expressionForRoot = this.mapRootToParsedExpression.get(folder.uri.toString());
|
||||
} else {
|
||||
expressionForRoot = this.mapRootToParsedExpression.get(ResourceGlobMatcher.NO_ROOT);
|
||||
}
|
||||
|
||||
// If the resource if from a workspace, convert its absolute path to a relative
|
||||
// path so that glob patterns have a higher probability to match. For example
|
||||
// a glob pattern of "src/**" will not match on an absolute path "/folder/src/file.txt"
|
||||
// but can match on "src/file.txt"
|
||||
let resourcePathToMatch: string;
|
||||
if (folder) {
|
||||
resourcePathToMatch = paths.normalize(paths.relative(folder.uri.fsPath, resource.fsPath));
|
||||
} else {
|
||||
resourcePathToMatch = resource.fsPath;
|
||||
}
|
||||
|
||||
return !!expressionForRoot(resourcePathToMatch);
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
this.toUnbind = dispose(this.toUnbind);
|
||||
return metadata;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ import { Command } from 'vs/editor/common/modes';
|
||||
|
||||
export type TreeViewItemHandleArg = {
|
||||
$treeViewId: string,
|
||||
$treeItemHandle: number
|
||||
$treeItemHandle: string
|
||||
};
|
||||
|
||||
export enum TreeItemCollapsibleState {
|
||||
@@ -20,7 +20,9 @@ export enum TreeItemCollapsibleState {
|
||||
|
||||
export interface ITreeItem {
|
||||
|
||||
handle: number;
|
||||
handle: string;
|
||||
|
||||
parentHandle: string;
|
||||
|
||||
label: string;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user