cursorless
cursorless copied to clipboard
Smarter snippet holes
The goal
We'd like to enhance the ability for snippets to be used to perform high-level syntactic transformations. To this end we'd like to add the following abilities:
- [ ] To indicate that a particular hole can accept a list, and indicate a snippet that should be used to wrap each element of the list before being inserted as into the snippet hole. The two primary applications of this mechanism are #444 and #60
- [ ] The ability to indicate that a list valued snippet should join its elements using a particular string
- [ ] On insertion, these list-valued holes should support a workflow where you can instantiate the snippet with
ninstances of the hole snippet - [ ] These list-valued holes should support a command to insert another instance of the hole
- [ ] To indicate a transformation written in typescript that should be applied to the input to a particular hole
Some examples
- Converting an
if-elsestatement to aswitchstatement:"switch repack if state" "bring air past bat as list"
Examples we'd like to support
- [ ] Transform a dictionary to just a list consisting of its keys
- [ ] Transform a list to a dictionary
Questions
- Could we get a lot of this stuff for free by switching to a proper templating engine like handlebars?
One really smart thing we probably could do with snippets is to support repeating it. For example if you issued the "next" command on "$0" it would insert the snippet once again and put the cursor in the new "$1". This would be really useful for inserting a large number of items in a map/dictionary. Cases in a switch state and so on.
I think you definitely want this kind of functionality when you're in a list-valued snippet hole, to indicate you'd like to create another element of the list, which would then insert a new instance of the snippet defined for elements of that list
I wonder how useful it is in other situations. Because for example how does it know where to put the new snippet instance? At the cursor? After the current scope instance?
We probably need add a lot more boilerplate to our snippet definitions ;)
We definitely want to be able to enabled this only on particular snippets and in those cases we need to instruct it how it should add the next one.
I don't think we're actually too far off. On the insert snippet PR we can already specify the default insertion scope for a snippet, so that eg "snip foo after this" will insert after current if statement.
I know. But I'm not sure inserting the snippet in relation to a token or selection is the same thing as inserting the next snippet in relation to the previous snippet. I'm just saying we probably need to add some more information anyway.
I'd be inclined to restrict that kinda thing to nested snippets in list-valued snippet holes at the start and see if that gets us what we need