187 lines
6.7 KiB
Lua
187 lines
6.7 KiB
Lua
-- Non-plugin and global helper keymaps
|
|
--
|
|
-- NOTE: LSP keymaps are primarily handled in lua/plugins/lsp.lua via LspAttach.
|
|
-- Buffer-local keymaps set there take precedence over these global fallbacks.
|
|
--
|
|
-- These global keymaps provide fallback behavior for buffers without LSP attached,
|
|
-- ensuring that common navigation keys still work with built-in Vim functionality
|
|
-- (e.g., ctags, included files, man pages).
|
|
|
|
local map = vim.keymap.set
|
|
|
|
-- Fallback navigation keymaps for non-LSP buffers
|
|
-- When LSP attaches, buffer-local keymaps in lsp.lua override these
|
|
map('n', 'gd', function()
|
|
-- Built-in: jump to definition via tags or included files
|
|
vim.cmd("normal! gd")
|
|
end, { desc = 'Vim: Go to definition (built-in fallback)', silent = true })
|
|
|
|
map('n', 'gD', function()
|
|
-- Built-in: jump to declaration (global)
|
|
vim.cmd("normal! gD")
|
|
end, { desc = 'Vim: Go to declaration (built-in fallback)', silent = true })
|
|
|
|
-- LSP-only keymaps (no useful fallback for these in non-LSP contexts)
|
|
map('n', 'gr', '<Nop>', { desc = 'LSP: References (requires LSP)', silent = true })
|
|
map('n', 'gI', '<Nop>', { desc = 'LSP: Implementation (requires LSP)', silent = true })
|
|
|
|
-- K: Hover/Help with sensible fallback
|
|
map('n', 'K', function()
|
|
-- Built-in K uses 'keywordprg' (defaults to 'man' for shell scripts, etc.)
|
|
-- LSP buffers override this with vim.lsp.buf.hover() in lsp.lua
|
|
if vim.bo.keywordprg ~= '' then
|
|
vim.cmd("normal! K")
|
|
end
|
|
end, { desc = 'Vim: Hover/Help (keywordprg fallback)', silent = true })
|
|
|
|
-- Diagnostic keymaps
|
|
map('n', '<leader>xx', vim.diagnostic.setloclist, { desc = 'Diagnostics: Buffer diagnostics (location list)', silent = true })
|
|
map('n', '<leader>xX', vim.diagnostic.setqflist, { desc = 'Diagnostics: All diagnostics (quickfix)', silent = true })
|
|
map('n', '<leader>xe', function()
|
|
vim.diagnostic.setloclist({ severity = vim.diagnostic.severity.ERROR })
|
|
end, { desc = 'Diagnostics: Buffer errors (location list)', silent = true })
|
|
map('n', '<leader>xE', function()
|
|
vim.diagnostic.setqflist({ severity = vim.diagnostic.severity.ERROR })
|
|
end, { desc = 'Diagnostics: All errors (quickfix)', silent = true })
|
|
map('n', '[d', vim.diagnostic.goto_prev, { desc = 'Diagnostics: Previous diagnostic', silent = true })
|
|
map('n', ']d', vim.diagnostic.goto_next, { desc = 'Diagnostics: Next diagnostic', silent = true })
|
|
map('n', '<leader>xd', vim.diagnostic.open_float, { desc = 'Diagnostics: Show diagnostic under cursor', silent = true })
|
|
map('n', '<leader>xt', function()
|
|
vim.diagnostic.enable(not vim.diagnostic.is_enabled())
|
|
end, { desc = 'Diagnostics: Toggle display', silent = true })
|
|
|
|
-- Debug: Show highlight group and color under cursor
|
|
map('n', '<leader>hi', function()
|
|
local cursor_pos = vim.api.nvim_win_get_cursor(0)
|
|
local row, col = cursor_pos[1] - 1, cursor_pos[2]
|
|
|
|
-- Get all highlight groups at cursor position
|
|
local ts_hl = vim.treesitter.get_captures_at_pos(0, row, col)
|
|
local synID = vim.fn.synID(row + 1, col + 1, 1)
|
|
local synName = vim.fn.synIDattr(synID, 'name')
|
|
local synTrans = vim.fn.synIDattr(vim.fn.synIDtrans(synID), 'name')
|
|
|
|
-- Helper to resolve highlight links
|
|
local function resolve_hl(name)
|
|
local hl = vim.api.nvim_get_hl(0, { name = name })
|
|
local max_depth = 10
|
|
local depth = 0
|
|
while hl.link and depth < max_depth do
|
|
name = hl.link
|
|
hl = vim.api.nvim_get_hl(0, { name = name })
|
|
depth = depth + 1
|
|
end
|
|
return hl, name
|
|
end
|
|
|
|
local lines = {
|
|
'=== Highlight Info Under Cursor ===',
|
|
'',
|
|
'Position: row=' .. row .. ' col=' .. col,
|
|
'',
|
|
}
|
|
|
|
-- TreeSitter captures
|
|
if #ts_hl > 0 then
|
|
table.insert(lines, 'TreeSitter Captures:')
|
|
for _, capture in ipairs(ts_hl) do
|
|
local cap_name = '@' .. capture.capture
|
|
local hl, resolved_name = resolve_hl(cap_name)
|
|
|
|
table.insert(lines, string.format(' %s', cap_name))
|
|
if resolved_name ~= cap_name then
|
|
table.insert(lines, string.format(' → resolves to: %s', resolved_name))
|
|
end
|
|
if hl.fg then
|
|
table.insert(lines, string.format(' fg: #%06x', hl.fg))
|
|
end
|
|
if hl.bg then
|
|
table.insert(lines, string.format(' bg: #%06x', hl.bg))
|
|
end
|
|
|
|
local styles = {}
|
|
if hl.bold then table.insert(styles, 'bold') end
|
|
if hl.italic then table.insert(styles, 'italic') end
|
|
if hl.underline then table.insert(styles, 'underline') end
|
|
if #styles > 0 then
|
|
table.insert(lines, ' style: ' .. table.concat(styles, ', '))
|
|
end
|
|
end
|
|
table.insert(lines, '')
|
|
end
|
|
|
|
-- Syntax group
|
|
if synName ~= '' then
|
|
table.insert(lines, 'Syntax Group: ' .. synName)
|
|
if synTrans ~= synName and synTrans ~= '' then
|
|
table.insert(lines, 'Translates to: ' .. synTrans)
|
|
end
|
|
|
|
local hl, resolved_name = resolve_hl(synTrans ~= '' and synTrans or synName)
|
|
if hl.fg then
|
|
table.insert(lines, string.format(' fg: #%06x', hl.fg))
|
|
end
|
|
if hl.bg then
|
|
table.insert(lines, string.format(' bg: #%06x', hl.bg))
|
|
end
|
|
table.insert(lines, '')
|
|
end
|
|
|
|
-- Final applied highlight (use TreeSitter if available, otherwise syntax)
|
|
local final_hl_name = nil
|
|
if #ts_hl > 0 then
|
|
final_hl_name = '@' .. ts_hl[1].capture
|
|
elseif synTrans ~= '' then
|
|
final_hl_name = synTrans
|
|
elseif synName ~= '' then
|
|
final_hl_name = synName
|
|
end
|
|
|
|
if final_hl_name then
|
|
local final_hl, final_resolved = resolve_hl(final_hl_name)
|
|
table.insert(lines, 'Applied Highlight: ' .. final_resolved)
|
|
if final_hl.fg then
|
|
table.insert(lines, string.format(' fg: #%06x', final_hl.fg))
|
|
else
|
|
table.insert(lines, ' fg: NONE')
|
|
end
|
|
if final_hl.bg then
|
|
table.insert(lines, string.format(' bg: #%06x', final_hl.bg))
|
|
else
|
|
table.insert(lines, ' bg: NONE')
|
|
end
|
|
|
|
local styles = {}
|
|
if final_hl.bold then table.insert(styles, 'bold') end
|
|
if final_hl.italic then table.insert(styles, 'italic') end
|
|
if final_hl.underline then table.insert(styles, 'underline') end
|
|
if final_hl.undercurl then table.insert(styles, 'undercurl') end
|
|
if #styles > 0 then
|
|
table.insert(lines, ' style: ' .. table.concat(styles, ', '))
|
|
end
|
|
end
|
|
|
|
-- Show in a floating window
|
|
local buf = vim.api.nvim_create_buf(false, true)
|
|
vim.api.nvim_buf_set_lines(buf, 0, -1, false, lines)
|
|
|
|
local width = 0
|
|
for _, line in ipairs(lines) do
|
|
width = math.max(width, #line)
|
|
end
|
|
width = math.min(width + 2, vim.o.columns - 4)
|
|
|
|
local height = #lines
|
|
local opts = {
|
|
relative = 'cursor',
|
|
width = width,
|
|
height = height,
|
|
row = 1,
|
|
col = 0,
|
|
style = 'minimal',
|
|
border = 'rounded',
|
|
}
|
|
|
|
vim.api.nvim_open_win(buf, false, opts)
|
|
end, { desc = 'Debug: Show highlight group and color under cursor', silent = true })
|