Skip to content

feat: creating, copying & moving in folder_browser #79

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jan 20, 2022
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
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