Skip to content

Commit

Permalink
feat: creating, copying & moving in folder_browser (#79)
Browse files Browse the repository at this point in the history
* feat: creating, copying & moving in folder_browser

This commit enables creating, copying, and moving
files and folders from within folder_browser mode.

In doing so, the currently selected directory within
folder_browser serves as the target directory for the
corresponding telescope-file-browser action.
  • Loading branch information
fdschmidt93 authored Jan 20, 2022
1 parent dd101ff commit e65a567
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 40 deletions.
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,11 +112,11 @@ Note: `path` corresponds to the folder the `file_browser` is currently in.

**Warning:** Batch renaming or moving files with path inter-dependencies are not resolved! For instance, moving a folder somewhere while moving another file into the original folder in later order within same action will fail.

| Action (incl. GIF)| Docs | Comment |
|-------------------|------------------------|----------|
| [creation](https://github.com/nvim-telescope/telescope-file-browser.nvim/issues/53#issuecomment-1010221098)| `:h fb_action.create`| Levers `vim.ui.input`, trailing path separator (e.g. `/` on unix) creates folder |
| [copying](https://github.com/nvim-telescope/telescope-file-browser.nvim/issues/53#issuecomment-1010298556) | `:h fb_action.copy` | Supports copying current selection in `path` & multi-selections to respective `path` |
| [moving](https://github.com/nvim-telescope/telescope-file-browser.nvim/issues/53#issuecomment-1010301465) | `:h fb_action.move` | Move multi-selected files to `path` |
| Action (incl. GIF)| Docs | Comment |
|-------------------|------------------------|---------|
| [creation](https://github.com/nvim-telescope/telescope-file-browser.nvim/issues/53#issuecomment-1010221098)| `:h fb_action.create`| Create file or folder (with trailing OS separator) at `path` (`file_browser`) or at selected directory (`folder_browser`)|
| [copying](https://github.com/nvim-telescope/telescope-file-browser.nvim/issues/53#issuecomment-1010298556) | `:h fb_action.copy` | Supports copying current selection & multi-selections to `path` (`file_browser`) or selected directory (`folder_browser`) |
| [moving](https://github.com/nvim-telescope/telescope-file-browser.nvim/issues/53#issuecomment-1010301465) | `:h fb_action.move` | Move multi-selected files to `path` (`file_browser`) or selected directory (`folder_browser`) |
| [removing](https://github.com/nvim-telescope/telescope-file-browser.nvim/issues/53#issuecomment-1010315578)| `:h fb_action.remove`| Remove (multi-)selected files |
| [renaming](https://github.com/nvim-telescope/telescope-file-browser.nvim/issues/53#issuecomment-1010323053)| `:h fb_action.rename`| Rename (multi-)selected files |

Expand Down
21 changes: 15 additions & 6 deletions doc/telescope-file-browser.txt
Original file line number Diff line number Diff line change
Expand Up @@ -135,11 +135,15 @@ require('telescope').setup {

fb_actions.create({prompt_bufnr}) *fb_actions.create()*
Creates a new file in the current directory of the
|fb_picker.file_browser|. Notes:
- You can create folders by ending the name in the path separator of your
OS, e.g. "/" on Unix systems
- You can implicitly create new folders by passing
$/CWD/new_folder/filename.lua
|fb_picker.file_browser|.
- Finder:
- file_browser: create a file in the currently opened directory
- folder_browser: create a file in the currently selected directory
- Notes:
- You can create folders by ending the name in the path separator of your
OS, e.g. "/" on Unix systems
- You can implicitly create new folders by passing
$/CWD/new_folder/filename.lua


Parameters: ~
Expand Down Expand Up @@ -172,7 +176,12 @@ fb_actions.move({prompt_bufnr}) *fb_actions.move()*
fb_actions.copy({prompt_bufnr}) *fb_actions.copy()*
Copy file or folders recursively to current directory in
|fb_picker.file_browser|.
Note: Performs a blocking synchronized file-system operation.

- Finder:
- file_browser: copies (multi-selected) file(s) in/to opened dir (w/o
multi-selection, creates in-place copy)
- folder_browser: copies (multi-selected) file(s) in/to selected dir (w/o
multi-selection, creates in-place copy)


Parameters: ~
Expand Down
68 changes: 39 additions & 29 deletions lua/telescope/_extensions/file_browser/actions.lua
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,30 @@ local fb_actions = setmetatable({}, {

local os_sep = Path.path.sep

-- utility to get absolute path of target directory for create, copy, moving files/folders
local get_target_dir = function(finder)
local entry_path
if finder.files == false then
local entry = action_state.get_selected_entry()
entry_path = entry and entry.value -- absolute path
end
return finder.files and finder.path or entry_path
end

--- Creates a new file in the current directory of the |fb_picker.file_browser|.
--- Notes:
--- - You can create folders by ending the name in the path separator of your OS, e.g. "/" on Unix systems
--- - You can implicitly create new folders by passing $/CWD/new_folder/filename.lua
--- - Finder:
--- - file_browser: create a file in the currently opened directory
--- - folder_browser: create a file in the currently selected directory
--- - Notes:
--- - You can create folders by ending the name in the path separator of your OS, e.g. "/" on Unix systems
--- - You can implicitly create new folders by passing $/CWD/new_folder/filename.lua
---@param prompt_bufnr number: The prompt bufnr
fb_actions.create = function(prompt_bufnr)
local current_picker = action_state.get_current_picker(prompt_bufnr)
local finder = current_picker.finder
vim.ui.input({ prompt = "Insert the file name:\n", default = finder.path .. os_sep }, function(file)

local default = get_target_dir(finder) .. os_sep
vim.ui.input({ prompt = "Insert the file name:\n", default = default }, function(file)
if not file then
return
end
Expand Down Expand Up @@ -222,24 +237,21 @@ end
fb_actions.move = function(prompt_bufnr)
local current_picker = action_state.get_current_picker(prompt_bufnr)
local finder = current_picker.finder
if finder.files ~= nil and finder.files == false then
error "Moving files in folder browser mode not supported."
return
end

local selections = fb_utils.get_selected_files(prompt_bufnr, false)
if vim.tbl_isempty(selections) then
print "[telescope] Nothing currently selected to be moved"
return
end

for _, file in ipairs(selections) do
local filename = file.filename:sub(#file:parent().filename + 2)
local new_path = Path:new { finder.path, filename }
local target_dir = get_target_dir(finder)
for _, selection in ipairs(selections) do
local filename = selection.filename:sub(#selection:parent().filename + 2)
local new_path = Path:new { target_dir, filename }
if new_path:exists() then
print(string.format("%s already exists in target folder! Skipping.", filename))
else
file:rename {
selection:rename {
new_name = new_path.filename,
}
print(string.format("%s has been moved!", filename))
Expand All @@ -251,33 +263,31 @@ fb_actions.move = function(prompt_bufnr)
end

--- Copy file or folders recursively to current directory in |fb_picker.file_browser|.<br>
--- Note: Performs a blocking synchronized file-system operation.
--- - Finder:
--- - file_browser: copies (multi-selected) file(s) in/to opened dir (w/o multi-selection, creates in-place copy)
--- - folder_browser: copies (multi-selected) file(s) in/to selected dir (w/o multi-selection, creates in-place copy)
---@param prompt_bufnr number: The prompt bufnr
fb_actions.copy = function(prompt_bufnr)
local current_picker = action_state.get_current_picker(prompt_bufnr)
local finder = current_picker.finder
if finder.files ~= nil and finder.files == false then
error "Copying files in folder browser mode not supported."
return
end

local selections = fb_utils.get_selected_files(prompt_bufnr, true)
if vim.tbl_isempty(selections) then
print "[telescope] Nothing currently selected to be copied"
return
end

for _, file in ipairs(selections) do
local filename = file.filename:sub(#file:parent().filename + 2)
local destination = Path
:new({
finder.path,
filename,
})
:absolute()
local target_dir = get_target_dir(finder)
for _, selection in ipairs(selections) do
-- file:absolute() == target_dir for copying folder in place in folder_browser
local name = selection:absolute() ~= target_dir and selection.filename:sub(#selection:parent().filename + 2) or nil
local destination = Path:new {
target_dir,
name,
}
-- copying file or folder within original directory
if file:parent():absolute() == finder.path then
local absolute_path = file:absolute()
if destination:absolute() == selection:absolute() then
local absolute_path = selection:absolute()
-- TODO: maybe use vim.ui.input but we *must* block which most likely is not guaranteed
destination = vim.fn.input {
prompt = string.format(
Expand All @@ -296,12 +306,12 @@ fb_actions.copy = function(prompt_bufnr)
end
end
if destination ~= "" then -- vim.fn.input may return "" on cancellation
file:copy {
selection:copy {
destination = destination,
recursive = true,
parents = true,
}
print(string.format("\n%s has been copied!", filename))
print(string.format("\n%s has been copied!", name))
end
end

Expand Down

0 comments on commit e65a567

Please sign in to comment.