-
-
Notifications
You must be signed in to change notification settings - Fork 84
Change the way we iterate for relative scopes #2128
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
Comments
Thought about this a bit more, and a few issues:
I don't think these are necessarily showstoppers, but just makes me think we maybe haven't gotten to the bottom of this one yet |
I started looking into this and of course ran into problem immediately :D if ( | true) {
console.log(1)
}
console.log(2) |
Yeah file should be iteration scope for statement. We should def add that with a test |
@AndreasArvidsson and I had a long discussion about this one. Here are our takeaways: First of all, we like the idea proposed in this PR. It has nice intuitive characteristics wrt "next" whereby sitting in the "header" of a structure should skip its body, but sitting in the body should not. We had a tangent where we thought maybe "interior" was the notion we actually wanted. The idea would be that for "next", you first expand input target to containing scope, and if that succeeds and you're not in its interior, you iterate starting from the end of the containing scope, otherwise iterate from input target as usual. In most cases, this would actually result in the same behaviour as the proposal in this issue. However, consider the scope type "arg", in the following code: function aaa(bbb, ccc = ddd(eee, fff), ggg) {
...
} We decided that In addition, the conistency with "every" is desirable, and the interior criterion would lose that. In order for this to work well, it is important that if a scope is hierarchical, there is always an iteration scope between a scope and its parent. Ie Let The above criterion causes hierarchical scopes to devolve to hierarchies of linear scopes. Each scope exists on a flat plane with other scopes of that plane, and within that plane the scope type behaves like a flat scope, so that "next scope", "two scopes", "every scope" all work as intuitively as flat scopes We would want to update the scope visualizer to be aware of these scope planes. For hierarchical scopes, your cursor position would determine which plane you're in by expanding to containing iteration scope and only showing scopes in that iteration scope, ignoring any scopes from descendant iteration scopes. We would have a way to indicate the available iteration scopes, but you'd only see actual scopes for one iteration scope at a time. We've had complaints that deeply nested scopes are very hard to understand in our scope visualizer, so this might be both a visual / mental model win It's also quite important then that we have good iteration scopes for every hierarchical scope So the steps are:
@AndreasArvidsson does this match our discussion? cc/ @josharian |
Looks good |
Note also that #2137 becomes much more natural: we just apply "grand" to iteration scope and then proceed as normal |
just had an example where I might not have wanted this behaviour: aaa(bbb) I had my cursor at the end of |
My understanding of the desired functionality is:
I feel like going to the parent once we have exhausted either all siblings or all children is non objectionable.
For the unfortunate not default option we can add a meta modifier like |
And here's another where I found today's "next" behaviour useful: function usingSetting<T, U>(
section: string,
setting: string,
factory: (value: T) => U,
): U {
return vscodeApi.workspace.getConfiguration(section).get<boolean>(setting);
} My cursor was in the function signature, and I just said |
It's not only about intuition. That ordinal and relative behaves differently is 95% of the problem. Now you need two different intuitions which just doesn't work for me. But for that example I don't agree. Next statement shouldn't be a child of the current in my mind. |
The problem
Today, the iteration semantics for relative scopes differs from the semantics for "every" and ordinal scopes. The latter first expand to iteration scope (if input target has no explicit range), and then get a list of all top-level scopes in that iteration scope. The former iterate directly from the input target, with no knowledge of iteration scopes. These semantics lead to the following problems:
The solution
If the scope has no iteration scope, maybe we just leave today's behaviour?
Otherwise, we first want to find the proper iteration scope in which to iterate:
Then we do the same thing we do with "every" / ordinal, where we construct a list of all scopes in the iteration scope. These are the scopes we use instead of directly working with the scope handler.
Note that if when iterating through the returned scopes, we run out, I think we move up to grand iteration scope and start over. Repeat that as many times as necessary
The text was updated successfully, but these errors were encountered: