From f117ced1ddbca4cdf77b828e11840d2f89fa82e2 Mon Sep 17 00:00:00 2001 From: Prad Nukala Date: Fri, 10 Oct 2025 15:11:54 -0400 Subject: [PATCH] refactor(nvim): simplify lazy loading configuration --- CLAUDE.md | 44 ---- devbox.lock | 53 ---- lua/community.lua | 2 +- lua/config/ignore_patterns.lua | 258 +++++++++++++++++++ lua/config/terminals.lua | 89 +++++++ lua/plugins/astrocore.lua | 237 ++---------------- lua/plugins/astrolsp.lua | 397 +++++++++++++++++++++++++++++ lua/plugins/astroui.lua | 197 --------------- lua/plugins/bufferline.lua | 5 +- lua/plugins/explorer.lua | 439 --------------------------------- lua/plugins/mason.lua | 31 --- lua/plugins/neotree.lua | 202 +++++---------- lua/plugins/obsidian.lua | 76 ------ lua/plugins/opencode.lua | 4 + 14 files changed, 827 insertions(+), 1207 deletions(-) delete mode 100644 CLAUDE.md delete mode 100644 devbox.lock create mode 100644 lua/config/ignore_patterns.lua create mode 100644 lua/config/terminals.lua create mode 100644 lua/plugins/astrolsp.lua delete mode 100644 lua/plugins/astroui.lua delete mode 100644 lua/plugins/explorer.lua delete mode 100644 lua/plugins/mason.lua delete mode 100644 lua/plugins/obsidian.lua diff --git a/CLAUDE.md b/CLAUDE.md deleted file mode 100644 index d9f913c..0000000 --- a/CLAUDE.md +++ /dev/null @@ -1,44 +0,0 @@ -# CLAUDE.md - -This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. - -## Overview -This is a Neovim configuration based on AstroNvim v4+ framework. The configuration follows a modular plugin architecture using lazy.nvim as the plugin manager. - -## Commands - -### Neovim Development -- **Install/Update plugins**: Launch Neovim and run `:Lazy` to manage plugins -- **Sync plugins**: `:Lazy sync` to update all plugins -- **Check plugin health**: `:checkhealth` to verify Neovim setup - -### Code Quality Tools -- **Lua linting**: Uses Selene for Lua linting (configured in `selene.toml`) -- **Lua formatting**: Uses Stylua with 120-character line width, 2-space indents (configured in `.stylua.toml`) - -## Architecture - -### Core Structure -The configuration bootstraps lazy.nvim and loads plugins in a specific order: -1. `init.lua` - Entry point that bootstraps lazy.nvim and sets leaders -2. `lua/lazy_setup.lua` - Configures lazy.nvim with AstroNvim and imports -3. `lua/community.lua` - Imports AstroCommunity plugin packs for language support -4. `lua/plugins/` - Custom plugin configurations -5. `lua/polish.lua` - Final configuration applied after all plugins load - -### Plugin Organization -- **Base Framework**: AstroNvim v4 provides the core configuration framework -- **Language Packs**: Imported from AstroCommunity for Go, TypeScript, Markdown, HTML/CSS, etc. -- **Custom Plugins**: Located in `lua/plugins/` directory, each file configures specific functionality: - - `astrocore.lua` - Core settings, keymappings, and autocmds - - `astroui.lua` - UI configuration - - `bufferline.lua` - Buffer/tab management - - `neotree.lua` - File explorer configuration with extensive ignore patterns - - `mason.lua` - LSP server management - - `obsidian.lua` - Note-taking integration - -### Key Configuration Patterns -- The configuration uses environment variables (e.g., `LAZY` for custom lazy.nvim path) -- Defensive programming with pcall() for robust loading across environments -- Shared ignore patterns between neotree and other file explorers to maintain consistency -- Leaders: Space as main leader, comma as local leader \ No newline at end of file diff --git a/devbox.lock b/devbox.lock deleted file mode 100644 index 82b45af..0000000 --- a/devbox.lock +++ /dev/null @@ -1,53 +0,0 @@ -{ - "lockfile_version": "1", - "packages": { - "neovim@latest": { - "last_modified": "2025-02-07T11:26:36Z", - "resolved": "github:NixOS/nixpkgs/d98abf5cf5914e5e4e9d57205e3af55ca90ffc1d#neovim", - "source": "devbox-search", - "version": "0.10.4", - "systems": { - "aarch64-darwin": { - "outputs": [ - { - "name": "out", - "path": "/nix/store/dsn4k9wp16xv1j4b7l0d4liwbk98ya44-neovim-0.10.4", - "default": true - } - ], - "store_path": "/nix/store/dsn4k9wp16xv1j4b7l0d4liwbk98ya44-neovim-0.10.4" - }, - "aarch64-linux": { - "outputs": [ - { - "name": "out", - "path": "/nix/store/mpq2wyqkippwzj8m2lx4qzn01kqjbfa5-neovim-0.10.4", - "default": true - } - ], - "store_path": "/nix/store/mpq2wyqkippwzj8m2lx4qzn01kqjbfa5-neovim-0.10.4" - }, - "x86_64-darwin": { - "outputs": [ - { - "name": "out", - "path": "/nix/store/izwv6gp1la8rcjax5xb8z0k8ws9j8al2-neovim-0.10.4", - "default": true - } - ], - "store_path": "/nix/store/izwv6gp1la8rcjax5xb8z0k8ws9j8al2-neovim-0.10.4" - }, - "x86_64-linux": { - "outputs": [ - { - "name": "out", - "path": "/nix/store/fhzw8ah6s37q2p9pak7d2alzhx0m137h-neovim-0.10.4", - "default": true - } - ], - "store_path": "/nix/store/fhzw8ah6s37q2p9pak7d2alzhx0m137h-neovim-0.10.4" - } - } - } - } -} diff --git a/lua/community.lua b/lua/community.lua index 178d4af..d62cc3c 100644 --- a/lua/community.lua +++ b/lua/community.lua @@ -6,7 +6,7 @@ return { "AstroNvim/astrocommunity", version = false, -- Use latest astrocommunity - { import = "astrocommunity.ai.oopencode-nvim" }, + { import = "astrocommunity.ai.opencode-nvim" }, { import = "astrocommunity.pack.astro" }, { import = "astrocommunity.pack.bash" }, { import = "astrocommunity.pack.biome" }, diff --git a/lua/config/ignore_patterns.lua b/lua/config/ignore_patterns.lua new file mode 100644 index 0000000..038fb09 --- /dev/null +++ b/lua/config/ignore_patterns.lua @@ -0,0 +1,258 @@ +--- Shared ignore patterns for file explorers and pickers +--- This module provides a centralized list of patterns to ignore across +--- neotree, telescope, snacks.picker, and other file browsing tools. +--- @module config.ignore_patterns + +local M = {} + +--- Core ignore patterns used across the configuration +--- These patterns use glob syntax (* for wildcards) +M.patterns = { + -- Build artifacts and generated files + "chain_*.json", + "*.pb.go", + "*.pkl.go", + "*.pulsar.go", + "*.pb.gorm.go", + "*.pb.gw.go", + "*_templ.go", + "*_mock.go", + "*_integration.go", + "*_test.go", + + -- Configuration files + "*config.*.js", + "*config.js", + "deps.mjs", + ".parcelrc", + "worker-configuration.d.ts", + "wrangler.jsonc", + "biome*", + ".cz.toml", + ".editorconfig", + ".gitpod.*", + "cspell.*", + + -- Documentation + "*_query_docs.md", + "*_tx_docs.md", + "readme.md", + "CLAUDE*", + + -- Lock files and dependencies + "*.lock", + "*.lockb", + "*.sum", + "*.work.*", + "package-lock.json", + "pnpm-lock.yaml", + + -- Temporary and cache files + "*.tmp", + ".typecopy", + ".python-version", + ".prettierrc", + ".trunk", + ".config", + ".pkl-lsp", + ".tsbuildinfo", + ".wrangler", + ".parcel-cache", + ".aider.tags.cache.v4", + ".aider.tags.cache.v3", + ".aider.chat.history.md", + ".aider.input.history", + ".conform*", + ".null-ls_*", + + -- Binary and media files + "*.wasm", + "*.png", + "*.jpg", + "*.icns", + "*.ico", + + -- Directories and special files + "contrib", + "interchaintest", + "PULL_REQUEST_TEMPLATE.md", + "Icon?", + "iCloud~", + "com~", +} + +--- Patterns that should never be shown in any file browser +M.never_show = { + -- Version control + ".git", + + -- Dependencies + "node_modules", + + -- Build outputs + ".next", + ".parcel-cache", + + -- Task runners and tools + ".task", + ".devbox", + ".turbo", + ".jj", + ".spawn", + + -- IDE and editor + ".idea", + ".venv", + ".metadata", + ".dart_tool", + ".devcontainer", + + -- Build tools + ".gradle", + "gradle.bat", + "heighliner", + + -- Temporary + ".tmp", + "tmp", + + -- Logs + "sonr.log", + "junit.xml", + + -- macOS + ".DS_Store", + ".DocumentRevisions-V100", + ".Spotlight-V100", + ".TemporaryItems", + ".Trashes", + ".fseventsd", + ".timemachine", + + -- Templates + "DISCUSSION_TEMPLATE", + "ISSUE_TEMPLATE", + + -- License + "LICENSE", +} + +--- Patterns that should never be shown (pattern matching) +M.never_show_patterns = { + "*DS_Store", + ".obsidian", + ".pkl-lsp", + ".tsbuildinfo", + "package-lock.json", + ".prettierrc", + "node_modules", + ".DocumentRevisions-V100", + ".Spotlight-V100", + ".TemporaryItems", + ".Trashes", + ".fseventsd", + ".editorconfig", + "*.min.js", + "*.lock", + "*lock*", + "*.lockb", + "*.pulsar.go", + "*.pb.gorm.go", + "*.pb.gw.go", + "*_templ.go", + "*.tmp", + "*.work.*", + "*.sum", + ".parcel-cache", + "*.icns", + "*.ico", + ".aider.tags.cache.v4", + "*.iml", + "Icon?", + "iCloud~", + "com~", + "*.icns", + ".conform*", + ".null-ls_*", +} + +--- Directories to ignore when filtering files +M.ignored_directories = { + "contracts", + "crypto", + "api", + "chains", + "test", + "examples", + "scripts", + "bridge", + "client", + "translations", + "env", + ".husky", +} + +--- Read additional ignore patterns from .rgignore file in git root +--- @return table patterns List of patterns from .rgignore +function M.read_rgignore() + local patterns = {} + local current_file = vim.fn.expand("%:p") + local current_dir = vim.fn.fnamemodify(current_file, ":h") + + if current_dir == "" then current_dir = vim.fn.getcwd() end + + local git_root = + vim.fn.systemlist("cd " .. vim.fn.shellescape(current_dir) .. " && git rev-parse --show-toplevel 2>/dev/null")[1] + + if git_root and git_root ~= "" and not git_root:match("^fatal:") then + local rgignore_path = git_root .. "/.rgignore" + local file = io.open(rgignore_path, "r") + + if file then + for line in file:lines() do + if line ~= "" and not line:match("^#") then + line = line:gsub("^%./", "") + table.insert(patterns, line) + end + end + file:close() + end + end + + return patterns +end + +--- Get all hide patterns including rgignore +--- @return table patterns Combined list of all patterns to hide +function M.get_all_patterns() + local rgignore_patterns = M.read_rgignore() + return vim.list_extend(vim.list_extend({}, M.patterns), rgignore_patterns) +end + +--- Create a file filter function for pickers +--- @return function filter Function that filters files based on ignore patterns +function M.create_picker_filter() + return function(item) + if not item or not item.file then return item end + + local file = item.file + local basename = vim.fn.fnamemodify(file, ":t") + local dir = vim.fn.fnamemodify(file, ":h:t") + + -- Check against all patterns + local all_patterns = M.get_all_patterns() + for _, pattern in ipairs(all_patterns) do + local lua_pattern = pattern:gsub("%.", "%%."):gsub("%*", ".*"):gsub("%?", ".") + if basename:match("^" .. lua_pattern .. "$") or file:match(lua_pattern) then return nil end + end + + -- Check ignored directories + for _, ignored in ipairs(M.ignored_directories) do + if dir == ignored or file:match("/" .. ignored .. "/") then return nil end + end + + return item + end +end + +return M diff --git a/lua/config/terminals.lua b/lua/config/terminals.lua new file mode 100644 index 0000000..99a632d --- /dev/null +++ b/lua/config/terminals.lua @@ -0,0 +1,89 @@ +--- Terminal configurations using toggleterm +--- This module provides terminal toggle functions for various CLI tools +--- @module config.terminals + +local M = {} + +--- Check if toggleterm is available +--- @return boolean available Whether toggleterm is loaded +local function is_toggleterm_available() + local ok, _ = pcall(require, "toggleterm.terminal") + return ok +end + +--- Initialize all terminal configurations +--- Only runs if toggleterm is available +function M.setup() + if not is_toggleterm_available() then + vim.notify("toggleterm not available, skipping terminal setup", vim.log.levels.WARN) + return + end + + local Terminal = require("toggleterm.terminal").Terminal + + -- Claude terminal configuration + local claude = Terminal:new({ + cmd = "claude", + hidden = true, + direction = "tab", + close_on_exit = true, + on_open = function(term) + vim.cmd("startinsert!") + vim.api.nvim_buf_set_keymap(term.bufnr, "n", "q", "close", { noremap = true, silent = true }) + end, + }) + + -- Yazi file manager terminal + local yazi = Terminal:new({ + cmd = "yazi", + hidden = true, + direction = "tab", + close_on_exit = true, + on_open = function(term) + vim.cmd("startinsert!") + vim.api.nvim_buf_set_keymap(term.bufnr, "n", "q", "close", { noremap = true, silent = true }) + end, + }) + + -- Scooter find and replace terminal + local scooter = Terminal:new({ + cmd = "scooter", + hidden = true, + direction = "vertical", + on_open = function(term) + vim.cmd("startinsert!") + vim.api.nvim_buf_set_keymap(term.bufnr, "n", "q", "close", { noremap = true, silent = true }) + end, + }) + + -- Lazyjournal terminal + local lazyjournal = Terminal:new({ + cmd = "lazyjournal", + hidden = true, + direction = "float", + on_open = function(term) + vim.cmd("startinsert!") + vim.api.nvim_buf_set_keymap(term.bufnr, "n", "q", "close", { noremap = true, silent = true }) + end, + }) + + -- Mk (make) terminal + local mk = Terminal:new({ + cmd = "mk", + hidden = true, + direction = "vertical", + on_open = function(term) + vim.cmd("startinsert!") + vim.api.nvim_buf_set_keymap(term.bufnr, "n", "q", "close", { noremap = true, silent = true }) + end, + }) + + -- Export toggle functions to module instead of global namespace + M.claude_toggle = function() claude:toggle() end + M.yazi_toggle = function() yazi:toggle() end + M.scooter_toggle = function() scooter:toggle() end + M.lazyjournal_toggle = function() lazyjournal:toggle() end + M.mk_toggle = function() mk:toggle() end +end + +return M diff --git a/lua/plugins/astrocore.lua b/lua/plugins/astrocore.lua index c14bf94..78ed221 100644 --- a/lua/plugins/astrocore.lua +++ b/lua/plugins/astrocore.lua @@ -1,206 +1,16 @@ -local Terminal = require("toggleterm.terminal").Terminal +--- AstroCore configuration +--- Core settings, keymappings, and autocmds for AstroNvim +--- @module plugins.astrocore --- Shared ignore patterns from neotree configuration -local ignore_patterns = { - -- Hidden patterns - "chain_*.json", - ".typecopy", - ".python-version", - "*.pb.go", - "*config.*.js", - "*config.js", - "deps.mjs", - ".parcelrc", - "worker-configuration.d.ts", - "wrangler.jsonc", - "*.pkl.go", - ".trunk", - ".config", - ".cz.toml", - "*_integration.go", - "*_test.go", - "*_query_docs.md", - "*_tx_docs.md", - "*_mock.go", - "biome*", - -- Never show patterns - "CLAUDE*", - ".pkl-lsp", - ".tsbuildinfo", - "contrib", - "interchaintest", - "package-lock.json", - ".prettierrc", - "node_modules", - "PULL_REQUEST_TEMPLATE.md", - ".DocumentRevisions-V100", - ".Spotlight-V100", - ".TemporaryItems", - ".Trashes", - ".fseventsd", - ".editorconfig", - "*.min.js", - ".gitpod.*", - "cspell.*", - "*.lock", - "*.lockb", - "*.pulsar.go", - "*.pb.gorm.go", - "*.pb.gw.go", - "*_templ.go", - "*.tmp", - "*.work.*", - "*.sum", - ".wrangler", - "*.wasm", - "*.png", - "*.jpg", - ".parcel-cache", - "*.icns", - "*.ico", - ".aider.tags.cache.v4", - "*.iml", - "Icon?", - "iCloud~", - "com~", - "readme.md", - ".conform*", - ".null-ls_*", - -- Additional never show items - ".git", - "pnpm-lock.yaml", - ".next", - ".task", - ".devbox", - ".dart_tool", - ".idea", - ".metadata", - ".venv", - ".gradle", - "gradle.bat", - ".aider.chat.history.md", - ".aider.input.history", - ".aider.tags.cache.v3", - ".devcontainer", - "heighliner", - ".tmp", - "go.work.sum", - ".DS_Store", - "LICENSE", - "tmp", - "sonr.log", - "DISCUSSION_TEMPLATE", - "ISSUE_TEMPLATE", - ".timemachine", - "junit.xml", - ".jj", - ".spawn", - ".turbo", -} +-- Import shared modules +local ignore_patterns = require("config.ignore_patterns") +local terminals = require("config.terminals") --- Create a custom transform function to filter out ignored files -local function create_file_filter() - return function(item) - if not item or not item.file then return item end +-- Initialize terminals +terminals.setup() - local file = item.file - local basename = vim.fn.fnamemodify(file, ":t") - local dir = vim.fn.fnamemodify(file, ":h:t") - - -- Check each ignore pattern - for _, pattern in ipairs(ignore_patterns) do - -- Convert glob pattern to Lua pattern - local lua_pattern = pattern:gsub("%.", "%%."):gsub("%*", ".*"):gsub("%?", ".") - - -- Check if the pattern matches the basename or path - if basename:match("^" .. lua_pattern .. "$") or file:match(lua_pattern) then - return nil -- Filter out this item - end - end - - -- Also filter out specific directory names - local ignored_dirs = { - "contracts", - "crypto", - "api", - "chains", - "test", - "examples", - "scripts", - "bridge", - "client", - "translations", - "env", - ".husky", - } - - for _, ignored in ipairs(ignored_dirs) do - if dir == ignored or file:match("/" .. ignored .. "/") then return nil end - end - - return item - end -end - -local file_filter = create_file_filter() - -local claude = Terminal:new { - cmd = "claude", - hidden = true, - direction = "tab", - close_on_exit = true, -- function to run on opening the terminal - on_open = function(term) - vim.cmd "startinsert!" - vim.api.nvim_buf_set_keymap(term.bufnr, "n", "q", "close", { noremap = true, silent = true }) - end, -} -local yazi = Terminal:new { - cmd = "yazi", - hidden = true, - direction = "tab", - close_on_exit = true, -- function to run on opening the terminal - on_open = function(term) - vim.cmd "startinsert!" - vim.api.nvim_buf_set_keymap(term.bufnr, "n", "q", "close", { noremap = true, silent = true }) - end, -} - -local scooter = Terminal:new { - cmd = "scooter", - hidden = true, - direction = "vertical", -- function to run on opening the terminal - on_open = function(term) - vim.cmd "startinsert!" - vim.api.nvim_buf_set_keymap(term.bufnr, "n", "q", "close", { noremap = true, silent = true }) - end, -} - -local lazyjournal = Terminal:new { - cmd = "lazyjournal", - hidden = true, - direction = "float", -- function to run on opening the terminal - on_open = function(term) - vim.cmd "startinsert!" - vim.api.nvim_buf_set_keymap(term.bufnr, "n", "q", "close", { noremap = true, silent = true }) - end, -} - -local mk = Terminal:new { - cmd = "mk", - hidden = true, - direction = "vertical", -- function to run on opening the terminal - on_open = function(term) - vim.cmd "startinsert!" - vim.api.nvim_buf_set_keymap(term.bufnr, "n", "q", "close", { noremap = true, silent = true }) - end, -} - --- Toggle Functions (global so they can be used in other files) -function _G.Claude_toggle() claude:toggle() end -function _G.Lazyjournal_toggle() lazyjournal:toggle() end -function _G.Mk_toggle() mk:toggle() end -function _G.Scooter_toggle() scooter:toggle() end -function _G.Yazi_toggle() yazi:toggle() end +-- Get file filter for pickers +local file_filter = ignore_patterns.create_picker_filter() return { "AstroNvim/astrocore", @@ -363,12 +173,10 @@ return { function() require("snacks").picker.git_branches() end, desc = "Search git branches", }, - ["K"] = { function() vim.diagnostic.goto_prev() end, desc = "Previous Diagnostic" }, - ["J"] = { function() vim.diagnostic.goto_next() end, desc = "Next Diagnostic" }, ["vv"] = { "gg0VG$", desc = "Select all contents in buffer" }, ["T"] = { "gg", desc = "Go to top of file" }, ["r"] = { - _G.Scooter_toggle, + terminals.scooter_toggle, desc = "Find and replace", }, ["d"] = { @@ -591,29 +399,12 @@ return { end, desc = "Find Service files", }, - ["a"] = { function() vim.lsp.buf.code_action() end, desc = "LSP Code Action" }, - ["c"] = { _G.Claude_toggle, desc = "Claude Toggle" }, - ["h"] = { function() vim.lsp.buf.hover() end, desc = "LSP Hover" }, - ["r"] = { - function() return ":IncRename " .. vim.fn.expand "" end, - expr = true, - desc = "Rename current symbol", - cond = "textDocument/rename", - }, - ["d"] = { - function() require("snacks").picker.diagnostics() end, - desc = "Find LSP diagnostics", - }, - ["s"] = { - function() require("snacks").picker.lsp_symbols() end, - desc = "Find LSP symbols", - }, - -- Terminal launcher + -- AI/Assistant mappings + ["c"] = { terminals.claude_toggle, desc = "Claude Toggle" }, }, i = { - [""] = { "w", desc = "Save current buffer and return to normal mode", noremap = true }, [""] = { "wabd", desc = "Save, close buffer, and return to normal mode" }, - [""] = { "wabd", desc = "Save, close buffer, and return to normal mode" }, -- Added C-x for insert mode + [""] = { "wabd", desc = "Save, close buffer, and return to normal mode" }, -- Added C-x for insert mode }, v = { [""] = { "Neotree toggle", desc = "Open Explorer" }, diff --git a/lua/plugins/astrolsp.lua b/lua/plugins/astrolsp.lua new file mode 100644 index 0000000..e201cd7 --- /dev/null +++ b/lua/plugins/astrolsp.lua @@ -0,0 +1,397 @@ +--- AstroLSP configuration optimized for tech stack: +--- - Cloudflare Workers/Pages +--- - Golang (Cosmos SDK) +--- - TypeScript/React/Vite +--- - Protobufs +--- - Bun/ES Modules/WASM +--- @module plugins.astrolsp + +return { + "AstroNvim/astrolsp", + ---@type AstroLSPOpts + opts = { + -- Enable LSP features + features = { + autoformat = true, + codelens = true, + inlay_hints = true, -- Enable inlay hints for TS/Go + lsp_handlers = true, + semantic_tokens = true, + }, + + -- LSP UI defaults + defaults = { + hover = { border = "rounded", silent = true }, -- Rounded border for hover windows + signature_help = { border = "rounded", silent = true }, -- Enable signature help + }, + + -- LSP client flags + flags = { + exit_timeout = 5000, -- Time to wait for LSP server to exit before force kill + debounce_text_changes = 150, -- Debounce didChange notifications + }, + + -- LSP Formatting Configuration + formatting = { + format_on_save = { + enabled = true, + -- Allow specific filetypes (prefer conform.nvim for JS/TS) + allow_filetypes = { + "go", + "proto", + "toml", + "lua", + }, + }, + -- Disable LSP formatting for these (use conform.nvim/biome instead) + disabled = { + "tsserver", -- Use biome/prettier via conform + "vtsls", -- Use biome/prettier via conform + "eslint", -- Diagnostics only, not formatting + "html", -- Use conform + "cssls", -- Use conform + "tailwindcss", -- Doesn't format + }, + timeout_ms = 5000, -- Increase timeout for large Go files + filter = function(client) + -- Prefer conform.nvim for JS/TS formatting + if vim.bo.filetype == "typescript" or vim.bo.filetype == "javascript" or vim.bo.filetype == "typescriptreact" or vim.bo.filetype == "javascriptreact" then + return false + end + -- Use gopls for Go formatting + if vim.bo.filetype == "go" then + return client.name == "gopls" + end + return true + end, + }, + + -- Enable file operations for better refactoring + file_operations = { + timeout = 10000, + operations = { + willCreate = true, + didCreate = true, + willRename = true, + didRename = true, + willDelete = true, + didDelete = true, + }, + }, + + -- Language server configurations + config = { + -- Golang configuration optimized for Cosmos SDK + gopls = { + settings = { + gopls = { + -- Code analysis + analyses = { + unusedparams = true, + shadow = true, + nilness = true, + unusedwrite = true, + useany = true, + unusedvariable = true, + }, + -- Staticcheck integration + staticcheck = true, + -- Inlay hints + hints = { + assignVariableTypes = true, + compositeLiteralFields = true, + compositeLiteralTypes = true, + constantValues = true, + functionTypeParameters = true, + parameterNames = true, + rangeVariableTypes = true, + }, + -- Code completion + usePlaceholders = true, + completeUnimported = true, + -- Build flags for Cosmos SDK + buildFlags = { "-tags=ledger,test" }, + -- Workspace settings + directoryFilters = { + "-**/node_modules", + "-**/.git", + "-**/.vscode", + "-**/.idea", + "-**/.devbox", + "-**/dist", + "-**/build", + }, + -- Semantic tokens + semanticTokens = true, + -- Code lenses + codelenses = { + gc_details = true, + generate = true, + regenerate_cgo = true, + test = true, + tidy = true, + upgrade_dependency = true, + vendor = true, + }, + }, + }, + }, + + -- TypeScript configuration for Vite/React/Cloudflare + tsserver = { + settings = { + typescript = { + inlayHints = { + includeInlayParameterNameHints = "all", + includeInlayParameterNameHintsWhenArgumentMatchesName = true, + includeInlayFunctionParameterTypeHints = true, + includeInlayVariableTypeHints = true, + includeInlayVariableTypeHintsWhenTypeMatchesName = true, + includeInlayPropertyDeclarationTypeHints = true, + includeInlayFunctionLikeReturnTypeHints = true, + includeInlayEnumMemberValueHints = true, + }, + suggest = { + completeFunctionCalls = true, + }, + -- Cloudflare Workers types + preferences = { + importModuleSpecifier = "relative", + importModuleSpecifierEnding = "minimal", + }, + }, + javascript = { + inlayHints = { + includeInlayParameterNameHints = "all", + includeInlayParameterNameHintsWhenArgumentMatchesName = true, + includeInlayFunctionParameterTypeHints = true, + includeInlayVariableTypeHints = true, + includeInlayPropertyDeclarationTypeHints = true, + includeInlayFunctionLikeReturnTypeHints = true, + includeInlayEnumMemberValueHints = true, + }, + suggest = { + completeFunctionCalls = true, + }, + }, + }, + }, + + -- ESLint configuration + eslint = { + settings = { + workingDirectories = { mode = "auto" }, + format = false, -- Don't use ESLint for formatting + }, + on_attach = function(client, bufnr) + -- Disable formatting capability (use conform.nvim) + client.server_capabilities.documentFormattingProvider = false + client.server_capabilities.documentRangeFormattingProvider = false + end, + }, + + -- Tailwind for React components + tailwindcss = { + settings = { + tailwindCSS = { + experimental = { + classRegex = { + -- Support for cn() and clsx() utilities + { "cn\\(([^)]*)\\)", "[\"'`]([^\"'`]*).*?[\"'`]" }, + { "clsx\\(([^)]*)\\)", "[\"'`]([^\"'`]*).*?[\"'`]" }, + { "cva\\(([^)]*)\\)", "[\"'`]([^\"'`]*).*?[\"'`]" }, + }, + }, + validate = true, + lint = { + cssConflict = "warning", + invalidApply = "error", + invalidScreen = "error", + invalidVariant = "error", + invalidConfigPath = "error", + invalidTailwindDirective = "error", + recommendedVariantOrder = "warning", + }, + }, + }, + }, + + -- HTML for React/templates + html = { + settings = { + html = { + format = { + templating = true, + wrapLineLength = 100, + wrapAttributes = "auto", + }, + hover = { + documentation = true, + references = true, + }, + }, + }, + }, + + -- Protobuf LSP + bufls = { + settings = { + -- Add any buf-specific settings + }, + }, + + -- JSON/JSONC for config files + jsonls = { + settings = { + json = { + schemas = { + -- Cloudflare wrangler.toml + { + fileMatch = { "wrangler.toml", "wrangler.json" }, + url = "https://raw.githubusercontent.com/cloudflare/wrangler/main/wrangler-schema.json", + }, + -- Package.json + { + fileMatch = { "package.json" }, + url = "https://json.schemastore.org/package.json", + }, + -- tsconfig.json + { + fileMatch = { "tsconfig.json", "tsconfig.*.json" }, + url = "https://json.schemastore.org/tsconfig.json", + }, + }, + validate = { enable = true }, + }, + }, + }, + + -- YAML for configs + yamlls = { + settings = { + yaml = { + schemaStore = { + enable = true, + url = "https://www.schemastore.org/api/json/catalog.json", + }, + schemas = { + ["https://json.schemastore.org/github-workflow.json"] = ".github/workflows/*.yml", + ["https://raw.githubusercontent.com/compose-spec/compose-spec/master/schema/compose-spec.json"] = "docker-compose*.yml", + }, + validate = true, + hover = true, + completion = true, + }, + }, + }, + + -- Lua for Neovim config + lua_ls = { + settings = { + Lua = { + hint = { + enable = true, + arrayIndex = "Auto", + setType = true, + }, + }, + }, + }, + }, + + -- Capabilities configuration + capabilities = { + textDocument = { + completion = { + completionItem = { + documentationFormat = { "markdown", "plaintext" }, + snippetSupport = true, + preselectSupport = true, + insertReplaceSupport = true, + labelDetailsSupport = true, + deprecatedSupport = true, + commitCharactersSupport = true, + tagSupport = { valueSet = { 1 } }, + resolveSupport = { + properties = { + "documentation", + "detail", + "additionalTextEdits", + }, + }, + }, + }, + }, + }, + + -- LSP-specific keymappings (keeping existing bindings) + mappings = { + n = { + -- LSP Code Actions + ["a"] = { + function() vim.lsp.buf.code_action() end, + desc = "LSP Code Action", + }, + + -- LSP Hover + ["h"] = { + function() vim.lsp.buf.hover() end, + desc = "LSP Hover", + }, + + -- LSP Rename (using inc-rename plugin) + ["r"] = { + function() return ":IncRename " .. vim.fn.expand("") end, + expr = true, + desc = "Rename current symbol", + cond = "textDocument/rename", + }, + + -- LSP Diagnostics (using snacks.picker) + ["d"] = { + function() require("snacks").picker.diagnostics() end, + desc = "Find LSP diagnostics", + }, + + -- LSP Symbols (using snacks.picker) + ["s"] = { + function() require("snacks").picker.lsp_symbols() end, + desc = "Find LSP symbols", + }, + + -- Navigate diagnostics + K = { + function() vim.diagnostic.goto_prev() end, + desc = "Previous Diagnostic", + }, + J = { + function() vim.diagnostic.goto_next() end, + desc = "Next Diagnostic", + }, + }, + }, + + -- Autocmds for LSP-specific behavior + autocmds = { + -- Disable inlay hints in insert mode for cleaner editing + no_insert_inlay_hints = { + cond = vim.lsp.inlay_hint and "textDocument/inlayHint" or false, + { + event = "InsertEnter", + desc = "Disable inlay hints on insert", + callback = function(args) + local filter = { bufnr = args.buf } + if vim.lsp.inlay_hint.is_enabled(filter) then + vim.lsp.inlay_hint.enable(false, filter) + vim.api.nvim_create_autocmd("InsertLeave", { + buffer = args.buf, + once = true, + callback = function() vim.lsp.inlay_hint.enable(true, filter) end, + }) + end + end, + }, + }, + }, + }, +} diff --git a/lua/plugins/astroui.lua b/lua/plugins/astroui.lua deleted file mode 100644 index 0271b1e..0000000 --- a/lua/plugins/astroui.lua +++ /dev/null @@ -1,197 +0,0 @@ -return { - { - "AstroNvim/astroui", - ---@type AstroUIOpts - opts = { - colorscheme = "cyberdream", - -- add new user interface icon - icons = { - VimIcon = "", - ScrollText = "", - GitBranch = "", - GitAdd = "", - GitChange = "", - GitDelete = "", - }, - -- modify variables used by heirline but not defined in the setup call directly - status = { - -- define the separators between each section - separators = { - left = { "", "" }, -- separator for the left side of the statusline - right = { "", "" }, -- separator for the right side of the statusline - tab = { "", "" }, - }, - -- add new colors that can be used by heirline - colors = function(hl) - local get_hlgroup = require("astroui").get_hlgroup - -- use helper function to get highlight group properties - local comment_fg = get_hlgroup("Comment").fg - hl.git_branch_fg = comment_fg - hl.git_added = comment_fg - hl.git_changed = comment_fg - hl.git_removed = comment_fg - hl.blank_bg = get_hlgroup("Folded").fg - hl.file_info_bg = get_hlgroup("Visual").bg - hl.nav_icon_bg = get_hlgroup("String").fg - hl.nav_fg = hl.nav_icon_bg - hl.folder_icon_bg = get_hlgroup("Error").fg - return hl - end, - attributes = { - mode = { bold = true }, - }, - icon_highlights = { - file_icon = { - statusline = false, - }, - }, - }, - }, - }, - { - "rebelot/heirline.nvim", - opts = function(_, opts) - local status = require "astroui.status" - -- Disable heirline's tabline since we're using bufferline - opts.tabline = nil - opts.statusline = { - -- default highlight for the entire statusline - hl = { fg = "fg", bg = "bg" }, - -- each element following is a component in astroui.status module - - -- add the vim mode component - status.component.mode { - -- enable mode text with padding as well as an icon before it - mode_text = { - icon = { kind = "VimIcon", padding = { right = 1, left = 1 } }, - }, - -- surround the component with a separators - surround = { - -- it's a left element, so use the left separator - separator = "left", - -- set the color of the surrounding based on the current mode using astronvim.utils.status module - color = function() return { main = status.hl.mode_bg(), right = "blank_bg" } end, - }, - }, - -- we want an empty space here so we can use the component builder to make a new section with just an empty string - status.component.builder { - { provider = "" }, - -- define the surrounding separator and colors to be used inside of the component - -- and the color to the right of the separated out section - surround = { - separator = "left", - color = { main = "blank_bg", right = "file_info_bg" }, - }, - }, - -- add a section for the currently opened file information - status.component.file_info { - -- enable the file_icon and disable the highlighting based on filetype - filename = { fallback = "Empty" }, - -- disable some of the info - filetype = false, - file_read_only = false, - -- add padding - padding = { right = 1 }, - -- define the section separator - surround = { separator = "left", condition = false }, - }, - -- add a component for the current git branch if it exists and use no separator for the sections - status.component.git_branch { - git_branch = { padding = { left = 1 } }, - surround = { separator = "none" }, - }, - -- add a component for the current git diff if it exists and use no separator for the sections - status.component.git_diff { - padding = { left = 1 }, - surround = { separator = "none" }, - }, - -- fill the rest of the statusline - -- the elements after this will appear in the middle of the statusline - status.component.fill(), - -- add a component to display if the LSP is loading, disable showing running client names, and use no separator - status.component.lsp { - lsp_client_names = false, - surround = { separator = "none", color = "bg" }, - }, - -- fill the rest of the statusline - -- the elements after this will appear on the right of the statusline - status.component.fill(), - -- add a component for the current diagnostics if it exists and use the right separator for the section - status.component.diagnostics { surround = { separator = "right" }, padding = { right = 1 } }, - -- add a component to display LSP clients, disable showing LSP progress, and use the right separator - status.component.lsp { - lsp_progress = false, - padding = { right = 1 }, - surround = { separator = "right" }, - }, - -- NvChad has some nice icons to go along with information, so we can create a parent component to do this - -- all of the children of this table will be treated together as a single component - { - flexible = 1, - { - -- define a simple component where the provider is just a folder icon - status.component.builder { - -- astronvim.get_icon gets the user interface icon for a closed folder with a space after it - { provider = require("astroui").get_icon "FolderClosed" }, - -- add padding after icon - padding = { right = 1 }, - -- set the foreground color to be used for the icon - hl = { fg = "bg" }, - -- use the right separator and define the background color - surround = { separator = "right", color = "folder_icon_bg" }, - }, - -- add a file information component and only show the current working directory name - status.component.file_info { - -- we only want filename to be used and we can change the fname - -- function to get the current working directory name - filename = { - fname = function(nr) return vim.fn.getcwd(nr) end, - padding = { left = 1, right = 1 }, - }, - -- disable all other elements of the file_info component - filetype = false, - file_icon = false, - file_modified = false, - file_read_only = false, - -- use no separator for this part but define a background color - surround = { - separator = "none", - color = "file_info_bg", - condition = false, - }, - }, - }, - {}, - }, - -- the final component of the NvChad statusline is the navigation section - -- this is very similar to the previous current working directory section with the icon - { -- make nav section with icon border - -- define a custom component with just a file icon - status.component.builder { - { provider = require("astroui").get_icon "ScrollText" }, - -- add padding after icon - padding = { right = 1 }, - -- set the icon foreground - hl = { fg = "bg" }, - -- use the right separator and define the background color - -- as well as the color to the left of the separator - surround = { - separator = "right", - color = { main = "nav_icon_bg", left = "file_info_bg" }, - }, - }, - -- add a navigation component and just display the percentage of progress in the file - status.component.nav { - -- add some padding for the percentage provider - percentage = { padding = { right = 1 } }, - -- disable all other providers - ruler = false, - scrollbar = false, - -- use no separator and define the background color - surround = { separator = "none", color = "file_info_bg" }, - }, - }, - } - end, - }, -} diff --git a/lua/plugins/bufferline.lua b/lua/plugins/bufferline.lua index ed46851..d997ecc 100644 --- a/lua/plugins/bufferline.lua +++ b/lua/plugins/bufferline.lua @@ -1,4 +1,7 @@ --- Bufferline configuration with AstroNvim integration +--- Bufferline configuration with AstroNvim integration +--- Provides enhanced buffer/tab management with diagnostics and custom close handlers +--- @module plugins.bufferline + return { "akinsho/bufferline.nvim", version = "*", diff --git a/lua/plugins/explorer.lua b/lua/plugins/explorer.lua deleted file mode 100644 index 220746c..0000000 --- a/lua/plugins/explorer.lua +++ /dev/null @@ -1,439 +0,0 @@ --- Function to read patterns from .rgignore file -local function read_rgignore_patterns() - local patterns = {} - local git_root = vim.fn.systemlist("git rev-parse --show-toplevel")[1] - - if git_root and git_root ~= "" then - local rgignore_path = git_root .. "/.rgignore" - local file = io.open(rgignore_path, "r") - - if file then - for line in file:lines() do - -- Skip comments and empty lines - if line ~= "" and not line:match "^#" then - -- Remove leading ./ if present - line = line:gsub("^%./", "") - -- Add the pattern - table.insert(patterns, line) - end - end - file:close() - end - end - - return patterns -end - --- Build exclude patterns for snacks.explorer -local function build_exclude_patterns() - -- Get patterns from .rgignore - local rgignore_patterns = read_rgignore_patterns() - - -- Default hide patterns (from original neotree config) - local hide_patterns = { - "chain_*.json", - "Library", - ".typecopy", - ".python-version", - "*.pb.go", - "*config.*.js", - "*config.js", - "deps.mjs", - ".parcelrc", - "worker-configuration.d.ts", - "wrangler.jsonc", - "*.pkl.go", - ".trunk", - ".config", - ".cz.toml", - "*_mock.go", - } - - -- Never show by pattern (from original neotree config) - local never_show_by_pattern = { - "*DS_Store", - ".obsidian", - ".pkl-lsp", - ".tsbuildinfo", - "package-lock.json", - ".prettierrc", - "node_modules", - ".DocumentRevisions-V100", - ".Spotlight-V100", - ".TemporaryItems", - ".Trashes", - ".fseventsd", - ".editorconfig", - "*.min.js", - "*.lock", - "*lock*", - "*.lockb", - "*.pulsar.go", - "*.pb.gorm.go", - "*.pb.gw.go", - "*_templ.go", - "*.tmp", - "*.work.*", - "*.sum", - ".parcel-cache", - "*.icns", - "*.ico", - ".aider.tags.cache.v4", - "*.iml", - "Icon?", - "iCloud~", - "com~", - "*.icns", - ".conform*", - ".null-ls_*", - } - - -- Never show directories (from original neotree config) - local never_show = { - ".git", - "pnpm-lock.yaml", - ".next", - ".task", - ".devbox", - ".dart_tool", - ".idea", - ".metadata", - ".venv", - ".gradle", - "gradle.bat", - ".aider.chat.history.md", - ".aider.input.history", - ".aider.tags.cache.v3", - ".devcontainer", - "heighliner", - ".tmp", - "go.work.sum", - ".DS_Store", - ".git", - "LICENSE", - "tmp", - "sonr.log", - "DISCUSSION_TEMPLATE", - "ISSUE_TEMPLATE", - ".devbox", - ".timemachine", - "junit.xml", - ".jj", - ".spawn", - ".turbo", - } - - -- Merge all patterns - local all_patterns = {} - - -- Add default hide patterns - for _, pattern in ipairs(hide_patterns) do - table.insert(all_patterns, pattern) - end - - -- Add rgignore patterns - for _, pattern in ipairs(rgignore_patterns) do - table.insert(all_patterns, pattern) - end - - -- Add never show by pattern - for _, pattern in ipairs(never_show_by_pattern) do - table.insert(all_patterns, pattern) - end - - -- Add never show directories - for _, pattern in ipairs(never_show) do - table.insert(all_patterns, pattern) - end - - return all_patterns -end - --- Custom transform function to filter items -local function create_transform_filter() - local exclude_patterns = build_exclude_patterns() - - return function(item, ctx) - if not item then return false end - - local name = item.name or (item.file and vim.fn.fnamemodify(item.file, ":t")) or "" - local path = item.file or "" - - -- Check each pattern - for _, pattern in ipairs(exclude_patterns) do - -- Convert glob pattern to Lua pattern - local lua_pattern = pattern - :gsub("([%.%+%-%[%]%(%)%$%^%%%?])", "%%%1") -- Escape special chars except * - :gsub("%*%*", ".*") -- ** matches any characters including / - :gsub("%*", "[^/]*") -- * matches any characters except / - :gsub("%?", ".") -- ? matches single character - - -- Check against filename - if name:match("^" .. lua_pattern .. "$") then - return false -- Filter out this item - end - - -- Check against full path - if path:match("/" .. lua_pattern .. "$") or path:match("/" .. lua_pattern .. "/") then - return false -- Filter out this item - end - end - - return item -- Keep the item - end -end - -return { - { - "folke/snacks.nvim", - priority = 1000, - lazy = false, - ---@type snacks.Config - opts = function() - return { - -- Enable explorer and replace netrw - explorer = { - replace_netrw = true, - }, - -- Dashboard configuration - dashboard = { - preset = { - header = table.concat({ - "", - "", - " ████████ ", - " ██████████████ ", - " ████████████████ ", - " ██████████ █████ ", - " ██████████ █ ", - " ██████████ █████ ", - " █████████ █████████ ", - " █████████ ████ █████████ ", - " ████████ ████████ ████████ ", - "███████ ████████████ ███████", - "███████ ██████████████ ██████", - "███████ ████████████ ███████", - " ████████ ████████ ████████ ", - " █████████ ████ █████████ ", - " ████████ ██████████ ", - " ██████ ██████████ ", - " ██ █████████ ", - " ████ ██████████ ", - " ████████████████ ", - " ██████████████ ", - " ████████ ", - "", - "", - }, "\n"), - }, - sections = { - { section = "header" }, - { - pane = 2, - section = "terminal", - cmd = "colorscript -e square", - height = 5, - padding = 1, - }, - { section = "keys", gap = 1, padding = 1 }, - { - pane = 2, - icon = " ", - desc = "Browse Repo", - padding = 1, - key = "b", - action = function() require("snacks").gitbrowse() end, - }, - function() - local in_git = require("snacks").git.get_root() ~= nil - local cmds = { - { - title = "Notifications", - cmd = "gh notify -s -a -n5", - action = function() vim.ui.open "https://github.com/notifications" end, - key = "n", - icon = " ", - height = 5, - enabled = true, - }, - { - title = "Open Issues", - cmd = "gh issue list -L 3", - key = "i", - action = function() vim.fn.jobstart("gh issue list --web", { detach = true }) end, - icon = " ", - height = 7, - }, - { - icon = " ", - title = "Open PRs", - cmd = "gh pr list -L 3", - key = "P", - action = function() vim.fn.jobstart("gh pr list --web", { detach = true }) end, - height = 7, - }, - { - icon = " ", - title = "Git Status", - cmd = "git --no-pager diff --stat -B -M -C", - height = 10, - }, - } - return vim.tbl_map( - function(cmd) - return vim.tbl_extend("force", { - pane = 2, - section = "terminal", - enabled = in_git, - padding = 1, - ttl = 5 * 60, - indent = 3, - }, cmd) - end, - cmds - ) - end, - { section = "startup" }, - }, - }, - -- Configure the explorer picker source - picker = { - sources = { - explorer = { - -- Explorer configuration matching neotree - tree = true, - hidden = true, -- Show hidden files by default (. files) - ignored = false, -- Don't show gitignored files - follow_file = true, - git_status = true, - git_untracked = true, - diagnostics = true, - watch = true, - -- Use transform to filter out unwanted files/directories - transform = create_transform_filter(), - focus = "list", - auto_close = false, - jump = { close = true }, -- Close explorer when jumping to a file - layout = { - preset = "sidebar", - preview = false, - layout = { - width = 34, - }, - }, - formatters = { - file = { filename_only = true }, - }, - matcher = { sort_empty = false, fuzzy = false }, - win = { - list = { - keys = { - -- Navigation (matching neotree) - ["H"] = "explorer_up", -- Navigate to parent directory - ["L"] = "explorer_focus", -- Open file/expand directory (with auto-close for files) - [""] = "confirm", -- Open file/expand directory (with auto-close for files) - [""] = "confirm", -- Open without closing - [""] = "explorer_close_all", -- Collapse all folders - ["!"] = "toggle_ignored", -- Toggle ignored files - ["."] = "toggle_hidden", -- Toggle hidden files - ["/"] = function(self) - -- Focus search input - self:focus "input" - end, - ["f"] = function(self) - -- Focus search input (filter) - self:focus "input" - end, - [""] = function(self) - -- Clear filter - self.input:set "" - end, - ["s"] = "edit_vsplit", -- Open in vertical split - ["S"] = "edit_split", -- Open in horizontal split - ["t"] = "tab", -- Open in new tab - - -- File operations - ["a"] = "explorer_add", -- Add file - ["d"] = "explorer_del", -- Delete - ["r"] = "explorer_rename", -- Rename - ["y"] = "explorer_yank", -- Copy - ["x"] = "explorer_move", -- Cut/Move - ["p"] = "explorer_paste", -- Paste - ["c"] = "explorer_yank", -- Copy to clipboard - ["R"] = "explorer_update", -- Refresh - -- Git keybindings from neotree - ["o"] = function() vim.cmd "!gh repo view --web" end, - ["h"] = function() - require("snacks").terminal("gh dash", { - hidden = true, - auto_close = false, - interactive = true, - }) - end, - ["g"] = function() - require("snacks").terminal("lazygit", { - hidden = true, - auto_close = true, - interactive = true, - }) - end, - ["d"] = function() require("snacks").picker.git_diff() end, - ["b"] = function() require("snacks").picker.git_branches() end, - -- Terminal keybindings from neotree - ["m"] = function() _G.Mk_toggle() end, - ["j"] = function() _G.Lazyjournal_toggle() end, - ["l"] = function() - require("snacks").terminal("lazydocker", { - hidden = true, - auto_close = true, - start_in_insert = true, - interactive = true, - }) - end, - ["du"] = function() - require("snacks").terminal("devbox services up", { - hidden = true, - auto_close = false, - start_in_insert = true, - interactive = true, - }) - end, - ["dd"] = function() - require("snacks").terminal("devbox services down", { - hidden = true, - auto_close = false, - start_in_insert = true, - interactive = true, - }) - end, - ["da"] = function() - require("snacks").terminal("devbox services attach", { - hidden = true, - auto_close = false, - start_in_insert = true, - interactive = true, - }) - end, - ["."] = function() _G.Yazi_toggle() end, - ["t"] = function() require("snacks").terminal() end, - -- Additional navigation - ["h"] = "explorer_close", -- Close directory - ["l"] = "confirm", -- Open/expand - ["o"] = "explorer_open", -- Open with system application - ["P"] = "toggle_preview", - ["I"] = "toggle_ignored", - ["Z"] = "explorer_close_all", - ["]g"] = "explorer_git_next", - ["[g"] = "explorer_git_prev", - ["]d"] = "explorer_diagnostic_next", - ["[d"] = "explorer_diagnostic_prev", - }, - }, - }, - }, - }, - }, - } - end, - }, -} diff --git a/lua/plugins/mason.lua b/lua/plugins/mason.lua deleted file mode 100644 index 16d4bee..0000000 --- a/lua/plugins/mason.lua +++ /dev/null @@ -1,31 +0,0 @@ --- Customize Mason - ----@type LazySpec -return { - -- use mason-tool-installer for automatically installing Mason packages - { - "WhoIsSethDaniel/mason-tool-installer.nvim", - -- overrides `require("mason-tool-installer").setup(...)` - opts = { - -- Make sure to use the names found in `:Mason` - ensure_installed = { - -- install language servers - "lua-language-server", - "pkl-lsp", - - -- install formatters - "stylua", - - -- install debuggers - "debugpy", - - -- install any other package - "tree-sitter-cli", - "protols", - "protolint", - "templ", - "yamlfmt", - }, - }, - }, -} diff --git a/lua/plugins/neotree.lua b/lua/plugins/neotree.lua index 0c95f61..636db7d 100644 --- a/lua/plugins/neotree.lua +++ b/lua/plugins/neotree.lua @@ -1,39 +1,9 @@ --- Function to read patterns from .rgignore file -local function read_rgignore_patterns() - local patterns = {} - -- Try to get the git root of the current buffer's directory - local current_file = vim.fn.expand "%:p" - local current_dir = vim.fn.fnamemodify(current_file, ":h") +--- Neo-tree configuration with dynamic pattern filtering +--- @module plugins.neotree - -- If no current file, use current working directory - if current_dir == "" then - current_dir = vim.fn.getcwd() - end - - -- Get git root from current directory - local git_root = vim.fn.systemlist("cd " .. vim.fn.shellescape(current_dir) .. " && git rev-parse --show-toplevel 2>/dev/null")[1] - - if git_root and git_root ~= "" and not git_root:match "^fatal:" then - local rgignore_path = git_root .. "/.rgignore" - local file = io.open(rgignore_path, "r") - - if file then - for line in file:lines() do - -- Skip comments and empty lines - if line ~= "" and not line:match "^#" then - -- Convert ripgrep patterns to neo-tree patterns - -- Remove leading ./ if present - line = line:gsub("^%./", "") - -- Add the pattern - table.insert(patterns, line) - end - end - file:close() - end - end - - return patterns -end +-- Import shared modules +local ignore_patterns = require("config.ignore_patterns") +local terminals = require("config.terminals") return { { @@ -54,41 +24,57 @@ return { }) end, opts = function() - -- Function to dynamically get patterns - local function get_dynamic_patterns() - return read_rgignore_patterns() - end + -- Get all hide patterns from shared module + local hide_patterns = ignore_patterns.get_all_patterns() - -- Default patterns - local default_patterns = { - "chain_*.json", - "Library", - ".typecopy", - ".python-version", - "*.pb.go", - "*config.*.js", - "*config.js", - "deps.mjs", - ".parcelrc", - "worker-configuration.d.ts", - "wrangler.jsonc", - "*.pkl.go", - ".trunk", - ".config", - ".cz.toml", - "*_mock.go", - } - - -- Create a function to merge patterns dynamically - local function get_hide_patterns() - local rgignore_patterns = get_dynamic_patterns() - return vim.list_extend(vim.list_extend({}, default_patterns), rgignore_patterns) - end - - -- Get initial patterns - local hide_patterns = get_hide_patterns() + -- Setup LSP file operations integration + local events = require("neo-tree.events") return { + -- LSP file operation event handlers for refactoring support + event_handlers = { + { + event = events.BEFORE_FILE_ADD, + handler = function(args) require("astrolsp.file_operations").willCreateFiles(args) end, + }, + { + event = events.FILE_ADDED, + handler = function(args) require("astrolsp.file_operations").didCreateFiles(args) end, + }, + { + event = events.BEFORE_FILE_DELETE, + handler = function(args) require("astrolsp.file_operations").willDeleteFiles(args) end, + }, + { + event = events.FILE_DELETED, + handler = function(args) require("astrolsp.file_operations").didDeleteFiles(args) end, + }, + { + event = events.BEFORE_FILE_MOVE, + handler = function(args) + require("astrolsp.file_operations").willRenameFiles({ from = args.source, to = args.destination }) + end, + }, + { + event = events.BEFORE_FILE_RENAME, + handler = function(args) + require("astrolsp.file_operations").willRenameFiles({ from = args.source, to = args.destination }) + end, + }, + { + event = events.FILE_MOVED, + handler = function(args) + require("astrolsp.file_operations").didRenameFiles({ from = args.source, to = args.destination }) + end, + }, + { + event = events.FILE_RENAMED, + handler = function(args) + require("astrolsp.file_operations").didRenameFiles({ from = args.source, to = args.destination }) + end, + }, + }, + popup_border_style = "rounded", enable_git_status = true, enable_diagnostics = true, @@ -110,7 +96,7 @@ return { require("neo-tree.sources.filesystem.commands").set_root(state) -- Refresh patterns when changing root vim.defer_fn(function() - local new_patterns = get_hide_patterns() + local new_patterns = ignore_patterns.get_all_patterns() require("neo-tree").config.filesystem.filtered_items.hide_by_pattern = new_patterns require("neo-tree.sources.manager").refresh("filesystem") end, 50) @@ -141,8 +127,8 @@ return { ["d"] = function() require("snacks").picker.git_diff() end, ["b"] = function() require("snacks").picker.git_branches() end, -- Terminal keybindings from astrocore - ["m"] = function() _G.Mk_toggle() end, - ["j"] = function() _G.Lazyjournal_toggle() end, + ["m"] = terminals.mk_toggle, + ["j"] = terminals.lazyjournal_toggle, ["l"] = function() require("snacks").terminal("lazydocker", { hidden = true, @@ -175,7 +161,7 @@ return { interactive = true, }) end, - ["."] = function() _G.Yazi_toggle() end, + ["."] = terminals.yazi_toggle, ["t"] = function() require("snacks").terminal() end, -- Find keybindings from astrocore -- These Find keybindings are defined in astrocore.lua @@ -261,7 +247,7 @@ return { -- Refresh patterns when changing directories refresh_patterns = function(state) -- Re-read patterns when navigating - local new_patterns = get_hide_patterns() + local new_patterns = ignore_patterns.get_all_patterns() state.filtered_items.hide_by_pattern = new_patterns require("neo-tree.sources.manager").refresh("filesystem") end, @@ -347,76 +333,8 @@ return { -- "bridge", -- "client", }, - never_show_by_pattern = { - "*DS_Store", - ".obsidian", - ".pkl-lsp", - ".tsbuildinfo", - "package-lock.json", - ".prettierrc", - "node_modules", - ".DocumentRevisions-V100", - ".Spotlight-V100", - ".TemporaryItems", - ".Trashes", - ".fseventsd", - ".editorconfig", - "*.min.js", - "*.lock", - "*lock*", - "*.lockb", - "*.pulsar.go", - "*.pb.gorm.go", - "*.pb.gw.go", - "*_templ.go", - "*.tmp", - "*.work.*", - "*.sum", - ".parcel-cache", - "*.icns", - "*.ico", - ".aider.tags.cache.v4", - "*.iml", - "Icon?", - "iCloud~", - "com~", - "*.icns", - ".conform*", - ".null-ls_*", - }, - never_show = { - ".git", - "pnpm-lock.yaml", - ".next", - ".task", - ".devbox", - ".dart_tool", - ".idea", - ".metadata", - ".venv", - ".gradle", - "gradle.bat", - ".aider.chat.history.md", - ".aider.input.history", - ".aider.tags.cache.v3", - ".devcontainer", - "heighliner", - ".tmp", - "go.work.sum", - ".DS_Store", - ".git", - "LICENSE", - "tmp", - "sonr.log", - "DISCUSSION_TEMPLATE", - "ISSUE_TEMPLATE", - ".devbox", - ".timemachine", - "junit.xml", - ".jj", - ".spawn", - ".turbo", - }, + never_show_by_pattern = ignore_patterns.never_show_patterns, + never_show = ignore_patterns.never_show, }, }, diagnostics = { diff --git a/lua/plugins/obsidian.lua b/lua/plugins/obsidian.lua deleted file mode 100644 index 32531ab..0000000 --- a/lua/plugins/obsidian.lua +++ /dev/null @@ -1,76 +0,0 @@ -return { - "obsidian-nvim/obsidian.nvim", - -- the obsidian vault in this default config ~/obsidian-vault - -- If you want to use the home shortcut '~' here you need to call 'vim.fn.expand': - event = { "bufreadpre " .. vim.fn.expand "~" .. "/Notes/**.md" }, - dependencies = { - "nvim-lua/plenary.nvim", - { "hrsh7th/nvim-cmp", optional = true }, - { - "AstroNvim/astrocore", - opts = { - mappings = { - n = { - ["gf"] = { - function() - if require("obsidian").util.cursor_on_markdown_link() then - return "Obsidian follow_link" - else - return "gf" - end - end, - desc = "Obsidian Follow Link", - }, - }, - }, - }, - }, - }, - opts = function(_, opts) - local astrocore = require "astrocore" - return astrocore.extend_tbl(opts, { - workspaces = { - { - path = vim.env.HOME .. "/Notes", -- specify the vault location. no need to call 'vim.fn.expand' here - }, - }, - open = { - use_advanced_uri = true, - }, - finder = (astrocore.is_available "snacks.pick" and "snacks.pick") - or (astrocore.is_available "telescope.nvim" and "telescope.nvim") - or (astrocore.is_available "fzf-lua" and "fzf-lua") - or (astrocore.is_available "mini.pick" and "mini.pick"), - - templates = { - subdir = "2 - Areas/Templates", - date_format = "%Y-%m-%d-%a", - time_format = "%H:%M", - }, - daily_notes = { - folder = "3 - Journals", - }, - completion = { - nvim_cmp = astrocore.is_available "nvim-cmp", - blink = astrocore.is_available "blink", - }, - - note_frontmatter_func = function(note) - -- This is equivalent to the default frontmatter function. - local out = { id = note.id, aliases = note.aliases, tags = note.tags } - -- `note.metadata` contains any manually added fields in the frontmatter. - -- So here we just make sure those fields are kept in the frontmatter. - if note.metadata ~= nil and not vim.tbl_isempty(note.metadata) then - for k, v in pairs(note.metadata) do - out[k] = v - end - end - return out - end, - - -- Optional, by default when you use `:ObsidianFollowLink` on a link to an external - -- URL it will be ignored but you can customize this behavior here. - follow_url_func = vim.ui.open, - }) - end, -} diff --git a/lua/plugins/opencode.lua b/lua/plugins/opencode.lua index 90ea433..ba858c1 100644 --- a/lua/plugins/opencode.lua +++ b/lua/plugins/opencode.lua @@ -1,3 +1,7 @@ +--- OpenCode integration for Neovim +--- Provides AI-powered code assistance directly within the editor +--- @module plugins.opencode + return { "NickvanDyke/opencode.nvim", dependencies = {