[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-73389":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":11,"languages":10,"totalLinesOfCode":10,"stars":12,"forks":13,"watchers":14,"openIssues":15,"contributorsCount":16,"subscribersCount":16,"size":16,"stars1d":17,"stars7d":18,"stars30d":19,"stars90d":16,"forks30d":16,"starsTrendScore":20,"compositeScore":21,"rankGlobal":10,"rankLanguage":10,"license":22,"archived":23,"fork":23,"defaultBranch":24,"hasWiki":25,"hasPages":23,"topics":26,"createdAt":10,"pushedAt":10,"updatedAt":30,"readmeContent":31,"aiSummary":32,"trendingCount":16,"starSnapshotCount":16,"syncStatus":33,"lastSyncTime":34,"discoverSource":35},73389,"claudecode.nvim","coder\u002Fclaudecode.nvim","coder","🧩 Claude Code Neovim IDE Extension","",null,"Lua",2810,196,13,51,0,15,44,134,45,108.88,"MIT License",false,"main",true,[27,28,29],"claude","claude-code","neovim","2026-06-12 04:01:09","# claudecode.nvim\n\n[![Tests](https:\u002F\u002Fgithub.com\u002Fcoder\u002Fclaudecode.nvim\u002Factions\u002Fworkflows\u002Ftest.yml\u002Fbadge.svg)](https:\u002F\u002Fgithub.com\u002Fcoder\u002Fclaudecode.nvim\u002Factions\u002Fworkflows\u002Ftest.yml)\n![Neovim version](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FNeovim-0.8%2B-green)\n![Status](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FStatus-beta-blue)\n\n**The first Neovim IDE integration for Claude Code** — bringing Anthropic's AI coding assistant to your favorite editor with a pure Lua implementation.\n\n> 🎯 **TL;DR:** When Anthropic released Claude Code with VS Code and JetBrains support, I reverse-engineered their extension and built this Neovim plugin. This plugin implements the same WebSocket-based MCP protocol, giving Neovim users the same AI-powered coding experience.\n\n\u003Chttps:\u002F\u002Fgithub.com\u002Fuser-attachments\u002Fassets\u002F9c310fb5-5a23-482b-bedc-e21ae457a82d>\n\n## What Makes This Special\n\nWhen Anthropic released Claude Code, they only supported VS Code and JetBrains. As a Neovim user, I wanted the same experience — so I reverse-engineered their extension and built this.\n\n- 🚀 **Pure Lua, Zero Dependencies** — Built entirely with `vim.loop` and Neovim built-ins\n- 🔌 **100% Protocol Compatible** — Same WebSocket MCP implementation as official extensions\n- 🎓 **Fully Documented Protocol** — Learn how to build your own integrations ([see PROTOCOL.md](.\u002FPROTOCOL.md))\n- ⚡ **First to Market** — Beat Anthropic to releasing Neovim support\n- 🛠️ **Built with AI** — Used Claude to reverse-engineer Claude's own protocol\n\n## Installation\n\n```lua\n{\n  \"coder\u002Fclaudecode.nvim\",\n  dependencies = { \"folke\u002Fsnacks.nvim\" },\n  config = true,\n  keys = {\n    { \"\u003Cleader>a\", nil, desc = \"AI\u002FClaude Code\" },\n    { \"\u003Cleader>ac\", \"\u003Ccmd>ClaudeCode\u003Ccr>\", desc = \"Toggle Claude\" },\n    { \"\u003Cleader>af\", \"\u003Ccmd>ClaudeCodeFocus\u003Ccr>\", desc = \"Focus Claude\" },\n    { \"\u003Cleader>ar\", \"\u003Ccmd>ClaudeCode --resume\u003Ccr>\", desc = \"Resume Claude\" },\n    { \"\u003Cleader>aC\", \"\u003Ccmd>ClaudeCode --continue\u003Ccr>\", desc = \"Continue Claude\" },\n    { \"\u003Cleader>am\", \"\u003Ccmd>ClaudeCodeSelectModel\u003Ccr>\", desc = \"Select Claude model\" },\n    { \"\u003Cleader>ab\", \"\u003Ccmd>ClaudeCodeAdd %\u003Ccr>\", desc = \"Add current buffer\" },\n    { \"\u003Cleader>as\", \"\u003Ccmd>ClaudeCodeSend\u003Ccr>\", mode = \"v\", desc = \"Send to Claude\" },\n    {\n      \"\u003Cleader>as\",\n      \"\u003Ccmd>ClaudeCodeTreeAdd\u003Ccr>\",\n      desc = \"Add file\",\n      ft = { \"NvimTree\", \"neo-tree\", \"oil\", \"minifiles\", \"netrw\" },\n    },\n    -- Diff management\n    { \"\u003Cleader>aa\", \"\u003Ccmd>ClaudeCodeDiffAccept\u003Ccr>\", desc = \"Accept diff\" },\n    { \"\u003Cleader>ad\", \"\u003Ccmd>ClaudeCodeDiffDeny\u003Ccr>\", desc = \"Deny diff\" },\n  },\n}\n```\n\nThat's it! The plugin will auto-configure everything else.\n\n## Requirements\n\n- Neovim >= 0.8.0\n- [Claude Code CLI](https:\u002F\u002Fdocs.anthropic.com\u002Fen\u002Fdocs\u002Fclaude-code) installed\n- [folke\u002Fsnacks.nvim](https:\u002F\u002Fgithub.com\u002Ffolke\u002Fsnacks.nvim) for enhanced terminal support\n\n## Local Installation Configuration\n\nIf you've used Claude Code's `migrate-installer` command to move to a local installation, you'll need to configure the plugin to use the local path.\n\n### What is a Local Installation?\n\nClaude Code offers a `claude migrate-installer` command that:\n\n- Moves Claude Code from a global npm installation to `~\u002F.claude\u002Flocal\u002F`\n- Avoids permission issues with system directories\n- Creates shell aliases but these may not be available to Neovim\n\n### Detecting Your Installation Type\n\nCheck your installation type:\n\n```bash\n# Check where claude command points\nwhich claude\n\n# Global installation shows: \u002Fusr\u002Flocal\u002Fbin\u002Fclaude (or similar)\n# Local installation shows: alias to ~\u002F.claude\u002Flocal\u002Fclaude\n\n# Verify installation health\nclaude doctor\n```\n\n### Configuring for Local Installation\n\nIf you have a local installation, configure the plugin with the direct path:\n\n```lua\n{\n  \"coder\u002Fclaudecode.nvim\",\n  dependencies = { \"folke\u002Fsnacks.nvim\" },\n  opts = {\n    terminal_cmd = \"~\u002F.claude\u002Flocal\u002Fclaude\", -- Point to local installation\n  },\n  config = true,\n  keys = {\n    -- Your keymaps here\n  },\n}\n```\n\n\u003Cdetails>\n\u003Csummary>Native Binary Installation (Alpha)\u003C\u002Fsummary>\n\nClaude Code also offers an experimental native binary installation method currently in alpha testing. This provides a single executable with no Node.js dependencies.\n\n#### Installation Methods\n\nInstall the native binary using one of these methods:\n\n```bash\n# Fresh install (recommended)\ncurl -fsSL claude.ai\u002Finstall.sh | bash\n\n# From existing Claude Code installation\nclaude install\n```\n\n#### Platform Support\n\n- **macOS**: Full support for Intel and Apple Silicon\n- **Linux**: x64 and arm64 architectures\n- **Windows**: Via WSL (Windows Subsystem for Linux)\n\n#### Benefits\n\n- **Zero Dependencies**: Single executable file with no external requirements\n- **Cross-Platform**: Consistent experience across operating systems\n- **Secure Installation**: Includes checksum verification and automatic cleanup\n\n#### Configuring for Native Binary\n\nThe exact binary path depends on your shell integration. To find your installation:\n\n```bash\n# Check where claude command points\nwhich claude\n\n# Verify installation type and health\nclaude doctor\n```\n\nConfigure the plugin with the detected path:\n\n```lua\n{\n  \"coder\u002Fclaudecode.nvim\",\n  dependencies = { \"folke\u002Fsnacks.nvim\" },\n  opts = {\n    terminal_cmd = \"\u002Fpath\u002Fto\u002Fyour\u002Fclaude\", -- Use output from 'which claude'\n  },\n  config = true,\n  keys = {\n    -- Your keymaps here\n  },\n}\n```\n\n\u003C\u002Fdetails>\n\n> **Note**: If Claude Code was installed globally via npm, you can use the default configuration without specifying `terminal_cmd`.\n\n## Quick Demo\n\n```vim\n\" Launch Claude Code in a split\n:ClaudeCode\n\n\" Claude now sees your current file and selections in real-time!\n\n\" Send visual selection as context\n:'\u003C,'>ClaudeCodeSend\n\n\" Claude can open files, show diffs, and more\n```\n\n## Usage\n\n1. **Launch Claude**: Run `:ClaudeCode` to open Claude in a split terminal\n2. **Send context**:\n   - Select text in visual mode and use `\u003Cleader>as` to send it to Claude\n   - In `nvim-tree`\u002F`neo-tree`\u002F`oil.nvim`\u002F`mini.nvim`, press `\u003Cleader>as` on a file to add it to Claude's context\n3. **Let Claude work**: Claude can now:\n   - See your current file and selections in real-time\n   - Open files in your editor\n   - Show diffs with proposed changes\n   - Access diagnostics and workspace info\n\n## Key Commands\n\n- `:ClaudeCode` - Toggle the Claude Code terminal window\n- `:ClaudeCodeFocus` - Smart focus\u002Ftoggle Claude terminal\n- `:ClaudeCodeSelectModel` - Select Claude model and open terminal with optional arguments\n- `:ClaudeCodeSend` - Send current visual selection to Claude\n- `:ClaudeCodeAdd \u003Cfile-path> [start-line] [end-line]` - Add specific file to Claude context with optional line range\n- `:ClaudeCodeDiffAccept` - Accept diff changes\n- `:ClaudeCodeDiffDeny` - Reject diff changes\n\n## Working with Diffs\n\nWhen Claude proposes changes, the plugin opens a native Neovim diff view:\n\n- **Accept**: `:w` (save) or `\u003Cleader>aa`\n- **Reject**: `:q` or `\u003Cleader>ad`\n\nYou can edit Claude's suggestions before accepting them.\n\n## How It Works\n\nThis plugin creates a WebSocket server that Claude Code CLI connects to, implementing the same protocol as the official VS Code extension. When you launch Claude, it automatically detects Neovim and gains full access to your editor.\n\nThe protocol uses a WebSocket-based variant of MCP (Model Context Protocol) that:\n\n1. Creates a WebSocket server on a random port\n2. Writes a lock file to `~\u002F.claude\u002Fide\u002F[port].lock` (or `$CLAUDE_CONFIG_DIR\u002Fide\u002F[port].lock` if `CLAUDE_CONFIG_DIR` is set) with connection info\n3. Sets environment variables that tell Claude where to connect\n4. Implements MCP tools that Claude can call\n\n📖 **[Read the full reverse-engineering story →](.\u002FSTORY.md)**\n🔧 **[Complete protocol documentation →](.\u002FPROTOCOL.md)**\n\n## Architecture\n\nBuilt with pure Lua and zero external dependencies:\n\n- **WebSocket Server** - RFC 6455 compliant implementation using `vim.loop`\n- **MCP Protocol** - Full JSON-RPC 2.0 message handling\n- **Lock File System** - Enables Claude CLI discovery\n- **Selection Tracking** - Real-time context updates\n- **Native Diff Support** - Seamless file comparison\n\nFor deep technical details, see [ARCHITECTURE.md](.\u002FARCHITECTURE.md).\n\n## Advanced Configuration\n\n```lua\n{\n  \"coder\u002Fclaudecode.nvim\",\n  dependencies = { \"folke\u002Fsnacks.nvim\" },\n  opts = {\n    -- Server Configuration\n    port_range = { min = 10000, max = 65535 },\n    auto_start = true,\n    log_level = \"info\", -- \"trace\", \"debug\", \"info\", \"warn\", \"error\"\n    terminal_cmd = nil, -- Custom terminal command (default: \"claude\")\n                        -- For local installations: \"~\u002F.claude\u002Flocal\u002Fclaude\"\n                        -- For native binary: use output from 'which claude'\n\n    -- Send\u002FFocus Behavior\n    -- When true, successful sends will focus the Claude terminal if already connected\n    focus_after_send = false,\n\n    -- Selection Tracking\n    track_selection = true,\n    visual_demotion_delay_ms = 50,\n\n    -- Terminal Configuration\n    terminal = {\n      split_side = \"right\", -- \"left\" or \"right\"\n      split_width_percentage = 0.30,\n      provider = \"auto\", -- \"auto\", \"snacks\", \"native\", \"external\", \"none\", or custom provider table\n      auto_close = true,\n      snacks_win_opts = {}, -- Opts to pass to `Snacks.terminal.open()` - see Floating Window section below\n\n      -- Provider-specific options\n      provider_opts = {\n        -- Command for external terminal provider. Can be:\n        -- 1. String with %s placeholder: \"alacritty -e %s\" (backward compatible)\n        -- 2. String with two %s placeholders: \"alacritty --working-directory %s -e %s\" (cwd, command)\n        -- 3. Function returning command: function(cmd, env) return \"alacritty -e \" .. cmd end\n        external_terminal_cmd = nil,\n      },\n    },\n\n    -- Diff Integration\n    diff_opts = {\n      layout = \"vertical\", -- \"vertical\" or \"horizontal\"\n      open_in_new_tab = false,\n      keep_terminal_focus = false, -- If true, moves focus back to terminal after diff opens\n      hide_terminal_in_new_tab = false,\n      -- on_new_file_reject = \"keep_empty\", -- \"keep_empty\" or \"close_window\"\n\n      -- Legacy aliases (still supported):\n      -- vertical_split = true,\n      -- open_in_current_tab = true,\n    },\n  },\n  keys = {\n    -- Your keymaps here\n  },\n}\n```\n\n### Working Directory Control\n\nYou can fix the Claude terminal's working directory regardless of `autochdir` and buffer-local cwd changes. Options (precedence order):\n\n- `cwd_provider(ctx)`: function that returns a directory string. Receives `{ file, file_dir, cwd }`.\n- `cwd`: static path to use as working directory.\n- `git_repo_cwd = true`: resolves git root from the current file directory (or cwd if no file).\n\nExamples:\n\n```lua\nrequire(\"claudecode\").setup({\n  -- Top-level aliases are supported and forwarded to terminal config\n  git_repo_cwd = true,\n})\n\nrequire(\"claudecode\").setup({\n  terminal = {\n    cwd = vim.fn.expand(\"~\u002Fprojects\u002Fmy-app\"),\n  },\n})\n\nrequire(\"claudecode\").setup({\n  terminal = {\n    cwd_provider = function(ctx)\n      -- Prefer repo root; fallback to file's directory\n      local cwd = require(\"claudecode.cwd\").git_root(ctx.file_dir or ctx.cwd) or ctx.file_dir or ctx.cwd\n      return cwd\n    end,\n  },\n})\n```\n\n## Floating Window Configuration\n\nThe `snacks_win_opts` configuration allows you to create floating Claude Code terminals with custom positioning, sizing, and key bindings. Here are several practical examples:\n\n### Basic Floating Window with Ctrl+, Toggle\n\n```lua\nlocal toggle_key = \"\u003CC-,>\"\nreturn {\n  {\n    \"coder\u002Fclaudecode.nvim\",\n    dependencies = { \"folke\u002Fsnacks.nvim\" },\n    keys = {\n      { toggle_key, \"\u003Ccmd>ClaudeCodeFocus\u003Ccr>\", desc = \"Claude Code\", mode = { \"n\", \"x\" } },\n    },\n    opts = {\n      terminal = {\n        ---@module \"snacks\"\n        ---@type snacks.win.Config|{}\n        snacks_win_opts = {\n          position = \"float\",\n          width = 0.9,\n          height = 0.9,\n          keys = {\n            claude_hide = {\n              toggle_key,\n              function(self)\n                self:hide()\n              end,\n              mode = \"t\",\n              desc = \"Hide\",\n            },\n          },\n        },\n      },\n    },\n  },\n}\n```\n\n\u003Cdetails>\n\u003Csummary>Alternative with Meta+, (Alt+,) Toggle\u003C\u002Fsummary>\n\n```lua\nlocal toggle_key = \"\u003CM-,>\"  -- Alt\u002FMeta + comma\nreturn {\n  {\n    \"coder\u002Fclaudecode.nvim\",\n    dependencies = { \"folke\u002Fsnacks.nvim\" },\n    keys = {\n      { toggle_key, \"\u003Ccmd>ClaudeCodeFocus\u003Ccr>\", desc = \"Claude Code\", mode = { \"n\", \"x\" } },\n    },\n    opts = {\n      terminal = {\n        snacks_win_opts = {\n          position = \"float\",\n          width = 0.8,\n          height = 0.8,\n          border = \"rounded\",\n          keys = {\n            claude_hide = { toggle_key, function(self) self:hide() end, mode = \"t\", desc = \"Hide\" },\n          },\n        },\n      },\n    },\n  },\n}\n```\n\n\u003C\u002Fdetails>\n\n\u003Cdetails>\n\u003Csummary>Centered Floating Window with Custom Styling\u003C\u002Fsummary>\n\n```lua\nrequire(\"claudecode\").setup({\n  terminal = {\n    snacks_win_opts = {\n      position = \"float\",\n      width = 0.6,\n      height = 0.6,\n      border = \"double\",\n      backdrop = 80,\n      keys = {\n        claude_hide = { \"\u003CEsc>\", function(self) self:hide() end, mode = \"t\", desc = \"Hide\" },\n        claude_close = { \"q\", \"close\", mode = \"n\", desc = \"Close\" },\n      },\n    },\n  },\n})\n```\n\n\u003C\u002Fdetails>\n\n\u003Cdetails>\n\u003Csummary>Multiple Key Binding Options\u003C\u002Fsummary>\n\n```lua\n{\n  \"coder\u002Fclaudecode.nvim\",\n  dependencies = { \"folke\u002Fsnacks.nvim\" },\n  keys = {\n    { \"\u003CC-,>\", \"\u003Ccmd>ClaudeCodeFocus\u003Ccr>\", desc = \"Claude Code (Ctrl+,)\", mode = { \"n\", \"x\" } },\n    { \"\u003CM-,>\", \"\u003Ccmd>ClaudeCodeFocus\u003Ccr>\", desc = \"Claude Code (Alt+,)\", mode = { \"n\", \"x\" } },\n    { \"\u003Cleader>tc\", \"\u003Ccmd>ClaudeCodeFocus\u003Ccr>\", desc = \"Toggle Claude\", mode = { \"n\", \"x\" } },\n  },\n  opts = {\n    terminal = {\n      snacks_win_opts = {\n        position = \"float\",\n        width = 0.85,\n        height = 0.85,\n        border = \"rounded\",\n        keys = {\n          -- Multiple ways to hide from terminal mode\n          claude_hide_ctrl = { \"\u003CC-,>\", function(self) self:hide() end, mode = \"t\", desc = \"Hide (Ctrl+,)\" },\n          claude_hide_alt = { \"\u003CM-,>\", function(self) self:hide() end, mode = \"t\", desc = \"Hide (Alt+,)\" },\n          claude_hide_esc = { \"\u003CC-\\\\>\u003CC-n>\", function(self) self:hide() end, mode = \"t\", desc = \"Hide (Ctrl+\\\\)\" },\n        },\n      },\n    },\n  },\n}\n```\n\n\u003C\u002Fdetails>\n\n\u003Cdetails>\n\u003Csummary>Window Position Variations\u003C\u002Fsummary>\n\n```lua\n-- Bottom floating (like a drawer)\nsnacks_win_opts = {\n  position = \"bottom\",\n  height = 0.4,\n  width = 1.0,\n  border = \"single\",\n}\n\n-- Side floating panel\nsnacks_win_opts = {\n  position = \"right\",\n  width = 0.4,\n  height = 1.0,\n  border = \"rounded\",\n}\n\n-- Small centered popup\nsnacks_win_opts = {\n  position = \"float\",\n  width = 120,  -- Fixed width in columns\n  height = 30,  -- Fixed height in rows\n  border = \"double\",\n  backdrop = 90,\n}\n```\n\n\u003C\u002Fdetails>\n\nFor complete configuration options, see:\n\n- [Snacks.nvim Terminal Documentation](https:\u002F\u002Fgithub.com\u002Ffolke\u002Fsnacks.nvim\u002Fblob\u002Fmain\u002Fdocs\u002Fterminal.md)\n- [Snacks.nvim Window Documentation](https:\u002F\u002Fgithub.com\u002Ffolke\u002Fsnacks.nvim\u002Fblob\u002Fmain\u002Fdocs\u002Fwin.md)\n\n## Terminal Providers\n\n### None (No-Op) Provider\n\nRun Claude Code without any terminal management inside Neovim. This is useful for advanced setups where you manage the CLI externally (tmux, kitty, separate terminal windows) while still using the WebSocket server and tools.\n\nYou have to take care of launching CC and connecting it to the IDE yourself. (e.g. `claude --ide` or launching claude and then selecting the IDE using the `\u002Fide` command)\n\n```lua\n{\n  \"coder\u002Fclaudecode.nvim\",\n  opts = {\n    terminal = {\n      provider = \"none\", -- no UI actions; server + tools remain available\n    },\n  },\n}\n```\n\nNotes:\n\n- No windows\u002Fbuffers are created. `:ClaudeCode` and related commands will not open anything.\n- The WebSocket server still starts and broadcasts work as usual. Launch the Claude CLI externally when desired.\n\n### External Terminal Provider\n\nRun Claude Code in a separate terminal application outside of Neovim:\n\n```lua\n-- Using a string template (simple)\n{\n  \"coder\u002Fclaudecode.nvim\",\n  opts = {\n    terminal = {\n      provider = \"external\",\n      provider_opts = {\n        external_terminal_cmd = \"alacritty -e %s\", -- %s is replaced with claude command\n        -- Or with working directory: \"alacritty --working-directory %s -e %s\" (first %s = cwd, second %s = command)\n      },\n    },\n  },\n}\n\n-- Using a function for dynamic command generation (advanced)\n{\n  \"coder\u002Fclaudecode.nvim\",\n  opts = {\n    terminal = {\n      provider = \"external\",\n      provider_opts = {\n        external_terminal_cmd = function(cmd, env)\n          -- You can build complex commands based on environment or conditions\n          if vim.fn.has(\"mac\") == 1 then\n            return { \"osascript\", \"-e\", string.format('tell app \"Terminal\" to do script \"%s\"', cmd) }\n          else\n            return \"alacritty -e \" .. cmd\n          end\n        end,\n      },\n    },\n  },\n}\n```\n\n### Custom Terminal Providers\n\nYou can create custom terminal providers by passing a table with the required functions instead of a string provider name:\n\n```lua\nrequire(\"claudecode\").setup({\n  terminal = {\n    provider = {\n      -- Required functions\n      setup = function(config)\n        -- Initialize your terminal provider\n      end,\n\n      open = function(cmd_string, env_table, effective_config, focus)\n        -- Open terminal with command and environment\n        -- focus parameter controls whether to focus terminal (defaults to true)\n      end,\n\n      close = function()\n        -- Close the terminal\n      end,\n\n      simple_toggle = function(cmd_string, env_table, effective_config)\n        -- Simple show\u002Fhide toggle\n      end,\n\n      focus_toggle = function(cmd_string, env_table, effective_config)\n        -- Smart toggle: focus terminal if not focused, hide if focused\n      end,\n\n      get_active_bufnr = function()\n        -- Return terminal buffer number or nil\n        return 123 -- example\n      end,\n\n      is_available = function()\n        -- Return true if provider can be used\n        return true\n      end,\n\n      -- Optional functions (auto-generated if not provided)\n      toggle = function(cmd_string, env_table, effective_config)\n        -- Defaults to calling simple_toggle for backward compatibility\n      end,\n\n      _get_terminal_for_test = function()\n        -- For testing only, defaults to return nil\n        return nil\n      end,\n    },\n  },\n})\n```\n\n### Custom Provider Example\n\nHere's a complete example using a hypothetical `my_terminal` plugin:\n\n```lua\nlocal my_terminal_provider = {\n  setup = function(config)\n    -- Store config for later use\n    self.config = config\n  end,\n\n  open = function(cmd_string, env_table, effective_config, focus)\n    if focus == nil then focus = true end\n\n    local my_terminal = require(\"my_terminal\")\n    my_terminal.open({\n      cmd = cmd_string,\n      env = env_table,\n      width = effective_config.split_width_percentage,\n      side = effective_config.split_side,\n      focus = focus,\n    })\n  end,\n\n  close = function()\n    require(\"my_terminal\").close()\n  end,\n\n  simple_toggle = function(cmd_string, env_table, effective_config)\n    require(\"my_terminal\").toggle()\n  end,\n\n  focus_toggle = function(cmd_string, env_table, effective_config)\n    local my_terminal = require(\"my_terminal\")\n    if my_terminal.is_focused() then\n      my_terminal.hide()\n    else\n      my_terminal.focus()\n    end\n  end,\n\n  get_active_bufnr = function()\n    return require(\"my_terminal\").get_bufnr()\n  end,\n\n  is_available = function()\n    local ok, _ = pcall(require, \"my_terminal\")\n    return ok\n  end,\n}\n\nrequire(\"claudecode\").setup({\n  terminal = {\n    provider = my_terminal_provider,\n  },\n})\n```\n\nThe custom provider will automatically fall back to the native provider if validation fails or `is_available()` returns false.\n\nNote: If your command or working directory may contain spaces or special characters, prefer returning a table of args from a function (e.g., `{ \"alacritty\", \"--working-directory\", cwd, \"-e\", \"claude\", \"--help\" }`) to avoid shell-quoting issues.\n\n## Community Extensions\n\nThe following are third-party community extensions that complement claudecode.nvim. **These extensions are not affiliated with Coder and are maintained independently by community members.** We do not ensure that these extensions work correctly or provide support for them.\n\n### 🔍 [claude-fzf.nvim](https:\u002F\u002Fgithub.com\u002Fpittcat\u002Fclaude-fzf.nvim)\n\nIntegrates fzf-lua's file selection with claudecode.nvim's context management:\n\n- Batch file selection with fzf-lua multi-select\n- Smart search integration with grep → Claude\n- Tree-sitter based context extraction\n- Support for files, buffers, git files\n\n### 📚 [claude-fzf-history.nvim](https:\u002F\u002Fgithub.com\u002Fpittcat\u002Fclaude-fzf-history.nvim)\n\nProvides convenient Claude interaction history management and access for enhanced workflow continuity.\n\n> **Disclaimer**: These community extensions are developed and maintained by independent contributors. The authors and their extensions are not affiliated with Coder. Use at your own discretion and refer to their respective repositories for installation instructions, documentation, and support.\n\n## Auto-Save Plugin Issues\n\nUsing auto-save plugins can cause diff windows opened by Claude to immediately accept without waiting for input. You can avoid this using a custom condition:\n\n\u003Cdetails>\n\u003Csummary>Pocco81\u002Fauto-save.nvim\u003C\u002Fsummary>\n\n```lua\nopts = {\n  -- ... other options\n  condition = function(buf)\n    local fn = vim.fn\n    local utils = require(\"auto-save.utils.data\")\n\n    -- First check the default conditions\n    if not (fn.getbufvar(buf, \"&modifiable\") == 1 and utils.not_in(fn.getbufvar(buf, \"&filetype\"), {})) then\n      return false\n    end\n\n    -- Exclude claudecode diff buffers by buffer name patterns\n    local bufname = vim.api.nvim_buf_get_name(buf)\n    if bufname:match(\"%(proposed%)\") or\n       bufname:match(\"%(NEW FILE %- proposed%)\") or\n       bufname:match(\"%(New%)\") then\n      return false\n    end\n\n    -- Exclude by buffer variables (claudecode sets these)\n    if vim.b[buf].claudecode_diff_tab_name or\n       vim.b[buf].claudecode_diff_new_win or\n       vim.b[buf].claudecode_diff_target_win then\n      return false\n    end\n\n    -- Exclude by buffer type (claudecode diff buffers use \"acwrite\")\n    local buftype = fn.getbufvar(buf, \"&buftype\")\n    if buftype == \"acwrite\" then\n      return false\n    end\n\n    return true -- Safe to auto-save\n  end,\n},\n```\n\n\u003C\u002Fdetails>\n\u003Cdetails>\n\u003Csummary>okuuva\u002Fauto-save.nvim\u003C\u002Fsummary>\n\n```lua\nopts = {\n  -- ... other options\n  condition = function(buf)\n    -- Exclude claudecode diff buffers by buffer name patterns\n    local bufname = vim.api.nvim_buf_get_name(buf)\n    if bufname:match('%(proposed%)') or bufname:match('%(NEW FILE %- proposed%)') or bufname:match('%(New%)') then\n      return false\n    end\n\n    -- Exclude by buffer variables (claudecode sets these)\n    if\n      vim.b[buf].claudecode_diff_tab_name\n      or vim.b[buf].claudecode_diff_new_win\n      or vim.b[buf].claudecode_diff_target_win\n    then\n      return false\n    end\n\n    -- Exclude by buffer type (claudecode diff buffers use \"acwrite\")\n    local buftype = vim.fn.getbufvar(buf, '&buftype')\n    if buftype == 'acwrite' then\n      return false\n    end\n\n    return true -- Safe to auto-save\n  end,\n},\n```\n\n\u003C\u002Fdetails>\n\n## Troubleshooting\n\n- **Claude not connecting?** Check `:ClaudeCodeStatus` and verify lock file exists in `~\u002F.claude\u002Fide\u002F` (or `$CLAUDE_CONFIG_DIR\u002Fide\u002F` if `CLAUDE_CONFIG_DIR` is set)\n- **Need debug logs?** Set `log_level = \"debug\"` in opts\n- **Terminal issues?** Try `provider = \"native\"` if using snacks.nvim\n- **Local installation not working?** If you used `claude migrate-installer`, set `terminal_cmd = \"~\u002F.claude\u002Flocal\u002Fclaude\"` in your config. Check `which claude` vs `ls ~\u002F.claude\u002Flocal\u002Fclaude` to verify your installation type.\n- **Native binary installation not working?** If you used the alpha native binary installer, run `claude doctor` to verify installation health and use `which claude` to find the binary path. Set `terminal_cmd = \"\u002Fpath\u002Fto\u002Fclaude\"` with the detected path in your config.\n\n## Contributing\n\nSee [DEVELOPMENT.md](.\u002FDEVELOPMENT.md) for build instructions and development guidelines. Tests can be run with `make test`.\n\n## License\n\n[MIT](LICENSE)\n\n## Acknowledgements\n\n- [Claude Code CLI](https:\u002F\u002Fdocs.anthropic.com\u002Fen\u002Fdocs\u002Fclaude-code) by Anthropic\n- Inspired by analyzing the official VS Code extension\n- Built with assistance from AI (how meta!)\n","claudecode.nvim 是一个将 Anthropic 的 AI 编码助手 Claude Code 集成到 Neovim 中的插件。该项目使用纯 Lua 语言编写，无外部依赖，实现了与官方扩展相同的 WebSocket 基于 MCP 协议，确保了与 VS Code 和 JetBrains 平台上相同的功能体验。其特点包括完全兼容的协议实现、详尽的文档支持以及利用 AI 技术进行反向工程开发。适用于寻求在 Neovim 环境下获得先进AI辅助编码能力的开发者。要求用户安装 Neovim 0.8 或更高版本及 Claude Code CLI。",2,"2026-06-11 03:45:17","high_star"]