diff --git a/config/nvim/.stylua.toml b/config/nvim/.stylua.toml index edd9761..fac487e 100644 --- a/config/nvim/.stylua.toml +++ b/config/nvim/.stylua.toml @@ -1,4 +1,4 @@ -column_width = 120 +column_width = 80 line_endings = "Unix" indent_type = "Spaces" indent_width = 2 diff --git a/config/nvim/init.lua b/config/nvim/init.lua index 66a7cbb..fa81d65 100644 --- a/config/nvim/init.lua +++ b/config/nvim/init.lua @@ -7,7 +7,14 @@ local lazypath = vim.fn.stdpath 'data' .. '/lazy/lazy.nvim' if not (vim.uv or vim.loop).fs_stat(lazypath) then local lazyrepo = 'https://github.com/folke/lazy.nvim.git' - local out = vim.fn.system { 'git', 'clone', '--filter=blob:none', '--branch=stable', lazyrepo, lazypath } + local out = vim.fn.system { + 'git', + 'clone', + '--filter=blob:none', + '--branch=stable', + lazyrepo, + lazypath, + } if vim.v.shell_error ~= 0 then vim.api.nvim_echo({ { 'Failed to clone lazy.nvim:\n', 'ErrorMsg' }, @@ -21,7 +28,10 @@ end vim.opt.rtp:prepend(lazypath) -- ── Add ~/.local/bin to the PATH ──────────────────────────────────── -vim.fn.setenv('PATH', vim.fn.expand '$HOME/.local/bin' .. ':' .. vim.fn.expand '$PATH') +vim.fn.setenv( + 'PATH', + vim.fn.expand '$HOME/.local/bin' .. ':' .. vim.fn.expand '$PATH' +) require 'options' require 'autogroups' diff --git a/config/nvim/lua/autogroups.lua b/config/nvim/lua/autogroups.lua index c999f13..a7b77d7 100644 --- a/config/nvim/lua/autogroups.lua +++ b/config/nvim/lua/autogroups.lua @@ -7,24 +7,48 @@ local autocmd = vim.api.nvim_create_autocmd -- Create autocommand -- ── Highlight on yank ─────────────────────────────────────────────── -- See `:help vim.highlight.on_yank()` -local highlight_group = augroup('YankHighlight', { clear = true }) autocmd('TextYankPost', { callback = function() vim.highlight.on_yank() end, - group = highlight_group, + group = augroup('YankHighlight', { clear = true }), pattern = '*', }) -- ── Windows to close with "q" ─────────────────────────────────────── autocmd('FileType', { - callback = function() vim.keymap.set('n', '', ':bd', { buffer = true, silent = true }) end, + group = augroup('close_with_q', { clear = true }), pattern = { + 'PlenaryTestPopup', + 'checkhealth', + 'dbout', + 'gitsigns.blame', + 'grug-far', 'help', - 'startuptime', - 'qf', 'lspinfo', 'man', - 'checkhealth', + 'neotest-output', + 'neotest-output-panel', + 'neotest-summary', + 'notify', + 'qf', + 'spectre_panel', + 'startuptime', + 'tsplayground', }, + callback = function(event) + vim.bo[event.buf].buflisted = false + vim.keymap.set('n', 'q', 'close', { + buffer = event.buf, + silent = true, + desc = 'Quit buffer', + }) + end, +}) + +-- ── make it easier to close man-files when opened inline ──────────── +autocmd('FileType', { + group = augroup('man_unlisted', { clear = true }), + pattern = { 'man' }, + callback = function(event) vim.bo[event.buf].buflisted = false end, }) -- vim: ts=2 sts=2 sw=2 et diff --git a/config/nvim/lua/options.lua b/config/nvim/lua/options.lua index a392e3a..69b1d71 100644 --- a/config/nvim/lua/options.lua +++ b/config/nvim/lua/options.lua @@ -32,7 +32,10 @@ vim.opt.showmode = false -- Sync clipboard between OS and Neovim. -- Schedule the setting after `UiEnter` because it can increase startup-time. -- See `:help 'clipboard'` -vim.schedule(function() vim.opt.clipboard = 'unnamedplus' end) +vim.schedule(function() + local c = vim.env.SSH_TTY and '' or 'unnamedplus' + vim.opt.clipboard = c +end) vim.opt.breakindent = true -- Enable break indent vim.opt.smartindent = true -- Insert indents automatically @@ -92,7 +95,8 @@ vim.g.loaded_ruby_provider = 0 -- kevinhwang91/nvim-ufo settings vim.o.fillchars = [[eob: ,fold: ,foldopen:,foldsep: ,foldclose:]] vim.o.foldcolumn = '1' -- '0' is not bad -vim.o.foldlevel = 99 -- Using ufo provider need a large value, feel free to decrease the value +-- Using ufo provider need a large value, feel free to decrease the value +vim.o.foldlevel = 99 vim.o.foldlevelstart = 99 vim.o.foldenable = true @@ -111,7 +115,17 @@ vim.g.noice_ignored_filetypes = { -- ── Deal with word wrap ─────────────────────────────────────────────────────── local m = vim.api.nvim_set_keymap -m('n', 'k', "v:count == 0 ? 'gk' : 'k'", { desc = 'Move up', noremap = true, expr = true }) -m('n', 'j', "v:count == 0 ? 'gj' : 'j'", { desc = 'Move down', noremap = true, expr = true }) +m( + 'n', + 'k', + "v:count == 0 ? 'gk' : 'k'", + { desc = 'Move up', noremap = true, expr = true } +) +m( + 'n', + 'j', + "v:count == 0 ? 'gj' : 'j'", + { desc = 'Move down', noremap = true, expr = true } +) -- vim: ts=2 sts=2 sw=2 et diff --git a/config/nvim/lua/plugins/cmp.lua b/config/nvim/lua/plugins/cmp.lua index 5c2c51d..e660cd3 100644 --- a/config/nvim/lua/plugins/cmp.lua +++ b/config/nvim/lua/plugins/cmp.lua @@ -4,9 +4,11 @@ return { { 'hrsh7th/nvim-cmp', lazy = false, + version = false, -- Use the latest version of the plugin event = 'InsertEnter', dependencies = { 'hrsh7th/cmp-nvim-lsp', + -- ── LuaSnip Dependencies ──────────────────────────────────────────── -- Snippet Engine for Neovim written in Lua. -- https://github.com/L3MON4D3/LuaSnip @@ -14,6 +16,7 @@ return { -- luasnip completion source for nvim-cmp -- https://github.com/saadparwaiz1/cmp_luasnip { 'saadparwaiz1/cmp_luasnip' }, + -- ── Adds other completion capabilities. ───────────────────────────── -- ── nvim-cmp does not ship with all sources by default. -- ── They are split into multiple repos for maintenance purposes. @@ -23,6 +26,7 @@ return { -- cmp import and use all environment variables from .env.* and system -- https://github.com/SergioRibera/cmp-dotenv { 'SergioRibera/cmp-dotenv' }, + -- ── Other deps ────────────────────────────────────────────────────── -- vscode-like pictograms for neovim lsp completion items -- https://github.com/onsails/lspkind.nvim @@ -62,9 +66,15 @@ return { require('copilot_cmp').setup() local has_words_before = function() - if vim.api.nvim_get_option_value('buftype', {}) == 'prompt' then return false end + if vim.api.nvim_get_option_value('buftype', {}) == 'prompt' then + return false + end local line, col = table.unpack(vim.api.nvim_win_get_cursor(0)) - return col ~= 0 and vim.api.nvim_buf_get_text(0, line - 1, 0, line - 1, col, {})[1]:match '^%s*$' == nil + return col ~= 0 + and vim.api + .nvim_buf_get_text(0, line - 1, 0, line - 1, col, {})[1] + :match '^%s*$' + == nil end cmp.setup { @@ -75,6 +85,8 @@ return { show_labelDetails = true, symbol_map = { Copilot = '', + Text = '', + Constructor = '', }, }, }, diff --git a/config/nvim/lua/plugins/lsp.lua b/config/nvim/lua/plugins/lsp.lua index 5211228..3e411a5 100644 --- a/config/nvim/lua/plugins/lsp.lua +++ b/config/nvim/lua/plugins/lsp.lua @@ -19,9 +19,6 @@ return { -- Extension to mason.nvim that makes it easier to use lspconfig with mason.nvim. -- https://github.com/williamboman/mason-lspconfig.nvim { 'williamboman/mason-lspconfig.nvim' }, - -- Install and upgrade third party tools automatically - -- https://github.com/WhoIsSethDaniel/mason-tool-installer.nvim - { 'WhoIsSethDaniel/mason-tool-installer.nvim' }, -- ── Formatting ────────────────────────────────────────────────────── -- Lightweight yet powerful formatter plugin for Neovim @@ -30,33 +27,81 @@ return { 'stevearc/conform.nvim', event = { 'BufWritePre' }, cmd = { 'ConformInfo' }, - opts = { - formatters_by_ft = { - lua = { 'stylua' }, - -- Conform will run multiple formatters sequentially - -- python = { 'isort', 'black', lsp_format = 'fallback' }, - -- You can customize some of the format options for the filetype (:help conform.format) - -- rust = { 'rustfmt', lsp_format = 'fallback' }, - -- Conform will run the first available formatter - javascript = { 'prettier', 'eslint', stop_after_first = true }, - }, - notify_on_error = true, - format_on_save = function(bufnr) - -- Disable "format_on_save lsp_fallback" for languages that don't - -- have a well standardized coding style. You can add additional - -- languages here or re-enable it for the disabled ones. - local disable_filetypes = { c = true, cpp = true } - return { - -- formatters = { 'injected' }, - lsp_fallback = not disable_filetypes[vim.bo[bufnr].filetype], - timeout_ms = 500, - } - end, - }, + config = function() + -- Select first conform formatter that is available + ---@param bufnr integer + ---@param ... string + ---@return string + local function first(bufnr, ...) + local conform = require 'conform' + for i = 1, select('#', ...) do + local formatter = select(i, ...) + if conform.get_formatter_info(formatter, bufnr).available then + return formatter + end + end + return select(1, ...) + end + + require('conform').setup { + -- Enable or disable logging + notify_on_error = true, + -- Set the default formatter for all filetypes + default_formatter = 'injected', + -- Set the default formatter for all filetypes + default_formatter_opts = { + lsp_format = 'fallback', + -- Set the default formatter for all filetypes + -- formatter = 'injected', + -- Set the default formatter for all filetypes + -- formatter_opts = {}, + }, + formatters_by_ft = { + markdown = function(bufnr) + return { first(bufnr, 'prettierd', 'prettier'), 'injected' } + end, + javascript = function(bufnr) + return { first(bufnr, 'prettier', 'eslint'), 'injected' } + end, + lua = { 'stylua' }, + -- Conform will run multiple formatters sequentially + -- python = { 'isort', 'black', lsp_format = 'fallback' }, + -- You can customize some of the format options for the filetype (:help conform.format) + -- rust = { 'rustfmt', lsp_format = 'fallback' }, + }, + format_on_save = function(bufnr) + -- Disable autoformat on certain filetypes + local ignore_filetypes = { + 'c', + 'cpp', + 'sql', + 'java', + } + if vim.tbl_contains(ignore_filetypes, vim.bo[bufnr].filetype) then + return + end + -- Disable with a global or buffer-local variable + if + vim.g.disable_autoformat or vim.b[bufnr].disable_autoformat + then + return + end + -- Disable autoformat for files in a certain path + local bufname = vim.api.nvim_buf_get_name(bufnr) + if bufname:match '/node_modules/' then return end + if bufname:match '/vendor/' then return end + if bufname:match '/dist/' then return end + if bufname:match '/build/' then return end + + return { timeout_ms = 500, lsp_format = 'fallback' } + end, + } + end, + init = function() + -- If you want the formatexpr, here is the place to set it + vim.o.formatexpr = "v:lua.require'conform'.formatexpr()" + end, }, - -- Automatically install formatters registered with conform.nvim via mason.nvim - -- https://github.com/zapling/mason-conform.nvim - { 'zapling/mason-conform.nvim' }, -- ── Misc ──────────────────────────────────────────────────────────── -- vscode-like pictograms for neovim lsp completion items @@ -82,20 +127,28 @@ return { ---@output nil local on_attach = function(_, bufnr) -- Create a command `:Format` local to the LSP buffer - vim.api.nvim_buf_create_user_command(bufnr, 'Format', function(_) - require('conform').format { formatters = { 'injected' }, async = true, lsp_fallback = true } - - -- if vim.lsp.buf.format then - -- vim.lsp.buf.format() - -- elseif vim.lsp.buf.formatting then - -- vim.lsp.buf.formatting() - -- end - end, { desc = 'Format current buffer with LSP' }) + vim.api.nvim_create_user_command('Format', function(args) + local range = nil + if args.count ~= -1 then + local end_line = vim.api.nvim_buf_get_lines( + bufnr, + args.line2 - 1, + args.line2, + true + )[1] + range = { + start = { args.line1, 0 }, + ['end'] = { args.line2, end_line:len() }, + } + end + require('conform').format { + async = true, + lsp_format = 'fallback', + range = range, + } + end, { range = true, desc = 'Format current buffer with LSP' }) end - -- ── Setup mason so it can manage external tooling ─────────────────── - require('mason').setup() - -- ── Enable the following language servers ─────────────────────────── -- :help lspconfig-all for all pre-configured LSPs local servers = { @@ -106,6 +159,7 @@ return { intelephense = {}, -- PHP tailwindcss = {}, -- Tailwind CSS ts_ls = {}, -- TypeScript + volar = {}, -- Vue lua_ls = { settings = { @@ -184,10 +238,10 @@ return { local ensure_installed = vim.tbl_keys(servers or {}) vim.list_extend(ensure_installed, mason_servers) - -- ── Automagically install tools ───────────────────────────────────── - require('mason-tool-installer').setup { + -- ── Setup mason so it can manage external tooling ─────────────────── + require('mason').setup { ensure_installed = ensure_installed, - auto_update = true, + automatic_installation = true, } -- nvim-cmp supports additional completion capabilities @@ -200,6 +254,15 @@ return { lineFoldingOnly = true, } + capabilities.textDocument.completion.completionItem.snippetSupport = true + capabilities.textDocument.completion.completionItem.resolveSupport = { + properties = { + 'documentation', + 'detail', + 'additionalTextEdits', + }, + } + local lspconfig_handlers = { -- The first entry (without a key) will be the default handler -- and will be called for each installed server that doesn't have @@ -211,8 +274,12 @@ return { } end, -- Next, you can provide targeted overrides for specific servers. - ['lua_ls'] = function() require('lspconfig')['lua_ls'].setup { settings = servers.lua_ls } end, - ['jsonls'] = function() require('lspconfig')['jsonls'].setup { settings = servers.jsonls } end, + ['lua_ls'] = function() + require('lspconfig')['lua_ls'].setup { settings = servers.lua_ls } + end, + ['jsonls'] = function() + require('lspconfig')['jsonls'].setup { settings = servers.jsonls } + end, } require('mason-lspconfig').setup { @@ -220,21 +287,6 @@ return { automatic_installation = true, handlers = lspconfig_handlers, } - - vim.api.nvim_create_autocmd('FileType', { - pattern = 'sh', - callback = function() - vim.lsp.start { - name = 'bash-language-server', - cmd = { 'bash-language-server', 'start' }, - } - end, - }) - - -- ── Setup formatting ──────────────────────────────────────────────── - require('mason-conform').setup { - -- ignore_install = { 'prettier' }, -- List of formatters to ignore during install - } end, }, @@ -309,80 +361,71 @@ return { end, }, }, - config = function() - local capabilities = vim.lsp.protocol.make_client_capabilities() - capabilities.textDocument.foldingRange = { - dynamicRegistration = false, - lineFoldingOnly = true, - } - local language_servers = require('lspconfig').util.available_servers() -- or list servers manually like {'gopls', 'clangd'} - for _, ls in ipairs(language_servers) do - require('lspconfig')[ls].setup { - capabilities = capabilities, - -- you can add other fields for setting up lsp server in this table - } - end - - require('ufo').setup { - open_fold_hl_timeout = 150, - close_fold_kinds_for_ft = { 'imports', 'comment' }, - preview = { - win_config = { - border = { '', '─', '', '', '', '─', '', '' }, - winhighlight = 'Normal:Folded', - winblend = 0, - }, - mappings = { - scrollU = '', - scrollD = '', - jumpTop = '[', - jumpBot = ']', - }, + opts = { + open_fold_hl_timeout = 150, + close_fold_kinds_for_ft = { 'imports', 'comment' }, + preview = { + win_config = { + border = { '', '─', '', '', '', '─', '', '' }, + winhighlight = 'Normal:Folded', + winblend = 0, }, + mappings = { + scrollU = '', + scrollD = '', + jumpTop = '[', + jumpBot = ']', + }, + }, - provider_selector = function(_, _, _) -- bufnr, filetype, buftype - return { 'treesitter', 'indent' } - end, + provider_selector = function(_, _, _) -- bufnr, filetype, buftype + return { 'treesitter', 'indent' } + end, - -- fold_virt_text_handler - -- - -- This handler is called when the fold text is too long to fit in the window. - -- It is expected to truncate the text and return a new list of virtual text. - -- - ---@param virtText table The current virtual text list. - ---@param lnum number The line number of the first line in the fold. - ---@param endLnum number The line number of the last line in the fold. - ---@param width number The width of the window. - ---@param truncate function Truncate function - ---@return table - fold_virt_text_handler = function(virtText, lnum, endLnum, width, truncate) - local newVirtText = {} - local suffix = (' 󰁂 %d '):format(endLnum - lnum) - local sufWidth = vim.fn.strdisplaywidth(suffix) - local targetWidth = width - sufWidth - local curWidth = 0 - for _, chunk in ipairs(virtText) do - local chunkText = chunk[1] - local chunkWidth = vim.fn.strdisplaywidth(chunkText) - if targetWidth > curWidth + chunkWidth then - table.insert(newVirtText, chunk) - else - chunkText = truncate(chunkText, targetWidth - curWidth) - local hlGroup = chunk[2] - table.insert(newVirtText, { chunkText, hlGroup }) - chunkWidth = vim.fn.strdisplaywidth(chunkText) - -- str width returned from truncate() may less than 2nd argument, need padding - if curWidth + chunkWidth < targetWidth then - suffix = suffix .. (' '):rep(targetWidth - curWidth - chunkWidth) - end - break + -- fold_virt_text_handler + -- + -- This handler is called when the fold text is too long to fit in the window. + -- It is expected to truncate the text and return a new list of virtual text. + -- + ---@param virtText table The current virtual text list. + ---@param lnum number The line number of the first line in the fold. + ---@param endLnum number The line number of the last line in the fold. + ---@param width number The width of the window. + ---@param truncate function Truncate function + ---@return table + fold_virt_text_handler = function( + virtText, + lnum, + endLnum, + width, + truncate + ) + local newVirtText = {} + local suffix = (' 󰁂 %d '):format(endLnum - lnum) + local sufWidth = vim.fn.strdisplaywidth(suffix) + local targetWidth = width - sufWidth + local curWidth = 0 + for _, chunk in ipairs(virtText) do + local chunkText = chunk[1] + local chunkWidth = vim.fn.strdisplaywidth(chunkText) + if targetWidth > curWidth + chunkWidth then + table.insert(newVirtText, chunk) + else + chunkText = truncate(chunkText, targetWidth - curWidth) + local hlGroup = chunk[2] + table.insert(newVirtText, { chunkText, hlGroup }) + chunkWidth = vim.fn.strdisplaywidth(chunkText) + -- str width returned from truncate() may less than 2nd argument, need padding + if curWidth + chunkWidth < targetWidth then + suffix = suffix .. (' '):rep(targetWidth - curWidth - chunkWidth) end - curWidth = curWidth + chunkWidth + break end - table.insert(newVirtText, { suffix, 'MoreMsg' }) - return newVirtText - end, - } - end, + curWidth = curWidth + chunkWidth + end + table.insert(newVirtText, { suffix, 'MoreMsg' }) + return newVirtText + end, + }, }, } diff --git a/config/nvim/lua/plugins/treesitter.lua b/config/nvim/lua/plugins/treesitter.lua index 8b74a0f..1fbf9b0 100644 --- a/config/nvim/lua/plugins/treesitter.lua +++ b/config/nvim/lua/plugins/treesitter.lua @@ -2,7 +2,10 @@ -- https://github.com/nvim-treesitter/nvim-treesitter return { 'nvim-treesitter/nvim-treesitter', - build = function() pcall(require('nvim-treesitter.install').update { with_sync = true }) end, + version = false, -- last release is way too old and doesn't work on Windows + build = function() + pcall(require('nvim-treesitter.install').update { with_sync = true }) + end, dependencies = { 'nvim-treesitter/nvim-treesitter-textobjects', }, diff --git a/config/nvim/lua/plugins/ui.lua b/config/nvim/lua/plugins/ui.lua index fdbf097..8b719cc 100644 --- a/config/nvim/lua/plugins/ui.lua +++ b/config/nvim/lua/plugins/ui.lua @@ -34,18 +34,14 @@ return { event = 'VimEnter', config = function() require('dashboard').setup { + theme = 'doom', config = { disable_move = true, week_header = { enable = true, }, - shortcut = { - { - desc = '󰊳 Lazy Update', - group = '@property', - action = 'Lazy update', - key = 'u', - }, + shortcut = {}, + center = { { icon = ' ', icon_hl = '@variable', @@ -55,23 +51,33 @@ return { key = 'f', }, { - desc = ' Marks', + icon = ' ', + desc = 'Marks', group = 'DiagnosticHint', action = 'Telescope harpoon marks', key = 'a', }, { - desc = '⚑ TODO', + icon = '⚑ ', + desc = 'TODO', group = 'DiagnosticOptions', action = 'TodoTelescope', key = 't', }, { - desc = '🔍 Search', + icon = ' ', + desc = 'Search', group = 'Number', action = 'Telescope live_grep', key = 's', }, + { + icon = '󰊳 ', + desc = 'Lazy Update', + group = '@property', + action = 'Lazy update', + key = 'u', + }, }, }, } @@ -110,6 +116,7 @@ return { -- https://github.com/lewis6991/gitsigns.nvim { 'lewis6991/gitsigns.nvim', + version = false, lazy = false, opts = { signs = { @@ -228,7 +235,10 @@ return { -- https://github.com/MeanderingProgrammer/render-markdown.nvim { 'MeanderingProgrammer/render-markdown.nvim', - dependencies = { 'nvim-treesitter/nvim-treesitter', 'nvim-tree/nvim-web-devicons' }, + dependencies = { + 'nvim-treesitter/nvim-treesitter', + 'nvim-tree/nvim-web-devicons', + }, ft = 'markdown', opts = {}, }, diff --git a/config/nvim/lua/plugins/which-key.lua b/config/nvim/lua/plugins/which-key.lua index 84c6fb0..15b05eb 100644 --- a/config/nvim/lua/plugins/which-key.lua +++ b/config/nvim/lua/plugins/which-key.lua @@ -27,31 +27,67 @@ return { return require('which-key.extras').expand.buf() end, }, - { 'bk', 'blast', desc = 'Buffer: Last' }, - { 'bj', 'bfirst', desc = 'Buffer: First' }, - { 'bh', 'bprev', desc = 'Buffer: Prev' }, - { 'bl', 'bnext', desc = 'Buffer: Next' }, - { 'bd', 'Bdelete', desc = 'Buffer: Delete' }, - { 'bw', 'Bwipeout', desc = 'Buffer: Wipeout' }, + { + { 'bk', 'blast', desc = 'Buffer: Last' }, + { 'bj', 'bfirst', desc = 'Buffer: First' }, + { 'bh', 'bprev', desc = 'Buffer: Prev' }, + { 'bl', 'bnext', desc = 'Buffer: Next' }, + { 'bd', 'Bdelete', desc = 'Buffer: Delete' }, + { 'bw', 'Bwipeout', desc = 'Buffer: Wipeout' }, + }, -- ── Code ──────────────────────────────────────────────────────────── { 'c', group = '[c] Code' }, - { 'ca', 'lua vim.lsp.buf.code_action()', desc = 'LSP: Code Action' }, - { 'cg', 'lua require("neogen").generate()', desc = 'Generate annotations' }, + { + { + 'ca', + 'lua vim.lsp.buf.code_action()', + desc = 'LSP: Code Action', + }, + { + 'cg', + 'lua require("neogen").generate()', + desc = 'Generate annotations', + }, + }, -- ── Code: CommentBox ──────────────────────────────────────────────── - { 'cb', group = 'CommentBox' }, - { 'cbb', 'CBccbox', desc = 'CommentBox: Box Title' }, - { 'cbd', 'CBd', desc = 'CommentBox: Remove a box' }, - { 'cbl', 'CBline', desc = 'CommentBox: Simple Line' }, - { 'cbm', 'CBllbox14', desc = 'CommentBox: Marked' }, - { 'cbt', 'CBllline', desc = 'CommentBox: Titled Line' }, + { + { 'cb', group = 'CommentBox' }, + { 'cbb', 'CBccbox', desc = 'CommentBox: Box Title' }, + { 'cbd', 'CBd', desc = 'CommentBox: Remove a box' }, + { 'cbl', 'CBline', desc = 'CommentBox: Simple Line' }, + { 'cbm', 'CBllbox14', desc = 'CommentBox: Marked' }, + { + 'cbt', + 'CBllline', + desc = 'CommentBox: Titled Line', + }, + }, -- ── Code: package.json control ────────────────────────────────────── -- See: lua/plugins/lazy.lua { 'cn', group = 'package.json control' }, - { 'cnd', 'lua require("package-info").delete()', desc = 'Delete package' }, - { 'cni', 'lua require("package-info").install()', desc = 'Install package' }, - { 'cns', 'lua require("package-info").show({ force = true })', desc = 'Show package info' }, - { 'cnu', 'lua require("package-info").change_version()', desc = 'Change version' }, + { + { + 'cnd', + 'lua require("package-info").delete()', + desc = 'Delete package', + }, + { + 'cni', + 'lua require("package-info").install()', + desc = 'Install package', + }, + { + 'cns', + 'lua require("package-info").show({ force = true })', + desc = 'Show package info', + }, + { + 'cnu', + 'lua require("package-info").change_version()', + desc = 'Change version', + }, + }, -- ── Code: Refactoring ─────────────────────────────────────────────── { 'cx', group = '[x] Refactoring' }, @@ -77,7 +113,7 @@ return { }, -- Inline func supports only normal { - 'cxi', + 'cxif', "lua require('refactoring').refactor('Inline Function')", desc = 'Inline Function', }, @@ -96,7 +132,7 @@ return { mode = { 'n', 'x' }, -- Inline var supports both normal and visual mode { - 'cxi', + 'cxiv', "lua require('refactoring').refactor('Inline Variable')", desc = 'Inline Variable', }, @@ -104,49 +140,141 @@ return { -- ── Code: LSPSaga ─────────────────────────────────────────────────── -- See: lua/plugins/lsp.lua - { '', 'Lspsaga term_toggle', desc = 'LSPSaga: Open Floaterm' }, - { 'ca', 'Lspsaga code_action', desc = 'LSPSaga: Code Actions' }, - { 'cci', 'Lspsaga incoming_calls', desc = 'LSPSaga: Incoming Calls' }, - { 'cco', 'Lspsaga outgoing_calls', desc = 'LSPSaga: Outgoing Calls' }, - { 'cd', 'Lspsaga show_line_diagnostics', desc = 'LSPSaga: Show Line Diagnostics' }, + { + '', + 'Lspsaga term_toggle', + desc = 'LSPSaga: Open Floaterm', + }, + { + 'ca', + 'Lspsaga code_action', + desc = 'LSPSaga: Code Actions', + }, + { + 'cci', + 'Lspsaga incoming_calls', + desc = 'LSPSaga: Incoming Calls', + }, + { + 'cco', + 'Lspsaga outgoing_calls', + desc = 'LSPSaga: Outgoing Calls', + }, + { + 'cd', + 'Lspsaga show_line_diagnostics', + desc = 'LSPSaga: Show Line Diagnostics', + }, { 'cf', 'lua require("conform").format({ async = true, lsp_fallback = true })', mode = { 'n', 'v' }, desc = 'Format buffer', }, - { 'ci', 'Lspsaga implement', desc = 'LSPSaga: Implementations' }, - { 'cl', 'Lspsaga show_cursor_diagnostics', desc = 'LSPSaga: Show Cursor Diagnostics' }, - { 'cp', 'Lspsaga peek_definition', desc = 'LSPSaga: Peek Definition' }, + { + 'ci', + 'Lspsaga implement', + desc = 'LSPSaga: Implementations', + }, + { + 'cl', + 'Lspsaga show_cursor_diagnostics', + desc = 'LSPSaga: Show Cursor Diagnostics', + }, + { + 'cp', + 'Lspsaga peek_definition', + desc = 'LSPSaga: Peek Definition', + }, { 'cr', 'Lspsaga rename', desc = 'LSPSaga: Rename' }, - { 'cR', 'Lspsaga rename ++project', desc = 'LSPSaga: Rename Project wide' }, - { 'cs', 'Lspsaga signature_help', desc = 'LSPSaga: Signature Documentation' }, - { 'ct', 'Lspsaga peek_type_definition', desc = 'LSPSaga: Peek Type Definition' }, - { 'cu', 'Lspsaga preview_definition', desc = 'LSPSaga: Preview Definition' }, - { 'cv', 'Lspsaga diagnostic_jump_prev', desc = 'LSPSaga: Diagnostic Jump Prev' }, - { 'cw', 'Lspsaga diagnostic_jump_next', desc = 'LSPSaga: Diagnostic Jump Next' }, + { + 'cR', + 'Lspsaga rename ++project', + desc = 'LSPSaga: Rename Project wide', + }, + { + 'cs', + 'Lspsaga signature_help', + desc = 'LSPSaga: Signature Documentation', + }, + { + 'ct', + 'Lspsaga peek_type_definition', + desc = 'LSPSaga: Peek Type Definition', + }, + { + 'cu', + 'Lspsaga preview_definition', + desc = 'LSPSaga: Preview Definition', + }, + { + 'cv', + 'Lspsaga diagnostic_jump_prev', + desc = 'LSPSaga: Diagnostic Jump Prev', + }, + { + 'cw', + 'Lspsaga diagnostic_jump_next', + desc = 'LSPSaga: Diagnostic Jump Next', + }, -- ── DAP ───────────────────────────────────────────────────────────── { 'd', group = '[d] DAP' }, - { 'db', 'DapToggleBreakpoint', desc = 'DAP: Toggle Breakpoint' }, - { 'dc', 'DapContinue', desc = 'DAP: Continue' }, - { 'do', 'lua vim.diagnostic.open_float()', desc = 'Diagnostic: Open float' }, - { 'dq', 'lua vim.diagnostic.setloclist()', desc = 'Diagnostic: Set loc list' }, - { 'dr', "lua require('dapui').open({reset = true})", desc = 'DAP: Reset' }, { - 'ds', - 'lua require("telescope.builtin").lsp_document_symbols()', - desc = 'LSP: Document Symbols', + { + 'db', + 'DapToggleBreakpoint', + desc = 'DAP: Toggle Breakpoint', + }, + { 'dc', 'DapContinue', desc = 'DAP: Continue' }, + { + 'do', + 'lua vim.diagnostic.open_float()', + desc = 'Diagnostic: Open float', + }, + { + 'dq', + 'lua vim.diagnostic.setloclist()', + desc = 'Diagnostic: Set loc list', + }, + { + 'dr', + "lua require('dapui').open({reset = true})", + desc = 'DAP: Reset', + }, + { + 'ds', + 'lua require("telescope.builtin").lsp_document_symbols()', + desc = 'LSP: Document Symbols', + }, + { 'dt', 'DapUiToggle', desc = 'DAP: Toggle UI' }, }, - { 'dt', 'DapUiToggle', desc = 'DAP: Toggle UI' }, -- ── Harpoon ───────────────────────────────────────────────────────── -- See: lua/plugins/telescope.lua { 'h', group = '[h] Harpoon' }, - { 'ha', 'lua require("harpoon"):list():add()', desc = 'harpoon file' }, - { 'hn', 'lua require("harpoon"):list():next()', desc = 'harpoon to next file' }, - { 'hp', 'lua require("harpoon"):list():prev()', desc = 'harpoon to previous file' }, - { 'ht', "lua require('harpoon.ui').toggle_quick_menu()", desc = 'DAP: Harpoon UI' }, + { + { + 'ha', + 'lua require("harpoon"):list():add()', + desc = 'harpoon file', + }, + { + 'hn', + 'lua require("harpoon"):list():next()', + desc = 'harpoon to next file', + }, + { + 'hp', + 'lua require("harpoon"):list():prev()', + desc = 'harpoon to previous file', + }, + { + 'ht', + "lua require('harpoon.ui').toggle_quick_menu()", + desc = 'DAP: Harpoon UI', + }, + }, -- ── LSP ───────────────────────────────────────────────────────────── { 'l', group = '[l] LSP' }, @@ -154,74 +282,164 @@ return { -- ── Quit ──────────────────────────────────────────────────────────── { 'q', group = '[q] Quit' }, - { 'qf', 'q', desc = 'Quicker close split' }, - { 'qq', 'wq!', desc = 'Quit with force saving' }, - { 'qw', 'wq', desc = 'Write and quit' }, + { + { 'qf', 'q', desc = 'Quicker close split' }, + { 'qq', 'wq!', desc = 'Quit with force saving' }, + { 'qw', 'wq', desc = 'Write and quit' }, + }, -- ── Search ────────────────────────────────────────────────────────── { 's', group = '[s] Search' }, -- See: lua/plugins/telescope.lua - { '', "lua require('telescope.builtin').buffers()", desc = 'Find existing buffers' }, - { '', "lua require('telescope.builtin').commands()", desc = 'Telescope: Commands' }, - { 'sd', "lua require('telescope.builtin').diagnostics()", desc = 'Search Diagnostics' }, - { 'sg', "lua require('telescope.builtin').live_grep()", desc = 'Search by Grep' }, - { 'sm', 'Telescope harpoon marks', desc = 'Harpoon Marks' }, - { 'sn', "lua require('telescope').extensions.notify.notify()", desc = 'Notify' }, - { 'so', "lua require('telescope.builtin').oldfiles()", desc = 'Find recently Opened files' }, + { + '', + "lua require('telescope.builtin').buffers()", + desc = 'Find existing buffers', + }, + { + '', + "lua require('telescope.builtin').commands()", + desc = 'Telescope: Commands', + }, + { + 'sd', + "lua require('telescope.builtin').diagnostics()", + desc = 'Search Diagnostics', + }, + { + 'sg', + "lua require('telescope.builtin').live_grep()", + desc = 'Search by Grep', + }, + { + 'sm', + 'Telescope harpoon marks', + desc = 'Harpoon Marks', + }, + { + 'sn', + "lua require('telescope').extensions.notify.notify()", + desc = 'Show Notifications', + }, + { + 'so', + "lua require('telescope.builtin').oldfiles()", + desc = 'Find recently Opened files', + }, { 'sp', "lua require('telescope').extensions.lazy_plugins.lazy_plugins()", desc = 'Find neovim/lazy configs', }, - { 'st', 'TodoTelescope', desc = 'Telescope: Todo' }, - { 'sw', "lua require('telescope.builtin').grep_string()", desc = 'Search current Word' }, + { 'st', 'TodoTelescope', desc = 'Telescope: Show Todo' }, + { + 'sw', + "lua require('telescope.builtin').grep_string()", + desc = 'Search current Word', + }, -- ── Toggle ────────────────────────────────────────────────────────── { 't', group = '[t] Toggle' }, - { 'tc', 'CloakToggle', desc = 'Toggle Cloak' }, - { 'tn', 'Noice dismiss', desc = 'Noice dismiss' }, - { 'ts', 'noh', desc = 'Toggle Search Highlighting' }, - { 'tt', 'TransparentToggle', desc = 'Toggle Transparency' }, - { 'tw', 'Twilight', desc = 'Toggle Twilight' }, + { + { 'tc', 'CloakToggle', desc = 'Toggle Cloak' }, + { 'tn', 'Noice dismiss', desc = 'Noice dismiss' }, + { 'ts', 'noh', desc = 'Toggle Search Highlighting' }, + { + 'tt', + 'TransparentToggle', + desc = 'Toggle Transparency', + }, + { 'tw', 'Twilight', desc = 'Toggle Twilight' }, + }, -- ── Workspace ─────────────────────────────────────────────────────── { 'w', group = '[w] Workspace' }, - { 'wa', 'lua vim.lsp.buf.add_workspace_folder()', desc = 'LSP: Workspace Add Folder' }, { - 'wl', - 'lua print(vim.inspect(vim.lsp.buf.list_workspace_folders()))', - desc = 'LSP: Workspace List Folders', - }, - { 'wr', 'lua vim.lsp.buf.remove_workspace_folder()', desc = 'LSP: Workspace Remove Folder' }, - { - 'ws', - 'lua require("telescope.builtin").lsp_dynamic_workspace_symbols()', - desc = 'LSP: Workspace Symbols', + { + 'wa', + 'lua vim.lsp.buf.add_workspace_folder()', + desc = 'LSP: Workspace Add Folder', + }, + { + 'wl', + 'lua print(vim.inspect(vim.lsp.buf.list_workspace_folders()))', + desc = 'LSP: Workspace List Folders', + }, + { + 'wr', + 'lua vim.lsp.buf.remove_workspace_folder()', + desc = 'LSP: Workspace Remove Folder', + }, + { + 'ws', + 'lua require("telescope.builtin").lsp_dynamic_workspace_symbols()', + desc = 'LSP: Workspace Symbols', + }, }, -- ── Trouble ───────────────────────────────────────────────────────── { 'x', group = '[x] Trouble' }, - { 'xx', 'Trouble', desc = 'Toggle Trouble' }, - { 'xw', 'Trouble workspace_diagnostics', desc = 'Toggle Workspace Diagnostics' }, - { 'xd', 'Trouble document_diagnostics', desc = 'Toggle Document Diagnostics' }, - { 'xl', 'Trouble loclist', desc = 'Toggle Loclist' }, - { 'xq', 'Trouble quickfix', desc = 'Toggle Quickfix' }, + { + { + 'xx', + 'Trouble diagnostics', + desc = 'Toggle Trouble Diagnostics', + }, + { + 'xw', + 'Trouble workspace_diagnostics', + desc = 'Toggle Workspace Diagnostics', + }, + { + 'xd', + 'Trouble document_diagnostics', + desc = 'Toggle Document Diagnostics', + }, + { 'xl', 'Trouble loclist', desc = 'Toggle Loclist' }, + { 'xq', 'Trouble quickfix', desc = 'Toggle Quickfix' }, + }, -- ── Help ──────────────────────────────────────────────────────────── { '?', group = '[?] Help & Cheat sheets' }, { - '?w', - 'lua require("which-key").show({global = false})', - desc = 'Buffer Local Keymaps (which-key)', + { + '?w', + 'lua require("which-key").show({global = false})', + desc = 'Buffer Local Keymaps (which-key)', + }, }, -- ── Misc ──────────────────────────────────────────────────────────── - { '1', 'lua require("harpoon"):list():select(1)', desc = 'harpoon to file 1' }, - { '2', 'lua require("harpoon"):list():select(2)', desc = 'harpoon to file 2' }, - { '3', 'lua require("harpoon"):list():select(3)', desc = 'harpoon to file 3' }, - { '4', 'lua require("harpoon"):list():select(4)', desc = 'harpoon to file 4' }, - { '5', 'lua require("harpoon"):list():select(5)', desc = 'harpoon to file 5' }, - { 'D', 'lua vim.lsp.buf.type_definition()', desc = 'LSP: Type Definition' }, + { + '1', + 'lua require("harpoon"):list():select(1)', + desc = 'harpoon to file 1', + }, + { + '2', + 'lua require("harpoon"):list():select(2)', + desc = 'harpoon to file 2', + }, + { + '3', + 'lua require("harpoon"):list():select(3)', + desc = 'harpoon to file 3', + }, + { + '4', + 'lua require("harpoon"):list():select(4)', + desc = 'harpoon to file 4', + }, + { + '5', + 'lua require("harpoon"):list():select(5)', + desc = 'harpoon to file 5', + }, + { + 'D', + 'lua vim.lsp.buf.type_definition()', + desc = 'LSP: Type Definition', + }, { 'e', 'Neotree reveal', desc = 'NeoTree reveal' }, -- ╭─────────────────────────────────────────────────────────╮ @@ -230,16 +448,48 @@ return { { 'y', group = 'Yank & Surround' }, { 'gp', group = 'Goto Preview' }, - { 'gpd', 'lua require("goto-preview").goto_preview_definition()' }, - { 'gpi', 'lua require("goto-preview").goto_preview_implementation()' }, - { 'gpP', 'lua require("goto-preview").close_all_windows()' }, + { + { + 'gpd', + 'lua require("goto-preview").goto_preview_definition()', + desc = 'Goto: Preview Definition', + }, + { + 'gpi', + 'lua require("goto-preview").goto_preview_implementation()', + desc = 'Goto: Preview Implementation', + }, + { + 'gpP', + 'lua require("goto-preview").close_all_windows()', + desc = 'Goto: Close All Preview Windows', + }, + }, -- ── tmux navigation ───────────────────────────────────────────────── - { '', 'TmuxNavigateLeft', desc = 'tmux: Navigate Left' }, - { '', 'TmuxNavigateDown', desc = 'tmux: Navigate Down' }, - { '', 'TmuxNavigateUp', desc = 'tmux: Navigate Up' }, - { '', 'TmuxNavigateRight', desc = 'tmux: Navigate Right' }, - { '', 'TmuxNavigatePrevious', desc = 'tmux: Navigate Previous' }, + { + { + '', + 'TmuxNavigateLeft', + desc = 'tmux: Navigate Left', + }, + { + '', + 'TmuxNavigateDown', + desc = 'tmux: Navigate Down', + }, + { '', 'TmuxNavigateUp', desc = 'tmux: Navigate Up' }, + { + '', + 'TmuxNavigateRight', + desc = 'tmux: Navigate Right', + }, + { + '', + 'TmuxNavigatePrevious', + desc = 'tmux: Navigate Previous', + }, + }, -- ── Old habits ────────────────────────────────────────────────────── { '', 'w', desc = 'Save file' }, @@ -254,23 +504,75 @@ return { }, -- ── LSP ───────────────────────────────────────────────────────────── - { '', 'lua vim.lsp.buf.signature_help()', desc = 'LSP: Signature Documentation' }, - { 'K', 'Lspsaga hover_doc', desc = 'LSPSaga: Hover Documentation' }, - { 'dn', 'lua vim.diagnostic.goto_next()', desc = 'Diagnostic: Goto Next' }, - { 'dp', 'lua vim.diagnostic.goto_prev()', desc = 'Diagnostic: Goto Prev' }, - { 'gD', 'lua vim.lsp.buf.declaration()', desc = 'LSP: Goto Declaration' }, - { 'gI', 'lua vim.lsp.buf.implementation()', desc = 'LSP: Goto Implementation' }, - { 'gR', 'Trouble lsp_references', desc = 'Toggle LSP References' }, - { 'gd', 'lua vim.lsp.buf.definition()', desc = 'LSP: Goto Definition' }, - { 'gr', 'lua require("telescope.builtin").lsp_references()', desc = 'LSP: Goto References' }, + { + '', + 'lua vim.lsp.buf.signature_help()', + desc = 'LSP: Signature Documentation', + }, + { + 'K', + 'Lspsaga hover_doc', + desc = 'LSPSaga: Hover Documentation', + }, + + { 'd', group = 'Diagnostics' }, + { + { + 'dn', + 'lua vim.diagnostic.goto_next()', + desc = 'Diagnostic: Goto Next', + }, + { + 'dp', + 'lua vim.diagnostic.goto_prev()', + desc = 'Diagnostic: Goto Prev', + }, + }, + { + { 'g', group = 'Goto' }, + { + 'gD', + 'lua vim.lsp.buf.declaration()', + desc = 'LSP: Goto Declaration', + }, + { + 'gI', + 'lua vim.lsp.buf.implementation()', + desc = 'LSP: Goto Implementation', + }, + { + 'gR', + 'Trouble lsp_references', + desc = 'Toggle LSP References', + }, + { + 'gd', + 'lua vim.lsp.buf.definition()', + desc = 'LSP: Goto Definition', + }, + { + 'gr', + 'lua require("telescope.builtin").lsp_references()', + desc = 'LSP: Goto References', + }, + }, -- ── Misc keybinds ─────────────────────────────────────────────────── -- Sublime-like shortcut 'go to file' ctrl+p. - { '', 'Telescope find_files', desc = 'Search for files starting at current directory.' }, + { + '', + 'Telescope find_files', + desc = 'Search for files starting at current directory.', + }, { 'QQ', 'q!', desc = 'Quit without saving' }, { 'WW', 'w!', desc = 'Force write to file' }, { 'ss', 'noh', desc = 'Clear Search Highlighting' }, - { 'jj', '', desc = 'Esc without touching esc in insert mode', mode = 'i' }, + { + 'jj', + '', + desc = 'Esc without touching esc in insert mode', + mode = 'i', + }, -- ── Splits ────────────────────────────────────────────────────────── -- Use CTRL+ to switch between windows in normal mode @@ -290,12 +592,13 @@ return { { '', 'echo "Use j to move!!"' }, -- ── Terminal ──────────────────────────────────────────────────────── - -- Exit terminal mode in the builtin terminal with a shortcut that is a bit easier - -- for people to discover. Otherwise, you normally need to press , which - -- is not what someone will guess without a bit more experience. + -- Exit terminal mode in the builtin terminal with a shortcut that is + -- a bit easier for people to discover. Otherwise, you normally need + -- to press , which is not what someone will guess without + -- a bit more experience. -- - -- NOTE: This won't work in all terminal emulators/tmux/etc. Try your own mapping - -- or just use to exit terminal mode. + -- NOTE: This won't work in all terminal emulators/tmux/etc. + -- Try your own mapping or just use to exit terminal mode. { '', '', desc = 'Exit terminal mode', mode = 't' }, -- ── Search ──────────────────────────────────────────────────────────