mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 18:46:40 -05:00
Merge from vscode 52dcb723a39ae75bee1bd56b3312d7fcdc87aeed (#6719)
This commit is contained in:
@@ -21,7 +21,7 @@ import { INotificationService } from 'vs/platform/notification/common/notificati
|
||||
class AlternativeKeyEmitter extends Emitter<boolean> {
|
||||
|
||||
private readonly _subscriptions = new DisposableStore();
|
||||
private _isPressed: boolean;
|
||||
private _isPressed: boolean = false;
|
||||
private static instance: AlternativeKeyEmitter;
|
||||
private _suppressAltKeyUp: boolean = false;
|
||||
|
||||
@@ -138,7 +138,7 @@ export class MenuEntryActionViewItem extends ActionViewItem {
|
||||
|
||||
static readonly ICON_PATH_TO_CSS_RULES: Map<string /* path*/, string /* CSS rule */> = new Map<string, string>();
|
||||
|
||||
private _wantsAltCommand: boolean;
|
||||
private _wantsAltCommand: boolean = false;
|
||||
private readonly _itemClassDispose = this._register(new MutableDisposable());
|
||||
private readonly _altKey: AlternativeKeyEmitter;
|
||||
|
||||
|
||||
@@ -31,8 +31,8 @@ class Menu extends Disposable implements IMenu {
|
||||
|
||||
private readonly _onDidChange = this._register(new Emitter<IMenu | undefined>());
|
||||
|
||||
private _menuGroups: MenuItemGroup[];
|
||||
private _contextKeys: Set<string>;
|
||||
private _menuGroups!: MenuItemGroup[];
|
||||
private _contextKeys!: Set<string>;
|
||||
|
||||
constructor(
|
||||
private readonly _id: MenuId,
|
||||
|
||||
@@ -10,7 +10,7 @@ import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiatio
|
||||
|
||||
export class BrowserClipboardService implements IClipboardService {
|
||||
|
||||
_serviceBrand: ServiceIdentifier<IClipboardService>;
|
||||
_serviceBrand!: ServiceIdentifier<IClipboardService>;
|
||||
|
||||
private _internalResourcesClipboard: URI[] | undefined;
|
||||
|
||||
@@ -46,4 +46,4 @@ export class BrowserClipboardService implements IClipboardService {
|
||||
}
|
||||
}
|
||||
|
||||
registerSingleton(IClipboardService, BrowserClipboardService, true);
|
||||
registerSingleton(IClipboardService, BrowserClipboardService, true);
|
||||
|
||||
@@ -63,6 +63,10 @@ export interface PerformanceInfo {
|
||||
workspaceInfo?: string;
|
||||
}
|
||||
|
||||
export interface IWorkspaceInformation extends IWorkspace {
|
||||
telemetryId: string | undefined;
|
||||
}
|
||||
|
||||
export const ID = 'diagnosticsService';
|
||||
export const IDiagnosticsService = createDecorator<IDiagnosticsService>(ID);
|
||||
|
||||
@@ -72,7 +76,7 @@ export interface IDiagnosticsService {
|
||||
getPerformanceInfo(mainProcessInfo: IMainProcessInfo, remoteInfo: (IRemoteDiagnosticInfo | IRemoteDiagnosticError)[]): Promise<PerformanceInfo>;
|
||||
getSystemInfo(mainProcessInfo: IMainProcessInfo, remoteInfo: (IRemoteDiagnosticInfo | IRemoteDiagnosticError)[]): Promise<SystemInfo>;
|
||||
getDiagnostics(mainProcessInfo: IMainProcessInfo, remoteInfo: (IRemoteDiagnosticInfo | IRemoteDiagnosticError)[]): Promise<string>;
|
||||
reportWorkspaceStats(workspace: IWorkspace): Promise<void>;
|
||||
reportWorkspaceStats(workspace: IWorkspaceInformation): Promise<void>;
|
||||
}
|
||||
|
||||
export function isRemoteDiagnosticError(x: any): x is IRemoteDiagnosticError {
|
||||
|
||||
@@ -36,7 +36,7 @@ export class DiagnosticsChannel implements IServerChannel {
|
||||
|
||||
export class DiagnosticsService implements IDiagnosticsService {
|
||||
|
||||
_serviceBrand: ServiceIdentifier<any>;
|
||||
_serviceBrand!: ServiceIdentifier<any>;
|
||||
|
||||
constructor(private channel: IChannel) { }
|
||||
|
||||
@@ -55,4 +55,4 @@ export class DiagnosticsService implements IDiagnosticsService {
|
||||
public reportWorkspaceStats(workspace: IWorkspace): Promise<void> {
|
||||
return this.channel.call('reportWorkspaceStats', workspace);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import * as osLib from 'os';
|
||||
import { virtualMachineHint } from 'vs/base/node/id';
|
||||
import { IMachineInfo, WorkspaceStats, WorkspaceStatItem, IDiagnosticsService, PerformanceInfo, SystemInfo, IRemoteDiagnosticInfo, IRemoteDiagnosticError, isRemoteDiagnosticError } from 'vs/platform/diagnostics/common/diagnosticsService';
|
||||
import { IMachineInfo, WorkspaceStats, WorkspaceStatItem, IDiagnosticsService, PerformanceInfo, SystemInfo, IRemoteDiagnosticInfo, IRemoteDiagnosticError, isRemoteDiagnosticError, IWorkspaceInformation } from 'vs/platform/diagnostics/common/diagnosticsService';
|
||||
import { readdir, stat, exists, readFile } from 'fs';
|
||||
import { join, basename } from 'vs/base/common/path';
|
||||
import { parse, ParseError } from 'vs/base/common/json';
|
||||
@@ -16,7 +16,6 @@ import { isWindows } from 'vs/base/common/platform';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { ProcessItem } from 'vs/base/common/processes';
|
||||
import { IMainProcessInfo } from 'vs/platform/launch/common/launchService';
|
||||
import { IWorkspace } from 'vs/platform/workspace/common/workspace';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
|
||||
export interface VersionInfo {
|
||||
@@ -514,7 +513,7 @@ export class DiagnosticsService implements IDiagnosticsService {
|
||||
}
|
||||
}
|
||||
|
||||
public async reportWorkspaceStats(workspace: IWorkspace): Promise<void> {
|
||||
public async reportWorkspaceStats(workspace: IWorkspaceInformation): Promise<void> {
|
||||
workspace.folders.forEach(folder => {
|
||||
const folderUri = URI.revive(folder.uri);
|
||||
if (folderUri.scheme === 'file') {
|
||||
@@ -525,16 +524,19 @@ export class DiagnosticsService implements IDiagnosticsService {
|
||||
count: { classification: 'SystemMetaData', purpose: 'FeatureInsight', isMeasurement: true };
|
||||
};
|
||||
type WorkspaceStatsClassification = {
|
||||
'workspace.id': { classification: 'SystemMetaData', purpose: 'FeatureInsight' };
|
||||
fileTypes: WorkspaceStatItemClassification;
|
||||
configTypes: WorkspaceStatItemClassification;
|
||||
launchConfigs: WorkspaceStatItemClassification;
|
||||
};
|
||||
type WorkspaceStatsEvent = {
|
||||
'workspace.id': string | undefined;
|
||||
fileTypes: WorkspaceStatItem[];
|
||||
configTypes: WorkspaceStatItem[];
|
||||
launchConfigs: WorkspaceStatItem[];
|
||||
};
|
||||
this.telemetryService.publicLog2<WorkspaceStatsEvent, WorkspaceStatsClassification>('workspace.stats', {
|
||||
'workspace.id': workspace.telemetryId,
|
||||
fileTypes: stats.fileTypes,
|
||||
configTypes: stats.configFiles,
|
||||
launchConfigs: stats.launchConfigFiles
|
||||
@@ -545,4 +547,4 @@ export class DiagnosticsService implements IDiagnosticsService {
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,32 +40,35 @@ export class DialogService implements IDialogService {
|
||||
buttons.push(nls.localize('cancelButton', "Cancel"));
|
||||
}
|
||||
|
||||
const severity = this.getSeverity(confirmation.type || 'none');
|
||||
const result = await this.show(severity, confirmation.message, buttons, { cancelId: 1, detail: confirmation.detail });
|
||||
const dialogDisposables = new DisposableStore();
|
||||
const dialog = new Dialog(
|
||||
this.layoutService.container,
|
||||
confirmation.message,
|
||||
buttons,
|
||||
{
|
||||
detail: confirmation.detail,
|
||||
cancelId: 1,
|
||||
type: confirmation.type,
|
||||
keyEventProcessor: (event: StandardKeyboardEvent) => {
|
||||
EventHelper.stop(event, true);
|
||||
},
|
||||
checkboxChecked: confirmation.checkbox ? confirmation.checkbox.checked : undefined,
|
||||
checkboxLabel: confirmation.checkbox ? confirmation.checkbox.label : undefined
|
||||
});
|
||||
|
||||
return { confirmed: result === 0 };
|
||||
}
|
||||
dialogDisposables.add(dialog);
|
||||
dialogDisposables.add(attachDialogStyler(dialog, this.themeService));
|
||||
|
||||
private getSeverity(type: DialogType): Severity {
|
||||
switch (type) {
|
||||
case 'error':
|
||||
return Severity.Error;
|
||||
case 'warning':
|
||||
return Severity.Warning;
|
||||
case 'question':
|
||||
case 'info':
|
||||
return Severity.Info;
|
||||
case 'none':
|
||||
default:
|
||||
return Severity.Ignore;
|
||||
}
|
||||
const result = await dialog.show();
|
||||
dialogDisposables.dispose();
|
||||
|
||||
return { confirmed: result.button === 0, checkboxChecked: result.checkboxChecked };
|
||||
}
|
||||
|
||||
private getDialogType(severity: Severity): DialogType {
|
||||
return (severity === Severity.Info) ? 'question' : (severity === Severity.Error) ? 'error' : (severity === Severity.Warning) ? 'warning' : 'none';
|
||||
}
|
||||
|
||||
|
||||
async show(severity: Severity, message: string, buttons: string[], options?: IDialogOptions): Promise<number> {
|
||||
this.logService.trace('DialogService#show', message);
|
||||
|
||||
@@ -86,9 +89,9 @@ export class DialogService implements IDialogService {
|
||||
dialogDisposables.add(dialog);
|
||||
dialogDisposables.add(attachDialogStyler(dialog, this.themeService));
|
||||
|
||||
const choice = await dialog.show();
|
||||
const result = await dialog.show();
|
||||
dialogDisposables.dispose();
|
||||
|
||||
return choice;
|
||||
return result.button;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -127,6 +127,8 @@ export const IDialogService = createDecorator<IDialogService>('dialogService');
|
||||
export interface IDialogOptions {
|
||||
cancelId?: number;
|
||||
detail?: string;
|
||||
checkboxLabel?: string;
|
||||
checkboxChecked?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -234,4 +236,4 @@ export function getConfirmMessage(start: string, resourcesToConfirm: URI[]): str
|
||||
|
||||
message.push('');
|
||||
return message.join('\n');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { createDecorator, ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
|
||||
export interface ParsedArgs {
|
||||
@@ -38,6 +38,7 @@ export interface ParsedArgs {
|
||||
'builtin-extensions-dir'?: string;
|
||||
extensionDevelopmentPath?: string | string[]; // one or more local paths or URIs
|
||||
extensionTestsPath?: string; // either a local path or a URI
|
||||
'extension-development-confirm-save'?: boolean;
|
||||
'inspect-extensions'?: string;
|
||||
'inspect-brk-extensions'?: string;
|
||||
debugId?: string;
|
||||
@@ -105,7 +106,8 @@ export interface IExtensionHostDebugParams extends IDebugParams {
|
||||
export const BACKUPS = 'Backups';
|
||||
|
||||
export interface IEnvironmentService {
|
||||
_serviceBrand: any;
|
||||
|
||||
_serviceBrand: ServiceIdentifier<any>;
|
||||
|
||||
args: ParsedArgs;
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as minimist from 'minimist';
|
||||
import * as minimist from 'vscode-minimist';
|
||||
import * as os from 'os';
|
||||
import { localize } from 'vs/nls';
|
||||
import { ParsedArgs } from 'vs/platform/environment/common/environment';
|
||||
@@ -69,6 +69,7 @@ export const options: Option[] = [
|
||||
{ id: 'locate-extension', type: 'string' },
|
||||
{ id: 'extensionDevelopmentPath', type: 'string' },
|
||||
{ id: 'extensionTestsPath', type: 'string' },
|
||||
{ id: 'extension-development-confirm-save', type: 'boolean' },
|
||||
{ id: 'debugId', type: 'string' },
|
||||
{ id: 'inspect-search', type: 'string', deprecates: 'debugSearch' },
|
||||
{ id: 'inspect-brk-search', type: 'string', deprecates: 'debugBrkSearch' },
|
||||
@@ -141,6 +142,10 @@ export function parseArgs(args: string[], isOptionSupported = (_: Option) => tru
|
||||
delete parsedArgs[o.deprecates];
|
||||
}
|
||||
}
|
||||
|
||||
// https://github.com/microsoft/vscode/issues/58177
|
||||
parsedArgs._ = parsedArgs._.filter(arg => arg.length > 0);
|
||||
|
||||
return parsedArgs;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ import { toLocalISOString } from 'vs/base/common/date';
|
||||
import { isWindows, isLinux } from 'vs/base/common/platform';
|
||||
import { getPathFromAmdModule } from 'vs/base/common/amd';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation';
|
||||
|
||||
// Read this before there's any chance it is overwritten
|
||||
// Related to https://github.com/Microsoft/vscode/issues/30624
|
||||
@@ -76,7 +77,7 @@ function getCLIPath(execPath: string, appRoot: string, isBuilt: boolean): string
|
||||
|
||||
export class EnvironmentService implements IEnvironmentService {
|
||||
|
||||
_serviceBrand: any;
|
||||
_serviceBrand!: ServiceIdentifier<any>;
|
||||
|
||||
get args(): ParsedArgs { return this._args; }
|
||||
|
||||
|
||||
@@ -52,4 +52,15 @@ suite('EnvironmentService', () => {
|
||||
assert.equal(parse(['--user-data-dir', './dir'], { cwd: () => '/foo', env: { 'VSCODE_CWD': '/bar' } }), path.resolve('/bar/dir'),
|
||||
'should use VSCODE_CWD as the cwd when --user-data-dir is specified');
|
||||
});
|
||||
|
||||
// https://github.com/microsoft/vscode/issues/78440
|
||||
test('careful with boolean file names', function () {
|
||||
let actual = parseArgs(['-r', 'arg.txt']);
|
||||
assert(actual['reuse-window']);
|
||||
assert.deepEqual(actual._, ['arg.txt']);
|
||||
|
||||
actual = parseArgs(['-r', 'true.txt']);
|
||||
assert(actual['reuse-window']);
|
||||
assert.deepEqual(actual._, ['true.txt']);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -21,7 +21,7 @@ import { Schemas } from 'vs/base/common/network';
|
||||
|
||||
export class FileService extends Disposable implements IFileService {
|
||||
|
||||
_serviceBrand: ServiceIdentifier<any>;
|
||||
_serviceBrand!: ServiceIdentifier<any>;
|
||||
|
||||
private readonly BUFFER_SIZE = 64 * 1024;
|
||||
|
||||
@@ -164,21 +164,25 @@ export class FileService extends Disposable implements IFileService {
|
||||
private async doResolveFile(resource: URI, options?: IResolveFileOptions): Promise<IFileStat> {
|
||||
const provider = await this.withProvider(resource);
|
||||
|
||||
// leverage a trie to check for recursive resolving
|
||||
const resolveTo = options && options.resolveTo;
|
||||
const trie = TernarySearchTree.forPaths<true>();
|
||||
trie.set(resource.toString(), true);
|
||||
if (isNonEmptyArray(resolveTo)) {
|
||||
resolveTo.forEach(uri => trie.set(uri.toString(), true));
|
||||
}
|
||||
|
||||
const resolveSingleChildDescendants = !!(options && options.resolveSingleChildDescendants);
|
||||
const resolveMetadata = !!(options && options.resolveMetadata);
|
||||
|
||||
const stat = await provider.stat(resource);
|
||||
|
||||
let trie: TernarySearchTree<boolean> | undefined;
|
||||
|
||||
return this.toFileStat(provider, resource, stat, undefined, resolveMetadata, (stat, siblings) => {
|
||||
|
||||
// lazy trie to check for recursive resolving
|
||||
if (!trie) {
|
||||
trie = TernarySearchTree.forPaths<true>();
|
||||
trie.set(resource.toString(), true);
|
||||
if (isNonEmptyArray(resolveTo)) {
|
||||
resolveTo.forEach(uri => trie!.set(uri.toString(), true));
|
||||
}
|
||||
}
|
||||
|
||||
// check for recursive resolving
|
||||
if (Boolean(trie.findSuperstr(stat.resource.toString()) || trie.get(stat.resource.toString()))) {
|
||||
return true;
|
||||
@@ -253,8 +257,12 @@ export class FileService extends Disposable implements IFileService {
|
||||
}
|
||||
|
||||
async exists(resource: URI): Promise<boolean> {
|
||||
const provider = await this.withProvider(resource);
|
||||
|
||||
try {
|
||||
return !!(await this.resolve(resource));
|
||||
const stat = await provider.stat(resource);
|
||||
|
||||
return !!stat;
|
||||
} catch (error) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -3,14 +3,14 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { mkdir, open, close, read, write, fdatasync, Dirent, Stats } from 'fs';
|
||||
import { mkdir, open, close, read, write, fdatasync } from 'fs';
|
||||
import { promisify } from 'util';
|
||||
import { IDisposable, Disposable, toDisposable, dispose, combinedDisposable } from 'vs/base/common/lifecycle';
|
||||
import { IFileSystemProvider, FileSystemProviderCapabilities, IFileChange, IWatchOptions, IStat, FileType, FileDeleteOptions, FileOverwriteOptions, FileWriteOptions, FileOpenOptions, FileSystemProviderErrorCode, createFileSystemProviderError, FileSystemProviderError } from 'vs/platform/files/common/files';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
import { isLinux, isWindows } from 'vs/base/common/platform';
|
||||
import { statLink, unlink, move, copy, readFile, truncate, rimraf, RimRafMode, exists, readdirWithFileTypes } from 'vs/base/node/pfs';
|
||||
import { statLink, readdir, unlink, move, copy, readFile, truncate, rimraf, RimRafMode, exists } from 'vs/base/node/pfs';
|
||||
import { normalize, basename, dirname } from 'vs/base/common/path';
|
||||
import { joinPath } from 'vs/base/common/resources';
|
||||
import { isEqual } from 'vs/base/common/extpath';
|
||||
@@ -62,8 +62,15 @@ export class DiskFileSystemProvider extends Disposable implements IFileSystemPro
|
||||
try {
|
||||
const { stat, isSymbolicLink } = await statLink(this.toFilePath(resource)); // cannot use fs.stat() here to support links properly
|
||||
|
||||
let type: number;
|
||||
if (isSymbolicLink) {
|
||||
type = FileType.SymbolicLink | (stat.isDirectory() ? FileType.Directory : FileType.File);
|
||||
} else {
|
||||
type = stat.isFile() ? FileType.File : stat.isDirectory() ? FileType.Directory : FileType.Unknown;
|
||||
}
|
||||
|
||||
return {
|
||||
type: this.toType(stat, isSymbolicLink),
|
||||
type,
|
||||
ctime: stat.ctime.getTime(),
|
||||
mtime: stat.mtime.getTime(),
|
||||
size: stat.size
|
||||
@@ -75,19 +82,13 @@ export class DiskFileSystemProvider extends Disposable implements IFileSystemPro
|
||||
|
||||
async readdir(resource: URI): Promise<[string, FileType][]> {
|
||||
try {
|
||||
const children = await readdirWithFileTypes(this.toFilePath(resource));
|
||||
const children = await readdir(this.toFilePath(resource));
|
||||
|
||||
const result: [string, FileType][] = [];
|
||||
await Promise.all(children.map(async child => {
|
||||
try {
|
||||
let type: FileType;
|
||||
if (child.isSymbolicLink()) {
|
||||
type = (await this.stat(joinPath(resource, child.name))).type; // always resolve target the link points to if any
|
||||
} else {
|
||||
type = this.toType(child);
|
||||
}
|
||||
|
||||
result.push([child.name, type]);
|
||||
const stat = await this.stat(joinPath(resource, child));
|
||||
result.push([child, stat.type]);
|
||||
} catch (error) {
|
||||
this.logService.trace(error); // ignore errors for individual entries that can arise from permission denied
|
||||
}
|
||||
@@ -99,14 +100,6 @@ export class DiskFileSystemProvider extends Disposable implements IFileSystemPro
|
||||
}
|
||||
}
|
||||
|
||||
private toType(entry: Stats | Dirent, isSymbolicLink = entry.isSymbolicLink()): FileType {
|
||||
if (isSymbolicLink) {
|
||||
return FileType.SymbolicLink | (entry.isDirectory() ? FileType.Directory : FileType.File);
|
||||
}
|
||||
|
||||
return entry.isFile() ? FileType.File : entry.isDirectory() ? FileType.Directory : FileType.Unknown;
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region File Reading/Writing
|
||||
@@ -148,6 +141,8 @@ export class DiskFileSystemProvider extends Disposable implements IFileSystemPro
|
||||
}
|
||||
}
|
||||
|
||||
private mapHandleToPos: Map<number, number> = new Map();
|
||||
|
||||
private writeHandles: Set<number> = new Set();
|
||||
private canFlush: boolean = true;
|
||||
|
||||
@@ -187,6 +182,13 @@ export class DiskFileSystemProvider extends Disposable implements IFileSystemPro
|
||||
|
||||
const handle = await promisify(open)(filePath, flags);
|
||||
|
||||
// remember this handle to track file position of the handle
|
||||
// we init the position to 0 since the file descriptor was
|
||||
// just created and the position was not moved so far (see
|
||||
// also http://man7.org/linux/man-pages/man2/open.2.html -
|
||||
// "The file offset is set to the beginning of the file.")
|
||||
this.mapHandleToPos.set(handle, 0);
|
||||
|
||||
// remember that this handle was used for writing
|
||||
if (opts.create) {
|
||||
this.writeHandles.add(handle);
|
||||
@@ -200,6 +202,10 @@ export class DiskFileSystemProvider extends Disposable implements IFileSystemPro
|
||||
|
||||
async close(fd: number): Promise<void> {
|
||||
try {
|
||||
|
||||
// remove this handle from map of positions
|
||||
this.mapHandleToPos.delete(fd);
|
||||
|
||||
// if a handle is closed that was used for writing, ensure
|
||||
// to flush the contents to disk if possible.
|
||||
if (this.writeHandles.delete(fd) && this.canFlush) {
|
||||
@@ -220,15 +226,81 @@ export class DiskFileSystemProvider extends Disposable implements IFileSystemPro
|
||||
}
|
||||
|
||||
async read(fd: number, pos: number, data: Uint8Array, offset: number, length: number): Promise<number> {
|
||||
const normalizedPos = this.normalizePos(fd, pos);
|
||||
|
||||
let bytesRead: number | null = null;
|
||||
try {
|
||||
const result = await promisify(read)(fd, data, offset, length, pos);
|
||||
const result = await promisify(read)(fd, data, offset, length, normalizedPos);
|
||||
|
||||
if (typeof result === 'number') {
|
||||
return result; // node.d.ts fail
|
||||
bytesRead = result; // node.d.ts fail
|
||||
} else {
|
||||
bytesRead = result.bytesRead;
|
||||
}
|
||||
|
||||
return result.bytesRead;
|
||||
return bytesRead;
|
||||
} catch (error) {
|
||||
throw this.toFileSystemProviderError(error);
|
||||
} finally {
|
||||
this.updatePos(fd, normalizedPos, bytesRead);
|
||||
}
|
||||
}
|
||||
|
||||
private normalizePos(fd: number, pos: number): number | null {
|
||||
|
||||
// when calling fs.read/write we try to avoid passing in the "pos" argument and
|
||||
// rather prefer to pass in "null" because this avoids an extra seek(pos)
|
||||
// call that in some cases can even fail (e.g. when opening a file over FTP -
|
||||
// see https://github.com/microsoft/vscode/issues/73884).
|
||||
//
|
||||
// as such, we compare the passed in position argument with our last known
|
||||
// position for the file descriptor and use "null" if they match.
|
||||
if (pos === this.mapHandleToPos.get(fd)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
private updatePos(fd: number, pos: number | null, bytesLength: number | null): void {
|
||||
const lastKnownPos = this.mapHandleToPos.get(fd);
|
||||
if (typeof lastKnownPos === 'number') {
|
||||
|
||||
// pos !== null signals that previously a position was used that is
|
||||
// not null. node.js documentation explains, that in this case
|
||||
// the internal file pointer is not moving and as such we do not move
|
||||
// our position pointer.
|
||||
//
|
||||
// Docs: "If position is null, data will be read from the current file position,
|
||||
// and the file position will be updated. If position is an integer, the file position
|
||||
// will remain unchanged."
|
||||
if (typeof pos === 'number') {
|
||||
// do not modify the position
|
||||
}
|
||||
|
||||
// bytesLength = number is a signal that the read/write operation was
|
||||
// successful and as such we need to advance the position in the Map
|
||||
//
|
||||
// Docs (http://man7.org/linux/man-pages/man2/read.2.html):
|
||||
// "On files that support seeking, the read operation commences at the
|
||||
// file offset, and the file offset is incremented by the number of
|
||||
// bytes read."
|
||||
//
|
||||
// Docs (http://man7.org/linux/man-pages/man2/write.2.html):
|
||||
// "For a seekable file (i.e., one to which lseek(2) may be applied, for
|
||||
// example, a regular file) writing takes place at the file offset, and
|
||||
// the file offset is incremented by the number of bytes actually
|
||||
// written."
|
||||
else if (typeof bytesLength === 'number') {
|
||||
this.mapHandleToPos.set(fd, lastKnownPos + bytesLength);
|
||||
}
|
||||
|
||||
// bytesLength = null signals an error in the read/write operation
|
||||
// and as such we drop the handle from the Map because the position
|
||||
// is unspecificed at this point.
|
||||
else {
|
||||
this.mapHandleToPos.delete(fd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -240,15 +312,23 @@ export class DiskFileSystemProvider extends Disposable implements IFileSystemPro
|
||||
}
|
||||
|
||||
private async doWrite(fd: number, pos: number, data: Uint8Array, offset: number, length: number): Promise<number> {
|
||||
const normalizedPos = this.normalizePos(fd, pos);
|
||||
|
||||
let bytesWritten: number | null = null;
|
||||
try {
|
||||
const result = await promisify(write)(fd, data, offset, length, pos);
|
||||
const result = await promisify(write)(fd, data, offset, length, normalizedPos);
|
||||
|
||||
if (typeof result === 'number') {
|
||||
return result; // node.d.ts fail
|
||||
bytesWritten = result; // node.d.ts fail
|
||||
} else {
|
||||
bytesWritten = result.bytesWritten;
|
||||
}
|
||||
|
||||
return result.bytesWritten;
|
||||
return bytesWritten;
|
||||
} catch (error) {
|
||||
throw this.toFileSystemProviderError(error);
|
||||
} finally {
|
||||
this.updatePos(fd, normalizedPos, bytesWritten);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -441,14 +521,17 @@ export class DiskFileSystemProvider extends Disposable implements IFileSystemPro
|
||||
watcherOptions?: IWatcherOptions
|
||||
): WindowsWatcherService | UnixWatcherService | NsfwWatcherService
|
||||
};
|
||||
let watcherOptions = undefined;
|
||||
|
||||
let watcherOptions: IWatcherOptions | undefined = undefined;
|
||||
|
||||
// requires a polling watcher
|
||||
if (this.watcherOptions && this.watcherOptions.usePolling) {
|
||||
// requires a polling watcher
|
||||
watcherImpl = UnixWatcherService;
|
||||
watcherOptions = this.watcherOptions;
|
||||
} else {
|
||||
// Single Folder Watcher
|
||||
}
|
||||
|
||||
// Single Folder Watcher
|
||||
else {
|
||||
if (this.recursiveFoldersToWatch.length === 1) {
|
||||
if (isWindows) {
|
||||
watcherImpl = WindowsWatcherService;
|
||||
@@ -471,6 +554,7 @@ export class DiskFileSystemProvider extends Disposable implements IFileSystemPro
|
||||
if (msg.type === 'error') {
|
||||
this._onDidWatchErrorOccur.fire(msg.message);
|
||||
}
|
||||
|
||||
this.logService[msg.type](msg.message);
|
||||
},
|
||||
this.logService.getLevel() === LogLevel.Trace,
|
||||
@@ -478,7 +562,7 @@ export class DiskFileSystemProvider extends Disposable implements IFileSystemPro
|
||||
);
|
||||
|
||||
if (!this.recursiveWatcherLogLevelListener) {
|
||||
this.recursiveWatcherLogLevelListener = this.logService.onDidChangeLogLevel(_ => {
|
||||
this.recursiveWatcherLogLevelListener = this.logService.onDidChangeLogLevel(() => {
|
||||
if (this.recursiveWatcher) {
|
||||
this.recursiveWatcher.setVerboseLogging(this.logService.getLevel() === LogLevel.Trace);
|
||||
}
|
||||
@@ -496,11 +580,13 @@ export class DiskFileSystemProvider extends Disposable implements IFileSystemPro
|
||||
if (msg.type === 'error') {
|
||||
this._onDidWatchErrorOccur.fire(msg.message);
|
||||
}
|
||||
|
||||
this.logService[msg.type](msg.message);
|
||||
},
|
||||
this.logService.getLevel() === LogLevel.Trace
|
||||
);
|
||||
const logLevelListener = this.logService.onDidChangeLogLevel(_ => {
|
||||
|
||||
const logLevelListener = this.logService.onDidChangeLogLevel(() => {
|
||||
watcherService.setVerboseLogging(this.logService.getLevel() === LogLevel.Trace);
|
||||
});
|
||||
|
||||
@@ -553,4 +639,4 @@ export class DiskFileSystemProvider extends Disposable implements IFileSystemPro
|
||||
dispose(this.recursiveWatcherLogLevelListener);
|
||||
this.recursiveWatcherLogLevelListener = undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ export class OutOfProcessWin32FolderWatcher {
|
||||
|
||||
private ignored: glob.ParsedPattern[];
|
||||
|
||||
private handle: cp.ChildProcess;
|
||||
private handle: cp.ChildProcess | undefined;
|
||||
private restartCounter: number;
|
||||
|
||||
constructor(
|
||||
|
||||
@@ -62,9 +62,9 @@ export class TestDiskFileSystemProvider extends DiskFileSystemProvider {
|
||||
|
||||
totalBytesRead: number = 0;
|
||||
|
||||
private invalidStatSize: boolean;
|
||||
private invalidStatSize: boolean = false;
|
||||
|
||||
private _testCapabilities: FileSystemProviderCapabilities;
|
||||
private _testCapabilities!: FileSystemProviderCapabilities;
|
||||
get capabilities(): FileSystemProviderCapabilities {
|
||||
if (!this._testCapabilities) {
|
||||
this._testCapabilities =
|
||||
@@ -115,7 +115,7 @@ export class TestDiskFileSystemProvider extends DiskFileSystemProvider {
|
||||
}
|
||||
}
|
||||
|
||||
suite('Disk File Service', () => {
|
||||
suite('Disk File Service', function () {
|
||||
|
||||
const parentDir = getRandomTestPath(tmpdir(), 'vsctests', 'diskfileservice');
|
||||
const testSchema = 'test';
|
||||
@@ -127,6 +127,12 @@ suite('Disk File Service', () => {
|
||||
|
||||
const disposables = new DisposableStore();
|
||||
|
||||
// Given issues such as https://github.com/microsoft/vscode/issues/78602
|
||||
// we see random test failures when accessing the native file system. To
|
||||
// diagnose further, we retry node.js file access tests up to 3 times to
|
||||
// rule out any random disk issue.
|
||||
this.retries(3);
|
||||
|
||||
setup(async () => {
|
||||
const logService = new NullLogService();
|
||||
|
||||
@@ -613,7 +619,7 @@ suite('Disk File Service', () => {
|
||||
await testMoveFolderAcrossProviders();
|
||||
});
|
||||
|
||||
test('move - directory - across providers (unbuffered => buffered)', async () => {
|
||||
test('move - directory - across providers (unbuffered => buffered)', async function () {
|
||||
setCapabilities(fileProvider, FileSystemProviderCapabilities.FileReadWrite);
|
||||
setCapabilities(testProvider, FileSystemProviderCapabilities.FileOpenReadWriteClose);
|
||||
|
||||
@@ -1915,4 +1921,94 @@ suite('Disk File Service', () => {
|
||||
function hasChange(changes: IFileChange[], type: FileChangeType, resource: URI): boolean {
|
||||
return changes.some(change => change.type === type && isEqual(change.resource, resource));
|
||||
}
|
||||
});
|
||||
|
||||
test('read - mixed positions', async () => {
|
||||
const resource = URI.file(join(testDir, 'lorem.txt'));
|
||||
|
||||
// read multiple times from position 0
|
||||
let buffer = VSBuffer.alloc(1024);
|
||||
let fd = await fileProvider.open(resource, { create: false });
|
||||
for (let i = 0; i < 3; i++) {
|
||||
await fileProvider.read(fd, 0, buffer.buffer, 0, 26);
|
||||
assert.equal(buffer.slice(0, 26).toString(), 'Lorem ipsum dolor sit amet');
|
||||
}
|
||||
await fileProvider.close(fd);
|
||||
|
||||
// read multiple times at various locations
|
||||
buffer = VSBuffer.alloc(1024);
|
||||
fd = await fileProvider.open(resource, { create: false });
|
||||
|
||||
let posInFile = 0;
|
||||
|
||||
await fileProvider.read(fd, posInFile, buffer.buffer, 0, 26);
|
||||
assert.equal(buffer.slice(0, 26).toString(), 'Lorem ipsum dolor sit amet');
|
||||
posInFile += 26;
|
||||
|
||||
await fileProvider.read(fd, posInFile, buffer.buffer, 0, 1);
|
||||
assert.equal(buffer.slice(0, 1).toString(), ',');
|
||||
posInFile += 1;
|
||||
|
||||
await fileProvider.read(fd, posInFile, buffer.buffer, 0, 12);
|
||||
assert.equal(buffer.slice(0, 12).toString(), ' consectetur');
|
||||
posInFile += 12;
|
||||
|
||||
await fileProvider.read(fd, 98 /* no longer in sequence of posInFile */, buffer.buffer, 0, 9);
|
||||
assert.equal(buffer.slice(0, 9).toString(), 'fermentum');
|
||||
|
||||
await fileProvider.read(fd, 27, buffer.buffer, 0, 12);
|
||||
assert.equal(buffer.slice(0, 12).toString(), ' consectetur');
|
||||
|
||||
await fileProvider.read(fd, 26, buffer.buffer, 0, 1);
|
||||
assert.equal(buffer.slice(0, 1).toString(), ',');
|
||||
|
||||
await fileProvider.read(fd, 0, buffer.buffer, 0, 26);
|
||||
assert.equal(buffer.slice(0, 26).toString(), 'Lorem ipsum dolor sit amet');
|
||||
|
||||
await fileProvider.read(fd, posInFile /* back in sequence */, buffer.buffer, 0, 11);
|
||||
assert.equal(buffer.slice(0, 11).toString(), ' adipiscing');
|
||||
|
||||
await fileProvider.close(fd);
|
||||
});
|
||||
|
||||
test('write - mixed positions', async () => {
|
||||
const resource = URI.file(join(testDir, 'lorem.txt'));
|
||||
|
||||
const buffer = VSBuffer.alloc(1024);
|
||||
const fdWrite = await fileProvider.open(resource, { create: true });
|
||||
const fdRead = await fileProvider.open(resource, { create: false });
|
||||
|
||||
let posInFileWrite = 0;
|
||||
let posInFileRead = 0;
|
||||
|
||||
const initialContents = VSBuffer.fromString('Lorem ipsum dolor sit amet');
|
||||
await fileProvider.write(fdWrite, posInFileWrite, initialContents.buffer, 0, initialContents.byteLength);
|
||||
posInFileWrite += initialContents.byteLength;
|
||||
|
||||
await fileProvider.read(fdRead, posInFileRead, buffer.buffer, 0, 26);
|
||||
assert.equal(buffer.slice(0, 26).toString(), 'Lorem ipsum dolor sit amet');
|
||||
posInFileRead += 26;
|
||||
|
||||
const contents = VSBuffer.fromString('Hello World');
|
||||
|
||||
await fileProvider.write(fdWrite, posInFileWrite, contents.buffer, 0, contents.byteLength);
|
||||
posInFileWrite += contents.byteLength;
|
||||
|
||||
await fileProvider.read(fdRead, posInFileRead, buffer.buffer, 0, contents.byteLength);
|
||||
assert.equal(buffer.slice(0, contents.byteLength).toString(), 'Hello World');
|
||||
posInFileRead += contents.byteLength;
|
||||
|
||||
await fileProvider.write(fdWrite, 6, contents.buffer, 0, contents.byteLength);
|
||||
|
||||
await fileProvider.read(fdRead, 0, buffer.buffer, 0, 11);
|
||||
assert.equal(buffer.slice(0, 11).toString(), 'Lorem Hello');
|
||||
|
||||
await fileProvider.write(fdWrite, posInFileWrite, contents.buffer, 0, contents.byteLength);
|
||||
posInFileWrite += contents.byteLength;
|
||||
|
||||
await fileProvider.read(fdRead, posInFileWrite - contents.byteLength, buffer.buffer, 0, contents.byteLength);
|
||||
assert.equal(buffer.slice(0, contents.byteLength).toString(), 'Hello World');
|
||||
|
||||
await fileProvider.close(fdWrite);
|
||||
await fileProvider.close(fdRead);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -40,7 +40,7 @@ export class HistoryMainService implements IHistoryMainService {
|
||||
|
||||
private static readonly recentlyOpenedStorageKey = 'openedPathsList';
|
||||
|
||||
_serviceBrand: ServiceIdentifier<IHistoryMainService>;
|
||||
_serviceBrand!: ServiceIdentifier<IHistoryMainService>;
|
||||
|
||||
private _onRecentlyOpenedChange = new Emitter<void>();
|
||||
readonly onRecentlyOpenedChange: CommonEvent<void> = this._onRecentlyOpenedChange.event;
|
||||
@@ -387,4 +387,4 @@ function indexOfFolder(arr: IRecent[], folderURI: ISingleFolderWorkspaceIdentifi
|
||||
|
||||
function indexOfFile(arr: IRecentFile[], fileURI: URI): number {
|
||||
return arrays.firstIndex(arr, f => areResourcesEqual(f.fileUri, fileURI));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ export interface IMainProcessService {
|
||||
|
||||
export class MainProcessService extends Disposable implements IMainProcessService {
|
||||
|
||||
_serviceBrand: ServiceIdentifier<any>;
|
||||
_serviceBrand!: ServiceIdentifier<any>;
|
||||
|
||||
private mainProcessConnection: Client;
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ export interface ISharedProcessService {
|
||||
|
||||
export class SharedProcessService implements ISharedProcessService {
|
||||
|
||||
_serviceBrand: ServiceIdentifier<any>;
|
||||
_serviceBrand!: ServiceIdentifier<any>;
|
||||
|
||||
private withSharedProcessConnection: Promise<Client<string>>;
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiatio
|
||||
|
||||
export class IssueService implements IIssueService {
|
||||
|
||||
_serviceBrand: ServiceIdentifier<any>;
|
||||
_serviceBrand!: ServiceIdentifier<any>;
|
||||
|
||||
private channel: IChannel;
|
||||
|
||||
|
||||
@@ -21,10 +21,10 @@ const DEFAULT_BACKGROUND_COLOR = '#1E1E1E';
|
||||
|
||||
export class IssueService implements IIssueService {
|
||||
_serviceBrand: any;
|
||||
_issueWindow: BrowserWindow | null;
|
||||
_issueParentWindow: BrowserWindow | null;
|
||||
_processExplorerWindow: BrowserWindow | null;
|
||||
_processExplorerParentWindow: BrowserWindow | null;
|
||||
_issueWindow: BrowserWindow | null = null;
|
||||
_issueParentWindow: BrowserWindow | null = null;
|
||||
_processExplorerWindow: BrowserWindow | null = null;
|
||||
_processExplorerParentWindow: BrowserWindow | null = null;
|
||||
|
||||
constructor(
|
||||
private machineId: string,
|
||||
|
||||
@@ -94,7 +94,7 @@ export class LaunchChannel implements IServerChannel {
|
||||
|
||||
export class LaunchChannelClient implements ILaunchService {
|
||||
|
||||
_serviceBrand: ServiceIdentifier<ILaunchService>;
|
||||
_serviceBrand!: ServiceIdentifier<ILaunchService>;
|
||||
|
||||
constructor(private channel: IChannel) { }
|
||||
|
||||
@@ -121,7 +121,7 @@ export class LaunchChannelClient implements ILaunchService {
|
||||
|
||||
export class LaunchService implements ILaunchService {
|
||||
|
||||
_serviceBrand: ServiceIdentifier<ILaunchService>;
|
||||
_serviceBrand!: ServiceIdentifier<ILaunchService>;
|
||||
|
||||
constructor(
|
||||
@ILogService private readonly logService: ILogService,
|
||||
|
||||
@@ -11,7 +11,7 @@ import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiatio
|
||||
|
||||
export class BrowserLifecycleService extends AbstractLifecycleService {
|
||||
|
||||
_serviceBrand: ServiceIdentifier<ILifecycleService>;
|
||||
_serviceBrand!: ServiceIdentifier<ILifecycleService>;
|
||||
|
||||
constructor(
|
||||
@ILogService readonly logService: ILogService
|
||||
@@ -56,4 +56,4 @@ export class BrowserLifecycleService extends AbstractLifecycleService {
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiatio
|
||||
|
||||
export abstract class AbstractLifecycleService extends Disposable implements ILifecycleService {
|
||||
|
||||
_serviceBrand: ServiceIdentifier<ILifecycleService>;
|
||||
_serviceBrand!: ServiceIdentifier<ILifecycleService>;
|
||||
|
||||
protected readonly _onBeforeShutdown = this._register(new Emitter<BeforeShutdownEvent>());
|
||||
readonly onBeforeShutdown: Event<BeforeShutdownEvent> = this._onBeforeShutdown.event;
|
||||
|
||||
@@ -18,7 +18,7 @@ export class LifecycleService extends AbstractLifecycleService {
|
||||
|
||||
private static readonly LAST_SHUTDOWN_REASON_KEY = 'lifecyle.lastShutdownReason';
|
||||
|
||||
_serviceBrand: ServiceIdentifier<ILifecycleService>;
|
||||
_serviceBrand!: ServiceIdentifier<ILifecycleService>;
|
||||
|
||||
private shutdownReason: ShutdownReason;
|
||||
|
||||
|
||||
@@ -131,7 +131,7 @@ export const enum LifecycleMainPhase {
|
||||
|
||||
export class LifecycleService extends Disposable implements ILifecycleService {
|
||||
|
||||
_serviceBrand: ServiceIdentifier<ILifecycleService>;
|
||||
_serviceBrand!: ServiceIdentifier<ILifecycleService>;
|
||||
|
||||
private static readonly QUIT_FROM_RESTART_MARKER = 'quit.from.restart'; // use a marker to find out if the session was restarted
|
||||
|
||||
|
||||
@@ -890,6 +890,7 @@ function workbenchTreeDataPreamble<T, TFilterData, TOptions extends IAbstractTre
|
||||
const horizontalScrolling = typeof options.horizontalScrolling !== 'undefined' ? options.horizontalScrolling : getHorizontalScrollingSetting(configurationService);
|
||||
const openOnSingleClick = useSingleClickToOpen(configurationService);
|
||||
const [workbenchListOptions, disposable] = toWorkbenchListOptions(options, configurationService, keybindingService);
|
||||
const additionalScrollHeight = options.additionalScrollHeight;
|
||||
|
||||
return {
|
||||
getAutomaticKeyboardNavigation,
|
||||
@@ -906,7 +907,8 @@ function workbenchTreeDataPreamble<T, TFilterData, TOptions extends IAbstractTre
|
||||
filterOnType: keyboardNavigation === 'filter',
|
||||
horizontalScrolling,
|
||||
openOnSingleClick,
|
||||
keyboardNavigationEventFilter: createKeyboardNavigationEventFilter(container, keybindingService)
|
||||
keyboardNavigationEventFilter: createKeyboardNavigationEventFilter(container, keybindingService),
|
||||
additionalScrollHeight
|
||||
} as TOptions
|
||||
};
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiatio
|
||||
|
||||
export class LocalizationsService implements ILocalizationsService {
|
||||
|
||||
_serviceBrand: ServiceIdentifier<any>;
|
||||
_serviceBrand!: ServiceIdentifier<any>;
|
||||
|
||||
private channel: IChannel;
|
||||
|
||||
|
||||
@@ -93,7 +93,7 @@ class LanguagePacksCache extends Disposable {
|
||||
private languagePacks: { [language: string]: ILanguagePack } = {};
|
||||
private languagePacksFilePath: string;
|
||||
private languagePacksFileLimiter: Queue<any>;
|
||||
private initializedCache: boolean;
|
||||
private initializedCache: boolean | undefined;
|
||||
|
||||
constructor(
|
||||
@IEnvironmentService environmentService: IEnvironmentService,
|
||||
@@ -184,4 +184,4 @@ class LanguagePacksCache extends Disposable {
|
||||
.then(() => result, error => this.logService.error(error));
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiatio
|
||||
|
||||
export class MenubarService implements IMenubarService {
|
||||
|
||||
_serviceBrand: ServiceIdentifier<any>;
|
||||
_serviceBrand!: ServiceIdentifier<any>;
|
||||
|
||||
private channel: IChannel;
|
||||
|
||||
|
||||
@@ -29,6 +29,26 @@ export interface INotificationProperties {
|
||||
* catch some attention.
|
||||
*/
|
||||
silent?: boolean;
|
||||
|
||||
/**
|
||||
* Adds an action to never show the notification again. The choice will be persisted
|
||||
* such as future requests will not cause the notification to show again.
|
||||
*/
|
||||
neverShowAgain?: INeverShowAgainOptions;
|
||||
}
|
||||
|
||||
export interface INeverShowAgainOptions {
|
||||
|
||||
/**
|
||||
* The id is used to persist the selection of not showing the notification again.
|
||||
*/
|
||||
id: string;
|
||||
|
||||
/**
|
||||
* By default the action will show up as primary action. Setting this to true will
|
||||
* make it a secondary action instead.
|
||||
*/
|
||||
isSecondary?: boolean;
|
||||
}
|
||||
|
||||
export interface INotification extends INotificationProperties {
|
||||
@@ -270,4 +290,4 @@ export class NoOpProgress implements INotificationProgress {
|
||||
done(): void { }
|
||||
total(value: number): void { }
|
||||
worked(value: number): void { }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,8 @@ import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiatio
|
||||
|
||||
export class ProductService implements IProductService {
|
||||
|
||||
_serviceBrand!: ServiceIdentifier<IProductService>;
|
||||
|
||||
private readonly productConfiguration: IProductConfiguration | null;
|
||||
|
||||
constructor() {
|
||||
@@ -15,9 +17,7 @@ export class ProductService implements IProductService {
|
||||
this.productConfiguration = element ? JSON.parse(element.getAttribute('data-settings')!) : null;
|
||||
}
|
||||
|
||||
_serviceBrand: ServiceIdentifier<IProductService>;
|
||||
|
||||
get version(): string { return '1.35.0'; }
|
||||
get version(): string { return this.productConfiguration && this.productConfiguration.version ? this.productConfiguration.version : '1.38.0-unknown'; }
|
||||
|
||||
get vscodeVersion(): string { return '1.35.0'; } // {{SQL CARBON EDIT}} add vscodeversion
|
||||
|
||||
@@ -25,7 +25,7 @@ export class ProductService implements IProductService {
|
||||
|
||||
get commit(): string | undefined { return this.productConfiguration ? this.productConfiguration.commit : undefined; }
|
||||
|
||||
get nameLong(): string { return ''; }
|
||||
get nameLong(): string { return this.productConfiguration ? this.productConfiguration.nameLong : 'Unknown'; }
|
||||
|
||||
get urlProtocol(): string { return ''; }
|
||||
|
||||
|
||||
@@ -3,17 +3,19 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { createDecorator, ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation';
|
||||
|
||||
export const IProductService = createDecorator<IProductService>('productService');
|
||||
|
||||
export interface IProductService {
|
||||
_serviceBrand: any;
|
||||
|
||||
_serviceBrand: ServiceIdentifier<any>;
|
||||
|
||||
readonly version: string;
|
||||
readonly vscodeVersion: string; // {{SQL CARBON EDIT}} add vscode version
|
||||
readonly recommendedExtensionsByScenario: { [area: string]: Array<string> }; // {{SQL CARBON EDIT}} add getter
|
||||
readonly commit?: string;
|
||||
readonly date?: string;
|
||||
|
||||
readonly nameLong: string;
|
||||
readonly urlProtocol: string;
|
||||
@@ -46,6 +48,7 @@ export interface IProductService {
|
||||
}
|
||||
|
||||
export interface IProductConfiguration {
|
||||
readonly version: string;
|
||||
nameShort: string;
|
||||
nameLong: string;
|
||||
readonly applicationName: string;
|
||||
|
||||
@@ -10,7 +10,7 @@ import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiatio
|
||||
|
||||
export class ProductService implements IProductService {
|
||||
|
||||
_serviceBrand: ServiceIdentifier<IProductService>;
|
||||
_serviceBrand!: ServiceIdentifier<IProductService>;
|
||||
|
||||
get version(): string { return pkg.version; }
|
||||
|
||||
|
||||
@@ -90,13 +90,13 @@ export interface IProgress<T> {
|
||||
export class Progress<T> implements IProgress<T> {
|
||||
|
||||
private _callback: (data: T) => void;
|
||||
private _value: T;
|
||||
private _value?: T;
|
||||
|
||||
constructor(callback: (data: T) => void) {
|
||||
this._callback = callback;
|
||||
}
|
||||
|
||||
get value() {
|
||||
get value(): T | undefined {
|
||||
return this._value;
|
||||
}
|
||||
|
||||
@@ -120,7 +120,7 @@ export interface IOperation {
|
||||
export class LongRunningOperation extends Disposable {
|
||||
private currentOperationId = 0;
|
||||
private readonly currentOperationDisposables = this._register(new DisposableStore());
|
||||
private currentProgressRunner: IProgressRunner;
|
||||
private currentProgressRunner: IProgressRunner | undefined;
|
||||
private currentProgressTimeout: any;
|
||||
|
||||
constructor(
|
||||
|
||||
@@ -33,7 +33,7 @@ export class RemoteExtensionsFileSystemProvider extends Disposable implements IF
|
||||
private readonly _onDidChangeCapabilities = this._register(new Emitter<void>());
|
||||
readonly onDidChangeCapabilities: Event<void> = this._onDidChangeCapabilities.event;
|
||||
|
||||
private _capabilities: FileSystemProviderCapabilities;
|
||||
private _capabilities!: FileSystemProviderCapabilities;
|
||||
get capabilities(): FileSystemProviderCapabilities { return this._capabilities; }
|
||||
|
||||
constructor(private readonly channel: IChannel, environment: Promise<IRemoteAgentEnvironment | null>) {
|
||||
|
||||
@@ -38,7 +38,7 @@ export class RequestService extends Disposable implements IRequestService {
|
||||
_serviceBrand: any;
|
||||
|
||||
private proxyUrl?: string;
|
||||
private strictSSL: boolean;
|
||||
private strictSSL: boolean | undefined;
|
||||
private authorization?: string;
|
||||
|
||||
constructor(
|
||||
@@ -143,4 +143,4 @@ export class RequestService extends Disposable implements IRequestService {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiatio
|
||||
|
||||
export class SignService implements ISignService {
|
||||
|
||||
_serviceBrand: ServiceIdentifier<ISignService>;
|
||||
_serviceBrand!: ServiceIdentifier<ISignService>;
|
||||
|
||||
private readonly _tkn: string | null;
|
||||
|
||||
|
||||
@@ -4,14 +4,10 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { ISignService } from 'vs/platform/sign/common/sign';
|
||||
import { memoize } from 'vs/base/common/decorators';
|
||||
|
||||
export class SignService implements ISignService {
|
||||
_serviceBrand: any;
|
||||
|
||||
// Cache the 'vsda' import, because when the same missing module is imported multiple times,
|
||||
// the ones after the first will not throw an error. And this will break the contract of the sign method.
|
||||
@memoize
|
||||
private vsda(): Promise<typeof import('vsda')> {
|
||||
return import('vsda');
|
||||
}
|
||||
@@ -29,4 +25,4 @@ export class SignService implements ISignService {
|
||||
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ import { runWhenIdle } from 'vs/base/common/async';
|
||||
|
||||
export class BrowserStorageService extends Disposable implements IStorageService {
|
||||
|
||||
_serviceBrand: ServiceIdentifier<any>;
|
||||
_serviceBrand!: ServiceIdentifier<any>;
|
||||
|
||||
private readonly _onDidChangeStorage: Emitter<IWorkspaceStorageChangeEvent> = this._register(new Emitter<IWorkspaceStorageChangeEvent>());
|
||||
readonly onDidChangeStorage: Event<IWorkspaceStorageChangeEvent> = this._onDidChangeStorage.event;
|
||||
@@ -28,11 +28,18 @@ export class BrowserStorageService extends Disposable implements IStorageService
|
||||
private globalStorage: IStorage;
|
||||
private workspaceStorage: IStorage;
|
||||
|
||||
private globalStorageDatabase: FileStorageDatabase;
|
||||
private workspaceStorageDatabase: FileStorageDatabase;
|
||||
|
||||
private globalStorageFile: URI;
|
||||
private workspaceStorageFile: URI;
|
||||
|
||||
private initializePromise: Promise<void>;
|
||||
|
||||
get hasPendingUpdate(): boolean {
|
||||
return this.globalStorageDatabase.hasPendingUpdate || this.workspaceStorageDatabase.hasPendingUpdate;
|
||||
}
|
||||
|
||||
constructor(
|
||||
@IEnvironmentService private readonly environmentService: IEnvironmentService,
|
||||
@IFileService private readonly fileService: IFileService
|
||||
@@ -76,12 +83,14 @@ export class BrowserStorageService extends Disposable implements IStorageService
|
||||
|
||||
// Workspace Storage
|
||||
this.workspaceStorageFile = joinPath(stateRoot, `${payload.id}.json`);
|
||||
this.workspaceStorage = new Storage(this._register(new FileStorageDatabase(this.workspaceStorageFile, this.fileService)));
|
||||
this.workspaceStorageDatabase = this._register(new FileStorageDatabase(this.workspaceStorageFile, this.fileService));
|
||||
this.workspaceStorage = new Storage(this.workspaceStorageDatabase);
|
||||
this._register(this.workspaceStorage.onDidChangeStorage(key => this._onDidChangeStorage.fire({ key, scope: StorageScope.WORKSPACE })));
|
||||
|
||||
// Global Storage
|
||||
this.globalStorageFile = joinPath(stateRoot, 'global.json');
|
||||
this.globalStorage = new Storage(this._register(new FileStorageDatabase(this.globalStorageFile, this.fileService)));
|
||||
this.globalStorageDatabase = this._register(new FileStorageDatabase(this.globalStorageFile, this.fileService));
|
||||
this.globalStorage = new Storage(this.globalStorageDatabase);
|
||||
this._register(this.globalStorage.onDidChangeStorage(key => this._onDidChangeStorage.fire({ key, scope: StorageScope.GLOBAL })));
|
||||
|
||||
// Init both
|
||||
@@ -134,5 +143,9 @@ export class BrowserStorageService extends Disposable implements IStorageService
|
||||
|
||||
// Signal as event so that clients can still store data
|
||||
this._onWillSaveState.fire({ reason: WillSaveStateReason.SHUTDOWN });
|
||||
|
||||
// Close DBs
|
||||
this.globalStorage.close();
|
||||
this.workspaceStorage.close();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -220,6 +220,11 @@ export class FileStorageDatabase extends Disposable implements IStorageDatabase
|
||||
|
||||
private pendingUpdate: Promise<void> = Promise.resolve();
|
||||
|
||||
private _hasPendingUpdate = false;
|
||||
get hasPendingUpdate(): boolean {
|
||||
return this._hasPendingUpdate;
|
||||
}
|
||||
|
||||
constructor(
|
||||
private readonly file: URI,
|
||||
private readonly fileService: IFileService
|
||||
@@ -260,7 +265,13 @@ export class FileStorageDatabase extends Disposable implements IStorageDatabase
|
||||
|
||||
await this.pendingUpdate;
|
||||
|
||||
this.pendingUpdate = this.fileService.writeFile(this.file, VSBuffer.fromString(JSON.stringify(mapToSerializable(items)))).then();
|
||||
this._hasPendingUpdate = true;
|
||||
|
||||
this.pendingUpdate = this.fileService.writeFile(this.file, VSBuffer.fromString(JSON.stringify(mapToSerializable(items))))
|
||||
.then(() => undefined)
|
||||
.finally(() => {
|
||||
this._hasPendingUpdate = false;
|
||||
});
|
||||
|
||||
return this.pendingUpdate;
|
||||
}
|
||||
@@ -312,4 +323,4 @@ export async function logStorage(global: Map<string, string>, workspace: Map<str
|
||||
console.groupEnd();
|
||||
|
||||
console.log(workspaceItemsParsed);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ export interface IStorageChangeEvent {
|
||||
|
||||
export class StorageMainService extends Disposable implements IStorageMainService {
|
||||
|
||||
_serviceBrand: ServiceIdentifier<any>;
|
||||
_serviceBrand!: ServiceIdentifier<any>;
|
||||
|
||||
private static STORAGE_NAME = 'state.vscdb';
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiatio
|
||||
|
||||
export class StorageService extends Disposable implements IStorageService {
|
||||
|
||||
_serviceBrand: ServiceIdentifier<any>;
|
||||
_serviceBrand!: ServiceIdentifier<any>;
|
||||
|
||||
private static WORKSPACE_STORAGE_NAME = 'state.vscdb';
|
||||
private static WORKSPACE_META_NAME = 'workspace.json';
|
||||
@@ -81,7 +81,7 @@ export class StorageService extends Disposable implements IStorageService {
|
||||
|
||||
const useInMemoryStorage = !!this.environmentService.extensionTestsLocationURI; // no storage during extension tests!
|
||||
|
||||
// Create workspace storage and initalize
|
||||
// Create workspace storage and initialize
|
||||
mark('willInitWorkspaceStorage');
|
||||
try {
|
||||
await this.createWorkspaceStorage(useInMemoryStorage ? SQLiteStorageDatabase.IN_MEMORY_PATH : join(result.path, StorageService.WORKSPACE_STORAGE_NAME), result.wasCreated ? StorageHint.STORAGE_DOES_NOT_EXIST : undefined).init();
|
||||
|
||||
@@ -224,6 +224,10 @@ export const selectListBackground = registerColor('dropdown.listBackground', { d
|
||||
export const selectForeground = registerColor('dropdown.foreground', { dark: '#F0F0F0', light: null, hc: Color.white }, nls.localize('dropdownForeground', "Dropdown foreground."));
|
||||
export const selectBorder = registerColor('dropdown.border', { dark: selectBackground, light: '#CECECE', hc: contrastBorder }, nls.localize('dropdownBorder', "Dropdown border."));
|
||||
|
||||
export const simpleCheckboxBackground = registerColor('checkbox.background', { dark: selectBackground, light: selectBackground, hc: selectBackground }, nls.localize('checkbox.background', "Background color of checkbox widget."));
|
||||
export const simpleCheckboxForeground = registerColor('checkbox.foreground', { dark: selectForeground, light: selectForeground, hc: selectForeground }, nls.localize('checkbox.foreground', "Foreground color of checkbox widget."));
|
||||
export const simpleCheckboxBorder = registerColor('checkbox.border', { dark: selectBorder, light: selectBorder, hc: selectBorder }, nls.localize('checkbox.border', "Border color of checkbox widget."));
|
||||
|
||||
export const listFocusBackground = registerColor('list.focusBackground', { dark: '#062F4A', light: '#D6EBFF', hc: null }, nls.localize('listFocusBackground', "List/Tree background color for the focused item when the list/tree is active. An active list/tree has keyboard focus, an inactive does not."));
|
||||
export const listFocusForeground = registerColor('list.focusForeground', { dark: null, light: null, hc: null }, nls.localize('listFocusForeground', "List/Tree foreground color for the focused item when the list/tree is active. An active list/tree has keyboard focus, an inactive does not."));
|
||||
export const listActiveSelectionBackground = registerColor('list.activeSelectionBackground', { dark: '#094771', light: '#0074E8', hc: null }, nls.localize('listActiveSelectionBackground', "List/Tree background color for the selected item when the list/tree is active. An active list/tree has keyboard focus, an inactive does not."));
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { ITheme, IThemeService } from 'vs/platform/theme/common/themeService';
|
||||
import { focusBorder, inputBackground, inputForeground, ColorIdentifier, selectForeground, selectBackground, selectListBackground, selectBorder, inputBorder, foreground, editorBackground, contrastBorder, inputActiveOptionBorder, inputActiveOptionBackground, listFocusBackground, listFocusForeground, listActiveSelectionBackground, listActiveSelectionForeground, listInactiveSelectionForeground, listInactiveSelectionBackground, listInactiveFocusBackground, listHoverBackground, listHoverForeground, listDropBackground, pickerGroupBorder, pickerGroupForeground, widgetShadow, inputValidationInfoBorder, inputValidationInfoBackground, inputValidationWarningBorder, inputValidationWarningBackground, inputValidationErrorBorder, inputValidationErrorBackground, activeContrastBorder, buttonForeground, buttonBackground, buttonHoverBackground, ColorFunction, badgeBackground, badgeForeground, progressBarBackground, breadcrumbsForeground, breadcrumbsFocusForeground, breadcrumbsActiveSelectionForeground, breadcrumbsBackground, editorWidgetBorder, inputValidationInfoForeground, inputValidationWarningForeground, inputValidationErrorForeground, menuForeground, menuBackground, menuSelectionForeground, menuSelectionBackground, menuSelectionBorder, menuBorder, menuSeparatorBackground, darken, listFilterWidgetOutline, listFilterWidgetNoMatchesOutline, listFilterWidgetBackground, editorWidgetBackground, treeIndentGuidesStroke, editorWidgetForeground } from 'vs/platform/theme/common/colorRegistry';
|
||||
import { focusBorder, inputBackground, inputForeground, ColorIdentifier, selectForeground, selectBackground, selectListBackground, selectBorder, inputBorder, foreground, editorBackground, contrastBorder, inputActiveOptionBorder, inputActiveOptionBackground, listFocusBackground, listFocusForeground, listActiveSelectionBackground, listActiveSelectionForeground, listInactiveSelectionForeground, listInactiveSelectionBackground, listInactiveFocusBackground, listHoverBackground, listHoverForeground, listDropBackground, pickerGroupBorder, pickerGroupForeground, widgetShadow, inputValidationInfoBorder, inputValidationInfoBackground, inputValidationWarningBorder, inputValidationWarningBackground, inputValidationErrorBorder, inputValidationErrorBackground, activeContrastBorder, buttonForeground, buttonBackground, buttonHoverBackground, ColorFunction, badgeBackground, badgeForeground, progressBarBackground, breadcrumbsForeground, breadcrumbsFocusForeground, breadcrumbsActiveSelectionForeground, breadcrumbsBackground, editorWidgetBorder, inputValidationInfoForeground, inputValidationWarningForeground, inputValidationErrorForeground, menuForeground, menuBackground, menuSelectionForeground, menuSelectionBackground, menuSelectionBorder, menuBorder, menuSeparatorBackground, darken, listFilterWidgetOutline, listFilterWidgetNoMatchesOutline, listFilterWidgetBackground, editorWidgetBackground, treeIndentGuidesStroke, editorWidgetForeground, simpleCheckboxBackground, simpleCheckboxBorder, simpleCheckboxForeground } from 'vs/platform/theme/common/colorRegistry';
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { Color } from 'vs/base/common/color';
|
||||
import { mixin } from 'vs/base/common/objects';
|
||||
@@ -341,6 +341,9 @@ export interface IDialogStyleOverrides extends IButtonStyleOverrides {
|
||||
dialogBackground?: ColorIdentifier;
|
||||
dialogShadow?: ColorIdentifier;
|
||||
dialogBorder?: ColorIdentifier;
|
||||
checkboxBorder?: ColorIdentifier;
|
||||
checkboxBackground?: ColorIdentifier;
|
||||
checkboxForeground?: ColorIdentifier;
|
||||
}
|
||||
|
||||
export const defaultDialogStyles = <IDialogStyleOverrides>{
|
||||
@@ -351,7 +354,10 @@ export const defaultDialogStyles = <IDialogStyleOverrides>{
|
||||
buttonForeground: buttonForeground,
|
||||
buttonBackground: buttonBackground,
|
||||
buttonHoverBackground: buttonHoverBackground,
|
||||
buttonBorder: contrastBorder
|
||||
buttonBorder: contrastBorder,
|
||||
checkboxBorder: simpleCheckboxBorder,
|
||||
checkboxBackground: simpleCheckboxBackground,
|
||||
checkboxForeground: simpleCheckboxForeground
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiatio
|
||||
|
||||
export class UpdateService implements IUpdateService {
|
||||
|
||||
_serviceBrand: ServiceIdentifier<any>;
|
||||
_serviceBrand!: ServiceIdentifier<any>;
|
||||
|
||||
private _onStateChange = new Emitter<State>();
|
||||
readonly onStateChange: Event<State> = this._onStateChange.event;
|
||||
|
||||
@@ -81,8 +81,15 @@ export abstract class AbstractUpdateService implements IUpdateService {
|
||||
return;
|
||||
}
|
||||
|
||||
// Start checking for updates after 30 seconds
|
||||
this.scheduleCheckForUpdates(30 * 1000).then(undefined, err => this.logService.error(err));
|
||||
if (updateMode === 'start') {
|
||||
this.logService.info('update#ctor - startup checks only; automatic updates are disabled by user preference');
|
||||
|
||||
// Check for updates only once after 30 seconds
|
||||
setTimeout(() => this.checkForUpdates(null), 30 * 1000);
|
||||
} else {
|
||||
// Start checking for updates after 30 seconds
|
||||
this.scheduleCheckForUpdates(30 * 1000).then(undefined, err => this.logService.error(err));
|
||||
}
|
||||
}
|
||||
|
||||
private getProductQuality(updateMode: string): string | undefined {
|
||||
|
||||
@@ -17,7 +17,7 @@ configurationRegistry.registerConfiguration({
|
||||
properties: {
|
||||
'update.mode': {
|
||||
type: 'string',
|
||||
enum: ['none', 'manual', 'default'],
|
||||
enum: ['none', 'manual', 'start', 'default'],
|
||||
default: 'default',
|
||||
scope: ConfigurationScope.APPLICATION,
|
||||
description: localize('updateMode', "Configure whether you receive automatic updates. Requires a restart after change. The updates are fetched from a Microsoft online service."),
|
||||
@@ -25,6 +25,7 @@ configurationRegistry.registerConfiguration({
|
||||
enumDescriptions: [
|
||||
localize('none', "Disable updates."),
|
||||
localize('manual', "Disable automatic background update checks. Updates will be available if you manually check for updates."),
|
||||
localize('start', "Check for updates only on startup. Disable automatic background update checks."),
|
||||
localize('default', "Enable automatic update checks. Code will check for updates automatically and periodically.")
|
||||
]
|
||||
},
|
||||
|
||||
@@ -12,7 +12,7 @@ import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiatio
|
||||
|
||||
export class URLService implements IURLService {
|
||||
|
||||
_serviceBrand: ServiceIdentifier<any>;
|
||||
_serviceBrand!: ServiceIdentifier<any>;
|
||||
|
||||
private handlers = new Set<IURLHandler>();
|
||||
|
||||
|
||||
@@ -303,7 +303,7 @@ export function getTitleBarStyle(configurationService: IConfigurationService, en
|
||||
return 'native'; // native tabs on sierra do not work with custom title style
|
||||
}
|
||||
|
||||
const useSimpleFullScreen = false; //isMacintosh && configuration.nativeFullScreen === false;
|
||||
const useSimpleFullScreen = isMacintosh && configuration.nativeFullScreen === false;
|
||||
if (useSimpleFullScreen) {
|
||||
return 'native'; // simple fullscreen does not work well with custom title style (https://github.com/Microsoft/vscode/issues/63291)
|
||||
}
|
||||
@@ -426,6 +426,7 @@ export interface IWindowConfiguration extends ParsedArgs {
|
||||
folderUri?: ISingleFolderWorkspaceIdentifier;
|
||||
|
||||
remoteAuthority?: string;
|
||||
connectionToken?: string;
|
||||
|
||||
zoomLevel?: number;
|
||||
fullscreen?: boolean;
|
||||
@@ -444,7 +445,6 @@ export interface IWindowConfiguration extends ParsedArgs {
|
||||
filesToDiff?: IPath[];
|
||||
filesToWait?: IPathsToWaitFor;
|
||||
termProgram?: string;
|
||||
connectionToken?: string;
|
||||
}
|
||||
|
||||
export interface IRunActionInWindowRequest {
|
||||
|
||||
@@ -27,7 +27,7 @@ import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiatio
|
||||
|
||||
export class WindowsService extends Disposable implements IWindowsService, IURLHandler {
|
||||
|
||||
_serviceBrand: ServiceIdentifier<any>;
|
||||
_serviceBrand!: ServiceIdentifier<any>;
|
||||
|
||||
private readonly disposables = this._register(new DisposableStore());
|
||||
|
||||
|
||||
Reference in New Issue
Block a user