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
5 changed files with 57 additions and 11 deletions

View File

@@ -1203,8 +1203,10 @@ exists.
- create - create
- remove - remove
- trash - trash
- rename_node `(node: table, modifier?: string vim.fn.fnamemodify argument)`
- rename - rename
- rename_sub - rename_sub
- rename_basename
- cut - cut
- paste - paste
- clear_clipboard - clear_clipboard
@@ -1337,6 +1339,7 @@ DEFAULT MAPPINGS *nvim-tree-default-mappings
`D` trash trash a file via |trash| option `D` trash trash a file via |trash| option
`r` rename rename a file `r` rename rename a file
`<C-r>` full_rename rename a file and omit the filename on input `<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 `x` cut add/remove file/directory to cut clipboard
`c` copy add/remove file/directory to copy 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 `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 = "D", action = "trash" },
{ key = "r", action = "rename" }, { key = "r", action = "rename" },
{ key = "<C-r>", action = "full_rename" }, { key = "<C-r>", action = "full_rename" },
{ key = "e", action = "rename_basename" },
{ key = "x", action = "cut" }, { key = "x", action = "cut" },
{ key = "c", action = "copy" }, { key = "c", action = "copy" },
{ key = "p", action = "paste" }, { key = "p", action = "paste" },

View File

@@ -22,11 +22,12 @@ local Actions = {
copy = require("nvim-tree.actions.fs.copy-paste").copy, copy = require("nvim-tree.actions.fs.copy-paste").copy,
create = require("nvim-tree.actions.fs.create-file").fn, create = require("nvim-tree.actions.fs.create-file").fn,
cut = require("nvim-tree.actions.fs.copy-paste").cut, 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, paste = require("nvim-tree.actions.fs.copy-paste").paste,
trash = require("nvim-tree.actions.fs.trash").fn, trash = require("nvim-tree.actions.fs.trash").fn,
remove = require("nvim-tree.actions.fs.remove-file").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 -- Movements in tree
close_node = require("nvim-tree.actions.moves.parent").fn(true), 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 M = {}
local ALLOWED_MODIFIERS = {
[":p"] = true,
[":t"] = true,
[":t:r"] = true,
}
local function err_fmt(from, to, reason) local function err_fmt(from, to, reason)
return string.format("Cannot rename %s -> %s: %s", from, to, reason) return string.format("Cannot rename %s -> %s: %s", from, to, reason)
end end
@@ -25,17 +31,45 @@ function M.rename(node, to)
events._dispatch_node_renamed(node.absolute_path, to) events._dispatch_node_renamed(node.absolute_path, to)
end end
function M.fn(with_sub) function M.fn(default_modifier)
return function(node) 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) node = lib.get_last_group_node(node)
if node.name == ".." then if node.name == ".." then
return return
end end
local namelen = node.name:len() 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) vim.ui.input(input_opts, function(new_file_path)
utils.clear_prompt() utils.clear_prompt()
@@ -43,7 +77,7 @@ function M.fn(with_sub)
return return
end end
M.rename(node, new_file_path) M.rename(node, prepend .. new_file_path .. append)
if M.enable_reload then if M.enable_reload then
require("nvim-tree.actions.reloaders.reloaders").reload_explorer() require("nvim-tree.actions.reloaders.reloaders").reload_explorer()
end end

View File

@@ -131,6 +131,11 @@ local DEFAULT_MAPPINGS = {
action = "full_rename", action = "full_rename",
desc = "rename a file and omit the filename on input", 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", key = "x",
action = "cut", action = "cut",

View File

@@ -9,9 +9,9 @@ local Api = {
} }
local function inject_node(f) local function inject_node(f)
return function(node) return function(node, ...)
node = node or require("nvim-tree.lib").get_node_at_cursor() node = node or require("nvim-tree.lib").get_node_at_cursor()
f(node) f(node, ...)
end end
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.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.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.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_node = 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(true)) 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.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.paste = inject_node(require("nvim-tree.actions.fs.copy-paste").paste)
Api.fs.clear_clipboard = require("nvim-tree.actions.fs.copy-paste").clear_clipboard Api.fs.clear_clipboard = require("nvim-tree.actions.fs.copy-paste").clear_clipboard