From 949913f1860eb85024fa1967dbd89ac797777b0d Mon Sep 17 00:00:00 2001 From: Ian Homer Date: Fri, 16 Dec 2022 02:32:48 +0000 Subject: [PATCH] feat(api): rename_basename API and action (#1791) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 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 --- doc/nvim-tree-lua.txt | 4 +++ lua/nvim-tree/actions/dispatch.lua | 5 +-- lua/nvim-tree/actions/fs/rename-file.lua | 44 +++++++++++++++++++++--- lua/nvim-tree/actions/init.lua | 5 +++ lua/nvim-tree/api.lua | 10 +++--- 5 files changed, 57 insertions(+), 11 deletions(-) diff --git a/doc/nvim-tree-lua.txt b/doc/nvim-tree-lua.txt index 436baf35..eda8f846 100644 --- a/doc/nvim-tree-lua.txt +++ b/doc/nvim-tree-lua.txt @@ -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 `` 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 = "", action = "full_rename" }, + { key = "e", action = "rename_basename" }, { key = "x", action = "cut" }, { key = "c", action = "copy" }, { key = "p", action = "paste" }, diff --git a/lua/nvim-tree/actions/dispatch.lua b/lua/nvim-tree/actions/dispatch.lua index e28fdb5c..a3781f80 100644 --- a/lua/nvim-tree/actions/dispatch.lua +++ b/lua/nvim-tree/actions/dispatch.lua @@ -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), diff --git a/lua/nvim-tree/actions/fs/rename-file.lua b/lua/nvim-tree/actions/fs/rename-file.lua index d37e35b5..443858ec 100644 --- a/lua/nvim-tree/actions/fs/rename-file.lua +++ b/lua/nvim-tree/actions/fs/rename-file.lua @@ -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 diff --git a/lua/nvim-tree/actions/init.lua b/lua/nvim-tree/actions/init.lua index 5764249c..b1f12c9a 100644 --- a/lua/nvim-tree/actions/init.lua +++ b/lua/nvim-tree/actions/init.lua @@ -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", diff --git a/lua/nvim-tree/api.lua b/lua/nvim-tree/api.lua index 92c14dc4..515d9ffd 100644 --- a/lua/nvim-tree/api.lua +++ b/lua/nvim-tree/api.lua @@ -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