Skip to content

Commit d3e1c1f

Browse files
blink-so[bot]ThomasK33
andcommitted
feat: implement visual selection detection for neo-tree multi-file selection
- Rewrite neo-tree selection detection to handle visual mode properly - Map line numbers to nodes to get files from visual selection range - Try multiple approaches: visual mode detection, get_selection, state.selected_nodes - Add comprehensive debug logging to understand selection behavior - Fix luacheck warning about unused variable This should properly detect when multiple files are selected in neo-tree using visual mode and send each file as a separate at_mention. Co-authored-by: ThomasK33 <[email protected]>
1 parent 24ff09a commit d3e1c1f

File tree

1 file changed

+61
-36
lines changed

1 file changed

+61
-36
lines changed

lua/claudecode/integrations.lua

Lines changed: 61 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -81,55 +81,82 @@ function M._get_neotree_selection()
8181
end
8282

8383
local files = {}
84+
local selection = nil
8485

85-
-- Debug: Check what methods are available
86-
if state.tree then
87-
logger.debug("integrations", "neo-tree state.tree available, checking for selection methods")
86+
-- Debug: Log available state structure
87+
logger.debug("integrations", "neo-tree state available, checking for selection")
8888

89-
-- Try different approaches for multi-selection
90-
local selection = nil
89+
-- Method 1: Check for visual selection in neo-tree (when using V to select multiple lines)
90+
-- This is likely what happens when you select multiple files with visual mode
9191

92-
-- Method 1: get_selection
93-
if state.tree.get_selection then
94-
selection = state.tree:get_selection()
95-
logger.debug(
96-
"integrations",
97-
"get_selection method available, selection count: " .. (selection and #selection or "nil")
98-
)
99-
else
100-
logger.debug("integrations", "get_selection method not available")
92+
-- Get visual selection range if in visual mode
93+
local mode = vim.fn.mode()
94+
if mode == "V" or mode == "v" or mode == "\22" then -- Visual modes
95+
logger.debug("integrations", "Visual mode detected: " .. mode)
96+
97+
-- Get the visual selection range
98+
local start_line = vim.fn.line("v")
99+
local end_line = vim.fn.line(".")
100+
if start_line > end_line then
101+
start_line, end_line = end_line, start_line
101102
end
102103

103-
-- Method 2: Check for selected nodes directly
104-
if not selection or #selection == 0 then
105-
if state.tree.get_nodes then
106-
local nodes = state.tree:get_nodes()
107-
if nodes then
108-
for _, node in ipairs(nodes) do
109-
if node.is_selected or (node.extra and node.extra.is_selected) then
110-
selection = selection or {}
111-
table.insert(selection, node)
112-
logger.debug(
113-
"integrations",
114-
"Found selected node via is_selected: " .. (node.path or node.name or "unknown")
115-
)
104+
logger.debug("integrations", "Visual selection from line " .. start_line .. " to " .. end_line)
105+
106+
-- Get the rendered tree to map line numbers to file paths
107+
if state.tree and state.tree.get_nodes then
108+
local nodes = state.tree:get_nodes()
109+
if nodes then
110+
local line_to_node = {}
111+
112+
-- Build a mapping of line numbers to nodes
113+
local function map_nodes(node_list, depth)
114+
depth = depth or 0
115+
for _, node in ipairs(node_list) do
116+
if node.position and node.position.row then
117+
line_to_node[node.position.row] = node
118+
end
119+
if node.children then
120+
map_nodes(node.children, depth + 1)
116121
end
117122
end
118123
end
124+
125+
map_nodes(nodes)
126+
127+
-- Get files from selected lines
128+
for line = start_line, end_line do
129+
local node = line_to_node[line]
130+
if node and node.type == "file" and node.path then
131+
table.insert(files, node.path)
132+
logger.debug("integrations", "Added file from line " .. line .. ": " .. node.path)
133+
end
134+
end
135+
136+
if #files > 0 then
137+
return files, nil
138+
end
119139
end
120140
end
141+
end
121142

122-
-- Method 3: Try to get selected items via neo-tree's selection state
123-
if not selection or #selection == 0 then
124-
if state.selected_nodes then
125-
selection = state.selected_nodes
126-
logger.debug("integrations", "Using state.selected_nodes, count: " .. #selection)
143+
-- Method 2: Try neo-tree's built-in selection methods
144+
if state.tree then
145+
if state.tree.get_selection then
146+
selection = state.tree:get_selection()
147+
if selection and #selection > 0 then
148+
logger.debug("integrations", "Found selection via get_selection: " .. #selection)
127149
end
128150
end
129151

130-
-- Process the selection if found
152+
-- Method 3: Check state-level selection
153+
if (not selection or #selection == 0) and state.selected_nodes then
154+
selection = state.selected_nodes
155+
logger.debug("integrations", "Found selection via state.selected_nodes: " .. #selection)
156+
end
157+
158+
-- Process selection if found
131159
if selection and #selection > 0 then
132-
logger.debug("integrations", "Found " .. #selection .. " selected items in neo-tree")
133160
for _, node in ipairs(selection) do
134161
if node.type == "file" and node.path then
135162
table.insert(files, node.path)
@@ -139,8 +166,6 @@ function M._get_neotree_selection()
139166
if #files > 0 then
140167
return files, nil
141168
end
142-
else
143-
logger.debug("integrations", "No multi-selection found, falling back to cursor node")
144169
end
145170
end
146171

0 commit comments

Comments
 (0)