src/vs/platform/files/common/diskFileSystemProvider.ts

256 LOC · 122 covered · 134 uncovered · 17 ranges · 58 concepts · 3 introducers · 32 tests

File neighbourhood

The centred file is linked to every concept that introduces one of its ranges, every test that runs code from the file, and the gray connector concepts standing between those tests and the file's own introducer concepts. Undirected links join concepts to every file where they introduce source and concepts to the tests they introduce; arrows show specialization between the displayed concepts and bridge only concepts omitted from this view. Concept colors match the source ranges below; connector concepts have no source color and are shown in gray.

Focused file, its introducer and connector concepts, their introduced files, and tests that run code from the file

In the embedded map, ordinary wheel input scrolls the page; use the visible controls to zoom and drag to pan. Open the full-screen map for canvas navigation: wheel pans, Ctrl/Command plus wheel zooms, and arrow keys pan when this region is focused. On touch screens, open the full-screen map to pan or pinch. If JavaScript or WebGL is unavailable, use the related-file, concept, and source links on this page.

Focused file, its introducer and connector concepts, their introduced files, and tests that run code from the filesrc/vs/base/parts/ipc/node/ipc.cp.ts · 284 LOCnode/ipc.cp.tssrc/vs/platform/files/common/fileService.ts · 1491 LOCcommon/fileService.tssrc/vs/platform/files/node/diskFileSystemProvider.ts · 898 LOCnode/diskFileSystemProvi…src/vs/platform/files/node/watcher/baseWatcher.ts · 275 LOCwatcher/baseWatcher.tssrc/vs/platform/files/node/watcher/nodejs/nodejsClient.ts · 26 LOCnodejs/nodejsClient.tssrc/vs/platform/files/node/watcher/nodejs/nodejsWatcher.ts · 178 LOCnodejs/nodejsWatcher.tssrc/vs/platform/files/node/watcher/nodejs/nodejsWatcherLib.ts · 637 LOCnodejs/nodejsWatcherLib.…src/vs/platform/files/node/watcher/watcherClient.ts · 47 LOCwatcher/watcherClient.tscolorThemeData.ts ×16 · 64 introduced LOCcolorThemeData.ts ×16tokenClassificationRegistry.ts ×1 · 3 introduced LOCtokenClassificationRegis…tokenClassificationRegistry.ts ×2 · 7 introduced LOCtokenClassificationRegis…tokenStyleResolving.test|title=Themes - TokenStyleResolving language|occurrence=1 · 0 introduced LOCtokenStyleResolving.test…colorThemeData.ts ×1 · 2 introduced LOCcolorThemeData.ts ×1colorThemeData.ts ×12 · 57 introduced LOCcolorThemeData.ts ×12tokenClassificationRegistry.ts ×2 · 6 introduced LOCtokenClassificationRegis…colorThemeData.ts ×5 · 21 introduced LOCcolorThemeData.ts ×5colorThemeData.ts ×1 · 6 introduced LOCcolorThemeData.ts ×1colorThemeData.ts ×33 · 242 introduced LOCcolorThemeData.ts ×33colorThemeData.ts ×2 · 5 introduced LOCcolorThemeData.ts ×2tokenStyleResolving.test|title=Themes - TokenStyleResolving resolveScopes - match most specific|occurrence=1 · 0 introduced LOCtokenStyleResolving.test…colorThemeData.ts ×5 · 33 introduced LOCcolorThemeData.ts ×5colorThemeData.ts ×1 · 4 introduced LOCcolorThemeData.ts ×1tokenClassificationRegistry.ts ×1 · 16 introduced LOCtokenClassificationRegis…colorThemeData.ts ×1 · 1 introduced LOCcolorThemeData.ts ×1colorThemeData.ts ×13 · 114 introduced LOCcolorThemeData.ts ×13colorThemeData.ts ×1 · 1 introduced LOCcolorThemeData.ts ×1colorThemeData.ts ×4 · 15 introduced LOCcolorThemeData.ts ×4colorThemeData.ts ×57 · 483 introduced LOCcolorThemeData.ts ×57agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: cache hit returns immediately without re-downloading|occurrence=1 · 0 introduced LOCagentSdkDownloader.test|…diskFileSystemProvider.ts ×11 · 79 introduced LOCdiskFileSystemProvider.t…agentSdkDownloader.ts ×3 · 28 introduced LOCagentSdkDownloader.ts ×3diskFileSystemProvider.ts ×20 · 260 introduced LOCdiskFileSystemProvider.t…agentSdkDownloader.ts ×1 · 2 introduced LOCagentSdkDownloader.ts ×1agentSdkDownloader.ts ×1 · 2 introduced LOCagentSdkDownloader.ts ×1agentSdkDownloader.ts ×2 · 20 introduced LOCagentSdkDownloader.ts ×2stateService.ts ×2 · 7 introduced LOCstateService.ts ×2stateService.ts ×1 · 2 introduced LOCstateService.ts ×1stateService.ts ×2 · 14 introduced LOCstateService.ts ×2stateService.ts ×1 · 2 introduced LOCstateService.ts ×1diskFileSystemProvider.ts ×9 · 73 introduced LOCdiskFileSystemProvider.t…agentSdkDownloader.ts ×1 · 6 introduced LOCagentSdkDownloader.ts ×1agentSdkDownloader.ts ×2 · 8 introduced LOCagentSdkDownloader.ts ×2agentSdkDownloader.ts ×1 · 5 introduced LOCagentSdkDownloader.ts ×1agentSdkDownloader.ts ×2 · 8 introduced LOCagentSdkDownloader.ts ×2agentSdkDownloader.ts ×5 · 10 introduced LOCagentSdkDownloader.ts ×5agentSdkDownloader.ts ×1 · 3 introduced LOCagentSdkDownloader.ts ×1agentSdkDownloader.ts ×3 · 5 introduced LOCagentSdkDownloader.ts ×3agentSdkDownloader.test|title=AgentSdkDownloader isAvailable: true when product config populated and host has a target|occurrence=1 · 0 introduced LOCagentSdkDownloader.test|…agentSdkDownloader.ts ×1 · 2 introduced LOCagentSdkDownloader.ts ×1agentSdkDownloader.ts ×2 · 3 introduced LOCagentSdkDownloader.ts ×2agentSdkDownloader.ts ×1 · 8 introduced LOCagentSdkDownloader.ts ×1diskFileSystemProvider.ts ×28 · 135 introduced LOCdiskFileSystemProvider.t…diskFileSystemProvider.ts ×3 · 12 introduced LOCdiskFileSystemProvider.t…io.ts ×12 · 175 introduced LOCio.ts ×12agentSdkDownloader.ts ×1 · 2 introduced LOCagentSdkDownloader.ts ×1agentSdkDownloader.ts ×1 · 2 introduced LOCagentSdkDownloader.ts ×1agentSdkDownloader.ts ×1 · 2 introduced LOCagentSdkDownloader.ts ×1agentSdkDownloader.ts ×2 · 5 introduced LOCagentSdkDownloader.ts ×2diskFileSystemProvider.ts ×17 · 105 introduced LOCdiskFileSystemProvider.t…diskFileSystemProvider.ts ×1 · 21 introduced LOCdiskFileSystemProvider.t…stateService.ts ×1 · 2 introduced LOCstateService.ts ×1stateService.ts ×16 · 141 introduced LOCstateService.ts ×16diskFileSystemProvider.ts ×2 · 3 introduced LOCdiskFileSystemProvider.t…diskFileSystemProvider.ts ×10 · 34 introduced LOCdiskFileSystemProvider.t…diskFileSystemProvider.ts ×15 · 104 introduced LOCdiskFileSystemProvider.t…diskFileSystemProvider.ts ×21 · 577 introduced LOCdiskFileSystemProvider.t…agentSdkDownloader.test|title=AgentSdkDownloader isAvailable: false when no env override and no product config|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/agentSdkDownloader.test|title=AgentSdkDownloader isAvailable: false when no env override and no product config|occurrence=1agentSdkDownloader.test|…agentSdkDownloader.test|title=AgentSdkDownloader isAvailable: true when env override set|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/agentSdkDownloader.test|title=AgentSdkDownloader isAvailable: true when env override set|occurrence=1agentSdkDownloader.test|…agentSdkDownloader.test|title=AgentSdkDownloader isAvailable: true when product config populated and host has a target|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/agentSdkDownloader.test|title=AgentSdkDownloader isAvailable: true when product config populated and host has a target|occurrence=1agentSdkDownloader.test|…agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: cache dir includes sdkTarget so Universal launches stay separate|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: cache dir includes sdkTarget so Universal launches stay separate|occurrence=1agentSdkDownloader.test|…agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: cache hit returns immediately without re-downloading|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: cache hit returns immediately without re-downloading|occurrence=1agentSdkDownloader.test|…agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: cache miss → downloads, extracts, writes sentinel|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: cache miss → downloads, extracts, writes sentinel|occurrence=1agentSdkDownloader.test|…agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: cancel before download completes cleans up scratch dir|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: cancel before download completes cleans up scratch dir|occurrence=1agentSdkDownloader.test|…agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: concurrent calls in same process share one download|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: concurrent calls in same process share one download|occurrence=1agentSdkDownloader.test|…agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: dev override returns the path unchanged|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: dev override returns the path unchanged|occurrence=1agentSdkDownloader.test|…agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: missing product config and no env override throws actionable error|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: missing product config and no env override throws actionable error|occurrence=1agentSdkDownloader.test|…agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: rename-loser path returns existing cache when winner already published|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: rename-loser path returns existing cache when winner already published|occurrence=1agentSdkDownloader.test|…agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: reports monotonic download progress ending at totalBytes|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: reports monotonic download progress ending at totalBytes|occurrence=1agentSdkDownloader.test|…agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: substitutes {sdkTarget} into urlTemplate|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: substitutes {sdkTarget} into urlTemplate|occurrence=1agentSdkDownloader.test|…agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: urlTemplate with unknown placeholder throws config error|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: urlTemplate with unknown placeholder throws config error|occurrence=1agentSdkDownloader.test|…agentSdkDownloader.test|title=resolveSdkTarget appends -musl on musl Linux iff the package has separate musl SKUs|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/agentSdkDownloader.test|title=resolveSdkTarget appends -musl on musl Linux iff the package has separate musl SKUs|occurrence=1agentSdkDownloader.test|…agentSdkDownloader.test|title=resolveSdkTarget returns <platform>-<arch> for supported (platform, arch)|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/agentSdkDownloader.test|title=resolveSdkTarget returns <platform>-<arch> for supported (platform, arch)|occurrence=1agentSdkDownloader.test|…agentSdkDownloader.test|title=resolveSdkTarget returns undefined for unsupported (platform, arch)|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/agentSdkDownloader.test|title=resolveSdkTarget returns undefined for unsupported (platform, arch)|occurrence=1agentSdkDownloader.test|…checksumService.test|title=Checksum Service checksum|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/checksum/test/node/checksumService.test|title=Checksum Service checksum|occurrence=1checksumService.test|tit…state.test|title=StateService Basics (delayed strategy)|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/state/test/node/state.test|title=StateService Basics (delayed strategy)|occurrence=1state.test|title=StateSe…state.test|title=StateService Basics (immediate strategy)|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/state/test/node/state.test|title=StateService Basics (immediate strategy)|occurrence=1state.test|title=StateSe…state.test|title=StateService Closed before init|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/state/test/node/state.test|title=StateService Closed before init|occurrence=1state.test|title=StateSe…state.test|title=StateService Multiple ops (Immediate Strategy)|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/state/test/node/state.test|title=StateService Multiple ops (Immediate Strategy)|occurrence=1state.test|title=StateSe…state.test|title=StateService Multiple ops are buffered and applied|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/state/test/node/state.test|title=StateService Multiple ops are buffered and applied|occurrence=1state.test|title=StateSe…state.test|title=StateService Used after close|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/state/test/node/state.test|title=StateService Used after close|occurrence=1state.test|title=StateSe…state.test|title=StateService Used before init|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/state/test/node/state.test|title=StateService Used before init|occurrence=1state.test|title=StateSe…tokenStyleResolving.test|title=Themes - TokenStyleResolving color defaults|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/workbench/services/themes/test/node/tokenStyleResolving.test|title=Themes - TokenStyleResolving color defaults|occurrence=1tokenStyleResolving.test…tokenStyleResolving.test|title=Themes - TokenStyleResolving language - scope resolving|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/workbench/services/themes/test/node/tokenStyleResolving.test|title=Themes - TokenStyleResolving language - scope resolving|occurrence=1tokenStyleResolving.test…tokenStyleResolving.test|title=Themes - TokenStyleResolving language|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/workbench/services/themes/test/node/tokenStyleResolving.test|title=Themes - TokenStyleResolving language|occurrence=1tokenStyleResolving.test…tokenStyleResolving.test|title=Themes - TokenStyleResolving resolveScopes - match most specific|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/workbench/services/themes/test/node/tokenStyleResolving.test|title=Themes - TokenStyleResolving resolveScopes - match most specific|occurrence=1tokenStyleResolving.test…tokenStyleResolving.test|title=Themes - TokenStyleResolving resolveScopes|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/workbench/services/themes/test/node/tokenStyleResolving.test|title=Themes - TokenStyleResolving resolveScopes|occurrence=1tokenStyleResolving.test…tokenStyleResolving.test|title=Themes - TokenStyleResolving rule matching|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/workbench/services/themes/test/node/tokenStyleResolving.test|title=Themes - TokenStyleResolving rule matching|occurrence=1tokenStyleResolving.test…tokenStyleResolving.test|title=Themes - TokenStyleResolving super type|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/workbench/services/themes/test/node/tokenStyleResolving.test|title=Themes - TokenStyleResolving super type|occurrence=1tokenStyleResolving.test…Focused file · src/vs/platform/files/common/diskFileSystemProvider.ts · 256 LOCcommon/diskFileSystemPro…

