diff --git a/.stylua.toml b/.stylua.toml index 0435f67..88b2e63 100644 --- a/.stylua.toml +++ b/.stylua.toml @@ -1,2 +1,3 @@ indent_type = "Spaces" indent_width = 2 + diff --git a/lua/cargdev/core/function/notification_manager.lua b/lua/cargdev/core/function/notification_manager.lua index fbb477a..63e6f46 100644 --- a/lua/cargdev/core/function/notification_manager.lua +++ b/lua/cargdev/core/function/notification_manager.lua @@ -303,8 +303,6 @@ function M.setup() -- Don't override vim.notify here to avoid circular dependency -- Let the system handle notifications naturally - - print("Notification manager initialized") end -- Initialize notification manager diff --git a/lua/cargdev/core/init.lua b/lua/cargdev/core/init.lua index a4520d3..947d43a 100644 --- a/lua/cargdev/core/init.lua +++ b/lua/cargdev/core/init.lua @@ -6,7 +6,7 @@ -- 0. Setup LuaRocks path for rest.nvim dependencies (Lua 5.1 - Neovim uses LuaJIT) local function setup_luarocks_path() - local luarocks_path = vim.fn.system("luarocks path --lr-path --lua-version=5.1 --local"):gsub("\n", "") + local luarocks_path = vim.fn.system("luarocks path --lr-path --lua-version=5.1 --local 2>/dev/null"):gsub("\n", "") if luarocks_path and luarocks_path ~= "" then package.path = package.path .. ";" .. luarocks_path end @@ -37,7 +37,7 @@ end vim.api.nvim_create_autocmd("BufRead", { pattern = "*", callback = function() - vim.cmd("filetype detect") + vim.cmd("silent filetype detect") end, }) diff --git a/lua/cargdev/core/keymaps/copilot.lua b/lua/cargdev/core/keymaps/copilot.lua index 40dfb3a..3d9f8fd 100644 --- a/lua/cargdev/core/keymaps/copilot.lua +++ b/lua/cargdev/core/keymaps/copilot.lua @@ -1,13 +1,18 @@ --- -- Copilot Chat keymaps --- local keymap = vim.keymap --- --- keymap.set("v", "zn", ":CopilotChatRename", { desc = "Rename variable (Copilot Chat)" }) --- keymap.set("n", "zc", ":CopilotChat", { desc = "Open Copilot Chat" }) --- keymap.set("v", "ze", ":CopilotChatExplain", { desc = "Explain code (Copilot Chat)" }) --- keymap.set("v", "zr", ":CopilotChatReview", { desc = "Review code (Copilot Chat)" }) --- keymap.set("v", "zf", ":CopilotChatFix", { desc = "Fix code issues (Copilot Chat)" }) --- keymap.set("v", "zo", ":CopilotChatOptimize", { desc = "Optimize code (Copilot Chat)" }) --- keymap.set("v", "zd", ":CopilotChatDocs", { desc = "Generate docs (Copilot Chat)" }) --- keymap.set("n", "cp", ":Copilot panel", { desc = "Copilot: Open copilot panel" }) --- keymap.set("n", "cd", ":Copilot disable", { desc = "Copilot: Disabled" }) --- keymap.set("n", "cs", ":Copilot status", { desc = "Copilot: Status" }) +-- Copilot keymaps +local keymap = vim.keymap + +-- Copilot panel and status +keymap.set("n", "cp", ":Copilot panel", { desc = "Copilot: Open copilot panel" }) +keymap.set("n", "cd", ":Copilot disable", { desc = "Copilot: Disable" }) +keymap.set("n", "ce", ":Copilot enable", { desc = "Copilot: Enable" }) +keymap.set("n", "cs", ":Copilot status", { desc = "Copilot: Status" }) + +-- Copilot suggestion navigation (insert mode) +-- These are configured in copilot.lua but documented here for reference: +-- ] - Next suggestion +-- [ - Previous suggestion +-- - Accept suggestion +-- - Dismiss suggestion + +-- CodeCompanion keymaps +keymap.set("n", "cc", ":CodeCompanion", { desc = "CodeCompanion: Open CodeCompanion" }) diff --git a/lua/cargdev/core/keymaps/personal.lua b/lua/cargdev/core/keymaps/personal.lua index d101f13..aa9cf45 100644 --- a/lua/cargdev/core/keymaps/personal.lua +++ b/lua/cargdev/core/keymaps/personal.lua @@ -89,4 +89,9 @@ keymap.set("v", "zd", ":CopilotChatDocs", { desc = "Generate docs (C -- Copilot keymap.set("n", "cp", ":Copilot panel", { desc = "Copilot: Open copilot panel" }) -keymap.set("n", "ce", ":CopilotChatExplain", { desc = "Copilot Chat: Explain code" }) +keymap.set("n", "ce", ":CopilotChatExplain", { desc = "Copilot Chat: Explain code" }) + +-- Paste HTML as Markdown using pandoc +keymap.set("n", "p", function() + vim.cmd("read !pbpaste -Prefer html | pandoc -f html -t gfm") +end, { desc = "Paste HTML clipboard as Markdown" }) diff --git a/lua/cargdev/core/options.lua b/lua/cargdev/core/options.lua index 2e63efb..e05ce14 100644 --- a/lua/cargdev/core/options.lua +++ b/lua/cargdev/core/options.lua @@ -1,6 +1,7 @@ -- Core options and settings local opt = vim.opt local g = vim.g +local fn = vim.fn -- Disable deprecated API warnings vim.deprecate = function() end @@ -17,6 +18,10 @@ opt.completeopt = "menuone,noselect" -- Better completion opt.undofile = true -- Persistent undo opt.undodir = vim.fn.stdpath("data") .. "/undodir" +-- Suppress startup messages to avoid "Press ENTER" prompts +opt.shortmess = "aoOtTIcFWS" -- Suppress various messages +opt.cmdheight = 1 -- Set command height to avoid prompts + -- Search settings opt.ignorecase = true -- Case insensitive search opt.smartcase = true -- Case sensitive when uppercase @@ -130,18 +135,19 @@ g.loaded_perl_provider = 0 -- Disable Perl provider g.loaded_ruby_provider = 0 -- Disable Ruby provider (optional) -- Python provider configuration -g.python3_host_prog = "/opt/homebrew/bin/python3.12" -- Explicit Python path + +g.python3_host_prog = fn.expand("~/.local/pipx/venvs/pynvim/bin/python") -- Clipboard provider optimization (macOS) g.clipboard = { - name = "xclip", + name = "macOS-clipboard", copy = { - ["+"] = "xclip -selection clipboard", - ["*"] = "xclip -selection primary", + ["+"] = "pbcopy", + ["*"] = "pbcopy", }, paste = { - ["+"] = "xclip -selection clipboard -o", - ["*"] = "xclip -selection primary -o", + ["+"] = "pbpaste", + ["*"] = "pbpaste", }, } diff --git a/lua/cargdev/plugins/avante.lua b/lua/cargdev/plugins/avante.lua index a53a7b1..52a4f5e 100644 --- a/lua/cargdev/plugins/avante.lua +++ b/lua/cargdev/plugins/avante.lua @@ -1,25 +1,34 @@ return { { - "yetone/avante.nvim", + dir = "/Users/carlos/Documents/projects/avante.nvim", + -- "yetone/avante.nvim", event = "VeryLazy", lazy = false, version = false, -- Always pull the latest change + build = "make", -- This will build on first load opts = { - provider = "claude", -- API provider configuration + provider = "cargdev", -- API provider configuration + mode = "agentic", -- Enable agentic mode for tool support + debug = true, -- Enable debug logging to troubleshoot tools providers = { - claude = { - endpoint = "https://api.anthropic.com", - model = "claude-3-haiku-20240307", - timeout = 30000, -- Timeout in milliseconds - extra_request_body = { - temperature = 0.75, - max_tokens = 4096, - }, + cargdev = { + name = "cargdev", -- Optional + endpoint = "http://localhost:5001", -- endpoint = "https://api-ai.cargdev.io", -- API endpoint + api_key_name = "CARGDEV_API_KEY", -- reference the ENV VAR below + model = "qwen2.5-coder:7b", + __inherited_from = "ollama", -- ensures compatibility + max_tokens = 8192, + -- Explicitly ensure tools are enabled + disable_tools = false, + -- Tool format: false = function calling (JSON tools in request), true = XML tool format (tools in prompt) + use_ReAct_prompt = false, -- Use function calling format (OpenAI-compatible) }, }, }, - -- Optional: Build from source if required - build = "make", + -- Build from source for development + -- Run `make BUILD_FROM_SOURCE=true` to build Rust components + -- You can also build manually: cd /Users/carlos/Documents/projects/avante.nvim && make + build = "make BUILD_FROM_SOURCE=true", dependencies = { "nvim-treesitter/nvim-treesitter", "nvim-lua/plenary.nvim", @@ -32,14 +41,31 @@ return { { "folke/snacks.nvim", -- for input provider snacks lazy = false, - priority = 1000, + priority = 1001, -- Higher than dressing to override it + dependencies = { + "stevearc/dressing.nvim", -- Load after dressing to override it + }, config = function() require("snacks").setup({ -- Enable all snacks modules bigfile = { enabled = true }, - dashboard = { enabled = true }, + dashboard = { + enabled = true, + autostart = true, + -- Ensure dashboard setup runs + auto_open = false, + }, explorer = { enabled = true }, - image = { enabled = true }, + image = { + enabled = true, + -- Auto-detect terminal (will try: kitty, wezterm, ghostty in order) + -- If none found, image rendering will be disabled with warnings + -- Note: LaTeX and Mermaid features require external tools: + -- - LaTeX: tectonic or pdflatex + -- - Mermaid: mmdc (Mermaid CLI) + -- These warnings are informational and won't prevent basic image rendering + terminal = nil, -- nil = auto-detect + }, input = { enabled = true }, lazygit = { enabled = true }, notifier = { enabled = true }, @@ -57,9 +83,24 @@ return { }, }) + -- Force dashboard module initialization + -- Access the dashboard module to ensure its setup function runs + vim.defer_fn(function() + pcall(function() + local dashboard = require("snacks.dashboard") + -- Access the module to trigger lazy initialization if needed + if dashboard and type(dashboard) == "table" then + -- Module loaded successfully + end + end) + end, 100) + -- Set up vim.ui.input and vim.ui.select for snacks - vim.ui.input = require("snacks.input").input - vim.ui.select = require("snacks.picker").select + -- Use vim.schedule to ensure this runs after all plugins are loaded + vim.schedule(function() + vim.ui.input = require("snacks.input").input + vim.ui.select = require("snacks.picker").select + end) end, }, "nvim-tree/nvim-web-devicons", -- or echasnovski/mini.icons @@ -85,6 +126,15 @@ return { require("render-markdown").setup({ file_types = { "markdown", "Avante" }, latex = { enabled = false }, -- Disable latex to avoid warning + html = { enabled = false }, -- Disable html support to avoid warnings + yaml = { enabled = false }, -- Disable yaml support to avoid warnings + }) + -- Enable treesitter highlighter for markdown buffers + vim.api.nvim_create_autocmd("FileType", { + pattern = { "markdown", "Avante" }, + callback = function() + vim.treesitter.start() + end, }) end, }, diff --git a/lua/cargdev/plugins/copilot.lua b/lua/cargdev/plugins/copilot.lua new file mode 100644 index 0000000..37a0f5f --- /dev/null +++ b/lua/cargdev/plugins/copilot.lua @@ -0,0 +1,84 @@ +return { + { + "zbirenbaum/copilot.lua", + cmd = "Copilot", + event = "InsertEnter", + config = function() + require("copilot").setup({ + panel = { + enabled = true, + auto_refresh = false, + keymap = { + jump_prev = "[[", + jump_next = "]]", + accept = "", + refresh = "gr", + open = "", + }, + layout = { + position = "bottom", -- | top | left | right + ratio = 0.4, + }, + }, + suggestion = { + enabled = true, + auto_trigger = true, -- Enable auto-trigger suggestions as you type + debounce = 75, + keymap = { + accept = "", + accept_word = false, + accept_line = false, + next = "]", -- Use leader key for next suggestion + prev = "[", -- Use leader key for previous suggestion + dismiss = "", + }, + }, + filetypes = { + markdown = true, + help = true, + gitcommit = true, + gitrebase = true, + hgcommit = true, + svn = true, + cvs = true, + ["."] = true, + }, + copilot_node_command = "node", -- Node.js version must be > 16.x + server_opts_overrides = {}, + }) + end, + }, + { + "zbirenbaum/copilot-cmp", + dependencies = { "zbirenbaum/copilot.lua" }, + config = function() + require("copilot_cmp").setup() + end, + }, + { + "olimorris/codecompanion.nvim", + dependencies = { + "zbirenbaum/copilot.lua", + "nvim-lua/plenary.nvim", + "nvim-telescope/telescope.nvim", + }, + cmd = { "CodeCompanion" }, + config = function() + require("codecompanion").setup({ + -- Use GitHub Copilot as the provider + providers = { + copilot = { + enabled = true, + }, + }, + -- Configure the UI + ui = { + window = { + width = 0.8, + height = 0.8, + }, + }, + }) + end, + }, +} diff --git a/lua/cargdev/plugins/curls.lua b/lua/cargdev/plugins/curls.lua index f8daede..a77ea59 100644 --- a/lua/cargdev/plugins/curls.lua +++ b/lua/cargdev/plugins/curls.lua @@ -1,5 +1,15 @@ return { "CarGDev/rest.nvim", + build = function() + -- Install LuaRocks dependencies for Lua 5.1 (Neovim uses LuaJIT which is Lua 5.1 compatible) + local packages = { "mimetypes", "xml2lua" } + for _, pkg in ipairs(packages) do + local result = vim.fn.system("luarocks install --local --lua-version=5.1 " .. pkg .. " 2>&1") + if vim.v.shell_error ~= 0 and not result:match("already installed") then + vim.notify("Warning: Failed to install " .. pkg .. ": " .. result, vim.log.levels.WARN) + end + end + end, dependencies = { "nvim-treesitter/nvim-treesitter", opts = function(_, opts) @@ -8,6 +18,26 @@ return { end, }, config = function() + -- Verify LuaRocks dependencies are available + local function check_dependency(name) + local success = pcall(require, name) + if not success then + vim.notify( + string.format( + "rest.nvim: Missing dependency '%s'. Please run: luarocks install --local %s", + name, + name + ), + vim.log.levels.WARN + ) + end + return success + end + + -- Check for required dependencies + check_dependency("mimetypes") + check_dependency("xml2lua") + -- Basic configuration for rest.nvim vim.g.rest_nvim = { -- Enable request highlighting diff --git a/lua/cargdev/plugins/lsp/lspconfig.lua b/lua/cargdev/plugins/lsp/lspconfig.lua index 784a1b4..7f9287b 100644 --- a/lua/cargdev/plugins/lsp/lspconfig.lua +++ b/lua/cargdev/plugins/lsp/lspconfig.lua @@ -28,6 +28,7 @@ return { "pyright", "svelte", "tailwindcss", + "ts_ls", }, }) @@ -127,7 +128,9 @@ return { } } }, - emmet_ls = {}, + emmet_ls = { + filetypes = { "html", "css", "sass", "scss", "less", "javascript", "javascriptreact", "typescript", "typescriptreact", "vue", "svelte" }, + }, eslint = { settings = { workingDirectory = { mode = "auto" } } }, @@ -140,8 +143,12 @@ return { } } }, - graphql = {}, - html = {}, + graphql = { + filetypes = { "graphql", "gql", "typescript", "javascript", "typescriptreact", "javascriptreact" }, + }, + html = { + filetypes = { "html" }, + }, lua_ls = { settings = { Lua = { @@ -155,7 +162,9 @@ return { }, }, }, - prismals = {}, + prismals = { + filetypes = { "prisma" }, + }, pyright = { settings = { python = { @@ -166,17 +175,59 @@ return { } } }, - svelte = {}, - tailwindcss = {}, + svelte = { + filetypes = { "svelte" }, + }, + tailwindcss = { + filetypes = { "html", "css", "sass", "scss", "less", "javascript", "javascriptreact", "typescript", "typescriptreact", "vue", "svelte" }, + init_options = { + userLanguages = { + html = "html", + css = "css", + javascript = "javascript", + typescript = "typescript", + javascriptreact = "javascriptreact", + typescriptreact = "typescriptreact", + vue = "vue", + svelte = "svelte", + }, + }, + }, + ts_ls = { + filetypes = { "typescript", "typescriptreact", "javascript", "javascriptreact" }, + settings = { + typescript = { + inlayHints = { + includeInlayParameterNameHints = "all", + includeInlayParameterNameHintsWhenArgumentMatchesName = false, + includeInlayFunctionParameterTypeHints = true, + includeInlayVariableTypeHints = true, + includeInlayPropertyDeclarationTypeHints = true, + includeInlayFunctionLikeReturnTypeHints = true, + includeInlayEnumMemberValueHints = true, + }, + }, + javascript = { + inlayHints = { + includeInlayParameterNameHints = "all", + includeInlayParameterNameHintsWhenArgumentMatchesName = false, + includeInlayFunctionParameterTypeHints = true, + includeInlayVariableTypeHints = true, + includeInlayPropertyDeclarationTypeHints = true, + includeInlayFunctionLikeReturnTypeHints = true, + includeInlayEnumMemberValueHints = true, + }, + }, + }, + }, -- sqls = { settings = { sqls = { connections = { /* …your dbs… */ } } } }, -- optional } -- Set up all LSP servers with performance optimizations and error handling for name, cfg in pairs(servers) do - lspconfig[name].setup({ + local server_config = { capabilities = capabilities, on_attach = on_attach, - settings = cfg.settings, flags = { debounce_text_changes = 150 }, handlers = { ["textDocument/publishDiagnostics"] = vim.lsp.with( @@ -184,7 +235,24 @@ return { { virtual_text = false, signs = true, underline = true, update_in_insert = false } ), }, - }) + } + + -- Add settings if present + if cfg.settings then + server_config.settings = cfg.settings + end + + -- Add filetypes if present + if cfg.filetypes then + server_config.filetypes = cfg.filetypes + end + + -- Add init_options if present + if cfg.init_options then + server_config.init_options = cfg.init_options + end + + lspconfig[name].setup(server_config) end -- Set up additional LSP servers that might not be in mason-lspconfig diff --git a/lua/cargdev/plugins/lsp/mason.lua b/lua/cargdev/plugins/lsp/mason.lua index 8f6e8df..adfd2de 100644 --- a/lua/cargdev/plugins/lsp/mason.lua +++ b/lua/cargdev/plugins/lsp/mason.lua @@ -49,6 +49,7 @@ return { "black", -- python formatter "pylint", "eslint_d", + "tree-sitter-cli", -- required for nvim-treesitter parser compilation }, }) end, diff --git a/lua/cargdev/plugins/nvim-cmp.lua b/lua/cargdev/plugins/nvim-cmp.lua index 423a9a3..b79ea05 100644 --- a/lua/cargdev/plugins/nvim-cmp.lua +++ b/lua/cargdev/plugins/nvim-cmp.lua @@ -47,10 +47,42 @@ return { [""] = cmp.mapping.complete(), -- show completion suggestions [""] = cmp.mapping.abort(), -- close completion window [""] = cmp.mapping.confirm({ select = false }), + -- Tab to accept Copilot suggestions, fallback to snippet expansion + [""] = cmp.mapping(function(fallback) + if cmp.visible() then + local entry = cmp.get_selected_entry() + -- If Copilot suggestion is available and selected, accept it + if entry and entry.source.name == "copilot" then + cmp.confirm({ select = true }) + else + -- Check if we can find a Copilot entry in the completion menu + -- Since Copilot has high priority (900), it's likely near the top + -- Just confirm the current selection (Copilot will be selected if available) + cmp.confirm({ select = true }) + end + elseif luasnip.expand_or_jumpable() then + -- Expand snippet or jump to next placeholder + luasnip.expand_or_jump() + else + -- Fallback to default Tab behavior + fallback() + end + end, { "i", "s" }), + -- Shift-Tab to go back in snippets + [""] = cmp.mapping(function(fallback) + if cmp.visible() then + cmp.select_prev_item() + elseif luasnip.jumpable(-1) then + luasnip.jump(-1) + else + fallback() + end + end, { "i", "s" }), }), -- sources for autocompletion sources = cmp.config.sources({ { name = "nvim_lsp", priority = 1000}, + { name = "copilot", priority = 900 }, -- GitHub Copilot suggestions { name = "luasnip", priority = 750 }, -- snippets { name = "buffer", priority = 500, keyword_length = 3 }, -- text within current buffer { name = "path", priority = 250 }, -- file system paths diff --git a/lua/cargdev/plugins/nvim-treesitter-text-objects.lua b/lua/cargdev/plugins/nvim-treesitter-text-objects.lua index 6ae0e9f..495639c 100644 --- a/lua/cargdev/plugins/nvim-treesitter-text-objects.lua +++ b/lua/cargdev/plugins/nvim-treesitter-text-objects.lua @@ -1,24 +1,10 @@ return { - { - "nvim-treesitter/nvim-treesitter", - build = ":TSUpdate", - opts = { - ensure_installed = { - "lua", - "html", -- required by leetcode.nvim - "python", - "javascript", - "typescript", - "cpp", - }, - highlight = { - enable = true, - }, - }, - }, { "nvim-treesitter/nvim-treesitter-textobjects", lazy = true, + dependencies = { + "nvim-treesitter/nvim-treesitter", + }, config = function() require("nvim-treesitter.configs").setup({ textobjects = { diff --git a/lua/cargdev/plugins/treesitter.lua b/lua/cargdev/plugins/treesitter.lua index 15a3aad..371d29e 100644 --- a/lua/cargdev/plugins/treesitter.lua +++ b/lua/cargdev/plugins/treesitter.lua @@ -1,73 +1,81 @@ return { "nvim-treesitter/nvim-treesitter", event = { "BufReadPost", "BufNewFile" }, -- Changed from BufReadPre to BufReadPost for better performance - build = ":TSUpdate", + build = function() + -- Install tree-sitter-cli if not available, then update parsers + if vim.fn.executable("tree-sitter") == 0 then + vim.notify("tree-sitter-cli not found. Please install it: npm install -g tree-sitter-cli", vim.log.levels.WARN) + end + vim.cmd("TSUpdate") + end, dependencies = { "windwp/nvim-ts-autotag", }, - config = function() - -- import nvim-treesitter plugin - local treesitter = require("nvim-treesitter.configs") - - -- configure treesitter - treesitter.setup({ -- enable syntax highlighting - highlight = { - enable = true, - disable = function(lang, buf) - -- Prevent Treesitter from parsing Copilot files - return lang == "copilot" or vim.api.nvim_buf_get_name(buf):match("copilot.lua") - end, - -- Performance optimizations - use_languagetree = true, - additional_vim_regex_highlighting = false, - }, - -- enable indentation - indent = { enable = true }, - -- enable autotagging (w/ nvim-ts-autotag plugin) - autotag = { - enable = true, - }, - -- ensure these language parsers are installed - ensure_installed = { - "json", - "javascript", - "typescript", - "java", - "tsx", - "yaml", - "html", - "css", - "prisma", - "markdown", - "markdown_inline", - "svelte", - "graphql", - "sql", - "bash", - "lua", - "vim", - "dockerfile", - "gitignore", - "query", - "vimdoc", - "c", - }, - incremental_selection = { - enable = true, - keymaps = { - init_selection = "", - node_incremental = "", - scope_incremental = false, - node_decremental = "", - }, - }, + opts = { + -- enable syntax highlighting + highlight = { + enable = true, + disable = function(lang, buf) + -- Prevent Treesitter from parsing Copilot files + return lang == "copilot" or vim.api.nvim_buf_get_name(buf):match("copilot.lua") + end, -- Performance optimizations - playground = { - enable = false, -- Disable playground for better performance + use_languagetree = true, + additional_vim_regex_highlighting = false, + }, + -- enable indentation + indent = { enable = true }, + -- enable autotagging (w/ nvim-ts-autotag plugin) + autotag = { + enable = true, + }, + -- ensure these language parsers are installed + ensure_installed = { + "json", + "javascript", + "typescript", + "java", + "tsx", + "yaml", + "html", + "css", + "scss", + "prisma", + "markdown", + "markdown_inline", + "svelte", + "vue", + "graphql", + "sql", + "bash", + "lua", + "vim", + "dockerfile", + "gitignore", + "query", + "vimdoc", + "c", + "python", + "cpp", + "latex", + "norg", + "typst", + }, + incremental_selection = { + enable = true, + keymaps = { + init_selection = "", + node_incremental = "", + scope_incremental = false, + node_decremental = "", }, - query_linter = { - enable = false, -- Disable query linter for better performance - }, - }) - end, + }, + -- Performance optimizations + playground = { + enable = false, -- Disable playground for better performance + }, + query_linter = { + enable = false, -- Disable query linter for better performance + }, + }, }