diff options
Diffstat (limited to 'dot_config/nvim/lua')
28 files changed, 899 insertions, 339 deletions
diff --git a/dot_config/nvim/lua/ibrahim/init.lua b/dot_config/nvim/lua/ibrahim/init.lua new file mode 100644 index 0000000..99a97be --- /dev/null +++ b/dot_config/nvim/lua/ibrahim/init.lua @@ -0,0 +1,19 @@ +require("ibrahim.lazy_init") +require("ibrahim.options") +require("ibrahim.keymaps") + +-- Format automatically after writing file +vim.api.nvim_create_autocmd('LspAttach', { + callback = function(args) + local client = vim.lsp.get_client_by_id(args.data.client_id) + + if client ~= nil and client:supports_method('textDocument/formatting') then + vim.api.nvim_create_autocmd('BufWritePre', { + buffer = args.buf, + callback = function() + vim.lsp.buf.format({bufnr = args.buf, id = client.id}) + end, + }) + end + end, +}) diff --git a/dot_config/nvim/lua/ibrahim/keymaps.lua b/dot_config/nvim/lua/ibrahim/keymaps.lua new file mode 100644 index 0000000..feb84da --- /dev/null +++ b/dot_config/nvim/lua/ibrahim/keymaps.lua @@ -0,0 +1,167 @@ +-- Set leader key as Space +vim.g.mapleader = " " + +local function map(mode, left, right, opts) + local default_opts = { + noremap = true, + silent = true, + } + opts = opts or {} + -- "keep" mode preserves the values from the leftmost table, + -- so prioritize any options provided over the defaults + local full_opts = vim.tbl_extend("keep", opts, default_opts) + vim.keymap.set(mode, left, right, full_opts) +end + +-- Clear any highlighted searches when pressing Esc +-- This lets me leave hlsearch on by default while having an easy way to clear +-- it again. +map({ "i", "n" }, "<esc>", "<cmd>noh<cr><esc>", { desc = "Escape and clear hlsearch" }) + +-- Move lines while in visual mode with J and K +map("v", "J", ":m '>+1<CR>gv=gv") +map("v", "K", ":m '<-2<CR>gv=gv") + +-- Easier execution of Lua code +map("n", "<leader>x", "<cmd>.lua<CR>", { desc = "Execute the current line" }) +map("n", "<leader><leader>x", "<cmd>source %<CR>", { desc = "Execute the current file" }) + +-- Keep cursor in the same place when using J to join lines +map("n", "J", "mzJ`z") + +-- Center the screen when jumping around with C-d and C-u +map("n", "<C-d>", "<C-d>zz") +map("n", "<C-u>", "<C-u>zz") + +-- Center the screen when jumping to next / previous search terms +map("n", "n", "nzzzv") +map("n", "N", "Nzzzv") + +-- Quick maps to paste/delete without overwriting the current buffer +map("x", "<leader>p", '"_dP') +map({ "n", "v" }, "<leader>d", '"_dP') + +-- Easier quickfix naviagion +map("n", "<C-k>", "<cmd>cprev<cr>", { desc = "Quickfix previous item" }) +map("n", "<C-j>", "<cmd>cnext<cr>", { desc = "Quickfix next item" }) + +-- System clipboard +map({ "n", "v" }, "<leader>cd", '"+d', { desc = "Clipboard delete" }) +map({ "n", "v" }, "<leader>cp", '"+p', { desc = "Clipboard paste" }) +map({ "n", "v" }, "<leader>cy", '"+y', { desc = "Clipboard yank" }) + +-- Map g- to netrw (temporary placeholder for oil) +-- map("n", "g-", vim.cmd.Ex, { desc = "Open netrw" }) + +map("n", "<leader>gx", function() + local command = "go run " .. vim.fn.expand("%") + local f = assert(io.popen(command, "r")) + local s = assert(f:read("*a")) + f:close() + s = string.gsub(s, "^%s+", "") + s = string.gsub(s, "%s+$", "") + s = string.gsub(s, "[\n\r]+", " ") + print(s) +end, { desc = "Execute current go file" }) + + +-- Create a GitHub URL for the current file and line number, and copy it +-- to the clipboard. +map("n", "<leader>yfg", function() + local remote_url = vim.fn.system("git config --get remote.origin.url") + if not remote_url:find("github.com") then + vim.notify("This is not a GitHub repository") + return + end + + local trimmed_remote_url = remote_url:gsub("%.git", ""):gsub("%s+", ""):gsub("\n", "") + local branch_name = vim.fn.system("git rev-parse --abbrev-ref HEAD"):gsub("\n", "") + + -- Now construct the link in this format: + -- <remote>/blob/<branch>/<file>#L<line> + + local filepath = vim.fn.expand("%:."):gsub("\\", "/") + + local line = vim.fn.line(".") + local result = trimmed_remote_url .. "/blob/" .. branch_name .. "/" .. filepath .. "#L" .. line + + vim.fn.setreg("+", result) + vim.notify("Copied GitHub URL to clipboard: " .. result) +end, { desc = "Yank GitHub URL to clipboard", expr = true }) + + +-- LSP specific keybindings +vim.api.nvim_create_autocmd("LspAttach", { + group = vim.api.nvim_create_augroup("IbrahimLspConfig", {}), + callback = function(evt) + local function lsp_map(mode, lhs, rhs, desc) + local opts = { buffer = evt.buf, desc = "LSP: " .. (desc or "") } + map(mode, lhs, rhs, opts) + end + + local has_telescope, _ = pcall(require, "telescope") + local function lsp_telescope_map(mode, lhs, with_telescope_rhs, no_telescope_rhs, desc) + if has_telescope then + desc = desc .. " (Telescope)" + lsp_map(mode, lhs, with_telescope_rhs, desc) + else + lsp_map(mode, lhs, no_telescope_rhs, desc) + end + end + local function tele_builtin(name, opts) + return function() + require("telescope.builtin")[name](opts) + end + end + + -- Navigation + lsp_map("n", "gd", vim.lsp.buf.definition, "[G]oto [D]efinition") + lsp_map("n", "gt", vim.lsp.buf.type_definition, "[G]oto [t]ype Definition") + lsp_map("n", "gD", vim.lsp.buf.declaration, "[G]oto [D]eclaration") + lsp_map("n", "gr", vim.lsp.buf.references, "[G]oto [R]eferences") + lsp_map("n", "gI", vim.lsp.buf.implementation, "[G]oto [I]mplementation") + + lsp_telescope_map("n", "gr", tele_builtin("lsp_references"), vim.lsp.buf.references, "Go to references") + lsp_telescope_map( + "n", + "<leader>sn", + tele_builtin("lsp_document_symbols"), + vim.lsp.buf.document_symbol, + "Search document symbols" + ) + lsp_telescope_map( + "n", + "<leader>sN", + tele_builtin("lsp_dynamic_workspace_symbols"), + vim.lsp.buf.workspace_symbol, + "Search workspace symbols" + ) + + -- Code changes + lsp_map("n", "<leader>cr", vim.lsp.buf.rename, "Rename") + -- <leader>ca is being overwritten by the 'actions-preview' plugin + -- lsp_map("n", "<leader>ca", vim.lsp.buf.code_action, "Code actions") + + -- Diagnostics + lsp_map("n", "<leader>ds", vim.diagnostic.open_float, "[s]how [d]iagnostic window") + lsp_map("n", "<leader>dn", function() + vim.diagnostic.jump({ count = 1, float = true }) + end, "Go to [n]ext [d]iagnostic") + lsp_map("n", "<leader>dp", function() + vim.diagnostic.jump({ count = -1, float = true }) + end, "Go to [p]revious [d]iagnostic") + + -- See `:help K` for why this keymap + lsp_map("n", "K", function () + vim.lsp.buf.hover { border = "single", max_height = 25, max_width = 120 } + end, "Hover Documentation") + lsp_map("n", "<C-S-k>", vim.lsp.buf.signature_help, "Signature Documentation") + + -- Workspace + lsp_map("n", "<leader>wa", vim.lsp.buf.add_workspace_folder, "[W]orkspace [A]dd Folder") + lsp_map("n", "<leader>wr", vim.lsp.buf.remove_workspace_folder, "[W]orkspace [R]emove Folder") + lsp_map("n", "<leader>wl", function() + print(vim.inspect(vim.lsp.buf.list_workspace_folders())) + end, "[W]orkspace [L]ist Folders") + end, +}) diff --git a/dot_config/nvim/lua/config/lazy.lua b/dot_config/nvim/lua/ibrahim/lazy_init.lua index 2e0f130..4d88957 100644 --- a/dot_config/nvim/lua/config/lazy.lua +++ b/dot_config/nvim/lua/ibrahim/lazy_init.lua @@ -15,18 +15,16 @@ if not (vim.uv or vim.loop).fs_stat(lazypath) then end vim.opt.rtp:prepend(lazypath) --- Make sure to setup `mapleader` and `maplocalleader` before --- loading lazy.nvim so that mappings are correct. --- This is also a good place to setup other settings (vim.opt) vim.g.mapleader = " " -vim.g.maplocalleader = " " +vim.opt.termguicolors = true -- Setup lazy.nvim require("lazy").setup({ spec = { -- import your plugins - { import = "plugins" }, + { import = "ibrahim.plugins" }, }, + install = { colorscheme = { "rose-pine" } }, -- Configure any other settings here. See the documentation for more details. -- automatically check for plugin updates checker = { enabled = true }, diff --git a/dot_config/nvim/lua/ibrahim/options.lua b/dot_config/nvim/lua/ibrahim/options.lua new file mode 100644 index 0000000..9e7252b --- /dev/null +++ b/dot_config/nvim/lua/ibrahim/options.lua @@ -0,0 +1,35 @@ +local opt = vim.opt + +opt.incsearch = true + +opt.number = true +opt.relativenumber = true + +opt.scrolloff = 8 + +vim.o.foldtext = "" +opt.foldlevelstart = 1 + +opt.conceallevel = 2 + +opt.tabstop = 4 +opt.softtabstop = 4 +opt.shiftwidth = 0 +opt.expandtab = true + +opt.autoindent = true +opt.smartindent = true +opt.breakindent = true + +opt.swapfile = false +opt.backup = false +opt.undodir = vim.fn.expand("~/.vim/undodir") +opt.undofile = true + +opt.ignorecase = true +opt.smartcase = true + +opt.updatetime = 250 + +vim.o.background = "dark" +vim.cmd([[colorscheme rose-pine]]) diff --git a/dot_config/nvim/lua/ibrahim/plugins/actions-preview.lua b/dot_config/nvim/lua/ibrahim/plugins/actions-preview.lua new file mode 100644 index 0000000..05532c4 --- /dev/null +++ b/dot_config/nvim/lua/ibrahim/plugins/actions-preview.lua @@ -0,0 +1,6 @@ +return { + "aznhe21/actions-preview.nvim", + config = function() + vim.keymap.set({ "v", "n" }, "<leader>ca", require("actions-preview").code_actions) + end, +} diff --git a/dot_config/nvim/lua/plugins/colorscheme.lua b/dot_config/nvim/lua/ibrahim/plugins/colorscheme.lua index 7cc5fd9..7cc5fd9 100644 --- a/dot_config/nvim/lua/plugins/colorscheme.lua +++ b/dot_config/nvim/lua/ibrahim/plugins/colorscheme.lua diff --git a/dot_config/nvim/lua/ibrahim/plugins/commenter.lua b/dot_config/nvim/lua/ibrahim/plugins/commenter.lua new file mode 100644 index 0000000..cdc88fe --- /dev/null +++ b/dot_config/nvim/lua/ibrahim/plugins/commenter.lua @@ -0,0 +1,11 @@ +return { + 'echasnovski/mini.nvim', + version = false, + config = function(_, opts) + -- I'm not sure why this is requireed. I thought Lazy.nvim didn't require the + -- config key if the only line in the function was to call setup(). + -- However, without this key, this plugin fails to load with the error + -- "mini" could not be found + require("mini.comment").setup(opts) + end, +} diff --git a/dot_config/nvim/lua/ibrahim/plugins/conform.lua b/dot_config/nvim/lua/ibrahim/plugins/conform.lua new file mode 100644 index 0000000..c1b38ab --- /dev/null +++ b/dot_config/nvim/lua/ibrahim/plugins/conform.lua @@ -0,0 +1,48 @@ +-- Use prettierd if it's available or prettier otherwise, but don't +-- try to run them both. +local prettier = { { "prettierd", "prettier" } } + +return { + "stevearc/conform.nvim", + event = { "BufReadPre", "BufNewFile" }, + cmd = { "ConformInfo", "Format" }, + opts = { + formatters = { + sqlfluff = { + -- By default, SQLFluff uses "ansi" formatting. My projects + -- right now use MySQL formatting instead. + -- Still looking for a better way to manage this. + args = { "fix", "--force", "--dialect=mysql", "-" }, + }, + }, + formatters_by_ft = { + lua = { "stylua" }, + + -- Ruff LSP handles formatting for Python code + -- -- Multiple items in one table will be run sequentially + python = { "ruff_format" }, + + c = { "clang-format" }, + css = prettier, + html = prettier, + javascript = prettier, + json = prettier, + markdown = prettier, + typescript = prettier, + yaml = prettier, + + sql = { "sqlfluff" }, + }, + }, + config = function(_, opts) + local conform = require("conform") + require("conform").setup(opts) + + local function format() + conform.format({ async = true, lsp_fallback = true }) + end + + vim.keymap.set({ "n", "v" }, "<leader>rf", format, { desc = "Reformat" }) + vim.api.nvim_create_user_command("Format", format, {}) + end, +} diff --git a/dot_config/nvim/lua/ibrahim/plugins/dap.lua b/dot_config/nvim/lua/ibrahim/plugins/dap.lua new file mode 100644 index 0000000..4e1df62 --- /dev/null +++ b/dot_config/nvim/lua/ibrahim/plugins/dap.lua @@ -0,0 +1,94 @@ +return { + { + "mfussenegger/nvim-dap", + dependencies = { + "leoluz/nvim-dap-go", + "rcarriga/nvim-dap-ui", + "theHamsta/nvim-dap-virtual-text", + "nvim-neotest/nvim-nio", + "williamboman/mason.nvim", + }, + config = function() + local dap = require "dap" + local ui = require "dapui" + + require("dapui").setup() + -- require("dap-go").setup() + + -- require("nvim-dap-virtual-text").setup { + -- -- This just tries to mitigate the chance that I leak tokens here. Probably won't stop it from happening... + -- display_callback = function(variable) + -- local name = string.lower(variable.name) + -- local value = string.lower(variable.value) + -- if name:match "secret" or name:match "api" or value:match "secret" or value:match "api" then + -- return "*****" + -- end + -- + -- if #variable.value > 15 then + -- return " " .. string.sub(variable.value, 1, 15) .. "... " + -- end + -- + -- return " " .. variable.value + -- end, + -- } + + -- Handled by nvim-dap-go + -- dap.adapters.go = { + -- type = "server", + -- port = "${port}", + -- executable = { + -- command = "dlv", + -- args = { "dap", "-l", "127.0.0.1:${port}" }, + -- }, + -- } + + -- local elixir_ls_debugger = vim.fn.exepath "elixir-ls-debugger" + -- if elixir_ls_debugger ~= "" then + -- dap.adapters.mix_task = { + -- type = "executable", + -- command = elixir_ls_debugger, + -- } + -- + -- dap.configurations.elixir = { + -- { + -- type = "mix_task", + -- name = "phoenix server", + -- task = "phx.server", + -- request = "launch", + -- projectDir = "${workspaceFolder}", + -- exitAfterTaskReturns = false, + -- debugAutoInterpretAllModules = false, + -- }, + -- } + -- end + + vim.keymap.set("n", "<space>b", dap.toggle_breakpoint) + vim.keymap.set("n", "<space>gb", dap.run_to_cursor) + + -- Eval var under cursor + vim.keymap.set("n", "<space>?", function() + require("dapui").eval(nil, { enter = true }) + end) + + vim.keymap.set("n", "<F1>", dap.continue) + vim.keymap.set("n", "<F2>", dap.step_into) + vim.keymap.set("n", "<F3>", dap.step_over) + vim.keymap.set("n", "<F4>", dap.step_out) + vim.keymap.set("n", "<F5>", dap.step_back) + vim.keymap.set("n", "<F13>", dap.restart) + + dap.listeners.before.attach.dapui_config = function() + ui.open() + end + dap.listeners.before.launch.dapui_config = function() + ui.open() + end + dap.listeners.before.event_terminated.dapui_config = function() + ui.close() + end + dap.listeners.before.event_exited.dapui_config = function() + ui.close() + end + end, + }, +} diff --git a/dot_config/nvim/lua/ibrahim/plugins/fugitive.lua b/dot_config/nvim/lua/ibrahim/plugins/fugitive.lua new file mode 100644 index 0000000..13a8f18 --- /dev/null +++ b/dot_config/nvim/lua/ibrahim/plugins/fugitive.lua @@ -0,0 +1,6 @@ +return { + "tpope/vim-fugitive", + keys = { -- load the plugin only when using it's keybinding: + { "<leader>gs", vim.cmd.Git, desc = "Vim Fugitive" }, + }, +} diff --git a/dot_config/nvim/lua/plugins/gitsigns.lua b/dot_config/nvim/lua/ibrahim/plugins/gitsigns.lua index dd89dfb..dd89dfb 100644 --- a/dot_config/nvim/lua/plugins/gitsigns.lua +++ b/dot_config/nvim/lua/ibrahim/plugins/gitsigns.lua diff --git a/dot_config/nvim/lua/plugins/gruvbox.lua b/dot_config/nvim/lua/ibrahim/plugins/gruvbox.lua index a04d39c..a04d39c 100644 --- a/dot_config/nvim/lua/plugins/gruvbox.lua +++ b/dot_config/nvim/lua/ibrahim/plugins/gruvbox.lua diff --git a/dot_config/nvim/lua/plugins/harpoon.lua b/dot_config/nvim/lua/ibrahim/plugins/harpoon.lua index 695b69c..695b69c 100644 --- a/dot_config/nvim/lua/plugins/harpoon.lua +++ b/dot_config/nvim/lua/ibrahim/plugins/harpoon.lua diff --git a/dot_config/nvim/lua/plugins/jinja.lua b/dot_config/nvim/lua/ibrahim/plugins/jinja.lua index 295db2f..295db2f 100644 --- a/dot_config/nvim/lua/plugins/jinja.lua +++ b/dot_config/nvim/lua/ibrahim/plugins/jinja.lua diff --git a/dot_config/nvim/lua/plugins/lsp-lines.lua b/dot_config/nvim/lua/ibrahim/plugins/lsp-lines.lua index e15055e..e15055e 100644 --- a/dot_config/nvim/lua/plugins/lsp-lines.lua +++ b/dot_config/nvim/lua/ibrahim/plugins/lsp-lines.lua diff --git a/dot_config/nvim/lua/ibrahim/plugins/lsp.lua b/dot_config/nvim/lua/ibrahim/plugins/lsp.lua new file mode 100644 index 0000000..a7fca1f --- /dev/null +++ b/dot_config/nvim/lua/ibrahim/plugins/lsp.lua @@ -0,0 +1,377 @@ +-- return { +-- { +-- "VonHeikemen/lsp-zero.nvim", +-- branch = "v4.x", +-- lazy = true, +-- config = false, +-- }, +-- +-- { +-- "williamboman/mason.nvim", +-- lazy = false, +-- config = true, +-- }, +-- +-- -- Autocompletion +-- { +-- "hrsh7th/nvim-cmp", +-- event = { "InsertEnter", "CmdlineEnter" }, +-- dependencies = { +-- "L3MON4D3/LuaSnip", -- Snippet engine +-- "onsails/lspkind.nvim", -- Pretty formatting in the completion menu +-- +-- -- Completion sources +-- "hrsh7th/cmp-nvim-lsp", +-- "hrsh7th/cmp-nvim-lsp-signature-help", +-- "hrsh7th/cmp-buffer", +-- "hrsh7th/cmp-path", +-- "saadparwaiz1/cmp_luasnip", +-- }, +-- config = function() +-- local cmp = require("cmp") +-- local luasnip = require("luasnip") +-- +-- cmp.setup({ +-- completion = { +-- -- See :help completeopt +-- completeopt = "menu,menuone,noinsert,preview", +-- }, +-- snippet = { +-- expand = function(args) +-- luasnip.lsp_expand(args.body) +-- end, +-- }, +-- mapping = cmp.mapping.preset.insert({ +-- ["<C-n>"] = cmp.mapping.select_next_item({ behavior = cmp.SelectBehavior.Insert }), +-- ["<C-p>"] = cmp.mapping.select_prev_item({ behavior = cmp.SelectBehavior.Insert }), +-- ["<C-b>"] = cmp.mapping.scroll_docs(-4), +-- ["<C-f>"] = cmp.mapping.scroll_docs(4), +-- +-- -- Ctrl+Space does not currently work in Neovim core on Windows +-- -- https://github.com/neovim/neovim/issues/8435 +-- -- ["<C-Space>"] = cmp.mapping.complete(), +-- ["<C-c>"] = cmp.mapping.complete(), +-- +-- ["<C-e>"] = cmp.mapping.abort(), +-- ["<C-y>"] = cmp.mapping.confirm({ +-- -- Accept currently selected item +-- behavior = cmp.ConfirmBehavior.Insert, +-- select = true, +-- }), +-- ["<C-S-y>"] = cmp.mapping.confirm({ +-- -- Accept currently selected item, replacing stuff as needed +-- behavior = cmp.ConfirmBehavior.Replace, +-- select = true, +-- }), +-- ["<CR>"] = cmp.mapping({ +-- -- https://github.com/hrsh7th/nvim-cmp/wiki/Example-mappings#safely-select-entries-with-cr +-- i = function(fallback) +-- -- In insert mode, only use Enter to complete something if cmp +-- -- is active and the user has explicitly selected an item +-- if cmp.visible() and cmp.get_active_entry() then +-- cmp.confirm({ behavior = cmp.ConfirmBehavior.Replace, select = false }) +-- else +-- fallback() +-- end +-- end, +-- s = cmp.mapping.confirm({ select = true }), +-- c = cmp.mapping.confirm({ behavior = cmp.ConfirmBehavior.Replace, select = true }), +-- }), +-- }), +-- sorting = { +-- priority_weight = 2, +-- comparators = { +-- cmp.config.compare.exact, +-- +-- -- Mostly default sort order from cmp +-- cmp.config.compare.offset, +-- -- cmp.config.compare.scopes, --this is commented in nvim-cmp too +-- cmp.config.compare.score, +-- cmp.config.compare.recently_used, +-- cmp.config.compare.locality, +-- cmp.config.compare.kind, +-- cmp.config.compare.sort_text, +-- cmp.config.compare.length, +-- cmp.config.compare.order, +-- }, +-- }, +-- sources = { +-- -- LSP results should be first priority +-- { name = "nvim_lsp", group_index = 1 }, +-- +-- { name = "nvim_lsp_signature_help", group_index = 2 }, +-- { name = "lazydev", group_index = 2 }, +-- { name = "luasnip", group_index = 2 }, +-- { name = "path", group_index = 2 }, +-- { name = "buffer", group_index = 2, keyword_length = 5 }, +-- }, +-- ---@diagnostic disable-next-line: missing-fields +-- formatting = { +-- format = require("lspkind").cmp_format({ +-- mode = "symbol_text", +-- maxwidth = function() +-- return math.floor(0.45 * vim.o.columns) +-- end, +-- ellipsis_char = "...", +-- show_labelDetails = true, +-- }), +-- }, +-- experimental = { +-- ghost_text = { +-- hl_group = "LspCodeLens", +-- }, +-- }, +-- window = { +-- completion = cmp.config.window.bordered(), +-- documentation = cmp.config.window.bordered(), +-- }, +-- }) +-- end, +-- }, +-- +-- -- LSP +-- { +-- "neovim/nvim-lspconfig", +-- cmd = { "LspInfo", "LspInstall", "LspStart" }, +-- event = { "BufReadPre", "BufNewFile" }, +-- dependencies = { +-- { "hrsh7th/cmp-nvim-lsp" }, +-- { "williamboman/mason.nvim" }, +-- { "williamboman/mason-lspconfig.nvim" }, +-- }, +-- config = function() +-- local lsp_zero = require("lsp-zero") +-- +-- lsp_zero.extend_lspconfig({ +-- sign_text = true, +-- capabilities = require("cmp_nvim_lsp").default_capabilities(), +-- }) +-- +-- local border = { +-- { "🭽", "FloatBorder" }, +-- { "▔", "FloatBorder" }, +-- { "🭾", "FloatBorder" }, +-- { "▕", "FloatBorder" }, +-- { "🭿", "FloatBorder" }, +-- { "▁", "FloatBorder" }, +-- { "🭼", "FloatBorder" }, +-- { "▏", "FloatBorder" }, +-- } +-- +-- local border_handlers = { +-- ["textDocument/hover"] = vim.lsp.buf.hover({ border = border }), +-- ["textDocument/signatureHelp"] = vim.lsp.buf.signature_help({ border = border }) +-- } +-- +-- require("mason-lspconfig").setup({ +-- automatic_enable = { "basedpyright", "ruff", "lua_ls" }, +-- handlers = { +-- -- this first function is the "default handler" +-- -- it applies to every language server without a "custom handler" +-- function(server_name) +-- require("lspconfig")[server_name].setup({ handlers = border_handlers }) +-- end, +-- +-- ["basedpyright"] = function() +-- local lspconfig = require("lspconfig") +-- lspconfig.basedpyright.setup({ +-- settings = { +-- basedpyright = { +-- typeCheckingMode = "standard", +-- }, +-- }, +-- }) +-- end, +-- }, +-- }) +-- vim.lsp.inlay_hint.enable() +-- end, +-- }, +-- +-- -- Formatting +-- { +-- "stevearc/conform.nvim", +-- config = function() +-- local conform = require("conform") +-- local prettier = { "prettierd", "prettier" } +-- conform.setup({ +-- formatters_by_ft = { +-- lua = { "stylua" }, +-- python = { "ruff_format", lsp_format = "fallback" }, +-- go = { "gopls" }, +-- rust = { "clippy", lsp_format = "fallback" }, +-- markdown = prettier, +-- }, +-- format_after_save = { +-- async = true, +-- stop_after_first = true, +-- lsp_format = "fallback", +-- }, +-- }) +-- +-- local function format() +-- conform.format({ async = true, lsp_fallback = true }) +-- end +-- +-- vim.keymap.set({ "n", "v" }, "<leader>rf", format, { desc = "Reformat" }) +-- vim.api.nvim_create_user_command("Format", format, {}) +-- end, +-- }, +-- +-- -- Lint +-- { +-- "mfussenegger/nvim-lint", +-- dependencies = { +-- -- Additional lua configuration, makes nvim stuff amazing! +-- "folke/neodev.nvim", +-- }, +-- event = { +-- "BufReadPre", +-- "BufNewFile", +-- }, +-- opts = { +-- autocmd = { +-- events = { "BufEnter", "BufWritePost" }, +-- pattern = { "*.py", "*.lua", "*.js", "*.ts", }, +-- linters_by_ft = { +-- python = { "mypy" }, +-- }, +-- }, +-- on_demand = { +-- linters_by_ft = { +-- python = { "mypy", "pylint" }, +-- }, +-- }, +-- }, +-- config = function(_, opts) +-- local lint = require("lint") +-- lint.linters_by_ft = { +-- javascript = { "eslint_d" }, +-- typescript = { "eslint_d" }, +-- } +-- +-- local function lint_autocmd() +-- local filetype = vim.bo.filetype +-- local linter_names = opts.autocmd.linters_by_ft[filetype] or {} +-- require("lint").try_lint(linter_names) +-- end +-- +-- local function lint_on_demand() +-- local filetype = vim.bo.filetype +-- local linter_names = opts.on_demand.linters_by_ft[filetype] or {} +-- require("lint").try_lint(linter_names) +-- end +-- +-- local lint_augroup = vim.api.nvim_create_augroup("user-nvim-lint", { clear = true }) +-- vim.api.nvim_create_autocmd(opts.autocmd.events, { +-- group = lint_augroup, +-- pattern = opts.autocmd.pattern, +-- callback = lint_autocmd, +-- }) +-- +-- vim.keymap.set("n", "<leader>cl", lint_on_demand, { desc = "[C]ode [l]int" }) +-- +-- -- Hate to remove this because I was pretty proud of it, but I'm removing +-- -- Pylint altogether. Since this is just my code, I'm leaving it here +-- -- as a reference if I want to mess with it again later. +-- -- -- I use Pylint consistently, and I have some projects that enforce +-- -- -- that Pylint must be passing. However, I don't always want to see +-- -- -- low-severity Pylint warnings like "missing docstring" for things +-- -- -- I'm still actively writing. They can be distracting. +-- -- -- +-- -- -- Build out a simple behavior that switches the Pylint arguments +-- -- -- to include or exclude Pylint's complexity (C) and conventions (R) +-- -- -- messages. +-- -- -- +-- -- -- I intentionally make this a global user command instead of a +-- -- -- buffer-specific one. +-- -- +-- -- local default_pylint_args = vim.deepcopy(lint.linters.pylint.args) +-- -- local simple_pylint_args = vim.deepcopy(lint.linters.pylint.args) +-- -- table.insert(simple_pylint_args, "--disable=C,R") +-- -- +-- -- local disable_pylint_low_severity = false +-- -- local function toggle_pylint_severity_mode() +-- -- disable_pylint_low_severity = not disable_pylint_low_severity +-- -- if disable_pylint_low_severity then +-- -- lint.linters.pylint.args = simple_pylint_args +-- -- print("Pylint mode changed to error/warning only") +-- -- else +-- -- lint.linters.pylint.args = default_pylint_args +-- -- print("Pylint mode reset to default") +-- -- end +-- -- -- Run the linter again to remove leftover messages or restore +-- -- -- newly added ones +-- -- lint.try_lint() +-- -- end +-- -- +-- -- vim.api.nvim_create_user_command("PylintSeverityToggle", toggle_pylint_severity_mode, {}) +-- end, +-- }, +-- +-- -- Code actions +-- { +-- "aznhe21/actions-preview.nvim", +-- config = function() +-- vim.keymap.set({ "v", "n" }, "<leader>ca", require("actions-preview").code_actions) +-- end, +-- }, +-- +-- -- Cool neovim dev stuff +-- { +-- "folke/lazydev.nvim", +-- ft = "lua", -- only load on lua files +-- opts = { +-- library = { +-- -- See the configuration section for more details +-- -- Load luvit types when the `vim.uv` word is found +-- { path = "luvit-meta/library", words = { "vim%.uv" } }, +-- }, +-- }, +-- }, +-- +-- { "Bilal2453/luvit-meta", lazy = true }, -- optional `vim.uv` typings +-- } +return { + + -- LSP + + { + "neovim/nvim-lspconfig" + }, + + { + "mason-org/mason.nvim", + opts = {} + }, + + { + "mason-org/mason-lspconfig.nvim", + dependencies = { + "neovim/nvim-lspconfig", + "mason-org/mason.nvim" + }, + opts = { + ensure_installed = { + "basedpyright", + "lua_ls", + "ruff", + "rust_analyzer" + } + } + }, + -- Cool neovim dev stuff + { + "folke/lazydev.nvim", + ft = "lua", -- only load on lua files + opts = { + library = { + -- See the configuration section for more details + -- Load luvit types when the `vim.uv` word is found + { path = "luvit-meta/library", words = { "vim%.uv" } }, + }, + }, + }, + + { "Bilal2453/luvit-meta", lazy = true }, -- optional `vim.uv` typings +} diff --git a/dot_config/nvim/lua/ibrahim/plugins/mini.lua b/dot_config/nvim/lua/ibrahim/plugins/mini.lua new file mode 100644 index 0000000..dd1247f --- /dev/null +++ b/dot_config/nvim/lua/ibrahim/plugins/mini.lua @@ -0,0 +1,8 @@ +return { + 'echasnovski/mini.nvim', + version = false, + config = function(_, opts) + -- Commenter + require("mini.comment").setup(opts) + end, +} diff --git a/dot_config/nvim/lua/plugins/neotest.lua b/dot_config/nvim/lua/ibrahim/plugins/neotest.lua index 68e7bc3..68e7bc3 100644 --- a/dot_config/nvim/lua/plugins/neotest.lua +++ b/dot_config/nvim/lua/ibrahim/plugins/neotest.lua diff --git a/dot_config/nvim/lua/ibrahim/plugins/nvim-cmp.lua b/dot_config/nvim/lua/ibrahim/plugins/nvim-cmp.lua new file mode 100644 index 0000000..151e67b --- /dev/null +++ b/dot_config/nvim/lua/ibrahim/plugins/nvim-cmp.lua @@ -0,0 +1,119 @@ +return { + "hrsh7th/nvim-cmp", + version = false, -- last release is way too old + event = { "InsertEnter", "CmdlineEnter" }, + dependencies = { + "L3MON4D3/LuaSnip", -- Snippet engine + "rafamadriz/friendly-snippets", -- Useful snippets in VSCode snippet format + "onsails/lspkind.nvim", -- Pretty formatting in the completion menu + + -- Completion sources + "hrsh7th/cmp-nvim-lsp", + "hrsh7th/cmp-nvim-lsp-signature-help", + "hrsh7th/cmp-buffer", + "hrsh7th/cmp-path", + "saadparwaiz1/cmp_luasnip", + }, + config = function() + local cmp = require("cmp") + local luasnip = require("luasnip") + + -- Load any VSCode-style snippets from other installed plugins + require("luasnip.loaders.from_vscode").lazy_load() + + cmp.setup({ + completion = { + -- See :help completeopt + completeopt = "menu,menuone,noinsert,preview", + }, + snippet = { + expand = function(args) + luasnip.lsp_expand(args.body) + end, + }, + mapping = cmp.mapping.preset.insert({ + ["<C-n>"] = cmp.mapping.select_next_item({ behavior = cmp.SelectBehavior.Insert }), + ["<C-p>"] = cmp.mapping.select_prev_item({ behavior = cmp.SelectBehavior.Insert }), + ["<C-b>"] = cmp.mapping.scroll_docs(-4), + ["<C-f>"] = cmp.mapping.scroll_docs(4), + + -- Ctrl+Space does not currently work in Neovim core on Windows + -- https://github.com/neovim/neovim/issues/8435 + -- ["<C-Space>"] = cmp.mapping.complete(), + ["<C-c>"] = cmp.mapping.complete(), + + ["<C-e>"] = cmp.mapping.abort(), + ["<C-y>"] = cmp.mapping.confirm({ + -- Accept currently selected item + behavior = cmp.ConfirmBehavior.Insert, + select = true, + }), + ["<C-S-y>"] = cmp.mapping.confirm({ + -- Accept currently selected item, replacing stuff as needed + behavior = cmp.ConfirmBehavior.Replace, + select = true, + }), + ["<CR>"] = cmp.mapping({ + -- https://github.com/hrsh7th/nvim-cmp/wiki/Example-mappings#safely-select-entries-with-cr + i = function(fallback) + -- In insert mode, only use Enter to complete something if cmp + -- is active and the user has explicitly selected an item + if cmp.visible() and cmp.get_active_entry() then + cmp.confirm({ behavior = cmp.ConfirmBehavior.Replace, select = false }) + else + fallback() + end + end, + s = cmp.mapping.confirm({ select = true }), + c = cmp.mapping.confirm({ behavior = cmp.ConfirmBehavior.Replace, select = true }), + }), + }), + sorting = { + priority_weight = 2, + comparators = { + cmp.config.compare.exact, + + -- Mostly default sort order from cmp + cmp.config.compare.offset, + -- cmp.config.compare.scopes, --this is commented in nvim-cmp too + cmp.config.compare.score, + cmp.config.compare.recently_used, + cmp.config.compare.locality, + cmp.config.compare.kind, + cmp.config.compare.sort_text, + cmp.config.compare.length, + cmp.config.compare.order, + }, + }, + sources = { + -- LSP results should be first priority + { name = "nvim_lsp", group_index = 1 }, + + { name = "nvim_lsp_signature_help", group_index = 2 }, + { name = "luasnip", group_index = 2 }, + { name = "path", group_index = 2 }, + { name = "buffer", group_index = 2, keyword_length = 5 }, + }, + formatting = { + format = require("lspkind").cmp_format({ + mode = "symbol_text", + -- maxwidth = 50, + maxwidth = function() + return math.floor(0.45 * vim.o.columns) + end, + ellipsis_char = "...", + show_labelDetails = true, + }), + }, + experimental = { + ghost_text = { + hl_group = "LspCodeLens", + }, + }, + window = { + completion = cmp.config.window.bordered(), + documentation = cmp.config.window.bordered(), + }, + }) + end, +} diff --git a/dot_config/nvim/lua/ibrahim/plugins/nvim-colorizer.lua b/dot_config/nvim/lua/ibrahim/plugins/nvim-colorizer.lua new file mode 100644 index 0000000..465d0a9 --- /dev/null +++ b/dot_config/nvim/lua/ibrahim/plugins/nvim-colorizer.lua @@ -0,0 +1,6 @@ +return { + 'norcalli/nvim-colorizer.lua', + config = function() + require 'colorizer'.setup() + end, +} diff --git a/dot_config/nvim/lua/plugins/obsidian.lua.tmpl b/dot_config/nvim/lua/ibrahim/plugins/obsidian.lua.tmpl index 24982a6..24982a6 100644 --- a/dot_config/nvim/lua/plugins/obsidian.lua.tmpl +++ b/dot_config/nvim/lua/ibrahim/plugins/obsidian.lua.tmpl diff --git a/dot_config/nvim/lua/plugins/oil.lua b/dot_config/nvim/lua/ibrahim/plugins/oil.lua index ac41c0a..ac41c0a 100644 --- a/dot_config/nvim/lua/plugins/oil.lua +++ b/dot_config/nvim/lua/ibrahim/plugins/oil.lua diff --git a/dot_config/nvim/lua/plugins/telescope.lua b/dot_config/nvim/lua/ibrahim/plugins/telescope.lua index 89efb5c..89efb5c 100644 --- a/dot_config/nvim/lua/plugins/telescope.lua +++ b/dot_config/nvim/lua/ibrahim/plugins/telescope.lua diff --git a/dot_config/nvim/lua/plugins/todo-comments.lua b/dot_config/nvim/lua/ibrahim/plugins/todo-comments.lua index b47cb51..b47cb51 100644 --- a/dot_config/nvim/lua/plugins/todo-comments.lua +++ b/dot_config/nvim/lua/ibrahim/plugins/todo-comments.lua diff --git a/dot_config/nvim/lua/plugins/treesitter.lua b/dot_config/nvim/lua/ibrahim/plugins/treesitter.lua index aade475..aade475 100644 --- a/dot_config/nvim/lua/plugins/treesitter.lua +++ b/dot_config/nvim/lua/ibrahim/plugins/treesitter.lua diff --git a/dot_config/nvim/lua/plugins/undotree.lua b/dot_config/nvim/lua/ibrahim/plugins/undotree.lua index 3465446..3465446 100644 --- a/dot_config/nvim/lua/plugins/undotree.lua +++ b/dot_config/nvim/lua/ibrahim/plugins/undotree.lua diff --git a/dot_config/nvim/lua/plugins/which-key.lua b/dot_config/nvim/lua/ibrahim/plugins/which-key.lua index 7410159..7410159 100644 --- a/dot_config/nvim/lua/plugins/which-key.lua +++ b/dot_config/nvim/lua/ibrahim/plugins/which-key.lua diff --git a/dot_config/nvim/lua/plugins/lsp.lua b/dot_config/nvim/lua/plugins/lsp.lua deleted file mode 100644 index f74243e..0000000 --- a/dot_config/nvim/lua/plugins/lsp.lua +++ /dev/null @@ -1,334 +0,0 @@ -return { - { - "VonHeikemen/lsp-zero.nvim", - branch = "v4.x", - lazy = true, - config = false, - }, - - { - "williamboman/mason.nvim", - lazy = false, - config = true, - }, - - -- Autocompletion - { - "hrsh7th/nvim-cmp", - event = { "InsertEnter", "CmdlineEnter" }, - dependencies = { - "L3MON4D3/LuaSnip", -- Snippet engine - "onsails/lspkind.nvim", -- Pretty formatting in the completion menu - - -- Completion sources - "hrsh7th/cmp-nvim-lsp", - "hrsh7th/cmp-nvim-lsp-signature-help", - "hrsh7th/cmp-buffer", - "hrsh7th/cmp-path", - "saadparwaiz1/cmp_luasnip", - }, - config = function() - local cmp = require("cmp") - local luasnip = require("luasnip") - - cmp.setup({ - completion = { - -- See :help completeopt - completeopt = "menu,menuone,noinsert,preview", - }, - snippet = { - expand = function(args) - luasnip.lsp_expand(args.body) - end, - }, - mapping = cmp.mapping.preset.insert({ - ["<C-n>"] = cmp.mapping.select_next_item({ behavior = cmp.SelectBehavior.Insert }), - ["<C-p>"] = cmp.mapping.select_prev_item({ behavior = cmp.SelectBehavior.Insert }), - ["<C-b>"] = cmp.mapping.scroll_docs(-4), - ["<C-f>"] = cmp.mapping.scroll_docs(4), - - -- Ctrl+Space does not currently work in Neovim core on Windows - -- https://github.com/neovim/neovim/issues/8435 - -- ["<C-Space>"] = cmp.mapping.complete(), - ["<C-c>"] = cmp.mapping.complete(), - - ["<C-e>"] = cmp.mapping.abort(), - ["<C-y>"] = cmp.mapping.confirm({ - -- Accept currently selected item - behavior = cmp.ConfirmBehavior.Insert, - select = true, - }), - ["<C-S-y>"] = cmp.mapping.confirm({ - -- Accept currently selected item, replacing stuff as needed - behavior = cmp.ConfirmBehavior.Replace, - select = true, - }), - ["<CR>"] = cmp.mapping({ - -- https://github.com/hrsh7th/nvim-cmp/wiki/Example-mappings#safely-select-entries-with-cr - i = function(fallback) - -- In insert mode, only use Enter to complete something if cmp - -- is active and the user has explicitly selected an item - if cmp.visible() and cmp.get_active_entry() then - cmp.confirm({ behavior = cmp.ConfirmBehavior.Replace, select = false }) - else - fallback() - end - end, - s = cmp.mapping.confirm({ select = true }), - c = cmp.mapping.confirm({ behavior = cmp.ConfirmBehavior.Replace, select = true }), - }), - }), - sorting = { - priority_weight = 2, - comparators = { - cmp.config.compare.exact, - - -- Mostly default sort order from cmp - cmp.config.compare.offset, - -- cmp.config.compare.scopes, --this is commented in nvim-cmp too - cmp.config.compare.score, - cmp.config.compare.recently_used, - cmp.config.compare.locality, - cmp.config.compare.kind, - cmp.config.compare.sort_text, - cmp.config.compare.length, - cmp.config.compare.order, - }, - }, - sources = { - -- LSP results should be first priority - { name = "nvim_lsp", group_index = 1 }, - - { name = "nvim_lsp_signature_help", group_index = 2 }, - { name = "lazydev", group_index = 2 }, - { name = "luasnip", group_index = 2 }, - { name = "path", group_index = 2 }, - { name = "buffer", group_index = 2, keyword_length = 5 }, - }, - ---@diagnostic disable-next-line: missing-fields - formatting = { - format = require("lspkind").cmp_format({ - mode = "symbol_text", - maxwidth = function() - return math.floor(0.45 * vim.o.columns) - end, - ellipsis_char = "...", - show_labelDetails = true, - }), - }, - experimental = { - ghost_text = { - hl_group = "LspCodeLens", - }, - }, - window = { - completion = cmp.config.window.bordered(), - documentation = cmp.config.window.bordered(), - }, - }) - end, - }, - - -- LSP - { - "neovim/nvim-lspconfig", - cmd = { "LspInfo", "LspInstall", "LspStart" }, - event = { "BufReadPre", "BufNewFile" }, - dependencies = { - { "hrsh7th/cmp-nvim-lsp" }, - { "williamboman/mason.nvim" }, - { "williamboman/mason-lspconfig.nvim" }, - }, - config = function() - local lsp_zero = require("lsp-zero") - - lsp_zero.extend_lspconfig({ - sign_text = true, - capabilities = require("cmp_nvim_lsp").default_capabilities(), - }) - - local border = { - { "🭽", "FloatBorder" }, - { "▔", "FloatBorder" }, - { "🭾", "FloatBorder" }, - { "▕", "FloatBorder" }, - { "🭿", "FloatBorder" }, - { "▁", "FloatBorder" }, - { "🭼", "FloatBorder" }, - { "▏", "FloatBorder" }, - } - - local border_handlers = { - ["textDocument/hover"] = vim.lsp.buf.hover({ border = border }), - ["textDocument/signatureHelp"] = vim.lsp.buf.signature_help({ border = border }) - } - - require("mason-lspconfig").setup({ - automatic_enable = { "basedpyright", "ruff", "lua_ls" }, - handlers = { - -- this first function is the "default handler" - -- it applies to every language server without a "custom handler" - function(server_name) - require("lspconfig")[server_name].setup({ handlers = border_handlers }) - end, - - ["basedpyright"] = function() - local lspconfig = require("lspconfig") - lspconfig.basedpyright.setup({ - settings = { - basedpyright = { - typeCheckingMode = "standard", - }, - }, - }) - end, - }, - }) - vim.lsp.inlay_hint.enable() - end, - }, - - -- Formatting - { - "stevearc/conform.nvim", - config = function() - local conform = require("conform") - local prettier = { "prettierd", "prettier" } - conform.setup({ - formatters_by_ft = { - lua = { "stylua" }, - python = { "ruff_format", lsp_format = "fallback" }, - go = { "gopls" }, - rust = { "clippy", lsp_format = "fallback" }, - markdown = prettier, - }, - format_after_save = { - async = true, - stop_after_first = true, - lsp_format = "fallback", - }, - }) - - local function format() - conform.format({ async = true, lsp_fallback = true }) - end - - vim.keymap.set({ "n", "v" }, "<leader>rf", format, { desc = "Reformat" }) - vim.api.nvim_create_user_command("Format", format, {}) - end, - }, - - -- Lint - { - "mfussenegger/nvim-lint", - dependencies = { - -- Additional lua configuration, makes nvim stuff amazing! - "folke/neodev.nvim", - }, - event = { - "BufReadPre", - "BufNewFile", - }, - opts = { - autocmd = { - events = { "BufEnter", "BufWritePost" }, - pattern = { "*.py", "*.lua", "*.js", "*.ts", }, - linters_by_ft = { - python = { "mypy" }, - }, - }, - on_demand = { - linters_by_ft = { - python = { "mypy", "pylint" }, - }, - }, - }, - config = function(_, opts) - local lint = require("lint") - lint.linters_by_ft = { - javascript = { "eslint_d" }, - typescript = { "eslint_d" }, - } - - local function lint_autocmd() - local filetype = vim.bo.filetype - local linter_names = opts.autocmd.linters_by_ft[filetype] or {} - require("lint").try_lint(linter_names) - end - - local function lint_on_demand() - local filetype = vim.bo.filetype - local linter_names = opts.on_demand.linters_by_ft[filetype] or {} - require("lint").try_lint(linter_names) - end - - local lint_augroup = vim.api.nvim_create_augroup("user-nvim-lint", { clear = true }) - vim.api.nvim_create_autocmd(opts.autocmd.events, { - group = lint_augroup, - pattern = opts.autocmd.pattern, - callback = lint_autocmd, - }) - - vim.keymap.set("n", "<leader>cl", lint_on_demand, { desc = "[C]ode [l]int" }) - - -- Hate to remove this because I was pretty proud of it, but I'm removing - -- Pylint altogether. Since this is just my code, I'm leaving it here - -- as a reference if I want to mess with it again later. - -- -- I use Pylint consistently, and I have some projects that enforce - -- -- that Pylint must be passing. However, I don't always want to see - -- -- low-severity Pylint warnings like "missing docstring" for things - -- -- I'm still actively writing. They can be distracting. - -- -- - -- -- Build out a simple behavior that switches the Pylint arguments - -- -- to include or exclude Pylint's complexity (C) and conventions (R) - -- -- messages. - -- -- - -- -- I intentionally make this a global user command instead of a - -- -- buffer-specific one. - -- - -- local default_pylint_args = vim.deepcopy(lint.linters.pylint.args) - -- local simple_pylint_args = vim.deepcopy(lint.linters.pylint.args) - -- table.insert(simple_pylint_args, "--disable=C,R") - -- - -- local disable_pylint_low_severity = false - -- local function toggle_pylint_severity_mode() - -- disable_pylint_low_severity = not disable_pylint_low_severity - -- if disable_pylint_low_severity then - -- lint.linters.pylint.args = simple_pylint_args - -- print("Pylint mode changed to error/warning only") - -- else - -- lint.linters.pylint.args = default_pylint_args - -- print("Pylint mode reset to default") - -- end - -- -- Run the linter again to remove leftover messages or restore - -- -- newly added ones - -- lint.try_lint() - -- end - -- - -- vim.api.nvim_create_user_command("PylintSeverityToggle", toggle_pylint_severity_mode, {}) - end, - }, - - -- Code actions - { - "aznhe21/actions-preview.nvim", - config = function() - vim.keymap.set({ "v", "n" }, "<leader>ca", require("actions-preview").code_actions) - end, - }, - - -- Cool neovim dev stuff - { - "folke/lazydev.nvim", - ft = "lua", -- only load on lua files - opts = { - library = { - -- See the configuration section for more details - -- Load luvit types when the `vim.uv` word is found - { path = "luvit-meta/library", words = { "vim%.uv" } }, - }, - }, - }, - - { "Bilal2453/luvit-meta", lazy = true }, -- optional `vim.uv` typings -} |
