mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 10:58:30 -05:00
Merge from vscode 12cb89c82e88e035f4ab630f1b9fcebac338dc03 (#5125)
This commit is contained in:
@@ -263,13 +263,13 @@ export class WorkspaceConfiguration extends Disposable {
|
||||
this._workspaceIdentifier = workspaceIdentifier;
|
||||
if (!(this._workspaceConfiguration instanceof FileServiceBasedWorkspaceConfiguration)) {
|
||||
if (this._workspaceIdentifier.configPath.scheme === Schemas.file) {
|
||||
this.switch();
|
||||
this.switch(new FileServiceBasedWorkspaceConfiguration(this._configurationFileService));
|
||||
} else {
|
||||
this.waitAndSwitch(this._workspaceIdentifier);
|
||||
}
|
||||
}
|
||||
await this._workspaceConfiguration.load(this._workspaceIdentifier);
|
||||
this._loaded = this._workspaceConfiguration instanceof FileServiceBasedWorkspaceConfiguration;
|
||||
await this._workspaceConfiguration.load(this._workspaceIdentifier);
|
||||
}
|
||||
|
||||
reload(): Promise<void> {
|
||||
@@ -300,21 +300,25 @@ export class WorkspaceConfiguration extends Disposable {
|
||||
private async waitAndSwitch(workspaceIdentifier: IWorkspaceIdentifier): Promise<void> {
|
||||
await this._configurationFileService.whenProviderRegistered(workspaceIdentifier.configPath.scheme);
|
||||
if (!(this._workspaceConfiguration instanceof FileServiceBasedWorkspaceConfiguration)) {
|
||||
this.switch();
|
||||
const fileServiceBasedWorkspaceConfiguration = this._register(new FileServiceBasedWorkspaceConfiguration(this._configurationFileService));
|
||||
await fileServiceBasedWorkspaceConfiguration.load(workspaceIdentifier);
|
||||
this.switch(fileServiceBasedWorkspaceConfiguration);
|
||||
this._loaded = true;
|
||||
this.onDidWorkspaceConfigurationChange();
|
||||
this.onDidWorkspaceConfigurationChange(false);
|
||||
}
|
||||
}
|
||||
|
||||
private switch(): void {
|
||||
private switch(fileServiceBasedWorkspaceConfiguration: FileServiceBasedWorkspaceConfiguration): void {
|
||||
this._workspaceConfiguration.dispose();
|
||||
this._workspaceConfigurationChangeDisposable.dispose();
|
||||
this._workspaceConfiguration = this._register(new FileServiceBasedWorkspaceConfiguration(this._configurationFileService));
|
||||
this._workspaceConfigurationChangeDisposable = this._register(this._workspaceConfiguration.onDidChange(e => this.onDidWorkspaceConfigurationChange()));
|
||||
this._workspaceConfiguration = this._register(fileServiceBasedWorkspaceConfiguration);
|
||||
this._workspaceConfigurationChangeDisposable = this._register(this._workspaceConfiguration.onDidChange(e => this.onDidWorkspaceConfigurationChange(true)));
|
||||
}
|
||||
|
||||
private async onDidWorkspaceConfigurationChange(): Promise<void> {
|
||||
await this.reload();
|
||||
private async onDidWorkspaceConfigurationChange(reload: boolean): Promise<void> {
|
||||
if (reload) {
|
||||
await this.reload();
|
||||
}
|
||||
this.updateCache();
|
||||
this._onDidUpdateConfiguration.fire();
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Disposable, IDisposable, toDisposable, combinedDisposable, dispose } from 'vs/base/common/lifecycle';
|
||||
import { IFileService, IResolveFileOptions, FileChangesEvent, FileOperationEvent, IFileSystemProviderRegistrationEvent, IFileSystemProvider, IFileStat, IResolveFileResult, ICreateFileOptions, IFileSystemProviderActivationEvent, FileOperationError, FileOperationResult, FileOperation, FileSystemProviderCapabilities, FileType, toFileSystemProviderErrorCode, FileSystemProviderErrorCode, IStat, IFileStatWithMetadata, IResolveMetadataFileOptions, etag, hasReadWriteCapability, hasFileFolderCopyCapability, hasOpenReadWriteCloseCapability, toFileOperationResult, IFileSystemProviderWithOpenReadWriteCloseCapability, IFileSystemProviderWithFileReadWriteCapability, IResolveFileResultWithMetadata, IWatchOptions, IWriteFileOptions, IReadFileOptions, IFileStreamContent, IFileContent } from 'vs/platform/files/common/files';
|
||||
import { IFileService, IResolveFileOptions, FileChangesEvent, FileOperationEvent, IFileSystemProviderRegistrationEvent, IFileSystemProvider, IFileStat, IResolveFileResult, ICreateFileOptions, IFileSystemProviderActivationEvent, FileOperationError, FileOperationResult, FileOperation, FileSystemProviderCapabilities, FileType, toFileSystemProviderErrorCode, FileSystemProviderErrorCode, IStat, IFileStatWithMetadata, IResolveMetadataFileOptions, etag, hasReadWriteCapability, hasFileFolderCopyCapability, hasOpenReadWriteCloseCapability, toFileOperationResult, IFileSystemProviderWithOpenReadWriteCloseCapability, IFileSystemProviderWithFileReadWriteCapability, IResolveFileResultWithMetadata, IWatchOptions, IWriteFileOptions, IReadFileOptions, IFileStreamContent, IFileContent, ETAG_DISABLED } from 'vs/platform/files/common/files';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation';
|
||||
@@ -337,7 +337,7 @@ export class FileService extends Disposable implements IFileService {
|
||||
// check for size is a weaker check because it can return a false negative if the file has changed
|
||||
// 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.mtime < stat.mtime && options.etag !== etag(stat.size, options.mtime)) {
|
||||
if (options && typeof options.mtime === 'number' && typeof options.etag === 'string' && options.etag !== ETAG_DISABLED && options.mtime < stat.mtime && options.etag !== etag(stat.size, options.mtime)) {
|
||||
throw new FileOperationError(localize('fileModifiedError', "File Modified Since"), FileOperationResult.FILE_MODIFIED_SINCE, options);
|
||||
}
|
||||
|
||||
@@ -375,7 +375,7 @@ export class FileService extends Disposable implements IFileService {
|
||||
// due to the likelyhood of hitting a NOT_MODIFIED_SINCE result.
|
||||
// otherwise, we let it run in parallel to the file reading for
|
||||
// optimal startup performance.
|
||||
if (options && options.etag) {
|
||||
if (options && typeof options.etag === 'string' && options.etag !== ETAG_DISABLED) {
|
||||
await statPromise;
|
||||
}
|
||||
|
||||
@@ -493,7 +493,7 @@ export class FileService extends Disposable implements IFileService {
|
||||
}
|
||||
|
||||
// Return early if file not modified since
|
||||
if (options && options.etag && options.etag === stat.etag) {
|
||||
if (options && options.etag === stat.etag) {
|
||||
throw new FileOperationError(localize('fileNotModifiedError', "File not modified since"), FileOperationResult.FILE_NOT_MODIFIED_SINCE, options);
|
||||
}
|
||||
|
||||
|
||||
@@ -1491,7 +1491,11 @@ suite('Disk File Service', () => {
|
||||
setTimeout(() => mkdirSync(folder.fsPath), 50);
|
||||
});
|
||||
|
||||
test.skip('watch - folder (non recursive) - delete folder', done => {
|
||||
test('watch - folder (non recursive) - delete folder', done => {
|
||||
if (isWindows) {
|
||||
return done(); // not happy
|
||||
}
|
||||
|
||||
const watchDir = URI.file(join(testDir, 'watch7'));
|
||||
mkdirSync(watchDir.fsPath);
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ import 'vs/css!./media/progressService2';
|
||||
|
||||
import { localize } from 'vs/nls';
|
||||
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
|
||||
import { IProgressService2, IProgressOptions, IProgressStep, ProgressLocation, IProgress, emptyProgress, Progress } from 'vs/platform/progress/common/progress';
|
||||
import { IProgressService2, IProgressOptions, IProgressStep, ProgressLocation, IProgress, emptyProgress, Progress, IProgressNotificationOptions } from 'vs/platform/progress/common/progress';
|
||||
import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
|
||||
import { StatusbarAlignment, IStatusbarService } from 'vs/platform/statusbar/common/statusbar';
|
||||
import { timeout } from 'vs/base/common/async';
|
||||
@@ -54,7 +54,7 @@ export class ProgressService2 implements IProgressService2 {
|
||||
|
||||
switch (location) {
|
||||
case ProgressLocation.Notification:
|
||||
return this._withNotificationProgress(options, task, onDidCancel);
|
||||
return this._withNotificationProgress({ ...options, location: ProgressLocation.Notification }, task, onDidCancel);
|
||||
case ProgressLocation.Window:
|
||||
return this._withWindowProgress(options, task);
|
||||
case ProgressLocation.Explorer:
|
||||
@@ -138,7 +138,7 @@ export class ProgressService2 implements IProgressService2 {
|
||||
}
|
||||
}
|
||||
|
||||
private _withNotificationProgress<P extends Promise<R>, R = unknown>(options: IProgressOptions, callback: (progress: IProgress<{ message?: string, increment?: number }>) => P, onDidCancel?: () => void): P {
|
||||
private _withNotificationProgress<P extends Promise<R>, R = unknown>(options: IProgressNotificationOptions, callback: (progress: IProgress<{ message?: string, increment?: number }>) => P, onDidCancel?: () => void): P {
|
||||
const toDispose: IDisposable[] = [];
|
||||
|
||||
const createNotification = (message: string | undefined, increment?: number): INotificationHandle | undefined => {
|
||||
@@ -146,7 +146,7 @@ export class ProgressService2 implements IProgressService2 {
|
||||
return undefined; // we need a message at least
|
||||
}
|
||||
|
||||
const actions: INotificationActions = { primary: [] };
|
||||
const actions: INotificationActions = { primary: options.primaryActions || [], secondary: options.secondaryActions || [] };
|
||||
if (options.cancellable) {
|
||||
const cancelAction = new class extends Action {
|
||||
constructor() {
|
||||
|
||||
@@ -16,7 +16,7 @@ import { ITextFileService, IAutoSaveConfiguration, ModelState, ITextFileEditorMo
|
||||
import { EncodingMode } from 'vs/workbench/common/editor';
|
||||
import { BaseTextEditorModel } from 'vs/workbench/common/editor/textEditorModel';
|
||||
import { IBackupFileService } from 'vs/workbench/services/backup/common/backup';
|
||||
import { IFileService, FileOperationError, FileOperationResult, CONTENT_CHANGE_EVENT_BUFFER_DELAY, FileChangesEvent, FileChangeType, IFileStatWithMetadata, etag } from 'vs/platform/files/common/files';
|
||||
import { IFileService, FileOperationError, FileOperationResult, CONTENT_CHANGE_EVENT_BUFFER_DELAY, FileChangesEvent, FileChangeType, IFileStatWithMetadata, ETAG_DISABLED } from 'vs/platform/files/common/files';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IModeService, ILanguageSelection } from 'vs/editor/common/services/modeService';
|
||||
import { IModelService } from 'vs/editor/common/services/modelService';
|
||||
@@ -55,26 +55,35 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil
|
||||
get onDidStateChange(): Event<StateChange> { return this._onDidStateChange.event; }
|
||||
|
||||
private resource: URI;
|
||||
|
||||
private contentEncoding: string; // encoding as reported from disk
|
||||
private preferredEncoding: string; // encoding as chosen by the user
|
||||
private dirty: boolean;
|
||||
|
||||
private versionId: number;
|
||||
private bufferSavedVersionId: number;
|
||||
private lastResolvedDiskStat: IFileStatWithMetadata;
|
||||
private blockModelContentChange: boolean;
|
||||
|
||||
private createTextEditorModelPromise: Promise<TextFileEditorModel> | null;
|
||||
|
||||
private lastResolvedDiskStat: IFileStatWithMetadata;
|
||||
|
||||
private autoSaveAfterMillies?: number;
|
||||
private autoSaveAfterMilliesEnabled: boolean;
|
||||
private autoSaveDisposable?: IDisposable;
|
||||
|
||||
private saveSequentializer: SaveSequentializer;
|
||||
private lastSaveAttemptTime: number;
|
||||
|
||||
private contentChangeEventScheduler: RunOnceScheduler;
|
||||
private orphanedChangeEventScheduler: RunOnceScheduler;
|
||||
private saveSequentializer: SaveSequentializer;
|
||||
private disposed: boolean;
|
||||
private lastSaveAttemptTime: number;
|
||||
private createTextEditorModelPromise: Promise<TextFileEditorModel> | null;
|
||||
|
||||
private dirty: boolean;
|
||||
private inConflictMode: boolean;
|
||||
private inOrphanMode: boolean;
|
||||
private inErrorMode: boolean;
|
||||
|
||||
private disposed: boolean;
|
||||
|
||||
constructor(
|
||||
resource: URI,
|
||||
preferredEncoding: string,
|
||||
@@ -271,8 +280,8 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil
|
||||
name: basename(this.resource),
|
||||
mtime: Date.now(),
|
||||
size: 0,
|
||||
etag: etag(Date.now(), 0),
|
||||
value: createTextBufferFactory(''), /* will be filled later from backup */
|
||||
etag: ETAG_DISABLED, // always allow to save content restored from a backup (see https://github.com/Microsoft/vscode/issues/72343)
|
||||
value: createTextBufferFactory(''), // will be filled later from backup
|
||||
encoding: this.textFileService.encoding.getPreferredWriteEncoding(this.resource, this.preferredEncoding).encoding,
|
||||
isReadonly: false
|
||||
};
|
||||
@@ -754,10 +763,6 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil
|
||||
this.telemetryService.publicLog('filePUT', this.getTelemetryData(options.reason));
|
||||
}
|
||||
}, error => {
|
||||
if (!error) {
|
||||
error = new Error('Unknown Save Error'); // TODO@remote we should never get null as error (https://github.com/Microsoft/vscode/issues/55051)
|
||||
}
|
||||
|
||||
this.logService.error(`doSave(${versionId}) - exit - resulted in a save error: ${error.toString()}`, this.resource);
|
||||
|
||||
// Flag as error state in the model
|
||||
|
||||
@@ -510,7 +510,6 @@ export abstract class TextFileService extends Disposable implements ITextFileSer
|
||||
}));
|
||||
}
|
||||
|
||||
|
||||
// Soft revert the dirty source files if any
|
||||
await this.revertAll(dirtySourceModels.map(dirtySourceModel => dirtySourceModel.getResource()), { soft: true });
|
||||
|
||||
|
||||
Reference in New Issue
Block a user