return { dir = "/Users/carlos/Documents/SSD_Documents/projects/intellij.nvim", dependencies = { "mfussenegger/nvim-jdtls", -- Java Language Server Protocol "mfussenegger/nvim-dap", -- Debug Adapter Protocol "rcarriga/nvim-dap-ui", -- DAP UI components "akinsho/toggleterm.nvim", -- Terminal integration "nvim-telescope/telescope.nvim", -- For command palette search }, config = function() require("intellij").setup({ -- Theme configuration theme = "inherit", -- or "light", "dark" -- Enable verbose logging for debugging verbose_logging = false, -- Automatically toggle auto-open main file on start auto_open_main_on_start = true, -- Custom actions for your workflow custom_actions = { { name = "Open Project in IntelliJ IDEA", action = function() vim.fn.system("idea .") vim.notify("Opening project in IntelliJ IDEA...") end }, { name = "Open in VS Code", action = function() vim.fn.system("code .") vim.notify("Opening project in VS Code...") end }, { name = "Git Status", action = function() require("toggleterm").exec("git status", 1, 12, "float") end }, { name = "Git Log", action = function() require("toggleterm").exec("git log --oneline -10", 1, 12, "float") end } }, -- Keymaps for quick access keymaps = { n = { ["jp"] = function() require('intellij').show_palette() end, ["jd"] = function() require('intellij').show_startup_diagnostics() end, ["jr"] = function() require('intellij').reload() end, ["jv"] = function() require('intellij').toggle_verbose_logging() end, }, v = { ["jt"] = function() local start_line = vim.fn.line("'<") local end_line = vim.fn.line("'>") require("toggleterm").exec("mvn test -Dtest=*#" .. start_line .. "_" .. end_line, 1, 12, "float") end } }, -- Project-specific commands based on project type project_commands = function(project_type) local commands = {} if project_type == "spring-boot" then table.insert(commands, { name = "Spring Boot DevTools", action = function() require("toggleterm").exec("mvn spring-boot:run -Dspring-boot.run.profiles=dev", 1, 12, "float") end }) table.insert(commands, { name = "Spring Boot Actuator Health", action = function() require("toggleterm").exec("curl -s http://localhost:8080/actuator/health | jq", 1, 12, "float") end }) end if project_type == "maven" then table.insert(commands, { name = "Maven Dependency Tree", action = function() require("toggleterm").exec("mvn dependency:tree", 1, 12, "float") end }) table.insert(commands, { name = "Maven Clean Install", action = function() require("toggleterm").exec("mvn clean install", 1, 12, "float") end }) end if project_type == "gradle" then table.insert(commands, { name = "Gradle Dependencies", action = function() require("toggleterm").exec("./gradlew dependencies", 1, 12, "float") end }) table.insert(commands, { name = "Gradle Clean Build", action = function() require("toggleterm").exec("./gradlew clean build", 1, 12, "float") end }) end return commands end }) -- Register hooks for additional functionality require("intellij").register_hook("actions", function(project_type) local hooks = {} -- Add recent files action table.insert(hooks, { name = "Recent Java Files", action = function() local recent_files = require("intellij").get_recent_java_files() if #recent_files > 0 then vim.ui.select(recent_files, { prompt = "Recent Java Files:" }, function(choice) if choice then local ok, _ = pcall(vim.cmd, "edit " .. choice) if not ok then vim.notify("Could not open file: " .. choice, vim.log.levels.WARN, { title = "intellij.nvim" }) end end end) else vim.notify("No recent Java files found") end end }) return hooks end) -- AUTOMATIC JAVA PROJECT DETECTION AND STARTUP local function find_main_java_files() local actions = require("intellij.actions") local configs = actions.get_run_configs() return configs and configs.mains or {} end local function is_main_file_open() local current_file = vim.api.nvim_buf_get_name(0) local main_files = find_main_java_files() for _, main_file in ipairs(main_files) do if current_file:match(main_file:gsub("%.", "/") .. "%.java$") then return true end end return false end local function open_first_main_file() local main_files = find_main_java_files() if #main_files > 0 then -- Try to find the main file in the project local project_root = vim.loop.cwd() local found_file = nil -- Debug: show what we're looking for vim.notify("Looking for main files: " .. table.concat(main_files, ", "), vim.log.levels.INFO, { title = "intellij.nvim" }) for _, main_class in ipairs(main_files) do local file_path if main_class:match("%.java$") then file_path = main_class:gsub("^%./", "") else file_path = main_class:gsub("%.", "/") .. ".java" end local possible_paths = { project_root .. "/" .. file_path, project_root .. "/src/main/java/" .. file_path, project_root .. "/src/java/" .. file_path, project_root .. "/src/" .. file_path, project_root .. "/app/src/main/java/" .. file_path, project_root .. "/main/java/" .. file_path, } for _, full_path in ipairs(possible_paths) do if vim.fn.filereadable(full_path) == 1 then found_file = full_path vim.notify("Found main file at: " .. full_path, vim.log.levels.INFO, { title = "intellij.nvim" }) break end end if found_file then break end end if found_file then local ok, _ = pcall(vim.cmd, "edit " .. found_file) if ok then vim.notify("Opened main file: " .. found_file, vim.log.levels.INFO, { title = "intellij.nvim" }) else vim.notify("Could not open main file: " .. found_file, vim.log.levels.WARN, { title = "intellij.nvim" }) end return true else -- Use telescope for better selection if available local function select_with_telescope(items, prompt, cb) local ok, telescope = pcall(require, 'telescope.builtin') if ok then telescope.find_files({ prompt_title = prompt, find_command = { 'echo', table.concat(items, '\n') }, attach_mappings = function(_, map) require('telescope.actions').select_default:replace(function() local entry = require('telescope.actions.state').get_selected_entry() cb(entry.value) require('telescope.actions').close(_) end) return true end, }) else vim.ui.select(items, { prompt = prompt }, cb) end end vim.notify("Could not automatically find main files. Showing selection dialog.", vim.log.levels.WARN, { title = "intellij.nvim" }) select_with_telescope(main_files, "Select main class to open:", function(choice) if choice then local file_path if choice:match("%.java$") then file_path = choice:gsub("^%./", "") else file_path = choice:gsub("%.", "/") .. ".java" end local possible_paths = { project_root .. "/" .. file_path, project_root .. "/src/main/java/" .. file_path, project_root .. "/src/java/" .. file_path, project_root .. "/src/" .. file_path, project_root .. "/app/src/main/java/" .. file_path, project_root .. "/main/java/" .. file_path, } local found = false for _, full_path in ipairs(possible_paths) do if vim.fn.filereadable(full_path) == 1 then local ok, _ = pcall(vim.cmd, "edit " .. full_path) if ok then vim.notify("Opened main file: " .. full_path, vim.log.levels.INFO, { title = "intellij.nvim" }) else vim.notify("Could not open main file: " .. full_path, vim.log.levels.WARN, { title = "intellij.nvim" }) end found = true break end end if not found then vim.notify("Could not find main file for: " .. choice .. "\nTried paths:\n" .. table.concat(possible_paths, "\n"), vim.log.levels.WARN, { title = "intellij.nvim" }) end end end) return true end else vim.notify("No main files found in project", vim.log.levels.WARN, { title = "intellij.nvim" }) end return false end local function detect_and_start_java_project() -- Prevent duplicate detection if vim.b.java_project_detected then return true end local actions = require("intellij.actions") local project_type = actions.detect_project_type() if project_type then -- Store project info in buffer variables vim.b.java_project_type = project_type vim.b.java_project_detected = true -- Get JDK and environment info local jdk_info = actions.get_jdk_info() local env_info = actions.get_env_info() -- Show project detection notification (only once) local jdk_version = jdk_info and jdk_info.jdk_version or "unknown" vim.notify( string.format("Java project detected: %s (JDK: %s)", project_type, jdk_version), vim.log.levels.INFO, { title = "intellij.nvim", timeout = 3000 } ) -- Auto-start Java LSP if available (only if not already started) if pcall(require, 'jdtls') and not vim.lsp.get_active_clients({ name = 'jdtls' })[1] then vim.defer_fn(function() -- Try to start LSP safely with error handling local ok, result = pcall(vim.cmd, "LspStart jdtls") if ok then vim.notify("Java LSP started", vim.log.levels.INFO, { title = "intellij.nvim" }) -- Add error handler for LSP semantic tokens issues vim.api.nvim_create_autocmd("LspAttach", { callback = function(args) local client = vim.lsp.get_client_by_id(args.data.client_id) if client and client.name == "jdtls" then -- Disable semantic tokens if they cause issues client.server_capabilities.semanticTokensProvider = nil end end, }) else vim.notify("Java LSP could not be started automatically", vim.log.levels.WARN, { title = "intellij.nvim" }) end end, 1000) end -- Auto-compile project on detection (optional) if vim.g.auto_compile_java_projects then vim.defer_fn(function() if project_type == "maven" then require("toggleterm").exec("mvn compile", 1, 12, "float") elseif project_type == "gradle" then require("toggleterm").exec("./gradlew compileJava", 1, 12, "float") end end, 2000) end -- Auto-open main file if not already open if vim.g.auto_open_main_file and not is_main_file_open() then vim.defer_fn(function() open_first_main_file() end, 1500) end return true end return false end -- Set up autocommands for automatic detection (with debouncing) local detection_timer = nil local function debounced_detection() if detection_timer then vim.loop.timer_stop(detection_timer) end detection_timer = vim.defer_fn(detect_and_start_java_project, 100) end vim.api.nvim_create_autocmd("FileType", { pattern = { "java" }, callback = function() -- Auto-detect project type when opening Java files debounced_detection() end }) -- Auto-detect when entering directories with Java project files vim.api.nvim_create_autocmd("DirChanged", { pattern = "*", callback = function() -- Check if we're in a Java project directory if vim.fn.filereadable("pom.xml") == 1 or vim.fn.filereadable("build.gradle") == 1 or vim.fn.filereadable("build.gradle.kts") == 1 then debounced_detection() end end }) -- Auto-detect when opening files in Java project directories vim.api.nvim_create_autocmd("BufRead", { pattern = "*", callback = function() local cwd = vim.loop.cwd() if cwd and (vim.fn.filereadable(cwd .. "/pom.xml") == 1 or vim.fn.filereadable(cwd .. "/build.gradle") == 1 or vim.fn.filereadable(cwd .. "/build.gradle.kts") == 1) then debounced_detection() end end }) -- Auto-detect when VimEnter (when Neovim starts) vim.api.nvim_create_autocmd("VimEnter", { pattern = "*", callback = function() -- Check if we started in a Java project directory local cwd = vim.loop.cwd() if cwd and (vim.fn.filereadable(cwd .. "/pom.xml") == 1 or vim.fn.filereadable(cwd .. "/build.gradle") == 1 or vim.fn.filereadable(cwd .. "/build.gradle.kts") == 1) then vim.defer_fn(detect_and_start_java_project, 500) end end }) -- Global variable to control auto-compilation vim.g.auto_compile_java_projects = true -- Global variable to control auto-opening main files vim.g.auto_open_main_file = true -- Add command to toggle auto-compilation vim.api.nvim_create_user_command("ToggleJavaAutoCompile", function() vim.g.auto_compile_java_projects = not vim.g.auto_compile_java_projects vim.notify( "Java auto-compilation " .. (vim.g.auto_compile_java_projects and "enabled" or "disabled"), vim.log.levels.INFO, { title = "intellij.nvim" } ) end, {}) -- Add command to clean up cache and temporary files vim.api.nvim_create_user_command("IntelliJCleanup", function() require("intellij").cleanup() end, {}) -- Add command to toggle auto-opening main files vim.api.nvim_create_user_command("ToggleJavaAutoOpenMain", function() vim.g.auto_open_main_file = not vim.g.auto_open_main_file vim.notify( "Java auto-open main file " .. (vim.g.auto_open_main_file and "enabled" or "disabled"), vim.log.levels.INFO, { title = "intellij.nvim" } ) end, {}) -- Add command to manually open main file vim.api.nvim_create_user_command("OpenJavaMainFile", function() if open_first_main_file() then vim.notify("Main file opened", vim.log.levels.INFO, { title = "intellij.nvim" }) else vim.notify("No main file found in current project", vim.log.levels.WARN, { title = "intellij.nvim" }) end end, {}) -- Add command to debug file search vim.api.nvim_create_user_command("DebugJavaFileSearch", function() local actions = require("intellij.actions") local configs = actions.get_run_configs() vim.notify("=== Java File Search Debug ===", vim.log.levels.INFO, { title = "intellij.nvim" }) vim.notify("Project root: " .. vim.loop.cwd(), vim.log.levels.INFO, { title = "intellij.nvim" }) if configs and configs.mains then vim.notify("Found main classes: " .. table.concat(configs.mains, ", "), vim.log.levels.INFO, { title = "intellij.nvim" }) for _, main_class in ipairs(configs.mains) do local file_path = main_class:gsub("%.", "/") .. ".java" local project_root = vim.loop.cwd() local possible_paths = { project_root .. "/src/main/java/" .. file_path, project_root .. "/src/java/" .. file_path, project_root .. "/src/" .. file_path, project_root .. "/" .. file_path, project_root .. "/app/src/main/java/" .. file_path, project_root .. "/main/java/" .. file_path, } vim.notify("Searching for: " .. main_class, vim.log.levels.INFO, { title = "intellij.nvim" }) for _, path in ipairs(possible_paths) do local exists = vim.fn.filereadable(path) == 1 vim.notify(" " .. path .. " -> " .. (exists and "EXISTS" or "NOT FOUND"), vim.log.levels.INFO, { title = "intellij.nvim" }) end end else vim.notify("No main classes found", vim.log.levels.WARN, { title = "intellij.nvim" }) end end, {}) -- Add command to manually detect Java project vim.api.nvim_create_user_command("DetectJavaProject", function() if detect_and_start_java_project() then vim.notify("Java project detection completed", vim.log.levels.INFO, { title = "intellij.nvim" }) else vim.notify("No Java project detected in current directory", vim.log.levels.WARN, { title = "intellij.nvim" }) end end, {}) -- Check for config flag to auto-toggle main file opening if type(require("intellij").opts) == "table" and require("intellij").opts.auto_open_main_on_start then vim.g.auto_open_main_file = true end end }