feat(api): rename_basename API and action (#1791)

* relative rename action

* 🔥 remove debug print statement

* 🐛 better handling of dot files

Also pickout extension in filename with more one dot

* 🔧 keymap e for relative-rename action

* 📝 update help with relative-rename mapping

*  add API for rename_relative

* 🚨 correct lint warnings

* rename_relative -> rename_root

* stylua

* ♻️ use fnamemodify instead of custom logic

* 💥 refactor renaming api using vim filename modifiers

Rename API now supports filename modifiers as arguments, although
only with limited support of options. The function signature however
will allow improvements going forward. The API signature is backward
compatible, although the behviour has changed as per the next comment.

This change changes the default behaviour of the renames, rename_full is
what rename was, rename now just renames the tail (i.e. the filename)

* 🐛 make api rename, without args, functional

*  allow modifier argument to be used in API call

* 📝 update documentation with new command name

* rename-file.fn takes only a modifier as argument

* add Api.fs.rename_basename, specify modifiers for rename, rename_sub

* add Api.fs.rename_node

* rename-file tidy allowed modifiers

* 🐛 fix bugs after last refactoring

rename ":t" and ":t:r" was moving file to root of project and not
maintaining sub-directory

* 🐛 correct absolute rename

which was loosing sub-directory on rename

* 🔥 remove debug print statements

* stylua

Co-authored-by: Alexander Courtis <alex@courtis.org>
This commit is contained in:
Ian Homer 2022-12-16 02:32:48 +00:00 committed by GitHub
parent a8d26bb088
commit 949913f186
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 57 additions and 11 deletions

View File

@ -1203,8 +1203,10 @@ exists.
- create
- remove
- trash
- rename_node `(node: table, modifier?: string vim.fn.fnamemodify argument)`
- rename
- rename_sub
- rename_basename
- cut
- paste
- clear_clipboard
@ -1337,6 +1339,7 @@ DEFAULT MAPPINGS *nvim-tree-default-mappings
`D` trash trash a file via |trash| option
`r` rename rename a file
`<C-r>` full_rename rename a file and omit the filename on input
`e` rename_basename rename a file with filename-modifiers ':t:r' without changing extension
`x` cut add/remove file/directory to cut clipboard
`c` copy add/remove file/directory to copy clipboard
`p` paste paste from clipboard; cut clipboard has precedence over copy; will prompt for confirmation
@ -1388,6 +1391,7 @@ DEFAULT MAPPINGS *nvim-tree-default-mappings
{ key = "D", action = "trash" },
{ key = "r", action = "rename" },
{ key = "<C-r>", action = "full_rename" },
{ key = "e", action = "rename_basename" },
{ key = "x", action = "cut" },
{ key = "c", action = "copy" },
{ key = "p", action = "paste" },

View File

@ -22,11 +22,12 @@ local Actions = {
copy = require("nvim-tree.actions.fs.copy-paste").copy,
create = require("nvim-tree.actions.fs.create-file").fn,
cut = require("nvim-tree.actions.fs.copy-paste").cut,
full_rename = require("nvim-tree.actions.fs.rename-file").fn(true),
full_rename = require("nvim-tree.actions.fs.rename-file").fn ":p",
paste = require("nvim-tree.actions.fs.copy-paste").paste,
trash = require("nvim-tree.actions.fs.trash").fn,
remove = require("nvim-tree.actions.fs.remove-file").fn,
rename = require("nvim-tree.actions.fs.rename-file").fn(false),
rename = require("nvim-tree.actions.fs.rename-file").fn ":t",
rename_basename = require("nvim-tree.actions.fs.rename-file").fn ":t:r",
-- Movements in tree
close_node = require("nvim-tree.actions.moves.parent").fn(true),

View File

@ -5,6 +5,12 @@ local notify = require "nvim-tree.notify"
local M = {}
local ALLOWED_MODIFIERS = {
[":p"] = true,
[":t"] = true,
[":t:r"] = true,
}
local function err_fmt(from, to, reason)
return string.format("Cannot rename %s -> %s: %s", from, to, reason)
end
@ -25,17 +31,45 @@ function M.rename(node, to)
events._dispatch_node_renamed(node.absolute_path, to)
end
function M.fn(with_sub)
return function(node)
function M.fn(default_modifier)
default_modifier = default_modifier or ":t"
return function(node, modifier)
if type(node) ~= "table" then
node = lib.get_node_at_cursor()
end
if type(modifier) ~= "string" then
modifier = default_modifier
end
-- support for only specific modifiers have been implemented
if not ALLOWED_MODIFIERS[modifier] then
return notify.warn(
"Modifier " .. vim.inspect(modifier) .. " is not in allowed list : " .. table.concat(ALLOWED_MODIFIERS, ",")
)
end
node = lib.get_last_group_node(node)
if node.name == ".." then
return
end
local namelen = node.name:len()
local abs_path = with_sub and node.absolute_path:sub(0, namelen * -1 - 1) or node.absolute_path
local directory = node.absolute_path:sub(0, namelen * -1 - 1)
local default_path
local prepend = ""
local append = ""
default_path = vim.fn.fnamemodify(node.absolute_path, modifier)
if modifier:sub(0, 2) == ":t" then
prepend = directory
end
if modifier == ":t:r" then
local extension = vim.fn.fnamemodify(node.name, ":e")
append = extension:len() == 0 and "" or "." .. extension
end
local input_opts = { prompt = "Rename to ", default = abs_path, completion = "file" }
local input_opts = { prompt = "Rename to ", default = default_path, completion = "file" }
vim.ui.input(input_opts, function(new_file_path)
utils.clear_prompt()
@ -43,7 +77,7 @@ function M.fn(with_sub)
return
end
M.rename(node, new_file_path)
M.rename(node, prepend .. new_file_path .. append)
if M.enable_reload then
require("nvim-tree.actions.reloaders.reloaders").reload_explorer()
end

View File

@ -131,6 +131,11 @@ local DEFAULT_MAPPINGS = {
action = "full_rename",
desc = "rename a file and omit the filename on input",
},
{
key = "e",
action = "rename_basename",
desc = "rename a file with filename-modifiers ':t:r' without changing extension",
},
{
key = "x",
action = "cut",

View File

@ -9,9 +9,9 @@ local Api = {
}
local function inject_node(f)
return function(node)
return function(node, ...)
node = node or require("nvim-tree.lib").get_node_at_cursor()
f(node)
f(node, ...)
end
end
@ -47,8 +47,10 @@ Api.tree.toggle_help = require("nvim-tree.actions.tree-modifiers.toggles").help
Api.fs.create = inject_node(require("nvim-tree.actions.fs.create-file").fn)
Api.fs.remove = inject_node(require("nvim-tree.actions.fs.remove-file").fn)
Api.fs.trash = inject_node(require("nvim-tree.actions.fs.trash").fn)
Api.fs.rename = inject_node(require("nvim-tree.actions.fs.rename-file").fn(false))
Api.fs.rename_sub = inject_node(require("nvim-tree.actions.fs.rename-file").fn(true))
Api.fs.rename_node = inject_node(require("nvim-tree.actions.fs.rename-file").fn ":t")
Api.fs.rename = inject_node(require("nvim-tree.actions.fs.rename-file").fn ":t")
Api.fs.rename_sub = inject_node(require("nvim-tree.actions.fs.rename-file").fn ":p")
Api.fs.rename_basename = inject_node(require("nvim-tree.actions.fs.rename-file").fn ":t:r")
Api.fs.cut = inject_node(require("nvim-tree.actions.fs.copy-paste").cut)
Api.fs.paste = inject_node(require("nvim-tree.actions.fs.copy-paste").paste)
Api.fs.clear_clipboard = require("nvim-tree.actions.fs.copy-paste").clear_clipboard