This commit is contained in:
Anthony Dresser 2019-04-26 17:24:54 -07:00 коммит произвёл GitHub
Родитель 8cda364210
Коммит 9b90400abd
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
17 изменённых файлов: 117 добавлений и 42 удалений

Просмотреть файл

@ -400,6 +400,7 @@
"statusBar.noFolderBackground": "#10192c",
"statusBar.debuggingBackground": "#10192c",
// "statusBar.foreground": "",
"statusBarItem.hostBackground": "#0063a5",
"statusBarItem.prominentBackground": "#0063a5",
"statusBarItem.prominentHoverBackground": "#0063a5dd",
// "statusBarItem.activeBackground": "",

Просмотреть файл

@ -4,7 +4,8 @@
"include": "./hc_black_defaults.json",
"colors": {
"selection.background": "#008000",
"editor.selectionBackground": "#FFFFFF"
"editor.selectionBackground": "#FFFFFF",
"statusBarItem.hostBackground": "#00000000"
},
"tokenColors": [
{

Просмотреть файл

@ -6,6 +6,7 @@
"editor.foreground": "#FFFFFF",
"editorIndentGuide.background": "#FFFFFF",
"editorIndentGuide.activeBackground": "#FFFFFF",
"statusBarItem.hostBackground": "#00000000",
"sideBarTitle.foreground": "#FFFFFF"
},
"settings": [

Просмотреть файл

@ -27,6 +27,7 @@
"statusBar.background": "#423523",
"statusBar.debuggingBackground": "#423523",
"statusBar.noFolderBackground": "#423523",
"statusBarItem.hostBackground": "#6e583b",
"activityBar.background": "#221a0f",
"activityBar.foreground": "#d3af86",
"sideBar.background": "#362712",

Просмотреть файл

@ -31,6 +31,7 @@
"statusBar.debuggingBackground": "#505050",
"statusBar.noFolderBackground": "#505050",
"titleBar.activeBackground": "#505050",
"statusBarItem.hostBackground": "#3655b5",
"activityBar.background": "#353535",
"activityBar.foreground": "#ffffff",
"activityBarBadge.background": "#3655b5",

Просмотреть файл

@ -50,6 +50,7 @@
"statusBar.background": "#414339",
"statusBar.noFolderBackground": "#414339",
"statusBar.debuggingBackground": "#75715E",
"statusBarItem.hostBackground": "#AC6218",
"activityBar.background": "#272822",
"activityBar.foreground": "#f8f8f2",
"activityBar.dropBackground": "#414339",

Просмотреть файл

@ -516,6 +516,7 @@
"statusBar.background": "#705697",
"statusBar.noFolderBackground": "#705697",
"statusBar.debuggingBackground": "#705697",
"statusBarItem.hostBackground": "#4e3c69",
"activityBar.background": "#EDEDF5",
"activityBar.foreground": "#705697",
"activityBarBadge.background": "#705697",

Просмотреть файл

@ -9,6 +9,7 @@
"sideBar.background": "#330000",
"statusBar.background": "#700000",
"statusBar.noFolderBackground": "#700000",
"statusBarItem.hostBackground": "#c33",
"editorGroupHeader.tabsBackground": "#330000",
"titleBar.activeBackground": "#770000",
"titleBar.inactiveBackground": "#772222",

Просмотреть файл

@ -448,6 +448,7 @@
"statusBar.background": "#00212B",
"statusBar.debuggingBackground": "#00212B",
"statusBar.noFolderBackground": "#00212B",
"statusBarItem.hostBackground": "#2AA19899",
"statusBarItem.prominentBackground": "#003847",
"statusBarItem.prominentHoverBackground": "#003847",
// "statusBarItem.activeBackground": "",

Просмотреть файл

@ -447,6 +447,7 @@
"statusBar.debuggingBackground": "#EEE8D5",
"statusBar.noFolderBackground": "#EEE8D5",
// "statusBar.foreground": "",
"statusBarItem.hostBackground": "#AC9D57",
"statusBarItem.prominentBackground": "#DDD6C1",
"statusBarItem.prominentHoverBackground": "#DDD6C199",
// "statusBarItem.activeBackground": "",

Просмотреть файл

@ -30,6 +30,7 @@
"debugToolBar.background": "#001c40",
"titleBar.activeBackground": "#001126",
"statusBar.background": "#001126",
"statusBarItem.hostBackground": "#0e639c",
"statusBar.noFolderBackground": "#001126",
"statusBar.debuggingBackground": "#001126",
"activityBar.background": "#001733",

Просмотреть файл

@ -141,13 +141,13 @@ export const enum ProtocolConstants {
*/
AcknowledgeTimeoutTime = 10000, // 10 seconds
/**
* Send at least a message every 30s for keep alive reasons.
* Send at least a message every 5s for keep alive reasons.
*/
KeepAliveTime = 30000, // 30 seconds
KeepAliveTime = 5000, // 5 seconds
/**
* If there is no message received for 60 seconds, consider the connection closed...
* If there is no message received for 10 seconds, consider the connection closed...
*/
KeepAliveTimeoutTime = 60000, // 60 seconds
KeepAliveTimeoutTime = 10000, // 10 seconds
/**
* If there is no reconnection within this time-frame, consider the connection permanently closed...
*/

Просмотреть файл

@ -1770,7 +1770,9 @@ export class InstallWorkspaceRecommendedExtensionsAction extends Action {
@INotificationService private readonly notificationService: INotificationService,
@IInstantiationService private readonly instantiationService: IInstantiationService,
@IOpenerService private readonly openerService: IOpenerService,
@IExtensionsWorkbenchService private readonly extensionWorkbenchService: IExtensionsWorkbenchService
@IExtensionsWorkbenchService private readonly extensionWorkbenchService: IExtensionsWorkbenchService,
@IConfigurationService private readonly configurationService: IConfigurationService,
@IExtensionManagementServerService private readonly extensionManagementServerService: IExtensionManagementServerService
) {
super(id, label, 'extension-action');
this.recommendations = recommendations;
@ -1787,17 +1789,30 @@ export class InstallWorkspaceRecommendedExtensionsAction extends Action {
let installPromises: Promise<any>[] = [];
let model = new PagedModel(pager);
for (let i = 0; i < pager.total; i++) {
installPromises.push(model.resolve(i, CancellationToken.None).then(e => {
return this.extensionWorkbenchService.install(e).then(undefined, err => {
console.error(err);
return promptDownloadManually(e.gallery, localize('failedToInstall', "Failed to install \'{0}\'.", e.identifier.id), err, this.instantiationService, this.notificationService, this.openerService);
});
}));
installPromises.push(model.resolve(i, CancellationToken.None).then(e => this.installExtension(e)));
}
return Promise.all(installPromises);
});
});
}
private async installExtension(extension: IExtension): Promise<void> {
try {
if (extension.local && extension.gallery) {
if (isUIExtension(extension.local.manifest, this.configurationService)) {
await this.extensionManagementServerService.localExtensionManagementServer.extensionManagementService.installFromGallery(extension.gallery);
return;
} else if (this.extensionManagementServerService.remoteExtensionManagementServer) {
await this.extensionManagementServerService.remoteExtensionManagementServer.extensionManagementService.installFromGallery(extension.gallery);
return;
}
}
await this.extensionWorkbenchService.install(extension);
} catch (err) {
console.error(err);
return promptDownloadManually(extension.gallery, localize('failedToInstall', "Failed to install \'{0}\'.", extension.identifier.id), err, this.instantiationService, this.notificationService, this.openerService);
}
}
}
export class InstallRecommendedExtensionAction extends Action {

Просмотреть файл

@ -274,22 +274,26 @@ export class RemoteFileDialog {
});
this.filePickBox.onDidChangeValue(async value => {
// onDidChangeValue can also be triggered by the auto complete, so if it looks like the auto complete, don't do anything
if (this.isChangeFromUser()) {
// If the user has just entered more bad path, don't change anything
if (!equalsIgnoreCase(value, this.constructFullUserPath()) && !this.isBadSubpath(value)) {
this.filePickBox.validationMessage = undefined;
const valueUri = this.remoteUriFrom(this.trimTrailingSlash(this.filePickBox.value));
let updated: UpdateResult = UpdateResult.NotUpdated;
if (!resources.isEqual(this.remoteUriFrom(this.trimTrailingSlash(this.pathFromUri(this.currentFolder))), valueUri, true)) {
updated = await this.tryUpdateItems(value, this.remoteUriFrom(this.filePickBox.value));
try {
// onDidChangeValue can also be triggered by the auto complete, so if it looks like the auto complete, don't do anything
if (this.isChangeFromUser()) {
// If the user has just entered more bad path, don't change anything
if (!equalsIgnoreCase(value, this.constructFullUserPath()) && !this.isBadSubpath(value)) {
this.filePickBox.validationMessage = undefined;
const valueUri = this.remoteUriFrom(this.trimTrailingSlash(this.filePickBox.value));
let updated: UpdateResult = UpdateResult.NotUpdated;
if (!resources.isEqual(this.remoteUriFrom(this.trimTrailingSlash(this.pathFromUri(this.currentFolder))), valueUri, true)) {
updated = await this.tryUpdateItems(value, this.remoteUriFrom(this.filePickBox.value));
}
if (updated === UpdateResult.NotUpdated) {
this.setActiveItems(value);
}
} else {
this.filePickBox.activeItems = [];
}
if (updated === UpdateResult.NotUpdated) {
this.setActiveItems(value);
}
} else {
this.filePickBox.activeItems = [];
}
} catch {
// Since any text can be entered in the input box, there is potential for error causing input. If this happens, do nothing.
}
});
this.filePickBox.onDidHide(() => {
@ -331,12 +335,13 @@ export class RemoteFileDialog {
this.filePickBox.busy = true;
let resolveValue: URI | undefined;
let navigateValue: URI | undefined;
const trimmedPickBoxValue = ((this.filePickBox.value.length > 1) && this.endsWithSlash(this.filePickBox.value)) ? this.filePickBox.value.substr(0, this.filePickBox.value.length - 1) : this.filePickBox.value;
const inputUri = this.remoteUriFrom(trimmedPickBoxValue);
const inputUriDirname = resources.dirname(inputUri);
let inputUri: URI | undefined;
let inputUriDirname: URI | undefined;
let stat: IFileStat | undefined;
let statDirname: IFileStat | undefined;
try {
inputUri = resources.removeTrailingPathSeparator(this.remoteUriFrom(this.filePickBox.value));
inputUriDirname = resources.dirname(inputUri);
statDirname = await this.fileService.resolve(inputUriDirname);
stat = await this.fileService.resolve(inputUri);
} catch (e) {
@ -363,17 +368,18 @@ export class RemoteFileDialog {
}
}
if (resolveValue) {
resolveValue = this.addPostfix(resolveValue);
if (navigateValue) {
// Try to navigate into the folder.
await this.updateItems(navigateValue, true, this.trailing);
} else {
if (resolveValue) {
resolveValue = this.addPostfix(resolveValue);
}
if (await this.validate(resolveValue)) {
this.filePickBox.busy = false;
return resolveValue;
}
} else if (navigateValue) {
// Try to navigate into the folder.
await this.updateItems(navigateValue, true, this.trailing);
} else {
// validation error. Path does not exist.
}
this.filePickBox.busy = false;
return undefined;
@ -575,7 +581,12 @@ export class RemoteFileDialog {
});
}
private async validate(uri: URI): Promise<boolean> {
private async validate(uri: URI | undefined): Promise<boolean> {
if (uri === undefined) {
this.filePickBox.validationMessage = nls.localize('remoteFileDialog.invalidPath', 'Please enter a valid path.');
return Promise.resolve(false);
}
let stat: IFileStat | undefined;
let statDirname: IFileStat | undefined;
try {

Просмотреть файл

@ -9,6 +9,7 @@ import { realpathSync } from 'vs/base/node/extpath';
import { IExtensionHostProfile, IExtensionService, ProfileSegmentId, ProfileSession } from 'vs/workbench/services/extensions/common/extensions';
import { IExtensionDescription } from 'vs/platform/extensions/common/extensions';
import { withNullAsUndefined } from 'vs/base/common/types';
import { Schemas } from 'vs/base/common/network';
export class ExtensionHostProfiler {
@ -30,7 +31,9 @@ export class ExtensionHostProfiler {
private distill(profile: Profile, extensions: IExtensionDescription[]): IExtensionHostProfile {
let searchTree = TernarySearchTree.forPaths<IExtensionDescription>();
for (let extension of extensions) {
searchTree.set(realpathSync(extension.extensionLocation.fsPath), extension);
if (extension.extensionLocation.scheme === Schemas.file) {
searchTree.set(realpathSync(extension.extensionLocation.fsPath), extension);
}
}
let nodes = profile.nodes;

Просмотреть файл

@ -338,8 +338,9 @@ export class FileService extends Disposable implements IFileService {
// but to the same length. This is a compromise we take to avoid having to produce checksums of
// the file content for comparison which would be much slower to compute.
if (
options && typeof options.mtime === 'number' && typeof options.etag === 'string' &&
options.etag !== ETAG_DISABLED && options.mtime < stat.mtime && options.etag !== etag({ mtime: options.mtime /* not using stat.mtime for a reason, see above */, size: stat.size })
options && typeof options.mtime === 'number' && typeof options.etag === 'string' && options.etag !== ETAG_DISABLED &&
typeof stat.mtime === 'number' && typeof stat.size === 'number' &&
options.mtime < stat.mtime && options.etag !== etag({ mtime: options.mtime /* not using stat.mtime for a reason, see above */, size: stat.size })
) {
throw new FileOperationError(localize('fileModifiedError', "File Modified Since"), FileOperationResult.FILE_MODIFIED_SINCE, options);
}
@ -496,7 +497,7 @@ export class FileService extends Disposable implements IFileService {
}
// Return early if file not modified since (unless disabled)
if (options && options.etag !== ETAG_DISABLED && options.etag === stat.etag) {
if (options && typeof options.etag === 'string' && options.etag !== ETAG_DISABLED && options.etag === stat.etag) {
throw new FileOperationError(localize('fileNotModifiedError', "File not modified since"), FileOperationResult.FILE_NOT_MODIFIED_SINCE, options);
}

Просмотреть файл

@ -15,7 +15,7 @@ import { getPathFromAmdModule } from 'vs/base/common/amd';
import { copy, rimraf, symlink, RimRafMode, rimrafSync } from 'vs/base/node/pfs';
import { URI } from 'vs/base/common/uri';
import { existsSync, statSync, readdirSync, readFileSync, writeFileSync, renameSync, unlinkSync, mkdirSync } from 'fs';
import { FileOperation, FileOperationEvent, IFileStat, FileOperationResult, FileSystemProviderCapabilities, FileChangeType, IFileChange, FileChangesEvent, FileOperationError, etag } from 'vs/platform/files/common/files';
import { FileOperation, FileOperationEvent, IFileStat, FileOperationResult, FileSystemProviderCapabilities, FileChangeType, IFileChange, FileChangesEvent, FileOperationError, etag, IStat } from 'vs/platform/files/common/files';
import { NullLogService } from 'vs/platform/log/common/log';
import { isLinux, isWindows } from 'vs/base/common/platform';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
@ -62,6 +62,8 @@ export class TestDiskFileSystemProvider extends DiskFileSystemProvider {
totalBytesRead: number = 0;
private invalidStatSize: boolean;
private _testCapabilities: FileSystemProviderCapabilities;
get capabilities(): FileSystemProviderCapabilities {
if (!this._testCapabilities) {
@ -82,6 +84,20 @@ export class TestDiskFileSystemProvider extends DiskFileSystemProvider {
this._testCapabilities = capabilities;
}
setInvalidStatSize(disabled: boolean): void {
this.invalidStatSize = disabled;
}
async stat(resource: URI): Promise<IStat> {
const res = await super.stat(resource);
if (this.invalidStatSize) {
res.size = String(res.size) as any; // for https://github.com/Microsoft/vscode/issues/72909
}
return res;
}
async read(fd: number, pos: number, data: Uint8Array, offset: number, length: number): Promise<number> {
const bytesRead = await super.read(fd, pos, data, offset, length);
@ -1049,6 +1065,24 @@ suite('Disk File Service', () => {
assert.equal(fileProvider.totalBytesRead, 0);
});
test('readFile - FILE_NOT_MODIFIED_SINCE does not fire wrongly - https://github.com/Microsoft/vscode/issues/72909', async () => {
setCapabilities(fileProvider, FileSystemProviderCapabilities.FileOpenReadWriteClose);
fileProvider.setInvalidStatSize(true);
const resource = URI.file(join(testDir, 'index.html'));
await service.readFile(resource);
let error: FileOperationError | undefined = undefined;
try {
await service.readFile(resource, { etag: undefined });
} catch (err) {
error = err;
}
assert.ok(!error);
});
test('readFile - FILE_NOT_MODIFIED_SINCE - unbuffered', async () => {
setCapabilities(fileProvider, FileSystemProviderCapabilities.FileReadWrite);