From bcae80e90e80f4e62dd4f8a46fdf7bfb5c76b611 Mon Sep 17 00:00:00 2001 From: Hope Hadfield Date: Fri, 22 Dec 2023 15:00:44 -0500 Subject: [PATCH] Add keybinding & setting to perform cleanup actions manually. Signed-off-by: Hope Hadfield --- README.md | 6 +++++- package.json | 46 ++++++++++++++++++++++++++++++++++++++++-- package.nls.json | 3 ++- package.nls.ko.json | 3 ++- package.nls.zh-cn.json | 3 ++- package.nls.zh-tw.json | 3 ++- src/commands.ts | 1 + src/protocol.ts | 6 +++++- src/sourceAction.ts | 35 +++++++++++++++++++++++++++++--- 9 files changed, 95 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 91ba932417..7e996aee84 100644 --- a/README.md +++ b/README.md @@ -219,7 +219,7 @@ The following settings are supported: * `java.completion.chain.enabled`: Enable/disable chain completion support. Defaults to `false`. * `java.completion.matchCase`: Specify whether to match case for code completion. Defaults to `firstLetter`. * `java.compile.nullAnalysis.mode`: Specify how to enable the annotation-based null analysis. Supported values are `disabled` (disable the null analysis), `interactive` (asks when null annotation types are detected), `automatic` (automatically enable null analysis when null annotation types are detected). Defaults to `interactive`. -* `java.cleanup.actionsOnSave`: The list of clean ups to be run on the current document when it's saved. Clean ups can automatically fix code style or programming mistakes. [Click here](document/_java.learnMoreAboutCleanUps.md#java-clean-ups) to learn more about what each clean up does. +* `java.cleanup.actionsOnSave`: **Deprecated, please use 'java.cleanup.actions' instead.** The list of clean ups to be run on the current document when it's saved. Clean ups can automatically fix code style or programming mistakes. [Click here](document/_java.learnMoreAboutCleanUps.md#java-clean-ups) to learn more about what each clean up does. * `java.import.gradle.annotationProcessing.enabled`: Enable/disable the annotation processing on Gradle projects and delegate to JDT APT. Only works for Gradle 5.2 or higher. * `java.sharedIndexes.enabled`: [Experimental] Specify whether to share indexes between different workspaces. Defaults to `auto` and the shared indexes is automatically enabled in Visual Studio Code - Insiders. - auto @@ -241,6 +241,10 @@ The following settings are supported: * `java.edit.smartSemicolonDetection.enabled`: Defines the `smart semicolon` detection. Defaults to `false`. * `java.configuration.detectJdksAtStart`: Automatically detect JDKs installed on local machine at startup. If you have specified the same JDK version in `java.configuration.runtimes`, the extension will use that version first. Defaults to `true`. +New in 1.28.0 +* `java.cleanup.actions`: The list of clean ups to be run on the current document when it's saved or when the cleanup command is issued. Clean ups can automatically fix code style or programming mistakes. [Click here](document/_java.learnMoreAboutCleanUps.md#java-clean-ups) to learn more about what each clean up does. +* `java.saveActions.cleanup`: Enable/disable cleanup actions on save. + Semantic Highlighting =============== [Semantic Highlighting](https://github.com/redhat-developer/vscode-java/wiki/Semantic-Highlighting) fixes numerous syntax highlighting issues with the default Java Textmate grammar. However, you might experience a few minor issues, particularly a delay when it kicks in, as it needs to be computed by the Java Language server, when opening a new file or when typing. Semantic highlighting can be disabled for all languages using the `editor.semanticHighlighting.enabled` setting, or for Java only using [language-specific editor settings](https://code.visualstudio.com/docs/getstarted/settings#_languagespecific-editor-settings). diff --git a/package.json b/package.json index ec559fe45b..309be1c460 100644 --- a/package.json +++ b/package.json @@ -1212,9 +1212,9 @@ "title": "Code Action", "order": 110, "properties": { - "java.cleanup.actionsOnSave": { + "java.cleanup.actions": { "type": "array", - "markdownDescription": "The list of clean ups to be run on the current document when it's saved. Clean ups can automatically fix code style or programming mistakes. Click [HERE](command:_java.learnMoreAboutCleanUps) to learn more about what each clean up does.", + "markdownDescription": "The list of clean ups to be run on the current document when it's saved or when the cleanup command is issued. Clean ups can automatically fix code style or programming mistakes. Click [HERE](command:_java.learnMoreAboutCleanUps) to learn more about what each clean up does.", "items": { "type": "string", "enum": [ @@ -1236,6 +1236,34 @@ "scope": "window", "order": 10 }, + "java.cleanup.actionsOnSave": { + "type": "array", + "deprecationMessage": "Deprecated, please use 'java.cleanup.actions' instead.", + "items": { + "type": "string", + "enum": [ + "qualifyMembers", + "qualifyStaticMembers", + "addOverride", + "addDeprecated", + "stringConcatToTextBlock", + "invertEquals", + "addFinalModifier", + "instanceofPatternMatch", + "lambdaExpressionFromAnonymousClass", + "lambdaExpression", + "switchExpression", + "tryWithResource" + ] + }, + "default": [], + "scope": "window" + }, + "java.saveActions.cleanup": { + "type": "boolean", + "default": true, + "description": "Enable/disable cleanup actions on save." + }, "java.saveActions.organizeImports": { "type": "boolean", "default": false, @@ -1560,6 +1588,11 @@ "command": "java.action.filesExplorerPasteAction", "title": "%java.action.filesExplorerPasteAction%", "category": "Java" + }, + { + "command": "java.action.doCleanup", + "title": "%java.action.doCleanup%", + "category": "Java" } ], "keybindings": [ @@ -1583,6 +1616,11 @@ "key": "ctrl+shift+v", "mac": "cmd+shift+v", "when": "explorerViewletFocus && config.editor.pasteAs.enabled" + }, + { + "command": "java.action.doCleanup", + "key": "ctrl+shift+alt+s", + "when": "javaLSReady && editorLangId == java" } ], "menus": { @@ -1705,6 +1743,10 @@ { "command": "java.action.filesExplorerPasteAction", "when": "false" + }, + { + "command": "java.action.doCleanup", + "when": "false" } ], "view/title": [ diff --git a/package.nls.json b/package.nls.json index ca4690b3bb..227404d82a 100644 --- a/package.nls.json +++ b/package.nls.json @@ -26,5 +26,6 @@ "java.clean.sharedIndexes": "Clean Shared Indexes", "java.server.restart": "Restart Java Language Server", "java.edit.smartSemicolonDetection": "Java Smart Semicolon Detection", - "java.action.filesExplorerPasteAction": "Paste clipboard text into a file" + "java.action.filesExplorerPasteAction": "Paste Clipboard Text Into a File", + "java.action.doCleanup": "Performs Cleanup Actions" } diff --git a/package.nls.ko.json b/package.nls.ko.json index 2e7214d928..ae20245ad6 100644 --- a/package.nls.ko.json +++ b/package.nls.ko.json @@ -23,5 +23,6 @@ "java.action.showSubtypeHierarchy": "Subtype 계층 구조 표시", "java.action.changeBaseType": "이 유형을 기준으로", "java.project.createModuleInfo.command": "module-info.java 생성", - "java.action.filesExplorerPasteAction": "클립보드 텍스트를 파일에 붙여넣기" + "java.action.filesExplorerPasteAction": "클립보드 텍스트를 파일에 붙여넣기", + "java.action.doCleanup": "정리 작업을 수행합니다" } diff --git a/package.nls.zh-cn.json b/package.nls.zh-cn.json index ebe40f3e8c..2526d4c36a 100644 --- a/package.nls.zh-cn.json +++ b/package.nls.zh-cn.json @@ -24,5 +24,6 @@ "java.action.changeBaseType": "基于此类型", "java.project.createModuleInfo.command": "创建 module-info.java", "java.clean.sharedIndexes": "清理共享的索引文件", - "java.action.filesExplorerPasteAction": "将剪贴板文本粘贴到文件中" + "java.action.filesExplorerPasteAction": "将剪贴板文本粘贴到文件中", + "java.action.doCleanup": "执行清理操作" } diff --git a/package.nls.zh-tw.json b/package.nls.zh-tw.json index 43ca820ce8..808fc1d97e 100644 --- a/package.nls.zh-tw.json +++ b/package.nls.zh-tw.json @@ -23,5 +23,6 @@ "java.action.showSubtypeHierarchy": "顯示子類別階層結構", "java.action.changeBaseType": "以此型別為基礎", "java.project.createModuleInfo.command": "創建 module-info.java", - "java.action.filesExplorerPasteAction": "將剪貼簿文字貼到文件中" + "java.action.filesExplorerPasteAction": "將剪貼簿文字貼到文件中", + "java.action.doCleanup": "執行清理操作" } \ No newline at end of file diff --git a/src/commands.ts b/src/commands.ts index ebf8eae3d1..8362f5045f 100644 --- a/src/commands.ts +++ b/src/commands.ts @@ -183,6 +183,7 @@ export namespace Commands { * Organize imports silently. */ export const ORGANIZE_IMPORTS_SILENTLY = "java.edit.organizeImports"; + export const MANUAL_CLEANUP = "java.action.doCleanup"; /** * Handle a paste event. */ diff --git a/src/protocol.ts b/src/protocol.ts index a8f6052392..1786286ab1 100644 --- a/src/protocol.ts +++ b/src/protocol.ts @@ -1,5 +1,6 @@ 'use strict'; +import { Command, Range } from 'vscode'; import { CodeActionParams, ExecuteCommandParams, @@ -13,7 +14,6 @@ import { WorkspaceEdit, WorkspaceSymbolParams, } from 'vscode-languageclient'; -import { Command, Range } from 'vscode'; /** * The message type. Copied from vscode protocol @@ -233,6 +233,10 @@ export namespace OrganizeImportsRequest { export const type = new RequestType('java/organizeImports'); } +export namespace CleanupRequest { + export const type = new RequestType('java/cleanup'); +} + export interface ImportCandidate { fullyQualifiedName: string; id: string; diff --git a/src/sourceAction.ts b/src/sourceAction.ts index c2acea150d..6cc7e1c396 100644 --- a/src/sourceAction.ts +++ b/src/sourceAction.ts @@ -1,17 +1,37 @@ 'use strict'; -import { commands, window, ExtensionContext, ViewColumn, Uri, Disposable, workspace, TextEditorRevealType } from 'vscode'; +import { Disposable, ExtensionContext, TextEditorRevealType, Uri, ViewColumn, commands, window, workspace } from 'vscode'; import { CodeActionParams, WorkspaceEdit } from 'vscode-languageclient'; import { LanguageClient } from 'vscode-languageclient/node'; import { Commands } from './commands'; -import { ListOverridableMethodsRequest, AddOverridableMethodsRequest, CheckHashCodeEqualsStatusRequest, GenerateHashCodeEqualsRequest, -OrganizeImportsRequest, ImportCandidate, ImportSelection, GenerateToStringRequest, CheckToStringStatusRequest, VariableBinding, GenerateAccessorsRequest, CheckConstructorStatusRequest, GenerateConstructorsRequest, CheckDelegateMethodsStatusRequest, GenerateDelegateMethodsRequest, AccessorKind, AccessorCodeActionRequest, AccessorCodeActionParams } from './protocol'; +import { + AccessorCodeActionParams, + AccessorCodeActionRequest, + AccessorKind, + AddOverridableMethodsRequest, + CheckConstructorStatusRequest, + CheckDelegateMethodsStatusRequest, + CheckHashCodeEqualsStatusRequest, + CheckToStringStatusRequest, + GenerateAccessorsRequest, + GenerateConstructorsRequest, + GenerateDelegateMethodsRequest, + GenerateHashCodeEqualsRequest, + GenerateToStringRequest, + ImportCandidate, ImportSelection, + ListOverridableMethodsRequest, + CleanupRequest, + OrganizeImportsRequest, + VariableBinding +} from './protocol'; import { applyWorkspaceEdit } from './standardLanguageClient'; +import { getActiveLanguageClient } from './extension'; export function registerCommands(languageClient: LanguageClient, context: ExtensionContext) { registerOverrideMethodsCommand(languageClient, context); registerHashCodeEqualsCommand(languageClient, context); registerOrganizeImportsCommand(languageClient, context); + registerCleanupCommand(languageClient, context); registerChooseImportCommand(context); registerGenerateToStringCommand(languageClient, context); registerGenerateAccessorsCommand(languageClient, context); @@ -67,6 +87,15 @@ function registerOverrideMethodsCommand(languageClient: LanguageClient, context: })); } +function registerCleanupCommand(languageClient: LanguageClient, context: ExtensionContext): void { + // Only active when editorLangId == java + context.subscriptions.push(commands.registerCommand(Commands.MANUAL_CLEANUP, async () => { + const languageClient: LanguageClient | undefined = await getActiveLanguageClient(); + const workspaceEdit = await languageClient.sendRequest(CleanupRequest.type, languageClient.code2ProtocolConverter.asTextDocumentIdentifier(window.activeTextEditor.document)); + await applyWorkspaceEdit(workspaceEdit, languageClient); + })); +} + function registerHashCodeEqualsCommand(languageClient: LanguageClient, context: ExtensionContext): void { context.subscriptions.push(commands.registerCommand(Commands.HASHCODE_EQUALS_PROMPT, async (params: CodeActionParams) => { const result = await languageClient.sendRequest(CheckHashCodeEqualsStatusRequest.type, params);