nvim-tree.lua icon indicating copy to clipboard operation
nvim-tree.lua copied to clipboard

Rename Input Callback

Open alex-courtis opened this issue 2 years ago • 11 comments

#1791 adds rename_root which presents the file without the absolute path, just the file name.

This is good UX and should also be applied to rename.

This change would be a break in existing functionality, however rename_full does provide most of the existing rename experience.

Change rename-file.lua fn to apply vim.fn.fnamemodify(node.absolute_path, ":t")) before presenting input.

Update: #1791 applies sane defaults, resolving the above, as well as adding configurable rename suggestion.

alex-courtis avatar Dec 04 '22 01:12 alex-courtis

Thoughts would be gratefully appreciated @gegoune

alex-courtis avatar Dec 04 '22 02:12 alex-courtis

Please see my response on https://github.com/nvim-tree/nvim-tree.lua/pull/1791#pullrequestreview-1203681148 for more details.

I think having a single rename() action to build upon would be a way forward. In comment linked above I specified that returned value (with somehow getting cursor into the right place) should be what will be presented to user as a rename candidate.

We could expand that functionality by returning table with keys such as:

candidate: string,
curpos: number,

We could then build up on that function and provide some default actions allowing users create whatever fancy renames they want.


I am all in for having function|string kind of actions and options. Something like recently added nvim-tree.renderer.root_folder_label. Instead of adding bunch of rename functions for all possible use cases allowing function will just give users required flexibility.

Speaking of nvim-tree.renderer.root_folder_label - did not pick it up them, but it should have led to deprecation/removal of

    *nvim-tree.view.hide_root_folder*
    Hide the path of the current working directory on top of the tree.
      Type: `boolean`, Default: `false`

in a sense that setting nvim-tree.renderer.root_folder_label to empty string or (even better) false hides it completely. Another great example that we don't need specialised options but functions that provide flexibility.

gegoune avatar Dec 04 '22 17:12 gegoune

I think having a single rename() action to build upon would be a way forward.

We could then build up on that function and provide some default actions allowing users create whatever fancy renames they want.

That would solve a lot of problems around the various input dialogues. The user can have full control to build something that works for them which cannot be done generically by nvim-tree.

I am all in for having function|string kind of actions and options. Something like recently added nvim-tree.renderer.root_folder_label. Instead of adding bunch of rename functions for all possible use cases allowing function will just give users required flexibility.

Absolutely. This has been very successful and we should continue with this pattern.

alex-courtis avatar Dec 10 '22 01:12 alex-courtis

RE this specific change, it has been done here https://github.com/nvim-tree/nvim-tree.lua/pull/1791/files#diff-9e3c7c24da100a99cd64039a01519c6de5b4d51f741e5c9d7ebde5fbd96a7c42R28

~~We could implement this proper rename in that PR or separately. Looking at orthogonality now...~~

Edit: the above PR now contains rename_node API.

alex-courtis avatar Dec 10 '22 01:12 alex-courtis

I think having a single rename() action to build upon would be a way forward. In comment linked above I specified that returned value (with somehow getting cursor into the right place) should be what will be presented to user as a rename candidate.

How do we do this? Naive options:

  • user specified callback in options
  • user passes a callback to rename

We probably don't even need curpos: they can figure it out for themselves.

How about:

--- @param path string absolute path of candidate to rename
--- @param modifier string optional user vim.fn.fnamemodify arguments
--- @return string absolute path of new name
function rename_cb(path, modifier)
  --
end

alex-courtis avatar Dec 10 '22 01:12 alex-courtis

Your thoughts would be gratefully appreciated @ianhomer

alex-courtis avatar Dec 11 '22 03:12 alex-courtis

How would we see a user overriding this? Would it from the config, e.g.

{
   actions = {
       rename = {
           callback = function(path, modifier) 
                                --
                              end
       }
   }

}

Perhaps API invocation,

require("nvim-tree.api").fs.rename {modifier, function(path, modifier) ... end }

path and modifier feel good inputs - filename of what we want to change, and what part of the filename we want to change.

Responsibility as you describe for the API is take current name (as string) and return the desired new name (as string). The core nvm-tree responsibility can then take care of other concerns (permissions, notifying, reloading views). That feels good.

rename-file.lua could be rewritten to use this callback approach (implementing with default behaviour currently in place - i.e. vim.ui.input with opts ). There may be some defaults from this behaviour (e.g. the prompt text), that the callback may want to use, so perhaps that could be passed in as another argument or (and probably better) those concepts could be moved into the config so that they could be configured and used in both the default behaviour and any call back.

On the the use case of customising the positioning the cursor, the logic could be encapsulated in the callback (e.g. place cursor after last path separator) and I feel the path and modifier inputs suffice.

So, yes - the direction feels really good.

ianhomer avatar Dec 13 '22 10:12 ianhomer

On the the use case of customising the positioning the cursor, the logic could be encapsulated in the callback (e.g. place cursor after last path separator) and I feel the path and modifier inputs suffice.

Yup. This should be the one and only way to do this, with all responsibility and power in the user's hands.

There may be some defaults from this behaviour (e.g. the prompt text), that the callback may want to use, so perhaps that could be passed in as another argument or (and probably better) those concepts could be moved into the config so that they could be configured and used in both the default behaviour and any call back.

The pattern we are moving towards now is function-or-table-or-value like sort_by so hopefully we could use this with minimal config schema changes.

alex-courtis avatar Dec 16 '22 02:12 alex-courtis

Perhaps API invocation,

require("nvim-tree.api").fs.rename {modifier, function(path, modifier) ... end }

My initial inclination is to have rename not take a parameter and use the configured callback, however that's not very friendly. The same callback for both should work nicely.

alex-courtis avatar Dec 16 '22 02:12 alex-courtis

So, yes - the direction feels really good.

PRs are always welcome :)

alex-courtis avatar Dec 16 '22 02:12 alex-courtis

A plugin stevearc/dressing.nvim is a candidate to use this: https://github.com/nvim-tree/nvim-tree.lua/discussions/1750#discussioncomment-4441421

We could come up with example for the doc/ recipe for the wiki.

alex-courtis avatar Dec 18 '22 22:12 alex-courtis