diff options
author | Squibid <me@zacharyscheiman.com> | 2025-04-17 11:41:32 -0500 |
---|---|---|
committer | Squibid <me@zacharyscheiman.com> | 2025-04-17 11:41:32 -0500 |
commit | 3094bf2a3983b375f4adeccd25c3b12bbbded2aa (patch) | |
tree | 860f0a9cfd3d83bf73837e2f3a0ccc1b0c75cf5b /lua/core | |
parent | 8eaa615596be321a3be12378c5e7d65cc7e482b6 (diff) | |
download | nvim-3094bf2a3983b375f4adeccd25c3b12bbbded2aa.tar.gz nvim-3094bf2a3983b375f4adeccd25c3b12bbbded2aa.tar.bz2 nvim-3094bf2a3983b375f4adeccd25c3b12bbbded2aa.zip |
a lot more stuff
Diffstat (limited to '')
-rw-r--r-- | lua/core/folding.lua | 120 | ||||
-rw-r--r-- | lua/core/lsp/functions.lua | 157 | ||||
-rw-r--r-- | lua/core/misc.lua | 60 |
3 files changed, 254 insertions, 83 deletions
diff --git a/lua/core/folding.lua b/lua/core/folding.lua new file mode 100644 index 0000000..37b5d78 --- /dev/null +++ b/lua/core/folding.lua @@ -0,0 +1,120 @@ +--- Stolen from: https://github.com/Wansmer/nvim-config/blob/main/lua/modules/foldtext.lua +--- modified for my use +--- +---@module Foldtext +---Based on https://www.reddit.com/r/neovim/comments/16sqyjz/finally_we_can_have_highlighted_folds/ +---Updated with vim.treesitter._fold.foldtext() + + +local function parse_line(linenr) + local bufnr = vim.api.nvim_get_current_buf() + + local line = vim.api.nvim_buf_get_lines(bufnr, linenr - 1, linenr, false)[1] + if not line then + return nil + end + + local ok, parser = pcall(vim.treesitter.get_parser, bufnr) + if not ok then + return nil + end + + local query = vim.treesitter.query.get(parser:lang(), "highlights") + if not query then + return nil + end + + local tree = parser:parse({ linenr - 1, linenr })[1] + local result = {} + local line_pos = 0 + + for id, node, metadata in query:iter_captures(tree:root(), 0, linenr - 1, linenr) do + local name = query.captures[id] + local start_row, start_col, end_row, end_col = node:range() + + local priority = tonumber(metadata.priority or vim.highlight.priorities.treesitter) + + if start_row == linenr - 1 and end_row == linenr - 1 then + -- check for characters ignored by treesitter + if start_col > line_pos then + table.insert(result, { + line:sub(line_pos + 1, start_col), + { { "Folded", priority } }, + range = { line_pos, start_col }, + }) + end + line_pos = end_col + + local text = line:sub(start_col + 1, end_col) + table.insert(result, { text, { { "@" .. name, priority } }, range = { start_col, end_col } }) + end + end + + local i = 1 + while i <= #result do + -- find first capture that is not in current range and apply highlights on the way + local j = i + 1 + while j <= #result and result[j].range[1] >= result[i].range[1] and result[j].range[2] <= result[i].range[2] do + for k, v in ipairs(result[i][2]) do + if not vim.tbl_contains(result[j][2], v) then + table.insert(result[j][2], k, v) + end + end + j = j + 1 + end + + -- remove the parent capture if it is split into children + if j > i + 1 then + table.remove(result, i) + else + -- highlights need to be sorted by priority, on equal prio, the deeper nested capture (earlier + -- in list) should be considered higher prio + if #result[i][2] > 1 then + table.sort(result[i][2], function(a, b) + return a[2] < b[2] + end) + end + + result[i][2] = vim.tbl_map(function(tbl) + return tbl[1] + end, result[i][2]) + result[i] = { result[i][1], result[i][2] } + + i = i + 1 + end + end + + return result +end + +--- create a string of highlighted text for folds +---@return table|string +local function HighlightedFoldtext() + local result = parse_line(vim.v.foldstart) + if not result then + return vim.fn.foldtext() + end + + table.insert(result, { + " ... ", + "LspCodeLens", + }) + + local result2 = parse_line(vim.v.foldend) + if result2 then + local first = result2[1] + result2[1] = { vim.trim(first[1]), first[2] } + for _, item in ipairs(result2) do + table.insert(result, item) + end + end + + table.insert(result, { + " "..(vim.v.foldend - vim.v.foldstart + 1).." Lines Folded ", + "LspCodeLens", + }) + + return result +end + +return HighlightedFoldtext diff --git a/lua/core/lsp/functions.lua b/lua/core/lsp/functions.lua index ab47ccc..4c27bca 100644 --- a/lua/core/lsp/functions.lua +++ b/lua/core/lsp/functions.lua @@ -1,90 +1,115 @@ local misc = require('core.misc') -local map = misc.map +local map, include = misc.map, misc.include local M = {} -function M.setup() - vim.diagnostic.config { - virtual_text = false, - virtual_lines = { - only_current_line = true, - }, - signs = true, - update_in_insert = false, - underline = true, - severity_sort = true - } - - vim.lsp.handlers['textDocument/hover'] = vim.lsp.with( - vim.lsp.handlers.hover, { border = 'solid' }) - - vim.lsp.handlers['textDocument/signatureHelp'] = vim.lsp.with( - vim.lsp.handlers.signature_help, { border = 'solid' }) - - for _, v in pairs({ - { "DiagnosticSignError", "x" }, - { "DiagnosticSignWarn", "!" }, - { "DiagnosticSignInfo", "i" }, - { "DiagnosticSignHint", "h" } - }) do - vim.fn.sign_define(v[1], { text = v[2], texthl = v[1] }) +local function on_list(options) + vim.fn.setqflist({}, 'r', options) + if #options.items > 1 then + vim.cmd.copen() end + vim.cmd("cc! 1") end ---- generate client capabilities for lsp servers ----@return table capabilities -function M.capabilities() - local capabilities = vim.lsp.protocol.make_client_capabilities() - capabilities.textDocument.completion.completionItem = { - snippetSupport = true, - preselectSupport = true, - insertReplaceSupport = true, - labelDetailsSupport = true, - deprecatedSupport = true, - commitCharactersSupport = true, - tagSupport = { - valueSet = { 1 } - }, - resolveSupport = { - properties = { - "documentation", - "detail", - "additionalTextEdits" - } - } - } - - return capabilities +local function _w(func) + return function() + func({ + border = "solid", + max_width = math.floor(vim.o.columns * 0.7), + }, { on_list = on_list }) + end end --- setup basic options on lsp attach ----@param client number client number ---@param bufnr number buffer number -function M.attach(client, bufnr) - local opts = { buffer = bufnr } +local function attach(bufnr) + local opts = { buffer = bufnr, nowait = true } + -- LSP actions - map('n', 'K', vim.lsp.buf.hover, opts) - map('n', 'gd', vim.lsp.buf.definition, opts) - map('n', 'gD', vim.lsp.buf.declaration) - map('n', 'gi', vim.lsp.buf.implementation, opts) - map('n', 'gy', vim.lsp.buf.type_definition, opts) - map('n', 'gr', vim.lsp.buf.references, opts) - map('n', '<S-Tab>', vim.lsp.buf.signature_help, opts) - map('n', '<leader>r', vim.lsp.buf.rename, opts) - map('n', '<F2>', vim.lsp.buf.rename, opts) - map('n', 'gA', vim.lsp.buf.code_action, { + map('n', 'K', _w(vim.lsp.buf.hover), opts) + map('n', 'gd', _w(vim.lsp.buf.definition), opts) + map('n', 'gD', _w(vim.lsp.buf.declaration), opts) + map('n', 'gi', _w(vim.lsp.buf.implementation), opts) + map('n', 'gy', _w(vim.lsp.buf.type_definition), opts) + map('n', 'gr', _w(vim.lsp.buf.references), opts) + map('n', '<S-Tab>', _w(vim.lsp.buf.signature_help), opts) + map('n', { '<leader>r', '<F2>' }, _w(vim.lsp.buf.rename), opts) + map('n', 'gA', _w(vim.lsp.buf.code_action), { buffer = bufnr, desc = 'check code actions', }) - map('n', '<F4>', vim.lsp.buf.code_action, { + map('n', '<F4>', _w(vim.lsp.buf.code_action), { buffer = bufnr, desc = 'check code actions' }) -- Diagnostics - map('n', '[d', vim.diagnostic.goto_prev, opts) - map('n', ']d', vim.diagnostic.goto_next, opts) + map('n', '[d', function() + if not vim.fn.has("nvim-0.11") then + vim.diagnostic.goto_prev() + else + vim.diagnostic.jump({ count = -1 }) + end + end, opts) + map('n', ']d', function() + if not vim.fn.has("nvim-0.11") then + vim.diagnostic.goto_next() + else + vim.diagnostic.jump({ count = 1 }) + end + end, opts) -- map('n', 'qD', vim.diagnostic.setqflist, opts) end +function M.setup() + vim.diagnostic.config { + virtual_text = false, + virtual_lines = { + only_current_line = true, + }, + update_in_insert = false, + underline = true, + severity_sort = true, + signs = { + text = { + [vim.diagnostic.severity.ERROR] = "x", + [vim.diagnostic.severity.WARN] = "!", + [vim.diagnostic.severity.INFO] = "i", + [vim.diagnostic.severity.HINT] = "h", + } + } + } + + if not vim.fn.has("nvim-0.11") then + vim.lsp.handlers['textDocument/hover'] = vim.lsp.with( + vim.lsp.handlers.hover, { border = 'solid' }) + + vim.lsp.handlers['textDocument/signatureHelp'] = vim.lsp.with( + vim.lsp.handlers.signature_help, { border = 'solid' }) + end + + -- set default capabilities + include('lspconfig.util').default_config.capabilities = M.capabilities + + -- run whenever a client attaches + vim.api.nvim_create_autocmd('LspAttach', { + callback = function(event) + -- map keybinds + attach(event.buf) + end + }) +end + +--- capabilities that are to be used in lsp servers, for those setup through +--- lspconfig, this is already set as the default. Incase there is a server +--- not setup through lspconfig this function may be called to receive the +--- proper capabilities data. +M.capabilities = vim.lsp.protocol.make_client_capabilities() + +--- add capabilities to the default capabilities string +---@param new_capabilities lsp.ClientCapabilities +function M.add_capabilities(new_capabilities) + vim.tbl_deep_extend('force', M.capabilities, new_capabilities) +end + return M diff --git a/lua/core/misc.lua b/lua/core/misc.lua index 5200c8b..5d0c0cf 100644 --- a/lua/core/misc.lua +++ b/lua/core/misc.lua @@ -29,10 +29,19 @@ end --- set colorscheme ---@param name string name of colorscheme function M.colorscheme(name) - vim.cmd.colorscheme(name) + -- only set the colorscheme if it exists + for _, v in pairs(vim.fn.getcompletion('', 'color')) do + if v == name then + vim.cmd("colorscheme "..name) + break + end + end + + -- override with any addons for _, v in pairs(vim.fn.getcompletion('', 'color')) do if v == name..'.ext' then - vim.cmd.colorscheme(name..'.ext') + vim.cmd("colorscheme"..name..'.ext') + break end end end @@ -41,12 +50,24 @@ end ---@param mode string|table mode for the keymap ---@param bind string|table keymap ---@param cmd function|string command to run ----@param opts table? keymap options +---@param opts vim.keymap.set.Opts? keymap options function M.map(mode, bind, cmd, opts) opts = opts or {} opts['noremap'] = true opts['silent'] = true + -- attempt to autogenerate a basic description + if not opts['desc'] then + if type(cmd) == "string" then + opts['desc'] = cmd:gsub("<%a+>", "") + elseif type(cmd) == "function" then + -- TODO: find a way to generate a better name + local file_name = vim.fn.fnamemodify(debug.getinfo(cmd, "S").short_src, ":t") + opts['desc'] = "origin@"..file_name + end + end + + -- define the keybinds if type(bind) == 'table' then for i in pairs(bind) do vim.keymap.set(mode, bind[i], cmd, opts) @@ -69,7 +90,7 @@ end --- extend vim.api.nvim_create_autocmd ---@param event string|table event or events ----@param opts table options +---@param opts vim.api.keyset.create_autocmd options function M.auto(event, opts) vim.api.nvim_create_autocmd(event, opts) end @@ -161,24 +182,29 @@ function M.timeout_highlight(opts) -- timer code was happily stolen from neovim/runtime/lua/vim/highlight.lua :) local timer, timer_cancel - - if timer then - timer:close() - assert(timer_cancel) - timer_cancel() + if not vim.fn.has("nvim-0.11") then + if timer then + timer:close() + assert(timer_cancel) + timer_cancel() + end end -- set the highlight - vim.highlight.range(0, namespaceid, opts.hl, opts.range[1], opts.range[2], {}) + vim.highlight.range(0, namespaceid, opts.hl, opts.range[1], opts.range[2], { + opts.timeout, + }) - timer_cancel = function() - timer = nil - timer_cancel = nil - pcall(vim.api.nvim_buf_clear_namespace, 0, namespaceid, 0, -1) - pcall(vim.api.nvim_win_remove_ns, 0, namespaceid) - end + if not vim.fn.has("nvim-0.11") then + timer_cancel = function() + timer = nil + timer_cancel = nil + pcall(vim.api.nvim_buf_clear_namespace, 0, namespaceid, 0, -1) + pcall(vim.api.nvim_win_remove_ns, 0, namespaceid) + end - timer = vim.defer_fn(timer_cancel, opts.timeout) + timer = vim.defer_fn(timer_cancel, opts.timeout) + end end return M |