From 51e5d6f89aecdb5ab38b74c404d035cb53f49ca4 Mon Sep 17 00:00:00 2001 From: Sheng Chen Date: Thu, 21 Jul 2022 17:01:21 +0800 Subject: [PATCH] feat: Show reload button at editor title when there is reload required diagnostics Signed-off-by: Sheng Chen --- package.json | 17 +++++++++++ src/commands.ts | 2 ++ src/constants.ts | 6 ++++ src/extension.ts | 50 ++++++++++++++++++++++++++++++-- test/maven-suite/context.test.ts | 35 ++++++++++++++++++++++ 5 files changed, 107 insertions(+), 3 deletions(-) create mode 100644 test/maven-suite/context.test.ts diff --git a/package.json b/package.json index b57b73bf..afe4a27b 100644 --- a/package.json +++ b/package.json @@ -45,6 +45,12 @@ "./server/com.microsoft.jdtls.ext.core-0.20.0.jar" ], "commands": [ + { + "command": "java.project.reloadProjectFromActiveFile", + "title": "Reload Java Project", + "category": "Java", + "icon": "$(sync)" + }, { "command": "java.project.create", "title": "%contributes.commands.java.project.create%", @@ -282,6 +288,10 @@ } ], "commandPalette": [ + { + "command": "java.project.reloadProjectFromActiveFile", + "when": "false" + }, { "command": "java.view.package.exportJar", "when": "java:serverMode == Standard && !java:noJavaProjects" @@ -383,6 +393,13 @@ "group": "navigation@100" } ], + "editor/title": [ + { + "command": "java.project.reloadProjectFromActiveFile", + "when": "java:reloadProjectActive && javaLSReady", + "group": "navigation" + } + ], "editor/title/context": [ { "command": "java.view.package.revealInProjectExplorer", diff --git a/src/commands.ts b/src/commands.ts index bf090287..2ac6b232 100644 --- a/src/commands.ts +++ b/src/commands.ts @@ -64,6 +64,8 @@ export namespace Commands { export const JAVA_PROJECT_UPDATE = "java.project.update"; + export const JAVA_PROJECT_RELOAD_ALL = "java.project.reloadProjectFromActiveFile"; + export const JAVA_PROJECT_REBUILD = "java.project.rebuild"; export const JAVA_PROJECT_EXPLORER_FOCUS = "javaProjectExplorer.focus"; diff --git a/src/constants.ts b/src/constants.ts index 36b81729..349f6f08 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -6,6 +6,7 @@ export namespace Context { export const LANGUAGE_SUPPORT_INSTALLED: string = "java:languageSupportInstalled"; export const NO_JAVA_PROJECT: string = "java:noJavaProjects"; export const WORKSPACE_CONTAINS_BUILD_FILES: string = "java:workspaceContainsBuildFiles"; + export const RELOAD_PROJECT_ACTIVE: string = "java:reloadProjectActive"; } export namespace Explorer { @@ -31,3 +32,8 @@ export namespace Explorer { export namespace ExtensionName { export const JAVA_LANGUAGE_SUPPORT: string = "redhat.java"; } + +/** + * The files names for all the build files we support. + */ +export const buildFiles = ["pom.xml", "build.gradle", "settings.gradle", "build.gradle.kts", "settings.gradle.kts"]; diff --git a/src/extension.ts b/src/extension.ts index bc437ff9..656c0e69 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -1,11 +1,13 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. -import { commands, Extension, ExtensionContext, extensions, tasks, Uri, workspace } from "vscode"; -import { dispose as disposeTelemetryWrapper, initializeFromJsonFile, instrumentOperation, sendInfo } from "vscode-extension-telemetry-wrapper"; + +import * as path from "path"; +import { commands, Diagnostic, Extension, ExtensionContext, extensions, languages, tasks, TextDocument, TextEditor, Uri, window, workspace } from "vscode"; +import { dispose as disposeTelemetryWrapper, initializeFromJsonFile, instrumentOperation, instrumentOperationAsVsCodeCommand, sendInfo } from "vscode-extension-telemetry-wrapper"; import { Commands, contextManager } from "../extension.bundle"; import { BuildTaskProvider } from "./tasks/build/buildTaskProvider"; -import { Context, ExtensionName } from "./constants"; +import { buildFiles, Context, ExtensionName } from "./constants"; import { LibraryController } from "./controllers/libraryController"; import { ProjectController } from "./controllers/projectController"; import { init as initExpService } from "./ExperimentationService"; @@ -40,6 +42,28 @@ async function activateExtension(_operationId: string, context: ExtensionContext context.subscriptions.push(syncHandler); context.subscriptions.push(tasks.registerTaskProvider(ExportJarTaskProvider.exportJarType, new ExportJarTaskProvider())); context.subscriptions.push(tasks.registerTaskProvider(BuildTaskProvider.type, new BuildTaskProvider())); + + context.subscriptions.push(window.onDidChangeActiveTextEditor((e: TextEditor | undefined) => { + setContextForReloadProject(e?.document); + })); + context.subscriptions.push(languages.onDidChangeDiagnostics(() => { + setContextForReloadProject(window.activeTextEditor?.document); + })); + instrumentOperationAsVsCodeCommand(Commands.JAVA_PROJECT_RELOAD_ALL, (uri?: Uri) => { + if (!uri) { + const activeDocument = window.activeTextEditor?.document; + if (!activeDocument) { + return; + } + uri = activeDocument.uri; + } + + if (!buildFiles.includes(path.basename(uri.fsPath))) { + return; + } + + commands.executeCommand(Commands.JAVA_PROJECT_CONFIGURATION_UPDATE, uri); + }); } // this method is called when your extension is deactivated @@ -61,3 +85,23 @@ function addExtensionChangeListener(context: ExtensionContext): void { context.subscriptions.push(extensionChangeListener); } } + +/** + * Set the context value when reload diagnostic is detected for the active + * build file. + */ +function setContextForReloadProject(document: TextDocument | undefined): void { + if (!document || !buildFiles.includes(path.basename(document.fileName))) { + contextManager.setContextValue(Context.RELOAD_PROJECT_ACTIVE, false); + return; + } + + const diagnostics: Diagnostic[] = languages.getDiagnostics(document.uri); + for (const diagnostic of diagnostics) { + if (diagnostic.message.startsWith("The build file has been changed")) { + contextManager.setContextValue(Context.RELOAD_PROJECT_ACTIVE, true); + return; + } + } + contextManager.setContextValue(Context.RELOAD_PROJECT_ACTIVE, false); +} diff --git a/test/maven-suite/context.test.ts b/test/maven-suite/context.test.ts new file mode 100644 index 00000000..c0d8848a --- /dev/null +++ b/test/maven-suite/context.test.ts @@ -0,0 +1,35 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +import * as path from "path"; +import * as assert from "assert"; +import { Diagnostic, DiagnosticSeverity, languages, Position, Range, Uri, window } from "vscode"; +import { contextManager } from "../../extension.bundle"; +import { setupTestEnv, Uris } from "../shared"; +import { sleep } from "../util"; + +// tslint:disable: only-arrow-functions +suite("Context Manager Tests", () => { + + suiteSetup(setupTestEnv); + + test("Can set reload project context correctly", async function() { + assert.strictEqual(!!contextManager.getContextValue("java:reloadProjectActive"), false); + + const pomUri = Uri.file(path.join(Uris.MAVEN_PROJECT_NODE, "pom.xml")); + await window.showTextDocument(pomUri); + assert.strictEqual(!!contextManager.getContextValue("java:reloadProjectActive"), false); + + const collection = languages.createDiagnosticCollection("test-collection"); + collection.set(pomUri, [new Diagnostic( + new Range(new Position(0, 0), new Position(0, 0)), + "The build file has been changed and may need reload to make it effective.", + DiagnosticSeverity.Information + )]); + await sleep(1000); + assert.strictEqual(!!contextManager.getContextValue("java:reloadProjectActive"), true); + + await window.showTextDocument(Uri.file(Uris.MAVEN_MAIN_CLASS)); + assert.strictEqual(!!contextManager.getContextValue("java:reloadProjectActive"), false); + }); +});