Files
.dotfiles/.config/nvim/lua/config/maps.lua
Quinn b066ba917f Rework nvim-treesitter to use the "newer" variant.
I still am experiencing some minor issues, when it comes to comment
placement, and inconsitencies with jsonc, for instance.
However, there's only so much one can do.
2026-01-26 22:56:50 +01:00

109 lines
4.4 KiB
Lua

-- unmap arrow keys in non-insert modes
Map({ 'n', 'v' }, '<up>', '<nop>')
Map({ 'n', 'v' }, '<down>', '<nop>')
Map({ 'n', 'v' }, '<left>', '<nop>')
Map({ 'n', 'v' }, '<right>', '<nop>')
-- tab management / navigation
Map('n', '<c-t>', '<cmd>enew<cr>', { desc = 'create a new buffer' })
Map('n', '<tab>', '<cmd>bnext<cr>', { desc = 'move to next buffer' })
Map('n', '<s-tab>', '<cmd>bprevious<cr>', { desc = 'move to previous buffer' })
Map('n', '<c-w>', '<cmd>bd<cr>', { desc = 'close buffer' })
Map('n', '<c-f4>', '<cmd>bd<cr>', { desc = 'close buffer' })
-- for help exiting certain modes
Map({ 'n', 'i' }, '<esc>', '<cmd>nohlsearch<cr><esc>', { desc = 'cancel search highlighting and escape' })
Map('t', '<c-esc>', '<c-\\><c-n>', { desc = 'exit terminal mode' })
-- window management
Map('n', '<m-s>', '<cmd>wincmd s<cr>', { desc = 'horizontal split' })
Map('n', '<m-v>', '<cmd>wincmd v<cr>', { desc = 'vertical split' })
Map('n', '<c-h>', '<cmd>wincmd h<cr>', { desc = 'move focus to the left window' })
Map('n', '<c-l>', '<cmd>wincmd l<cr>', { desc = 'move focus to the right window' })
Map('n', '<c-j>', '<cmd>wincmd j<cr>', { desc = 'move focus to the lower window' })
Map('n', '<c-k>', '<cmd>wincmd k<cr>', { desc = 'move focus to the upper window' })
Map('n', '<m-H>', '<cmd>wincmd H<cr>', { desc = 'move window to left' })
Map('n', '<m-L>', '<cmd>wincmd L<cr>', { desc = 'move window to right' })
Map('n', '<m-K>', '<cmd>wincmd K<cr>', { desc = 'move window to top' })
Map('n', '<m-J>', '<cmd>wincmd J<cr>', { desc = 'move window to bottom' })
-- diagnostic / lsp key bindings
Map('n', 'K', vim.lsp.buf.hover, { desc = 'symbol hover' })
Map('n', '<F2>', vim.lsp.buf.rename, { desc = 'rename symbol' })
Map('n', '<leader>lm', vim.diagnostic.open_float, { desc = 'view line\'s diagnostic messages' })
Map('n', '<leader>q', vim.lsp.buf.code_action, { desc = 'view quickfix list' })
Map('n', 'gd', vim.lsp.buf.definition, { desc = "Go to the definition" })
Map('n', 'gr', vim.lsp.buf.references, { desc = "Go to the reference" })
-- smart tabulation
Map('i', '<tab>', function()
local _, col = unpack(vim.api.nvim_win_get_cursor(0)) -- get cursor position
local ln = vim.api.nvim_get_current_line():sub(1, col)
local isindent = ln:match('^%s*$')
local tabexpnd = vim.bo.expandtab
local tabwidth = vim.bo.shiftwidth > 0 and vim.bo.shiftwidth or vim.bo.tabstop
if not tabexpnd and isindent then
return '\t'
else -- Compute the amount of spaces needed for the line.
local i = col
while i >= 1 do
if ln:sub(i, i) == '\t' then break end
i = i - 1
end
local spaces = tabwidth - (col - i) % tabwidth
return string.rep(' ', spaces == 0 and tabwidth or spaces)
end
end, { expr = true, desc = "smart tabulation" })
-- set the keybind for appending in front of a comment, rather than behind.
Map('n', 'A', function()
local ts = vim.treesitter -- get reference to treesitter
local buf = vim.api.nvim_get_current_buf() -- get the current buffer id
local row, col = unpack(vim.api.nvim_win_get_cursor(0)) -- get cursor position
-- ensure the parser exists
local res = nil
repeat
-- get the parser
if not ts.language.get_lang(vim.bo[buf].filetype) then break end
local parser = ts.get_parser(buf, nil, { error = false })
if not parser then break end
-- query the buffer using the parser
local root = parser:parse()[1]:root()
local ok, dat = pcall(ts.query.parse, parser:lang(), [[(comment) @comment]])
if not ok or not dat then break end
-- set the result
res = { query = dat, root = root }
until true
-- check if we successfully made a query
if res then
-- loop through the captures from the query
for _, node in res.query:iter_captures(res.root, buf, row - 1, row) do
-- ensure the comment is on the same row as the cursor and after the cursor's column
local srow, scol, _, _ = node:range() -- extract the starting row and starting column
if srow ~= row - 1 or col >= scol then goto continue end
-- get the line text and remove trailing whitespace
local txt = vim.api.nvim_buf_get_lines(buf, srow, srow + 1, true)[1]:sub(0, scol)
txt = txt:gsub("%s*$", "")
local len = txt:len()
-- check if we found a match
if len > 0 then
vim.api.nvim_win_set_cursor(0, { row, len })
vim.cmd [[startinsert]]
return
end
::continue:: -- lua is stupid
end
end
-- no comment start was found, behave like normal (moves cursor to the end of the line)
vim.cmd [[startinsert!]]
end, { desc = 'append end of line' })