Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ When Anthropic released Claude Code, they only supported VS Code and JetBrains.
"<leader>as",
"<cmd>ClaudeCodeTreeAdd<cr>",
desc = "Add file",
ft = { "NvimTree", "neo-tree", "oil", "minifiles" },
ft = { "NvimTree", "neo-tree", "oil", "minifiles", "netrw" },
},
-- Diff management
{ "<leader>aa", "<cmd>ClaudeCodeDiffAccept<cr>", desc = "Accept diff" },
Expand Down
2 changes: 1 addition & 1 deletion dev-config.lua
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ return {
"<leader>as",
"<cmd>ClaudeCodeTreeAdd<cr>",
desc = "Add file from tree",
ft = { "NvimTree", "neo-tree", "oil", "minifiles" },
ft = { "NvimTree", "neo-tree", "oil", "minifiles", "netrw" },
},

-- Development helpers
Expand Down
1 change: 1 addition & 0 deletions lua/claudecode/diff.lua
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ local function find_main_editor_window()
or filetype == "NvimTree"
or filetype == "oil"
or filetype == "minifiles"
or filetype == "netrw"
or filetype == "aerial"
or filetype == "tagbar"
)
Expand Down
2 changes: 2 additions & 0 deletions lua/claudecode/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -656,6 +656,7 @@ function M._create_commands()
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://")
Expand Down Expand Up @@ -710,6 +711,7 @@ function M._create_commands()
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://")
Expand Down
71 changes: 71 additions & 0 deletions lua/claudecode/integrations.lua
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ function M.get_selected_files_from_tree()
return M._get_oil_selection()
elseif current_ft == "minifiles" then
return M._get_mini_files_selection()
elseif current_ft == "netrw" then
return M._get_netrw_selection()
else
return nil, "Not in a supported tree buffer (current filetype: " .. current_ft .. ")"
end
Expand Down Expand Up @@ -406,4 +408,73 @@ function M._get_mini_files_selection()
return {}, "No file found under cursor"
end

--- Get selected files from netrw
--- Supports both marked files and single file under cursor
--- Reference: :help netrw-mf, :help markfilelist
--- @return table files List of file paths
--- @return string|nil error Error message if operation failed
function M._get_netrw_selection()
local has_call = (vim.fn.exists("*netrw#Call") == 1)
local has_expose = (vim.fn.exists("*netrw#Expose") == 1)
if not (has_call and has_expose) then
return {}, "netrw not available"
end

-- function to resolve a 'word' (filename in netrw listing) to an absolute path using b:netrw_curdir
local function resolve_word_to_path(word)
if type(word) ~= "string" or word == "" then
return nil
end
if word == "." or word == ".." or word == "../" then
return nil
end
local curdir = vim.b.netrw_curdir or vim.fn.getcwd()
local joined = curdir .. "/" .. word
return vim.fn.fnamemodify(joined, ":p")
end

-- 1. Check for marked files
do
local mf_ok, mf_result = pcall(function()
if has_expose then
return vim.fn.call("netrw#Expose", { "netrwmarkfilelist" })
end
return nil
end)

local marked_files = {}
if mf_ok and type(mf_result) == "table" and #mf_result > 0 then
for _, file_path in ipairs(mf_result) do
if vim.fn.filereadable(file_path) == 1 or vim.fn.isdirectory(file_path) == 1 then
table.insert(marked_files, vim.fn.fnamemodify(file_path, ":p"))
end
end
end

if #marked_files > 0 then
return marked_files, nil
end
end

-- 2. No marked files. Check for a file or dir under cursor
local path_ok, path_result = pcall(function()
if has_call then
local word = vim.fn.call("netrw#Call", { "NetrwGetWord" })
local p = resolve_word_to_path(word)
return p
end
return nil
end)

if not path_ok or not path_result or path_result == "" then
return {}, "Failed to get path from netrw"
end

if vim.fn.filereadable(path_result) == 1 or vim.fn.isdirectory(path_result) == 1 then
return { path_result }, nil
end

return {}, "Invalid file or directory path: " .. path_result
end

return M
1 change: 1 addition & 0 deletions lua/claudecode/tools/open_file.lua
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ local function find_main_editor_window()
or filetype == "NvimTree"
or filetype == "oil"
or filetype == "minifiles"
or filetype == "netrw"
or filetype == "aerial"
or filetype == "tagbar"
)
Expand Down
36 changes: 36 additions & 0 deletions lua/claudecode/visual_commands.lua
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,8 @@ function M.get_tree_state()
end

return oil, "oil"
elseif current_ft == "netrw" then
return { curdir = vim.b.netrw_curdir }, "netrw"
else
return nil, nil
end
Expand Down Expand Up @@ -432,6 +434,40 @@ function M.get_files_from_visual_selection(visual_data)
end
end
end
elseif tree_type == "netrw" then
local netrw = tree_state

local function resolve_word_to_path(word)
if type(word) ~= "string" or word == "" then
return nil
end
if word == "." or word == ".." or word == "../" then
return nil
end
local curdir = netrw.curdir or vim.b.netrw_curdir or vim.fn.getcwd()
local joined = curdir .. "/" .. word
return vim.fn.fnamemodify(joined, ":p")
end

if start_pos and end_pos then
local cursor_pos = vim.api.nvim_win_get_cursor(0)

-- Move cursor to each line and do NetrwGetWord
for lnum = start_pos, end_pos do
pcall(vim.api.nvim_win_set_cursor, 0, { lnum, 0 })
local ok, word = pcall(function()
return vim.fn.call("netrw#Call", { "NetrwGetWord" })
end)
if ok then
local path = resolve_word_to_path(word)
if path and (vim.fn.filereadable(path) == 1 or vim.fn.isdirectory(path) == 1) then
table.insert(files, path)
end
end
end

pcall(vim.api.nvim_win_set_cursor, 0, cursor_pos)
end
end

return files, nil
Expand Down
Loading