提交 59cc8326 编写于 作者: B Benjamin Pasero

fileservice 💄

上级 c92769fa
......@@ -20,13 +20,14 @@ import { isEqual } from 'vs/base/common/resources';
import { isLinux, isMacintosh, isWindows } from 'vs/base/common/platform';
import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle';
import { IDialogService } from 'vs/platform/dialogs/common/dialogs';
import { equals } from 'vs/base/common/objects';
interface IConfiguration extends IWindowsConfiguration {
update: { channel: string; };
telemetry: { enableCrashReporter: boolean };
keyboard: { touchbar: { enabled: boolean } };
workbench: { tree: { horizontalScrolling: boolean } };
files: { useExperimentalFileWatcher: boolean };
files: { useExperimentalFileWatcher: boolean, watcherExclude: object };
}
export class SettingsChangeRelauncher implements IWorkbenchContribution {
......@@ -42,6 +43,7 @@ export class SettingsChangeRelauncher implements IWorkbenchContribution {
private treeHorizontalScrolling: boolean;
private windowsSmoothScrollingWorkaround: boolean;
private experimentalFileWatcher: boolean;
private fileWatcherExclude: object;
private firstFolderResource: URI;
private extensionHostRestarter: RunOnceScheduler;
......@@ -111,6 +113,14 @@ export class SettingsChangeRelauncher implements IWorkbenchContribution {
changed = true;
}
// File Watcher Excludes (only if in folder workspace mode)
if (!this.experimentalFileWatcher && this.contextService.getWorkbenchState() === WorkbenchState.FOLDER) {
if (config.files && typeof config.files.watcherExclude === 'object' && !equals(config.files.watcherExclude, this.fileWatcherExclude)) {
this.fileWatcherExclude = config.files.watcherExclude;
changed = true;
}
}
// macOS: Touchbar config
if (isMacintosh && config.keyboard && config.keyboard.touchbar && typeof config.keyboard.touchbar.enabled === 'boolean' && config.keyboard.touchbar.enabled !== this.touchbarEnabled) {
this.touchbarEnabled = config.keyboard.touchbar.enabled;
......
......@@ -47,61 +47,6 @@ import product from 'vs/platform/node/product';
import { WORKSPACE_EXTENSION } from 'vs/platform/workspaces/common/workspaces';
import { shell } from 'electron';
export interface IEncodingOverride {
parent?: uri;
extension?: string;
encoding: string;
}
export interface IFileServiceTestOptions {
tmpDir?: string;
disableWatcher?: boolean;
encodingOverride?: IEncodingOverride[];
}
function etag(stat: fs.Stats): string;
function etag(size: number, mtime: number): string;
function etag(arg1: any, arg2?: any): string {
let size: number;
let mtime: number;
if (typeof arg2 === 'number') {
size = arg1;
mtime = arg2;
} else {
size = (<fs.Stats>arg1).size;
mtime = (<fs.Stats>arg1).mtime.getTime();
}
return `"${crypto.createHash('sha1').update(String(size) + String(mtime)).digest('hex')}"`;
}
class BufferPool {
static _64K = new BufferPool(64 * 1024, 5);
constructor(
readonly bufferSize: number,
private readonly _capacity: number,
private readonly _free: Buffer[] = [],
) {
//
}
acquire(): Buffer {
if (this._free.length === 0) {
return Buffer.allocUnsafe(this.bufferSize);
} else {
return this._free.shift();
}
}
release(buf: Buffer): void {
if (this._free.length <= this._capacity) {
this._free.push(buf);
}
}
}
export class FileService implements IFileService {
public _serviceBrand: any;
......@@ -118,8 +63,6 @@ export class FileService implements IFileService {
protected readonly _onFileChanges: Emitter<FileChangesEvent>;
protected readonly _onAfterOperation: Emitter<FileOperationEvent>;
private tmpPath: string;
private toDispose: IDisposable[];
private activeWorkspaceFileChangeWatcher: IDisposable;
......@@ -127,9 +70,6 @@ export class FileService implements IFileService {
private fileChangesWatchDelayer: ThrottledDelayer<void>;
private undeliveredRawFileChangesEvents: IRawFileChange[];
private useExperimentalFileWatcher: boolean;
private watcherIgnoredPatterns: string[];
private encodingOverride: IEncodingOverride[];
constructor(
......@@ -143,7 +83,6 @@ export class FileService implements IFileService {
private options: IFileServiceTestOptions = Object.create(null)
) {
this.toDispose = [];
this.tmpPath = this.options.tmpDir || os.tmpdir();
this._onFileChanges = new Emitter<FileChangesEvent>();
this.toDispose.push(this._onFileChanges);
......@@ -155,15 +94,6 @@ export class FileService implements IFileService {
this.fileChangesWatchDelayer = new ThrottledDelayer<void>(FileService.FS_EVENT_DELAY);
this.undeliveredRawFileChangesEvents = [];
const configuration = this.configurationService.getValue<IFilesConfiguration>();
this.watcherIgnoredPatterns = [];
if (configuration.files && configuration.files.watcherExclude) {
this.watcherIgnoredPatterns = Object.keys(configuration.files.watcherExclude).filter(k => !!configuration.files.watcherExclude[k]);
}
this.useExperimentalFileWatcher = configuration.files && configuration.files.useExperimentalFileWatcher;
this.encodingOverride = this.options.encodingOverride || this.getEncodingOverrides();
this.registerListeners();
......@@ -281,26 +211,32 @@ export class FileService implements IFileService {
}
// new watcher: use it if setting tells us so or we run in multi-root environment
if (this.useExperimentalFileWatcher || workbenchState === WorkbenchState.WORKSPACE) {
const configuration = this.configurationService.getValue<IFilesConfiguration>();
if ((configuration.files && configuration.files.useExperimentalFileWatcher) || workbenchState === WorkbenchState.WORKSPACE) {
this.activeWorkspaceFileChangeWatcher = toDisposable(this.setupNsfwWorkspaceWatching().startWatching());
}
// old watcher
else {
let watcherIgnoredPatterns: string[] = [];
if (configuration.files && configuration.files.watcherExclude) {
watcherIgnoredPatterns = Object.keys(configuration.files.watcherExclude).filter(k => !!configuration.files.watcherExclude[k]);
}
if (isWindows) {
this.activeWorkspaceFileChangeWatcher = toDisposable(this.setupWin32WorkspaceWatching().startWatching());
this.activeWorkspaceFileChangeWatcher = toDisposable(this.setupWin32WorkspaceWatching(watcherIgnoredPatterns).startWatching());
} else {
this.activeWorkspaceFileChangeWatcher = toDisposable(this.setupUnixWorkspaceWatching().startWatching());
this.activeWorkspaceFileChangeWatcher = toDisposable(this.setupUnixWorkspaceWatching(watcherIgnoredPatterns).startWatching());
}
}
}
private setupWin32WorkspaceWatching(): WindowsWatcherService {
return new WindowsWatcherService(this.contextService, this.watcherIgnoredPatterns, e => this._onFileChanges.fire(e), err => this.handleError(err), this.environmentService.verbose);
private setupWin32WorkspaceWatching(watcherIgnoredPatterns: string[]): WindowsWatcherService {
return new WindowsWatcherService(this.contextService, watcherIgnoredPatterns, e => this._onFileChanges.fire(e), err => this.handleError(err), this.environmentService.verbose);
}
private setupUnixWorkspaceWatching(): UnixWatcherService {
return new UnixWatcherService(this.contextService, this.watcherIgnoredPatterns, e => this._onFileChanges.fire(e), err => this.handleError(err), this.environmentService.verbose);
private setupUnixWorkspaceWatching(watcherIgnoredPatterns: string[]): UnixWatcherService {
return new UnixWatcherService(this.contextService, watcherIgnoredPatterns, e => this._onFileChanges.fire(e), err => this.handleError(err), this.environmentService.verbose);
}
private setupNsfwWorkspaceWatching(): NsfwWatcherService {
......@@ -745,7 +681,7 @@ export class FileService implements IFileService {
writeOptions.encoding = this.getEncoding(resource, options.encoding);
// 2.) write to a temporary file to be able to copy over later
const tmpPath = paths.join(this.tmpPath, `code-elevated-${Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, 6)}`);
const tmpPath = paths.join(os.tmpdir(), `code-elevated-${Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, 6)}`);
return this.updateContent(uri.file(tmpPath), value, writeOptions).then(() => {
// 3.) invoke our CLI as super user
......@@ -773,7 +709,7 @@ export class FileService implements IFileService {
}).then(() => {
// 3.) delete temp file
return pfs.del(tmpPath, this.tmpPath).then(() => {
return pfs.del(tmpPath, os.tmpdir()).then(() => {
// 4.) resolve again
return this.resolve(resource);
......@@ -1033,7 +969,7 @@ export class FileService implements IFileService {
private doDelete(resource: uri): TPromise<void> {
const absolutePath = this.toAbsolutePath(resource);
return pfs.del(absolutePath, this.tmpPath).then(() => {
return pfs.del(absolutePath, os.tmpdir()).then(() => {
// Events
this._onAfterOperation.fire(new FileOperationEvent(resource, FileOperation.DELETE));
......@@ -1245,6 +1181,60 @@ export class FileService implements IFileService {
}
}
export interface IEncodingOverride {
parent?: uri;
extension?: string;
encoding: string;
}
export interface IFileServiceTestOptions {
disableWatcher?: boolean;
encodingOverride?: IEncodingOverride[];
}
function etag(stat: fs.Stats): string;
function etag(size: number, mtime: number): string;
function etag(arg1: any, arg2?: any): string {
let size: number;
let mtime: number;
if (typeof arg2 === 'number') {
size = arg1;
mtime = arg2;
} else {
size = (<fs.Stats>arg1).size;
mtime = (<fs.Stats>arg1).mtime.getTime();
}
return `"${crypto.createHash('sha1').update(String(size) + String(mtime)).digest('hex')}"`;
}
class BufferPool {
static _64K = new BufferPool(64 * 1024, 5);
constructor(
readonly bufferSize: number,
private readonly _capacity: number,
private readonly _free: Buffer[] = [],
) {
//
}
acquire(): Buffer {
if (this._free.length === 0) {
return Buffer.allocUnsafe(this.bufferSize);
} else {
return this._free.shift();
}
}
release(buf: Buffer): void {
if (this._free.length <= this._capacity) {
this._free.push(buf);
}
}
}
export class StatResolver {
private name: string;
private etag: string;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册