diff options
| author | Kyren223 <contact@kyren.codes> | 2026-06-22 01:30:43 +0300 |
|---|---|---|
| committer | Kyren223 <contact@kyren.codes> | 2026-06-22 01:30:43 +0300 |
| commit | 604addae2145f5823a2830927187489f5a79b92d (patch) | |
| tree | 2664321e35347605a5751fef0c6a2262e9f4664c | |
| parent | 48b2a7d4a56784f3695a92c274be9ae3a034ee4b (diff) | |
Add java and kotlin config
| -rw-r--r-- | .config/nvim/after/ftplugin/java.lua | 5 | ||||
| -rw-r--r-- | .config/nvim/after/ftplugin/kotlin.lua | 5 | ||||
| -rw-r--r-- | .config/nvim/lua/extra.lua | 165 | ||||
| -rw-r--r-- | .config/nvim/lua/lsp.lua | 2 | ||||
| -rw-r--r-- | .config/nvim/lua/plugins/nvim-jdtls.lua | 73 | ||||
| -rw-r--r-- | .config/nvim/lua/plugins/nvim-treesitter.lua | 1 | ||||
| -rw-r--r-- | .zshrc | 1 |
7 files changed, 174 insertions, 78 deletions
diff --git a/.config/nvim/after/ftplugin/java.lua b/.config/nvim/after/ftplugin/java.lua new file mode 100644 index 0000000..7c0f925 --- /dev/null +++ b/.config/nvim/after/ftplugin/java.lua @@ -0,0 +1,5 @@ +Event = 'VeryLazy' + +vim.opt_local.tabstop = 4 -- number of visual spaces per TAB +vim.opt_local.softtabstop = 4 -- number of idfk tab when editing +vim.opt_local.shiftwidth = 4 -- number of spaces to insert on tab diff --git a/.config/nvim/after/ftplugin/kotlin.lua b/.config/nvim/after/ftplugin/kotlin.lua new file mode 100644 index 0000000..7c0f925 --- /dev/null +++ b/.config/nvim/after/ftplugin/kotlin.lua @@ -0,0 +1,5 @@ +Event = 'VeryLazy' + +vim.opt_local.tabstop = 4 -- number of visual spaces per TAB +vim.opt_local.softtabstop = 4 -- number of idfk tab when editing +vim.opt_local.shiftwidth = 4 -- number of spaces to insert on tab diff --git a/.config/nvim/lua/extra.lua b/.config/nvim/lua/extra.lua index a595ab8..34e23c9 100644 --- a/.config/nvim/lua/extra.lua +++ b/.config/nvim/lua/extra.lua @@ -810,94 +810,133 @@ vim.api.nvim_create_autocmd({ 'BufNewFile', 'BufEnter' }, { local nullaway_ns = vim.api.nvim_create_namespace('nullaway_diagnostics') -vim.api.nvim_create_autocmd('BufWritePost', { +-- TOGGLE: When true, isolates "[NullAway]" errors and strips the "[NullAway]" +-- tag prefix from the inline diagnostic text. +local strip_nullaway_prefix = true + +local debounce_timer = nil +local active_job_id = nil +local DEBOUNCE_MS = 800 + +vim.api.nvim_create_autocmd({ 'TextChanged', 'TextChangedI', 'BufEnter', 'BufWritePost' }, { pattern = '*.java', callback = function() - print('[NullAway] File saved. Spawning background build...') + -- vim.notify("[NullAway] Event triggered, managing build window...", vim.log.levels.DEBUG) local bufnr = vim.api.nvim_get_current_buf() local current_file = vim.api.nvim_buf_get_name(bufnr) local gradlew_search = vim.fs.find('gradlew', { upward = true, path = vim.fs.dirname(current_file) }) if #gradlew_search == 0 then - print('[NullAway Error] Could not find gradlew executable up the directory tree.') return end local gradlew_path = gradlew_search[1] local project_root = vim.fs.dirname(gradlew_path) - local diagnostics = {} - vim.fn.jobstart({ gradlew_path, 'compileJava', '--console=plain' }, { - cwd = project_root, - stdout_buffered = true, - stderr_buffered = true, + if debounce_timer then + debounce_timer:stop() + debounce_timer:close() + debounce_timer = nil + end - on_stderr = function(_, data) - if not data then - return + debounce_timer = vim.uv.new_timer() + debounce_timer:start( + DEBOUNCE_MS, + 0, + vim.schedule_wrap(function() + if active_job_id then + vim.fn.jobstop(active_job_id) + active_job_id = nil end - -- Use a standard counter loop so we can look ahead to find javac carets - for i = 1, #data do - local line = data[i] - if line:find('error: %[NullAway%]') then - local clean_line = line:match('^%s*(.*)') - if clean_line then - local path_and_line, msg = clean_line:match('^(.-):%s*error:%s*(.*)') - if path_and_line and msg then - local file_path, lnum_str = path_and_line:match('^(.*):(%d+)$') - if file_path and lnum_str then - if vim.fs.normalize(file_path) == vim.fs.normalize(current_file) then - local col = 0 - local end_col = nil + local diagnostics = {} - -- Look ahead up to 3 lines to grab the caret line (e.g., " ^") - for offset = 1, 3 do - local lookahead_line = data[i + offset] - if lookahead_line then - local indent = lookahead_line:match('^(%s*)%^') - if indent then - col = #indent -- Length of leading spaces equals the 0-indexed column + active_job_id = vim.fn.jobstart({ gradlew_path, 'compileJava', '--console=plain' }, { + cwd = project_root, + stdout_buffered = true, + stderr_buffered = true, - -- Smart Range: Extract the parameter text out of the message to calculate width - local param_token = msg:match("parameter '([^']+)'") - if param_token then - end_col = col + #param_token - end - break - end - end - end + on_stderr = function(_, data) + if not data then + return + end + + local function process_entry(index) + local line = data[index] + + if line:match('^%s') then + return + end + if not line:find('error: %[NullAway%]') then + return + end + + local file_path, lnum_str, msg = line:match('^(.-):(%d+):%s+error:%s+(.*)') + if not (file_path and lnum_str and msg) then + return + end + if vim.fs.normalize(file_path) ~= vim.fs.normalize(current_file) then + return + end + + -- Clean up the diagnostic string based on the toggle configuration + if strip_nullaway_prefix then + msg = msg:gsub('^%[NullAway%]%s*', '') + end - table.insert(diagnostics, { - lnum = tonumber(lnum_str) - 1, - col = col, - end_col = end_col, -- Neovim 0.11 will beautifully underline the exact token length - severity = vim.diagnostic.severity.ERROR, - message = msg, - source = 'NullAway', - }) + local col = 0 + local end_col = nil + + for offset = 1, 3 do + local lookahead = data[index + offset] + if lookahead then + local indent = lookahead:match('^(%s*)%^') + if indent then + col = #indent + local param_token = msg:match("parameter '([^']+)'") + if param_token then + end_col = col + #param_token + end + break end end end + + table.insert(diagnostics, { + lnum = tonumber(lnum_str) - 1, + col = col, + end_col = end_col, + severity = vim.diagnostic.severity.ERROR, + message = msg, + source = 'NullAway', + }) end - end - end - end, - on_exit = function(_, exit_code) - vim.schedule(function() - vim.diagnostic.reset(nullaway_ns, bufnr) - if #diagnostics > 0 then - vim.diagnostic.set(nullaway_ns, bufnr, diagnostics) - print('[NullAway] Build complete. Placed ' .. #diagnostics .. ' error(s) inline.') - else - print('[NullAway] Build complete (Exit ' .. exit_code .. '). No errors for this file.') - end - end) - end, - }) + for i = 1, #data do + process_entry(i) + end + end, + + on_exit = function(job_id, exit_code) + if job_id ~= active_job_id then + return + end + active_job_id = nil + + vim.schedule(function() + vim.diagnostic.reset(nullaway_ns, bufnr) + if #diagnostics > 0 then + vim.diagnostic.set(nullaway_ns, bufnr, diagnostics) + -- vim.notify("[NullAway] Live check placed " .. #diagnostics .. " error(s).", vim.log.levels.INFO) + else + -- vim.notify("[NullAway] Live check clean.", vim.log.levels.INFO) + end + end) + end, + }) + end) + ) end, }) diff --git a/.config/nvim/lua/lsp.lua b/.config/nvim/lua/lsp.lua index 7d65727..7556b18 100644 --- a/.config/nvim/lua/lsp.lua +++ b/.config/nvim/lua/lsp.lua @@ -5,6 +5,7 @@ return { clangd = true, gopls = true, jsonls = true, + kotlin_lsp = true, lemminx = true, -- xml lua_ls = true, markdown_oxide = true, @@ -23,7 +24,6 @@ return { -- mdx_analyzer = true, -- kotlin_language_server = true, - -- kotlin_lsp = false, -- TODO(kyren): delete these? -- gh_actions_ls = true, diff --git a/.config/nvim/lua/plugins/nvim-jdtls.lua b/.config/nvim/lua/plugins/nvim-jdtls.lua index 21a5fc4..c1f4962 100644 --- a/.config/nvim/lua/plugins/nvim-jdtls.lua +++ b/.config/nvim/lua/plugins/nvim-jdtls.lua @@ -1,19 +1,64 @@ return { 'mfussenegger/nvim-jdtls', ft = { 'java' }, - opts = { - cmd = { 'jdtls' }, - root_dir = vim.fs.dirname(vim.fs.find({ - '.git', - 'build.gradle', - 'build.gradle.kts', - 'build.xml', - 'pom.xml', - 'settings.gradle', - 'settings.gradle.kts', - }, { upward = true })[1]), - }, - config = function(_, opts) - require('jdtls').start_or_attach(opts) + dependencies = { 'Saghen/blink.cmp' }, + config = function() + local setup_jdtls = function() + local current_buf = vim.api.nvim_buf_get_name(0) + local root_file = vim.fs.find({ + '.git', + 'build.gradle', + 'build.gradle.kts', + 'build.xml', + 'pom.xml', + 'settings.gradle', + 'settings.gradle.kts', + }, { upward = true, path = current_buf })[1] + + local root_dir = root_file and vim.fs.dirname(root_file) or vim.fn.getcwd() + local project_name = vim.fn.fnamemodify(root_dir, ':p:h:t') + local workspace_dir = vim.fn.expand('~/.cache/jdtls-workspace/') .. project_name + + -- Safely mix standard blink capabilities with internal jdtls mappings + local lsp_capabilities = require('blink.cmp').get_lsp_capabilities() + + local opts = { + cmd = { 'jdtls', '-data', workspace_dir }, + root_dir = root_dir, + capabilities = lsp_capabilities, + + -- Extended capabilities must live here, NOT in the root capabilities key + init_options = { + extendedClientCapabilities = require('jdtls').extendedClientCapabilities, + }, + + settings = { + java = { + signatureHelp = { enabled = true }, + compile = { + nullAnalysis = { + mode = 'enabled', + nullable = { 'org.jspecify.annotations.Nullable' }, + nonnull = { 'org.jspecify.annotations.NonNull' }, + nonnullbydefault = { 'org.jspecify.annotations.NullMarked' }, + }, + }, + format = { enabled = true }, + errors = { + incompleteClasspath = 'warning', + }, + }, + }, + } + + require('jdtls').start_or_attach(opts) + end + + setup_jdtls() + + vim.api.nvim_create_autocmd('FileType', { + pattern = 'java', + callback = setup_jdtls, + }) end, } diff --git a/.config/nvim/lua/plugins/nvim-treesitter.lua b/.config/nvim/lua/plugins/nvim-treesitter.lua index 4301939..e79070d 100644 --- a/.config/nvim/lua/plugins/nvim-treesitter.lua +++ b/.config/nvim/lua/plugins/nvim-treesitter.lua @@ -46,6 +46,7 @@ return { 'jsdoc', 'json', 'jsonc', + 'kotlin', 'latex', 'linkerscript', 'lua', @@ -124,6 +124,7 @@ export PATH="$PATH:/opt/nvim-linux-x86_64/bin" export PATH="$PATH:/opt/lua-language-server-linux-x64/bin" export PATH="$PATH:/opt/zen" export PATH="$PATH:/opt/aseprite" +export PATH="$PATH:/opt/jdt-language-server-1.58.0/bin" export PATH="$PATH:$HOME/.local/bin" export PATH="$PATH:$HOME/.cargo/bin" |
