diff --git a/nvim/.config/nvim/init.lua b/nvim/.config/nvim/init.lua index 971dbdf..e86cd09 100644 --- a/nvim/.config/nvim/init.lua +++ b/nvim/.config/nvim/init.lua @@ -1,546 +1,570 @@ -vim.g.mapleader = " " -vim.g.maplocalleader = " " -vim.g.have_nerd_font = true -vim.o.number = true -vim.o.relativenumber = true -vim.o.mouse = "a" -vim.o.showmode = false -vim.schedule(function() - vim.o.clipboard = "unnamedplus" -end) -vim.o.breakindent = true -vim.o.undofile = true -vim.o.ignorecase = true -vim.o.smartcase = true -vim.o.signcolumn = "yes" -vim.o.updatetime = 250 -vim.o.timeoutlen = 300 -vim.o.splitright = true -vim.o.splitbelow = true -vim.o.list = true -vim.opt.listchars = { tab = "» ", trail = "·", nbsp = "␣" } -vim.o.inccommand = "split" -vim.o.cursorline = true -vim.o.scrolloff = 15 -vim.o.confirm = true +-- ============================================================ +-- SECTION 1: OPTIONS +-- Core Neovim settings, leaders, options +-- ============================================================ +do + vim.loader.enable() -vim.keymap.set("n", "", "nohlsearch") + vim.g.mapleader = " " + vim.g.maplocalleader = " " -vim.diagnostic.config({ - update_in_insert = false, - severity_sort = true, - float = { border = "rounded", source = "if_many" }, - underline = { severity = { min = vim.diagnostic.severity.WARN } }, - virtual_text = true, - virtual_lines = false, - jump = { float = true }, -}) + vim.g.have_nerd_font = true -vim.keymap.set("n", "q", vim.diagnostic.setloclist, { desc = "Open diagnostic [Q]uickfix list" }) -vim.keymap.set("t", "", "", { desc = "Exit terminal mode" }) -vim.keymap.set("n", "", "", { desc = "Move focus to the left window" }) -vim.keymap.set("n", "", "", { desc = "Move focus to the right window" }) -vim.keymap.set("n", "", "", { desc = "Move focus to the lower window" }) -vim.keymap.set("n", "", "", { desc = "Move focus to the upper window" }) + vim.o.number = true + vim.o.relativenumber = true + vim.o.mouse = "a" + vim.o.showmode = false + vim.schedule(function() + vim.o.clipboard = "unnamedplus" + end) + vim.o.breakindent = true + vim.o.undofile = true + vim.o.ignorecase = true + vim.o.smartcase = true + vim.o.signcolumn = "yes" + vim.o.updatetime = 250 + vim.o.timeoutlen = 300 + vim.o.splitright = true + vim.o.splitbelow = true + vim.o.list = true + vim.opt.listchars = { tab = "» ", trail = "·", nbsp = "␣" } + vim.o.inccommand = "split" + vim.o.cursorline = true + vim.o.scrolloff = 15 + vim.o.confirm = true +end -vim.api.nvim_create_autocmd("TextYankPost", { - desc = "Highlight when yanking (copying) text", - group = vim.api.nvim_create_augroup("kickstart-highlight-yank", { clear = true }), - callback = function() - vim.hl.on_yank() - end, -}) +-- ============================================================ +-- SECTION 2: KEYMAPS & AUTOCMDS +-- basic keymaps, basic autocmds +-- ============================================================ +do + vim.keymap.set("n", "", "nohlsearch") + vim.diagnostic.config({ + update_in_insert = false, + severity_sort = true, + float = { border = "rounded", source = "if_many" }, + underline = { severity = { min = vim.diagnostic.severity.WARN } }, + virtual_text = true, + virtual_lines = false, + jump = { + on_jump = function(_, bufnr) + vim.diagnostic.open_float({ + bufnr = bufnr, + scope = "cursor", + focus = false, + }) + end, + }, + }) + vim.keymap.set("n", "q", vim.diagnostic.setloclist, { desc = "Open diagnostic [Q]uickfix list" }) + vim.keymap.set("t", "", "", { desc = "Exit terminal mode" }) -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 - error("Error cloning lazy.nvim:\n" .. out) + vim.keymap.set("n", "", 'echo "Use h to move!!"') + vim.keymap.set("n", "", 'echo "Use l to move!!"') + vim.keymap.set("n", "", 'echo "Use k to move!!"') + vim.keymap.set("n", "", 'echo "Use j to move!!"') + vim.keymap.set("n", "", "", { desc = "Move focus to the left window" }) + vim.keymap.set("n", "", "", { desc = "Move focus to the right window" }) + vim.keymap.set("n", "", "", { desc = "Move focus to the lower window" }) + vim.keymap.set("n", "", "", { desc = "Move focus to the upper window" }) + + vim.api.nvim_create_autocmd("TextYankPost", { + desc = "Highlight when yanking (copying) text", + group = vim.api.nvim_create_augroup("kickstart-highlight-yank", { clear = true }), + callback = function() + vim.hl.on_yank() + end, + }) +end + +-- ============================================================ +-- SECTION 3: PLUGIN MANAGER INTRO +-- vim.pack intro, build hooks +-- ============================================================ +do + local function run_build(name, cmd, cwd) + local result = vim.system(cmd, { cwd = cwd }):wait() + if result.code ~= 0 then + local stderr = result.stderr or "" + local stdout = result.stdout or "" + local output = stderr ~= "" and stderr or stdout + if output == "" then + output = "No output from build command." + end + vim.notify(("Build failed for %s:\n%s"):format(name, output), vim.log.levels.ERROR) + end + end + + vim.api.nvim_create_autocmd("PackChanged", { + callback = function(ev) + local name = ev.data.spec.name + local kind = ev.data.kind + if kind ~= "install" and kind ~= "update" then + return + end + + if name == "telescope-fzf-native.nvim" and vim.fn.executable("make") == 1 then + run_build(name, { "make" }, ev.data.path) + return + end + + if name == "LuaSnip" then + if vim.fn.has("win32") ~= 1 and vim.fn.executable("make") == 1 then + run_build(name, { "make", "install_jsregexp" }, ev.data.path) + end + return + end + + if name == "blink.cmp" and vim.fn.executable("cargo") == 1 then + run_build(name, { "cargo", "build", "--release" }, ev.data.path) + return + end + + if name == "go.nvim" then + if not ev.data.active then + vim.cmd.packadd("go.nvim") + end + pcall(function() + require("go.install").update_all_sync() + end) + return + end + + if name == "nvim-treesitter" then + if not ev.data.active then + vim.cmd.packadd("nvim-treesitter") + end + vim.cmd("TSUpdate") + return + end + end, + }) +end + +---@param repo string +---@return string +local function gh(repo) + return "https://github.com/" .. repo +end + +-- ============================================================ +-- SECTION 4: UI / CORE UX PLUGINS +-- guess-indent, gitsigns, which-key, colorscheme, todo-comments, mini modules, oil +-- ============================================================ +do + vim.pack.add({ gh("NMAC427/guess-indent.nvim") }) + require("guess-indent").setup({}) + + vim.pack.add({ gh("lewis6991/gitsigns.nvim") }) + require("gitsigns").setup({ + signs = { + add = { text = "+" }, ---@diagnostic disable-line: missing-fields + change = { text = "~" }, ---@diagnostic disable-line: missing-fields + delete = { text = "_" }, ---@diagnostic disable-line: missing-fields + topdelete = { text = "‾" }, ---@diagnostic disable-line: missing-fields + changedelete = { text = "~" }, ---@diagnostic disable-line: missing-fields + }, + }) + + vim.pack.add({ { src = "https://github.com/catppuccin/nvim", name = "catppuccin" } }) + + vim.cmd.colorscheme("catppuccin-macchiato") + + vim.pack.add({ gh("folke/todo-comments.nvim") }) + require("todo-comments").setup({ signs = false }) + + vim.pack.add({ gh("nvim-mini/mini.nvim") }) + + if vim.g.have_nerd_font then + require("mini.icons").setup() + MiniIcons.mock_nvim_web_devicons() + end + + require("mini.ai").setup({ + mappings = { + around_next = "aa", + inside_next = "ii", + }, + n_lines = 500, + }) + + require("mini.surround").setup() + + require("mini.pairs").setup() + + local statusline = require("mini.statusline") + statusline.setup({ use_icons = vim.g.have_nerd_font }) + + ---@diagnostic disable-next-line: duplicate-set-field + statusline.section_location = function() + return "%2l:%-2v" + end + + vim.pack.add({ gh("stevearc/oil.nvim") }) + require("oil").setup({ + view_options = { + show_hidden = true, + }, + }) + vim.keymap.set("n", "-", "Oil", { desc = "Open parent directory" }) +end + +-- ============================================================ +-- SECTION 5: SEARCH & NAVIGATION +-- Telescope setup, keymaps, LSP picker mappings +-- ============================================================ +do + ---@type (string|vim.pack.Spec)[] + local telescope_plugins = { + gh("nvim-lua/plenary.nvim"), + gh("nvim-telescope/telescope.nvim"), + gh("nvim-telescope/telescope-ui-select.nvim"), + } + if vim.fn.executable("make") == 1 then + table.insert(telescope_plugins, gh("nvim-telescope/telescope-fzf-native.nvim")) + end + + -- NOTE: You can install multiple plugins at once + vim.pack.add(telescope_plugins) + + require("telescope").setup({ + extensions = { + ["ui-select"] = { require("telescope.themes").get_dropdown() }, + }, + }) + + pcall(require("telescope").load_extension, "fzf") + pcall(require("telescope").load_extension, "ui-select") + + local builtin = require("telescope.builtin") + vim.keymap.set("n", "sh", builtin.help_tags, { desc = "[S]earch [H]elp" }) + vim.keymap.set("n", "sk", builtin.keymaps, { desc = "[S]earch [K]eymaps" }) + vim.keymap.set("n", "sf", builtin.find_files, { desc = "[S]earch [F]iles" }) + vim.keymap.set("n", "ss", builtin.builtin, { desc = "[S]earch [S]elect Telescope" }) + vim.keymap.set({ "n", "v" }, "sw", builtin.grep_string, { desc = "[S]earch current [W]ord" }) + vim.keymap.set("n", "sg", builtin.live_grep, { desc = "[S]earch by [G]rep" }) + vim.keymap.set("n", "sd", builtin.diagnostics, { desc = "[S]earch [D]iagnostics" }) + vim.keymap.set("n", "sr", builtin.resume, { desc = "[S]earch [R]esume" }) + vim.keymap.set("n", "s.", builtin.oldfiles, { desc = '[S]earch Recent Files ("." for repeat)' }) + vim.keymap.set("n", "sc", builtin.commands, { desc = "[S]earch [C]ommands" }) + vim.keymap.set("n", "", builtin.buffers, { desc = "[ ] Find existing buffers" }) + + vim.api.nvim_create_autocmd("LspAttach", { + group = vim.api.nvim_create_augroup("telescope-lsp-attach", { clear = true }), + callback = function(event) + local buf = event.buf + + vim.keymap.set("n", "grr", builtin.lsp_references, { buffer = buf, desc = "[G]oto [R]eferences" }) + + vim.keymap.set("n", "gri", builtin.lsp_implementations, { buffer = buf, desc = "[G]oto [I]mplementation" }) + + vim.keymap.set("n", "grd", builtin.lsp_definitions, { buffer = buf, desc = "[G]oto [D]efinition" }) + + vim.keymap.set("n", "gO", builtin.lsp_document_symbols, { buffer = buf, desc = "Open Document Symbols" }) + + vim.keymap.set( + "n", + "gW", + builtin.lsp_dynamic_workspace_symbols, + { buffer = buf, desc = "Open Workspace Symbols" } + ) + + vim.keymap.set( + "n", + "grt", + builtin.lsp_type_definitions, + { buffer = buf, desc = "[G]oto [T]ype Definition" } + ) + end, + }) + + vim.keymap.set("n", "/", function() + builtin.current_buffer_fuzzy_find(require("telescope.themes").get_dropdown({ + winblend = 10, + previewer = false, + })) + end, { desc = "[/] Fuzzily search in current buffer" }) + + vim.keymap.set("n", "s/", function() + builtin.live_grep({ + grep_open_files = true, + prompt_title = "Live Grep in Open Files", + }) + end, { desc = "[S]earch [/] in Open Files" }) + + vim.keymap.set("n", "sn", function() + builtin.find_files({ cwd = vim.fn.stdpath("config"), follow = true }) + end, { desc = "[S]earch [N]eovim files" }) +end + +-- ============================================================ +-- SECTION 6: LSP +-- LSP keymaps, server configuration, Mason tools installations +-- ============================================================ +do + vim.pack.add({ gh("j-hui/fidget.nvim") }) + require("fidget").setup({}) + + vim.api.nvim_create_autocmd("LspAttach", { + group = vim.api.nvim_create_augroup("kickstart-lsp-attach", { clear = true }), + callback = function(event) + local map = function(keys, func, desc, mode) + mode = mode or "n" + vim.keymap.set(mode, keys, func, { buffer = event.buf, desc = "LSP: " .. desc }) + end + + map("grn", vim.lsp.buf.rename, "[R]e[n]ame") + + map("gra", vim.lsp.buf.code_action, "[G]oto Code [A]ction", { "n", "x" }) + + map("grD", vim.lsp.buf.declaration, "[G]oto [D]eclaration") + + local client = vim.lsp.get_client_by_id(event.data.client_id) + if client and client:supports_method("textDocument/documentHighlight", event.buf) then + local highlight_augroup = vim.api.nvim_create_augroup("kickstart-lsp-highlight", { clear = false }) + vim.api.nvim_create_autocmd({ "CursorHold", "CursorHoldI" }, { + buffer = event.buf, + group = highlight_augroup, + callback = vim.lsp.buf.document_highlight, + }) + + vim.api.nvim_create_autocmd({ "CursorMoved", "CursorMovedI" }, { + buffer = event.buf, + group = highlight_augroup, + callback = vim.lsp.buf.clear_references, + }) + + vim.api.nvim_create_autocmd("LspDetach", { + group = vim.api.nvim_create_augroup("kickstart-lsp-detach", { clear = true }), + callback = function(event2) + vim.lsp.buf.clear_references() + vim.api.nvim_clear_autocmds({ group = "kickstart-lsp-highlight", buffer = event2.buf }) + end, + }) + end + + if client and client:supports_method("textDocument/inlayHint", event.buf) then + map("th", function() + vim.lsp.inlay_hint.enable(not vim.lsp.inlay_hint.is_enabled({ bufnr = event.buf })) + end, "[T]oggle Inlay [H]ints") + end + end, + }) + + -- Enable the following language servers + -- Feel free to add/remove any LSPs that you want here. They will automatically be installed. + -- See `:help lsp-config` for information about keys and how to configure + ---@type table + local servers = { + clangd = {}, + gopls = {}, + pyright = {}, + rust_analyzer = {}, + ts_ls = {}, + stylua = {}, + zls = {}, + jdtls = {}, + lua_ls = { + on_init = function(client) + client.server_capabilities.documentFormattingProvider = false + + if client.workspace_folders then + local path = client.workspace_folders[1].name + if + path ~= vim.fn.stdpath("config") + and (vim.uv.fs_stat(path .. "/.luarc.json") or vim.uv.fs_stat(path .. "/.luarc.jsonc")) + then + return + end + end + + local current_settings = client.config.settings --[[@as lspconfig.settings.lua_ls]] + client.config.settings.Lua = vim.tbl_deep_extend("force", current_settings.Lua, { + runtime = { + version = "LuaJIT", + path = { "lua/?.lua", "lua/?/init.lua" }, + }, + workspace = { + checkThirdParty = false, + library = vim.api.nvim_get_runtime_file("", true), + }, + }) + end, + ---@type lspconfig.settings.lua_ls + settings = { + Lua = { + format = { enable = false }, + }, + }, + }, + } + + vim.pack.add({ + gh("neovim/nvim-lspconfig"), + gh("mason-org/mason.nvim"), + gh("mason-org/mason-lspconfig.nvim"), + gh("WhoIsSethDaniel/mason-tool-installer.nvim"), + }) + + require("mason").setup({}) + + require("mason-lspconfig").setup({ + automatic_enable = false, + }) + + local ensure_installed = vim.tbl_keys(servers or {}) + vim.list_extend(ensure_installed, {}) + + require("mason-tool-installer").setup({ ensure_installed = ensure_installed }) + + for name, server in pairs(servers) do + vim.lsp.config(name, server) + vim.lsp.enable(name) end end ----@type vim.Option -local rtp = vim.opt.rtp -rtp:prepend(lazypath) - -require("lazy").setup({ - { "NMAC427/guess-indent.nvim", opts = {} }, - - { - "lewis6991/gitsigns.nvim", - ---@module 'gitsigns' - ---@type Gitsigns.Config - ---@diagnostic disable-next-line: missing-fields - opts = { - signs = { - add = { text = "+" }, ---@diagnostic disable-line: missing-fields - change = { text = "~" }, ---@diagnostic disable-line: missing-fields - delete = { text = "_" }, ---@diagnostic disable-line: missing-fields - topdelete = { text = "‾" }, ---@diagnostic disable-line: missing-fields - changedelete = { text = "~" }, ---@diagnostic disable-line: missing-fields - }, - }, - }, - - { - "MeanderingProgrammer/render-markdown.nvim", - dependencies = { "nvim-treesitter/nvim-treesitter", "nvim-tree/nvim-web-devicons" }, - opts = {}, - ft = { "markdown", "norg", "rmd", "org", "codecompanion" }, - }, - - { - "iamcco/markdown-preview.nvim", - cmd = { "MarkdownPreviewToggle", "MarkdownPreview", "MarkdownPreviewStop" }, - build = "cd app && yarn install", - init = function() - vim.g.mkdp_filetypes = { "markdown" } - end, - ft = { "markdown" }, - }, - - { - "stevearc/oil.nvim", - ---@module 'oil' - ---@type oil.SetupOpts - opts = { - view_options = { - show_hidden = true, - }, - }, - dependencies = { "nvim-tree/nvim-web-devicons" }, - lazy = false, - keys = { - { "-", "Oil", desc = "Open parent directory" }, - }, - }, - - { - "nvim-telescope/telescope.nvim", - enabled = true, - event = "VimEnter", - dependencies = { - "nvim-lua/plenary.nvim", - { - "nvim-telescope/telescope-fzf-native.nvim", - build = "make", - cond = function() - return vim.fn.executable("make") == 1 - end, - }, - { "nvim-telescope/telescope-ui-select.nvim" }, - { "nvim-tree/nvim-web-devicons", enabled = vim.g.have_nerd_font }, - }, - config = function() - require("telescope").setup({ - extensions = { - ["ui-select"] = { require("telescope.themes").get_dropdown() }, - }, - }) - pcall(require("telescope").load_extension, "fzf") - pcall(require("telescope").load_extension, "ui-select") - - local builtin = require("telescope.builtin") - vim.keymap.set("n", "sh", builtin.help_tags, { desc = "[S]earch [H]elp" }) - vim.keymap.set("n", "sk", builtin.keymaps, { desc = "[S]earch [K]eymaps" }) - vim.keymap.set("n", "sf", builtin.find_files, { desc = "[S]earch [F]iles" }) - vim.keymap.set("n", "ss", builtin.builtin, { desc = "[S]earch [S]elect Telescope" }) - vim.keymap.set({ "n", "v" }, "sw", builtin.grep_string, { desc = "[S]earch current [W]ord" }) - vim.keymap.set("n", "sg", builtin.live_grep, { desc = "[S]earch by [G]rep" }) - vim.keymap.set("n", "sd", builtin.diagnostics, { desc = "[S]earch [D]iagnostics" }) - vim.keymap.set("n", "sr", builtin.resume, { desc = "[S]earch [R]esume" }) - vim.keymap.set("n", "s.", builtin.oldfiles, { desc = '[S]earch Recent Files ("." for repeat)' }) - vim.keymap.set("n", "sc", builtin.commands, { desc = "[S]earch [C]ommands" }) - vim.keymap.set("n", "", builtin.buffers, { desc = "[ ] Find existing buffers" }) - - vim.api.nvim_create_autocmd("LspAttach", { - group = vim.api.nvim_create_augroup("telescope-lsp-attach", { clear = true }), - callback = function(event) - local buf = event.buf - vim.keymap.set("n", "grr", builtin.lsp_references, { buffer = buf, desc = "[G]oto [R]eferences" }) - vim.keymap.set( - "n", - "gri", - builtin.lsp_implementations, - { buffer = buf, desc = "[G]oto [I]mplementation" } - ) - vim.keymap.set("n", "grd", builtin.lsp_definitions, { buffer = buf, desc = "[G]oto [D]efinition" }) - vim.keymap.set( - "n", - "gO", - builtin.lsp_document_symbols, - { buffer = buf, desc = "Open Document Symbols" } - ) - vim.keymap.set( - "n", - "gW", - builtin.lsp_dynamic_workspace_symbols, - { buffer = buf, desc = "Open Workspace Symbols" } - ) - vim.keymap.set( - "n", - "grt", - builtin.lsp_type_definitions, - { buffer = buf, desc = "[G]oto [T]ype Definition" } - ) - end, - }) - - vim.keymap.set("n", "/", function() - builtin.current_buffer_fuzzy_find(require("telescope.themes").get_dropdown({ - winblend = 20, - previewer = false, - })) - end, { desc = "[/] Fuzzily search in current buffer" }) - - vim.keymap.set("n", "s/", function() - builtin.live_grep({ - grep_open_files = true, - prompt_title = "Live Grep in Open Files", - }) - end, { desc = "[S]earch [/] in Open Files" }) - - vim.keymap.set("n", "sn", function() - builtin.find_files({ cwd = vim.fn.stdpath("config") }) - end, { desc = "[S]earch [N]eovim files" }) - end, - }, - - { - "neovim/nvim-lspconfig", - dependencies = { - { "j-hui/fidget.nvim", opts = {} }, - }, - config = function() - vim.api.nvim_create_autocmd("LspAttach", { - group = vim.api.nvim_create_augroup("kickstart-lsp-attach", { clear = true }), - callback = function(event) - local map = function(keys, func, desc, mode) - mode = mode or "n" - vim.keymap.set(mode, keys, func, { buffer = event.buf, desc = "LSP: " .. desc }) - end - - map("grn", vim.lsp.buf.rename, "[R]e[n]ame") - map("gra", vim.lsp.buf.code_action, "[G]oto Code [A]ction", { "n", "x" }) - map("grD", vim.lsp.buf.declaration, "[G]oto [D]eclaration") - - local client = vim.lsp.get_client_by_id(event.data.client_id) - - if client and client:supports_method("textDocument/documentHighlight", event.buf) then - local highlight_augroup = - vim.api.nvim_create_augroup("kickstart-lsp-highlight", { clear = false }) - - vim.api.nvim_create_autocmd({ "CursorHold", "CursorHoldI" }, { - buffer = event.buf, - group = highlight_augroup, - callback = vim.lsp.buf.document_highlight, - }) - - vim.api.nvim_create_autocmd({ "CursorMoved", "CursorMovedI" }, { - buffer = event.buf, - group = highlight_augroup, - callback = vim.lsp.buf.clear_references, - }) - - vim.api.nvim_create_autocmd("LspDetach", { - group = vim.api.nvim_create_augroup("kickstart-lsp-detach", { clear = true }), - callback = function(event2) - vim.lsp.buf.clear_references() - vim.api.nvim_clear_autocmds({ - group = "kickstart-lsp-highlight", - buffer = event2.buf, - }) - end, - }) - end - - if client and client:supports_method("textDocument/inlayHint", event.buf) then - map("th", function() - vim.lsp.inlay_hint.enable(not vim.lsp.inlay_hint.is_enabled({ bufnr = event.buf })) - end, "[T]oggle Inlay [H]ints") - end - end, - }) - - local servers = { - clangd = {}, - zls = {}, - gopls = {}, - rust_analyzer = {}, - omnisharp = {}, - jdtls = {}, - - ts_ls = {}, - - lua_ls = { - on_init = function(client) - if client.workspace_folders then - local path = client.workspace_folders[1].name - if - path ~= vim.fn.stdpath("config") - and (vim.uv.fs_stat(path .. "/.luarc.json") or vim.uv.fs_stat(path .. "/.luarc.jsonc")) - then - return - end - end - - client.config.settings.Lua = vim.tbl_deep_extend("force", client.config.settings.Lua, { - runtime = { - version = "LuaJIT", - path = { "lua/?.lua", "lua/?/init.lua" }, - }, - workspace = { - checkThirdParty = false, - library = vim.tbl_extend("force", vim.api.nvim_get_runtime_file("", true), { - "${3rd}/luv/library", - "${3rd}/busted/library", - }), - }, - }) - end, - settings = { - Lua = {}, - }, - }, +-- ============================================================ +-- SECTION 7: FORMATTING +-- conform.nvim setup and keymap +-- ============================================================ +do + -- [[ Formatting ]] + vim.pack.add({ gh("stevearc/conform.nvim") }) + require("conform").setup({ + notify_on_error = false, + format_on_save = function(bufnr) + local enabled_filetypes = { + -- lua = true, + -- python = true, } - - for name, server in pairs(servers) do - vim.lsp.config(name, server) - vim.lsp.enable(name) + if enabled_filetypes[vim.bo[bufnr].filetype] then + return { timeout_ms = 500 } + else + return nil end end, - }, - - { - "ray-x/go.nvim", - dependencies = { - "ray-x/guihua.lua", - "neovim/nvim-lspconfig", - "nvim-treesitter/nvim-treesitter", - "L3MON4D3/LuaSnip", + default_format_opts = { + lsp_format = "fallback", }, - event = { "CmdlineEnter" }, - ft = { "go", "gomod", "gowork", "gotmpl" }, - build = ':lua require("go.install").update_all_sync()', - opts = {}, - config = function(_, opts) - require("go").setup(opts) - local format_sync_grp = vim.api.nvim_create_augroup("GoFormat", { clear = true }) - vim.api.nvim_create_autocmd("BufWritePre", { - pattern = "*.go", - callback = function() - require("go.format").goimports() - end, - group = format_sync_grp, - }) - end, - }, - - { - "stevearc/conform.nvim", - event = { "BufWritePre" }, - cmd = { "ConformInfo" }, - keys = { - { - "f", - function() - require("conform").format({ async = true, lsp_format = "fallback" }) - end, - mode = "", - desc = "[F]ormat buffer", - }, + formatters_by_ft = { + rust = { "rustfmt" }, + python = { "isort", "black" }, + javascript = { "prettierd", "prettier", stop_after_first = true }, + go = { "goimports", "gofmt", stop_after_first = true }, }, - ---@module 'conform' - ---@type conform.setupOpts - opts = { - notify_on_error = false, - format_on_save = function(bufnr) - local disable_filetypes = { c = true, cpp = true } - if disable_filetypes[vim.bo[bufnr].filetype] then - return nil - else - return { - timeout_ms = 500, - lsp_format = "fallback", - } - end - end, - formatters_by_ft = { - lua = { "stylua" }, - python = { "isort", "black" }, - }, + }) + + vim.keymap.set({ "n", "v" }, "f", function() + require("conform").format({ async = true }) + end, { desc = "[F]ormat buffer" }) +end + +-- ============================================================ +-- SECTION 8: AUTOCOMPLETE & SNIPPETS +-- blink.cmp and luasnip setup +-- ============================================================ +do + vim.pack.add({ { src = gh("L3MON4D3/LuaSnip"), version = vim.version.range("2.*") } }) + require("luasnip").setup({}) + + vim.pack.add({ gh("rafamadriz/friendly-snippets") }) + require("luasnip.loaders.from_vscode").lazy_load() + + -- [[ Autocomplete Engine ]] + vim.pack.add({ { src = gh("saghen/blink.cmp"), version = vim.version.range("1.*") } }) + require("blink.cmp").setup({ + keymap = { + preset = "default", }, - }, - { - "saghen/blink.cmp", - event = "VimEnter", - version = "1.*", - dependencies = { - { - "L3MON4D3/LuaSnip", - version = "2.*", - build = (function() - if vim.fn.has("win32") == 1 or vim.fn.executable("make") == 0 then - return - end - return "make install_jsregexp" - end)(), - dependencies = {}, - opts = {}, - }, + appearance = { + nerd_font_variant = "mono", }, - ---@module 'blink.cmp' - ---@type blink.cmp.Config - opts = { - keymap = { - preset = "default", - }, - appearance = { - nerd_font_variant = "mono", - }, - completion = { - documentation = { auto_show = false, auto_show_delay_ms = 500 }, - }, - sources = { - default = { "lsp", "path", "snippets" }, - }, - snippets = { preset = "luasnip" }, - fuzzy = { implementation = "prefer_rust_with_warning" }, - signature = { enabled = true }, + + completion = { + documentation = { auto_show = false, auto_show_delay_ms = 500 }, }, - }, - { - "rebelot/kanagawa.nvim", - priority = 1000, - config = function() - ---@diagnostic disable-next-line: missing-fields - require("kanagawa").setup({ - theme = "wave", - }) - vim.cmd.colorscheme("kanagawa") - end, - }, + sources = { + default = { "lsp", "path", "snippets" }, + }, - { - "folke/todo-comments.nvim", - event = "VimEnter", - dependencies = { "nvim-lua/plenary.nvim" }, - ---@module 'todo-comments' - ---@type TodoOptions - ---@diagnostic disable-next-line: missing-fields - opts = { signs = false }, - }, + snippets = { preset = "luasnip" }, + fuzzy = { implementation = "prefer_rust_with_warning" }, - { - "nvim-mini/mini.nvim", - config = function() - require("mini.ai").setup({ n_lines = 500 }) - require("mini.surround").setup() - require("mini.pairs").setup() - local statusline = require("mini.statusline") - statusline.setup({ use_icons = vim.g.have_nerd_font }) - ---@diagnostic disable-next-line: duplicate-set-field - statusline.section_location = function() - return "%2l:%-2v" - end - end, - }, + signature = { enabled = true }, + }) +end - { - "nvim-treesitter/nvim-treesitter", - lazy = false, - branch = "main", - build = ":TSUpdate", - config = function() - -- Pre-install parsers for languages we know we use. - -- For any other filetype, the FileType autocmd below will - -- auto-install the parser on first open. - local parsers = { - "javascript", - "typescript", - "tsx", - "json", - "bash", - "c", - "c_sharp", - "diff", - "go", - "html", - "java", - "lua", - "luadoc", - "markdown", - "markdown_inline", - "python", - "query", - "rust", - "vim", - "vimdoc", - "zig", - } +-- ============================================================ +-- SECTION 9: TREESITTER +-- Parser installation, syntax highlighting, folds, indentation +-- ============================================================ +do + vim.pack.add({ { src = gh("nvim-treesitter/nvim-treesitter"), version = "main" } }) - local installed = require("nvim-treesitter.config").get_installed() - local to_install = vim.tbl_filter(function(p) - return not vim.tbl_contains(installed, p) - end, parsers) - if #to_install > 0 then - require("nvim-treesitter").install(to_install) + local parsers = + { "bash", "c", "diff", "html", "lua", "luadoc", "markdown", "markdown_inline", "query", "vim", "vimdoc" } + require("nvim-treesitter").install(parsers) + + ---@param buf integer + ---@param language string + local function treesitter_try_attach(buf, language) + if not vim.treesitter.language.add(language) then + return + end + vim.treesitter.start(buf, language) + local has_indent_query = vim.treesitter.query.get(language, "indents") ~= nil + if has_indent_query then + vim.bo.indentexpr = "v:lua.require'nvim-treesitter'.indentexpr()" + end + end + + local available_parsers = require("nvim-treesitter").get_available() + vim.api.nvim_create_autocmd("FileType", { + callback = function(args) + local buf, filetype = args.buf, args.match + + local language = vim.treesitter.language.get_lang(filetype) + if not language then + return end - -- Helper: try to start treesitter highlighting + indentation for a buffer - local function treesitter_try_attach(buf, language) - if not pcall(vim.treesitter.start, buf, language) then - return - end - local has_indent_query = pcall(vim.treesitter.query.get, language, "indents") - if has_indent_query then - vim.bo[buf].indentexpr = "v:lua.require'nvim-treesitter'.indentexpr()" - end + local installed_parsers = require("nvim-treesitter").get_installed("parsers") + + if vim.tbl_contains(installed_parsers, language) then + treesitter_try_attach(buf, language) + elseif vim.tbl_contains(available_parsers, language) then + require("nvim-treesitter").install(language):await(function() + treesitter_try_attach(buf, language) + end) + else + treesitter_try_attach(buf, language) end - - -- On every FileType event: - -- 1. If the parser is already installed, attach immediately. - -- 2. If not, auto-install it then attach once done. - vim.api.nvim_create_autocmd("FileType", { - callback = function(args) - local buf, filetype = args.buf, args.match - local language = vim.treesitter.language.get_lang(filetype) - if not language then - return - end - - if vim.treesitter.language.add(language) then - -- Parser already available — attach right away - treesitter_try_attach(buf, language) - else - -- Parser missing — install it, then attach - require("nvim-treesitter").install(language):await(function() - treesitter_try_attach(buf, language) - end) - end - end, - }) end, - }, -}, { ---@diagnostic disable-line: missing-fields - ui = { - icons = vim.g.have_nerd_font and {} or { - cmd = "⌘", - config = "🛠", - event = "📅", - ft = "📂", - init = "⚙", - keys = "🗝", - plugin = "🔌", - runtime = "💻", - require = "🌙", - source = "📄", - start = "🚀", - task = "📌", - lazy = "💤 ", - }, - }, -}) + }) +end + +-- ============================================================ +-- SECTION 10: GO +-- go.nvim setup with guihua.lua dependency +-- ============================================================ +do + vim.pack.add({ + gh("ray-x/guihua.lua"), + gh("ray-x/go.nvim"), + }) + + require("go").setup({}) + + local format_sync_grp = vim.api.nvim_create_augroup("GoFormat", { clear = true }) + vim.api.nvim_create_autocmd("BufWritePre", { + pattern = "*.go", + callback = function() + require("go.format").goimports() + end, + group = format_sync_grp, + }) +end +-- vim: ts=2 sts=2 sw=2 et diff --git a/nvim/.config/nvim/nvim-pack-lock.json b/nvim/.config/nvim/nvim-pack-lock.json new file mode 100644 index 0000000..090af7f --- /dev/null +++ b/nvim/.config/nvim/nvim-pack-lock.json @@ -0,0 +1,95 @@ +{ + "plugins": { + "LuaSnip": { + "rev": "642b0c595e11608b4c18219e93b88d7637af27bc", + "src": "https://github.com/L3MON4D3/LuaSnip", + "version": "2.0.0 - 3.0.0" + }, + "blink.cmp": { + "rev": "78336bc89ee5365633bcf754d93df01678b5c08f", + "src": "https://github.com/saghen/blink.cmp", + "version": "1.0.0 - 2.0.0" + }, + "catppuccin": { + "rev": "edefef779ab08ce1a4a404713e3012b0d202bd35", + "src": "https://github.com/catppuccin/nvim" + }, + "conform.nvim": { + "rev": "016802de402556da54c36bd7359b441266b01cdd", + "src": "https://github.com/stevearc/conform.nvim" + }, + "fidget.nvim": { + "rev": "6f793b2bcd2d35e201c09520f698bb763220908a", + "src": "https://github.com/j-hui/fidget.nvim" + }, + "friendly-snippets": { + "rev": "6cd7280adead7f586db6fccbd15d2cac7e2188b9", + "src": "https://github.com/rafamadriz/friendly-snippets" + }, + "gitsigns.nvim": { + "rev": "5be654f2232c10ddcad19c1607a67b6b4b78fc29", + "src": "https://github.com/lewis6991/gitsigns.nvim" + }, + "go.nvim": { + "rev": "0768d79bbebdb1a112a845f9cd6293bfbd544dab", + "src": "https://github.com/ray-x/go.nvim" + }, + "guess-indent.nvim": { + "rev": "84a4987ff36798c2fc1169cbaff67960aed9776f", + "src": "https://github.com/NMAC427/guess-indent.nvim" + }, + "guihua.lua": { + "rev": "4c513d5dac550af77034cced421967b393261509", + "src": "https://github.com/ray-x/guihua.lua" + }, + "mason-lspconfig.nvim": { + "rev": "9d28935aa95fa6c1dc7c4d6747f101a72a8a4bec", + "src": "https://github.com/mason-org/mason-lspconfig.nvim" + }, + "mason-tool-installer.nvim": { + "rev": "443f1ef8b5e6bf47045cb2217b6f748a223cf7dc", + "src": "https://github.com/WhoIsSethDaniel/mason-tool-installer.nvim" + }, + "mason.nvim": { + "rev": "2a6940af80375532e5e9e7c1f2fc6319a1b7a69d", + "src": "https://github.com/mason-org/mason.nvim" + }, + "mini.nvim": { + "rev": "8d86a057fa14681cf7cab74ea7cba894a0abe14f", + "src": "https://github.com/nvim-mini/mini.nvim" + }, + "nvim-lspconfig": { + "rev": "221c43884319e791519f0d6c94a7f2fbcd653278", + "src": "https://github.com/neovim/nvim-lspconfig" + }, + "nvim-treesitter": { + "rev": "e82ef6ae2c3eeb96c6916b29917f96bf630b2cdb", + "src": "https://github.com/nvim-treesitter/nvim-treesitter", + "version": "'main'" + }, + "oil.nvim": { + "rev": "b73018b75affd13fa38e2fc94ef753b465f770d7", + "src": "https://github.com/stevearc/oil.nvim" + }, + "plenary.nvim": { + "rev": "74b06c6c75e4eeb3108ec01852001636d85a932b", + "src": "https://github.com/nvim-lua/plenary.nvim" + }, + "telescope-fzf-native.nvim": { + "rev": "b25b749b9db64d375d782094e2b9dce53ad53a40", + "src": "https://github.com/nvim-telescope/telescope-fzf-native.nvim" + }, + "telescope-ui-select.nvim": { + "rev": "6e51d7da30bd139a6950adf2a47fda6df9fa06d2", + "src": "https://github.com/nvim-telescope/telescope-ui-select.nvim" + }, + "telescope.nvim": { + "rev": "40aedd8a68c78a656a10a8d62d80c54af59420fb", + "src": "https://github.com/nvim-telescope/telescope.nvim" + }, + "todo-comments.nvim": { + "rev": "31e3c38ce9b29781e4422fc0322eb0a21f4e8668", + "src": "https://github.com/folke/todo-comments.nvim" + } + } +}