-
-
Notifications
You must be signed in to change notification settings - Fork 606
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(actions): git-aware cut / paste / rename fs actions #2542
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a fantastic! I love the direction you are taking with the fallback pattern, which won't disturb current users.
I think a lot of users, myself included, will end up mapping to these actions instead of the defaults.
This one will take a while, I'd like to dogfood this for some time before merge.
Big concern: repetition -> maintainability. There's a lot of duplicated code here. Suggestions:
- Fold
actions/git/init.lua
actions/git/init.lua
into the existingcopy-paste.lua
,rename-file.lua
etc, extending the current persistence mechanisms as needed. - Use the existing
git/runner.lua
, exposing internal API / refactoring as necessary. - There's a lot of great improvements here that should be applied to existing code. Not in this PR. One of:
- Prefactor PR for existing
copy-paste.lua
etc. before this PR - Tidy / improvement PR after merging this PR
- Prefactor PR for existing
doc/nvim-tree-lua.txt
Outdated
@@ -1906,9 +1906,67 @@ node.run.system() *nvim-tree-api.node.run.system()* | |||
============================================================================== | |||
6.4 API GIT *nvim-tree-api.git* | |||
|
|||
This api is a set of |nvim-tree-api.fs|.* like functions that use git cli | |||
for file cutting, pasting, and renaming instead of system routines. | |||
Many actions in the git API automatically fallback to the |nvim-tree-api.fs| |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work.
lua/nvim-tree/actions/git/cli.lua
Outdated
|
||
local stdin = uv.new_pipe() | ||
local stdout = uv.new_pipe() | ||
local stderr = uv.new_pipe() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This functionality appears to duplicate git/runner.lua
.
Let's not repeat ourselves and share that code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please merge:
#2551
lua/nvim-tree/actions/git/init.lua
Outdated
events._dispatch_will_rename_node(path_src, path_dst) | ||
M.prompt_for_rename(node, { absolute = true }) | ||
-- Skip git mv | ||
goto loop |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
goto? no thank you. Standard flow of control please.
--- @class gitClipboard | ||
--- @field prototype gitClipboardInstance | ||
--- @field prototype.constructor gitClipboard | ||
M.Clipboard = { prototype = { constructor = M.Clipboard } } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The prototype pattern is surfacing a lot of warnings and confusing lua_language_server. Any reason we need that over an "ordinary" class?
lua/nvim-tree/actions/git/init.lua
Outdated
local prompt_default = "" | ||
prompt_default = opts.absolute and node.absolute_path or prompt_default | ||
prompt_default = opts.filename and fnamemodify(node.absolute_path, ":t") or prompt_default | ||
prompt_default = opts.basename and fnamemodify(node.absolute_path, ":t:r") or prompt_default |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This method repeats a lot of rename-file.lua
.
Can we please share?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It can be shared by a separate refactor(actions): rename-file.lua
PR. Are you going to accept a separate PR with rename-file.lua
refactoring?
Currently rename-file.lua
isn't exporting internal utils so it's not reusable. The chunk of code above si similar to (IMO very inefficient) following string comparison:
nvim-tree.lua/lua/nvim-tree/actions/fs/rename-file.lua
Lines 64 to 79 in 46e1f77
local namelen = node.name:len() | |
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 | |
if modifier == ":p:h" then | |
default_path = default_path .. "/" | |
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It can be shared by a separate
refactor(actions): rename-file.lua
PR. Are you going to accept a separate PR withrename-file.lua
refactoring?
Absolutely! That's what I meant by "prefactor". Sorry, I shoud have been clearer.
Something like "chore(#2542): refactor rename file"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or refactor(…): …
. :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Heh... didn't realise that was a prefix, thank you.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please merge:
#2550
This PR is going to use common code from that PR. The refactoring is dead-simple.
---@param node table | ||
---@return HL_POSITION position none when clipboard empty | ||
---@return string|nil group only when node present in clipboard | ||
function M.get_highlight(node) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is calling this?
ALTERNATIVE: This isn't particularly tightly coupled with nvim-tree. It could easily be extracted into an extension plugin. What do you reckon @gegoune @Akmadan23 ? |
That's true, but not completely... Nvim-tree already has some level of git integration, so it makes sense to enhance this aspect, and having these features ready out of the box would be really handy. |
@alex-courtis I agree with @Akmadan23 - support for git commands out of the box is essential. I'm going to do some refactoring. Many modules in this project simply don't export routines that can be reused so I was forced to duplicate them. I'm under impression that the code was NOT intended to be modular/reusable in first place or authors werent even suspecting that the code might be used elsewhere. As you can see in this PR I've exported everything to make I also plan to introduce simple undo history in the future, when I have enough time on my hands. Merging with
|
On why this is not a plugintl;dr: It would be nice if If Like, what if plugin spec looked like this?: plugin.source -- a table of funcs that export recursive table to be displayed as a tree; user can switch sources
plugin.source_ui -- a table of functions handling UI events emitted by nvim-tree to modify appearance
plugin.commands -- i.e. a table actions exposed to user / others plugins (e.g. actions over focused node)
plugin.clipboard -- integration with nvim-tree global clipboard
plugin.history -- integration with nvim-tree actions history (i.e. undo/redo lists config)
--- etc
The one would make extending nvim-tree very simple. Btw, |
That would indeed be useful; I've reflexively tried that a few times and was disappointed. |
Fair enough, this functionality is suited for nvim-tree itself rather than another plugin. RE API: https://github.com/nvim-tree/nvim-tree.lua#roadmap we have been adding API as needed, however that's not practical for this case. |
We are always striving to improve. Modularising / exposing is desirable.
Yes please! |
fee8231
to
3653a09
Compare
Thanks for the detailed instructions. Unfortunately my time is limited. I'll process PRs sequentially: #2551 then #2550 then this PR. |
65ffd5a
to
59ffa4d
Compare
Use git cut / rename / paste actions for tracked files Use wrapper fs.* for untracked files (rename, cut, and paste) Add docs on new git actions Highlighting for clipboard cut Upgradee git cli wrapper with more functions (rm, mv, is_tracked) Cut clipboard for git actions (based on Set class)
See #2551 (comment) |
git-actions-demo.mov
This PR allows:
fs.*
like file actions for cut / paste / renamefs.{cut,paste}
as usualfs.*
APIs nicely, minimize redundancyUsage
No keymaps setup by default. Example:
API
Adds:
api.git.cut(node)
- store a file under cursor into a git actions clipboard (just likeapi.fs.cut
)api.git.paste(node)
- pop files from clipboard into a folder under cursorapi.git.rename(node)
- rename file under cursorapi.git.rename_sub(node)
api.git.rename_basename(node)
api.git.rename_absolute(node)
api.git.clear_clipboard(node)
api.git.print_clipboard(node)
Utils:
git(uvSpawnOptions, onErrOrData, onExit)
- a wrapper func aroundgit
cli command (usesuv
)git_is_tracked(path, cb, onExit)
- checks whether given path is trackedgit_mv(path_src, path_dst, callback, onExit)
- moves files around by using gitClipboard
- a class for future for clipboard; used for git actions local copy / paste stackDesign considerations
I'm aware of git runner for git but as I said earlier elsewhere - it's too limited to be used for a general purpose git commands, so this PR introduces a full-fledged proxy to git.