Graph controls are ready.

Interactive rendering requires JavaScript and WebGL. Use the related-file, concept, and source links on this page while the interactive map is unavailable.

1 > /*--------------------------------------------------------------------------------------------- diskFileSystemProvider.ts ×21
2 > * Copyright (c) Microsoft Corporation. All rights reserved.
3 > * Licensed under the MIT License. See License.txt in the project root for license information.
4 > *--------------------------------------------------------------------------------------------*/
5 >
6 > import { insert } from '../../../base/common/arrays.js';
7 > import { ThrottledDelayer } from '../../../base/common/async.js';
8 > import { onUnexpectedError } from '../../../base/common/errors.js';
9 > import { Emitter } from '../../../base/common/event.js';
10 > import { removeTrailingPathSeparator } from '../../../base/common/extpath.js';
11 > import { Disposable, IDisposable, toDisposable } from '../../../base/common/lifecycle.js';
12 > import { normalize } from '../../../base/common/path.js';
13 > import { URI } from '../../../base/common/uri.js';
14 > import { IFileChange, IFileSystemProvider, IWatchOptions } from './files.js';
15 > import { AbstractNonRecursiveWatcherClient, AbstractUniversalWatcherClient, ILogMessage, INonRecursiveWatchRequest, IRecursiveWatcherOptions, isRecursiveWatchRequest, IUniversalWatchRequest, reviveFileChanges } from './watcher.js';
16 > import { ILogService, LogLevel } from '../../log/common/log.js';
17 >
18 > export interface IDiskFileSystemProviderOptions {
19 > watcher?: {
20 >
21 > /**
22 > * Extra options for the recursive file watching.
23 > */
24 > recursive?: IRecursiveWatcherOptions;
25 >
26 > /**
27 > * Forces all file watch requests to run through a
28 > * single universal file watcher, both recursive
29 > * and non-recursively.
30 > *
31 > * Enabling this option might cause some overhead,
32 > * specifically the universal file watcher will run
33 > * in a separate process given its complexity. Only
34 > * enable it when you understand the consequences.
35 > */
36 > forceUniversal?: boolean;
37 > };
38 > }
39 >
40 > export abstract class AbstractDiskFileSystemProvider extends Disposable implements
41 > Pick<IFileSystemProvider, 'watch'>,
42 > Pick<IFileSystemProvider, 'onDidChangeFile'>,
43 > Pick<IFileSystemProvider, 'onDidWatchError'> {
44 >
45 > constructor(
46 > protected readonly logService: ILogService, diskFileSystemProvider.ts ×15
47 > private readonly options?: IDiskFileSystemProviderOptions
48 > ) {
49 > super();
50 > }
51 >
52 > protected readonly _onDidChangeFile = this._register(new Emitter<readonly IFileChange[]>());
53 > readonly onDidChangeFile = this._onDidChangeFile.event;
54 >
55 > protected readonly _onDidWatchError = this._register(new Emitter<string>());
56 > readonly onDidWatchError = this._onDidWatchError.event;
57 >
58 > watch(resource: URI, opts: IWatchOptions): IDisposable {
59 if (opts.recursive || this.options?.watcher?.forceUniversal) {
60 return this.watchUniversal(resource, opts);
61 }
62
63 return this.watchNonRecursive(resource, opts);
64 }
66 > private getRefreshWatchersDelay(count: number): number {
67 > if (count > 200) {
68 // If there are many requests to refresh, start to throttle
69 // the refresh to reduce pressure. We see potentially thousands
70 // of requests coming in on startup repeatedly so we take it easy.
71 return 500;
72 }
74 > // By default, use a short delay to keep watchers updating fast but still
75 > // with a delay so that we can efficiently deduplicate requests or reuse
76 > // existing watchers.
77 > return 0;
78 > }
79 >
80 > //#region File Watching (universal)
81 >
82 > private universalWatcher: AbstractUniversalWatcherClient | undefined;
83 >
84 > private readonly universalWatchRequests: IUniversalWatchRequest[] = [];
85 > private readonly universalWatchRequestDelayer = this._register(new ThrottledDelayer<void>(this.getRefreshWatchersDelay(this.universalWatchRequests.length)));
86 >
87 > private watchUniversal(resource: URI, opts: IWatchOptions): IDisposable {
88 const request = this.toWatchRequest(resource, opts);
89 const remove = insert(this.universalWatchRequests, request);
90
91 // Trigger update
92 this.refreshUniversalWatchers();
93
94 return toDisposable(() => {
95
96 // Remove from list of paths to watch universally
97 remove();
98
99 // Trigger update
100 this.refreshUniversalWatchers();
101 });
102 }
104 > private toWatchRequest(resource: URI, opts: IWatchOptions): IUniversalWatchRequest {
105 const request: IUniversalWatchRequest = {
106 path: this.toWatchPath(resource),
107 excludes: opts.excludes,
108 includes: opts.includes,
109 recursive: opts.recursive,
110 filter: opts.filter,
111 correlationId: opts.correlationId
112 };
113
114 if (isRecursiveWatchRequest(request)) {
115
116 // Adjust for polling
117 const usePolling = this.options?.watcher?.recursive?.usePolling;
118 if (usePolling === true) {
119 request.pollingInterval = this.options?.watcher?.recursive?.pollingInterval ?? 5000;
120 } else if (Array.isArray(usePolling)) {
121 if (usePolling.includes(request.path)) {
122 request.pollingInterval = this.options?.watcher?.recursive?.pollingInterval ?? 5000;
123 }
124 }
125 }
126
127 return request;
128 }
130 > private refreshUniversalWatchers(): void {
131 this.universalWatchRequestDelayer.trigger(() => {
132 return this.doRefreshUniversalWatchers();
133 }, this.getRefreshWatchersDelay(this.universalWatchRequests.length)).catch(error => onUnexpectedError(error));
134 }
136 > private doRefreshUniversalWatchers(): Promise<void> {
137
138 // Create watcher if this is the first time
139 if (!this.universalWatcher) {
140 this.universalWatcher = this._register(this.createUniversalWatcher(
141 changes => this._onDidChangeFile.fire(reviveFileChanges(changes)),
142 msg => this.onWatcherLogMessage(msg),
143 this.logService.getLevel() === LogLevel.Trace
144 ));
145
146 // Apply log levels dynamically
147 this._register(this.logService.onDidChangeLogLevel(() => {
148 this.universalWatcher?.setVerboseLogging(this.logService.getLevel() === LogLevel.Trace);
149 }));
150 }
151
152 // Ask to watch the provided paths
153 return this.universalWatcher.watch(this.universalWatchRequests);
154 }
156 > protected abstract createUniversalWatcher(
157 > onChange: (changes: IFileChange[]) => void,
158 > onLogMessage: (msg: ILogMessage) => void,
159 > verboseLogging: boolean
160 > ): AbstractUniversalWatcherClient;
161 >
162 > //#endregion
163 >
164 > //#region File Watching (non-recursive)
165 >
166 > private nonRecursiveWatcher: AbstractNonRecursiveWatcherClient | undefined;
167 >
168 > private readonly nonRecursiveWatchRequests: INonRecursiveWatchRequest[] = [];
169 > private readonly nonRecursiveWatchRequestDelayer = this._register(new ThrottledDelayer<void>(this.getRefreshWatchersDelay(this.nonRecursiveWatchRequests.length)));
171 > private watchNonRecursive(resource: URI, opts: IWatchOptions): IDisposable {
172
173 // Add to list of paths to watch non-recursively
174 const request: INonRecursiveWatchRequest = {
175 path: this.toWatchPath(resource),
176 excludes: opts.excludes,
177 includes: opts.includes,
178 recursive: false,
179 filter: opts.filter,
180 correlationId: opts.correlationId
181 };
182 const remove = insert(this.nonRecursiveWatchRequests, request);
183
184 // Trigger update
185 this.refreshNonRecursiveWatchers();
186
187 return toDisposable(() => {
188
189 // Remove from list of paths to watch non-recursively
190 remove();
191
192 // Trigger update
193 this.refreshNonRecursiveWatchers();
194 });
195 }
197 > private refreshNonRecursiveWatchers(): void {
198 this.nonRecursiveWatchRequestDelayer.trigger(() => {
199 return this.doRefreshNonRecursiveWatchers();
200 }, this.getRefreshWatchersDelay(this.nonRecursiveWatchRequests.length)).catch(error => onUnexpectedError(error));
201 }
203 > private doRefreshNonRecursiveWatchers(): Promise<void> {
204
205 // Create watcher if this is the first time
206 if (!this.nonRecursiveWatcher) {
207 this.nonRecursiveWatcher = this._register(this.createNonRecursiveWatcher(
208 changes => this._onDidChangeFile.fire(reviveFileChanges(changes)),
209 msg => this.onWatcherLogMessage(msg),
210 this.logService.getLevel() === LogLevel.Trace
211 ));
212
213 // Apply log levels dynamically
214 this._register(this.logService.onDidChangeLogLevel(() => {
215 this.nonRecursiveWatcher?.setVerboseLogging(this.logService.getLevel() === LogLevel.Trace);
216 }));
217 }
218
219 // Ask to watch the provided paths
220 return this.nonRecursiveWatcher.watch(this.nonRecursiveWatchRequests);
221 }
223 > protected abstract createNonRecursiveWatcher(
224 > onChange: (changes: IFileChange[]) => void,
225 > onLogMessage: (msg: ILogMessage) => void,
226 > verboseLogging: boolean
227 > ): AbstractNonRecursiveWatcherClient;
228 >
229 > //#endregion
230 >
231 > private onWatcherLogMessage(msg: ILogMessage): void {
232 if (msg.type === 'error') {
233 this._onDidWatchError.fire(msg.message);
234 }
235
236 this.logWatcherMessage(msg);
237 }
239 > protected logWatcherMessage(msg: ILogMessage): void {
240 this.logService[msg.type](msg.message);
241 }
243 > protected toFilePath(resource: URI): string {
244 > return normalize(resource.fsPath); diskFileSystemProvider.ts ×10
245 > }
247 > private toWatchPath(resource: URI): string {
248 const filePath = this.toFilePath(resource);
249
250 // Ensure to have any trailing path separators removed, otherwise
251 // we may believe the path is not "real" and will convert every
252 // event back to this form, which is not warranted.
253 // See also https://github.com/microsoft/vscode/issues/210517
254 return removeTrailingPathSeparator(filePath);
255 }