Skip to content

[BUG] ClaudeCodeSend misclassifies regular buffers as tree buffers when file path contains "neo-tree" or "NvimTree" #289

Description

@gogongxt

Bug Description

ClaudeCodeSend misclassifies a regular file buffer as a "tree buffer" when the file path (not filetype) contains the substring neo-tree, NvimTree, or minifiles://. This causes visual selection sends to fail with:

ClaudeCode Error [ClaudeCode] [command] [ERROR] ClaudeCodeSend_visual->TreeAdd: Not in visual mode (current mode: n)

The root cause is in lua/claudecode/init.lua, where is_tree_buffer is determined by both filetype and substring matching against the buffer name:

local is_tree_buffer = current_ft == "NvimTree"
  or current_ft == "neo-tree"
  or current_ft == "oil"
  or current_ft == "minifiles"
  or current_ft == "netrw"
  or string.match(current_bufname, "neo%-tree")    -- ← false positive
  or string.match(current_bufname, "NvimTree")     -- ← false positive
  or string.match(current_bufname, "minifiles://")

When a user opens a file whose path contains one of those substrings (for example a Neovim config file named _neo-tree.lua, or anything under a directory called nvim-tree-config/), is_tree_buffer evaluates to true even though filetype is something like lua. The visual handler then tries to use tree-specific extraction via get_files_from_visual_selection, but:

  1. capture_visual_selection_data() returns nil because get_tree_state() correctly returns nil for a non-tree buffer.
  2. ESC has already been fed to exit visual mode.
  3. get_files_from_visual_selection(nil) calls validate_visual_mode(), which fails because we're now in normal mode → error logged.

This also affects the handle_send_normal path at lines 732-740 with the same string.match checks.

To Reproduce

Steps to reproduce:

  1. Create a file whose path contains the substring neo-tree, e.g. ~/.config/nvim/lua/plugins/_neo-tree_.lua.
  2. Open it in Neovim: nvim ~/.config/nvim/lua/plugins/_neo-tree_.lua.
  3. Start Claude Code: :ClaudeCodeStart (or whichever command you use).
  4. In the lua buffer, visually select a few lines and run :'<,'>ClaudeCodeSend (or the user's <leader>as mapping which calls ClaudeCodeSend).

Expected: the visual selection is sent to Claude.
Actual: error notification ClaudeCodeSend_visual->TreeAdd: Not in visual mode (current mode: n), nothing is sent.

Files whose paths do not contain neo-tree / NvimTree / minifiles:// work fine — which is why this bug appears intermittent (some files send, some don't).

Expected Behavior

is_tree_buffer should be determined by filetype only. The string.match(current_bufname, ...) checks are false positives — a regular file whose path happens to contain those substrings is not a tree buffer.

Environment

  • Neovim version: NVIM v0.12.2
  • Claude Code CLI version: 2.1.153
  • OS: macOS 15
  • Plugin version: 0.3.0 (commit e6c9dd4d4f144910b0066489100ad94b7133821f)

Suggested Fix

Remove the string.match(current_bufname, ...) lines from both handle_send_normal (around line 738-740) and handle_send_visual (around line 793-795). The filetype checks above them are sufficient and correct.

     local is_tree_buffer = current_ft == "NvimTree"
       or current_ft == "neo-tree"
       or current_ft == "oil"
       or current_ft == "minifiles"
       or current_ft == "netrw"
-      or string.match(current_bufname, "neo%-tree")
-      or string.match(current_bufname, "NvimTree")
-      or string.match(current_bufname, "minifiles://")

The minifiles:// check may still be needed if minifiles uses a virtual buffer name without setting filetype = "minifiles" — worth confirming with the minifiles integration. But the neo-tree and NvimTree substring checks appear redundant with the filetype checks and should be safe to remove.

Additional Context

Workaround for affected users: rename files so their paths don't contain neo-tree / NvimTree, or map the send key to a custom wrapper that calls send_at_mention_for_visual_selection directly instead of ClaudeCodeSend.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions