diff --git a/CHANGELOG.md b/CHANGELOG.md index 92da6383..b300b217 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ - [#376](https://github.com/estruyf/vscode-front-matter/issues/376): Ability to run scripts after content was created - [#377](https://github.com/estruyf/vscode-front-matter/issues/377): Git sync actions added on panel and content dashboard (pull and push your changes to remote) +- [#379](https://github.com/estruyf/vscode-front-matter/issues/377): New `frontMatter.config.reload` command to reload the configuration file + reinitialize its listeners ### 🎨 Enhancements diff --git a/package.json b/package.json index 5c942772..1359acda 100644 --- a/package.json +++ b/package.json @@ -1380,6 +1380,11 @@ } }, "commands": [ + { + "command": "frontMatter.config.reload", + "title": "Reload config", + "category": "Front Matter" + }, { "command": "frontMatter.authenticate", "title": "Authenticate", diff --git a/src/commands/Backers.ts b/src/commands/Backers.ts index 55ea0168..73bb80a4 100644 --- a/src/commands/Backers.ts +++ b/src/commands/Backers.ts @@ -1,5 +1,5 @@ import { commands, ExtensionContext } from 'vscode'; -import { CONTEXT } from '../constants'; +import { COMMAND_NAME, CONTEXT } from '../constants'; import { Extension } from '../helpers'; import { Credentials } from "../services/Credentials"; import fetch from "node-fetch"; @@ -17,7 +17,7 @@ export class Backers { Backers.tryUsernameCheck(); context.subscriptions.push( - commands.registerCommand('frontMatter.authenticate', async () => { + commands.registerCommand(COMMAND_NAME.authenticate, async () => { Backers.tryUsernameCheck(); }) ); diff --git a/src/constants/Extension.ts b/src/constants/Extension.ts index ada6a795..b2eff6c8 100644 --- a/src/constants/Extension.ts +++ b/src/constants/Extension.ts @@ -65,4 +65,10 @@ export const COMMAND_NAME = { // Git gitSync: getCommandName("git.sync"), + + // Authenticate + authenticate: getCommandName("authenticate"), + + // Config + reloadConfig: getCommandName("config.reload"), }; \ No newline at end of file diff --git a/src/helpers/SettingsHelper.ts b/src/helpers/SettingsHelper.ts index 1833005f..a2391cfc 100644 --- a/src/helpers/SettingsHelper.ts +++ b/src/helpers/SettingsHelper.ts @@ -1,24 +1,36 @@ +import { parseWinPath } from './parseWinPath'; import { Telemetry } from './Telemetry'; import { Notifications } from './Notifications'; import { commands, Uri, workspace, window } from 'vscode'; import * as vscode from 'vscode'; import { ContentType, CustomTaxonomy, TaxonomyType } from '../models'; -import { SETTING_TAXONOMY_TAGS, SETTING_TAXONOMY_CATEGORIES, CONFIG_KEY, CONTEXT, ExtensionState, SETTING_TAXONOMY_CUSTOM, TelemetryEvent } from '../constants'; +import { SETTING_TAXONOMY_TAGS, SETTING_TAXONOMY_CATEGORIES, CONFIG_KEY, CONTEXT, ExtensionState, SETTING_TAXONOMY_CUSTOM, TelemetryEvent, COMMAND_NAME } from '../constants'; import { Folders } from '../commands/Folders'; import { join, basename } from 'path'; import { existsSync, readFileSync, watch, writeFileSync } from 'fs'; import { Extension } from './Extension'; import { debounceCallback } from './DebounceCallback'; +import { Logger } from './Logger'; export class Settings { public static globalFile = "frontmatter.json"; private static config: vscode.WorkspaceConfiguration; private static globalConfig: any; - + private static isInitialized: boolean = false; + private static listeners: any[] = []; + private static fileCreationWatcher: vscode.FileSystemWatcher | undefined; public static init() { Settings.readConfig(); + Settings.listeners = []; + + if (!Settings.isInitialized) { + Settings.isInitialized = true; + + commands.registerCommand(COMMAND_NAME.reloadConfig, Settings.rebindWatchers) + } + Settings.config = vscode.workspace.getConfiguration(CONFIG_KEY); Settings.onConfigChange((global?: any) => { @@ -59,10 +71,20 @@ export class Settings { callback(); }); + // Keep track of the listeners + Settings.listeners.push(callback); + + if (projectConfig && !existsSync(projectConfig)) { + // No config file, no need to watch + Settings.createFileCreationWatcher(); + return; + } + // Background listener for when it is not a user interaction if (projectConfig && existsSync(projectConfig)) { let watcher = workspace.createFileSystemWatcher(projectConfig, true, false, true); watcher.onDidChange(async (uri: Uri) => { + Logger.info(`Config change detected - ${projectConfig} changed`); configDebouncer(() => callback(), 200); // callback() }); @@ -72,6 +94,8 @@ export class Settings { const filename = e.uri.fsPath; if (Settings.checkProjectConfig(filename)) { + Logger.info(`Config change detected - ${projectConfig} saved`); + const file = await workspace.openTextDocument(e.uri); if (file) { const fileContents = file.getText(); @@ -384,4 +408,35 @@ export class Settings { Settings.globalConfig = undefined; } } + + /** + * Create a file creation watcher + */ + private static createFileCreationWatcher() { + const ext = Extension.getInstance(); + + if (!Settings.fileCreationWatcher) { + Settings.fileCreationWatcher = workspace.createFileSystemWatcher(`**/*.json`, false, true, true); + Settings.fileCreationWatcher.onDidCreate(uri => { + if (parseWinPath(uri.fsPath) === parseWinPath(Settings.projectConfigPath)) { + Settings.rebindWatchers(); + // Stop listening to file creation events + Settings.fileCreationWatcher?.dispose(); + Settings.fileCreationWatcher = undefined; + } + }, null, ext.subscriptions); + } + } + + /** + * Rebind the configuration watchers + */ + private static rebindWatchers() { + Logger.info(`Rebinding ${this.listeners.length} listeners`); + + this.listeners.forEach(l => { + Settings.onConfigChange(l); + l(); + }); + } } \ No newline at end of file