1
1
---
2
2
-- Tree integration module for ClaudeCode.nvim
3
- -- Handles detection and selection of files from nvim-tree and neo-tree
3
+ -- Handles detection and selection of files from nvim-tree, neo-tree, and oil.nvim
4
4
-- @module claudecode.integrations
5
5
local M = {}
6
6
@@ -14,6 +14,8 @@ function M.get_selected_files_from_tree()
14
14
return M ._get_nvim_tree_selection ()
15
15
elseif current_ft == " neo-tree" then
16
16
return M ._get_neotree_selection ()
17
+ elseif current_ft == " oil" then
18
+ return M ._get_oil_selection ()
17
19
else
18
20
return nil , " Not in a supported tree buffer (current filetype: " .. current_ft .. " )"
19
21
end
@@ -178,4 +180,87 @@ function M._get_neotree_selection()
178
180
return {}, " No file found under cursor"
179
181
end
180
182
183
+
184
+
185
+ --- Get selected files from oil.nvim
186
+ --- Supports both visual selection and single file under cursor
187
+ --- @return table files List of file paths
188
+ --- @return string | nil error Error message if operation failed
189
+ function M ._get_oil_selection ()
190
+ local success , oil = pcall (require , " oil" )
191
+ if not success then
192
+ return {}, " oil.nvim not available"
193
+ end
194
+
195
+ local bufnr = vim .api .nvim_get_current_buf () --[[ @as number]]
196
+ local files = {}
197
+
198
+ -- Check if we're in visual mode
199
+ local mode = vim .fn .mode ()
200
+ if mode == " V" or mode == " v" or mode == " \22 " then
201
+ -- Visual mode: use the common visual range function
202
+ local visual_commands = require (" claudecode.visual_commands" )
203
+ local start_line , end_line = visual_commands .get_visual_range ()
204
+
205
+ -- Get current directory once
206
+ local dir_ok , current_dir = pcall (oil .get_current_dir , bufnr )
207
+ if not dir_ok or not current_dir then
208
+ return {}, " Failed to get current directory"
209
+ end
210
+
211
+ -- Process each line in the visual selection
212
+ for line = start_line , end_line do
213
+ local entry_ok , entry = pcall (oil .get_entry_on_line , bufnr , line )
214
+ if entry_ok and entry and entry .name then
215
+ -- Skip parent directory entries
216
+ if entry .name ~= " .." and entry .name ~= " ." then
217
+ local full_path = current_dir .. entry .name
218
+ -- Handle various entry types
219
+ if entry .type == " file" or entry .type == " link" then
220
+ table.insert (files , full_path )
221
+ elseif entry .type == " directory" then
222
+ -- Ensure directory paths end with /
223
+ table.insert (files , full_path :match (" /$" ) and full_path or full_path .. " /" )
224
+ else
225
+ -- For unknown types, return the path anyway
226
+ table.insert (files , full_path )
227
+ end
228
+ end
229
+ end
230
+ end
231
+
232
+ if # files > 0 then
233
+ return files , nil
234
+ end
235
+ else
236
+ -- Normal mode: get file under cursor with error handling
237
+ local ok , entry = pcall (oil .get_cursor_entry )
238
+ if not ok or not entry then
239
+ return {}, " Failed to get cursor entry"
240
+ end
241
+
242
+ local dir_ok , current_dir = pcall (oil .get_current_dir , bufnr )
243
+ if not dir_ok or not current_dir then
244
+ return {}, " Failed to get current directory"
245
+ end
246
+
247
+ -- Process the entry
248
+ if entry .name and entry .name ~= " .." and entry .name ~= " ." then
249
+ local full_path = current_dir .. entry .name
250
+ -- Handle various entry types
251
+ if entry .type == " file" or entry .type == " link" then
252
+ return { full_path }, nil
253
+ elseif entry .type == " directory" then
254
+ -- Ensure directory paths end with /
255
+ return { full_path :match (" /$" ) and full_path or full_path .. " /" }, nil
256
+ else
257
+ -- For unknown types, return the path anyway
258
+ return { full_path }, nil
259
+ end
260
+ end
261
+ end
262
+
263
+ return {}, " No file found under cursor"
264
+ end
265
+
181
266
return M
0 commit comments