diff --git a/README.md b/README.md index b9bc55a..144eb56 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Neovim Configuration -Portable Neovim configuration using lazy.nvim, Mason-managed tooling, native LSP, Treesitter, Telescope, and DAP (Neovim 0.11+, tested on 0.12.1). +Portable Neovim configuration using lazy.nvim and native LSP (Neovim 0.11+, tested on 0.12.1). ## Installation @@ -19,13 +19,16 @@ git clone --recurse-submodules git@github.com:itme-brain/nixos.git - **Native LSP** (`vim.lsp.config` / `vim.lsp.enable`) - no manual server list needed - **Smart LSP picker** (`css`) - auto-detects installed servers for current filetype - **Neovim 0.12 compatible** - uses built-in `:lsp` commands and keeps legacy `:Lsp*` aliases working -- **Portable** - Mason is the source of truth for LSP servers, debug adapters, and tree-sitter-cli -- **Treesitter** - starts via Neovim's native `vim.treesitter.start` -- **Debugging** - lazy-loaded `nvim-dap` stack with Mason-managed adapters +- **Portable** - works on NixOS (LSPs via extraPackages) or any system (LSPs via Mason) +- **Mason** - auto-disabled on NixOS, auto-installs essentials elsewhere ## LSP Setup -Mason installs the shared LSP baseline on every system: +On NixOS, LSPs come from: +- `neovim.extraPackages` (global essentials) +- Project `devShell` (project-specific) + +On other systems, Mason auto-installs: - `lua_ls` - Lua/Neovim - `nil_ls` - Nix - `bashls` - Bash/Shell @@ -36,30 +39,9 @@ Mason installs the shared LSP baseline on every system: - `taplo` - TOML - `yamlls` - YAML -On NixOS, Mason-installed binaries require `nix-ld` so downloaded tools can execute. The NixOS module should provide `nix-ld`; Neovim itself does not keep a separate Nix-only LSP package list. - The smart picker (`css`) scans all lspconfig servers and shows only those with binaries installed. On Neovim 0.12+, start/stop/restart uses the built-in `:lsp` commands under the hood. -## Treesitter - -Treesitter uses the current `nvim-treesitter` main branch API: -- Parsers are installed with `nvim-treesitter` -- Highlighting starts through `vim.treesitter.start` -- `tree-sitter-cli` is bootstrapped through Mason when needed for parser installs/updates - -## Debugging - -Debugging uses `nvim-dap`, `nvim-dap-ui`, `nvim-dap-virtual-text`, `telescope-dap.nvim`, and `mason-nvim-dap.nvim`. - -The DAP stack is lazy-loaded. Normal startup does not load DAP; it loads only when a `:Dap...` command runs or a `d...` mapping is used. - -Mason installs: -- `debugpy` - Python -- `codelldb` - C/C++/Rust -- `bash-debug-adapter` - Bash -- `js-debug-adapter` - JavaScript/TypeScript - ## Key Bindings | Key | Action | @@ -76,17 +58,6 @@ Mason installs: | `bd` | Delete buffer | | `/` | Live grep from git root | | `ff` | Find files from git root | -| `db` | Toggle breakpoint | -| `dB` | Set conditional breakpoint | -| `dc` | Continue debugging | -| `di` | Step into | -| `do` | Step over | -| `dO` | Step out | -| `du` | Toggle debug UI | -| `dt` | Terminate debug session | -| `de` | Evaluate expression | -| `ds` | Debug configurations | -| `dS` | Debug breakpoints | ## Plugins @@ -95,9 +66,6 @@ Mason installs: - **nvim-cmp** - completion - **telescope.nvim** - fuzzy finder - **nvim-treesitter** - syntax highlighting -- **nvim-dap** - debug adapter client -- **nvim-dap-ui** - debugging UI panes -- **mason-nvim-dap.nvim** - Mason debug adapter integration - **neo-tree.nvim** - file explorer - **gitsigns.nvim** - git integration - **lualine.nvim** - statusline diff --git a/lazy-lock.json b/lazy-lock.json index e2b4d99..f403e7c 100644 --- a/lazy-lock.json +++ b/lazy-lock.json @@ -1,22 +1,27 @@ { - "anticuus": { "branch": "main", "commit": "259315038503e2327cc3024dc306af36563d7f5b" }, + "LuaSnip": { "branch": "master", "commit": "642b0c595e11608b4c18219e93b88d7637af27bc" }, "autoclose.nvim": { "branch": "main", "commit": "bafd0368716216fa6a7bb2a43ecd889b44efdb46" }, - "blink.cmp": { "branch": "main", "commit": "78336bc89ee5365633bcf754d93df01678b5c08f" }, - "fzf-lua": { "branch": "main", "commit": "b437bafc981a180d609bb4092c56ce8999f7a2c4" }, + "base16-vim": { "branch": "master", "commit": "3be3cd82cd31acfcab9a41bad853d9c68d30478d" }, + "bitcoin-script-hints.nvim": { "branch": "main", "commit": "628badbb09a230e3838d863b21dcc07cdd2429bc" }, + "bufferline.nvim": { "branch": "main", "commit": "655133c3b4c3e5e05ec549b9f8cc2894ac6f51b3" }, + "cmp-nvim-lsp": { "branch": "main", "commit": "cbc7b02bb99fae35cb42f514762b89b5126651ef" }, + "cmp_luasnip": { "branch": "master", "commit": "98d9cb5c2c38532bd9bdb481067b20fea8f32e90" }, "gitsigns.nvim": { "branch": "main", "commit": "6d808f99bd63303646794406e270bd553ad7792e" }, "indent-blankline.nvim": { "branch": "master", "commit": "d28a3f70721c79e3c5f6693057ae929f3d9c0a03" }, "lazy.nvim": { "branch": "main", "commit": "306a05526ada86a7b30af95c5cc81ffba93fef97" }, "log-highlight.nvim": { "branch": "main", "commit": "ca88628f6dd3b9bb46f9a7401669e24cf7de47a4" }, + "lualine.nvim": { "branch": "master", "commit": "131a558e13f9f28b15cd235557150ccb23f89286" }, "mason-lspconfig.nvim": { "branch": "main", "commit": "0c2823e0418f3d9230ff8b201c976e84de1cb401" }, - "mason-nvim-dap.nvim": { "branch": "main", "commit": "9a10e096703966335bd5c46c8c875d5b0690dade" }, "mason.nvim": { "branch": "main", "commit": "cb8445f8ce85d957416c106b780efd51c6298f89" }, - "nvim-dap": { "branch": "master", "commit": "45a69eba683a2c448dd9ecfc4de89511f0646b5f" }, - "nvim-lspconfig": { "branch": "master", "commit": "31026a13eefb20681124706a79fc1df6bf11ab27" }, - "nvim-treesitter": { "branch": "main", "commit": "4916d6592ede8c07973490d9322f187e07dfefac" }, + "neo-tree.nvim": { "branch": "main", "commit": "19d20a99bf0061a5ecc4343d2f09fa713306c965" }, + "nui.nvim": { "branch": "main", "commit": "de740991c12411b663994b2860f1a4fd0937c130" }, + "nvim-cmp": { "branch": "main", "commit": "a1d504892f2bc56c2e79b65c6faded2fd21f3eca" }, + "nvim-lspconfig": { "branch": "master", "commit": "f7e89f3d19fb436e1fbeff3bf4291eef35da94e3" }, + "nvim-navic": { "branch": "master", "commit": "f5eba192f39b453675d115351808bd51276d9de5" }, + "nvim-treesitter": { "branch": "main", "commit": "df7489eeea351bece7fd0f9c825be5cb6a1438f0" }, "nvim-web-devicons": { "branch": "master", "commit": "4fc505ac7bd7692824a142e96e5f529c133862f8" }, - "oil.nvim": { "branch": "master", "commit": "0fcc83805ad11cf714a949c98c605ed717e0b83e" }, "plenary.nvim": { "branch": "master", "commit": "74b06c6c75e4eeb3108ec01852001636d85a932b" }, - "render-markdown.nvim": { "branch": "main", "commit": "3f3eea97b80839f629c951ca660ffd125bfa5b34" }, + "telescope.nvim": { "branch": "0.1.x", "commit": "a0bbec21143c7bc5f8bb02e0005fa0b982edc026" }, "todo-comments.nvim": { "branch": "main", "commit": "31e3c38ce9b29781e4422fc0322eb0a21f4e8668" }, "treesitter-parser-registry": { "branch": "main", "commit": "6eb15358bb9fc88f0d3401d8538d56652e9bdf3c" }, "which-key.nvim": { "branch": "main", "commit": "3aab2147e74890957785941f0c1ad87d0a44c15a" } diff --git a/lua/config/lazy.lua b/lua/config/lazy.lua index c06ab36..89c356d 100644 --- a/lua/config/lazy.lua +++ b/lua/config/lazy.lua @@ -29,7 +29,7 @@ require("lazy").setup({ }, -- Configure any other settings here. See the documentation for more details. -- colorscheme that will be used when installing plugins. - install = { colorscheme = { "anticuus" } }, + install = { colorscheme = { "onedark" } }, -- automatically check for plugin updates checker = { enabled = false }, }) diff --git a/lua/config/options.lua b/lua/config/options.lua index 70edefe..3bb30b8 100644 --- a/lua/config/options.lua +++ b/lua/config/options.lua @@ -13,6 +13,7 @@ vim.opt.tabstop = 2 vim.opt.shiftwidth = 2 vim.opt.softtabstop = 2 vim.opt.expandtab = true +vim.opt.smartindent = true vim.opt.ignorecase = true vim.opt.smartcase = true vim.opt.incsearch = false @@ -25,29 +26,11 @@ vim.opt.guicursor = "n-v-c:block,i:block,r:block" vim.opt.fillchars = { eob = " " } -vim.opt.laststatus = 3 - -local mode_names = { - n = "NORMAL", i = "INSERT", v = "VISUAL", V = "V-LINE", - ["\22"] = "V-BLOCK", c = "COMMAND", R = "REPLACE", t = "TERM", -} - -_G.statusline_mode = function() - return mode_names[vim.api.nvim_get_mode().mode] or "?" -end - -_G.statusline_branch = function() - local b = vim.b.gitsigns_head - return b and (" " .. b) or "" -end - -vim.opt.statusline = " %{v:lua.statusline_mode()} %f%m%r %= %{v:lua.statusline_branch()} %l:%c " - local options_group = vim.api.nvim_create_augroup("config_options", { clear = true }) vim.api.nvim_create_autocmd("FileType", { group = options_group, - pattern = { "python", "c", "cpp" }, + pattern = { "python", "haskell", "c", "cpp" }, callback = function() local opt = vim.opt_local opt.tabstop = 4 @@ -55,3 +38,11 @@ vim.api.nvim_create_autocmd("FileType", { opt.softtabstop = 4 end, }) + +vim.api.nvim_create_autocmd({ "BufRead", "BufNewFile" }, { + group = options_group, + pattern = "*.purs", + callback = function(event) + vim.bo[event.buf].filetype = "purescript" + end, +}) diff --git a/lua/plugins/blink-cmp.lua b/lua/plugins/blink-cmp.lua deleted file mode 100644 index 1e49884..0000000 --- a/lua/plugins/blink-cmp.lua +++ /dev/null @@ -1,30 +0,0 @@ -return { - { - "saghen/blink.cmp", - version = "*", - event = "InsertEnter", - opts = { - keymap = { - preset = "none", - [""] = { "select_and_accept" }, - [""] = { "cancel" }, - [""] = { "select_next", "fallback" }, - [""] = { "select_prev", "fallback" }, - [""] = { "scroll_documentation_down", "fallback" }, - [""] = { "scroll_documentation_up", "fallback" }, - }, - completion = { - list = { - selection = { preselect = false, auto_insert = false }, - }, - documentation = { - auto_show = true, - auto_show_delay_ms = 200, - }, - }, - sources = { - default = { "lsp", "buffer", "path" }, - }, - }, - }, -} diff --git a/lua/plugins/bufferline.lua b/lua/plugins/bufferline.lua new file mode 100644 index 0000000..8ddec03 --- /dev/null +++ b/lua/plugins/bufferline.lua @@ -0,0 +1,40 @@ +return { + { + "akinsho/bufferline.nvim", + version = "*", + dependencies = "nvim-tree/nvim-web-devicons", + config = function() + require("bufferline").setup{ + options = { + separator_style = "thin", + show_buffer_close_buttons = false, + show_close_icon = false, + }, + highlights = { + -- Force all icon backgrounds to transparent + buffer_selected = { bg = "NONE" }, + buffer_visible = { bg = "NONE" }, + background = { bg = "NONE" }, + fill = { bg = "NONE" }, + separator = { bg = "NONE" }, + separator_selected = { bg = "NONE" }, + separator_visible = { bg = "NONE" }, + close_button = { bg = "NONE" }, + close_button_selected = { bg = "NONE" }, + close_button_visible = { bg = "NONE" }, + modified = { bg = "NONE" }, + modified_selected = { bg = "NONE" }, + modified_visible = { bg = "NONE" }, + duplicate = { bg = "NONE" }, + duplicate_selected = { bg = "NONE" }, + duplicate_visible = { bg = "NONE" }, + indicator_selected = { bg = "NONE" }, + indicator_visible = { bg = "NONE" }, + pick = { bg = "NONE" }, + pick_selected = { bg = "NONE" }, + pick_visible = { bg = "NONE" }, + }, + } + end + } +} diff --git a/lua/plugins/colorscheme.lua b/lua/plugins/colorscheme.lua index de3f5d8..a5ab11e 100644 --- a/lua/plugins/colorscheme.lua +++ b/lua/plugins/colorscheme.lua @@ -1,70 +1,60 @@ return { { - "https://codeberg.org/juanmilkah/anticuus.nvim", - name = "anticuus", - lazy = false, - priority = 1000, + "chriskempson/base16-vim", config = function() local color_group = vim.api.nvim_create_augroup("config_colorscheme", { clear = true }) - vim.cmd.colorscheme("anticuus") - local highlights = { - Comment = { fg = "#5a5a5a", italic = true }, - ["@comment"] = { fg = "#5a5a5a", italic = true }, - - Function = { fg = "#88ddcc" }, - ["@function"] = { fg = "#88ddcc" }, - ["@function.builtin"] = { fg = "#88ddcc" }, - ["@function.method"] = { fg = "#88ddcc" }, - - Type = { fg = "#e8a060" }, - Typedef = { fg = "#e8a060" }, - ["@type"] = { fg = "#e8a060" }, - ["@type.builtin"] = { fg = "#e8a060" }, - - Number = { fg = "#c490d0" }, - Boolean = { fg = "#c490d0" }, - Float = { fg = "#c490d0" }, - Constant = { fg = "#c490d0" }, - ["@number"] = { fg = "#c490d0" }, - ["@number.float"] = { fg = "#c490d0" }, - ["@boolean"] = { fg = "#c490d0" }, - ["@constant"] = { fg = "#c490d0" }, - ["@constant.builtin"] = { fg = "#c490d0" }, - - ["@tag"] = { fg = "#ff6b6b" }, - ["@tag.delimiter"] = { fg = "#ff6b6b" }, - ["@keyword.return"] = { fg = "#ff6b6b" }, - ["@keyword.exception"] = { fg = "#ff6b6b" }, - - MatchParen = { fg = "#c490d0", bold = true, underline = true }, - - IncSearch = { fg = "#000000", bg = "#88ddcc" }, - CurSearch = { fg = "#000000", bg = "#c490d0" }, - - DiffAdd = { fg = "#a5d6a7", bg = "#0a2010" }, - DiffChange = { fg = "#e8a060", bg = "#201a0a" }, - DiffDelete = { fg = "#ff6b6b", bg = "#200a0a" }, - DiffText = { fg = "#ffcc00", bg = "#3a2000", bold = true }, - - WinBar = { fg = "#dadada", bold = true }, - WinBarNC = { fg = "#888888" }, - - ConflictMarker = { link = "DiagnosticError" }, - YankHighlight = { link = "Search" }, - - OilCreate = { link = "DiagnosticOk" }, - OilDelete = { link = "DiagnosticError" }, - OilMove = { link = "DiagnosticWarn" }, - OilCopy = { link = "DiagnosticInfo" }, - - BlinkCmpLabelMatch = { link = "Search" }, - BlinkCmpMenuSelection = { link = "PmenuSel" }, - - FzfLuaTitle = { link = "Title" }, - FzfLuaPreviewTitle = { link = "Title" }, - FzfLuaHeaderBind = { link = "Special" }, + Normal = { bg = "NONE", fg = "#FFFFFF" }, + Visual = { bg = "Gray", fg = "Black" }, + NonText = { bg = "NONE" }, + LineNr = { bg = "NONE" }, + CursorLine = { bg = "NONE" }, + CursorLineNr = { bg = "NONE", fg = "#E5C07B", bold = true }, + Search = { bg = "#FFCC66", fg = "#000000" }, + Pmenu = { bg = "Black", fg = "White" }, + PmenuSel = { bg = "Green", fg = "Black" }, + PmenuThumb = { bg = "Green" }, + PmenuSbar = { bg = "Black" }, + WinSeparator = { bg = "NONE" }, + GitGutterChange = { bg = "NONE" }, + GitGutterAdd = { bg = "NONE" }, + GitGutterDelete = { bg = "NONE" }, + GitSignsAddNr = { bg = "NONE", fg = "#98c379" }, + GitSignsChangeNr = { bg = "NONE", fg = "#61afef" }, + GitSignsDeleteNr = { bg = "NONE", fg = "#e06c75" }, + SignColumn = { bg = "NONE" }, + NeoTreeGitAdded = { bg = "NONE", fg = "#98c379" }, + NeoTreeGitModified = { bg = "NONE", fg = "#e5c07b" }, + NeoTreeGitDeleted = { bg = "NONE", fg = "#e06c75" }, + NeoTreeGitConflict = { bg = "NONE", fg = "#e06c75" }, + NeoTreeGitUntracked = { bg = "NONE", fg = "#61afef" }, + TelescopeSelection = { bg = "Gray", fg = "Green", bold = true }, + TelescopePreviewMatch = { bg = "Yellow", fg = "Black" }, + TreesitterContext = { bg = "NONE" }, + LazyH1 = { bg = "Black", fg = "Green" }, + IblScope = { bg = "NONE", fg = "Yellow" }, + ConflictMarker = { fg = "red" }, + DiffAdd = { bg = "NONE" }, + DiffChange = { bg = "NONE" }, + DiffDelete = { bg = "NONE" }, + DiffText = { bg = "NONE" }, + BufferLineFill = { bg = "NONE" }, + BufferLineBackground = { bg = "NONE", fg = "#5c6370" }, + BufferLineBuffer = { bg = "NONE", fg = "#5c6370" }, + BufferLineBufferSelected = { bg = "NONE", fg = "#FFFFFF", bold = true }, + BufferLineBufferVisible = { bg = "NONE", fg = "#abb2bf" }, + BufferLineCloseButton = { bg = "NONE", fg = "#5c6370" }, + BufferLineCloseButtonSelected = { bg = "NONE", fg = "#e06c75" }, + BufferLineCloseButtonVisible = { bg = "NONE", fg = "#5c6370" }, + BufferLineModified = { bg = "NONE", fg = "#e5c07b" }, + BufferLineModifiedSelected = { bg = "NONE", fg = "#e5c07b" }, + BufferLineModifiedVisible = { bg = "NONE", fg = "#e5c07b" }, + BufferLineSeparator = { bg = "NONE", fg = "#3e4452" }, + BufferLineSeparatorSelected = { bg = "NONE", fg = "#3e4452" }, + BufferLineSeparatorVisible = { bg = "NONE", fg = "#3e4452" }, + BufferLineIndicatorSelected = { bg = "NONE", fg = "#61afef" }, + YankHighlight = { bg = "yellow", fg = "black" }, } local function apply_highlights() @@ -83,6 +73,7 @@ return { }) end + vim.cmd.colorscheme("base16-onedark") apply_highlights() vim.api.nvim_create_autocmd("ColorScheme", { @@ -92,7 +83,7 @@ return { vim.api.nvim_create_autocmd({ "BufWinEnter", "WinEnter" }, { group = color_group, - callback = function() + callback = function(event) apply_conflict_match(vim.api.nvim_get_current_win()) end, }) @@ -112,6 +103,7 @@ return { }, { - "fei6409/log-highlight.nvim", - }, + "fei6409/log-highlight.nvim" + } + } diff --git a/lua/plugins/debug.lua b/lua/plugins/debug.lua deleted file mode 100644 index 89c8ea4..0000000 --- a/lua/plugins/debug.lua +++ /dev/null @@ -1,123 +0,0 @@ -local dap_adapters = { - "python", - "codelldb", - "bash", - "js", -} - -return { - { - "mfussenegger/nvim-dap", - dependencies = { - "williamboman/mason.nvim", - "jay-babu/mason-nvim-dap.nvim", - }, - cmd = { - "DapContinue", - "DapDisconnect", - "DapInstall", - "DapLoadLaunchJSON", - "DapNew", - "DapRestartFrame", - "DapSetLogLevel", - "DapShowLog", - "DapStepInto", - "DapStepOut", - "DapStepOver", - "DapTerminate", - "DapToggleBreakpoint", - "DapUninstall", - }, - keys = { - { "db", function() require("dap").toggle_breakpoint() end, desc = "Toggle Breakpoint" }, - { "dB", function() require("dap").set_breakpoint(vim.fn.input("Breakpoint condition: ")) end, desc = "Conditional Breakpoint" }, - { "dc", function() require("dap").continue() end, desc = "Continue" }, - { "di", function() require("dap").step_into() end, desc = "Step Into" }, - { "do", function() require("dap").step_over() end, desc = "Step Over" }, - { "dO", function() require("dap").step_out() end, desc = "Step Out" }, - { "dr", function() require("dap").repl.toggle() end, desc = "Toggle REPL" }, - { "dl", function() require("dap").run_last() end, desc = "Run Last" }, - { "dt", function() require("dap").terminate() end, desc = "Terminate" }, - { "de", function() require("dap.ui.widgets").hover() end, mode = { "n", "v" }, desc = "Evaluate" }, - { "du", - function() - local widgets = require("dap.ui.widgets") - widgets.centered_float(widgets.scopes) - end, - desc = "Show Scopes" }, - { "df", - function() - local widgets = require("dap.ui.widgets") - widgets.centered_float(widgets.frames) - end, - desc = "Call Stack" }, - { "ds", - function() - local dap = require("dap") - local ft = vim.bo.filetype - local configs = dap.configurations[ft] or {} - if #configs == 0 then - vim.notify("No DAP configurations for filetype: " .. ft, vim.log.levels.WARN) - return - end - vim.ui.select(configs, { - prompt = "Select DAP configuration:", - format_item = function(c) return c.name end, - }, function(choice) - if choice then dap.run(choice) end - end) - end, - desc = "Debug Configurations" }, - { "dS", function() require("dap").list_breakpoints() end, desc = "List Breakpoints" }, - }, - config = function() - local dap = require("dap") - - require("mason").setup() - require("mason-nvim-dap").setup({ - ensure_installed = dap_adapters, - automatic_installation = false, - handlers = {}, - }) - - vim.fn.sign_define("DapBreakpoint", { text = "B", texthl = "DiagnosticSignError" }) - vim.fn.sign_define("DapBreakpointCondition", { text = "C", texthl = "DiagnosticSignWarn" }) - vim.fn.sign_define("DapLogPoint", { text = "L", texthl = "DiagnosticSignInfo" }) - vim.fn.sign_define("DapStopped", { text = ">", texthl = "DiagnosticSignWarn", linehl = "Visual" }) - vim.fn.sign_define("DapBreakpointRejected", { text = "R", texthl = "DiagnosticSignError" }) - - dap.adapters["pwa-node"] = { - type = "server", - host = "localhost", - port = "${port}", - executable = { - command = vim.fn.stdpath("data") .. "/mason/bin/js-debug-adapter", - args = { "${port}" }, - }, - } - - local js_configurations = { - { - type = "pwa-node", - request = "launch", - name = "Node: Launch file", - program = "${file}", - cwd = "${workspaceFolder}", - console = "integratedTerminal", - }, - { - type = "pwa-node", - request = "attach", - name = "Node: Attach process", - processId = require("dap.utils").pick_process, - cwd = "${workspaceFolder}", - }, - } - - dap.configurations.javascript = js_configurations - dap.configurations.typescript = js_configurations - dap.configurations.javascriptreact = js_configurations - dap.configurations.typescriptreact = js_configurations - end, - }, -} diff --git a/lua/plugins/disabled.lua b/lua/plugins/disabled.lua new file mode 100644 index 0000000..0b7a483 --- /dev/null +++ b/lua/plugins/disabled.lua @@ -0,0 +1,3 @@ +return { + { "jay-babu/mason-nvim-dap.nvim", enabled = false }, +} diff --git a/lua/plugins/fzf-lua.lua b/lua/plugins/fzf-lua.lua deleted file mode 100644 index 5425e5a..0000000 --- a/lua/plugins/fzf-lua.lua +++ /dev/null @@ -1,87 +0,0 @@ -local function get_root() - local result = vim.system({ "git", "rev-parse", "--show-toplevel" }, { text = true }):wait() - if result.code == 0 and result.stdout then - local git_dir = vim.trim(result.stdout) - if git_dir ~= "" then - return git_dir - end - end - return vim.fn.getcwd() -end - --- Close oil first so picker actions land in a normal window, not oil's float. -local function pick(action) - return function() - if vim.bo.filetype == "oil" then - require("oil").close() - end - action() - end -end - -return { - { - "ibhagwan/fzf-lua", - dependencies = { "nvim-tree/nvim-web-devicons" }, - config = function() - local fzf = require("fzf-lua") - local fzf_actions = require("fzf-lua.actions") - - fzf.setup({ - keymap = { - fzf = { - true, - ["ctrl-d"] = "preview-half-page-down", - ["ctrl-u"] = "preview-half-page-up", - ["tab"] = "down", - ["shift-tab"] = "up", - }, - }, - actions = { - files = { - true, - ["enter"] = fzf_actions.file_edit, - ["ctrl-x"] = fzf_actions.file_split, - }, - }, - }) - fzf.register_ui_select() - - require("which-key").add({ - { "/", pick(function() fzf.live_grep({ cwd = get_root() }) end), desc = "grep" }, - { "ff", pick(function() fzf.files({ cwd = get_root() }) end), desc = "Search for Files" }, - { "fp", pick(fzf.oldfiles), desc = "Oldfiles" }, - { "bf", - pick(function() - fzf.buffers({ sort_lastused = true, ignore_current_buffer = true }) - end), - desc = "Find Buffer" }, - { "?", pick(fzf.command_history), desc = "Command History" }, - { "cm", pick(fzf.manpages), desc = "Manpages" }, - - -- Code - { "gd", - pick(function() - local attached = vim.lsp.get_clients({ bufnr = 0 }) - if next(attached) ~= nil then - fzf.lsp_definitions() - else - vim.api.nvim_feedkeys("gd", "n", false) - end - end), - mode = "n", - desc = "Go to Definition" }, - { "gd", pick(fzf.lsp_definitions), desc = "Go to Definition" }, - { "gr", pick(fzf.lsp_references), desc = "Goto References" }, - { "gi", pick(fzf.lsp_implementations), desc = "Go to Implementations" }, - { "gt", pick(fzf.lsp_typedefs), desc = "Go to Type Definition" }, - { "cv", pick(fzf.lsp_document_symbols), desc = "Document Symbols" }, - { "cd", pick(fzf.diagnostics_workspace), desc = "Code Diagnostics" }, - - -- Git - { "Gt", pick(fzf.git_branches), desc = "Git Branches" }, - { "Gc", pick(fzf.git_commits), desc = "Git Commits" }, - }) - end, - }, -} diff --git a/lua/plugins/gitsigns.lua b/lua/plugins/gitsigns.lua index cfc0fff..b34952f 100644 --- a/lua/plugins/gitsigns.lua +++ b/lua/plugins/gitsigns.lua @@ -2,13 +2,58 @@ return { { "lewis6991/gitsigns.nvim", config = function() - require("gitsigns").setup({ - signcolumn = false, - numhl = true, - }) + require('gitsigns').setup { + signs = { + add = { text = '+' }, + change = { text = '~' }, + delete = { text = '-' }, + topdelete = { text = '‾' }, + changedelete = { text = '~' }, + untracked = { text = '┆' }, + }, + signs_staged = { + add = { text = '+' }, + change = { text = '~' }, + delete = { text = '-' }, + topdelete = { text = '‾' }, + changedelete = { text = '~' }, + untracked = { text = '┆' }, + }, + signs_staged_enable = true, + signcolumn = false, -- Toggle with `:Gitsigns toggle_signs` + numhl = true, -- Toggle with `:Gitsigns toggle_numhl` + linehl = false, -- Toggle with `:Gitsigns toggle_linehl` + word_diff = false, -- Toggle with `:Gitsigns toggle_word_diff` + watch_gitdir = { + follow_files = true + }, + auto_attach = true, + attach_to_untracked = false, + current_line_blame = false, -- Toggle with `:Gitsigns toggle_current_line_blame` + current_line_blame_opts = { + virt_text = true, + virt_text_pos = 'eol', -- 'eol' | 'overlay' | 'right_align' + delay = 0, + ignore_whitespace = false, + virt_text_priority = 100, + }, + current_line_blame_formatter = ', - ', + sign_priority = 6, + update_debounce = 100, + status_formatter = nil, -- Use default + max_file_length = 40000, -- Disable if file is longer than this (in lines) + preview_config = { + -- Options passed to nvim_open_win + border = 'single', + style = 'minimal', + relative = 'cursor', + row = 0, + col = 1 + }, + } require("which-key").add({ - { "Gb", ":Gitsigns toggle_current_line_blame", desc = "Git blame" }, + { "Gb", ":Gitsigns toggle_current_line_blame", desc = "Git blame" } }) - end, - }, + end + } } diff --git a/lua/plugins/lsp.lua b/lua/plugins/lsp.lua index c62fa96..3372cff 100644 --- a/lua/plugins/lsp.lua +++ b/lua/plugins/lsp.lua @@ -23,10 +23,10 @@ local treesitter_parsers = { "rust", "bash", "markdown", - "markdown_inline", "html", "html_tags", "javascript", + "ecma", "jsx", "css", "vim", @@ -198,6 +198,58 @@ return { end }, + { + "hrsh7th/nvim-cmp", + dependencies = { + { + "L3MON4D3/LuaSnip", + version = "v2.*", + build = "make install_jsregexp", + }, + "saadparwaiz1/cmp_luasnip", + "hrsh7th/cmp-nvim-lsp" + }, + + config = function() + local cmp = require("cmp") + cmp.setup({ + enabled = function() + local context = require("cmp.config.context") + if vim.api.nvim_get_mode().mode == "c" then + return true + else + return not context.in_treesitter_capture("comment") and not context.in_syntax_group("comment") + end + end, + + snippet = { + expand = function(args) + require('luasnip').lsp_expand(args.body) + end + }, + + mapping = cmp.mapping.preset.insert({ + [""] = cmp.mapping.select_prev_item(), + [""] = cmp.mapping.select_next_item(), + [""] = cmp.mapping.scroll_docs(-4), + [""] = cmp.mapping.scroll_docs(4), + [""] = cmp.mapping.abort(), + [""] = cmp.mapping.confirm(), + [""] = cmp.mapping(function(fallback) + fallback() + end, { "i", "s" }), + }), + + sources = cmp.config.sources({ + { name = 'nvim_lsp' }, + { name = 'luasnip' }, + }, { + { name = 'buffer' } + }), + }) + end + }, + -- Mason: portable LSP installer. On NixOS this requires nix-ld for -- downloaded Linux binaries to run. { @@ -220,7 +272,7 @@ return { { "neovim/nvim-lspconfig", dependencies = { - "saghen/blink.cmp", + "hrsh7th/cmp-nvim-lsp", }, config = function() local lspconfig = require('lspconfig') @@ -297,12 +349,18 @@ return { local all_servers = get_all_servers() - local capabilities = require('blink.cmp').get_lsp_capabilities() + -- local navic = require('nvim-navic') + local capabilities = require('cmp_nvim_lsp').default_capabilities() -- Global config applied to all servers vim.lsp.config('*', { autostart = false, -- Don't auto-attach, use css to start manually capabilities = capabilities, + -- on_attach = function(client, bufnr) + -- if client.server_capabilities.documentSymbolProvider then + -- navic.attach(client, bufnr) + -- end + -- end, }) -- Server-specific settings (merged with lspconfig defaults) @@ -377,4 +435,12 @@ return { }) end }, + + { + "taproot-wizards/bitcoin-script-hints.nvim", + dependencies = { "nvim-treesitter" }, + config = function() + require("bitcoin-script-hints").setup() + end + } } diff --git a/lua/plugins/lualine.lua b/lua/plugins/lualine.lua new file mode 100644 index 0000000..1c09d05 --- /dev/null +++ b/lua/plugins/lualine.lua @@ -0,0 +1,60 @@ +return { + { + "nvim-lualine/lualine.nvim", + dependencies = { + "nvim-tree/nvim-web-devicons", + "SmiteshP/nvim-navic" + }, + config = function() + require("lualine").setup ({ + options = { + icons_enabled = true, + theme = 'material', + component_separators = { left = '>', right = '|'}, + section_separators = { left = '', right = ''}, + disabled_filetypes = { + statusline = {}, + winbar = {}, + }, + ignore_focus = {}, + always_divide_middle = true, + globalstatus = true, + refresh = { + statusline = 1000, + tabline = 1000, + winbar = 1000, + } + }, + sections = { + lualine_a = {'mode'}, + lualine_b = {'branch', 'diff', 'diagnostics'}, + lualine_c = { + {'filename'}, + { function() return require("nvim-navic").get_location() end, cond = function() + return require("nvim-navic").is_available() + end, + }, + }, + lualine_x = {'filetype'}, + lualine_y = {'progress'}, + lualine_z = {'location'} + }, + inactive_sections = { + lualine_a = {}, + lualine_b = {}, + lualine_c = {}, + lualine_x = {}, + lualine_y = {}, + lualine_z = {} + }, + tabline = {}, + winbar = {}, + inactive_winbar = {}, + extensions = { + 'lazy', + 'neo-tree', + } + }) + end + } +} diff --git a/lua/plugins/neotree.lua b/lua/plugins/neotree.lua new file mode 100644 index 0000000..c7de716 --- /dev/null +++ b/lua/plugins/neotree.lua @@ -0,0 +1,102 @@ +return { + { + "nvim-neo-tree/neo-tree.nvim", + dependencies = { + "nvim-lua/plenary.nvim", + "nvim-tree/nvim-web-devicons", -- not strictly required, but recommended + "MunifTanjim/nui.nvim", + }, + config = function() + require("neo-tree").setup({ + enable_diagnostics = false, + default_component_configs = { + git_status = { + symbols = { + added = "+", + modified = "~", + deleted = "-", + renamed = ">", + untracked = "?", + ignored = "!", + unstaged = "U", + staged = "S", + conflict = "C", + }, + }, + }, + window = { + position = "left", + width = 20, + }, + event_handlers = { + { + event = "neo_tree_window_after_open", + handler = function() + local win = vim.api.nvim_get_current_win() + vim.wo[win].winfixwidth = true + vim.wo[win].winfixbuf = true + vim.wo[win].cursorline = true + end + }, + }, + }) + + -- Keep the selected entry readable without a solid row background. + vim.api.nvim_set_hl(0, "NeoTreeCursorLine", { bg = "NONE", fg = "#a6e3a1" }) + + -- Apply highlight and re-apply on colorscheme change + vim.api.nvim_create_autocmd({ "FileType", "ColorScheme" }, { + pattern = { "neo-tree", "*" }, + callback = function(ev) + if ev.event == "ColorScheme" then + vim.api.nvim_set_hl(0, "NeoTreeCursorLine", { bg = "NONE", fg = "#a6e3a1" }) + end + local win = vim.api.nvim_get_current_win() + local buf = vim.api.nvim_win_get_buf(win) + if vim.bo[buf].filetype == "neo-tree" then + vim.wo[win].winhighlight = "CursorLine:NeoTreeCursorLine" + end + end, + }) + + -- Lock cursor to leftmost column in neo-tree + vim.api.nvim_create_autocmd("CursorMoved", { + pattern = "neo-tree*", + callback = function() + local col = vim.api.nvim_win_get_cursor(0)[2] + if col ~= 0 then + vim.api.nvim_win_set_cursor(0, { vim.api.nvim_win_get_cursor(0)[1], 0 }) + end + end, + }) + + local function toggle_neotree() + local api = vim.api + local bufs = api.nvim_list_bufs() + + for _, buf in ipairs(bufs) do + local name = api.nvim_buf_get_name(buf) + if name:match("neo%-tree filesystem") then + vim.cmd("Neotree close") + return + end + end + + vim.cmd("Neotree") + end + + require("which-key").add({ + { "e", toggle_neotree, desc = "File Explorer" } + }) + + --vim.fn.sign_define("DiagnosticSignError", + -- {text = " ", texthl = "DiagnosticSignError"}) + --vim.fn.sign_define("DiagnosticSignWarn", + -- {text = " ", texthl = "DiagnosticSignWarn"}) + --vim.fn.sign_define("DiagnosticSignInfo", + -- {text = " ", texthl = "DiagnosticSignInfo"}) + --vim.fn.sign_define("DiagnosticSignHint", + -- {text = "󰌵", texthl = "DiagnosticSignHint"}) + end, + }, +} diff --git a/lua/plugins/oil.lua b/lua/plugins/oil.lua deleted file mode 100644 index 4b1e7c1..0000000 --- a/lua/plugins/oil.lua +++ /dev/null @@ -1,29 +0,0 @@ -return { - { - "stevearc/oil.nvim", - dependencies = { "nvim-tree/nvim-web-devicons" }, - lazy = false, - config = function() - local oil = require("oil") - - oil.setup({ - default_file_explorer = true, - skip_confirm_for_simple_edits = true, - view_options = { - show_hidden = true, - }, - float = { - padding = 4, - max_width = 100, - max_height = 30, - border = "rounded", - }, - }) - - require("which-key").add({ - { "-", "Oil", desc = "Open Parent Dir" }, - { "e", oil.toggle_float, desc = "File Explorer" }, - }) - end, - }, -} diff --git a/lua/plugins/render-markdown.lua b/lua/plugins/render-markdown.lua deleted file mode 100644 index 76aaf9f..0000000 --- a/lua/plugins/render-markdown.lua +++ /dev/null @@ -1,17 +0,0 @@ -return { - { - "MeanderingProgrammer/render-markdown.nvim", - ft = { "markdown" }, - dependencies = { - "nvim-treesitter/nvim-treesitter", - "nvim-tree/nvim-web-devicons", - }, - opts = { - enabled = false, - completions = { lsp = { enabled = true } }, - }, - keys = { - { "mr", "RenderMarkdown toggle", desc = "Toggle Markdown Render" }, - }, - }, -} diff --git a/lua/plugins/telescope.lua b/lua/plugins/telescope.lua new file mode 100644 index 0000000..06d1e0c --- /dev/null +++ b/lua/plugins/telescope.lua @@ -0,0 +1,62 @@ +local function get_root() + local result = vim.system({ "git", "rev-parse", "--show-toplevel" }, { text = true }):wait() + if result.code == 0 and result.stdout then + local git_dir = vim.trim(result.stdout) + if git_dir ~= "" then + return git_dir + end + end + + return vim.fn.getcwd() +end + +return { + { + "nvim-telescope/telescope.nvim", + branch = '0.1.x', + dependencies = { + { 'nvim-lua/plenary.nvim' }, + { 'nvim-tree/nvim-web-devicons' } + }, + config = function() + -- Custom Telescope command to grep from Git root + require("which-key").add({ + { "/", function() + require('telescope.builtin').live_grep({ cwd = get_root() }) + end, + desc = "grep" }, + { "ff", function() + require('telescope.builtin').find_files({ cwd = get_root() }) + end, + desc = "Search for Files" }, + { "fp", ":Telescope oldfiles", desc = "Oldfiles" }, + { "?", ":Telescope command_history", desc = "Command History" }, + { "cm", ":Telescope man_pages", desc = "Manpages" }, + + -- Code + { "gd", + function() + local attached = vim.lsp.get_clients({ bufnr = 0 }) + if next(attached) ~= nil then + require('telescope.builtin').lsp_definitions() + else + vim.api.nvim_feedkeys("gd", "n", false) + end + end, + mode = "n", + desc = "Go to Definition" + }, + { "gd", ":Telescope lsp_definitions", desc = "Go to Definition" }, + { "gr", ":Telescope lsp_references", desc = "Goto References" }, + { "gi", ":Telescope lsp_implementations", desc = "Go to Implementations" }, + { "gt", ":Telescope lsp_type_definitions", desc = "Go to Type Definition" }, + { "cv", ":Telescope treesitter", desc = "Function Names & Variables" }, + { "cd", ":Telescope diagnostics", desc = "Code Diagnostics" }, + + -- Git + { "Gt", ":Telescope git_branches", desc = "Git Branches" }, + { "Gc", ":Telescope git_commits", desc = "Git Commits" }, + }) + end + } +} diff --git a/lua/plugins/which-key.lua b/lua/plugins/which-key.lua index 3249172..94aac0a 100644 --- a/lua/plugins/which-key.lua +++ b/lua/plugins/which-key.lua @@ -7,7 +7,7 @@ return { { "l", ":Lazy", desc = "Lazy" }, { "t", function() - vim.cmd("botright new") + vim.cmd.botright("new") vim.opt_local.number = false vim.opt_local.relativenumber = false vim.cmd.resize(10) @@ -28,19 +28,40 @@ return { { "b", group = "Buffers"}, { "bd", function() + local function is_neotree(bufnr) + return vim.bo[bufnr].filetype == "neo-tree" + end + local current_buf = vim.api.nvim_get_current_buf() + + -- Skip if in neo-tree + if is_neotree(current_buf) then + vim.notify("Cannot delete buffer from neo-tree", vim.log.levels.WARN) + return + end local buflisted = vim.fn.getbufinfo({ buflisted = 1 }) + -- Prevent deleting last buffer if #buflisted <= 1 then vim.notify("Cannot delete last buffer", vim.log.levels.WARN) return end vim.cmd.bprevious() vim.cmd.bdelete({ args = { tostring(current_buf) } }) + -- If we ended up in neo-tree, move back to a regular window + local new_buf = vim.api.nvim_get_current_buf() + if is_neotree(new_buf) then + vim.cmd.wincmd("l") + end end, desc = "Delete Buffer" }, { "bD", function() local current_buf = vim.api.nvim_get_current_buf() local current_win = vim.api.nvim_get_current_win() + if vim.bo[current_buf].filetype == "neo-tree" then + vim.notify("Cannot delete neo-tree buffer", vim.log.levels.WARN) + return + end + local wins = vim.fn.win_findbuf(current_buf) if #wins > 1 then vim.api.nvim_win_close(current_win, false) @@ -61,7 +82,6 @@ return { { "G", group = "Git"}, { "f", group = "Files"}, { "c", group = "Code"}, - { "d", group = "Debug"}, { "g", group = "Goto"}, }, },