summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKyren223 <contact@kyren.codes>2026-06-22 01:30:43 +0300
committerKyren223 <contact@kyren.codes>2026-06-22 01:30:43 +0300
commit604addae2145f5823a2830927187489f5a79b92d (patch)
tree2664321e35347605a5751fef0c6a2262e9f4664c
parent48b2a7d4a56784f3695a92c274be9ae3a034ee4b (diff)
Add java and kotlin config
-rw-r--r--.config/nvim/after/ftplugin/java.lua5
-rw-r--r--.config/nvim/after/ftplugin/kotlin.lua5
-rw-r--r--.config/nvim/lua/extra.lua165
-rw-r--r--.config/nvim/lua/lsp.lua2
-rw-r--r--.config/nvim/lua/plugins/nvim-jdtls.lua73
-rw-r--r--.config/nvim/lua/plugins/nvim-treesitter.lua1
-rw-r--r--.zshrc1
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',
diff --git a/.zshrc b/.zshrc
index 5cb41bc..f107c30 100644
--- a/.zshrc
+++ b/.zshrc
@@ -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"