From 7876fabd7c5c625194ee723972e63105eca4b505 Mon Sep 17 00:00:00 2001 From: Ibrahim Muftee Date: Thu, 3 Oct 2024 17:54:22 -0500 Subject: feat(nvim): neovim config rewrite --- dot_config/nvim/after/ftplugin/python.lua | 4 - dot_config/nvim/init.lua | 25 +-- dot_config/nvim/lazy-lock.json | 38 ++++ dot_config/nvim/lua/config/lazy.lua | 38 ++++ dot_config/nvim/lua/ibrahim/icons.lua | 62 ------ dot_config/nvim/lua/ibrahim/keys.lua | 124 ------------ dot_config/nvim/lua/ibrahim/set.lua.tmpl | 87 --------- dot_config/nvim/lua/plugins/actions-preview.lua | 6 - dot_config/nvim/lua/plugins/commenter.lua | 11 -- dot_config/nvim/lua/plugins/conform.lua | 48 ----- dot_config/nvim/lua/plugins/fugitive.lua | 6 - dot_config/nvim/lua/plugins/gitsigns.lua | 36 ++-- dot_config/nvim/lua/plugins/gruvbox.lua | 35 +--- dot_config/nvim/lua/plugins/harpoon.lua | 41 ++-- dot_config/nvim/lua/plugins/jinja.lua | 2 +- dot_config/nvim/lua/plugins/lsp-lines.lua | 70 +++---- dot_config/nvim/lua/plugins/lsp-zero.lua | 173 ----------------- dot_config/nvim/lua/plugins/lsp.lua | 237 ++++++++++++++++++++++ dot_config/nvim/lua/plugins/mini.lua | 8 - dot_config/nvim/lua/plugins/neotest.lua | 78 ++++---- dot_config/nvim/lua/plugins/nvim-cmp.lua | 119 ------------ dot_config/nvim/lua/plugins/nvim-colorizer.lua | 6 - dot_config/nvim/lua/plugins/oil.lua | 17 +- dot_config/nvim/lua/plugins/todo-comments.lua | 7 +- dot_config/nvim/lua/plugins/treesitter.lua | 248 +++++++++++------------- dot_config/nvim/lua/plugins/undotree.lua | 12 +- dot_config/nvim/lua/plugins/which-key.lua | 41 +--- dot_config/nvim/plugin/keymaps.lua | 139 +++++++++++++ dot_config/nvim/plugin/options.lua | 35 ++++ 29 files changed, 750 insertions(+), 1003 deletions(-) delete mode 100644 dot_config/nvim/after/ftplugin/python.lua create mode 100644 dot_config/nvim/lazy-lock.json create mode 100644 dot_config/nvim/lua/config/lazy.lua delete mode 100644 dot_config/nvim/lua/ibrahim/icons.lua delete mode 100644 dot_config/nvim/lua/ibrahim/keys.lua delete mode 100644 dot_config/nvim/lua/ibrahim/set.lua.tmpl delete mode 100644 dot_config/nvim/lua/plugins/actions-preview.lua delete mode 100644 dot_config/nvim/lua/plugins/commenter.lua delete mode 100644 dot_config/nvim/lua/plugins/conform.lua delete mode 100644 dot_config/nvim/lua/plugins/fugitive.lua delete mode 100644 dot_config/nvim/lua/plugins/lsp-zero.lua create mode 100644 dot_config/nvim/lua/plugins/lsp.lua delete mode 100644 dot_config/nvim/lua/plugins/mini.lua delete mode 100644 dot_config/nvim/lua/plugins/nvim-cmp.lua delete mode 100644 dot_config/nvim/lua/plugins/nvim-colorizer.lua create mode 100644 dot_config/nvim/plugin/keymaps.lua create mode 100644 dot_config/nvim/plugin/options.lua (limited to 'dot_config/nvim') diff --git a/dot_config/nvim/after/ftplugin/python.lua b/dot_config/nvim/after/ftplugin/python.lua deleted file mode 100644 index b06591a..0000000 --- a/dot_config/nvim/after/ftplugin/python.lua +++ /dev/null @@ -1,4 +0,0 @@ --- Colored columns at 72 and 88 are for line lengths, and are based on --- Python conventions. Docstrings in Python should terminate at 72 --- characters, and 88 is the max line length for the Black formatter. -vim.opt_local.colorcolumn = { 72, 88 } diff --git a/dot_config/nvim/init.lua b/dot_config/nvim/init.lua index 005fad5..55b8979 100644 --- a/dot_config/nvim/init.lua +++ b/dot_config/nvim/init.lua @@ -1,24 +1 @@ --- Setting the leader key just in case -vim.g.mapleader = " " -vim.g.maplocalleader = " " - --- Sourcing regular nvim settings/keybindings -require("ibrahim.set") -require("ibrahim.keys") - --- Bootstrap Lazy plugin manager -local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim" -if not vim.loop.fs_stat(lazypath) then - vim.fn.system({ - "git", - "clone", - "--filter=blob:none", - "https://github.com/folke/lazy.nvim.git", - "--branch=stable", -- latest stable release - lazypath, - }) -end -vim.opt.rtp:prepend(lazypath) - -require("lazy").setup("plugins") - +require("config.lazy") diff --git a/dot_config/nvim/lazy-lock.json b/dot_config/nvim/lazy-lock.json new file mode 100644 index 0000000..b53624c --- /dev/null +++ b/dot_config/nvim/lazy-lock.json @@ -0,0 +1,38 @@ +{ + "FixCursorHold.nvim": { "branch": "master", "commit": "1900f89dc17c603eec29960f57c00bd9ae696495" }, + "LuaSnip": { "branch": "master", "commit": "e808bee352d1a6fcf902ca1a71cee76e60e24071" }, + "actions-preview.nvim": { "branch": "master", "commit": "9f52a01c374318e91337697ebed51c6fae57f8a4" }, + "cmp-buffer": { "branch": "main", "commit": "3022dbc9166796b644a841a02de8dd1cc1d311fa" }, + "cmp-nvim-lsp": { "branch": "main", "commit": "39e2eda76828d88b773cc27a3f61d2ad782c922d" }, + "cmp-nvim-lsp-signature-help": { "branch": "main", "commit": "031e6ba70b0ad5eee49fd2120ff7a2e325b17fa7" }, + "cmp-path": { "branch": "main", "commit": "91ff86cd9c29299a64f968ebb45846c485725f23" }, + "cmp_luasnip": { "branch": "master", "commit": "05a9ab28b53f71d1aece421ef32fee2cb857a843" }, + "conform.nvim": { "branch": "master", "commit": "1a99fdc1d3aa9ccdf3021e67982a679a8c5c740c" }, + "gitsigns.nvim": { "branch": "main", "commit": "863903631e676b33e8be2acb17512fdc1b80b4fb" }, + "gruvbox.nvim": { "branch": "main", "commit": "49d9c0b150ba70efcd831ec7b3cb8ee740067045" }, + "harpoon": { "branch": "harpoon2", "commit": "0378a6c428a0bed6a2781d459d7943843f374bce" }, + "lazy.nvim": { "branch": "main", "commit": "1159bdccd8910a0fd0914b24d6c3d186689023d9" }, + "lazydev.nvim": { "branch": "main", "commit": "491452cf1ca6f029e90ad0d0368848fac717c6d2" }, + "lsp-zero.nvim": { "branch": "v4.x", "commit": "b8411704591ae8e1501f1b9b31c801c09927baac" }, + "lsp_lines.nvim": { "branch": "main", "commit": "7d9e2748b61bff6ebba6e30adbc7173ccf21c055" }, + "lspkind.nvim": { "branch": "master", "commit": "59c3f419af48a2ffb2320cea85e44e5a95f71664" }, + "luvit-meta": { "branch": "main", "commit": "ce76f6f6cdc9201523a5875a4471dcfe0186eb60" }, + "mason-lspconfig.nvim": { "branch": "main", "commit": "25c11854aa25558ee6c03432edfa0df0217324be" }, + "mason.nvim": { "branch": "main", "commit": "e2f7f9044ec30067bc11800a9e266664b88cda22" }, + "neotest": { "branch": "master", "commit": "6d3d22cdad49999ef774ebe1bc250a4994038964" }, + "neotest-python": { "branch": "master", "commit": "a2861ab3c9a0bf75a56b11835c2bfc8270f5be7e" }, + "nvim-cmp": { "branch": "main", "commit": "ae644feb7b67bf1ce4260c231d1d4300b19c6f30" }, + "nvim-lspconfig": { "branch": "master", "commit": "fb453a1a443b6ea6b54a1e4c101b1160c9d37950" }, + "nvim-nio": { "branch": "master", "commit": "a428f309119086dc78dd4b19306d2d67be884eee" }, + "nvim-treesitter": { "branch": "master", "commit": "cc2c11c403a9143827501223b4ee64432dcaf246" }, + "nvim-treesitter-textobjects": { "branch": "master", "commit": "4a2d05ec24eaa6b655c7d19092a3b6c0219d46b9" }, + "nvim-web-devicons": { "branch": "master", "commit": "6b53401918a9033a41159d012160c5fb5eb249ae" }, + "obsidian.nvim": { "branch": "main", "commit": "ae1f76a75c7ce36866e1d9342a8f6f5b9c2caf9b" }, + "oil.nvim": { "branch": "master", "commit": "9e6fb844fe4cce13d9e3f6a7c970cbc669bb1629" }, + "plenary.nvim": { "branch": "master", "commit": "2d9b06177a975543726ce5c73fca176cedbffe9d" }, + "telescope.nvim": { "branch": "0.1.x", "commit": "a0bbec21143c7bc5f8bb02e0005fa0b982edc026" }, + "todo-comments.nvim": { "branch": "main", "commit": "ae0a2afb47cf7395dc400e5dc4e05274bf4fb9e0" }, + "undotree": { "branch": "main", "commit": "eab459ab87dd249617b5f7187bb69e614a083047" }, + "vim-jinja": { "branch": "master", "commit": "7c54e2320c5f676636cdd8697480782eebfb2bf2" }, + "which-key.nvim": { "branch": "main", "commit": "8badb359f7ab8711e2575ef75dfe6fbbd87e4821" } +} diff --git a/dot_config/nvim/lua/config/lazy.lua b/dot_config/nvim/lua/config/lazy.lua new file mode 100644 index 0000000..ce16483 --- /dev/null +++ b/dot_config/nvim/lua/config/lazy.lua @@ -0,0 +1,38 @@ +-- Bootstrap lazy.nvim +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) + +-- 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 = " " + +-- Setup lazy.nvim +require("lazy").setup({ + spec = { + -- import your plugins + { import = "plugins" }, + }, + -- Configure any other settings here. See the documentation for more details. + -- colorscheme that will be used when installing plugins. + install = { colorscheme = { "gruvbox" } }, + -- automatically check for plugin updates + checker = { enabled = true }, + change_detection = { + notify = false, + } +}) diff --git a/dot_config/nvim/lua/ibrahim/icons.lua b/dot_config/nvim/lua/ibrahim/icons.lua deleted file mode 100644 index d6573ab..0000000 --- a/dot_config/nvim/lua/ibrahim/icons.lua +++ /dev/null @@ -1,62 +0,0 @@ -return { - diagnostics = { - -- Error = " ", - -- Warn = " ", - -- Hint = " ", - -- Info = " ", - Error = " ", - Warn = " ", - -- Hint = " ", - Hint = "󰌵 ", - Info = " ", - }, - git = { - -- Change type - added = " ", - -- added = "✚" - modified = " ", - -- modified = "" - removed = " ", - deleted = "󱂑", - renamed = "󰑕", - -- Status type - untracked = "", - ignored = "", - unstaged = "", - staged = "", - conflict = "", - }, - gitsigns = { - -- Signs that will appear in the statusline column - added = "✚", - modified = "", - deleted = "", - }, - lsp = { - Text = "", - Method = "", - Function = "󰡱", - Constructor = "", - Field = "", - Variable = "󰫧", - Class = "", - Interface = "", - Module = "", - Property = "", - Unit = "", - Value = "", - Enum = "", - Keyword = "", - Snippet = "", - Color = "", - File = "", - Reference = "", - Folder = "", - EnumMember = "", - Constant = "", - Struct = "", - Event = "", - Operator = "", - TypeParameter = "", - }, -} diff --git a/dot_config/nvim/lua/ibrahim/keys.lua b/dot_config/nvim/lua/ibrahim/keys.lua deleted file mode 100644 index 9fa423f..0000000 --- a/dot_config/nvim/lua/ibrahim/keys.lua +++ /dev/null @@ -1,124 +0,0 @@ --- 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" }, "", "noh", { desc = "Escape and clear hlsearch" }) - --- Move lines while in visual mode with J and K -map("v", "J", ":m '>+1gv=gv") -map("v", "K", ":m '<-2gv=gv") - --- 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", "", "zz") -map("n", "", "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", "p", '"_dP') -map({ "n", "v" }, "d", '"_dP') - --- Easier quickfix naviagion -map("n", "", "cprev", { desc = "Quickfix previous item" }) -map("n", "", "cnext", { desc = "Quickfix next item" }) - --- System clipboard -map({ "n", "v" }, "cd", '"+d', { desc = "Clipboard delete" }) -map({ "n", "v" }, "cp", '"+p', { desc = "Clipboard paste" }) -map({ "n", "v" }, "cy", '"+y', { desc = "Clipboard yank" }) - --- Map g- to netrw (temporary placeholder for oil) --- map("n", "g-", vim.cmd.Ex, { desc = "Open netrw" }) - --- 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", - "sn", - tele_builtin("lsp_document_symbols"), - vim.lsp.buf.document_symbol, - "Search document symbols" - ) - lsp_telescope_map( - "n", - "sN", - tele_builtin("lsp_dynamic_workspace_symbols"), - vim.lsp.buf.workspace_symbol, - "Search workspace symbols" - ) - - -- Code changes - lsp_map("n", "cr", vim.lsp.buf.rename, "Rename") - -- ca is being overwritten by the 'actions-preview' plugin - -- lsp_map("n", "ca", vim.lsp.buf.code_action, "Code actions") - - -- Diagnostics - lsp_map("n", "ds", vim.diagnostic.open_float, "[s]how [d]iagnostic window") - lsp_map("n", "dn", function() - vim.diagnostic.goto_next({ float = true }) - end, "Go to [n]ext [d]iagnostic") - lsp_map("n", "dp", function() - vim.diagnostic.goto_prev({ float = true }) - end, "Go to [p]revious [d]iagnostic") - - -- See `:help K` for why this keymap - lsp_map("n", "K", vim.lsp.buf.hover, "Hover Documentation") - lsp_map("n", "", vim.lsp.buf.signature_help, "Signature Documentation") - - -- Workspace - lsp_map("n", "wa", vim.lsp.buf.add_workspace_folder, "[W]orkspace [A]dd Folder") - lsp_map("n", "wr", vim.lsp.buf.remove_workspace_folder, "[W]orkspace [R]emove Folder") - lsp_map("n", "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/ibrahim/set.lua.tmpl b/dot_config/nvim/lua/ibrahim/set.lua.tmpl deleted file mode 100644 index 019fa4f..0000000 --- a/dot_config/nvim/lua/ibrahim/set.lua.tmpl +++ /dev/null @@ -1,87 +0,0 @@ --- vim:ft=lua ----@diagnostic disable: undefined-global - -local opt = vim.opt - --- Set default shell -{{- if eq .chezmoi.os "windows" }} -opt.shell = "pwsh" -{{ else }} -opt.shell = "zsh" -{{ end }} - --- Begin searching as I type a search string instead of waiting for me to press Enter -opt.incsearch = true - --- Make line numbers default -opt.number = true -opt.relativenumber = true - --- Highlight only the line number for the current line. --- Disable the second line here to highlight the entire line where the --- cursor is. -opt.cursorline = true -opt.cursorlineopt = "number" - --- Try to keep this many lines visible above and below the cursor. --- This makes the window scroll sooner if mashing j / k. -opt.scrolloff = 8 - --- Folds -vim.o.foldtext = '' - --- Don't fold absolutely everything when opening a new file -opt.foldlevelstart = 1 - --- Enable mouse mode -opt.mouse = "a" - --- Set the conceal level (mainly for obsidian md formatting) -opt.conceallevel = 2 - --- Tab settings -opt.tabstop = 4 -opt.softtabstop = 4 -opt.shiftwidth = 0 -opt.expandtab = true - --- Automatically set the same indent level on a new line -opt.autoindent = true - --- Increase or decrease indent based on braces or language keywords -opt.smartindent = true - --- Enable break indent -opt.breakindent = true - --- Don't make local backup files. Instead, write undo history to disk. --- This works especially well with the undotree plugin. -opt.swapfile = false -opt.backup = false -opt.undodir = vim.fn.expand("~/.vim/undodir") -opt.undofile = true - --- Case insensitive searching UNLESS /C or capital in search -opt.ignorecase = true -opt.smartcase = true - --- Decrease update time -opt.updatetime = 250 - --- Enable signcolumn (used for diagnostics and gitsigns) -opt.signcolumn = "yes" - --- Column at line 80 -opt.colorcolumn = "80" - --- Set completeopt to have a better completion experience -opt.completeopt = "menuone,noselect" - --- Highlight when yanking text -vim.api.nvim_create_autocmd('TextYankPost', { - desc = 'Highlight when yanking text', - group = vim.api.nvim_create_augroup('IbrahimHighlightYank', { clear = true }), - callback = function() - vim.highlight.on_yank() - end, -}) diff --git a/dot_config/nvim/lua/plugins/actions-preview.lua b/dot_config/nvim/lua/plugins/actions-preview.lua deleted file mode 100644 index 05532c4..0000000 --- a/dot_config/nvim/lua/plugins/actions-preview.lua +++ /dev/null @@ -1,6 +0,0 @@ -return { - "aznhe21/actions-preview.nvim", - config = function() - vim.keymap.set({ "v", "n" }, "ca", require("actions-preview").code_actions) - end, -} diff --git a/dot_config/nvim/lua/plugins/commenter.lua b/dot_config/nvim/lua/plugins/commenter.lua deleted file mode 100644 index cdc88fe..0000000 --- a/dot_config/nvim/lua/plugins/commenter.lua +++ /dev/null @@ -1,11 +0,0 @@ -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/plugins/conform.lua b/dot_config/nvim/lua/plugins/conform.lua deleted file mode 100644 index c1b38ab..0000000 --- a/dot_config/nvim/lua/plugins/conform.lua +++ /dev/null @@ -1,48 +0,0 @@ --- 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" }, "rf", format, { desc = "Reformat" }) - vim.api.nvim_create_user_command("Format", format, {}) - end, -} diff --git a/dot_config/nvim/lua/plugins/fugitive.lua b/dot_config/nvim/lua/plugins/fugitive.lua deleted file mode 100644 index 13a8f18..0000000 --- a/dot_config/nvim/lua/plugins/fugitive.lua +++ /dev/null @@ -1,6 +0,0 @@ -return { - "tpope/vim-fugitive", - keys = { -- load the plugin only when using it's keybinding: - { "gs", vim.cmd.Git, desc = "Vim Fugitive" }, - }, -} diff --git a/dot_config/nvim/lua/plugins/gitsigns.lua b/dot_config/nvim/lua/plugins/gitsigns.lua index ad6b8d0..dd89dfb 100644 --- a/dot_config/nvim/lua/plugins/gitsigns.lua +++ b/dot_config/nvim/lua/plugins/gitsigns.lua @@ -1,20 +1,20 @@ return { - "lewis6991/gitsigns.nvim", - config = function() - require("gitsigns").setup({ - current_line_blame = true, - current_line_blame_opts = { - virt_text = true, - delay = 1000 / 3, - }, - signs = { - add = { text = '┃' }, - change = { text = '┃' }, - delete = { text = '_' }, - topdelete = { text = '‾' }, - changedelete = { text = '~' }, - untracked = { text = '┆' }, - }, - }) - end, + "lewis6991/gitsigns.nvim", + config = function() + require("gitsigns").setup({ + current_line_blame = true, + current_line_blame_opts = { + virt_text = true, + delay = 1000 / 3, + }, + signs = { + add = { text = "┃" }, + change = { text = "┃" }, + delete = { text = "_" }, + topdelete = { text = "‾" }, + changedelete = { text = "~" }, + untracked = { text = "┆" }, + }, + }) + end, } diff --git a/dot_config/nvim/lua/plugins/gruvbox.lua b/dot_config/nvim/lua/plugins/gruvbox.lua index 81389a5..a04d39c 100644 --- a/dot_config/nvim/lua/plugins/gruvbox.lua +++ b/dot_config/nvim/lua/plugins/gruvbox.lua @@ -1,34 +1 @@ -return { - "ellisonleao/gruvbox.nvim", - priority = 1000 , - init = function() - require("gruvbox").setup({ - terminal_colors = true, -- add neovim terminal colors - undercurl = true, - underline = true, - bold = true, - italic = { - strings = true, - emphasis = true, - comments = true, - operators = false, - folds = true, - }, - strikethrough = true, - invert_selection = false, - invert_signs = false, - invert_tabline = false, - invert_intend_guides = false, - inverse = true, -- invert background for search, diffs, statuslines and errors - contrast = "", -- can be "hard", "soft" or empty string - palette_overrides = {}, - overrides = {}, - dim_inactive = false, - transparent_mode = true, - }) - - vim.opt.termguicolors = true - vim.opt.background = "dark" - vim.cmd.colorscheme("gruvbox") - end, -} +return { "ellisonleao/gruvbox.nvim", priority = 1000, config = true } diff --git a/dot_config/nvim/lua/plugins/harpoon.lua b/dot_config/nvim/lua/plugins/harpoon.lua index 797abdd..695b69c 100644 --- a/dot_config/nvim/lua/plugins/harpoon.lua +++ b/dot_config/nvim/lua/plugins/harpoon.lua @@ -1,15 +1,30 @@ return { - "ThePrimeagen/harpoon", - dependencies = { - "nvim-lua/plenary.nvim", - }, - keys = { - { "a", function() require("harpoon.mark").add_file() end, desc = "Mark file with Harpoon" }, - { "", function() require("harpoon.ui").toggle_quick_menu() end, desc = "Open Harpoon menu" }, - { "j", function() require("harpoon.ui").nav_file(1) end, desc = "Open Harpoon file 1" }, - { "k", function() require("harpoon.ui").nav_file(2) end, desc = "Open Harpoon file 2" }, - { "l", function() require("harpoon.ui").nav_file(3) end, desc = "Open Harpoon file 3" }, - { ";", function() require("harpoon.ui").nav_file(4) end, desc = "Open Harpoon file 4" }, - }, - config = true + "ThePrimeagen/harpoon", + branch = "harpoon2", + dependencies = { "nvim-lua/plenary.nvim" }, + config = function() + local harpoon = require("harpoon") + harpoon:setup() + + vim.keymap.set("n", "a", function() + harpoon:list():add() + end, { desc = "Mark file with Harpoon" }) + + vim.keymap.set("n", "", function() + harpoon.ui:toggle_quick_menu(harpoon:list()) + end, { desc = "Open Harpoon menu" }) + + vim.keymap.set("n", "j", function() + harpoon:list():select(1) + end, { desc = "Open Harpoon file 1" }) + vim.keymap.set("n", "k", function() + harpoon:list():select(2) + end, { desc = "Open Harpoon file 2" }) + vim.keymap.set("n", "l", function() + harpoon:list():select(3) + end, { desc = "Open Harpoon file 3" }) + vim.keymap.set("n", ";", function() + harpoon:list():select(4) + end, { desc = "Open Harpoon file 4" }) + end, } diff --git a/dot_config/nvim/lua/plugins/jinja.lua b/dot_config/nvim/lua/plugins/jinja.lua index e745fdb..295db2f 100644 --- a/dot_config/nvim/lua/plugins/jinja.lua +++ b/dot_config/nvim/lua/plugins/jinja.lua @@ -1,3 +1,3 @@ return { - "lepture/vim-jinja" + "lepture/vim-jinja", } diff --git a/dot_config/nvim/lua/plugins/lsp-lines.lua b/dot_config/nvim/lua/plugins/lsp-lines.lua index 8263d32..e15055e 100644 --- a/dot_config/nvim/lua/plugins/lsp-lines.lua +++ b/dot_config/nvim/lua/plugins/lsp-lines.lua @@ -1,41 +1,35 @@ --- lsp_lines --- --- A neat little plugin that shows diagnostics as separate lines instead of --- virtual text at the end of each line. This makes it easier to read. - return { - url = "https://git.sr.ht/~whynothugo/lsp_lines.nvim", - event = { "BufReadPre", "BufNewFile" }, - cond = not vim.g.vscode, - keys = { - -- The keys table here supports anything in the opts table for - -- vim.keymap.set, but be careful not to nest it in another table - -- like you would for that function. - -- { "di", desc = "Toggle [d]iagnostic [i]nline" }, - "di", - }, - opts = { - enabled = { - virtual_lines = true, - virtual_text = false, - }, - disabled = { - virtual_lines = false, - virtual_text = { spacing = 4, prefix = "●" }, - }, - }, - config = function(_, opts) - require("lsp_lines").setup() - local is_enabled = false - vim.diagnostic.config(opts.disabled) + url = "https://git.sr.ht/~whynothugo/lsp_lines.nvim", + event = { "BufReadPre", "BufNewFile" }, + keys = { + -- The keys table here supports anything in the opts table for + -- vim.keymap.set, but be careful not to nest it in another table + -- like you would for that function. + -- { "di", desc = "Toggle [d]iagnostic [i]nline" }, + "di", + }, + opts = { + enabled = { + virtual_lines = true, + virtual_text = false, + }, + disabled = { + virtual_lines = false, + virtual_text = { spacing = 4, prefix = "●" }, + }, + }, + config = function(_, opts) + require("lsp_lines").setup() + local is_enabled = false + vim.diagnostic.config(opts.disabled) - vim.keymap.set("n", "di", function() - is_enabled = not is_enabled - if is_enabled then - vim.diagnostic.config(opts.enabled) - else - vim.diagnostic.config(opts.disabled) - end - end, { desc = "Toggle [d]iagnostics [i]nline" }) - end, + vim.keymap.set("n", "di", function() + is_enabled = not is_enabled + if is_enabled then + vim.diagnostic.config(opts.enabled) + else + vim.diagnostic.config(opts.disabled) + end + end, { desc = "Toggle [d]iagnostics [i]nline" }) + end, } diff --git a/dot_config/nvim/lua/plugins/lsp-zero.lua b/dot_config/nvim/lua/plugins/lsp-zero.lua deleted file mode 100644 index b58284e..0000000 --- a/dot_config/nvim/lua/plugins/lsp-zero.lua +++ /dev/null @@ -1,173 +0,0 @@ -return { - - { - 'VonHeikemen/lsp-zero.nvim', - branch = 'v3.x', - lazy = true, - config = false, - init = function() - -- Disable automatic setup, we are doing it manually - vim.g.lsp_zero_extend_cmp = 0 - vim.g.lsp_zero_extend_lspconfig = 0 - end, - }, - - { - 'williamboman/mason.nvim', - lazy = false, - config = true, - }, - - - -- LSP - { - 'neovim/nvim-lspconfig', - cmd = { 'LspInfo', 'LspInstall', 'LspStart' }, - event = { 'BufReadPre', 'BufNewFile' }, - dependencies = { - { 'hrsh7th/cmp-nvim-lsp' }, - { 'williamboman/mason-lspconfig.nvim' }, - { "j-hui/fidget.nvim", tag = "legacy", opts = {} }, - }, - config = function() - -- This is where all the LSP shenanigans will live - local lsp_zero = require('lsp-zero') - lsp_zero.extend_lspconfig() - - -- if you want to know more about lsp-zero and mason.nvim - -- read this: https://github.com/VonHeikemen/lsp-zero.nvim/blob/v3.x/doc/md/guides/integrate-with-mason-nvim.md - lsp_zero.on_attach(function(client, bufnr) - -- see :help lsp_zero_keybindings - -- to learn the available actions - lsp_zero.default_keymaps({ buffer = bufnr }) - end) - - require('mason-lspconfig').setup({ - ensure_installed = { - 'basedpyright', - 'ruff_lsp', - 'tsserver', - 'lua_ls', - }, - handlers = { - lsp_zero.default_setup, - basedpyright = function() - local basedpyright_opts = { - settings = { - basedpyright = { - -- Type checking is very strict by default. Standard is a good balance. - typeCheckingMode = "standard", - } - } - } - require('lspconfig').basedpyright.setup(basedpyright_opts) - - end, - lua_ls = function() - -- (Optional) Configure lua langauge server for neovim - local lua_opts = lsp_zero.nvim_lua_ls() - require('lspconfig').lua_ls.setup(lua_opts) - end, - }, - }) - - vim.diagnostic.config({ - underline = false, - }) - - vim.lsp.inlay_hint.enable() - - 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", "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, - } -} diff --git a/dot_config/nvim/lua/plugins/lsp.lua b/dot_config/nvim/lua/plugins/lsp.lua new file mode 100644 index 0000000..b944572 --- /dev/null +++ b/dot_config/nvim/lua/plugins/lsp.lua @@ -0,0 +1,237 @@ +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({ + [""] = cmp.mapping.select_next_item({ behavior = cmp.SelectBehavior.Insert }), + [""] = cmp.mapping.select_prev_item({ behavior = cmp.SelectBehavior.Insert }), + [""] = cmp.mapping.scroll_docs(-4), + [""] = cmp.mapping.scroll_docs(4), + + -- Ctrl+Space does not currently work in Neovim core on Windows + -- https://github.com/neovim/neovim/issues/8435 + -- [""] = cmp.mapping.complete(), + [""] = cmp.mapping.complete(), + + [""] = cmp.mapping.abort(), + [""] = cmp.mapping.confirm({ + -- Accept currently selected item + behavior = cmp.ConfirmBehavior.Insert, + select = true, + }), + [""] = cmp.mapping.confirm({ + -- Accept currently selected item, replacing stuff as needed + behavior = cmp.ConfirmBehavior.Replace, + select = true, + }), + [""] = 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.with(vim.lsp.handlers.hover, { border = border }), + ["textDocument/signatureHelp"] = vim.lsp.with(vim.lsp.handlers.signature_help, { border = border }), + } + + require("mason-lspconfig").setup({ + ensure_installed = { "basedpyright", "ruff", "lua_ls", "gopls", "rust_analyzer" }, + 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", lsp_format = "fallback" }, + go = { "gopls" }, + rust = { "clippy", lsp_format = "fallback" }, + markdown = prettier, + }, + format_after_save = { + async = true, + stop_after_first = true, + lsp_format = "fallback", + }, + }) + end, + }, + + -- Code actions + { + "aznhe21/actions-preview.nvim", + config = function() + vim.keymap.set({ "v", "n" }, "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 +} diff --git a/dot_config/nvim/lua/plugins/mini.lua b/dot_config/nvim/lua/plugins/mini.lua deleted file mode 100644 index dd1247f..0000000 --- a/dot_config/nvim/lua/plugins/mini.lua +++ /dev/null @@ -1,8 +0,0 @@ -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/plugins/neotest.lua index e2ad2ce..68e7bc3 100644 --- a/dot_config/nvim/lua/plugins/neotest.lua +++ b/dot_config/nvim/lua/plugins/neotest.lua @@ -1,40 +1,44 @@ return { - "nvim-neotest/neotest", - cond = not vim.g.vscode, - ft = { "python" }, - dependencies = { - "nvim-lua/plenary.nvim", - "antoinemadec/FixCursorHold.nvim", - "nvim-treesitter/nvim-treesitter", - "nvim-neotest/neotest-python", - "nvim-neotest/nvim-nio", - }, - opts = function() - return { - adapters = { - require("neotest-python")({ - -- Use the current Python binary on the path. - -- This will usually be a virtual environment. - python = "python", - runner = "pytest", - is_test_file = function(file_path) ---@param file_path string - -- I place all of my Python test files in a - -- `tests` directory, and they all start with - -- `test_` per Pytest conventions. - local normalized_path = vim.fs.normalize(file_path) - return normalized_path:match("tests/.*%/test_.*%.py$") ~= nil - end, - }), - }, - } - end, - config = function(_, opts) - require("neotest").setup(opts) + "nvim-neotest/neotest", + ft = { "python" }, + dependencies = { + "nvim-lua/plenary.nvim", + "antoinemadec/FixCursorHold.nvim", + "nvim-treesitter/nvim-treesitter", + "nvim-neotest/neotest-python", + "nvim-neotest/nvim-nio", + }, + opts = function() + return { + adapters = { + require("neotest-python")({ + -- Use the current Python binary on the path. + -- This will usually be a virtual environment. + python = "python", + runner = "pytest", + is_test_file = function(file_path) ---@param file_path string + -- I place all of my Python test files in a + -- `tests` directory, and they all start with + -- `test_` per Pytest conventions. + local normalized_path = vim.fs.normalize(file_path) + return normalized_path:match("tests/.*%/test_.*%.py$") ~= nil + end, + }), + }, + } + end, + config = function(_, opts) + require("neotest").setup(opts) - vim.keymap.set({ "n" }, "tr", require("neotest").run.run, { desc = "Neotest: run test at cursor" }) - vim.keymap.set({ "n" }, "tf", function() - require("neotest").run.run(vim.fn.expand("%")) - end, { desc = "Neotest: run all tests in current file" }) - vim.keymap.set({ "n", }, "ts", require("neotest").summary.toggle, { desc = "Neotest: toggle summary panel" }) - end, + vim.keymap.set({ "n" }, "tr", require("neotest").run.run, { desc = "Neotest: run test at cursor" }) + vim.keymap.set({ "n" }, "tf", function() + require("neotest").run.run(vim.fn.expand("%")) + end, { desc = "Neotest: run all tests in current file" }) + vim.keymap.set( + { "n" }, + "ts", + require("neotest").summary.toggle, + { desc = "Neotest: toggle summary panel" } + ) + end, } diff --git a/dot_config/nvim/lua/plugins/nvim-cmp.lua b/dot_config/nvim/lua/plugins/nvim-cmp.lua deleted file mode 100644 index 151e67b..0000000 --- a/dot_config/nvim/lua/plugins/nvim-cmp.lua +++ /dev/null @@ -1,119 +0,0 @@ -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({ - [""] = cmp.mapping.select_next_item({ behavior = cmp.SelectBehavior.Insert }), - [""] = cmp.mapping.select_prev_item({ behavior = cmp.SelectBehavior.Insert }), - [""] = cmp.mapping.scroll_docs(-4), - [""] = cmp.mapping.scroll_docs(4), - - -- Ctrl+Space does not currently work in Neovim core on Windows - -- https://github.com/neovim/neovim/issues/8435 - -- [""] = cmp.mapping.complete(), - [""] = cmp.mapping.complete(), - - [""] = cmp.mapping.abort(), - [""] = cmp.mapping.confirm({ - -- Accept currently selected item - behavior = cmp.ConfirmBehavior.Insert, - select = true, - }), - [""] = cmp.mapping.confirm({ - -- Accept currently selected item, replacing stuff as needed - behavior = cmp.ConfirmBehavior.Replace, - select = true, - }), - [""] = 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/plugins/nvim-colorizer.lua b/dot_config/nvim/lua/plugins/nvim-colorizer.lua deleted file mode 100644 index 465d0a9..0000000 --- a/dot_config/nvim/lua/plugins/nvim-colorizer.lua +++ /dev/null @@ -1,6 +0,0 @@ -return { - 'norcalli/nvim-colorizer.lua', - config = function() - require 'colorizer'.setup() - end, -} diff --git a/dot_config/nvim/lua/plugins/oil.lua b/dot_config/nvim/lua/plugins/oil.lua index 3daab43..ac41c0a 100644 --- a/dot_config/nvim/lua/plugins/oil.lua +++ b/dot_config/nvim/lua/plugins/oil.lua @@ -1,14 +1,15 @@ return { "stevearc/oil.nvim", dependencies = { "nvim-tree/nvim-web-devicons" }, - keys = { - { "g-", function() require("oil").open() end, desc = "Open Oil fil browser" }, - }, lazy = false, - opts = { - keymaps = { - -- Disabling because I want Telescope to use this - [""] = false + config = function() + require("oil").setup { + keymaps = { + -- Disabling because I want Telescope to find files in Oil + [""] = false + } } - } + + vim.keymap.set("n", "g-", "Oil", { desc = "Open parent directory" }) + end, } diff --git a/dot_config/nvim/lua/plugins/todo-comments.lua b/dot_config/nvim/lua/plugins/todo-comments.lua index 898f466..b47cb51 100644 --- a/dot_config/nvim/lua/plugins/todo-comments.lua +++ b/dot_config/nvim/lua/plugins/todo-comments.lua @@ -1 +1,6 @@ -return { 'folke/todo-comments.nvim', event = 'VimEnter', dependencies = { 'nvim-lua/plenary.nvim' }, opts = { signs = false } } +return { + "folke/todo-comments.nvim", + event = "VimEnter", + dependencies = { "nvim-lua/plenary.nvim" }, + opts = { signs = false }, +} diff --git a/dot_config/nvim/lua/plugins/treesitter.lua b/dot_config/nvim/lua/plugins/treesitter.lua index de3ad90..aade475 100644 --- a/dot_config/nvim/lua/plugins/treesitter.lua +++ b/dot_config/nvim/lua/plugins/treesitter.lua @@ -1,144 +1,132 @@ return { - "nvim-treesitter/nvim-treesitter", - dependencies = { - "nvim-treesitter/nvim-treesitter-textobjects", - -- Playground is integrated into nvim-treesitter itself now - -- "nvim-treesitter/playground", - }, - build = ":TSUpdate", - event = { "BufReadPre", "BufNewFile" }, - opts = { - -- List of parsers to install automatically - ensure_installed = { "bash", "javascript", "java", "json", "lua", "python", "html", "typescript", "vim", "vimdoc" }, - auto_install = true, - highlight = { - enable = true, - -- Setting this to true will run `:h syntax` and tree-sitter at the same time. - -- Set this to `true` if you depend on 'syntax' being enabled (like for indentation). - -- Using this option may slow down your editor, and you may see some duplicate highlights. - -- Instead of true it can also be a list of languages - additional_vim_regex_highlighting = false, - }, - indent = { - -- Syntax-aware indentation with the = operator - enable = true, - }, - incremental_selection = { - enable = true, - keymaps = { - init_selection = "vn", - node_incremental = "n", - node_decremental = "", - scope_incremental = false, - }, - }, - textobjects = { - move = { - enable = true, + "nvim-treesitter/nvim-treesitter", + dependencies = { + "nvim-treesitter/nvim-treesitter-textobjects", + }, + build = ":TSUpdate", + event = { "BufReadPre", "BufNewFile" }, + opts = { + -- List of parsers to install automatically + ensure_installed = { "lua", "vim", "vimdoc", "python", "json", "toml", "yaml", "bash", "javascript" }, + auto_install = true, + highlight = { + enable = true, + -- Setting this to true will run `:h syntax` and tree-sitter at the same time. + -- Set this to `true` if you depend on 'syntax' being enabled (like for indentation). + -- Using this option may slow down your editor, and you may see some duplicate highlights. + -- Instead of true it can also be a list of languages + additional_vim_regex_highlighting = false, + }, + indent = { + -- Syntax-aware indentation with the = operator + enable = true, + }, + incremental_selection = { + enable = true, + keymaps = { + init_selection = "vn", + node_incremental = "n", + node_decremental = "", + scope_incremental = false, + }, + }, + textobjects = { + move = { + enable = true, - -- Add jumps to the jumplist for navigating with Ctrl+I/O - set_jumps = true, - goto_next_start = { - ["]m"] = { query = "@call.outer", desc = "Next method/function call start" }, - ["]f"] = { query = "@function.outer", desc = "Next function def start" }, - ["]c"] = { query = "@class.outer", desc = "Next class start" }, - ["]i"] = { query = "@conditional.outer", desc = "Next conditional start" }, - ["]l"] = { query = "@loop.outer", desc = "Next loop start" }, + -- Add jumps to the jumplist for navigating with Ctrl+I/O + set_jumps = true, + goto_next_start = { + ["]m"] = { query = "@call.outer", desc = "Next method/function call start" }, + ["]f"] = { query = "@function.outer", desc = "Next function def start" }, + ["]c"] = { query = "@class.outer", desc = "Next class start" }, + ["]i"] = { query = "@conditional.outer", desc = "Next conditional start" }, + ["]l"] = { query = "@loop.outer", desc = "Next loop start" }, - -- You can pass a query group to use query from `queries//.scm file in your runtime path. - -- Below example nvim-treesitter's `locals.scm` and `folds.scm`. They also provide highlights.scm and indent.scm. - ["]s"] = { query = "@scope", query_group = "locals", desc = "Next scope" }, - ["]z"] = { query = "@fold", query_group = "folds", desc = "Next fold" }, - }, - goto_next_end = { - ["]M"] = { query = "@call.outer", desc = "Next method/function call end" }, - ["]F"] = { query = "@function.outer", desc = "Next function def end" }, - ["]C"] = { query = "@class.outer", desc = "Next class end" }, - ["]I"] = { query = "@conditional.outer", desc = "Next conditional end" }, - ["]L"] = { query = "@loop.outer", desc = "Next loop end" }, - }, - goto_previous_start = { - ["[m"] = { query = "@call.outer", desc = "Previous method/function call start" }, - ["[f"] = { query = "@function.outer", desc = "Previous function def start" }, - ["[c"] = { query = "@class.outer", desc = "Previous class start" }, - ["[i"] = { query = "@conditional.outer", desc = "Previous conditional start" }, - ["[l"] = { query = "@loop.outer", desc = "Previous loop start" }, - }, - goto_previous_end = { - ["[M"] = { query = "@call.outer", desc = "Previous method/function call end" }, - ["[F"] = { query = "@function.outer", desc = "Previous function def end" }, - ["[C"] = { query = "@class.outer", desc = "Previous class end" }, - ["[I"] = { query = "@conditional.outer", desc = "Previous conditional end" }, - ["[L"] = { query = "@loop.outer", desc = "Previous loop end" }, - }, - }, + -- You can pass a query group to use query from `queries//.scm file in your runtime path. + -- Below example nvim-treesitter's `locals.scm` and `folds.scm`. They also provide highlights.scm and indent.scm. + ["]s"] = { query = "@scope", query_group = "locals", desc = "Next scope" }, + ["]z"] = { query = "@fold", query_group = "folds", desc = "Next fold" }, + }, + goto_next_end = { + ["]M"] = { query = "@call.outer", desc = "Next method/function call end" }, + ["]F"] = { query = "@function.outer", desc = "Next function def end" }, + ["]C"] = { query = "@class.outer", desc = "Next class end" }, + ["]I"] = { query = "@conditional.outer", desc = "Next conditional end" }, + ["]L"] = { query = "@loop.outer", desc = "Next loop end" }, + }, + goto_previous_start = { + ["[m"] = { query = "@call.outer", desc = "Previous method/function call start" }, + ["[f"] = { query = "@function.outer", desc = "Previous function def start" }, + ["[c"] = { query = "@class.outer", desc = "Previous class start" }, + ["[i"] = { query = "@conditional.outer", desc = "Previous conditional start" }, + ["[l"] = { query = "@loop.outer", desc = "Previous loop start" }, + }, + goto_previous_end = { + ["[M"] = { query = "@call.outer", desc = "Previous method/function call end" }, + ["[F"] = { query = "@function.outer", desc = "Previous function def end" }, + ["[C"] = { query = "@class.outer", desc = "Previous class end" }, + ["[I"] = { query = "@conditional.outer", desc = "Previous conditional end" }, + ["[L"] = { query = "@loop.outer", desc = "Previous loop end" }, + }, + }, - select = { - enable = true, + select = { + enable = true, - -- automatically jump forward to a text object if the - -- cursor isn't on one when triggering the plugin - lookahead = true, + -- automatically jump forward to a text object if the + -- cursor isn't on one when triggering the plugin + lookahead = true, - keymaps = { - -- Use = as an "assignment" text object - ["a="] = { query = "@assignment.outer", desc = "Select outer part of an assignment" }, - ["i="] = { query = "@assignment.inner", desc = "Select inner part of an assignment" }, - ["l="] = { query = "@assignment.lhs", desc = "Select left hand side of an assignment" }, - ["r="] = { query = "@assignment.rhs", desc = "Select right hand side of an assignment" }, + keymaps = { + -- Use = as an "assignment" text object + ["a="] = { query = "@assignment.outer", desc = "Select outer part of an assignment" }, + ["i="] = { query = "@assignment.inner", desc = "Select inner part of an assignment" }, + ["l="] = { query = "@assignment.lhs", desc = "Select left hand side of an assignment" }, + ["r="] = { query = "@assignment.rhs", desc = "Select right hand side of an assignment" }, - -- Use "a" for "argument" - ["aa"] = { query = "@parameter.outer", desc = "Select outer part of an argument / parameter" }, - ["ia"] = { query = "@parameter.inner", desc = "Select inner part of an argument / parameter" }, + -- Use "a" for "argument" + ["aa"] = { query = "@parameter.outer", desc = "Select outer part of an argument / parameter" }, + ["ia"] = { query = "@parameter.inner", desc = "Select inner part of an argument / parameter" }, - -- Use "i" for "conditional" (saving c for class) - ["ai"] = { query = "@conditional.outer", desc = "Select outer part of a conditional" }, - ["ii"] = { query = "@conditional.inner", desc = "Select inner part of a conditional" }, + -- Use "i" for "conditional" (saving c for class) + ["ai"] = { query = "@conditional.outer", desc = "Select outer part of a conditional" }, + ["ii"] = { query = "@conditional.inner", desc = "Select inner part of a conditional" }, - -- Use "l" for "loop" - ["al"] = { query = "@loop.outer", desc = "Select outer part of a loop" }, - ["ij"] = { query = "@loop.inner", desc = "Select inner part of a loop" }, + -- Use "l" for "loop" + ["al"] = { query = "@loop.outer", desc = "Select outer part of a loop" }, + ["ij"] = { query = "@loop.inner", desc = "Select inner part of a loop" }, - -- Use "f" for "function definition" (body of a function) - ["af"] = { query = "@function.outer", desc = "Select outer part of a function definition" }, - ["if"] = { query = "@function.inner", desc = "Select inner part of a function definition" }, + -- Use "f" for "function definition" (body of a function) + ["af"] = { query = "@function.outer", desc = "Select outer part of a function definition" }, + ["if"] = { query = "@function.inner", desc = "Select inner part of a function definition" }, - -- Use "m" for "method call" (invocation of a function) - ["am"] = { query = "@call.outer", desc = "Select outer part of a method/function call" }, - ["im"] = { query = "@call.inner", desc = "Select inner part of a method/function call" }, + -- Use "m" for "method call" (invocation of a function) + ["am"] = { query = "@call.outer", desc = "Select outer part of a method/function call" }, + ["im"] = { query = "@call.inner", desc = "Select inner part of a method/function call" }, - -- Use "c" for "class" - ["ac"] = { query = "@class.outer", desc = "Select outer part of a class" }, - ["ic"] = { query = "@class.inner", desc = "Select inner part of a class" }, - }, - }, + -- Use "c" for "class" + ["ac"] = { query = "@class.outer", desc = "Select outer part of a class" }, + ["ic"] = { query = "@class.inner", desc = "Select inner part of a class" }, + }, + }, - swap = { - enable = true, - swap_next = { - ["na"] = "@parameter.inner", -- Swap parameter with next - ["nf"] = "@function.outer", -- Swap function with next - }, - swap_previous = { - ["pa"] = "@parameter.inner", -- Swap parameter with previous - ["pf"] = "@function.outer", -- Swap function with previous - }, - }, - }, - }, - config = function(_, opts) - require("nvim-treesitter.configs").setup(opts) - vim.opt.foldmethod = "expr" - vim.opt.foldexpr = "nvim_treesitter#foldexpr()" - - -- Allow , and ; to repeat motions... - local ts_repeat_move = require("nvim-treesitter.textobjects.repeatable_move") - vim.keymap.set({ "n", "x", "o" }, ";", ts_repeat_move.repeat_last_move) - vim.keymap.set({ "n", "x", "o" }, ";", ts_repeat_move.repeat_last_move_opposite) - -- ...but make sure they still work for the built-in f/t jumps - vim.keymap.set({ "n", "x", "o" }, "f", ts_repeat_move.builtin_f) - vim.keymap.set({ "n", "x", "o" }, "F", ts_repeat_move.builtin_F) - vim.keymap.set({ "n", "x", "o" }, "t", ts_repeat_move.builtin_t) - vim.keymap.set({ "n", "x", "o" }, "T", ts_repeat_move.builtin_T) - end, + swap = { + enable = true, + swap_next = { + ["na"] = "@parameter.inner", -- Swap parameter with next + ["nf"] = "@function.outer", -- Swap function with next + }, + swap_previous = { + ["pa"] = "@parameter.inner", -- Swap parameter with previous + ["pf"] = "@function.outer", -- Swap function with previous + }, + }, + }, + }, + config = function(_, opts) + require("nvim-treesitter.configs").setup(opts) + vim.opt.foldmethod = "expr" + vim.opt.foldexpr = "nvim_treesitter#foldexpr()" + end, } diff --git a/dot_config/nvim/lua/plugins/undotree.lua b/dot_config/nvim/lua/plugins/undotree.lua index 3a6d160..3465446 100644 --- a/dot_config/nvim/lua/plugins/undotree.lua +++ b/dot_config/nvim/lua/plugins/undotree.lua @@ -1,8 +1,8 @@ return { - "jiaoshijie/undotree", - dependencies = "nvim-lua/plenary.nvim", - config = true, - keys = { -- load the plugin only when using it's keybinding: - { "u", "lua require('undotree').toggle()", desc = "Toggle Undotree" }, - }, + "jiaoshijie/undotree", + dependencies = "nvim-lua/plenary.nvim", + config = true, + keys = { -- load the plugin only when using it's keybinding: + { "u", "lua require('undotree').toggle()", desc = "Toggle Undotree" }, + }, } diff --git a/dot_config/nvim/lua/plugins/which-key.lua b/dot_config/nvim/lua/plugins/which-key.lua index 0cfcf14..7410159 100644 --- a/dot_config/nvim/lua/plugins/which-key.lua +++ b/dot_config/nvim/lua/plugins/which-key.lua @@ -1,41 +1,4 @@ --- which-key --- https://github.com/folke/which-key.nvim --- --- Shows a popup window with key bindings when the native vim --- timeout length has expired. --- --- I go back and forth on whether I like this plugin, but right now I --- think it's nice as an occasional referenc for stuff I don't use --- frequently. - return { - "folke/which-key.nvim", - event = "VeryLazy", - config = function() - vim.opt.timeout = true - vim.opt.timeoutlen = 1000 - local wk = require("which-key") - wk.setup({ - window = { - border = "double", - position = "bottom", - margin = { 1, 0, 1, 0 }, - padding = { 3, 2, 3, 2 }, - winblend = 20, - }, - layout = { - height = { min = 4, max = 25 }, - width = { min = 20, max = 50 }, - spacing = 8, - align = "center", - }, - }) - wk.register({ - [""] = { - c = { name = "+code / clipboard" }, - -- d = { name = "+diagnostics" }, - s = { name = "+search" }, - }, - }) - end + "folke/which-key.nvim", + event = "VeryLazy", } diff --git a/dot_config/nvim/plugin/keymaps.lua b/dot_config/nvim/plugin/keymaps.lua new file mode 100644 index 0000000..8f5ff28 --- /dev/null +++ b/dot_config/nvim/plugin/keymaps.lua @@ -0,0 +1,139 @@ +-- 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" }, "", "noh", { desc = "Escape and clear hlsearch" }) + +-- Move lines while in visual mode with J and K +map("v", "J", ":m '>+1gv=gv") +map("v", "K", ":m '<-2gv=gv") + +-- Easier execution of Lua code +map("n", "x", ".lua", { desc = "Execute the current line" }) +map("n", "x", "source %", { 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", "", "zz") +map("n", "", "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", "p", '"_dP') +map({ "n", "v" }, "d", '"_dP') + +-- Easier quickfix naviagion +map("n", "", "cprev", { desc = "Quickfix previous item" }) +map("n", "", "cnext", { desc = "Quickfix next item" }) + +-- System clipboard +map({ "n", "v" }, "cd", '"+d', { desc = "Clipboard delete" }) +map({ "n", "v" }, "cp", '"+p', { desc = "Clipboard paste" }) +map({ "n", "v" }, "cy", '"+y', { desc = "Clipboard yank" }) + +-- Map g- to netrw (temporary placeholder for oil) +-- map("n", "g-", vim.cmd.Ex, { desc = "Open netrw" }) + +map("n", "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" }) + +-- 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", + "sn", + tele_builtin("lsp_document_symbols"), + vim.lsp.buf.document_symbol, + "Search document symbols" + ) + lsp_telescope_map( + "n", + "sN", + tele_builtin("lsp_dynamic_workspace_symbols"), + vim.lsp.buf.workspace_symbol, + "Search workspace symbols" + ) + + -- Code changes + lsp_map("n", "cr", vim.lsp.buf.rename, "Rename") + -- ca is being overwritten by the 'actions-preview' plugin + -- lsp_map("n", "ca", vim.lsp.buf.code_action, "Code actions") + + -- Diagnostics + lsp_map("n", "ds", vim.diagnostic.open_float, "[s]how [d]iagnostic window") + lsp_map("n", "dn", function() + vim.diagnostic.goto_next({ float = true }) + end, "Go to [n]ext [d]iagnostic") + lsp_map("n", "dp", function() + vim.diagnostic.goto_prev({ float = true }) + end, "Go to [p]revious [d]iagnostic") + + -- See `:help K` for why this keymap + lsp_map("n", "K", vim.lsp.buf.hover, "Hover Documentation") + lsp_map("n", "", vim.lsp.buf.signature_help, "Signature Documentation") + + -- Workspace + lsp_map("n", "wa", vim.lsp.buf.add_workspace_folder, "[W]orkspace [A]dd Folder") + lsp_map("n", "wr", vim.lsp.buf.remove_workspace_folder, "[W]orkspace [R]emove Folder") + lsp_map("n", "wl", function() + print(vim.inspect(vim.lsp.buf.list_workspace_folders())) + end, "[W]orkspace [L]ist Folders") + end, +}) diff --git a/dot_config/nvim/plugin/options.lua b/dot_config/nvim/plugin/options.lua new file mode 100644 index 0000000..044f24f --- /dev/null +++ b/dot_config/nvim/plugin/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 gruvbox]]) -- cgit v1.2.3