summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKyren223 <contact@kyren.codes>2026-06-22 01:36:33 +0300
committerKyren223 <contact@kyren.codes>2026-06-22 01:36:33 +0300
commit8b0a17b68d3dbd69caf469c611d7caf82edb71c9 (patch)
treee29be98d7c4542034aadbce66bd5064aa41d760a
parent416dce6b9ea46a570f0d3eeafd2650f0e5bb0ee5 (diff)
Problematic lsp hover shit
-rw-r--r--.config/nvim/lua/extra.lua3
-rw-r--r--.config/nvim/lua/keymaps.lua16
-rw-r--r--.config/nvim/lua/lsphover.lua216
-rw-r--r--.config/nvim/lua/plugins/noice.lua17
4 files changed, 247 insertions, 5 deletions
diff --git a/.config/nvim/lua/extra.lua b/.config/nvim/lua/extra.lua
index 34e23c9..1ec5d96 100644
--- a/.config/nvim/lua/extra.lua
+++ b/.config/nvim/lua/extra.lua
@@ -805,7 +805,7 @@ vim.api.nvim_create_autocmd({ 'BufNewFile', 'BufEnter' }, {
})
----------------------------------------------------------------------------
--- NOTE:
+-- NOTE: Show NullAway Jspecify diagnostics inside nvim
----------------------------------------------------------------------------
local nullaway_ns = vim.api.nvim_create_namespace('nullaway_diagnostics')
@@ -943,3 +943,4 @@ vim.api.nvim_create_autocmd({ 'TextChanged', 'TextChangedI', 'BufEnter', 'BufWri
----------------------------------------------------------------------------
-- NOTE:
----------------------------------------------------------------------------
+
diff --git a/.config/nvim/lua/keymaps.lua b/.config/nvim/lua/keymaps.lua
index 0c25603..258b89e 100644
--- a/.config/nvim/lua/keymaps.lua
+++ b/.config/nvim/lua/keymaps.lua
@@ -119,6 +119,22 @@ local keymaps = {
-- { 'n', '<leader>w', next_diagnostic(severity.WARN), { desc = 'Goto [W]arning' } },
-- { 'n', '<leader>W', prev_diagnostic(severity.WARN), { desc = 'Goto [W]arning (prev)' } },
{ 'n', '<leader>D', cursor_diagnostics, { desc = '[D]iagnostics under cursor' } },
+ -- MARK lsphover:
+ -- {
+ -- 'n',
+ -- 'K',
+ -- function()
+ -- vim.lsp.buf.hover({
+ -- border = 'rounded',
+ -- focusable = true,
+ -- relative = 'cursor',
+ -- wrap = true,
+ -- wrap_at = 120,
+ -- width = 120,
+ -- })
+ -- end,
+ -- { desc = '[D]iagnostics under cursor' },
+ -- },
}
local function set_keymaps(tbl, bufnr)
diff --git a/.config/nvim/lua/lsphover.lua b/.config/nvim/lua/lsphover.lua
new file mode 100644
index 0000000..02a6baf
--- /dev/null
+++ b/.config/nvim/lua/lsphover.lua
@@ -0,0 +1,216 @@
+-- vim.api.nvim_create_autocmd('FileType', {
+-- pattern = { 'markdown', 'noice' },
+-- callback = function()
+-- vim.opt_local.conceallevel = 2
+-- vim.opt_local.concealcursor = 'nc'
+-- end,
+-- })
+--
+-- vim.api.nvim_create_autocmd('FileType', {
+-- pattern = { 'noice', 'markdown' },
+-- callback = function(args)
+-- -- Target only floating windows
+-- if vim.api.nvim_win_get_config(0).relative == '' then
+-- return
+-- end
+--
+-- -- Bind 'gd' specifically inside the hover popup buffer
+-- vim.keymap.set('n', 'gd', function()
+-- -- Grab word under cursor in the popup
+-- local cword = vim.fn.expand('<cword>')
+-- local win_ids = vim.api.nvim_list_wins()
+--
+-- -- Find the main file window underneath the float
+-- for _, win in ipairs(win_ids) do
+-- if vim.api.nvim_win_get_config(win).relative == '' then
+-- -- Jump back to main source code window
+-- vim.api.nvim_set_current_win(win)
+-- -- Execute search/definition lookup based on the word extracted from the doc
+-- vim.cmd('lua vim.lsp.buf.definition()')
+-- -- Alternatively, just use lookups if it's a plain keyword:
+-- vim.fn.search(cword)
+-- break
+-- end
+-- end
+-- end, { buffer = args.buf, silent = true, desc = 'Follow Definition from Hover' })
+-- end,
+-- })
+
+-- local orig_convert = vim.lsp.util.convert_input_to_markdown_lines
+-- vim.lsp.util.convert_input_to_markdown_lines = function(input, contents)
+-- local lines = orig_convert(input, contents)
+--
+-- for i, line in ipairs(lines) do
+-- -- 1. Nuke the Markdown link syntax completely to solve the gap issue.
+-- -- Converts "[foo](https://...)" directly into "foo"
+-- line = line:gsub('%[([^%]]+)%]%([^%)]+%)', '%1')
+--
+-- -- 2. Clean up Java/Javadoc specific formatting if we are in a Java file
+-- if vim.bo.filetype == 'java' then
+-- line = line:gsub('<p>', ''):gsub('</p>', '')
+-- line = line:gsub('<br%s*/?>', '')
+-- line = line:gsub('@param%s+', '* **Param:** ')
+-- line = line:gsub('@return%s+', '* **Returns:** ')
+-- line = line:gsub('@throws%s+', '* **Throws:** ')
+-- line = line:gsub('%%{@link%s+([^}]+)%%}', '`%1`')
+-- end
+--
+-- lines[i] = line
+-- end
+--
+-- return lines
+-- end
+
+-- vim.defer_fn(function()
+-- vim.notify('DID IT')
+--
+-- local orig_convert = vim.lsp.util.convert_input_to_markdown_lines
+-- vim.lsp.util.convert_input_to_markdown_lines = function(input, contents)
+-- local lines = orig_convert(input, contents)
+--
+-- for i, line in ipairs(lines) do
+-- -- 1. Nuke the Markdown link syntax completely to solve the gap issue.
+-- -- Converts "[foo](https://...)" directly into "foo"
+-- line = line:gsub('%[([^%]]+)%]%([^%)]+%)', '%1')
+--
+-- -- 2. Clean up Java/Javadoc specific formatting if we are in a Java file
+-- if vim.bo.filetype == 'java' then
+-- line = line:gsub('<p>', ''):gsub('</p>', '')
+-- line = line:gsub('<br%s*/?>', '')
+-- line = line:gsub('@param%s+', '* **Param:** ')
+-- line = line:gsub('@return%s+', '* **Returns:** ')
+-- line = line:gsub('@throws%s+', '* **Throws:** ')
+-- line = line:gsub('%%{@link%s+([^}]+)%%}', '`%1`')
+-- end
+--
+-- lines[i] = line
+-- end
+--
+-- return lines
+-- end
+-- end, 1000)
+
+-- To handle window-local options like conceallevel and concealcursor,
+-- we need to hook into the buffer creation event for the LSP floating window.
+vim.api.nvim_create_autocmd('BufWinEnter', {
+ group = vim.api.nvim_create_augroup('LspHoverCustom', { clear = true }),
+ callback = function(args)
+ -- Check if the buffer is an LSP floating doc window (filetype is typically 'markdown')
+ if vim.bo[args.buf].filetype == 'markdown' then
+ -- Get the current window ID for the buffer that just entered
+ local win = vim.fn.bufwinid(args.buf)
+
+ -- Ensure it's a floating window before applying local settings
+ if win > -1 and vim.api.nvim_win_get_config(win).relative ~= '' then
+ -- Set your preferred conceal options
+ vim.wo[win].conceallevel = 2
+ vim.wo[win].concealcursor = 'n'
+ vim.wo[win].linebreak = true
+
+ if not vim.b[args.buf].padded then
+ vim.b[args.buf].padded = true -- Guard flag against infinite loops
+ local lines = { 'foo' }
+ vim.api.nvim_buf_set_lines(args.buf, 0, -1, false, lines)
+
+ -- local lines = vim.api.nvim_buf_get_lines(args.buf, 0, -1, false)
+ -- for i, line in ipairs(lines) do
+ -- lines[i] = ' ' .. line .. ' ' -- 2 spaces left, 2 spaces right
+ -- end
+ -- vim.api.nvim_buf_set_lines(args.buf, 0, -1, false, lines)
+ --
+ -- -- 3. Expand the window width by 4 so the text doesn't wrap awkwardly
+ -- local config = vim.api.nvim_win_get_config(win)
+ -- config.width = config.width + 4
+ -- vim.api.nvim_win_set_config(win, config)
+ end
+ end
+ end
+ end,
+})
+
+-- Helper function to perform your exact regex formatting
+local function clean_hover_text(text, ft)
+ if type(text) ~= 'string' then
+ return text
+ end
+
+ -- 1. Nuke Markdown links: "[foo](https://...)" -> "foo"
+ text = text:gsub('%[([^%]]+)%]%([^%)]+%)', '%1')
+
+ -- 2. Clean Java/Javadoc specific formatting safely
+ if ft == 'java' then
+ text = text:gsub('<p>', ''):gsub('</p>', '')
+ text = text:gsub('<br%s*/?>', '')
+ text = text:gsub('@param%s+', '* **Param:** ')
+ text = text:gsub('@return%s+', '* **Returns:** ')
+ text = text:gsub('@throws%s+', '* **Throws:** ')
+ text = text:gsub('%%{@link%s+([^}]+)%%}', '`%1`')
+ end
+ return text
+end
+
+-- Core interceptor logic
+local function intercept_hover_for_client(client)
+ -- Prevent double-wrapping the same client
+ if not client or client._hover_intercepted then
+ return
+ end
+ client._hover_intercepted = true
+
+ local orig_request = client.request
+
+ client.request = function(method, params, handler, bufnr)
+ if method == 'textDocument/hover' then
+ -- CRITICAL FIX: If Noice or Neovim passes a `nil` handler, they expect the system
+ -- to use the global fallback. We must resolve it exactly like Neovim does natively.
+ local resolved_handler = handler or client.handlers[method] or vim.lsp.handlers[method]
+
+ if resolved_handler then
+ local orig_handler = resolved_handler
+
+ -- Wrap the resolved handler to mutate the text payload before it reaches Noice
+ handler = function(err, result, ctx, config)
+ if result and result.contents then
+ local buf = bufnr or (ctx and ctx.bufnr) or vim.api.nvim_get_current_buf()
+ local ft = vim.api.nvim_get_option_value('filetype', { buf = buf })
+
+ local contents = result.contents
+ if type(contents) == 'table' and contents.value then
+ contents.value = clean_hover_text(contents.value, ft)
+ elseif type(contents) == 'string' then
+ result.contents = clean_hover_text(contents, ft)
+ elseif type(contents) == 'table' then
+ for i, item in ipairs(contents) do
+ if type(item) == 'string' then
+ contents[i] = clean_hover_text(item, ft)
+ elseif type(item) == 'table' and item.value then
+ item.value = clean_hover_text(item.value, ft)
+ end
+ end
+ end
+ end
+
+ -- Pass the sanitized text down the pipeline
+ return orig_handler(err, result, ctx, config)
+ end
+ end
+ end
+
+ return orig_request(method, params, handler, bufnr)
+ end
+end
+
+--- 1. Catch clients that are ALREADY attached (Fixes the race condition)
+local get_clients = vim.lsp.get_clients or vim.lsp.get_active_clients
+for _, client in ipairs(get_clients()) do
+ intercept_hover_for_client(client)
+end
+
+--- 2. Catch any future clients that attach later
+vim.api.nvim_create_autocmd('LspAttach', {
+ desc = 'Intercept raw LSP hover responses to format before Noice reads them',
+ callback = function(args)
+ local client = vim.lsp.get_client_by_id(args.data.client_id)
+ intercept_hover_for_client(client)
+ end,
+})
diff --git a/.config/nvim/lua/plugins/noice.lua b/.config/nvim/lua/plugins/noice.lua
index a9e08f4..3648b55 100644
--- a/.config/nvim/lua/plugins/noice.lua
+++ b/.config/nvim/lua/plugins/noice.lua
@@ -1,6 +1,8 @@
return {
'folke/noice.nvim',
event = 'VeryLazy',
+ -- lazy = false,
+ -- enabled = false,
opts = {
-- notify = { enabled = false },
lsp = {
@@ -8,13 +10,14 @@ return {
override = {
-- override markdown rendering so that **cmp** and other plugins use **Treesitter**
-- override the default lsp markdown formatter with Noice
- -- ['vim.lsp.util.convert_input_to_markdown_lines'] = true,
+ ['vim.lsp.util.convert_input_to_markdown_lines'] = true,
-- override the lsp markdown formatter with Noice
-- ['vim.lsp.util.stylize_markdown'] = true,
+ -- ['cmp.entry.get_documentation'] = true,
},
hover = {
---@type NoiceViewOptions
- enabled = true,
+ enabled = false,
silent = false, -- set to true to not show a message if hover is not available
view = nil, -- when nil, use defaults from documentation
opts = {}, -- merged with defaults from documentation
@@ -34,13 +37,16 @@ return {
-- defaults for hover and signature help
documentation = {
view = 'hover',
- ---@type NoiceViewOptions
+ --- @type NoiceViewOptions
opts = {
lang = 'markdown',
replace = true,
render = 'plain',
+ -- render = function(buf, notif, hl, config)
+ -- self:render(buf, { offset = offset, highlight = true, messages = messages })
+ -- end,
format = { '{message}' },
- win_options = { concealcursor = 'n', conceallevel = 3 },
+ win_options = { concealcursor = 'nvic', conceallevel = 3 },
},
},
},
@@ -108,4 +114,7 @@ return {
'MunifTanjim/nui.nvim',
'rcarriga/nvim-notify',
},
+ config = function(_, opts)
+ require('noice').setup(opts)
+ end,
}