@@ -3,6 +3,10 @@ local luv = vim.loop
33local open_mode = luv .constants .O_CREAT + luv .constants .O_WRONLY + luv .constants .O_TRUNC
44
55local M = {}
6+ local clipboard = {
7+ move = {},
8+ copy = {}
9+ }
610
711local function clear_prompt ()
812 vim .api .nvim_command (' normal :esc<CR>' )
@@ -109,6 +113,95 @@ local function remove_dir(cwd)
109113 return luv .fs_rmdir (cwd )
110114end
111115
116+ local function do_copy (source , destination )
117+ local source_stats = luv .fs_stat (source )
118+
119+ if source_stats and source_stats .type == ' file' then
120+ return luv .fs_copyfile (source , destination )
121+ end
122+
123+ local handle = luv .fs_scandir (source )
124+
125+ if type (handle ) == ' string' then
126+ return false , handle
127+ end
128+
129+ luv .fs_mkdir (destination , source_stats .mode )
130+
131+ while true do
132+ local name , t = luv .fs_scandir_next (handle )
133+ if not name then break end
134+
135+ local new_name = source .. ' /' .. name
136+ local new_destination = destination .. ' /' .. name
137+ local success , msg = do_copy (new_name , new_destination )
138+ if not success then return success , msg end
139+ end
140+
141+ return true
142+ end
143+
144+ local function do_paste (node , action_type , action_fn )
145+ if node .name == ' ..' then return end
146+ local clip = clipboard [action_type ]
147+ if # clip == 0 then return end
148+
149+ local destination = node .absolute_path
150+ local stats = luv .fs_stat (destination )
151+ local is_dir = stats and stats .type == ' directory'
152+
153+ if not is_dir then
154+ destination = vim .fn .fnamemodify (destination , ' :p:h' )
155+ elseif not node .open then
156+ destination = vim .fn .fnamemodify (destination , ' :p:h:h' )
157+ end
158+
159+ local msg = # clip .. ' entries'
160+
161+ if # clip == 1 then
162+ msg = clip [1 ].absolute_path
163+ end
164+
165+ local ans = vim .fn .input (action_type .. ' ' .. msg .. ' to ' .. destination .. ' ? y/n: ' )
166+ clear_prompt ()
167+ if not ans :match (' ^y' ) then
168+ return api .nvim_out_write (' Canceled.\n ' )
169+ end
170+
171+ for _ , entry in ipairs (clip ) do
172+ local dest = destination .. ' /' .. entry .name
173+ local dest_stats = luv .fs_stat (dest )
174+ local should_process = true
175+ if dest_stats then
176+ local ans = vim .fn .input (dest .. ' already exists, overwrite ? y/n: ' )
177+ clear_prompt ()
178+ should_process = ans :match (' ^y' )
179+ end
180+
181+ if should_process then
182+ local success , msg = action_fn (entry .absolute_path , dest )
183+ if not success then
184+ api .nvim_err_writeln (' Could not ' .. action_type .. ' ' .. entry .absolute_path .. ' - ' .. msg )
185+ end
186+ end
187+ end
188+ clipboard [action_type ] = {}
189+ return refresh_tree ()
190+ end
191+
192+ local function add_to_clipboard (node , clip )
193+ if node .name == ' ..' then return end
194+
195+ for idx , entry in ipairs (clip ) do
196+ if entry .absolute_path == node .absolute_path then
197+ table.remove (clip , idx )
198+ return api .nvim_out_write (node .absolute_path .. ' removed to clipboard.\n ' )
199+ end
200+ end
201+ table.insert (clip , node )
202+ api .nvim_out_write (node .absolute_path .. ' added to clipboard.\n ' )
203+ end
204+
112205function M .remove (node )
113206 if node .name == ' ..' then return end
114207
@@ -153,4 +246,38 @@ function M.rename(node)
153246 refresh_tree ()
154247end
155248
249+ function M .copy (node )
250+ add_to_clipboard (node , clipboard .copy )
251+ end
252+
253+ function M .cut (node )
254+ add_to_clipboard (node , clipboard .move )
255+ end
256+
257+ function M .paste (node )
258+ if clipboard .move [1 ] ~= nil then
259+ return do_paste (node , ' move' , luv .fs_rename )
260+ end
261+
262+ return do_paste (node , ' copy' , do_copy )
263+ end
264+
265+ function M .print_clipboard ()
266+ local content = {}
267+ if # clipboard .move > 0 then
268+ table.insert (content , ' Cut' )
269+ for _ , item in pairs (clipboard .move ) do
270+ table.insert (content , ' * ' .. item .absolute_path )
271+ end
272+ end
273+ if # clipboard .copy > 0 then
274+ table.insert (content , ' Copy' )
275+ for _ , item in pairs (clipboard .copy ) do
276+ table.insert (content , ' * ' .. item .absolute_path )
277+ end
278+ end
279+
280+ return api .nvim_out_write (table.concat (content , ' \n ' ).. ' \n ' )
281+ end
282+
156283return M
0 commit comments