diff options
author | Toby Vincent <tobyv13@gmail.com> | 2022-08-11 10:47:00 -0500 |
---|---|---|
committer | Toby Vincent <tobyv13@gmail.com> | 2022-08-11 10:47:00 -0500 |
commit | 81839b9079ffa5629e69d5362b5aea21b77cb868 (patch) | |
tree | b47c1ca0535c1c3f751c25764c2018d22156843c /nvim/.config | |
parent | 0e3004446824a4c923b5c494ff331dad2dc455d3 (diff) |
feat(nvim): impove workflow in rust and lua
Diffstat (limited to 'nvim/.config')
23 files changed, 627 insertions, 276 deletions
diff --git a/nvim/.config/nvim/lua/tobyvin/keymaps.lua b/nvim/.config/nvim/lua/tobyvin/keymaps.lua index aa9c8f3..1d88d82 100644 --- a/nvim/.config/nvim/lua/tobyvin/keymaps.lua +++ b/nvim/.config/nvim/lua/tobyvin/keymaps.lua @@ -1,13 +1,18 @@ local utils = require("tobyvin.utils") local M = {} +M.write = function() + vim.cmd("write") +end + M.setup = function() local nmap = utils.create_map_group("n", "<leader>") - nmap("q", utils.quit, { desc = "quit" }) - nmap("c", utils.bdelete, { desc = "close" }) - nmap("w", function() - vim.cmd("write") - end, { desc = "write" }) + nmap("q", utils.quit, { desc = "Quit" }) + nmap("c", utils.bdelete, { desc = "Close" }) + nmap("x", utils.tabclose, { desc = "Close" }) + nmap("h", utils.hover, { desc = "Hover" }) + nmap("H", utils.docs, { desc = "Docs" }) + nmap("w", M.write, { desc = "Write" }) end return M diff --git a/nvim/.config/nvim/lua/tobyvin/lsp/diagnostics.lua b/nvim/.config/nvim/lua/tobyvin/lsp/diagnostics.lua new file mode 100644 index 0000000..6b21ca2 --- /dev/null +++ b/nvim/.config/nvim/lua/tobyvin/lsp/diagnostics.lua @@ -0,0 +1,38 @@ +local utils = require("tobyvin.utils") +local M = {} + +M.on_attach = function(_, bufnr) + vim.api.nvim_create_autocmd("CursorHold", { + buffer = bufnr, + callback = function() + local opts = { + focusable = false, + close_events = { "BufLeave", "CursorMoved", "InsertEnter", "FocusLost" }, + border = "rounded", + source = "always", + prefix = " ", + scope = "cursor", + } + vim.diagnostic.open_float(nil, opts) + end, + }) +end + +M.setup = function() + vim.diagnostic.config({ + virtual_text = { + source = "if_many" + }, + signs = true, + underline = true, + update_in_insert = true, + severity_sort = true, + }) + + vim.fn.sign_define("DiagnosticSignError", utils.diagnostic_signs.error) + vim.fn.sign_define("DiagnosticSignWarn", utils.diagnostic_signs.warn) + vim.fn.sign_define("DiagnosticSignInfo", utils.diagnostic_signs.info) + vim.fn.sign_define("DiagnosticSignHint", utils.diagnostic_signs.hint) +end + +return M diff --git a/nvim/.config/nvim/lua/tobyvin/lsp/handlers.lua b/nvim/.config/nvim/lua/tobyvin/lsp/handlers.lua index 3d7d403..5adda44 100644 --- a/nvim/.config/nvim/lua/tobyvin/lsp/handlers.lua +++ b/nvim/.config/nvim/lua/tobyvin/lsp/handlers.lua @@ -1,3 +1,4 @@ +local utils = require("tobyvin.utils") local M = {} M.setup = function() @@ -14,9 +15,8 @@ M.setup = function() end end - vim.lsp.handlers["textDocument/publishDiagnostics"] = vim.lsp.with( - vim.lsp.handlers["textDocument/publishDiagnostics"], - { + vim.lsp.handlers["textDocument/publishDiagnostics"] = + vim.lsp.with(vim.lsp.handlers["textDocument/publishDiagnostics"], { signs = { severity_limit = "Error", }, @@ -25,67 +25,56 @@ M.setup = function() }, update_in_insert = true, virtual_text = true, - } - ) - - vim.lsp.handlers["$/progress"] = function(_, result, ctx) - local utils = require("tobyvin.lsp.utils") - local client_id = ctx.client_id - local val = result.value - - if not val.kind then - return - end - - local notif_data = utils.get_notif_data(client_id, result.token) - - if val.kind == "begin" then - local message = utils.format_message(val.message, val.percentage) - - notif_data.notification = vim.notify(message, "info", { - title = utils.format_title(val.title, vim.lsp.get_client_by_id(client_id).name), - icon = utils.spinner_frames[1], - timeout = false, - hide_from_history = false, - }) - - notif_data.spinner = 1 - utils.update_spinner(client_id, result.token) - elseif val.kind == "report" and notif_data then - notif_data.notification = vim.notify(utils.format_message(val.message, val.percentage), "info", { - replace = notif_data.notification, - hide_from_history = false, - }) - elseif val.kind == "end" and notif_data then - notif_data.notification = vim.notify( - val.message and utils.format_message(val.message) or "Complete", - "info", - { - icon = "", - replace = notif_data.notification, - timeout = 3000, - } - ) + }) - notif_data.spinner = nil - end - end + -- vim.lsp.handlers["$/progress"] = function(_, result, ctx) + -- local client_id = ctx.client_id + -- local val = result.value + -- if val.kind then + -- if not utils.client_notifs[client_id] then + -- utils.client_notifs[client_id] = {} + -- end + -- local notif_data = utils.client_notifs[client_id][result.token] + -- if val.kind == "begin" then + -- local message = utils.format_message(val.message, val.percentage) + -- local notification = vim.notify(message, "info", { + -- title = utils.format_title(val.title, vim.lsp.get_client_by_id(client_id)), + -- icon = utils.progress_signs.spinner.text[1], + -- timeout = false, + -- hide_from_history = false, + -- }) + -- utils.client_notifs[client_id][result.token] = { + -- notification = notification, + -- spinner = 1, + -- } + -- utils.update_spinner(client_id, result.token) + -- elseif val.kind == "report" and notif_data then + -- local new_notif = vim.notify( + -- utils.format_message(val.message, val.percentage), + -- "info", + -- { replace = notif_data.notification, hide_from_history = false } + -- ) + -- utils.client_notifs[client_id][result.token] = { + -- notification = new_notif, + -- spinner = notif_data.spinner, + -- } + -- elseif val.kind == "end" and notif_data then + -- local new_notif = vim.notify( + -- val.message and utils.format_message(val.message) or "Complete", + -- "info", + -- { icon = utils.progress_signs.complete.text, replace = notif_data.notification, timeout = 3000 } + -- ) + -- utils.client_notifs[client_id][result.token] = { + -- notification = new_notif, + -- } + -- end + -- end + -- end vim.lsp.handlers["window/showMessage"] = function(_, result, ctx) - local client = vim.lsp.get_client_by_id(ctx.client_id) - local lvl = ({ - "ERROR", - "WARN", - "INFO", - "DEBUG", - })[result.type] - - vim.notify({ result.message }, lvl, { - title = "LSP | " .. client.name, - timeout = 10000, - keep = function() - return lvl == "ERROR" or lvl == "WARN" - end, + vim.notify({ result.message }, 5 - result.type, { + title = "[LSP] " .. vim.lsp.get_client_by_id(ctx.client_id), + timeout = 2500, }) end end diff --git a/nvim/.config/nvim/lua/tobyvin/lsp/init.lua b/nvim/.config/nvim/lua/tobyvin/lsp/init.lua index cbe4f14..391ef3d 100644 --- a/nvim/.config/nvim/lua/tobyvin/lsp/init.lua +++ b/nvim/.config/nvim/lua/tobyvin/lsp/init.lua @@ -1,8 +1,11 @@ +local utils = require("tobyvin.utils") local M = {} M.on_attach = function(client, bufnr) + vim.api.nvim_buf_set_option(bufnr, "omnifunc", "v:lua.vim.lsp.omnifunc") + vim.keymap.set("n", "<C-Space>", vim.lsp.buf.code_action, { desc = "Code Action" }) - local nmap = require("tobyvin.utils").create_map_group("n", "<leader>l", { desc = "LSP", buffer = bufnr }) + local nmap = utils.create_map_group("n", "<leader>l", { desc = "LSP", buffer = bufnr }) nmap("a", vim.lsp.buf.code_action, { desc = "Code Action" }) nmap("d", "<cmd>TroubleToggle document_diagnostics<cr>", { desc = "Document Diagnostics" }) @@ -11,7 +14,6 @@ M.on_attach = function(client, bufnr) nmap("H", vim.lsp.buf.signature_help, { desc = "Signature Help" }) nmap("j", vim.diagnostic.goto_next, { desc = "Next Diagnostic" }) nmap("k", vim.diagnostic.goto_prev, { desc = "Prev Diagnostic" }) - nmap("l", vim.lsp.codelens.run, { desc = "CodeLens Action" }) nmap("o", "<cmd>SymbolsOutline<cr>", { desc = "Outline" }) -- nmap("q", vim.lsp.diagnostic.setloclist, { desc = "Quickfix" }) nmap("r", vim.lsp.buf.rename, { desc = "Rename" }) @@ -20,14 +22,19 @@ M.on_attach = function(client, bufnr) nmap("S", "<cmd>Telescope lsp_dynamic_workspace_symbols<cr>", { desc = "Workspace Symbols" }) nmap("w", "<cmd>Telescope lsp_workspace_diagnostics<cr>", { desc = "Workspace Diagnostics" }) - local nmap_goto = require("tobyvin.utils").create_map_group("n", "<leader>lg", { desc = "Goto", buffer = bufnr }) + local nmap_goto = utils.create_map_group("n", "<leader>lg", { desc = "Goto", buffer = bufnr }) nmap_goto("d", vim.lsp.buf.definition, { desc = "Definition" }) + nmap_goto("t", vim.lsp.buf.type_definition, { desc = "Type" }) nmap_goto("D", vim.lsp.buf.declaration, { desc = "Declaration" }) nmap_goto("i", vim.lsp.buf.implementation, { desc = "Implementation" }) nmap_goto("r", vim.lsp.buf.references, { desc = "References" }) + local nmap_tests = utils.create_map_group("n", "<leader>t", { desc = "Test", buffer = bufnr }) + nmap_tests("l", vim.lsp.codelens.run, { desc = "CodeLens Action" }) + -- disabled in favor of https://github.com/nvim-treesitter/nvim-treesitter-refactor#highlight-definitions -- require("tobyvin.lsp.highlighting").on_attach(client, bufnr) + require("tobyvin.lsp.diagnostics").on_attach(client, bufnr) require("tobyvin.lsp.formatting").on_attach(client, bufnr) require("tobyvin.lsp.symbol").on_attach(client, bufnr) require("lsp_signature").on_attach() @@ -46,6 +53,7 @@ end M.setup = function() require("tobyvin.lsp.handlers").setup() + require("tobyvin.lsp.diagnostics").setup() end return M diff --git a/nvim/.config/nvim/lua/tobyvin/lsp/utils.lua b/nvim/.config/nvim/lua/tobyvin/lsp/utils.lua index c56d657..5044d6f 100644 --- a/nvim/.config/nvim/lua/tobyvin/lsp/utils.lua +++ b/nvim/.config/nvim/lua/tobyvin/lsp/utils.lua @@ -1,44 +1,3 @@ local M = {} -M.spinner_frames = { "⣷", "⣯", "⣟", "⡿", "⢿", "⣻", "⣽", "⣾" } - -M.get_notif_data = function(client_id, token) - if not M.client_notifs[client_id] then - M.client_notifs[client_id] = {} - end - - if not M.client_notifs[client_id][token] then - M.client_notifs[client_id][token] = {} - end - - return M.client_notifs[client_id][token] -end - -M.update_spinner = function(client_id, token) - local notif_data = M.get_notif_data(client_id, token) - - if notif_data.spinner then - local new_spinner = (notif_data.spinner + 1) % #M.spinner_frames - notif_data.spinner = new_spinner - - notif_data.notification = vim.notify(nil, nil, { - hide_from_history = true, - icon = M.spinner_frames[new_spinner], - replace = notif_data.notification, - }) - - vim.defer_fn(function() - M.update_spinner(client_id, token) - end, 100) - end -end - -M.format_title = function(title, client_name) - return client_name .. (#title > 0 and ": " .. title or "") -end - -M.format_message = function(message, percentage) - return (percentage and percentage .. "%\t" or "") .. (message or "") -end - return M diff --git a/nvim/.config/nvim/lua/tobyvin/options.lua b/nvim/.config/nvim/lua/tobyvin/options.lua index 40bc9c5..aa69f93 100644 --- a/nvim/.config/nvim/lua/tobyvin/options.lua +++ b/nvim/.config/nvim/lua/tobyvin/options.lua @@ -1,14 +1,8 @@ -local utils = require("tobyvin.utils") local M = {} M.setup = function() vim.g.mapleader = " " - vim.fn.sign_define("DiagnosticSignError", utils.diagnostic_signs.error) - vim.fn.sign_define("DiagnosticSignWarn", utils.diagnostic_signs.warn) - vim.fn.sign_define("DiagnosticSignInfo", utils.diagnostic_signs.info) - vim.fn.sign_define("DiagnosticSignHint", utils.diagnostic_signs.hint) - vim.opt.termguicolors = true vim.opt.laststatus = 3 vim.opt.undofile = true diff --git a/nvim/.config/nvim/lua/tobyvin/plugins.lua b/nvim/.config/nvim/lua/tobyvin/plugins.lua index 31a685b..2d01be2 100644 --- a/nvim/.config/nvim/lua/tobyvin/plugins.lua +++ b/nvim/.config/nvim/lua/tobyvin/plugins.lua @@ -38,6 +38,7 @@ M.plugins = function(use) -- TODO: implement custom hls using base-16-gruvbox and remove this use({ "eddyekofo94/gruvbox-flat.nvim", + requires = { "xiyaowong/nvim-transparent" }, config = function() require("tobyvin.plugins.gruvbox-flat").setup() end, @@ -106,7 +107,7 @@ M.plugins = function(use) use({ "simrat39/rust-tools.nvim", after = "nvim-lspconfig", - branch = "modularize_and_inlay_rewrite", + -- branch = "modularize_and_inlay_rewrite", requires = { "neovim/nvim-lspconfig", }, @@ -222,7 +223,6 @@ M.plugins = function(use) "nvim-telescope/telescope-github.nvim", { "nvim-telescope/telescope-fzf-native.nvim", run = "make" }, { "nvim-telescope/telescope-smart-history.nvim", requires = { "tami5/sqlite.lua", module = "sqlite" } }, - { "nvim-telescope/telescope-frecency.nvim", requires = { "tami5/sqlite.lua", module = "sqlite" } }, }, config = function() require("tobyvin.plugins.telescope").setup() @@ -251,12 +251,16 @@ M.plugins = function(use) end, }) + -- TODO: revert once https://github.com/nvim-treesitter/nvim-treesitter-textobjects/pull/233 is merged + use("~/src/nvim-treesitter-textobjects") + use({ "nvim-treesitter/nvim-treesitter", run = ":TSUpdate", requires = { + "nvim-treesitter/playground", "nvim-treesitter/nvim-treesitter-refactor", - "nvim-treesitter/nvim-treesitter-textobjects", + "~/src/nvim-treesitter-textobjects", "nvim-treesitter/nvim-treesitter-context", "RRethy/nvim-treesitter-textsubjects", "JoosepAlviste/nvim-ts-context-commentstring", @@ -322,7 +326,6 @@ M.plugins = function(use) "nvim-lualine/lualine.nvim", requires = { "kyazdani42/nvim-web-devicons", - "arkav/lualine-lsp-progress", "SmiteshP/nvim-navic", }, config = function() @@ -331,6 +334,13 @@ M.plugins = function(use) }) use({ + "j-hui/fidget.nvim", + config = function() + require("tobyvin.plugins.fidget").setup() + end, + }) + + use({ "SmiteshP/nvim-navic", requires = "onsails/lspkind-nvim", config = function() @@ -415,7 +425,6 @@ M.plugins = function(use) use("nacro90/numb.nvim") use("ThePrimeagen/harpoon") use("b0o/SchemaStore.nvim") - use("windwp/nvim-spectre") use("ggandor/lightspeed.nvim") use({ @@ -440,13 +449,20 @@ M.plugins = function(use) }) use({ - "akinsho/nvim-bufferline.lua", - requires = "kyazdani42/nvim-web-devicons", + "tiagovla/scope.nvim", config = function() - require("tobyvin.plugins.bufferline").setup() + require("scope").setup() end, }) + -- use({ + -- "akinsho/nvim-bufferline.lua", + -- requires = "kyazdani42/nvim-web-devicons", + -- config = function() + -- require("tobyvin.plugins.bufferline").setup() + -- end, + -- }) + use("SmiteshP/nvim-gps") if PackerBootstrap then @@ -489,23 +505,23 @@ M.setup = function() }) -- TODO: either remove this or improve it to properly reload the file before syncing - local augroup_packer = vim.api.nvim_create_augroup("Packer", { clear = true }) - vim.api.nvim_create_autocmd("BufWritePost", { - group = augroup_packer, - pattern = "plugins.lua", - callback = function(args) - local dotfiles = vim.env.HOME .. "/.dotfiles" - local realpath = vim.fn.system({ "realpath", args.match }) - - if vim.fn.match(realpath, dotfiles) == -1 then - return - end - - -- utils.reload("tobyvin.plugins") - packer.sync() - end, - desc = "Reload packer config on write", - }) + -- local augroup_packer = vim.api.nvim_create_augroup("Packer", { clear = true }) + -- vim.api.nvim_create_autocmd("BufWritePost", { + -- group = augroup_packer, + -- pattern = "plugins.lua", + -- callback = function(args) + -- local dotfiles = vim.env.HOME .. "/.dotfiles" + -- local realpath = vim.fn.system({ "realpath", args.match }) + -- + -- if vim.fn.match(realpath, dotfiles) == -1 then + -- return + -- end + -- + -- -- utils.reload("tobyvin.plugins") + -- packer.sync() + -- end, + -- desc = "Reload packer config on write", + -- }) local nmap = utils.create_map_group("n", "<leader>p", { desc = "Packer" }) diff --git a/nvim/.config/nvim/lua/tobyvin/plugins/bufferline.lua b/nvim/.config/nvim/lua/tobyvin/plugins/bufferline.lua index e8e9259..7605e7a 100644 --- a/nvim/.config/nvim/lua/tobyvin/plugins/bufferline.lua +++ b/nvim/.config/nvim/lua/tobyvin/plugins/bufferline.lua @@ -1,18 +1,15 @@ +---@diagnostic disable: assign-type-mismatch local utils = require("tobyvin.utils") local M = {} -M.diagnostic_signs = function(name) - name = name:gsub("warning", "warn") - return utils.diagnostic_signs[name] -end - M.diagnostics_indicator = function(_, _, errors, _) - local s = " " - for e, n in pairs(errors) do - local sign = utils.diagnostic_signs[e:gsub("warning", "warn")].text - s = s .. (#s > 1 and " " or "") .. sign .. n + local outstr = " " + for level, count in pairs(errors) do + local sign = utils.diagnostic_signs[level:gsub("warning", "warn")].text + -- outstr = outstr .. sign .. (#count > 1 and count or "") + outstr = outstr .. sign .. count end - return s + return outstr end M.setup = function() @@ -23,13 +20,22 @@ M.setup = function() end bufferline.setup({ + -- highlights = { + -- fill = { + -- guibg = { + -- attribute = "fg", + -- highlight = "Pmenu", + -- }, + -- }, + -- }, options = { right_mouse_command = "buffer %d", always_show_bufferline = false, + color_icons = false, + show_close_icon = false, + show_buffer_close_icons = false, diagnostics = "nvim_lsp", diagnostics_indicator = M.diagnostics_indicator, - -- show_tab_indicators = true, - show_close_icon = false, left_trunc_marker = "<", right_trunc_marker = ">", }, diff --git a/nvim/.config/nvim/lua/tobyvin/plugins/cmp.lua b/nvim/.config/nvim/lua/tobyvin/plugins/cmp.lua index 418732b..5fd35d0 100644 --- a/nvim/.config/nvim/lua/tobyvin/plugins/cmp.lua +++ b/nvim/.config/nvim/lua/tobyvin/plugins/cmp.lua @@ -10,10 +10,6 @@ M.enabled = function() return enabled end -M.snippets = function(args) - require("luasnip").lsp_expand(args.body) -end - M.has_words_before = function() local line, col = unpack(vim.api.nvim_win_get_cursor(0)) return col ~= 0 and vim.api.nvim_buf_get_lines(0, line - 1, line, true)[1]:sub(col, col):match("%s") == nil @@ -30,39 +26,35 @@ M.complete = function(fallback) end end --- TODO: make this work more idiomatically with luasnip. Currently, a completion item must be accepted in order to --- expand/jump to next snippet item -M.next_item = function(fallback) - local cmp = require("cmp") +M.expand_snip = function(args) + require("luasnip").lsp_expand(args.body) +end + +M.next_snip = function(fallback) local luasnip = require("luasnip") - if cmp.visible() then - cmp.select_next_item() - elseif luasnip.expand_or_jumpable() then + if luasnip.expand_or_jumpable() then luasnip.expand_or_jump() - elseif M.has_words_before() then - cmp.complete() else fallback() end end -M.prev_item = function(fallback) - local cmp = require("cmp") +M.prev_snip = function(fallback) local luasnip = require("luasnip") - if cmp.visible() then - cmp.select_prev_item() - elseif luasnip.jumpable(-1) then + if luasnip.in_snippet() and luasnip.jumpable(-1) then luasnip.jump(-1) else fallback() end end --- TODO: wipe the luasnip expandable/jumpable list on close M.close = function(fallback) local cmp = require("cmp") - cmp.close() - fallback() + if cmp.visible() then + cmp.close() + else + fallback() + end end M.setup = function() @@ -75,17 +67,34 @@ M.setup = function() cmp.setup({ enabled = M.enabled, snippet = { - expand = M.snippets, - }, - mapping = { - ["<Tab>"] = cmp.mapping(M.next_item), - ["<S-Tab>"] = cmp.mapping(M.prev_item), - ["<C-d>"] = cmp.mapping.scroll_docs(-4), - ["<C-u>"] = cmp.mapping.scroll_docs(4), - ["<C-Space>"] = cmp.mapping(M.complete), - ["<CR>"] = cmp.mapping.confirm({ behavior = cmp.ConfirmBehavior.insert }), - ["<C-c>"] = cmp.mapping(M.close), + expand = M.expand_snip, }, + mapping = cmp.mapping.preset.cmdline({ + -- ["<Tab>"] = cmp.mapping(M.next_snip, { "i", "s" }), + -- ["<S-Tab>"] = cmp.mapping(M.prev_snip, { "i", "s" }), + -- ["<C-n>"] = cmp.mapping(cmp.mapping.select_next_item(), { "i", "s" }), + -- ["<C-p>"] = cmp.mapping(cmp.mapping.select_prev_item(), { "i", "s" }), + -- ["<C-d>"] = cmp.mapping(cmp.mapping.scroll_docs(-4), { "i", "s" }), + -- ["<C-u>"] = cmp.mapping(cmp.mapping.scroll_docs(4), { "i", "s" }), + -- ["<C-Space>"] = cmp.mapping(M.complete, { "i", "s" }), + -- ["<CR>"] = cmp.mapping(cmp.mapping.confirm({ select = false }), { "i", "s" }), + -- ["<C-e>"] = cmp.mapping(M.close), + ["<C-p>"] = cmp.mapping(cmp.mapping.select_prev_item(), { "i", "s" }), + ["<C-n>"] = cmp.mapping(cmp.mapping.select_next_item(), { "i", "s" }), + ["<S-Tab>"] = cmp.mapping(cmp.mapping.select_prev_item(), { "i", "s" }), + ["<Tab>"] = cmp.mapping(cmp.mapping.select_next_item(), { "i", "s" }), + ["<C-d>"] = cmp.mapping(cmp.mapping.scroll_docs(4), { "i", "s" }), + ["<C-u>"] = cmp.mapping(cmp.mapping.scroll_docs(-4), { "i", "s" }), + ["<C-Space>"] = cmp.mapping(cmp.mapping.complete(), { "i", "s" }), + ["<C-e>"] = cmp.mapping(cmp.mapping.close(), { "i", "s" }), + ["<CR>"] = cmp.mapping( + cmp.mapping.confirm({ + behavior = cmp.ConfirmBehavior.Insert, + select = true, + }), + { "i", "s" } + ), + }), ghost_text = true, sources = { { name = "nvim_lsp", group_index = 1 }, @@ -123,7 +132,7 @@ M.setup = function() }, }) - -- TODO: fix the default completion menu from showing on the cmdline + -- TODO: fix the default completion menu from showing on the cmdline cmp.setup.cmdline(":", { sources = { { name = "cmdline_history", max_item_count = 10 }, diff --git a/nvim/.config/nvim/lua/tobyvin/plugins/dap.lua b/nvim/.config/nvim/lua/tobyvin/plugins/dap.lua index 989d244..87a3f37 100644 --- a/nvim/.config/nvim/lua/tobyvin/plugins/dap.lua +++ b/nvim/.config/nvim/lua/tobyvin/plugins/dap.lua @@ -20,21 +20,38 @@ M.eval = function() end) end -M.open_in_tab = function() +M.dapui_open = function() if M.dapui_win and vim.api.nvim_win_is_valid(M.dapui_win) then vim.api.nvim_set_current_win(M.dapui_win) return end + local dap = require("dap") + local dapui = require("dapui") + vim.cmd("tabedit %") M.dapui_win = vim.fn.win_getid() M.dapui_tab = vim.api.nvim_win_get_tabpage(M.dapui_win) - require("dapui").open({}) + dapui.open({}) + + vim.keymap.set("n", "<leader>q", dap.terminate, { desc = "Quit (DAP)" }) + + local on_tab_closed = function() + dap.terminate() + return true + end + + local group = vim.api.nvim_create_augroup("DapAU", { clear = true }) + vim.api.nvim_create_autocmd("TabClosed", { group = group, callback = on_tab_closed }) end -M.close_tab = function() - require("dapui").close({}) +M.dapui_close = function() + local dapui = require("dapui") + + dapui.close({}) + + vim.keymap.set("n", "<leader>q", utils.quit, { desc = "Quit" }) if M.dapui_tab and vim.api.nvim_tabpage_is_valid(M.dapui_tab) then local tabnr = vim.api.nvim_tabpage_get_number(M.dapui_tab) @@ -45,6 +62,38 @@ M.close_tab = function() M.dapui_tab = nil end +M.progress_start = function(session, body) + local notif_data = utils.get_notif_data("dap", body.progressId) + + local message = utils.format_message(body.message, body.percentage) + notif_data.notification = vim.notify(message, "info", { + title = utils.format_title(body.title, session.config.type), + icon = utils.signs.spinner.text[1], + timeout = false, + hide_from_history = false, + }) + + notif_data.notification.spinner = 1, utils.update_spinner("dap", body.progressId) +end + +M.progress_update = function(session, body) + local notif_data = utils.get_notif_data("dap", body.progressId) + notif_data.notification = vim.notify(utils.format_message(body.message, body.percentage), "info", { + replace = notif_data.notification, + hide_from_history = false, + }) +end + +M.progress_end = function(session, body) + local notif_data = utils.client_notifs["dap"][body.progressId] + notif_data.notification = vim.notify(body.message and utils.format_message(body.message) or "Complete", "info", { + icon = utils.signs.complete.text, + replace = notif_data.notification, + timeout = 3000, + }) + notif_data.spinner = nil +end + M.setup = function() local status_ok, dap = pcall(require, "dap") if not status_ok then @@ -52,7 +101,7 @@ M.setup = function() return end - -- TODO: Break these configs out into seperate module, similar to my LSP configs + -- TODO: Break these configs out into seperate module, similar to my LSP configs -- Debugpy dap.adapters.python = { type = "executable", @@ -139,14 +188,20 @@ M.setup = function() -- DAPUI require("dapui").setup() + -- Progress handlers + dap.listeners.before.event_progressStart["progress-notifications"] = M.progress_start + dap.listeners.before.event_progressUpdate["progress-notifications"] = M.progress_update + dap.listeners.before.event_progressEnd["progress-notifications"] = M.progress_end + + -- Delete repl buffer dap.listeners.before.event_terminated["close_repl"] = dap.repl.close dap.listeners.before.event_exited["close_repl"] = dap.repl.close -- Attach DAP UI to DAP events - dap.listeners.after.event_initialized["dapui_config"] = M.open_in_tab - dap.listeners.before.event_terminated["dapui_config"] = M.close_tab - dap.listeners.before.event_exited["dapui_config"] = M.close_tab - dap.listeners.before.disconnect["dapui_config"] = M.close_tab + dap.listeners.after.event_initialized["dapui_config"] = M.dapui_open + dap.listeners.before.event_terminated["dapui_config"] = M.dapui_close + dap.listeners.before.event_exited["dapui_config"] = M.dapui_close + dap.listeners.before.disconnect["dapui_config"] = M.dapui_close -- Telescope require("telescope").load_extension("dap") @@ -158,7 +213,8 @@ M.setup = function() vim.keymap.set("n", "<F12>", dap.step_out, { desc = "Step Out" }) local nmap = utils.create_map_group("n", "<leader>d", { desc = "Debug" }) - nmap("d", dap.continue, { desc = "Continue" }) + nmap("d", require("telescope").extensions.dap.configurations, { desc = "Configurations" }) + nmap("c", dap.continue, { desc = "Continue" }) nmap("a", dap.step_over, { desc = "Step Over" }) nmap("i", dap.step_into, { desc = "Step Into" }) nmap("o", dap.step_out, { desc = "Step Out" }) @@ -167,8 +223,7 @@ M.setup = function() nmap("b", dap.toggle_breakpoint, { desc = "Toggle Breakpoint" }) nmap("B", M.set_custom_breakpoint, { desc = "Custom Breakpoint" }) - nmap("c", require("telescope").extensions.dap.commands, { desc = "Commands" }) - nmap("C", require("telescope").extensions.dap.configurations, { desc = "Configurations" }) + nmap("C", require("telescope").extensions.dap.commands, { desc = "Commands" }) nmap("l", require("telescope").extensions.dap.list_breakpoints, { desc = "List Breakpoints" }) nmap("v", require("telescope").extensions.dap.variables, { desc = "Variables" }) nmap("f", require("telescope").extensions.dap.frames, { desc = "Frames" }) diff --git a/nvim/.config/nvim/lua/tobyvin/plugins/dressing.lua b/nvim/.config/nvim/lua/tobyvin/plugins/dressing.lua index b74d134..10d1aa1 100644 --- a/nvim/.config/nvim/lua/tobyvin/plugins/dressing.lua +++ b/nvim/.config/nvim/lua/tobyvin/plugins/dressing.lua @@ -7,6 +7,9 @@ M.kinds = { select_normal = { telescope = themes.get_dropdown({ initial_mode = "normal" }), }, + -- ["rust-tools/debuggables"] = { + -- telescope = themes.get_ivy({}), + -- }, }, } @@ -20,12 +23,23 @@ M.setup = function() dressing.setup({ select = { get_config = function(opts) - if vim.tbl_contains(M.kinds, opts.kind) then + if vim.tbl_contains(vim.tbl_keys(M.kinds.select), opts.kind) then return M.kinds.select[opts.kind] elseif vim.tbl_contains(backends, opts.kind) then return { backend = opts.kind } end end, + format_item_override = { + ["rust-tools/debuggables"] = function(item) + item = item:gsub(" %-%-no%-run", "") + item = item:gsub(" %-%-package", " -p") + item = item:gsub(" %-%-all%-features", "") + item = item:gsub(" %-%-all%-targets", "") + item = item:gsub(" %-%-exact", "") + item = item:gsub(" %-%-nocapture", "") + return item + end, + }, }, }) end diff --git a/nvim/.config/nvim/lua/tobyvin/plugins/fidget.lua b/nvim/.config/nvim/lua/tobyvin/plugins/fidget.lua new file mode 100644 index 0000000..fcef526 --- /dev/null +++ b/nvim/.config/nvim/lua/tobyvin/plugins/fidget.lua @@ -0,0 +1,20 @@ +local utils = require("tobyvin.utils") +local M = {} + +M.setup = function() + local status_ok, fidget = pcall(require, "fidget") + if not status_ok then + vim.notify("Failed to load module 'fidget'", "error") + return + end + + fidget.setup({ + text = { + spinner = utils.progress_signs.spinner.text, + done = vim.trim(utils.progress_signs.complete.text), + }, + window = { blend = 0 }, + }) +end + +return M diff --git a/nvim/.config/nvim/lua/tobyvin/plugins/gruvbox-flat.lua b/nvim/.config/nvim/lua/tobyvin/plugins/gruvbox-flat.lua index f0e2e0c..9ba6f32 100644 --- a/nvim/.config/nvim/lua/tobyvin/plugins/gruvbox-flat.lua +++ b/nvim/.config/nvim/lua/tobyvin/plugins/gruvbox-flat.lua @@ -4,12 +4,11 @@ local M = {} M.setup = function() vim.opt.background = "dark" vim.g.gruvbox_flat_style = "hard" - vim.g.gruvbox_transparent = true local colors = require("gruvbox.colors").setup({}) local theme = require("gruvbox.theme").setup({}) - vim.g.gruvbox_colors = { bg_statusline = colors.bg_highlight } + vim.g.gruvbox_colors = { bg_statusline = "none" } vim.g.gruvbox_theme = { debugBreakpoint = { bg = theme.base.SignColumn.bg, fg = "error" }, } @@ -18,7 +17,13 @@ M.setup = function() local ns_id = vim.api.nvim_create_namespace("gruvbox") - -- TODO: figure out why dap/dapui highlights are not being used + -- TODO: figure out why these highlights are not being used + -- Transparent + vim.api.nvim_set_hl(ns_id, "NormalFloat", { fg = colors.fg, bg = colors.bg_float, sp = "none" }) + vim.api.nvim_set_hl(ns_id, "SignColumn", { fg = colors.fg_gutter, bg = colors.bg, sp = "none" }) + vim.api.nvim_set_hl(ns_id, "Normal", { fg = colors.fg, bg = colors.bg, sp = "none" }) + vim.api.nvim_set_hl(ns_id, "NormalNC", { fg = colors.fg, bg = colors.bg, sp = "none" }) + -- nvim-dap vim.api.nvim_set_hl(ns_id, "DapBreakpoint", { link = "debugBreakpoint" }) vim.api.nvim_set_hl(ns_id, "DapStopped", { link = "debugPC" }) @@ -42,6 +47,10 @@ M.setup = function() vim.api.nvim_set_hl(ns_id, "DapUIBreakpointsInfo", { link = "LspDiagnosticsInfo" }) vim.api.nvim_set_hl(ns_id, "DapUIBreakpointsCurrentLine", { link = "DapStopped" }) vim.api.nvim_set_hl(ns_id, "DapUIBreakpointsLine", { link = "DapUILineNumber" }) + + require("transparent").setup({ + enable = true, + }) end return M diff --git a/nvim/.config/nvim/lua/tobyvin/plugins/lspconfig.lua b/nvim/.config/nvim/lua/tobyvin/plugins/lspconfig.lua index 7c8ad15..2152c91 100644 --- a/nvim/.config/nvim/lua/tobyvin/plugins/lspconfig.lua +++ b/nvim/.config/nvim/lua/tobyvin/plugins/lspconfig.lua @@ -11,6 +11,8 @@ M.setup = function() return end + lspconfig.bashls.setup(lsp.config()) + lspconfig.taplo.setup(lsp.config()) lspconfig.yamlls.setup(lsp.config({ @@ -53,6 +55,10 @@ M.setup = function() staticcheck = true, }, }, + on_attach = function(client, bufnr) + vim.api.nvim_buf_set_option(bufnr, "omnifunc", "v:lua.vim.lsp.omnifunc") + lsp.on_attach(client, bufnr) + end, })) lspconfig.ltex.setup(lsp.config({ diff --git a/nvim/.config/nvim/lua/tobyvin/plugins/lua-dev.lua b/nvim/.config/nvim/lua/tobyvin/plugins/lua-dev.lua index 37e7df1..f764559 100644 --- a/nvim/.config/nvim/lua/tobyvin/plugins/lua-dev.lua +++ b/nvim/.config/nvim/lua/tobyvin/plugins/lua-dev.lua @@ -11,7 +11,14 @@ M.setup = function() local lspconfig = require("lspconfig") lspconfig.sumneko_lua.setup(lua_dev.setup({ - runtime_path = true, + library = { + vimruntime = true, -- runtime path + types = true, -- full signature, docs and completion of vim.api, vim.treesitter, vim.lsp and others + plugins = true, -- installed opt or start plugins in packpath + -- you can also specify the list of plugins to make available as a workspace library + -- plugins = { "nvim-treesitter", "plenary.nvim", "telescope.nvim" }, + }, + -- runtime_path = true, lspconfig = lsp.config({ settings = { Lua = { diff --git a/nvim/.config/nvim/lua/tobyvin/plugins/lualine.lua b/nvim/.config/nvim/lua/tobyvin/plugins/lualine.lua index 9ea3d2f..a7b223a 100644 --- a/nvim/.config/nvim/lua/tobyvin/plugins/lualine.lua +++ b/nvim/.config/nvim/lua/tobyvin/plugins/lualine.lua @@ -24,11 +24,87 @@ M.setup = function() local nvim_navic = require("nvim-navic") + local modules = require("lualine_require").lazy_require({ + highlight = "lualine.highlight", + utils = "lualine.utils.utils", + }) + + local buffer = require("lualine.components.buffers.buffer") + ---returns rendered buffer + ---@return string + function buffer:render() + local name = self:name() + if self.options.fmt then + name = self.options.fmt(name or "", self.bufnr) + end + + if self.ellipse then -- show ellipsis + name = "..." + else + name = self:apply_mode(name) + end + name = buffer.apply_padding(name, self.options.padding) + self.len = vim.fn.strchars(name) + + -- setup for mouse clicks + local line = self:configure_mouse_click(name) + -- apply highlight + line = modules.highlight.component_format_highlight(self.highlights[(self.current and "active" or "inactive")]) + .. line + + -- apply separators + if self.options.self.section < "x" and not self.first then + local sep_before = self:separator_before() + line = sep_before .. line + self.len = self.len + vim.fn.strchars(sep_before) + elseif self.options.self.section >= "x" and not self.last then + local sep_after = self:separator_after() + line = line .. sep_after + self.len = self.len + vim.fn.strchars(sep_after) + end + return line + end + + local tab = require("lualine.components.tabs.tab") + + ---returns name for tab. Tabs name is the name of buffer in last active window + --- of the tab. + ---@return string + function tab:label() + local ok, custom_tabname = pcall(vim.api.nvim_tabpage_get_var, self.tabId, "tabname") + if not ok then + custom_tabname = nil + end + if custom_tabname and custom_tabname ~= "" then + return modules.utils.stl_escape(custom_tabname) + elseif self.options.mode == 1 then + return tostring(self.tabnr) + end + local buflist = vim.fn.tabpagebuflist(self.tabnr) + local winnr = vim.fn.tabpagewinnr(self.tabnr) + local bufnr = buflist[winnr] + local file = modules.utils.stl_escape(vim.api.nvim_buf_get_name(bufnr)) + local buftype = vim.fn.getbufvar(bufnr, "&buftype") + if buftype == "help" then + return "help:" .. vim.fn.fnamemodify(file, ":t:r") + elseif buftype == "terminal" then + local match = string.match(vim.split(file, " ")[1], "term:.*:(%a+)") + return match ~= nil and match or vim.fn.fnamemodify(vim.env.SHELL, ":t") + elseif vim.fn.isdirectory(file) == 1 then + return vim.fn.fnamemodify(file, ":p:.") + elseif file == "" then + return "[No Name]" + end + return vim.fn.fnamemodify(file, ":t") + end + lualine.setup({ options = { - component_separators = { left = "", right = "" }, - section_separators = { left = "", right = "" }, - globalstatus = false, + refresh = { + statusline = 200, + }, + component_separators = "", + section_separators = "", }, sections = { lualine_a = { { "mode", fmt = M.to_char } }, @@ -37,7 +113,7 @@ M.setup = function() { "diff", source = M.diff_source }, { "diagnostics", - sources = { "nvim_lsp" }, + sources = { "nvim_workspace_diagnostic", "nvim_lsp" }, symbols = { error = utils.diagnostic_signs.error.text, warn = utils.diagnostic_signs.warn.text, @@ -52,20 +128,31 @@ M.setup = function() { nvim_navic.get_location, cond = nvim_navic.is_available }, }, lualine_x = { - { - "lsp_progress", - display_components = { "lsp_client_name", "spinner", { "title", "percentage", "message" } }, - timer = { progress_enddelay = 500, spinner = 1000, lsp_client_name_enddelay = 1000 }, - spinner_symbols = utils.spinner_frames, - }, "encoding", "fileformat", "filetype", }, }, - tabline = {}, + tabline = { + -- lualine_b = { { "buffers", buffers_color = { inactive = "StatusLineNC" } } }, + lualine_b = { + { + "buffers", + -- TODO: figure out how to highlight diagnostic signs + fmt = function(name, bufnr) + return string.format("%s %s", name, utils.diagnostics_str(bufnr)) + end, + }, + }, + -- lualine_y = { "tabs" }, + lualine_y = { { "tabs", mode = 1 } }, + }, extensions = { "quickfix", "man", "fzf", "nvim-dap-ui" }, }) + + -- local nmap = utils.create_map_group("n", "<leader>b", { desc = "Buffers" }) + -- nmap("c", M.close_with_pick, { desc = "Close Buffer" }) + -- nmap("b", M.pick_buffer, { desc = "Pick Buffer" }) end return M diff --git a/nvim/.config/nvim/lua/tobyvin/plugins/luasnip.lua b/nvim/.config/nvim/lua/tobyvin/plugins/luasnip.lua index 7fb80d5..4a94226 100644 --- a/nvim/.config/nvim/lua/tobyvin/plugins/luasnip.lua +++ b/nvim/.config/nvim/lua/tobyvin/plugins/luasnip.lua @@ -7,7 +7,6 @@ M.setup = function() end luasnip.config.set_config({ - history = true, updateevents = "TextChanged,TextChangedI", }) diff --git a/nvim/.config/nvim/lua/tobyvin/plugins/neogit.lua b/nvim/.config/nvim/lua/tobyvin/plugins/neogit.lua index bcf2307..a91bf71 100644 --- a/nvim/.config/nvim/lua/tobyvin/plugins/neogit.lua +++ b/nvim/.config/nvim/lua/tobyvin/plugins/neogit.lua @@ -8,6 +8,7 @@ M.setup = function() return end + require("neogit") neogit.setup({ disable_commit_confirmation = true, disable_signs = true, diff --git a/nvim/.config/nvim/lua/tobyvin/plugins/null-ls.lua b/nvim/.config/nvim/lua/tobyvin/plugins/null-ls.lua index c247177..c94b73b 100644 --- a/nvim/.config/nvim/lua/tobyvin/plugins/null-ls.lua +++ b/nvim/.config/nvim/lua/tobyvin/plugins/null-ls.lua @@ -24,7 +24,7 @@ M.setup = function() -- Diagnostics diagnostics.markdownlint, -- diagnostics.luacheck, - diagnostics.shellcheck, + -- diagnostics.shellcheck, diagnostics.checkmake, -- Formatting diff --git a/nvim/.config/nvim/lua/tobyvin/plugins/rust-tools.lua b/nvim/.config/nvim/lua/tobyvin/plugins/rust-tools.lua index f78d360..8a854f0 100644 --- a/nvim/.config/nvim/lua/tobyvin/plugins/rust-tools.lua +++ b/nvim/.config/nvim/lua/tobyvin/plugins/rust-tools.lua @@ -1,3 +1,4 @@ +local utils = require("tobyvin.utils") local lsp = require("tobyvin.lsp") local M = { codelldb = "/usr/lib/codelldb/adapter/codelldb", @@ -10,6 +11,7 @@ M.dap_adapter = function() adapter = require("rust-tools.dap").get_codelldb_adapter(M.codelldb, M.liblldb), } end + vim.notify("Failed to find codelldb adapter") end M.setup = function() @@ -20,19 +22,20 @@ M.setup = function() end rust_tools.setup({ - tools = { - autoSetHints = true, - hover_with_actions = true, - runnables = { - use_telescope = true, - }, - inlay_hints = { - show_parameter_hints = true, - parameter_hints_prefix = "", - other_hints_prefix = "", - }, - }, + -- tools = { + -- autoSetHints = true, + -- hover_with_actions = true, + -- runnables = { + -- use_telescope = true, + -- }, + -- inlay_hints = { + -- show_parameter_hints = true, + -- parameter_hints_prefix = "", + -- other_hints_prefix = "", + -- }, + -- }, server = lsp.config({ + standalone = true, settings = { ["rust-analyzer"] = { cargo = { @@ -51,7 +54,16 @@ M.setup = function() { title = "[rust-tools] codelldb not found" } ) end + vim.api.nvim_buf_set_option(bufnr, "formatexpr", "v:lua.vim.lsp.formatexpr()") + vim.api.nvim_buf_set_option(bufnr, "omnifunc", "v:lua.vim.lsp.omnifunc") + vim.api.nvim_buf_set_option(bufnr, "tagfunc", "v:lua.vim.lsp.tagfunc") lsp.on_attach(client, bufnr) + + local nmap = utils.create_map_group("n", "<leader>", { buffer = bufnr }) + nmap("dd", rust_tools.debuggables.debuggables, { desc = "Debug" }) + nmap("tt", rust_tools.runnables.runnables, { desc = "Run" }) + -- nmap("lh", rust_tools.hover_actions.hover_actions, { desc = "Hover Actions" }) + -- nmap("la", rust_tools.code_action_group.code_action_group, { desc = "Code Actions" }) end, }), dap = M.dap_adapter(), diff --git a/nvim/.config/nvim/lua/tobyvin/plugins/telescope.lua b/nvim/.config/nvim/lua/tobyvin/plugins/telescope.lua index f5ab0f5..b7dd3a2 100644 --- a/nvim/.config/nvim/lua/tobyvin/plugins/telescope.lua +++ b/nvim/.config/nvim/lua/tobyvin/plugins/telescope.lua @@ -17,7 +17,7 @@ M.setup = function() ["<C-h>"] = actions.which_key, }, }, - file_ignore_patterns = { "^.git/" }, + file_ignore_patterns = { "^.git/", "^target/" }, vimgrep_arguments = { "rg", "--color=never", @@ -52,21 +52,11 @@ M.setup = function() sort_lastused = true, }, }, - extensions = { - frecency = { - default_workspace = "CWD", - workspaces = { - ["src"] = "~/src", - }, - theme = "dropdown", - }, - }, }) -- Extensions telescope.load_extension("smart_history") telescope.load_extension("fzf") - telescope.load_extension("frecency") telescope.load_extension("packer") telescope.load_extension("gh") @@ -86,8 +76,6 @@ M.setup = function() nmap_find("'", builtins.registers, { desc = "Registers" }) nmap_find("t", builtins.colorscheme, { desc = "Colorscheme" }) nmap_find("p", telescope.extensions.packer.packer, { desc = "Packer" }) - -- TODO: Improve layout of frecency and make default - nmap_find("e", telescope.extensions.frecency.frecency, { desc = "Frecency" }) local nmap_git = require("tobyvin.utils").create_map_group("n", "<leader>g", { desc = "Git" }) nmap_git("b", builtins.git_branches, { desc = "Checkout branch" }) diff --git a/nvim/.config/nvim/lua/tobyvin/plugins/treesitter.lua b/nvim/.config/nvim/lua/tobyvin/plugins/treesitter.lua index 293d924..636d53d 100644 --- a/nvim/.config/nvim/lua/tobyvin/plugins/treesitter.lua +++ b/nvim/.config/nvim/lua/tobyvin/plugins/treesitter.lua @@ -28,6 +28,24 @@ M.setup = function() node_decremental = "<S-TAB>", }, }, + playground = { + enable = true, + -- disable = {}, + -- updatetime = 25, -- Debounced time for highlighting nodes in the playground from source code + -- persist_queries = false, -- Whether the query persists across vim sessions + -- keybindings = { + -- toggle_query_editor = "o", + -- toggle_hl_groups = "i", + -- toggle_injected_languages = "t", + -- toggle_anonymous_nodes = "a", + -- toggle_language_display = "I", + -- focus_language = "f", + -- unfocus_language = "F", + -- update = "R", + -- goto_node = "<cr>", + -- show_help = "?", + -- }, + }, refactor = { highlight_definitions = { enable = true, @@ -51,21 +69,21 @@ M.setup = function() enable = true, lookahead = true, keymaps = { - ["af"] = "@function.outer", - ["if"] = "@function.inner", - ["is"] = "@statement.inner", - ["as"] = "@statement.outer", - ["il"] = "@loop.inner", - ["al"] = "@loop.outer", - ["ib"] = "@block.inner", - ["ab"] = "@block.outer", - ["io"] = "@class.inner", - ["ao"] = "@class.outer", - ["a/"] = "@comment.outer", - ["ii"] = "@conditional.inner", - ["ai"] = "@conditional.outer", - ["iv"] = "@parameter.inner", - ["av"] = "@parameter.outer", + ["af"] = { query = "@function.outer", desc = "a function" }, + ["if"] = { query = "@function.inner", desc = "inner function" }, + ["ia"] = { query = "@statement.inner", desc = "inner statement" }, + ["aa"] = { query = "@statement.outer", desc = "a statement" }, + ["il"] = { query = "@loop.inner", desc = "inner loop" }, + ["al"] = { query = "@loop.outer", desc = "a loop" }, + ["ib"] = { query = "@block.inner", desc = "inner block" }, + ["ab"] = { query = "@block.outer", desc = "a block" }, + ["ic"] = { query = "@class.inner", desc = "inner class" }, + ["ac"] = { query = "@class.outer", desc = "a class" }, + ["a/"] = { query = "@comment.outer", desc = "a comment" }, + ["ii"] = { query = "@conditional.inner", desc = "inner conditional" }, + ["ai"] = { query = "@conditional.outer", desc = "a conditional" }, + ["iv"] = { query = "@parameter.inner", desc = "inner parameter" }, + ["av"] = { query = "@parameter.outer", desc = "a parameter" }, }, }, }, @@ -74,8 +92,8 @@ M.setup = function() prev_selection = ",", -- (Optional) keymap to select the previous selection keymaps = { ["."] = "textsubjects-smart", - ["ac"] = "textsubjects-container-outer", - ["ic"] = "textsubjects-container-inner", + ["a."] = "textsubjects-container-outer", + ["i."] = "textsubjects-container-inner", }, }, }) diff --git a/nvim/.config/nvim/lua/tobyvin/utils.lua b/nvim/.config/nvim/lua/tobyvin/utils.lua index 081affb..a7705f9 100644 --- a/nvim/.config/nvim/lua/tobyvin/utils.lua +++ b/nvim/.config/nvim/lua/tobyvin/utils.lua @@ -1,5 +1,105 @@ +---@diagnostic disable: missing-parameter local M = {} +M.diagnostic_signs = { + hint = { text = " ", texthl = "DiagnosticSignHint" }, + info = { text = " ", texthl = "DiagnosticSignInfo" }, + warn = { text = " ", texthl = "DiagnosticSignWarn" }, + error = { text = " ", texthl = "DiagnosticSignError" }, +} + +setmetatable(M.diagnostic_signs, { + __index = function(t, k) + if type(k) == "number" then + local levels = { "hint", "info", "warn", "error" } + return levels[k] + end + + local fmt_k = k:gsub("warning", "warn"):lower() + if t[fmt_k] ~= nil then + return t[fmt_k] + end + + return t[k] + end, +}) + +M.debug_signs = { + breakpoint = { text = " ", texthl = "debugBreakpoint" }, + condition = { text = "ﳁ ", texthl = "debugBreakpoint" }, + rejected = { text = " ", texthl = "debugBreakpoint" }, + logpoint = { text = " ", texthl = "debugBreakpoint" }, + stopped = { text = " ", texthl = "debugBreakpoint", linehl = "debugPC", numhl = "debugPC" }, +} + +M.progress_signs = { + complete = { text = " ", texthl = "diffAdded" }, + spinner = { text = { "⣷", "⣯", "⣟", "⡿", "⢿", "⣻", "⣽", "⣾" }, texthl = "DiagnosticSignInfo" }, +} + +M.diagnostics_indicator = function(diagnostics_count) + local tbl = {} + for level, count in pairs(diagnostics_count) do + table.insert(tbl, M.diagnostic_signs[level].text .. count) + end + return table.concat(tbl, " ") +end + +M.diagnostics_count = function(bufnr) + local items = {} + for i, level in ipairs({ "hint", "info", "warn", "error" }) do + local count = #vim.diagnostic.get(bufnr, { severity = i }) + if count > 0 then + items[level] = count + end + end + return items +end + +M.diagnostics_str = function(bufnr, highlight) + return M.diagnostics_indicator(M.diagnostics_count(bufnr)) +end + +M.update_spinner = function(client_id, token) + local notif_data = M.get_notif_data(client_id, token) + + if notif_data.spinner then + local new_spinner = (notif_data.spinner + 1) % #M.progress_signs.spinner.text + notif_data.spinner = new_spinner + + notif_data.notification = vim.notify(nil, nil, { + hide_from_history = true, + icon = M.progress_signs.spinner.text[new_spinner], + replace = notif_data.notification, + }) + + vim.defer_fn(function() + M.update_spinner(client_id, token) + end, 100) + end +end + +M.hover = function() + if vim.fn.expand("%:t") == "Cargo.toml" then + require("crates").show_popup() + else + vim.lsp.buf.hover() + end +end + +M.docs = function() + local filetype = vim.bo.filetype + if vim.tbl_contains({ "vim", "help" }, filetype) then + vim.cmd("help " .. vim.fn.expand("<cword>")) + elseif vim.tbl_contains({ "man" }, filetype) then + vim.cmd("Man " .. vim.fn.expand("<cword>")) + elseif vim.tbl_contains({ "rust" }, filetype) then + require("rust-tools.external_docs").open_external_docs() + else + M.hover() + end +end + ---@param retry fun(force:boolean?):nil M.modified_prompt_retry = function(retry) local bufname = vim.fn.bufname(vim.fn.bufname()) @@ -62,6 +162,15 @@ M.quit = function(force) M.win_buf_kill("quit", force) end +---@param force boolean +M.tabclose = function(force) + local cmd = "tabclose" + if #vim.api.nvim_list_tabpages() == 1 then + cmd = "qall" + end + vim.cmd(cmd .. (force and "!" or "")) +end + M.escape = function() local key = "<ESC>" vim.api.nvim_replace_termcodes(key, true, false, true) @@ -79,28 +188,30 @@ M.get_visual_range = function() -- return { { line = start_pos[2], col = start_pos[3] }, { line = end_pos[2], col = end_pos[3] } } end -M.spinner_frames = { "⣷", "⣯", "⣟", "⡿", "⢿", "⣻", "⣽", "⣾" } +M.client_notifs = {} -M.diagnostic_signs = { - error = { text = " ", texthl = "DiagnosticSignError" }, - warn = { text = " ", texthl = "DiagnosticSignWarn" }, - info = { text = " ", texthl = "DiagnosticSignInfo" }, - hint = { text = "", texthl = "DiagnosticSignHint" }, -} +M.get_notif_data = function(client_id, token) + if not M.client_notifs[client_id] then + M.client_notifs[client_id] = {} + end -M.debug_signs = { - breakpoint = { text = "", texthl = "debugBreakpoint" }, - condition = { text = "ﳁ", texthl = "debugBreakpoint" }, - rejected = { text = "", texthl = "debugBreakpoint" }, - logpoint = { text = "", texthl = "debugBreakpoint" }, - stopped = { text = "", texthl = "debugBreakpoint", linehl = "debugPC", numhl = "debugPC" }, -} + if not M.client_notifs[client_id][token] then + M.client_notifs[client_id][token] = {} + end -setmetatable(M.diagnostic_signs, { - __index = function() - return M.diagnostic_signs.info - end, -}) + return M.client_notifs[client_id][token] +end + +M.format_title = function(title, client) + if type(client) == "table" then + client = client.name + end + return client .. (#title > 0 and ": " .. title or "") +end + +M.format_message = function(message, percentage) + return (percentage and percentage .. "%\t" or "") .. (message or "") +end --- Helper function to create a group of keymaps that share a common prefix and/or options. ---@param mode string|table Same mode short names as vim.keymap.set(). A list will create the group on all modes. |