diff --git a/package-lock.json b/package-lock.json index 602d7353..e7ef48d7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -25,6 +25,12 @@ "@types/node": "*" } }, + "@types/lodash": { + "version": "4.14.139", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.139.tgz", + "integrity": "sha512-Z6pbDYaWpluqcF8+6qgv6STPEl0jIlyQmpYGwTrzhgwqok8ltBh/p7GAmYnz81wUhxQRhEr8MBpQrB4fQ/hwIA==", + "dev": true + }, "@types/mocha": { "version": "5.2.5", "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-5.2.5.tgz", @@ -5274,6 +5280,11 @@ } } }, + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" + }, "lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", diff --git a/package.json b/package.json index 8104fb0a..3e171acf 100644 --- a/package.json +++ b/package.json @@ -104,6 +104,11 @@ "description": "%configuration.java.dependency.autoRefresh%", "default": true }, + "java.dependency.refreshDelay": { + "type": "number", + "description": "%configuration.java.dependency.refreshDelay%", + "default": 2000 + }, "java.dependency.packagePresentation": { "type": "string", "enum": [ @@ -167,6 +172,7 @@ ], "devDependencies": { "@types/fs-extra": "^5.0.4", + "@types/lodash": "^4.14.139", "@types/mocha": "^5.2.5", "@types/node": "^8.10.36", "@types/xml2js": "^0.4.3", @@ -186,6 +192,7 @@ "dependencies": { "find-java-home": "^0.2.0", "fs-extra": "^7.0.1", + "lodash": "^4.17.15", "vscode-extension-telemetry-wrapper": "^0.4.0", "xml2js": "^0.4.19" } diff --git a/package.nls.json b/package.nls.json index 8dabb906..a8bcd4a3 100644 --- a/package.nls.json +++ b/package.nls.json @@ -11,5 +11,6 @@ "configuration.java.dependency.showOutline": "Enable show outline in the Java Dependency explorer", "configuration.java.dependency.syncWithFolderExplorer": "Synchronize dependency viewer selection with folder explorer", "configuration.java.dependency.autoRefresh": "Synchronize dependency viewer with changes", + "configuration.java.dependency.refreshDelay": "The delay time (ms) the auto refresh is invoked when changes are detected.", "configuration.java.dependency.packagePresentation": "Package presentation mode: flat or hierarchical" } diff --git a/package.nls.zh.json b/package.nls.zh.json index 53a066d8..3c9c655a 100644 --- a/package.nls.zh.json +++ b/package.nls.zh.json @@ -11,5 +11,6 @@ "configuration.java.dependency.showOutline": "在 Java 依赖项资源管理器中显示类成员大纲", "configuration.java.dependency.syncWithFolderExplorer": "在 Java 依赖项资源管理器中同步关联当前打开的文件", "configuration.java.dependency.autoRefresh": "在 Java 依赖项资源管理器中自动同步修改", + "configuration.java.dependency.refreshDelay": "控制Java 依赖项资源管理器刷新的延迟时间 (毫秒)。", "configuration.java.dependency.packagePresentation": "Java 包显示方式: 平行显示或者分层显示" } diff --git a/src/fileWather.ts b/src/fileWather.ts index 373917d1..6623476e 100644 --- a/src/fileWather.ts +++ b/src/fileWather.ts @@ -45,6 +45,6 @@ export class SyncHandler { } private static refresh(): void { - commands.executeCommand(Commands.VIEW_PACKAGE_REFRESH); + commands.executeCommand(Commands.VIEW_PACKAGE_REFRESH, /* debounce = */true); } } diff --git a/src/settings.ts b/src/settings.ts index 0350dcf0..50e3b343 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -17,6 +17,9 @@ export class Settings { return; } const updatedConfig = workspace.getConfiguration("java.dependency"); + for (const listener of this._configurationListeners) { + listener(updatedConfig, this._dependencyConfig); + } if (updatedConfig.showOutline !== this._dependencyConfig.showOutline || updatedConfig.packagePresentation !== this._dependencyConfig.packagePresentation || (updatedConfig.syncWithFolderExplorer !== this._dependencyConfig.syncWithFolderExplorer @@ -32,6 +35,8 @@ export class Settings { })); SyncHandler.updateFileWatcher(Settings.autoRefresh()); + context.subscriptions.push({ dispose: () => { this._configurationListeners = []; } }); + context.subscriptions.push(commands.registerCommand(Commands.VIEW_PACKAGE_LINKWITHFOLDER, instrumentOperation(Commands.VIEW_PACKAGE_LINKWITHFOLDER, Settings.linkWithFolderCommand))); @@ -45,6 +50,10 @@ export class Settings { instrumentOperation(Commands.VIEW_PACKAGE_CHANGETOHIERARCHICALPACKAGEVIEW, Settings.changeToHierarchicalPackageView))); } + public static registerConfigurationListener(listener: Listener) { + this._configurationListeners.push(listener); + } + public static linkWithFolderCommand(): void { workspace.getConfiguration().update("java.dependency.syncWithFolderExplorer", true, false); } @@ -77,10 +86,18 @@ export class Settings { return this._dependencyConfig.get("packagePresentation") === PackagePresentation.Hierarchical; } + public static refreshDelay(): number { + return this._dependencyConfig.get("refreshDelay"); + } + private static _dependencyConfig: WorkspaceConfiguration = workspace.getConfiguration("java.dependency"); + + private static _configurationListeners: Listener[] = []; } enum PackagePresentation { Flat = "flat", Hierarchical = "hierarchical", } + +type Listener = (updatedConfig: WorkspaceConfiguration, dependencyConfig: WorkspaceConfiguration) => void; diff --git a/src/views/dependencyDataProvider.ts b/src/views/dependencyDataProvider.ts index b2848598..4857b651 100644 --- a/src/views/dependencyDataProvider.ts +++ b/src/views/dependencyDataProvider.ts @@ -1,6 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +import * as _ from "lodash"; import { commands, Event, EventEmitter, ExtensionContext, ProviderResult, Range, Selection, TextEditorRevealType, TreeDataProvider, TreeItem, Uri, window, workspace, @@ -23,26 +24,46 @@ export class DependencyDataProvider implements TreeDataProvider { public onDidChangeTreeData: Event = this._onDidChangeTreeData.event; private _rootItems: ExplorerNode[] = null; + private _refreshDelayTrigger: (() => void) & _.Cancelable; constructor(public readonly context: ExtensionContext) { - context.subscriptions.push(commands.registerCommand(Commands.VIEW_PACKAGE_REFRESH, () => this.refreshWithLog())); + context.subscriptions.push(commands.registerCommand(Commands.VIEW_PACKAGE_REFRESH, (debounce?: boolean) => this.refreshWithLog(debounce))); context.subscriptions.push(commands.registerCommand(Commands.VIEW_PACKAGE_OPEN_FILE, instrumentOperation(Commands.VIEW_PACKAGE_OPEN_FILE, (_operationId, uri) => this.openFile(uri)))); context.subscriptions.push(commands.registerCommand(Commands.VIEW_PACKAGE_OUTLINE, instrumentOperation(Commands.VIEW_PACKAGE_OUTLINE, (_operationId, uri, range) => this.goToOutline(uri, range)))); + Settings.registerConfigurationListener((updatedConfig, dependencyConfig) => { + if (updatedConfig.refreshDelay !== dependencyConfig.refreshDelay) { + this.setRefreshDelay(updatedConfig.refreshDelay); + } + }); + this.setRefreshDelay(); } - public refreshWithLog() { + public refreshWithLog(debounce?: boolean) { if (Settings.autoRefresh()) { - this.refresh(); + this.refresh(debounce); } else { - instrumentOperation(Commands.VIEW_PACKAGE_REFRESH, () => this.refresh())(); + instrumentOperation(Commands.VIEW_PACKAGE_REFRESH, () => this.refresh(debounce))(); } } - public refresh() { - this._rootItems = null; - this._onDidChangeTreeData.fire(); + public refresh(debounce = false) { + if (debounce) { + this._refreshDelayTrigger(); + } else { // Immediately refresh + this._refreshDelayTrigger.flush(); + } + } + + public setRefreshDelay(wait?: number) { + if (!wait) { + wait = Settings.refreshDelay(); + } + if (this._refreshDelayTrigger) { + this._refreshDelayTrigger.cancel(); + } + this._refreshDelayTrigger = _.debounce(() => this.doRefresh(), wait); } public openFile(uri: string) { @@ -83,6 +104,11 @@ export class DependencyDataProvider implements TreeDataProvider { return project ? project.revealPaths(paths) : null; } + private doRefresh(): void { + this._rootItems = null; + this._onDidChangeTreeData.fire(); + } + private async getRootProjects(): Promise { const rootElements = this._rootItems ? this._rootItems : await this.getChildren(); if (rootElements[0] instanceof ProjectNode) {