diff --git a/CHANGELOG.md b/CHANGELOG.md index 8445c10..994b462 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## [1.18.0](https://github.com/nvim-java/nvim-java/compare/v1.17.0...v1.18.0) (2024-07-14) + + +### Features + +* add warning on not yet implemented client commands ([a889ff4](https://github.com/nvim-java/nvim-java/commit/a889ff4ab49774849bd647d136370fa1b69c70f8)) + ## [1.17.0](https://github.com/nvim-java/nvim-java/compare/v1.16.0...v1.17.0) (2024-07-13) diff --git a/README.md b/README.md index f856563..7a47211 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ Just install and start writing `public static void main(String[] args)`. - :white_check_mark: Organize Imports & Code Formatting - :white_check_mark: Running Tests - :white_check_mark: Run & Debug profiles -- :white_check_mark: Code Actions +- :white_check_mark: [Code Actions](https://github.com/nvim-java/nvim-java/wiki/Tips-&-Tricks#running-code-actions) ## :bulb: Why @@ -132,7 +132,6 @@ Yep! That's all :) - `JavaRefactorExtractConstant` - Create a constant from the value at cursor/selection - `JavaRefactorExtractMethod` - Create a method from the value at cursor/selection - `JavaRefactorExtractField` - Create a field from the value at cursor/selection -- `JavaRefactorConvertVariableToField` - Change a local variable to field ### Settings @@ -256,12 +255,6 @@ require('java').refactor.extract_method() require('java').refactor.extract_field() ``` -- `convert_variable_to_field` - Change a local variable to field - -```lua -require('java').refactor.convert_variable_to_field() -``` - ### Settings - `change_runtime` - Change the JDK version to another diff --git a/doc/nvim-java.txt b/doc/nvim-java.txt index 93ea986..e47b886 100644 --- a/doc/nvim-java.txt +++ b/doc/nvim-java.txt @@ -1,4 +1,4 @@ -*nvim-java.txt* For Neovim >= 0.9.4 Last change: 2024 July 13 +*nvim-java.txt* For Neovim >= 0.9.4 Last change: 2024 July 14 ============================================================================== Table of Contents *nvim-java-table-of-contents* @@ -42,7 +42,7 @@ FEATURES *nvim-java-features* - Organize Imports & Code Formatting - Running Tests - Run & Debug profiles -- Code Actions +- Code Actions WHY *nvim-java-why* @@ -155,7 +155,6 @@ REFACTOR ~ - `JavaRefactorExtractConstant` - Create a constant from the value at cursor/selection - `JavaRefactorExtractMethod` - Create a method from the value at cursor/selection - `JavaRefactorExtractField` - Create a field from the value at cursor/selection -- `JavaRefactorConvertVariableToField` - Change a local variable to field SETTINGS ~ @@ -283,12 +282,6 @@ REFACTOR ~ require('java').refactor.extract_field() < -- `convert_variable_to_field` - Change a local variable to field - ->lua - require('java').refactor.convert_variable_to_field() -< - SETTINGS ~ diff --git a/lua/java/api/refactor.lua b/lua/java/api/refactor.lua index 8ab3b95..87803c8 100644 --- a/lua/java/api/refactor.lua +++ b/lua/java/api/refactor.lua @@ -1,43 +1,39 @@ -local jdtls = require('java.utils.jdtls2') -local get_error_handler = require('java.handlers.error') - -local async = require('java-core.utils.async').sync - local M = {} function M.extract_variable() - M.extract('extractVariable') + M.run_code_action('refactor.extract.variable', 'extractVariable') end function M.extract_variable_all_occurrence() - M.extract('extractVariableAllOccurrence') + M.run_code_action('refactor.extract.variable', 'extractVariableAllOccurrence') end function M.extract_constant() - M.extract('extractConstant') + M.run_code_action('refactor.extract.constant') end function M.extract_method() - M.extract('extractMethod') + M.run_code_action('refactor.extract.function') end function M.extract_field() - M.extract('extractField') -end - -function M.convert_variable_to_field() - M.extract('convertVariableToField') + M.run_code_action('refactor.extract.field') end ----@param refactor_command jdtls.CodeActionCommand -function M.extract(refactor_command) - return async(function() - local RefactorCommands = require('java-refactor.refactor-commands') - local refactor_commands = RefactorCommands(jdtls()) - refactor_commands:refactor(refactor_command) - end) - .catch(get_error_handler('failed to refactor variable')) - .run() +---@private +---@param action_type string +---@param filter? string +function M.run_code_action(action_type, filter) + vim.lsp.buf.code_action({ + apply = true, + context = { + diagnostics = vim.lsp.diagnostic.get_line_diagnostics(0), + only = { action_type }, + }, + filter = filter and function(refactor) + return refactor.command.arguments[1] == filter + end or nil, + }) end return M diff --git a/lua/java/commands/init.lua b/lua/java/commands/init.lua index a5ad7fa..33485bf 100644 --- a/lua/java/commands/init.lua +++ b/lua/java/commands/init.lua @@ -1,4 +1,5 @@ local log = require('java.utils.log') +local notify = require('java-core.utils.notify') local M = {} @@ -23,174 +24,94 @@ id = vim.api.nvim_create_autocmd('LspAttach', { }) M.commands = { - - OPEN_BROWSER = 'vscode.open', - - OPEN_OUTPUT = 'java.open.output', - - SHOW_JAVA_REFERENCES = 'java.show.references', - - SHOW_JAVA_IMPLEMENTATIONS = 'java.show.implementations', - - SHOW_REFERENCES = 'editor.action.showReferences', - - GOTO_LOCATION = 'editor.action.goToLocations', - - MARKDOWN_API_RENDER = 'markdown.api.render', - - CONFIGURATION_UPDATE = 'java.projectConfiguration.update', - - IGNORE_INCOMPLETE_CLASSPATH = 'java.ignoreIncompleteClasspath', - - IGNORE_INCOMPLETE_CLASSPATH_HELP = 'java.ignoreIncompleteClasspath.help', - - RELOAD_WINDOW = 'workbench.action.reloadWindow', - - PROJECT_CONFIGURATION_STATUS = 'java.projectConfiguration.status', - - NULL_ANALYSIS_SET_MODE = 'java.compile.nullAnalysis.setMode', - + ADD_TO_SOURCEPATH = 'java.project.addToSourcePath', + ADD_TO_SOURCEPATH_CMD = 'java.project.addToSourcePath.command', + APPLY_REFACTORING_COMMAND = 'java.action.applyRefactoringCommand', APPLY_WORKSPACE_EDIT = 'java.apply.workspaceEdit', - - EXECUTE_WORKSPACE_COMMAND = 'java.execute.workspaceCommand', - - COMPILE_WORKSPACE = 'java.workspace.compile', - BUILD_PROJECT = 'java.project.build', - - OPEN_SERVER_LOG = 'java.open.serverLog', - - OPEN_SERVER_STDOUT_LOG = 'java.open.serverStdoutLog', - - OPEN_SERVER_STDERR_LOG = 'java.open.serverStderrLog', - - OPEN_CLIENT_LOG = 'java.open.clientLog', - - OPEN_LOGS = 'java.open.logs', - - OPEN_FORMATTER = 'java.open.formatter.settings', - - OPEN_FILE = 'java.open.file', - - CLEAN_WORKSPACE = 'java.clean.workspace', - - UPDATE_SOURCE_ATTACHMENT_CMD = 'java.project.updateSourceAttachment.command', - UPDATE_SOURCE_ATTACHMENT = 'java.project.updateSourceAttachment', - - RESOLVE_SOURCE_ATTACHMENT = 'java.project.resolveSourceAttachment', - - ADD_TO_SOURCEPATH_CMD = 'java.project.addToSourcePath.command', - ADD_TO_SOURCEPATH = 'java.project.addToSourcePath', - - REMOVE_FROM_SOURCEPATH_CMD = 'java.project.removeFromSourcePath.command', - REMOVE_FROM_SOURCEPATH = 'java.project.removeFromSourcePath', - - LIST_SOURCEPATHS_CMD = 'java.project.listSourcePaths.command', - LIST_SOURCEPATHS = 'java.project.listSourcePaths', - - IMPORT_PROJECTS_CMD = 'java.project.import.command', - IMPORT_PROJECTS = 'java.project.import', + CHANGE_BASE_TYPE = 'java.action.changeBaseType', CHANGE_IMPORTED_PROJECTS = 'java.project.changeImportedProjects', - - OVERRIDE_METHODS_PROMPT = 'java.action.overrideMethodsPrompt', - - HASHCODE_EQUALS_PROMPT = 'java.action.hashCodeEqualsPrompt', - - OPEN_JSON_SETTINGS = 'workbench.action.openSettingsJson', - - ORGANIZE_IMPORTS = 'java.action.organizeImports', - - ORGANIZE_IMPORTS_SILENTLY = 'java.edit.organizeImports', - MANUAL_CLEANUP = 'java.action.doCleanup', - - HANDLE_PASTE_EVENT = 'java.edit.handlePasteEvent', - + CHOOSE_IMPORTS = 'java.action.organizeImports.chooseImports', + CLEAN_SHARED_INDEXES = 'java.clean.sharedIndexes', + CLEAN_WORKSPACE = 'java.clean.workspace', CLIPBOARD_ONPASTE = 'java.action.clipboardPasteAction', - + COMPILE_WORKSPACE = 'java.workspace.compile', + CONFIGURATION_UPDATE = 'java.projectConfiguration.update', + CREATE_MODULE_INFO = 'java.project.createModuleInfo', + CREATE_MODULE_INFO_COMMAND = 'java.project.createModuleInfo.command', + EXECUTE_WORKSPACE_COMMAND = 'java.execute.workspaceCommand', FILESEXPLORER_ONPASTE = 'java.action.filesExplorerPasteAction', - - CHOOSE_IMPORTS = 'java.action.organizeImports.chooseImports', - - GENERATE_TOSTRING_PROMPT = 'java.action.generateToStringPrompt', - GENERATE_ACCESSORS_PROMPT = 'java.action.generateAccessorsPrompt', - GENERATE_CONSTRUCTORS_PROMPT = 'java.action.generateConstructorsPrompt', - GENERATE_DELEGATE_METHODS_PROMPT = 'java.action.generateDelegateMethodsPrompt', - - APPLY_REFACTORING_COMMAND = 'java.action.applyRefactoringCommand', - - RENAME_COMMAND = 'java.action.rename', - - NAVIGATE_TO_SUPER_IMPLEMENTATION_COMMAND = 'java.action.navigateToSuperImplementation', - - SHOW_TYPE_HIERARCHY = 'java.action.showTypeHierarchy', - - SHOW_SUPERTYPE_HIERARCHY = 'java.action.showSupertypeHierarchy', - - SHOW_SUBTYPE_HIERARCHY = 'java.action.showSubtypeHierarchy', - - SHOW_CLASS_HIERARCHY = 'java.action.showClassHierarchy', - - CHANGE_BASE_TYPE = 'java.action.changeBaseType', - - OPEN_TYPE_HIERARCHY = 'java.navigate.openTypeHierarchy', - - RESOLVE_TYPE_HIERARCHY = 'java.navigate.resolveTypeHierarchy', - - SHOW_SERVER_TASK_STATUS = 'java.show.server.task.status', - - GET_PROJECT_SETTINGS = 'java.project.getSettings', - + GENERATE_TOSTRING_PROMPT = 'java.action.generateToStringPrompt', + GET_ALL_JAVA_PROJECTS = 'java.project.getAll', GET_CLASSPATHS = 'java.project.getClasspaths', - + GET_DECOMPILED_SOURCE = 'java.decompile', + GET_PROJECT_SETTINGS = 'java.project.getSettings', + GET_WORKSPACE_PATH = '_java.workspace.path', + GOTO_LOCATION = 'editor.action.goToLocations', + HANDLE_PASTE_EVENT = 'java.edit.handlePasteEvent', + HASHCODE_EQUALS_PROMPT = 'java.action.hashCodeEqualsPrompt', + IGNORE_INCOMPLETE_CLASSPATH = 'java.ignoreIncompleteClasspath', + IGNORE_INCOMPLETE_CLASSPATH_HELP = 'java.ignoreIncompleteClasspath.help', + IMPORT_PROJECTS = 'java.project.import', + IMPORT_PROJECTS_CMD = 'java.project.import.command', IS_TEST_FILE = 'java.project.isTestFile', - - GET_ALL_JAVA_PROJECTS = 'java.project.getAll', - - SWITCH_SERVER_MODE = 'java.server.mode.switch', - - RESTART_LANGUAGE_SERVER = 'java.server.restart', - - LEARN_MORE_ABOUT_REFACTORING = '_java.learnMoreAboutRefactorings', - LEARN_MORE_ABOUT_CLEAN_UPS = '_java.learnMoreAboutCleanUps', - - TEMPLATE_VARIABLES = '_java.templateVariables', - - NOT_COVERED_EXECUTION = '_java.notCoveredExecution', - - METADATA_FILES_GENERATION = '_java.metadataFilesGeneration', - - RUNTIME_VALIDATION_OPEN = 'java.runtimeValidation.open', - - RESOLVE_WORKSPACE_SYMBOL = 'java.project.resolveWorkspaceSymbol', - - GET_WORKSPACE_PATH = '_java.workspace.path', - - UPGRADE_GRADLE_WRAPPER_CMD = 'java.project.upgradeGradle.command', - UPGRADE_GRADLE_WRAPPER = 'java.project.upgradeGradle', - + LEARN_MORE_ABOUT_REFACTORING = '_java.learnMoreAboutRefactorings', + LIST_SOURCEPATHS = 'java.project.listSourcePaths', + LIST_SOURCEPATHS_CMD = 'java.project.listSourcePaths.command', LOMBOK_CONFIGURE = 'java.lombokConfigure', - - CREATE_MODULE_INFO = 'java.project.createModuleInfo', - - CREATE_MODULE_INFO_COMMAND = 'java.project.createModuleInfo.command', - + MANUAL_CLEANUP = 'java.action.doCleanup', + MARKDOWN_API_RENDER = 'markdown.api.render', + METADATA_FILES_GENERATION = '_java.metadataFilesGeneration', + NAVIGATE_TO_SUPER_IMPLEMENTATION_COMMAND = 'java.action.navigateToSuperImplementation', + NOT_COVERED_EXECUTION = '_java.notCoveredExecution', + NULL_ANALYSIS_SET_MODE = 'java.compile.nullAnalysis.setMode', + OPEN_BROWSER = 'vscode.open', + OPEN_CLIENT_LOG = 'java.open.clientLog', + OPEN_FILE = 'java.open.file', + OPEN_FORMATTER = 'java.open.formatter.settings', + OPEN_JSON_SETTINGS = 'workbench.action.openSettingsJson', + OPEN_LOGS = 'java.open.logs', + OPEN_OUTPUT = 'java.open.output', + OPEN_SERVER_LOG = 'java.open.serverLog', + OPEN_SERVER_STDERR_LOG = 'java.open.serverStderrLog', + OPEN_SERVER_STDOUT_LOG = 'java.open.serverStdoutLog', + OPEN_STATUS_SHORTCUT = '_java.openShortcuts', + OPEN_TYPE_HIERARCHY = 'java.navigate.openTypeHierarchy', + ORGANIZE_IMPORTS = 'java.action.organizeImports', + ORGANIZE_IMPORTS_SILENTLY = 'java.edit.organizeImports', + OVERRIDE_METHODS_PROMPT = 'java.action.overrideMethodsPrompt', + PROJECT_CONFIGURATION_STATUS = 'java.projectConfiguration.status', REFRESH_BUNDLES = 'java.reloadBundles', - REFRESH_BUNDLES_COMMAND = '_java.reloadBundles.command', - - CLEAN_SHARED_INDEXES = 'java.clean.sharedIndexes', - - GET_DECOMPILED_SOURCE = 'java.decompile', - - SMARTSEMICOLON_DETECTION = 'java.edit.smartSemicolonDetection', - + RELOAD_WINDOW = 'workbench.action.reloadWindow', + REMOVE_FROM_SOURCEPATH = 'java.project.removeFromSourcePath', + REMOVE_FROM_SOURCEPATH_CMD = 'java.project.removeFromSourcePath.command', + RENAME_COMMAND = 'java.action.rename', RESOLVE_PASTED_TEXT = 'java.project.resolveText', - - OPEN_STATUS_SHORTCUT = '_java.openShortcuts', + RESOLVE_SOURCE_ATTACHMENT = 'java.project.resolveSourceAttachment', + RESOLVE_TYPE_HIERARCHY = 'java.navigate.resolveTypeHierarchy', + RESOLVE_WORKSPACE_SYMBOL = 'java.project.resolveWorkspaceSymbol', + RESTART_LANGUAGE_SERVER = 'java.server.restart', + RUNTIME_VALIDATION_OPEN = 'java.runtimeValidation.open', + SHOW_CLASS_HIERARCHY = 'java.action.showClassHierarchy', + SHOW_JAVA_IMPLEMENTATIONS = 'java.show.implementations', + SHOW_JAVA_REFERENCES = 'java.show.references', + SHOW_REFERENCES = 'editor.action.showReferences', + SHOW_SERVER_TASK_STATUS = 'java.show.server.task.status', + SHOW_SUBTYPE_HIERARCHY = 'java.action.showSubtypeHierarchy', + SHOW_SUPERTYPE_HIERARCHY = 'java.action.showSupertypeHierarchy', + SHOW_TYPE_HIERARCHY = 'java.action.showTypeHierarchy', + SMARTSEMICOLON_DETECTION = 'java.edit.smartSemicolonDetection', + SWITCH_SERVER_MODE = 'java.server.mode.switch', + TEMPLATE_VARIABLES = '_java.templateVariables', + UPDATE_SOURCE_ATTACHMENT = 'java.project.updateSourceAttachment', + UPDATE_SOURCE_ATTACHMENT_CMD = 'java.project.updateSourceAttachment.command', + UPGRADE_GRADLE_WRAPPER = 'java.project.upgradeGradle', + UPGRADE_GRADLE_WRAPPER_CMD = 'java.project.upgradeGradle.command', } M.handlers = { @@ -205,3 +126,27 @@ M.handlers = { require('java.api.build').full_build_workspace(is_full_build) end, } + +local ignored_commands = { M.commands.REFRESH_BUNDLES_COMMAND } + +for _, command in pairs(M.commands) do + if + not M.handlers[command] and not vim.tbl_contains(ignored_commands, command) + then + local message = string.format( + '"%s" is not supported yet!' + .. '\nPlease request the feature using below link' + .. '\nhttps://github.com/nvim-java/nvim-java/issues/new?assignees=' + .. '&labels=enhancement&projects=&template=feature_request.yml&title=feature%%3A+', + command + ) + + M.handlers[command] = function() + notify.warn(message) + return vim.lsp.rpc_response_error( + vim.lsp.protocol.ErrorCodes.MethodNotFound, + 'Not implemented yes' + ) + end + end +end diff --git a/lua/java/runner/runner.lua b/lua/java/runner/runner.lua index 6b0ddc4..8705ed2 100644 --- a/lua/java/runner/runner.lua +++ b/lua/java/runner/runner.lua @@ -103,7 +103,14 @@ end function Runner.select_dap_config(args) local dap = DapSetup(jdtls()) local dap_config_list = dap:get_dap_config() - local selected_dap_config = ui.select_from_dap_configs(dap_config_list) + + local selected_dap_config = ui.select( + 'Select the main class (module -> mainClass)', + dap_config_list, + function(config) + return config.name + end + ) if not selected_dap_config then return nil, nil diff --git a/lua/java/ui/profile.lua b/lua/java/ui/profile.lua index 023a3a9..54bb1ac 100644 --- a/lua/java/ui/profile.lua +++ b/lua/java/ui/profile.lua @@ -357,11 +357,25 @@ M.ProfileUI = ProfileUI function M.ui() return async(function() - local dap_config = DapSetup(jdtls().client):get_dap_config() - local selected_config = ui.select_from_dap_configs(dap_config) + local configs = DapSetup(jdtls().client):get_dap_config() + + if not configs or #configs == 0 then + notify.error('No classes with main methods are found') + return + end + + local selected_config = ui.select( + 'Select the main class (module -> mainClass)', + configs, + function(config) + return config.name + end + ) + if not selected_config then return end + M.profile_ui = ProfileUI(selected_config.name) return M.profile_ui:openMenu() end) diff --git a/lua/java/utils/ui.lua b/lua/java/utils/ui.lua index ece856e..d487775 100644 --- a/lua/java/utils/ui.lua +++ b/lua/java/utils/ui.lua @@ -1,5 +1,4 @@ local wait = require('async.waits.wait') -local notify = require('java-core.utils.notify') local List = require('java-core.utils.list') local M = {} @@ -9,9 +8,17 @@ local M = {} ---@param prompt string ---@param values T[] ---@param format_item? fun(item: T): string ----@return T -function M.select(prompt, values, format_item) +---@param opts? { return_one: boolean } +---@return T | nil +function M.select(prompt, values, format_item, opts) + opts = opts or { prompt_single = false } + return wait(function(callback) + if not opts.prompt_single and #values == 1 then + callback(values[1]) + return + end + vim.ui.select(values, { prompt = prompt, format_item = format_item, @@ -19,6 +26,12 @@ function M.select(prompt, values, format_item) end) end +---Async vim.ui.select function +---@generic T +---@param prompt string +---@param values T[] +---@param format_item? fun(item: T): string +---@return T[] | nil function M.multi_select(prompt, values, format_item) return wait(function(callback) local wrapped_items = List:new(values):map(function(item, index) @@ -72,33 +85,4 @@ function M.input(prompt) end) end ----@param configs table -function M.select_from_dap_configs(configs) - local config_names = {} - local config_lookup = {} - for _, config in ipairs(configs) do - if config.projectName then - local key = config.name - if config.extra_args then - key = key .. ' | ' .. config.extra_args - end - table.insert(config_names, key) - config_lookup[key] = config - end - end - - if #config_names == 0 then - notify.warn('Config not found') - return - end - - if #config_names == 1 then - return config_lookup[config_names[1]] - end - - local selected_config = - M.select('Select the main class (modul -> mainClass)', config_names) - return config_lookup[selected_config] -end - return M diff --git a/plugin/java.lua b/plugin/java.lua index b6ac3f7..1357c32 100644 --- a/plugin/java.lua +++ b/plugin/java.lua @@ -50,11 +50,6 @@ local cmd_map = { java.refactor.extract_field, { range = 2 }, }, - - JavaRefactorConvertVariableToField = { - java.refactor.convert_variable_to_field, - { range = 2 }, - }, } for cmd, details in pairs(cmd_map) do