-
-
Notifications
You must be signed in to change notification settings - Fork 49
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
Add action to open a subtree recursively #480
Conversation
get_child_nodes seems to interfere with the expansion status of the next level of directories
I'm not going to pretend to understand why, but for some reason, Aside that, I've been testing it since I made the initial implementation, and no problems so far. There's still probably more to do, but it's arguably good enough for now; the PR is as ready as I can get it |
Thanks for your contribution. It seems OK so could you re-organize your commits (to remove some draft commits or so on) or shall I squash all commits into a single one? |
Squashing is easier and faster |
Interesting changes! A few questions/comments. At first glance, it was a bit unclear what these changes do. For clarity in the commit messages and fern documentation, I think it would be good to mention recursive expansion of trees. For example:
For directory structures that are quite deep or have significant breadth, expanding a tree recursively can be a fairly significant operation. It would be nice if the user would be notified that the request is being fulfilled. Maybe with a simple message, or some other mechanism. I checked out your changes locally and it looks like the recursive tree expansion doesn't work when the node is already in the expanded state. To reproduce:
Other than that, changes look good so far. Looking forward to seeing this integrated :-) |
Sounds good. Please mention that in docs @LunarWatcher
I've noticed that too, but I feel like that's a limitation and it's easy to start over so we can merge. |
Sounds good, will do.
There's already an update spinner system, but it doesn't seem to stay on the node being recursively expanded. Would be optimal to integrate with it, but not sure if that's an option
That's currently half intentional, based on the existing function for |
…ng the recursive expansion
It was not that easy. Got this far: return s:Promise.new({ resolve ->
\ s:Lambda.if(
\ a:node.status isnot# s:STATUS_EXPANDED,
\ { -> resolve(
\ fern#internal#node#expand(a:node, a:nodes, a:provider, a:comparator, a:token)
\ )},
\ { -> resolve(a:nodes) }
\ )})
\.then({ ns -> s:set_expanded(a:node.__key, ns) })
\.then({ ns -> s:Lambda.let(state, 'ns', ns) })
\.then({ -> fern#internal#node#children(a:node, a:provider, a:token) })
\.then(s:AsyncLambda.filter_f({ child -> child isnot# v:null && child.status isnot# s:STATUS_NONE }))
\.then(s:AsyncLambda.map_f({child_node -> fern#internal#node#expand_tree(child_node, state.ns, a:provider, a:comparator, a:token) }))
\.then({ subtree_promises -> s:Promise.all(subtree_promises) })
\.then({ -> l:state.ns })
\.finally({ -> Done() }) with function! s:set_expanded(key, nodes) abort
let index = fern#internal#node#index(a:key, a:nodes)
if index is# -1
return a:nodes
endif
let a:nodes[index].status = s:STATUS_EXPANDED
return a:nodes
endfunction As a probably misguided guess at the problem. For some reason, Anyway, the last commit includes the requested doc wording change, and I noticed what made the spinners work, so I added one of those too, so that's all good. |
Documentation changes look good, thanks! 👌 I'll go through the rest of the changes when I'm not at work 😆
That would be nice if we could make that work! If not, no big deal, that could be a later enhancement. Answering earlier comments:
Weeeird. This sounds like defective behaviour to me; shouldn't |
That's the bit I got working
I do wonder if that function also was fine, but that it's weird behaviour caused by state not being properly set. Can't be arsed to check though, but it might be the same problem. The only difference is that the bug I failed to fix to recursively open already open folders can be triggered an unlimited number of times. /shrug though, as long as it works, etc |
Actually, I think it's intentional. I'll describe the detail later but the function try to return fresh child nodes that should not be modified (expanded is modified status). So it actually is idempotent. |
I noticed that expand is not immutable so I'll fix that first. I guess that makes this PR code clear. |
The current implementation relies on the behavior of New one works OK with already expanded nodes. |
Seems to work. Feels a bit slower, but nothing too noticeable. I'll close this PR in favour of the other one |
Opening entire subtrees is incredibly nice to have. Seeing as this hasn't been implemented due to the difficulty of implementation, I decided to take a stab at it.
This fixes at least #39, #320, and #412.
The current state of the PR:
in
andstay
both work (in a bare minimum proof-of-concept-type way; take that with a truckload of salt)<Plug>
maps have been added and documented (or at least their existence is mentioned in the docs; only did half a glance at the docs, not sure if they need to be mentioned elsewhere)node.vimspec
file. I assume more tests would be nice,but I haven't looked extensively, so not sure where they'd gobut I'm not seeing any equivalent tests that I can copy-pasta and modify. I can still add some if desiredCurrently, the PR is a draft, because there are a couple problems that I can't quite deal with on my own:
s:Promise.all
to merge the subtree promises feels like a hack, but I'm not seeing any obviously better options in vital.vim for dealing with arrays of promises. There's also plenty of discarded values, in part becausea:nodes
appears to be mutated, so just directly returning it is convenient. I'm not sure if this means the entire tree is refreshed, or if it's just some convenient abstraction representing change.a:nodes
' mutability), the implementation complexity goes up considerably, particularly when it's time to merge the return values. I can store and returnns
(whatever that is anyway) fromexpand
, but the difficulty lies in merging a list of otherns
es into the currentns
. A very, very quick and shallow search only found a method that adds a single node toa:nodes
, and not one that trivially merges twoa:nodes
lists together. I could make one, but I opted not to whena:nodes
is mutable, and there might be an even better approach that makes the entire thing pointlessThere's probably more stuff to grill in a code review as well (including bugs to be found; I do suspect using
a:nodes
instead ofns
return values is something that'll come back to haunt me, but I haven't found anything obvious yet). A chunk of the implementation was based on existing functions (particularly the convenients:expand_recursively
that I shamelessly copy-pasta'd for a starting point), so there's probably a fair share of copy-pasta errors and redundancies as well