private registerFileWatcher()

in Extension/src/LanguageServer/client.ts [2294:2377]


    private registerFileWatcher(): void {
        console.assert(this.languageClient !== undefined, "This method must not be called until this.languageClient is set in \"onReady\"");

        if (this.rootFolder) {
            // WARNING: The default limit on Linux is 8k, so for big directories, this can cause file watching to fail.
            this.rootPathFileWatcher = vscode.workspace.createFileSystemWatcher(
                "**/*",
                false /* ignoreCreateEvents */,
                false /* ignoreChangeEvents */,
                false /* ignoreDeleteEvents */);

            this.rootPathFileWatcher.onDidCreate(async (uri) => {
                if (uri.scheme !== 'file') {
                    return;
                }
                const fileName: string = path.basename(uri.fsPath).toLowerCase();
                if (fileName === ".editorconfig") {
                    cachedEditorConfigSettings.clear();
                    cachedEditorConfigLookups.clear();
                    await this.updateActiveDocumentTextOptions();
                }
                if (fileName === ".clang-format" || fileName === "_clang-format") {
                    cachedEditorConfigLookups.clear();
                }

                this.languageClient.sendNotification(FileCreatedNotification, { uri: uri.toString() });
            });

            // TODO: Handle new associations without a reload.
            this.associations_for_did_change = new Set<string>(["cu", "cuh", "c", "i", "cpp", "cc", "cxx", "c++", "cp", "hpp", "hh", "hxx", "h++", "hp", "h", "ii", "ino", "inl", "ipp", "tcc", "idl"]);
            const assocs: any = new OtherSettings().filesAssociations;
            for (const assoc in assocs) {
                const dotIndex: number = assoc.lastIndexOf('.');
                if (dotIndex !== -1) {
                    const ext: string = assoc.substr(dotIndex + 1);
                    this.associations_for_did_change.add(ext);
                }
            }
            this.rootPathFileWatcher.onDidChange(async (uri) => {
                if (uri.scheme !== 'file') {
                    return;
                }
                const dotIndex: number = uri.fsPath.lastIndexOf('.');
                const fileName: string = path.basename(uri.fsPath).toLowerCase();
                if (fileName === ".editorconfig") {
                    cachedEditorConfigSettings.clear();
                    cachedEditorConfigLookups.clear();
                    await this.updateActiveDocumentTextOptions();
                }
                if (dotIndex !== -1) {
                    const ext: string = uri.fsPath.substr(dotIndex + 1);
                    if (this.associations_for_did_change?.has(ext)) {
                        // VS Code has a bug that causes onDidChange events to happen to files that aren't changed,
                        // which causes a large backlog of "files to parse" to accumulate.
                        // We workaround this via only sending the change message if the modified time is within 10 seconds.
                        const mtime: Date = fs.statSync(uri.fsPath).mtime;
                        const duration: number = Date.now() - mtime.getTime();
                        if (duration < 10000) {
                            this.languageClient.sendNotification(FileChangedNotification, { uri: uri.toString() });
                        }
                    }
                }
            });

            this.rootPathFileWatcher.onDidDelete((uri) => {
                if (uri.scheme !== 'file') {
                    return;
                }
                const fileName: string = path.basename(uri.fsPath).toLowerCase();
                if (fileName === ".editorconfig") {
                    cachedEditorConfigSettings.clear();
                    cachedEditorConfigLookups.clear();
                }
                if (fileName === ".clang-format" || fileName === "_clang-format") {
                    cachedEditorConfigLookups.clear();
                }
                this.languageClient.sendNotification(FileDeletedNotification, { uri: uri.toString() });
            });

            this.disposables.push(this.rootPathFileWatcher);
        } else {
            this.rootPathFileWatcher = undefined;
        }
    }