diff --git a/nvim/init.lua b/nvim/init.lua index 3ac0e95..c6b078d 100644 --- a/nvim/init.lua +++ b/nvim/init.lua @@ -1,938 +1,20 @@ --- non-plugin settings -require("remap") -require("settings") +vim.loader.enable() --- lazy package manager setup -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 }) - if vim.v.shell_error ~= 0 then - vim.api.nvim_echo({ - { "Failed to clone lazy.nvim:\n", "ErrorMsg" }, - { out, "WarningMsg" }, - { "\nPress any key to exit..." }, - }, true, {}) - vim.fn.getchar() - os.exit(1) - end -end -vim.opt.rtp:prepend(lazypath) +-- pack hooks/commands should be defined before plugin modules run +require("utils.pack").setup() -require("lazy").setup({ - -- icons - { "nvim-tree/nvim-web-devicons", lazy = true }, - -- finder - { - "nvim-telescope/telescope.nvim", - branch = 'master', - -- tag = "0.1.5", - dependencies = { "nvim-lua/plenary.nvim" }, - }, - -- looks - { "catppuccin/nvim", name = "catppuccin", priority = 1000 }, - { "nvim-lualine/lualine.nvim" }, - { "akinsho/bufferline.nvim", version = "*" }, - -- add indent lines - { "lukas-reineke/indent-blankline.nvim", main = "ibl", opts = {} }, - -- auto brackets - { - "windwp/nvim-autopairs", - event = "InsertEnter", - opts = { - disable_filetype = { "TelescopePrompt" }, - }, -- this is equalent to setup({}) function - }, - -- html auto tags - -- https://github.com/windwp/nvim-ts-autotag - { - "windwp/nvim-ts-autotag", - event = "InsertEnter", - }, - -- commenter - { - "numToStr/Comment.nvim", - opts = { - toggler = { line = "cc" }, - opleader = { line = "cc" }, - }, - lazy = false, - }, - -- search and replacer - -- https://github.com/nvim-pack/nvim-spectre - -- search and replace - { - "nvim-pack/nvim-spectre", - event = "VeryLazy", - dependencies = { - "nvim-lua/plenary.nvim", - }, - keys = { - { - "S", - function() - local root = vim.fs.root(0, { ".git" }) - require("spectre").open_visual({ - cwd = root or vim.fn.getcwd(), - select_word = true, - }) - end, - desc = "Search current word at project root" - }, - { - "s", - function() - require("spectre").open_file_search({ - select_word = true, - }) - end, - desc = "Search on current file" - }, - }, - opts = { - default = { - find = { - cmd = "rg", - options = { "case-sensitive", "word-regexp" } -- This makes rg case-sensitive - }, - replace = { - cmd = "sed" - } - }, - mapping = { - ['toggle_word_regexp'] = { - map = "tw", - cmd = "lua require('spectre').change_options('word-regexp')", - desc = "toggle word boundary" - }, - ['toggle_case_sensitive'] = { - map = "tc", - cmd = "lua require('spectre').change_options('case-sensitive')", - desc = "toggle case sensitive" - }, - ['toggle_ignore_case'] = { - map = 'ti', - cmd = "lua require('spectre').change_options('ignore-case')", - desc = 'toggle ignore case', - }, - ['toggle_ignore_hidden'] = { - map = 'th', - cmd = "lua require('spectre').change_options('hidden')", - desc = 'toggle search hidden', - }, - }, - find_engine = { - ['rg'] = { - cmd = 'rg', - -- default args - args = { - '--color=never', - '--no-heading', - '--with-filename', - '--line-number', - '--column', - }, - options = { - ['ignore-case'] = { - value = '--ignore-case', - icon = '[I]', - desc = 'ignore case match', - }, - ['hidden'] = { - value = '--hidden', - desc = 'hidden file', - icon = '[H]', - }, - ['word-regexp'] = { - value = '-w', - desc = 'match word only', - icon = '[W]', - }, - ['case-sensitive'] = { - value = '--case-sensitive', - desc = 'case sensitive match', - icon = '[C]', - } - }, - }, - } - }, - }, - -- syntax highlighter and stuff - { - "nvim-treesitter/nvim-treesitter", - dependencies = { - 'nvim-treesitter/nvim-treesitter-refactor', - }, - build = ":TSUpdate", - config = function() - local configs = require("nvim-treesitter.configs") +-- editor settings and non-plugin keymaps +require("settings.options") +require("settings.keymaps") - configs.setup({ - ensure_installed = { - "python", - "lua", - "vim", - "javascript", - "typescript", - "html", - "htmldjango", - "toml", - "tsx", - "templ", - "go", - "astro" - }, - sync_install = false, - highlight = { enable = true }, - indent = { enable = true }, - refactor = { - smart_rename = { - enable = true, - keymaps = { - smart_rename = 'lr', -- "local rename" - }, - }, - -- optional: highlights the block scope of the symbol under cursor - highlight_definitions = { - enable = true, - clear_on_cursor_move = true, - }, - }, - }) - end, - }, - { - "supermaven-inc/supermaven-nvim", - config = function() - require("supermaven-nvim").setup({}) - end, - }, - -- lsp - -- https://github.com/neovim/nvim-lspconfig - -- lsp package manager - -- https://github.com/williamboman/mason-lspconfig.nvim - { - "williamboman/mason.nvim", - "williamboman/mason-lspconfig.nvim", - "neovim/nvim-lspconfig", - }, - -- completion - { - "hrsh7th/nvim-cmp", - event = { "InsertEnter", "CmdlineEnter" }, - dependencies = { - "hrsh7th/cmp-nvim-lsp", - "hrsh7th/cmp-buffer", - "hrsh7th/cmp-path", - "hrsh7th/cmp-cmdline", - "hrsh7th/cmp-nvim-lsp-signature-help", - }, - }, - -- completion snippets - { - "L3MON4D3/LuaSnip", - event = { "InsertEnter", "CmdlineEnter" }, - dependencies = { - "saadparwaiz1/cmp_luasnip", - }, - }, - -- usage/references - { - 'Wansmer/symbol-usage.nvim', - event = 'BufReadPre', -- need run before LspAttach if you use nvim 0.9. On 0.10 use 'LspAttach' - }, - -- errors visibility - { - "folke/trouble.nvim", - opts = {}, -- for default options, refer to the configuration section for custom setup. - cmd = "Trouble", - keys = { - { - "xx", - "Trouble diagnostics toggle", - desc = "Diagnostics (Trouble)", - }, - { - "xX", - "Trouble diagnostics toggle filter.buf=0", - desc = "Buffer Diagnostics (Trouble)", - }, - { - "cs", - "Trouble symbols toggle focus=false", - desc = "Symbols (Trouble)", - }, - { - "cl", - "Trouble lsp toggle focus=false win.position=right", - desc = "LSP Definitions / references / ... (Trouble)", - }, - { - "xL", - "Trouble loclist toggle", - desc = "Location List (Trouble)", - }, - { - "xQ", - "Trouble qflist toggle", - desc = "Quickfix List (Trouble)", - }, - }, - }, - -- formatter - { - "stevearc/conform.nvim", - event = { "BufWritePre" }, - cmd = { "ConformInfo" }, - keys = { - { - -- Customize or remove this keymap to your liking - "F", - function() - require("conform").format({ async = true, lsp_fallback = true }) - end, - mode = "", - desc = "Format buffer", - }, - }, - opts = { - formatters_by_ft = { - lua = { "stylua" }, - sh = { "shfmt" }, - bash = { "shfmt" }, - python = { "isort", "black" }, - javascript = { "prettierd" }, - typescript = { "prettierd" }, - astro = { "prettierd" }, - html = { "prettierd" }, - css = { "prettierd" }, - json = { "prettierd" }, - jsonc = { "prettierd" }, - }, - }, - formatters = { - prettierd_json = { - command = vim.fn.stdpath("data") .. "~/.local/share/nvim/mason/bin/prettierd", - args = { - "--stdin-filepath", "$FILENAME", - "--parser", "json", - "--trailing-comma", "none" - }, - stdin = true, - }, - prettierd = { - command = vim.fn.stdpath("data") .. "~/.local/share/nvim/mason/bin/prettierd", - args = function(self, ctx) - local args = { "--stdin-filepath", "$FILENAME" } - - if vim.bo[ctx.buf].filetype == "jsonc" then - table.insert(args, "--parser") - table.insert(args, "json") - table.insert(args, "--trailing-comma") - table.insert(args, "none") - end - - return args - end, - }, - }, - }, - -- css color picker - { - "eero-lehtinen/oklch-color-picker.nvim", - event = "VeryLazy", - version = "*", - keys = { - -- One handed keymap recommended, you will be using the mouse - { - "v", - function() require("oklch-color-picker").pick_under_cursor() end, - desc = "Color pick under cursor", - }, - }, - ---@type oklch.Opts - opts = {}, - }, - -- markdown render - { - "MeanderingProgrammer/render-markdown.nvim", - dependencies = { "nvim-treesitter/nvim-treesitter" }, - ft = { "markdown" }, - opts = {}, - }, -}) --- end lazy package manager setup - --- usage hints formatter -local function h(name) return vim.api.nvim_get_hl(0, { name = name }) end - --- hl-groups can have any name -vim.api.nvim_set_hl(0, 'SymbolUsageRounding', { fg = h('CursorLine').bg, italic = true }) -vim.api.nvim_set_hl(0, 'SymbolUsageContent', { bg = h('CursorLine').bg, fg = h('Comment').fg, italic = true }) -vim.api.nvim_set_hl(0, 'SymbolUsageRef', { fg = h('Function').fg, bg = h('CursorLine').bg, italic = true }) -vim.api.nvim_set_hl(0, 'SymbolUsageDef', { fg = h('Type').fg, bg = h('CursorLine').bg, italic = true }) -vim.api.nvim_set_hl(0, 'SymbolUsageImpl', { fg = h('@keyword').fg, bg = h('CursorLine').bg, italic = true }) - -local function text_format(symbol) - local res = {} - - local round_start = { '', 'SymbolUsageRounding' } - local round_end = { '', 'SymbolUsageRounding' } - - -- Indicator that shows if there are any other symbols in the same line - local stacked_functions_content = symbol.stacked_count > 0 - and ("+%s"):format(symbol.stacked_count) - or '' - - if symbol.references then - local usage = symbol.references <= 1 and 'usage' or 'usages' - local num = symbol.references == 0 and 'no' or symbol.references - table.insert(res, round_start) - table.insert(res, { '󰌹 ', 'SymbolUsageRef' }) - table.insert(res, { ('%s %s'):format(num, usage), 'SymbolUsageContent' }) - table.insert(res, round_end) - end - - if symbol.definition then - if #res > 0 then - table.insert(res, { ' ', 'NonText' }) - end - table.insert(res, round_start) - table.insert(res, { '󰳽 ', 'SymbolUsageDef' }) - table.insert(res, { symbol.definition .. ' defs', 'SymbolUsageContent' }) - table.insert(res, round_end) - end - - if symbol.implementation then - if #res > 0 then - table.insert(res, { ' ', 'NonText' }) - end - table.insert(res, round_start) - table.insert(res, { '󰡱 ', 'SymbolUsageImpl' }) - table.insert(res, { symbol.implementation .. ' impls', 'SymbolUsageContent' }) - table.insert(res, round_end) - end - - if stacked_functions_content ~= '' then - if #res > 0 then - table.insert(res, { ' ', 'NonText' }) - end - table.insert(res, round_start) - table.insert(res, { ' ', 'SymbolUsageImpl' }) - table.insert(res, { stacked_functions_content, 'SymbolUsageContent' }) - table.insert(res, round_end) - end - - return res -end -require('symbol-usage').setup({ - text_format = text_format, - references = { enabled = true, include_declaration = false }, - definition = { enabled = true }, - kinds = { - vim.lsp.protocol.SymbolKind.Function, - vim.lsp.protocol.SymbolKind.Method, - vim.lsp.protocol.SymbolKind.Constant, - vim.lsp.protocol.SymbolKind.Struct, -- Add this for Go structs - vim.lsp.protocol.SymbolKind.Interface, -- You might also want interfaces - vim.lsp.protocol.SymbolKind.Class, -- Some languages use Class - } -}) --- end usage hints formatter - --- lsp stuff -local capabilities = vim.lsp.protocol.make_client_capabilities() -capabilities = require("cmp_nvim_lsp").default_capabilities(capabilities) -capabilities.offsetEncoding = { "utf-16", "utf-8" } -require("mason").setup() -require("mason-lspconfig").setup({ - ensure_installed = { - "lua_ls", - "bashls", - -- "python-lsp-server", - "astro", - "tailwindcss", - "ts_ls", - "html", - "pyright", - "templ", - "gopls", - "emmet_ls", -- for cmp mainly, helps with auto quotes in html - }, - automatic_installation = true, - automatic_enable = false -}) --- Tailwind CSS -vim.lsp.config('tailwindcss', { - capabilities = capabilities, - settings = { - tailwindCSS = { - experimental = { - -- this will capture any variable assignment in single/double quotes and encased in brackets as well - classRegex = { - "Css = (\\{[^\\{\\}]+\\}|\\[[^\\[\\]]+\\]|'[^']+'|\"[^\"]+\")", - }, - }, - }, - }, - filetypes = { "htmldjango", "templ", 'html', 'css', 'javascript', 'typescript', 'jsx', 'tsx' }, -}) -vim.lsp.enable('tailwindcss') - --- Python -vim.lsp.config('pyright', { - capabilities = capabilities, -}) -vim.lsp.enable('pyright') - --- Bash -vim.lsp.config('bashls', { - capabilities = capabilities, -}) -vim.lsp.enable('bashls') - --- Astro -vim.lsp.config('astro', { - capabilities = capabilities, -}) -vim.lsp.enable('astro') - --- Typescript -vim.lsp.config('ts_ls', { - capabilities = capabilities, -}) -vim.lsp.enable('ts_ls') - --- Emmet -vim.lsp.config('emmet_ls', { - capabilities = capabilities, -}) -vim.lsp.enable('emmet_ls') - --- HTML -vim.lsp.config('html', { - capabilities = capabilities, - filetypes = { "htmldjango", "templ" }, -}) -vim.lsp.enable('html') - --- Templ -vim.lsp.config('templ', { - capabilities = capabilities, -}) -vim.lsp.enable('templ') - --- Gopls -vim.lsp.config('gopls', { - capabilities = capabilities, - -- settings = { - -- gopls = { - -- -- directoryFilters = { "-**/*_templ.go" }, - -- }, - -- }, -}) -vim.lsp.enable('gopls') - --- Lua LS -vim.lsp.config('lua_ls', { - capabilities = capabilities, - settings = { - Lua = { - diagnostics = { - globals = { "vim" }, - }, - telemetry = { enable = false }, - workspace = { checkThirdParty = false }, - hint = { enable = true }, - }, - }, -}) -vim.lsp.enable('lua_ls') - --- rust -vim.lsp.config('rust_analyzer', { - capabilities = capabilities, -}) -vim.lsp.enable('rust_analyzer') - -local has_words_before = function() - unpack = unpack or table.unpack - 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 -end -local function border(hl_name) - return { - { "╭", hl_name }, - { "─", hl_name }, - { "╮", hl_name }, - { "│", hl_name }, - { "╯", hl_name }, - { "─", hl_name }, - { "╰", hl_name }, - { "│", hl_name }, - } -end -local luasnip = require("luasnip") -luasnip.add_snippets("all", { - luasnip.s("html", { - luasnip.t({ - "", - "", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - "", - " ", - "" - }) - }) -}) - -local cmp = require("cmp") -cmp.setup({ - window = { - completion = { - border = border("CmpBorder"), - winhighlight = "Normal:CmpPmenu,CursorLine:PmenuSel,Search:None", - }, - documentation = { border = border("CmpDocBorder") }, - }, - snippet = { - expand = function(args) - luasnip.lsp_expand(args.body) - end, - }, - mapping = { - [""] = cmp.mapping.scroll_docs(-4), - [""] = cmp.mapping.scroll_docs(4), - [""] = cmp.mapping.complete(), - [""] = cmp.mapping.abort(), - [""] = cmp.mapping.confirm({ select = true }), -- = enter key - [""] = cmp.mapping(function(fallback) - if cmp.visible() then - cmp.select_next_item() - elseif luasnip.expand_or_jumpable() then - luasnip.expand_or_jump() - elseif has_words_before() then - cmp.complete() - else - fallback() - end - end, { "i", "s" }), - [""] = cmp.mapping(function(fallback) - if cmp.visible() then - cmp.select_prev_item() - elseif luasnip.jumpable(-1) then - luasnip.jump(-1) - else - fallback() - end - end, { "i", "s" }), - }, - sources = { - { name = "supermaven" }, - { name = "nvim_lsp" }, - { name = "luasnip" }, - { name = "buffer" }, - { name = "nvim_lsp_signature_help" }, - { name = "path" }, - }, -}) - --- Global mappings. --- See `:help vim.diagnostic.*` for documentation on any of the below functions --- ## lsp diagnostics --- virtual_text = inline diagnostics -vim.diagnostic.config({ virtual_text = false }) - --- apply global float border -local orig_util_open_floating_preview = vim.lsp.util.open_floating_preview -function vim.lsp.util.open_floating_preview(contents, syntax, opts, ...) - opts = opts or {} - opts.border = opts.border or border("FloatBorder") - return orig_util_open_floating_preview(contents, syntax, opts, ...) -end - --- show diagnostics on cursor hover -vim.o.updatetime = 250 --- vim.cmd( --- [[autocmd CursorHold,CursorHoldI * lua if not require("cmp").visible() then vim.diagnostic.open_float(nil, {focus=false}) end]] --- ) -vim.api.nvim_create_autocmd({ 'CursorHold', 'CursorHoldI' }, { - callback = function() - -- Don't show diagnostic if completion menu is visible - if require("cmp").visible() then - return - end - - -- Don't show diagnostic if a hover/signature window is already open - for _, win in ipairs(vim.api.nvim_list_wins()) do - local config = vim.api.nvim_win_get_config(win) - if config.relative ~= '' then - local buf = vim.api.nvim_win_get_buf(win) - local ft = vim.bo[buf].filetype - -- Check if it's a hover window (usually has 'markdown' filetype) - if ft == 'markdown' or config.focusable == true then - return - end - end - end - - vim.diagnostic.open_float(nil, { focus = false }) - end -}) --- ## end lsp diagnostics - --- override gopls qualified template definition jumping -local function custom_go_to_definition() - -- Early exit for non-Go/templ files - local ft = vim.bo.filetype - -- if ft == "python" then - -- vim.lsp.buf.definition() - -- return - if ft ~= "go" and ft ~= "templ" then - require('telescope.builtin').lsp_definitions() - return - end - -- Early exit if no gopls client attached - local clients = vim.lsp.get_clients({ bufnr = 0, name = "gopls" }) - if #clients == 0 then - require('telescope.builtin').lsp_definitions() - return - end - -- Use the gopls client for position encoding - local gopls_client = clients[1] - local params = vim.lsp.util.make_position_params(0, gopls_client.offset_encoding) - vim.lsp.buf_request(0, 'textDocument/definition', params, function(err, result, ctx, config) - if err or not result or vim.tbl_isempty(result) then - require('telescope.builtin').lsp_definitions() - return - end - -- Convert single result to array - if result.uri then - result = { result } - end - -- Quick check: do we have any _templ.go files in results? - local has_templ_generated = false - for _, location in ipairs(result) do - local uri = location.uri or location.targetUri - local filepath = vim.uri_to_fname(uri) - if filepath:match("_templ%.go$") then - has_templ_generated = true - break - end - end - -- If no generated templ files, use normal telescope - if not has_templ_generated then - require('telescope.builtin').lsp_definitions() - return - end - -- Only do the heavy processing if we found generated files - local word_under_cursor = vim.fn.expand('') - local processed_results = {} - for _, location in ipairs(result) do - local uri = location.uri or location.targetUri - local filepath = vim.uri_to_fname(uri) - if filepath:match("_templ%.go$") then - local templ_file = filepath:gsub("_templ%.go$", ".templ") - if vim.fn.filereadable(templ_file) == 1 then - -- Simple search for the symbol - local cmd = string.format("grep -n 'templ %s\\|func %s' %s", - word_under_cursor, word_under_cursor, vim.fn.shellescape(templ_file)) - local output = vim.fn.system(cmd) - if vim.v.shell_error == 0 and output ~= "" then - local lnum = output:match("^(%d+)") - if lnum then - table.insert(processed_results, { - uri = vim.uri_from_fname(templ_file), - range = { - start = { line = tonumber(lnum) - 1, character = 0 }, - ["end"] = { line = tonumber(lnum) - 1, character = 0 } - } - }) - end - else - -- Keep original if not found in templ - table.insert(processed_results, location) - end - else - table.insert(processed_results, location) - end - else - table.insert(processed_results, location) - end - end - local final_results = #processed_results > 0 and processed_results or result - if #final_results == 1 then - -- Use modern API instead of deprecated jump_to_location - local location = final_results[1] - local uri = location.uri or location.targetUri - local range = location.range or location.targetRange - -- Open the file - vim.cmd('edit ' .. vim.fn.fnameescape(vim.uri_to_fname(uri))) - -- Jump to position - local row = range.start.line + 1 - local col = range.start.character + 1 - vim.api.nvim_win_set_cursor(0, { row, col - 1 }) - -- Center the view - vim.cmd('normal! zz') - else - local qf_items = {} - for _, location in ipairs(final_results) do - local filename = vim.uri_to_fname(location.uri or location.targetUri) - local range = location.range or location.targetRange - table.insert(qf_items, { - filename = filename, - lnum = range.start.line + 1, - col = range.start.character + 1, - text = "", - }) - end - vim.fn.setqflist(qf_items) - require('telescope.builtin').quickfix() - end - end) -end - -vim.keymap.set("n", "e", vim.diagnostic.open_float) -vim.keymap.set("n", "[d", vim.diagnostic.goto_prev) -vim.keymap.set("n", "]d", vim.diagnostic.goto_next) -vim.keymap.set("n", "q", vim.diagnostic.setloclist) - --- auto on_attach on lspconfig server setup --- Use LspAttach autocommand to only map the following keys --- after the language server attaches to the current buffer -vim.api.nvim_create_autocmd("LspAttach", { - group = vim.api.nvim_create_augroup("UserLspConfig", {}), - callback = function(ev) - local client = vim.lsp.get_client_by_id(ev.data.client_id) - -- Enable completion triggered by - if client.server_capabilities.completionProvider then - vim.bo[ev.buf].omnifunc = "v:lua.vim.lsp.omnifunc" - end - if client.server_capabilities.definitionProvider then - vim.bo[ev.buf].tagfunc = "v:lua.vim.lsp.tagfunc" - end - - local opts = { noremap = true, silent = true, buffer = ev.buf } - - -- Buffer local mappings. - -- See `:help vim.lsp.*` for documentation on any of the below functions - vim.keymap.set("n", "gD", vim.lsp.buf.declaration, opts) - vim.keymap.set("n", "K", vim.lsp.buf.hover, opts) - vim.keymap.set("n", "gi", vim.lsp.buf.implementation, opts) - vim.keymap.set("n", "", vim.lsp.buf.signature_help, opts) - vim.keymap.set("n", "wa", vim.lsp.buf.add_workspace_folder, opts) - vim.keymap.set("n", "wr", vim.lsp.buf.remove_workspace_folder, opts) - vim.keymap.set("n", "wl", function() - print(vim.inspect(vim.lsp.buf.list_workspace_folders())) - end, opts) - vim.keymap.set("n", "D", vim.lsp.buf.type_definition, opts) - vim.keymap.set("n", "rn", vim.lsp.buf.rename, opts) - vim.keymap.set({ "n", "v" }, "ca", vim.lsp.buf.code_action, opts) - vim.keymap.set("n", "gd", custom_go_to_definition, opts) - vim.keymap.set("n", "gr", require('telescope.builtin').lsp_references, opts) - -- full project-wide rename (LSP-aware, cross-file) - vim.keymap.set('n', 'ar', vim.lsp.buf.rename, - vim.tbl_extend('force', opts, { desc = 'LSP: Rename all references' })) - end, -}) --- end lsp stuff - --- html auto tags -require('nvim-ts-autotag').setup({ - aliases = { - ["astro"] = "html" - } -}) --- end html auto tags - --- theme -require("catppuccin").setup({ - compile_path = vim.fn.stdpath("cache") .. "/catppuccin", - flavour = "macchiato", - transparent_background = true, - integrations = { - cmp = true, - treesitter = true, - }, - telescope = { - enabled = true, - }, -}) -vim.cmd.colorscheme("catppuccin") --- end theme - --- bufferline -require("bufferline").setup({ - options = { mode = "tabs", separator_style = "thin" }, -}) -vim.keymap.set("n", "", "BufferLineCycleNext", {}) -vim.keymap.set("n", "", "BufferLineCyclePrev", {}) --- end bufferline - --- lualine -require("lualine").setup({}) --- end lualine - --- telescope -require("telescope").setup({ - pickers = { - find_files = { - -- `hidden = true` will still show the inside of `.git/` as it's not `.gitignore`d. - find_command = { - "rg", - "--files", - '--no-heading', - '--with-filename', - '--line-number', - '--column', - "--glob", "!**/.git/*", - -- "--hidden", - }, - }, - live_grep = { - additional_args = function() - return { - "--glob", "!**/.git/*", - "--glob", "!**/go.sum", - "--glob", "!**/go.mod", - } - end - }, - lsp_definitions = { - show_line = false, - file_ignore_patterns = { ".*_templ.go" }, - theme = "dropdown", - }, - lsp_references = { - show_line = false, - include_declaration = false, - file_ignore_patterns = { ".*_templ.go" }, - theme = "dropdown", - }, - }, -}) -local telescope_builtin = require("telescope.builtin") -vim.keymap.set("n", "fg", telescope_builtin.live_grep, {}) -vim.keymap.set("n", "f", telescope_builtin.find_files, {}) -vim.keymap.set("n", "", function() - -- Handling error to output 1 line instead of several - if pcall(telescope_builtin.git_files, { show_untracked = true }) then - else - print("Not a git project. Try running git init in root.") - end -end) --- end telescope - --- commenter -local ft = require("Comment.ft") -ft.set("typescriptreact", "{/* %s */}") -ft.htmldjango = "{# %s #}" -ft.templ = "// %s" --- end commenter +-- plugins +require("plugins.catppuccin").setup() +require("plugins.lsp").setup() +require("plugins.cmp").setup() +require("plugins.treesitter").setup() +require("plugins.telescope").setup_keymaps() +require("plugins.mini").setup() +require("plugins.ui").setup() +require("plugins.autotag").setup() +require("plugins.tools").setup() +require("plugins.ai").setup() diff --git a/nvim/lazy-lock.json b/nvim/lazy-lock.json deleted file mode 100644 index e0650c3..0000000 --- a/nvim/lazy-lock.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "Comment.nvim": { "branch": "master", "commit": "0236521ea582747b58869cb72f70ccfa967d2e89" }, - "LuaSnip": { "branch": "master", "commit": "8ae1dedd988eb56441b7858bd1e8554dfadaa46d" }, - "bufferline.nvim": { "branch": "main", "commit": "6c456b888823d9e4832aa91c482bccd19445c009" }, - "catppuccin": { "branch": "main", "commit": "5e36ca599f4aa41bdd87fbf2c5aae4397ac55074" }, - "cmp-buffer": { "branch": "main", "commit": "3022dbc9166796b644a841a02de8dd1cc1d311fa" }, - "cmp-cmdline": { "branch": "main", "commit": "8ee981b4a91f536f52add291594e89fb6645e451" }, - "cmp-nvim-lsp": { "branch": "main", "commit": "5af77f54de1b16c34b23cba810150689a3a90312" }, - "cmp-nvim-lsp-signature-help": { "branch": "main", "commit": "3d8912ebeb56e5ae08ef0906e3a54de1c66b92f1" }, - "cmp-path": { "branch": "main", "commit": "91ff86cd9c29299a64f968ebb45846c485725f23" }, - "cmp_luasnip": { "branch": "master", "commit": "05a9ab28b53f71d1aece421ef32fee2cb857a843" }, - "conform.nvim": { "branch": "master", "commit": "c4b2efb8aee4af0ef179a9b49ba401de3c4ef5d2" }, - "indent-blankline.nvim": { "branch": "master", "commit": "3c8a185da4b8ab7aef487219f5e001b11d4b6aaf" }, - "lazy.nvim": { "branch": "main", "commit": "96584866b9c5e998cbae300594d0ccfd0c464627" }, - "lualine.nvim": { "branch": "master", "commit": "566b7036f717f3d676362742630518a47f132fff" }, - "mason-lspconfig.nvim": { "branch": "main", "commit": "56e435e09f8729af2d41973e81a0db440f8fe9c9" }, - "mason.nvim": { "branch": "main", "commit": "a09da6ac634926a299dd439da08bdb547a8ca011" }, - "nvim-autopairs": { "branch": "master", "commit": "9fd41181693dd4106b3e414a822bb6569924de81" }, - "nvim-cmp": { "branch": "main", "commit": "538e37ba87284942c1d76ed38dd497e54e65b891" }, - "nvim-lspconfig": { "branch": "master", "commit": "ce0e625df61be77abe1340fbc9afe9ad39b31dd8" }, - "nvim-spectre": { "branch": "master", "commit": "d8906855f1949ac97b1e77aaf8d3fe12ed158ddc" }, - "nvim-treesitter": { "branch": "master", "commit": "0da349ed303bea955942f409d29059cdb89dbe2c" }, - "nvim-ts-autotag": { "branch": "main", "commit": "8515e48a277a2f4947d91004d9aa92c29fdc5e18" }, - "nvim-web-devicons": { "branch": "master", "commit": "3e24abe1ae66532135cec911562f553fe247cb56" }, - "plenary.nvim": { "branch": "master", "commit": "55d9fe89e33efd26f532ef20223e5f9430c8b0c0" }, - "telescope.nvim": { "branch": "master", "commit": "d90956833d7c27e73c621a61f20b29fdb7122709" } -} \ No newline at end of file diff --git a/nvim/lua/plugins/ai.lua b/nvim/lua/plugins/ai.lua new file mode 100644 index 0000000..9fbf808 --- /dev/null +++ b/nvim/lua/plugins/ai.lua @@ -0,0 +1,15 @@ +local M = {} + +local pack = require("utils.pack") + +function M.setup() + vim.api.nvim_create_autocmd("InsertEnter", { + once = true, + callback = function() + pack.add({ "supermaven-nvim" }) + require("supermaven-nvim").setup({}) + end, + }) +end + +return M diff --git a/nvim/lua/plugins/autotag.lua b/nvim/lua/plugins/autotag.lua new file mode 100644 index 0000000..5ad4c15 --- /dev/null +++ b/nvim/lua/plugins/autotag.lua @@ -0,0 +1,20 @@ +local M = {} + +local pack = require("utils.pack") + +function M.setup() + vim.api.nvim_create_autocmd("FileType", { + pattern = { "html", "xml", "javascriptreact", "typescriptreact", "astro", "templ" }, + once = true, + callback = function() + pack.add({ "nvim-ts-autotag" }) + require("nvim-ts-autotag").setup({ + aliases = { + astro = "html", + }, + }) + end, + }) +end + +return M diff --git a/nvim/lua/plugins/catppuccin.lua b/nvim/lua/plugins/catppuccin.lua new file mode 100644 index 0000000..d607cde --- /dev/null +++ b/nvim/lua/plugins/catppuccin.lua @@ -0,0 +1,65 @@ +local M = {} + +local ui = require("utils.ui") +local pack = require("utils.pack") + +local function apply_theme_overrides() + local transparent_groups = { + "NormalFloat", + "FloatBorder", + "TelescopeNormal", + "TelescopeBorder", + "TelescopePromptNormal", + "TelescopePromptBorder", + "TelescopeResultsNormal", + "TelescopeResultsBorder", + "TelescopePreviewNormal", + "TelescopePreviewBorder", + } + for _, g in ipairs(transparent_groups) do + vim.api.nvim_set_hl(0, g, { bg = "none" }) + end + + for _, group in ipairs(vim.fn.getcompletion("", "highlight")) do + local ok, hl = pcall(vim.api.nvim_get_hl, 0, { name = group }) + if ok and hl and hl.italic then + hl.italic = nil + vim.api.nvim_set_hl(0, group, hl) + end + end +end + +function M.setup() + pack.add({ "catppuccin", "nvim-web-devicons" }) + + local theme_group = vim.api.nvim_create_augroup("UserThemeTweaks", { clear = true }) + vim.api.nvim_create_autocmd("ColorScheme", { + group = theme_group, + callback = apply_theme_overrides, + }) + + require("catppuccin").setup({ + flavour = "macchiato", + transparent_background = true, + compile_path = vim.fn.stdpath("cache") .. "/catppuccin", + integrations = { + cmp = true, + treesitter = true, + }, + telescope = { + enabled = true, + }, + }) + + vim.cmd.colorscheme("catppuccin") + apply_theme_overrides() + + local orig = vim.lsp.util.open_floating_preview + vim.lsp.util.open_floating_preview = function(contents, syntax, opts, ...) + opts = opts or {} + opts.border = opts.border or ui.border("FloatBorder") + return orig(contents, syntax, opts, ...) + end +end + +return M diff --git a/nvim/lua/plugins/cmp.lua b/nvim/lua/plugins/cmp.lua new file mode 100644 index 0000000..2e4b3eb --- /dev/null +++ b/nvim/lua/plugins/cmp.lua @@ -0,0 +1,65 @@ +local M = {} + +local ui = require("utils.ui") +local pack = require("utils.pack") + +function M.setup() + pack.add({ "nvim-cmp", "cmp-nvim-lsp", "cmp-buffer", "cmp-path", "luasnip", "cmp_luasnip" }) + + local cmp = require("cmp") + local luasnip = require("luasnip") + + cmp.setup({ + window = { + completion = { + border = ui.border("CmpBorder"), + winhighlight = "Normal:CmpPmenu,CursorLine:PmenuSel,Search:None", + }, + documentation = { + border = ui.border("CmpDocBorder"), + }, + }, + snippet = { + expand = function(args) + luasnip.lsp_expand(args.body) + end, + }, + mapping = cmp.mapping.preset.insert({ + [""] = cmp.mapping.confirm({ select = true }), + [""] = cmp.mapping(function(fallback) + if cmp.visible() then + cmp.select_next_item() + elseif luasnip.expand_or_jumpable() then + luasnip.expand_or_jump() + else + fallback() + end + end, { "i", "s" }), + [""] = cmp.mapping(function(fallback) + if cmp.visible() then + cmp.select_prev_item() + elseif luasnip.jumpable(-1) then + luasnip.jump(-1) + else + fallback() + end + end, { "i", "s" }), + }), + sources = cmp.config.sources({ + { name = "nvim_lsp" }, + { name = "luasnip" }, + { name = "path" }, + { + name = "buffer", + option = { + keyword_length = 4, + get_bufnrs = function() + return { vim.api.nvim_get_current_buf() } + end, + }, + }, + }), + }) +end + +return M diff --git a/nvim/lua/plugins/lsp.lua b/nvim/lua/plugins/lsp.lua new file mode 100644 index 0000000..8d106ad --- /dev/null +++ b/nvim/lua/plugins/lsp.lua @@ -0,0 +1,162 @@ +local M = {} + +local pack = require("utils.pack") + +local tools = { + { kind = "lsp", lsp = "lua_ls", mason = "lua-language-server" }, + { kind = "lsp", lsp = "bashls", mason = "bash-language-server" }, + { kind = "lsp", lsp = "astro", mason = "astro-language-server" }, + { kind = "lsp", lsp = "tailwindcss", mason = "tailwindcss-language-server" }, + { kind = "lsp", lsp = "ts_ls", mason = "typescript-language-server" }, + { kind = "lsp", lsp = "html", mason = "html-lsp" }, + { kind = "lsp", lsp = "pyright", mason = "pyright" }, + { kind = "lsp", lsp = "templ", mason = "templ" }, + { kind = "lsp", lsp = "gopls", mason = "gopls" }, + { kind = "lsp", lsp = "emmet_ls", mason = "emmet-language-server" }, + { kind = "lsp", lsp = "rust_analyzer", mason = "rust-analyzer" }, + { kind = "formatter", mason = "stylua", ft = { "lua" } }, + { kind = "formatter", mason = "shfmt", ft = { "sh", "bash" } }, + { kind = "formatter", mason = "isort", ft = { "python" } }, + { kind = "formatter", mason = "black", ft = { "python" } }, + { kind = "formatter", mason = "prettierd", ft = { "javascript", "typescript", "astro", "html", "css", "json", "jsonc" } }, +} + +function M.setup() + pack.add({ "mason", "nvim-lspconfig", "conform" }) + + require("mason").setup() + + local capabilities = vim.lsp.protocol.make_client_capabilities() + pcall(function() + capabilities = require("cmp_nvim_lsp").default_capabilities(capabilities) + end) + vim.lsp.config("*", { capabilities = capabilities }) + + vim.lsp.config("tailwindcss", { + settings = { + tailwindCSS = { + experimental = { + classRegex = { + "Css = (\\{[^\\{\\}]+\\}|\\[[^\\[\\]]+\\]|'[^']+'|\"[^\"]+\")", + }, + }, + }, + }, + filetypes = { "htmldjango", "templ", "html", "css", "javascript", "typescript", "jsx", "tsx" }, + }) + vim.lsp.config("html", { filetypes = { "html", "htmldjango", "templ" } }) + vim.lsp.config("lua_ls", { + settings = { + Lua = { + diagnostics = { globals = { "vim" } }, + telemetry = { enable = false }, + workspace = { checkThirdParty = false }, + hint = { enable = true }, + }, + }, + }) + + local lsp_names = {} + for _, t in ipairs(tools) do + if t.kind == "lsp" then + table.insert(lsp_names, t.lsp) + end + end + vim.lsp.enable(lsp_names) + + require("conform").setup({ + formatters_by_ft = { + lua = { "stylua" }, + sh = { "shfmt" }, + bash = { "shfmt" }, + python = { "isort", "black" }, + javascript = { "prettierd" }, + typescript = { "prettierd" }, + astro = { "prettierd" }, + html = { "prettierd" }, + css = { "prettierd" }, + json = { "prettierd" }, + jsonc = { "prettierd" }, + }, + }) + + vim.keymap.set("n", "F", function() + require("conform").format({ async = true, lsp_fallback = true }) + end, { desc = "Format buffer" }) + + vim.api.nvim_create_user_command("MasonInstallDefaults", function() + local registry = require("mason-registry") + registry.refresh(function() + local seen, to_install = {}, {} + for _, t in ipairs(tools) do + if t.mason and not seen[t.mason] then + seen[t.mason] = true + local ok, pkg = pcall(registry.get_package, t.mason) + if ok and not pkg:is_installed() then + table.insert(to_install, pkg) + end + end + end + + if #to_install == 0 then + vim.notify("MasonInstallDefaults: all tools already installed", vim.log.levels.INFO) + return + end + for _, pkg in ipairs(to_install) do + pkg:install() + end + vim.notify(("MasonInstallDefaults: installing %d tool(s)"):format(#to_install), vim.log.levels.INFO) + end) + end, { desc = "Install missing Mason tools from `tools` table" }) + + vim.diagnostic.config({ virtual_text = false }) + + local lsp_group = vim.api.nvim_create_augroup("UserLspAttach", { clear = true }) + vim.api.nvim_create_autocmd("LspAttach", { + group = lsp_group, + callback = function(ev) + local bufnr = ev.buf + local client = vim.lsp.get_client_by_id(ev.data.client_id) + if not client then + return + end + + if client:supports_method("textDocument/completion") then + vim.bo[bufnr].omnifunc = "v:lua.vim.lsp.omnifunc" + end + if client:supports_method("textDocument/definition") then + vim.bo[bufnr].tagfunc = "v:lua.vim.lsp.tagfunc" + end + + local map = function(mode, lhs, rhs, desc) + vim.keymap.set(mode, lhs, rhs, { + buffer = bufnr, + silent = true, + noremap = true, + desc = desc, + }) + end + + map("n", "gD", vim.lsp.buf.declaration, "LSP declaration") + map("n", "K", vim.lsp.buf.hover, "LSP hover") + map("n", "gi", vim.lsp.buf.implementation, "LSP implementation") + map("n", "", vim.lsp.buf.signature_help, "LSP signature help") + map("n", "wa", vim.lsp.buf.add_workspace_folder, "LSP add workspace folder") + map("n", "wr", vim.lsp.buf.remove_workspace_folder, "LSP remove workspace folder") + map("n", "wl", function() + print(vim.inspect(vim.lsp.buf.list_workspace_folders())) + end, "LSP list workspace folders") + map("n", "D", vim.lsp.buf.type_definition, "LSP type definition") + map("n", "rn", vim.lsp.buf.rename, "LSP rename") + map({ "n", "v" }, "ca", vim.lsp.buf.code_action, "LSP code action") + map("n", "gd", function() + require("plugins.telescope").lsp_definitions() + end, "LSP definitions (Telescope)") + map("n", "gr", function() + require("plugins.telescope").lsp_references() + end, "LSP references (Telescope)") + end, + }) +end + +return M diff --git a/nvim/lua/plugins/mini.lua b/nvim/lua/plugins/mini.lua new file mode 100644 index 0000000..bc6c7c4 --- /dev/null +++ b/nvim/lua/plugins/mini.lua @@ -0,0 +1,41 @@ +local M = {} + +local pack = require("utils.pack") + +function M.setup() + pack.add({ "mini.nvim" }) + + require("mini.comment").setup({ + options = { + custom_commentstring = function() + local ft = vim.bo.filetype + if ft == "typescriptreact" then + return "{/* %s */}" + end + if ft == "htmldjango" then + return "{# %s #}" + end + if ft == "templ" then + return "// %s" + end + return nil + end, + }, + }) + + vim.keymap.set("n", "cc", function() + require("mini.comment").toggle_lines(vim.fn.line("."), vim.fn.line(".")) + end, { desc = "Toggle comment line" }) + + vim.keymap.set("v", "cc", function() + local s, e = vim.fn.line("v"), vim.fn.line(".") + if s > e then + s, e = e, s + end + require("mini.comment").toggle_lines(s, e) + end, { desc = "Toggle comment selection" }) + + require("mini.pairs").setup() +end + +return M diff --git a/nvim/lua/plugins/registry.lua b/nvim/lua/plugins/registry.lua new file mode 100644 index 0000000..5d00753 --- /dev/null +++ b/nvim/lua/plugins/registry.lua @@ -0,0 +1,56 @@ +local M = {} + +M.map = { + catppuccin = { name = "catppuccin", src = "https://github.com/catppuccin/nvim" }, + ["nvim-web-devicons"] = { name = "nvim-web-devicons", src = "https://github.com/nvim-tree/nvim-web-devicons" }, + mason = { name = "mason", src = "https://github.com/mason-org/mason.nvim" }, + ["nvim-lspconfig"] = { name = "nvim-lspconfig", src = "https://github.com/neovim/nvim-lspconfig" }, + conform = { name = "conform", src = "https://github.com/stevearc/conform.nvim" }, + ["nvim-cmp"] = { name = "nvim-cmp", src = "https://github.com/hrsh7th/nvim-cmp" }, + ["cmp-nvim-lsp"] = { name = "cmp-nvim-lsp", src = "https://github.com/hrsh7th/cmp-nvim-lsp" }, + ["cmp-buffer"] = { name = "cmp-buffer", src = "https://github.com/hrsh7th/cmp-buffer" }, + ["cmp-path"] = { name = "cmp-path", src = "https://github.com/hrsh7th/cmp-path" }, + luasnip = { name = "luasnip", src = "https://github.com/L3MON4D3/LuaSnip" }, + cmp_luasnip = { name = "cmp_luasnip", src = "https://github.com/saadparwaiz1/cmp_luasnip" }, + ["nvim-treesitter"] = { name = "nvim-treesitter", src = "https://github.com/nvim-treesitter/nvim-treesitter" }, + ["mini.nvim"] = { name = "mini.nvim", src = "https://github.com/echasnovski/mini.nvim" }, + ["indent-blankline.nvim"] = { + name = "indent-blankline.nvim", + src = "https://github.com/lukas-reineke/indent-blankline.nvim", + }, + ["lualine.nvim"] = { name = "lualine.nvim", src = "https://github.com/nvim-lualine/lualine.nvim" }, + ["bufferline.nvim"] = { name = "bufferline.nvim", src = "https://github.com/akinsho/bufferline.nvim" }, + ["plenary.nvim"] = { name = "plenary.nvim", src = "https://github.com/nvim-lua/plenary.nvim" }, + ["telescope.nvim"] = { name = "telescope.nvim", src = "https://github.com/nvim-telescope/telescope.nvim" }, + ["trouble.nvim"] = { name = "trouble.nvim", src = "https://github.com/folke/trouble.nvim" }, + ["grug-far.nvim"] = { name = "grug-far.nvim", src = "https://github.com/MagicDuck/grug-far.nvim" }, + ["nvim-ts-autotag"] = { name = "nvim-ts-autotag", src = "https://github.com/windwp/nvim-ts-autotag" }, + ["supermaven-nvim"] = { name = "supermaven-nvim", src = "https://github.com/supermaven-inc/supermaven-nvim" }, +} + +function M.by_names(names) + local out = {} + for _, name in ipairs(names) do + local spec = M.map[name] + if not spec then + error("Unknown plugin spec: " .. tostring(name)) + end + table.insert(out, spec) + end + return out +end + +function M.names() + local keys = {} + for name, _ in pairs(M.map) do + table.insert(keys, name) + end + table.sort(keys) + return keys +end + +function M.all() + return M.by_names(M.names()) +end + +return M diff --git a/nvim/lua/plugins/telescope.lua b/nvim/lua/plugins/telescope.lua new file mode 100644 index 0000000..5b78707 --- /dev/null +++ b/nvim/lua/plugins/telescope.lua @@ -0,0 +1,70 @@ +local M = {} + +local lazy = require("utils.lazy") +local pack = require("utils.pack") + +local function with_telescope(fn) + lazy.load_once("telescope", pack.registry({ "plenary.nvim", "telescope.nvim" }), function() + require("telescope").setup({ + defaults = { file_ignore_patterns = { "%.git/" } }, + pickers = { + find_files = { + find_command = { "rg", "--files", "--hidden", "--glob", "!**/.git/*" }, + }, + live_grep = { + additional_args = function() + return { "--glob", "!**/.git/*", "--glob", "!**/go.sum", "--glob", "!**/go.mod" } + end, + }, + lsp_definitions = { + show_line = false, + theme = "dropdown", + file_ignore_patterns = { ".*_templ.go" }, + }, + lsp_references = { + show_line = false, + include_declaration = false, + theme = "dropdown", + file_ignore_patterns = { ".*_templ.go" }, + }, + }, + }) + end) + fn(require("telescope.builtin")) +end + +function M.lsp_definitions() + with_telescope(function(builtin) + builtin.lsp_definitions() + end) +end + +function M.lsp_references() + with_telescope(function(builtin) + builtin.lsp_references() + end) +end + +function M.setup_keymaps() + vim.keymap.set("n", "f", function() + with_telescope(function(builtin) + builtin.find_files() + end) + end, { desc = "Find files" }) + + vim.keymap.set("n", "fg", function() + with_telescope(function(builtin) + builtin.live_grep() + end) + end, { desc = "Live grep" }) + + vim.keymap.set("n", "", function() + with_telescope(function(builtin) + if not pcall(builtin.git_files, { show_untracked = true }) then + vim.notify("Not a git project. Try running git init in root.", vim.log.levels.WARN) + end + end) + end, { desc = "Git files" }) +end + +return M diff --git a/nvim/lua/plugins/tools.lua b/nvim/lua/plugins/tools.lua new file mode 100644 index 0000000..798e913 --- /dev/null +++ b/nvim/lua/plugins/tools.lua @@ -0,0 +1,58 @@ +local M = {} + +local lazy = require("utils.lazy") +local pack = require("utils.pack") + +local function with_trouble(fn) + lazy.load_once("trouble", pack.registry({ "trouble.nvim" }), function() + require("trouble").setup({}) + end) + fn() +end + +local function with_grug(fn) + lazy.load_once("grug-far", pack.registry({ "grug-far.nvim" }), function() + require("grug-far").setup({}) + end) + fn(require("grug-far")) +end + +function M.setup() + vim.keymap.set("n", "xx", function() + with_trouble(function() + vim.cmd("Trouble diagnostics toggle") + end) + end, { desc = "Diagnostics (Trouble)" }) + + vim.keymap.set("n", "xX", function() + with_trouble(function() + vim.cmd("Trouble diagnostics toggle filter.buf=0") + end) + end, { desc = "Buffer diagnostics" }) + + vim.keymap.set("n", "xQ", function() + with_trouble(function() + vim.cmd("Trouble qflist toggle") + end) + end, { desc = "Quickfix list" }) + + vim.keymap.set("n", "S", function() + with_grug(function() + vim.cmd("GrugFar") + end) + end, { desc = "Search/replace project" }) + + vim.keymap.set("n", "s", function() + with_grug(function(grug) + grug.open({ prefills = { paths = vim.fn.expand("%") } }) + end) + end, { desc = "Search/replace current file" }) + + vim.keymap.set("v", "s", function() + with_grug(function() + vim.cmd("'<,'>GrugFarWithin") + end) + end, { desc = "Search/replace in selection" }) +end + +return M diff --git a/nvim/lua/plugins/treesitter.lua b/nvim/lua/plugins/treesitter.lua new file mode 100644 index 0000000..06313f9 --- /dev/null +++ b/nvim/lua/plugins/treesitter.lua @@ -0,0 +1,50 @@ +local M = {} + +local pack = require("utils.pack") + +function M.setup() + pack.add({ "nvim-treesitter" }) + + require("nvim-treesitter").setup({ + install_dir = vim.fn.stdpath("data") .. "/site", + }) + + require("nvim-treesitter").install({ + "lua", + "vim", + "python", + "bash", + "javascript", + "typescript", + "html", + "css", + "json", + "toml", + "go", + "astro", + "templ", + }) + + vim.api.nvim_create_autocmd("FileType", { + pattern = { + "lua", + "vim", + "python", + "bash", + "javascript", + "typescript", + "html", + "css", + "json", + "toml", + "go", + "astro", + "templ", + }, + callback = function(args) + pcall(vim.treesitter.start, args.buf) + end, + }) +end + +return M diff --git a/nvim/lua/plugins/ui.lua b/nvim/lua/plugins/ui.lua new file mode 100644 index 0000000..7d27514 --- /dev/null +++ b/nvim/lua/plugins/ui.lua @@ -0,0 +1,22 @@ +local M = {} + +local pack = require("utils.pack") + +function M.setup() + pack.add({ "indent-blankline.nvim", "lualine.nvim", "bufferline.nvim" }) + + require("ibl").setup({ + indent = { char = "▏" }, + scope = { enabled = false }, + }) + + require("lualine").setup() + require("bufferline").setup({ + options = { mode = "tabs", separator_style = "thin" }, + }) + + vim.keymap.set("n", "", "BufferLineCycleNext", {}) + vim.keymap.set("n", "", "BufferLineCyclePrev", {}) +end + +return M diff --git a/nvim/lua/remap.lua b/nvim/lua/remap.lua deleted file mode 100644 index 7e639f6..0000000 --- a/nvim/lua/remap.lua +++ /dev/null @@ -1,204 +0,0 @@ -vim.g.mapleader = " " - --- vim.cmd [[autocmd CursorHold,CursorHoldI * lua vim.diagnostic.open_float(nil, {focus=false})]] --- Open project folder view -vim.keymap.set('n', 'E', ':Ex') -vim.keymap.set('n', 'ER', ':bw') --- Set current window as current root directory for searching -vim.keymap.set("n", "sr", ":cd %:p:h") - --- Split window movement -vim.keymap.set("n", "", "h") -vim.keymap.set("n", "", "j") -vim.keymap.set("n", "", "k") -vim.keymap.set("n", "", "l") - --- netrw duplicate file, d -vim.api.nvim_create_autocmd('FileType', { - pattern = 'netrw', - callback = function() - vim.keymap.set('n', 'd', function() - -- Save current directory - local original_dir = vim.fn.getcwd() - - -- Change to the directory shown in netrw - vim.cmd('lcd %:p:h') - - -- Feed the keys with proper mode flag - vim.api.nvim_feedkeys('mt', 'x', false) - vim.api.nvim_feedkeys('mf', 'x', false) - vim.api.nvim_feedkeys('mc', 'x', false) - - -- Return to original directory after delay - vim.defer_fn(function() - vim.fn.chdir(original_dir) - end, 500) - end, { buffer = true, desc = 'Duplicate file in netrw' }) - end, -}) - --- Jump buffers movement -local tab_buffer_histories = {} -local is_navigating = false - -local function get_current_tab_history() - local tab = vim.fn.tabpagenr() - if not tab_buffer_histories[tab] then - tab_buffer_histories[tab] = { - buffers = {}, - index = 1 - } - end - return tab_buffer_histories[tab] -end - -vim.api.nvim_create_autocmd("BufEnter", { - callback = function() - if is_navigating then return end - local buf = vim.fn.bufnr('%') - if not vim.bo[buf].buflisted then return end - local history = get_current_tab_history() - - -- Remove any existing occurrence of this buffer from history - for i = #history.buffers, 1, -1 do - if history.buffers[i] == buf then - table.remove(history.buffers, i) - if i < history.index then - history.index = history.index - 1 - elseif i == history.index then - history.index = math.max(1, history.index - 1) - end - end - end - - -- If we're in the middle of history and switch to a new buffer, - -- truncate future history - if history.index < #history.buffers then - for i = #history.buffers, history.index + 1, -1 do - table.remove(history.buffers) - end - end - - -- Add the buffer to history - table.insert(history.buffers, buf) - history.index = #history.buffers - end -}) - -vim.keymap.set("n", "", function() - local history = get_current_tab_history() - if history.index > 1 then - is_navigating = true - history.index = history.index - 1 - local target_buf = history.buffers[history.index] - - -- Check if buffer still exists and is valid - if vim.fn.bufexists(target_buf) == 1 and vim.bo[target_buf].buflisted then - vim.cmd('buffer ' .. target_buf) - else - -- Skip invalid buffers - table.remove(history.buffers, history.index) - history.index = math.max(1, history.index - 1) - end - - vim.schedule(function() is_navigating = false end) - end -end) - -vim.keymap.set("n", "", function() - local history = get_current_tab_history() - if history.index < #history.buffers then - is_navigating = true - history.index = history.index + 1 - local target_buf = history.buffers[history.index] - - -- Check if buffer still exists and is valid - if vim.fn.bufexists(target_buf) == 1 and vim.bo[target_buf].buflisted then - vim.cmd('buffer ' .. target_buf) - else - -- Skip invalid buffers - table.remove(history.buffers, history.index) - history.index = math.min(#history.buffers, history.index) - end - - vim.schedule(function() is_navigating = false end) - end -end) - -vim.keymap.set("n", "", function() - local current_buf = vim.fn.bufnr('%') - local history = get_current_tab_history() - history.buffers = { current_buf } - history.index = 1 - print("Buffer history cleared") -end) - -vim.keymap.set("n", "", function() - local current_buf = vim.fn.bufnr('%') - local history = get_current_tab_history() - -- Remove current buffer from history - for i = #history.buffers, 1, -1 do - if history.buffers[i] == current_buf then - table.remove(history.buffers, i) - if i <= history.index then - history.index = math.max(1, history.index - 1) - end - end - end - -- Navigate to previous buffer in history if available - if #history.buffers > 0 and history.index <= #history.buffers then - is_navigating = true - vim.cmd('buffer ' .. history.buffers[history.index]) - vim.schedule(function() is_navigating = false end) - end - -- Delete the buffer - vim.cmd('bd ' .. current_buf) -end) - --- Clean up history when a tab is closed -vim.api.nvim_create_autocmd("TabClosed", { - callback = function() - local closed_tab = tonumber(vim.fn.expand("")) - if closed_tab then - tab_buffer_histories[closed_tab] = nil - end - end -}) - --- Makes shift+j not move cursor to the end -vim.keymap.set("n", "J", "mzJ`z") --- collapse a tag with the cursor at the start of the tag -vim.keymap.set("n", "j", "gJdw:j!", { silent = true }) - --- nnoremap :nohl --- vim.keymap.set("n", "", vim.cmd(":nohl")) - --- Visual Mode: Move blocks of lines up or down -vim.keymap.set("v", "J", ":m '>+1gv=gv'") -vim.keymap.set("v", "K", ":m '<-2gv=gv'") - --- Autopairs sometimes wraps things, and sometimes doesnt --- This is for wrapping a word in a pair -vim.keymap.set("n", "e{", "bcw{}P") -vim.keymap.set("n", "e[", "bcw[]P") -vim.keymap.set("n", "e<", "bcw<>P") -vim.keymap.set("n", "e(", "bcw()P") -vim.keymap.set("n", "e'", "bcw''P") -vim.keymap.set("n", "e\"", "bcw\"\"P") -vim.keymap.set("n", "e`", "bcw``P") - --- vertical movements --- center cursor after going up or down -vim.keymap.set("n", "", "zz") -vim.keymap.set("n", "", "zz") - - --- lsp restart -vim.keymap.set('n', 'l', function() - vim.cmd('LspRestart') - vim.defer_fn(function() - -- Reload the plugin module - package.loaded['symbol-usage'] = nil - require('symbol-usage').refresh() - end, 1000) -end, { desc = 'Restart LSP and reload symbol-usage' }) diff --git a/nvim/lua/settings.lua b/nvim/lua/settings.lua deleted file mode 100644 index 01ff134..0000000 --- a/nvim/lua/settings.lua +++ /dev/null @@ -1,83 +0,0 @@ --- leader timeout -vim.opt.timeoutlen = 350 --- Vim sets and globals -vim.opt.wrap = true -vim.opt.relativenumber = true -vim.opt.mouse = "nvi" -vim.opt.clipboard = "unnamedplus" -- Able to yank and paste crap from anywhere -vim.opt.guicursor = "i-ci:ver30-iCursor-blinkwait300-blinkon200-blinkoff150" -vim.opt.termguicolors = true -vim.opt.encoding = "utf-8" -vim.opt.cursorline = true -- Current line tracking -vim.opt.number = true -- Current line number display - -vim.opt.backup = false -vim.opt.writebackup = false -vim.opt.undodir = os.getenv("HOME") .. "/.vim/undodir" -vim.opt.undofile = true - -vim.opt.updatetime = 50 -vim.opt.signcolumn = "no" -vim.opt.scrolloff = 8 - --- Indenting --- vim.opt.smartindent = true -vim.opt.tabstop = 4 -vim.opt.softtabstop = 4 -vim.opt.shiftwidth = 4 -vim.opt.expandtab = true -vim.api.nvim_create_autocmd({"FileType"}, { - pattern = {"typescriptreact", "typescript", "javascript", "css", "html", "htmldjango", "yaml", "json", "md", "toml"}, - command = "setlocal shiftwidth=2 tabstop=2 softtabstop=2" -}) - -vim.g.grepper = {tools = {"rg"}} -- This is for replace in project, ripgrep required -vim.opt.wildignore:append{"*/node_modules/*", "*/venv/*"} -vim.opt.path:append{"**"} -- find files down subfolders -vim.g.python_host_prog = "/usr/bin/python2" -vim.g.python3_host_prog = "/usr/bin/python3" - --- skeletons -vim.cmd [[autocmd BufNewFile *.py 0r ~/.config/nvim/templates/skeleton.py]] -vim.cmd [[autocmd BufNewFile *.sh 0r ~/.config/nvim/templates/skeleton.sh]] - --- filetypes -vim.filetype.add({ - extension = { - templ = "templ", - }, -}) - --- popout styling -vim.api.nvim_create_autocmd("ColorScheme", { - callback = function() - vim.api.nvim_set_hl(0, "NormalFloat", { bg = "none" }) - vim.api.nvim_set_hl(0, "FloatBorder", { bg = "none" }) - end, -}) -vim.keymap.set('n', 'x', function() - vim.lsp.buf.clear_references() - local win_ids = vim.fn.getwininfo() - for _, win in pairs(win_ids) do - if win.quickfix == 0 and win.loclist == 0 and win.terminal == 0 and win.tabnr == vim.fn.tabpagenr() then - if vim.api.nvim_win_get_config(win.winid).relative ~= '' then - vim.api.nvim_win_close(win.winid, false) - end - end - end -end, { desc = "Close LSP floating windows" }) - --- disable italics on conditionals -vim.api.nvim_create_autocmd("ColorScheme", { - pattern = "*", - callback = function() - -- Get all highlight groups and remove italic styling - for _, group in ipairs(vim.fn.getcompletion("", "highlight")) do - local hl = vim.api.nvim_get_hl(0, { name = group }) - if hl.italic then - hl.italic = nil - vim.api.nvim_set_hl(0, group, hl) - end - end - end, -}) diff --git a/nvim/lua/settings/keymaps.lua b/nvim/lua/settings/keymaps.lua new file mode 100644 index 0000000..9ca8239 --- /dev/null +++ b/nvim/lua/settings/keymaps.lua @@ -0,0 +1,165 @@ +-- project / netrw +vim.keymap.set("n", "E", "Ex", { desc = "Open netrw" }) +vim.keymap.set("n", "ER", "bw", { desc = "Close buffer" }) +vim.keymap.set("n", "sr", ":cd %:p:h", { desc = "Set cwd to file dir" }) + +-- split navigation +vim.keymap.set("n", "", "h") +vim.keymap.set("n", "", "j") +vim.keymap.set("n", "", "k") +vim.keymap.set("n", "", "l") + +-- netrw duplicate helper (d) +vim.api.nvim_create_autocmd("FileType", { + pattern = "netrw", + callback = function() + vim.keymap.set("n", "d", function() + local cwd = vim.fn.getcwd() + vim.cmd("lcd %:p:h") + vim.api.nvim_feedkeys("mt", "x", false) + vim.api.nvim_feedkeys("mf", "x", false) + vim.api.nvim_feedkeys("mc", "x", false) + vim.defer_fn(function() + vim.fn.chdir(cwd) + end, 500) + end, { buffer = true, desc = "Duplicate file in netrw" }) + end, +}) + +-- buffer history (per-tab) +local hist_by_tab = {} +local navigating = false + +local function tab_hist() + local t = vim.fn.tabpagenr() + hist_by_tab[t] = hist_by_tab[t] or { bufs = {}, idx = 1 } + return hist_by_tab[t] +end + +vim.api.nvim_create_autocmd("BufEnter", { + callback = function() + if navigating then + return + end + local b = vim.fn.bufnr("%") + if not vim.bo[b].buflisted then + return + end + local h = tab_hist() + + for i = #h.bufs, 1, -1 do + if h.bufs[i] == b then + table.remove(h.bufs, i) + if i <= h.idx then + h.idx = math.max(1, h.idx - 1) + end + end + end + + while h.idx < #h.bufs do + table.remove(h.bufs) + end + + table.insert(h.bufs, b) + h.idx = #h.bufs + end, +}) + +vim.keymap.set("n", "", function() + local h = tab_hist() + if h.idx <= 1 then + return + end + navigating = true + h.idx = h.idx - 1 + local b = h.bufs[h.idx] + if vim.fn.bufexists(b) == 1 and vim.bo[b].buflisted then + vim.cmd("buffer " .. b) + else + table.remove(h.bufs, h.idx) + h.idx = math.max(1, h.idx - 1) + end + vim.schedule(function() + navigating = false + end) +end, { desc = "Prev buffer (history)" }) + +vim.keymap.set("n", "", function() + local h = tab_hist() + if h.idx >= #h.bufs then + return + end + navigating = true + h.idx = h.idx + 1 + local b = h.bufs[h.idx] + if vim.fn.bufexists(b) == 1 and vim.bo[b].buflisted then + vim.cmd("buffer " .. b) + else + table.remove(h.bufs, h.idx) + h.idx = math.min(#h.bufs, h.idx) + end + vim.schedule(function() + navigating = false + end) +end, { desc = "Next buffer (history)" }) + +vim.keymap.set("n", "", function() + local h = tab_hist() + h.bufs = { vim.fn.bufnr("%") } + h.idx = 1 + vim.notify("Buffer history cleared") +end, { desc = "Clear buffer history" }) + +vim.keymap.set("n", "", function() + local current = vim.fn.bufnr("%") + local h = tab_hist() + + for i = #h.bufs, 1, -1 do + if h.bufs[i] == current then + table.remove(h.bufs, i) + if i <= h.idx then + h.idx = math.max(1, h.idx - 1) + end + end + end + + if #h.bufs > 0 and h.idx <= #h.bufs then + navigating = true + vim.cmd("buffer " .. h.bufs[h.idx]) + vim.schedule(function() + navigating = false + end) + end + + vim.cmd("bd " .. current) +end, { desc = "Close buffer + keep history" }) + +vim.api.nvim_create_autocmd("TabClosed", { + callback = function() + local closed = tonumber(vim.fn.expand("")) + if closed then + hist_by_tab[closed] = nil + end + end, +}) + +-- editing helpers +vim.keymap.set("n", "J", "mzJ`z") +vim.keymap.set("n", "j", "gJdw:j!", { silent = true, desc = "Collapse tag line" }) +vim.keymap.set("v", "J", ":m '>+1gv=gv") +vim.keymap.set("v", "K", ":m '<-2gv=gv") + +-- centered paging +vim.keymap.set("n", "", "zz") +vim.keymap.set("n", "", "zz") + +-- close floats + clear refs +vim.keymap.set("n", "x", function() + vim.lsp.buf.clear_references() + for _, win in ipairs(vim.api.nvim_list_wins()) do + local cfg = vim.api.nvim_win_get_config(win) + if cfg.relative ~= "" then + pcall(vim.api.nvim_win_close, win, false) + end + end +end, { desc = "Close floating windows" }) diff --git a/nvim/lua/settings/options.lua b/nvim/lua/settings/options.lua new file mode 100644 index 0000000..518605a --- /dev/null +++ b/nvim/lua/settings/options.lua @@ -0,0 +1,72 @@ +vim.g.mapleader = " " + +vim.opt.timeoutlen = 350 +vim.opt.updatetime = 50 + +vim.opt.number = true +vim.opt.relativenumber = true +vim.opt.cursorline = true +vim.opt.wrap = true +vim.opt.termguicolors = true +vim.opt.signcolumn = "no" +vim.opt.scrolloff = 8 +vim.opt.mouse = "nvi" +vim.opt.guicursor = "i-ci:ver30-iCursor-blinkwait300-blinkon200-blinkoff150" + +vim.opt.clipboard = "unnamedplus" + +vim.opt.backup = false +vim.opt.writebackup = false + +local undo_dir = vim.fs.joinpath(vim.fn.stdpath("state"), "undo") +vim.fn.mkdir(undo_dir, "p") +vim.opt.undodir = undo_dir +vim.opt.undofile = true + +vim.opt.tabstop = 4 +vim.opt.softtabstop = 4 +vim.opt.shiftwidth = 4 +vim.opt.expandtab = true + +vim.api.nvim_create_autocmd("FileType", { + pattern = { + "typescriptreact", + "typescript", + "javascript", + "css", + "html", + "htmldjango", + "yaml", + "json", + "markdown", + "toml", + }, + callback = function() + vim.opt_local.shiftwidth = 2 + vim.opt_local.tabstop = 2 + vim.opt_local.softtabstop = 2 + end, +}) + +vim.opt.wildignore:append({ "*/node_modules/*", "*/venv/*" }) +vim.opt.path:append({ "**" }) + +vim.g.python3_host_prog = "/usr/bin/python3" + +vim.filetype.add({ + extension = { templ = "templ" }, +}) + +vim.api.nvim_create_autocmd("BufNewFile", { + pattern = "*.py", + callback = function() + vim.cmd("0r " .. vim.fn.fnameescape(vim.fs.joinpath(vim.fn.stdpath("config"), "templates", "skeleton.py"))) + end, +}) + +vim.api.nvim_create_autocmd("BufNewFile", { + pattern = "*.sh", + callback = function() + vim.cmd("0r " .. vim.fn.fnameescape(vim.fs.joinpath(vim.fn.stdpath("config"), "templates", "skeleton.sh"))) + end, +}) diff --git a/nvim/lua/utils/lazy.lua b/nvim/lua/utils/lazy.lua new file mode 100644 index 0000000..5c8bb68 --- /dev/null +++ b/nvim/lua/utils/lazy.lua @@ -0,0 +1,16 @@ +local M = {} + +local loaded = {} + +function M.load_once(key, specs, setup) + if loaded[key] then + return + end + loaded[key] = true + vim.pack.add(specs) + if setup then + setup() + end +end + +return M diff --git a/nvim/lua/utils/pack.lua b/nvim/lua/utils/pack.lua new file mode 100644 index 0000000..888ba02 --- /dev/null +++ b/nvim/lua/utils/pack.lua @@ -0,0 +1,92 @@ +local M = {} + +local registry = require("plugins.registry") + +function M.registry(names) + return registry.by_names(names) +end + +-- Backward-compatible alias +M.specs = M.registry + +function M.add(names, opts) + vim.pack.add(M.registry(names), opts) +end + +function M.names() + return registry.names() +end + +function M.setup() + local group = vim.api.nvim_create_augroup("UserPackHooks", { clear = true }) + + vim.api.nvim_create_autocmd("PackChanged", { + group = group, + callback = function(ev) + local name, kind = ev.data.spec.name, ev.data.kind + if name == "nvim-treesitter" and kind == "update" then + if not ev.data.active then + vim.cmd.packadd("nvim-treesitter") + end + pcall(vim.cmd, "TSUpdate") + end + end, + }) + + vim.api.nvim_create_user_command("PackInstall", function() + M.add(M.names(), { + confirm = false, + load = function() end, + }) + vim.notify("PackInstall: ensured all configured plugins are installed", vim.log.levels.INFO) + end, { desc = "Install all configured vim.pack plugins without loading" }) + + vim.api.nvim_create_user_command("PackUpdate", function(opts) + local names = (#opts.fargs > 0) and opts.fargs or nil + vim.pack.update(names) + end, { + nargs = "*", + complete = function(arglead) + local out = {} + for _, name in ipairs(M.names()) do + if name:find("^" .. vim.pesc(arglead)) then + table.insert(out, name) + end + end + return out + end, + desc = "Update vim.pack plugins (optionally pass plugin names)", + }) + + vim.api.nvim_create_user_command("PackSync", function() + vim.pack.update(nil, { target = "lockfile" }) + end, { desc = "Sync installed plugins to nvim-pack-lock.json" }) + + vim.api.nvim_create_user_command("PackClean", function() + local stale = vim.iter(vim.pack.get()) + :filter(function(p) + return not p.active + end) + :map(function(p) + return p.spec.name + end) + :totable() + + if #stale == 0 then + vim.notify("PackClean: nothing to clean", vim.log.levels.INFO) + return + end + + local msg = "PackClean will remove:\n - " .. table.concat(stale, "\n - ") + local choice = vim.fn.confirm(msg, "&Yes\n&No", 2) + if choice ~= 1 then + vim.notify("PackClean: cancelled", vim.log.levels.INFO) + return + end + + vim.pack.del(stale) + vim.notify("PackClean: removed " .. #stale .. " plugin(s)", vim.log.levels.INFO) + end, { desc = "Delete inactive vim.pack plugins from disk" }) +end + +return M diff --git a/nvim/lua/utils/ui.lua b/nvim/lua/utils/ui.lua new file mode 100644 index 0000000..98fd887 --- /dev/null +++ b/nvim/lua/utils/ui.lua @@ -0,0 +1,16 @@ +local M = {} + +function M.border(hl) + return { + { "╭", hl }, + { "─", hl }, + { "╮", hl }, + { "│", hl }, + { "╯", hl }, + { "─", hl }, + { "╰", hl }, + { "│", hl }, + } +end + +return M diff --git a/nvim/nvim-pack-lock.json b/nvim/nvim-pack-lock.json new file mode 100644 index 0000000..69e9ca2 --- /dev/null +++ b/nvim/nvim-pack-lock.json @@ -0,0 +1,88 @@ +{ + "plugins": { + "LuaSnip": { + "rev": "a62e1083a3cfe8b6b206e7d3d33a51091df25357", + "src": "https://github.com/L3MON4D3/LuaSnip" + }, + "bufferline.nvim": { + "rev": "655133c3b4c3e5e05ec549b9f8cc2894ac6f51b3", + "src": "https://github.com/akinsho/bufferline.nvim" + }, + "catppuccin": { + "rev": "426dbebe06b5c69fd846ceb17b42e12f890aedf1", + "src": "https://github.com/catppuccin/nvim" + }, + "cmp-buffer": { + "rev": "b74fab3656eea9de20a9b8116afa3cfc4ec09657", + "src": "https://github.com/hrsh7th/cmp-buffer" + }, + "cmp-nvim-lsp": { + "rev": "cbc7b02bb99fae35cb42f514762b89b5126651ef", + "src": "https://github.com/hrsh7th/cmp-nvim-lsp" + }, + "cmp-path": { + "rev": "c642487086dbd9a93160e1679a1327be111cbc25", + "src": "https://github.com/hrsh7th/cmp-path" + }, + "cmp_luasnip": { + "rev": "98d9cb5c2c38532bd9bdb481067b20fea8f32e90", + "src": "https://github.com/saadparwaiz1/cmp_luasnip" + }, + "conform": { + "rev": "086a40dc7ed8242c03be9f47fbcee68699cc2395", + "src": "https://github.com/stevearc/conform.nvim" + }, + "conform.nvim": { + "rev": "086a40dc7ed8242c03be9f47fbcee68699cc2395", + "src": "https://github.com/stevearc/conform.nvim" + }, + "indent-blankline.nvim": { + "rev": "d28a3f70721c79e3c5f6693057ae929f3d9c0a03", + "src": "https://github.com/lukas-reineke/indent-blankline.nvim" + }, + "lualine.nvim": { + "rev": "a905eeebc4e63fdc48b5135d3bf8aea5618fb21c", + "src": "https://github.com/nvim-lualine/lualine.nvim" + }, + "luasnip": { + "rev": "a62e1083a3cfe8b6b206e7d3d33a51091df25357", + "src": "https://github.com/L3MON4D3/LuaSnip" + }, + "mason": { + "rev": "b03fb0f20bc1d43daf558cda981a2be22e73ac42", + "src": "https://github.com/mason-org/mason.nvim" + }, + "mini.nvim": { + "rev": "c67822c53e8e282fe863343e88aa0a8ca3534059", + "src": "https://github.com/echasnovski/mini.nvim" + }, + "nvim-cmp": { + "rev": "a1d504892f2bc56c2e79b65c6faded2fd21f3eca", + "src": "https://github.com/hrsh7th/nvim-cmp" + }, + "nvim-lspconfig": { + "rev": "8a9378a822719346a0288fa004dab302ca3c0a8f", + "src": "https://github.com/neovim/nvim-lspconfig" + }, + "nvim-treesitter": { + "rev": "4916d6592ede8c07973490d9322f187e07dfefac", + "src": "https://github.com/nvim-treesitter/nvim-treesitter" + }, + "nvim-web-devicons": { + "rev": "c72328a5494b4502947a022fe69c0c47e53b6aa6", + "src": "https://github.com/nvim-tree/nvim-web-devicons" + }, + "plenary.nvim": { + "rev": "74b06c6c75e4eeb3108ec01852001636d85a932b", + "src": "https://github.com/nvim-lua/plenary.nvim" + }, + "supermaven-nvim": { + "rev": "07d20fce48a5629686aefb0a7cd4b25e33947d50", + "src": "https://github.com/supermaven-inc/supermaven-nvim" + }, + "telescope.nvim": { + "rev": "f7c673b8e46e8f233ff581d3624a517d33a7e264", + "src": "https://github.com/nvim-telescope/telescope.nvim" + } + } +} diff --git a/update.sh b/update.sh index 0288025..446deb6 100755 --- a/update.sh +++ b/update.sh @@ -1,4 +1,5 @@ #!/bin/bash cp ~/.config/nvim/init.lua ./nvim/init.lua -cp -r ~/.config/nvim/lua/* ./nvim/lua -cp -r ~/.config/nvim/templates/* ./nvim/templates +cp ~/.config/nvim/nvim-pack-lock.json ./nvim/nvim-pack-lock.json +cp -a ~/.config/nvim/lua/* ./nvim/lua +cp -a ~/.config/nvim/templates/* ./nvim/templates