Merge from vscode 52dcb723a39ae75bee1bd56b3312d7fcdc87aeed (#6719)

This commit is contained in:
Anthony Dresser
2019-08-12 21:31:51 -07:00
committed by GitHub
parent 00250839fc
commit 7eba8c4c03
616 changed files with 9472 additions and 7087 deletions

View File

@@ -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;

View File

@@ -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,

View File

@@ -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);

View File

@@ -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 {

View File

@@ -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);
}
}
}

View File

@@ -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 {
}
});
}
}
}

View File

@@ -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;
}
}

View File

@@ -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');
}
}

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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; }

View File

@@ -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']);
});
});

View File

@@ -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;
}

View File

@@ -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;
}
}
}

View File

@@ -18,7 +18,7 @@ export class OutOfProcessWin32FolderWatcher {
private ignored: glob.ParsedPattern[];
private handle: cp.ChildProcess;
private handle: cp.ChildProcess | undefined;
private restartCounter: number;
constructor(

View File

@@ -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);
});
});

View File

@@ -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));
}
}

View File

@@ -21,7 +21,7 @@ export interface IMainProcessService {
export class MainProcessService extends Disposable implements IMainProcessService {
_serviceBrand: ServiceIdentifier<any>;
_serviceBrand!: ServiceIdentifier<any>;
private mainProcessConnection: Client;

View File

@@ -23,7 +23,7 @@ export interface ISharedProcessService {
export class SharedProcessService implements ISharedProcessService {
_serviceBrand: ServiceIdentifier<any>;
_serviceBrand!: ServiceIdentifier<any>;
private withSharedProcessConnection: Promise<Client<string>>;

View File

@@ -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;

View File

@@ -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,

View File

@@ -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,

View File

@@ -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;
}
}
}

View File

@@ -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;

View File

@@ -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;

View File

@@ -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

View File

@@ -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
};
}

View File

@@ -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;

View File

@@ -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));
});
}
}
}

View File

@@ -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;

View File

@@ -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 { }
}
}

View File

@@ -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 ''; }

View File

@@ -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;

View File

@@ -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; }

View File

@@ -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(

View File

@@ -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>) {

View File

@@ -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 {
}
}
}

View File

@@ -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;

View File

@@ -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;
}
}
}

View File

@@ -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();
}
}

View File

@@ -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);
}
}

View File

@@ -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';

View File

@@ -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();

View File

@@ -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."));

View File

@@ -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
};

View File

@@ -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;

View File

@@ -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 {

View File

@@ -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.")
]
},

View File

@@ -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>();

View File

@@ -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 {

View File

@@ -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());