Skip to content

Commit 6f6b8d1

Browse files
authored
feat: add comprehensive tree explorer integration with @-mention support
## Summary - Add seamless integration with nvim-tree and neo-tree file explorers - Implement @-mention functionality for files and directories via new ClaudeCodeTreeAdd and ClaudeCodeAdd commands - Enable Claude to navigate and understand project file structures through visual selection - Add support for new file creation in diff system with proper directory handling ## New Features - **Tree Integration**: Context-aware <leader>as keybinding that sends text in normal buffers or adds files from tree explorers - **@-mention Commands**: - `:ClaudeCodeTreeAdd` - Add selected files from tree explorers to Claude context - `:ClaudeCodeAdd <path> [start] [end]` - Add files/directories by path with optional line ranges - **Enhanced Diff System**: Support for creating new files with automatic parent directory creation - **Visual Selection**: Improved multi-file selection detection for both nvim-tree and neo-tree ## Technical Improvements - Comprehensive test coverage with dedicated specs for @-mention functionality - Improved error handling and user feedback for edge cases - Enhanced build system with Nix integration for consistent development environment - Code cleanup and maintainability improvements throughout codebase ## Breaking Changes None - all changes are additive and backward compatible. Fixes #14 Merge pull request #22 from coder/thomask33/nvim-tree-integration
1 parent c1cdcd5 commit 6f6b8d1

26 files changed

+3693
-333
lines changed

.github/workflows/test.yml

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -59,12 +59,9 @@ jobs:
5959

6060
- name: Generate coverage report
6161
run: |
62-
# Check if stats file exists (created by busted --coverage)
6362
if [ -f "luacov.stats.out" ]; then
64-
# Generate the regular luacov report
6563
nix develop .#ci -c luacov
6664
67-
# Create simple lcov.info from luacov.report.out
6865
echo "Creating lcov.info from luacov.report.out"
6966
{
7067
echo "TN:"
@@ -81,24 +78,20 @@ jobs:
8178
done
8279
} > lcov.info
8380
84-
# Create markdown coverage summary for GitHub Actions
8581
{
8682
echo "## 📊 Test Coverage Report"
8783
echo ""
8884
89-
# Extract overall coverage percentage
9085
if [ -f "luacov.report.out" ]; then
9186
overall_coverage=$(grep -E "Total.*%" luacov.report.out | grep -oE "[0-9]+\.[0-9]+%" | head -1)
9287
if [ -n "$overall_coverage" ]; then
9388
echo "**Overall Coverage: $overall_coverage**"
9489
echo ""
9590
fi
9691
97-
# Create table header
9892
echo "| File | Coverage |"
9993
echo "|------|----------|"
10094
101-
# Extract file-by-file coverage
10295
grep -E "^[^ ].*:" luacov.report.out | while read -r line; do
10396
file=$(echo "$line" | cut -d':' -f1)
10497
percent=$(echo "$line" | grep -oE "[0-9]+\.[0-9]+%" | head -1)

Makefile

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,18 @@
11
.PHONY: check format test clean
22

33
# Default target
4-
all: check format
4+
all: format check test
55

66
# Check for syntax errors
77
check:
88
@echo "Checking Lua files for syntax errors..."
9-
@find lua -name "*.lua" -type f -exec lua -e "assert(loadfile('{}'))" \;
9+
nix develop .#ci -c find lua -name "*.lua" -type f -exec lua -e "assert(loadfile('{}'))" \;
1010
@echo "Running luacheck..."
11-
@luacheck lua/ tests/ --no-unused-args --no-max-line-length
11+
nix develop .#ci -c luacheck lua/ tests/ --no-unused-args --no-max-line-length
1212

1313
# Format all files
1414
format:
15-
@echo "Formatting files..."
16-
@if command -v nix >/dev/null 2>&1; then \
17-
nix fmt; \
18-
elif command -v stylua >/dev/null 2>&1; then \
19-
stylua lua/; \
20-
else \
21-
echo "Neither nix nor stylua found. Please install one of them."; \
22-
exit 1; \
23-
fi
15+
nix fmt
2416

2517
# Run tests
2618
test:

README.md

Lines changed: 82 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,15 @@ Using [lazy.nvim](https://github.com/folke/lazy.nvim):
4949
"coder/claudecode.nvim",
5050
config = true,
5151
keys = {
52+
{ "<leader>a", nil, desc = "AI/Claude Code" },
5253
{ "<leader>ac", "<cmd>ClaudeCode<cr>", desc = "Toggle Claude" },
5354
{ "<leader>as", "<cmd>ClaudeCodeSend<cr>", mode = "v", desc = "Send to Claude" },
55+
{
56+
"<leader>as",
57+
"<cmd>ClaudeCodeTreeAdd<cr>",
58+
desc = "Add file",
59+
ft = { "NvimTree", "neo-tree" },
60+
},
5461
},
5562
}
5663
```
@@ -60,13 +67,80 @@ That's it! For more configuration options, see [Advanced Setup](#advanced-setup)
6067
## Usage
6168

6269
1. **Launch Claude**: Run `:ClaudeCode` to open Claude in a split terminal
63-
2. **Send context**: Select text and run `:'<,'>ClaudeCodeSend` to send it to Claude
70+
2. **Send context**:
71+
- Select text in visual mode and use `<leader>as` to send it to Claude
72+
- In `nvim-tree` or `neo-tree`, press `<leader>as` on a file to add it to Claude's context
6473
3. **Let Claude work**: Claude can now:
6574
- See your current file and selections in real-time
6675
- Open files in your editor
6776
- Show diffs with proposed changes
6877
- Access diagnostics and workspace info
6978

79+
## Commands
80+
81+
- `:ClaudeCode` - Toggle the Claude Code terminal window
82+
- `:ClaudeCodeSend` - Send current visual selection to Claude, or add files from tree explorer
83+
- `:ClaudeCodeTreeAdd` - Add selected file(s) from tree explorer to Claude context (also available via ClaudeCodeSend)
84+
- `:ClaudeCodeAdd <file-path> [start-line] [end-line]` - Add a specific file or directory to Claude context by path with optional line range
85+
86+
### Tree Integration
87+
88+
The `<leader>as` keybinding has context-aware behavior:
89+
90+
- **In normal buffers (visual mode)**: Sends selected text to Claude
91+
- **In nvim-tree/neo-tree buffers**: Adds the file under cursor (or selected files) to Claude's context
92+
93+
This allows you to quickly add entire files to Claude's context for review, refactoring, or discussion.
94+
95+
#### Features
96+
97+
- **Single file**: Place cursor on any file and press `<leader>as`
98+
- **Multiple files**: Select multiple files (using tree plugin's selection features) and press `<leader>as`
99+
- **Smart detection**: Automatically detects whether you're in nvim-tree or neo-tree
100+
- **Error handling**: Clear feedback if no files are selected or if tree plugins aren't available
101+
102+
### Direct File Addition
103+
104+
The `:ClaudeCodeAdd` command allows you to add files or directories directly by path, with optional line range specification:
105+
106+
```vim
107+
:ClaudeCodeAdd src/main.lua
108+
:ClaudeCodeAdd ~/projects/myproject/
109+
:ClaudeCodeAdd ./README.md
110+
:ClaudeCodeAdd src/main.lua 50 100 " Lines 50-100 only
111+
:ClaudeCodeAdd config.lua 25 " From line 25 to end of file
112+
```
113+
114+
#### Features
115+
116+
- **Path completion**: Tab completion for file and directory paths
117+
- **Path expansion**: Supports `~` for home directory and relative paths
118+
- **Line range support**: Optionally specify start and end lines for files (ignored for directories)
119+
- **Validation**: Checks that files and directories exist before adding, validates line numbers
120+
- **Flexible**: Works with both individual files and entire directories
121+
122+
#### Examples
123+
124+
```vim
125+
" Add entire files
126+
:ClaudeCodeAdd src/components/Header.tsx
127+
:ClaudeCodeAdd ~/.config/nvim/init.lua
128+
129+
" Add entire directories (line numbers ignored)
130+
:ClaudeCodeAdd tests/
131+
:ClaudeCodeAdd ../other-project/
132+
133+
" Add specific line ranges
134+
:ClaudeCodeAdd src/main.lua 50 100 " Lines 50 through 100
135+
:ClaudeCodeAdd config.lua 25 " From line 25 to end of file
136+
:ClaudeCodeAdd utils.py 1 50 " First 50 lines
137+
:ClaudeCodeAdd README.md 10 20 " Just lines 10-20
138+
139+
" Path expansion works with line ranges
140+
:ClaudeCodeAdd ~/project/src/app.js 100 200
141+
:ClaudeCodeAdd ./relative/path.lua 30
142+
```
143+
70144
## How It Works
71145

72146
This 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.
@@ -132,8 +206,15 @@ See [DEVELOPMENT.md](./DEVELOPMENT.md) for build instructions and development gu
132206
},
133207
config = true,
134208
keys = {
209+
{ "<leader>a", nil, desc = "AI/Claude Code" },
135210
{ "<leader>ac", "<cmd>ClaudeCode<cr>", desc = "Toggle Claude" },
136211
{ "<leader>as", "<cmd>ClaudeCodeSend<cr>", mode = "v", desc = "Send to Claude" },
212+
{
213+
"<leader>as",
214+
"<cmd>ClaudeCodeTreeAdd<cr>",
215+
desc = "Add file",
216+
ft = { "NvimTree", "neo-tree" },
217+
},
137218
{ "<leader>ao", "<cmd>ClaudeCodeOpen<cr>", desc = "Open Claude" },
138219
{ "<leader>ax", "<cmd>ClaudeCodeClose<cr>", desc = "Close Claude" },
139220
},

flake.lock

Lines changed: 6 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

flake.nix

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
luajitPackages.luacov
4141
neovim
4242
treefmt.config.build.wrapper
43+
findutils
4344
];
4445

4546
# Development packages (additional tools for development)
@@ -49,7 +50,7 @@
4950
gnumake
5051
websocat
5152
jq
52-
claude-code
53+
# claude-code
5354
];
5455
in
5556
{

lua/claudecode/config.lua

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ M.defaults = {
1818
}
1919

2020
--- Validates the provided configuration table.
21-
-- Ensures that all configuration options are of the correct type and within valid ranges.
2221
-- @param config table The configuration table to validate.
2322
-- @return boolean true if the configuration is valid.
2423
-- @error string if any configuration option is invalid.
@@ -54,7 +53,6 @@ function M.validate(config)
5453
"visual_demotion_delay_ms must be a non-negative number"
5554
)
5655

57-
-- Validate diff_opts
5856
assert(type(config.diff_opts) == "table", "diff_opts must be a table")
5957
assert(type(config.diff_opts.auto_close_on_accept) == "boolean", "diff_opts.auto_close_on_accept must be a boolean")
6058
assert(type(config.diff_opts.show_diff_stats) == "boolean", "diff_opts.show_diff_stats must be a boolean")
@@ -65,8 +63,6 @@ function M.validate(config)
6563
end
6664

6765
--- Applies user configuration on top of default settings and validates the result.
68-
-- Merges the user-provided configuration with the default configuration,
69-
-- then validates the merged configuration.
7066
-- @param user_config table|nil The user-provided configuration table.
7167
-- @return table The final, validated configuration table.
7268
function M.apply(user_config)

0 commit comments

Comments
 (0)