|
| 1 | +# snacks-picker fixture — triage for issue #192 |
| 2 | + |
| 3 | +Reproduces and explores [#192](https://github.com/coder/claudecode.nvim/issues/192): |
| 4 | +make adding the **highlighted/selected file in a snacks.nvim picker** to Claude's |
| 5 | +context work, instead of failing with: |
| 6 | + |
| 7 | +``` |
| 8 | +[ClaudeCode] [command] [ERROR] ClaudeCodeTreeAdd: Not in a supported tree buffer (current filetype: snacks_picker_list) |
| 9 | +``` |
| 10 | + |
| 11 | +Unlike the tree-explorer integrations (`nvim-tree`, `neo-tree`, `oil`, |
| 12 | +`mini.files`, `netrw`), a snacks **picker** is a modal fuzzy finder. Its window |
| 13 | +layout is: |
| 14 | + |
| 15 | +| window | filetype | buftype | usual focus | |
| 16 | +| ------ | --------------------- | -------- | --------------------------------- | |
| 17 | +| box | `snacks_layout_box` | `nofile` | — | |
| 18 | +| list | `snacks_picker_list` | `nofile` | only when you `<Tab>`/cycle to it | |
| 19 | +| input | `snacks_picker_input` | `prompt` | **default (insert mode)** | |
| 20 | + |
| 21 | +`:ClaudeCodeTreeAdd` only sees `snacks_picker_list` when the **list** window is |
| 22 | +focused — but the picker normally keeps focus in the **input** box. That is why |
| 23 | +the idiomatic fix is an in-picker _action bound to a key_, not an ex-command. |
| 24 | + |
| 25 | +Note: `Snacks.explorer()` is built on the picker and also uses the |
| 26 | +`snacks_picker_list` filetype, so the same code path covers both. |
| 27 | + |
| 28 | +## Run it |
| 29 | + |
| 30 | +```bash |
| 31 | +source fixtures/nvim-aliases.sh |
| 32 | +vv snacks-picker |
| 33 | +``` |
| 34 | + |
| 35 | +Then `:ClaudeCodeStart` (or it auto-starts), and: |
| 36 | + |
| 37 | +- `<leader>ff` → files picker, `<leader>fg` → grep picker. |
| 38 | + |
| 39 | +### Path A — zero-change WORKAROUND (works on stock claudecode.nvim) |
| 40 | + |
| 41 | +`lua/plugins/snacks.lua` registers a custom picker action `claude_add` bound to |
| 42 | +`<c-o>` in both the input and list windows. From the picker (input box, insert |
| 43 | +mode): |
| 44 | + |
| 45 | +1. Type to filter; optionally `<Tab>` to multi-select several files. |
| 46 | +2. Press `<c-o>` → the selected files (or the one under the cursor) are sent to |
| 47 | + Claude via the public `require("claudecode").send_at_mention()` API, and the |
| 48 | + picker closes. |
| 49 | + |
| 50 | +This needs **no changes to claudecode.nvim**. It mirrors how the community |
| 51 | +`claude-fzf.nvim` plugin integrates fzf-lua. |
| 52 | + |
| 53 | +### Path B — built-in command path |
| 54 | + |
| 55 | +The in-core `snacks_picker_list` handler (`integrations._get_snacks_picker_selection`) |
| 56 | +makes `:ClaudeCodeTreeAdd` work when the list window is focused: |
| 57 | + |
| 58 | +1. Open a picker, `<Tab>` to focus/cycle to the **list** window (filetype becomes |
| 59 | + `snacks_picker_list`). |
| 60 | +2. `:ClaudeCodeTreeAdd` (or `<leader>at`) → selected/cursor files are added. |
| 61 | + |
| 62 | +## Deterministic, headless proof (no Claude client needed) |
| 63 | + |
| 64 | +The behavior was validated headlessly: |
| 65 | + |
| 66 | +```text |
| 67 | +# Without the snacks_picker_list handler (the issue #192 state), list focused: |
| 68 | +focused_filetype: snacks_picker_list |
| 69 | +dispatch_error: Not in a supported tree buffer (current filetype: snacks_picker_list) |
| 70 | +
|
| 71 | +# With the in-core handler, 2 files multi-selected: |
| 72 | +handler_basenames: alpha.lua,beta.lua |
| 73 | +dispatch_files: 2 err: nil |
| 74 | +
|
| 75 | +# Key-bound action (Path A), 2 files multi-selected: |
| 76 | +send_at_mention_results: alpha.lua=true,beta.lua=true |
| 77 | +``` |
| 78 | + |
| 79 | +To reproduce headlessly, a small throwaway harness (not committed) opens a picker |
| 80 | +with `Snacks.picker.files({ cwd = ... })`, `vim.wait`s until |
| 81 | +`Snacks.picker.get()` returns a picker with items, focuses the list window, then |
| 82 | +calls `require("claudecode.integrations").get_selected_files_from_tree()` and |
| 83 | +inspects the returned paths. The committed unit test |
| 84 | +`tests/unit/snacks_picker_integration_spec.lua` covers the same logic |
| 85 | +deterministically with mocked snacks. |
0 commit comments