diff --git a/lua/nvim-tree/actions/fs/rename-file.lua b/lua/nvim-tree/actions/fs/rename-file.lua index ec87c475920..d83f3f53e84 100644 --- a/lua/nvim-tree/actions/fs/rename-file.lua +++ b/lua/nvim-tree/actions/fs/rename-file.lua @@ -9,6 +9,16 @@ local M = { config = {}, } +---@param iter function iterable +---@return integer +local function get_num_nodes(iter) + local i = 0 + for _ in iter do + i = i + 1 + end + return i +end + local ALLOWED_MODIFIERS = { [":p"] = true, [":p:h"] = true, @@ -31,15 +41,46 @@ function M.rename(node, to) return end - events._dispatch_will_rename_node(node.absolute_path, to) - local success, err = vim.loop.fs_rename(node.absolute_path, to) - if not success then - notify.warn(err_fmt(notify_from, notify_to, err)) - return + -- create a folder for each path element if the folder does not exist + local idx = 0 + local path_to_create = "" + + local num_nodes = get_num_nodes(utils.path_split(utils.path_remove_trailing(to))) + local is_error = false + for path in utils.path_split(to) do + idx = idx + 1 + + local p = utils.path_remove_trailing(path) + if #path_to_create == 0 and vim.fn.has "win32" == 1 then + path_to_create = utils.path_join { p, path_to_create } + else + path_to_create = utils.path_join { path_to_create, p } + end + + if idx == num_nodes then + events._dispatch_will_rename_node(node.absolute_path, to) + local success, err = vim.loop.fs_rename(node.absolute_path, to) + + if not success then + notify.warn(err_fmt(notify_from, notify_to, err)) + return + end + elseif not utils.file_exists(path_to_create) then + local success = vim.loop.fs_mkdir(path_to_create, 493) + if not success then + notify.error("Could not create folder " .. notify.render_path(path_to_create)) + is_error = true + break + end + is_error = false + end + end + + if not is_error then + notify.info(string.format("%s -> %s", notify_from, notify_to)) + utils.rename_loaded_buffers(node.absolute_path, to) + events._dispatch_node_renamed(node.absolute_path, to) end - notify.info(string.format("%s -> %s", notify_from, notify_to)) - utils.rename_loaded_buffers(node.absolute_path, to) - events._dispatch_node_renamed(node.absolute_path, to) end ---@param default_modifier string|nil