-
-
Notifications
You must be signed in to change notification settings - Fork 83
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
Stable snippets #443
Comments
This is a really interesting idea -- I came here after watching your YouTube video. I have a few clarification questions on the implementation. You mentioned that these would be so stable that they don't go away if you navigate to another file. Do you also intend that these remain active if you navigate to another place in the same file? That sounds harder, because at least the cursor location within an editor is saved when switching editors. Similarly, how about closing and reopening a file? Are you expecting to only have one snippet active at time? How about nested snippets? These all sound really difficult to support, but they would be very powerful: essentially promoting snippets to first-class entities alongside tree-sitter nodes. I completely understand if this is way out of scope -- I'm just trying to better understand what you have in mind. Maybe this makes more sense if only applied to a subset of snippets which are intended to mirror tree-sitter node types.
Is the idea that you would use the existing hat decorations, except on the empty holes instead of on characters? Or did you have something else in mind? I was thinking that the natural way to refer to these holes is via modifiers named after the snippet structure. So if my cursor is anywhere within an "if" snippet with a "condition" placeholder, then I can refer to "snip condition" just as I can refer to "funk" if I'm anywhere within a function. I could also refer to "snip if" (or maybe just "snip") to select the entire snippet. This is maybe a confusing example because "condition" exists today as a scope, but hopefully it's clear how this would generalize to user-defined snippets.
Maybe your response to my earlier question will answer this: what do you mean by "add marks"? Do you mean a whole new mark type, or a decoration? Your example "snip condition" sounds more like a modifier, similar to what I described above, but I'm probably misunderstanding. Thanks for your patience here -- still new to Cursorless but your videos (especially the internals walkthrough) have been super helpful to building my mental model. |
I do, and it's actually not any harder. The snippet placeholders will just be represented by a location, so where your cursor happens to be at any given moment isn't actually relevant Even if you close and reopen a workspace, you should be ok, because we can store the locations in workspace state (scroll down to
That's a super good question. The answer is "no", but I hadn't actually thought too hard about that case. If you have multiple snippets active that have different placeholder names, it should be ok. If you have multiple snippets active which have the same placeholder names (eg the same snippet), I think probably the best solution would be to have a stack, and by default the placeholder marks refer to the top level of the stack, but you can use some prefix to refer to other open copies of the same snippet, such as ordinals, so eg "second snip condition" We'd want to do something to make sure you don't leave a snippet open accidentally 🤔
Yep! Shouldn't be any extra work to support nested snippets once we support multiple snippets
💯
Not out of scope at all! And really helpful to make me clarify 😊
I think we'd support it no matter what mechanism is used to keep the snippet hole range up to date, but obviously I'd imagine that mirroring to a tree-sitter node will be a common case (tho keep in mind we likely won't mirror directly to a tree-sitter node type, but rather to a cursorless scope type which corresponds to a pattern matcher.
No, basically we'd render something that looks like placeholder text you'd see in an HTML form, using the name of the snippet hole as the placeholder text
Yes that's what I was thinking as well, but I wouldn't require your cursor to be inside the "if" snippet; you could use that mark from anywhere, including another file / if the original file was hidden or closed
It's a whole new mark type
Not at all! Questions always very much appreciated. Hope these answers help |
Very interesting, thank you for clarifying all that. The idea of a new mark for snippet holes now makes a lot of sense with your example of placeholder text in an HTML form. I now see that I had quite a different mental model for how multiple snippets in a file might be supported, which I think may be interesting to discuss. I was assuming that you would drop the distinction of an active vs. inactive snippet altogether, and simply pattern match against whatever is in the file to find snippets. For example, if a user "chucks" a condition of an if statement, you could imagine that the snippet placeholder appears for that condition. Users could potentially "bring" structure from one part of a file to another, but have it provide placeholders to change the details. This is also why I was assuming that a user might refer to a snippet relative to their cursor location, or to a mark -- like they do with existing scopes. This model would avoid the whole problem of whether a user left a snippet open accidentally. This would be much more difficult to implement, e.g. because multiple different snippets may overlap in arbitrary ways with a single piece of code. That's why I was thinking that this supercharged functionality might only be applied to a set of snippets maintained by Cursorless. My motivation is that it seems pretty intuitive to me that the same conceptual entities that are currently used for destruction of code can also be used for construction (using your terminology). On the other hand, to support ideas like snippets that span multiple files, I can see why the concept of an "active snippet" is very useful. Perhaps these could coexist, and what I'm describing wouldn't be surfaced as snippets but rather as more construction-focused functionality added to existing predefined scopes. |
I think it's worth hashing this one out over a jitsi / discord What you're describing sounds a lot like what cursorless already supports today. For example, I can already say "change condition" from anywhere in an I do think it's worth exploring how we formalise the connection between the above (which are modifiers applied to the current selection(s)), and the snippet placeholders described in this issue (which are marks) |
The problem
The tab stops in VSCode's snippet interface can be a bit fragile, especially when combining them with cursorless commands. If you're not careful, vscode will decide that you're no longer in a snippet and drop all the tab stops.
In addition, VSCode snippets have no way of indicating how a snippet hole should expand as text is inserted and the code around it changes. Should it expand in both directions? Should it expand to match a particular syntactic scope (eg the syntax node corresponding to the condition of an
if
statement)?Having an extremely stable version of snippets where the tab stops don't go away even if you switch to a different file could also enable some interesting workflows where you set up a snippet and then navigate from file to file adding things to a snippet body that is still in the background
We'd like an experience which is similar to the way that holes work in agda.
Implementation
"condition"
, etcReferences
We should take a look at https://github.com/ethan-leba/tree-edit
The text was updated successfully, but these errors were encountered: