vscode-postfix-ts
vscode-postfix-ts copied to clipboard
[proposal] Add `{{exprLast}}` template placeholder
Template Examples
{
"name": "destruct",
"body": "const { {{exprLast}}$1 } = {{exprRest}}",
"when": [
"expression",
]
},
{
"name": "log2",
"body": "console.log('{{exprLast}}', {{expr}})",
"when": [
"identifier",
"expression",
"function-call"
]
},
Usage Examples
defaultSettings.getGeneralSettings().clipboardLinkDetection.destruct
// => destruct
const { clipboardLinkDetection } = defaultSettings.getGeneralSettings()
(await fetchData()).customField.destruct
// => destruct
const { customField } = (await fetchData())
defaultSettings.general.clipboardLinkDetection.log2
// => log2
console.log('clipboardLinkDetection', defaultSettings.general.clipboardLinkDetection)
// update to include even more ideas
checkInterval.clear /* -> */ clearInterval(checkInterval)
closeTimeout.clear /* -> */ clearTimeout(closeTimeout)
While {{exprLast}}
can be useful in some scenarios like logging or usage for some custom function that accepts label as first argument. Another example would be usage with test()
& capitalize filter.
However, for now I can imagine only one case, where {{exprRest}}
can be useful (destruct
example above).
If you want, I can add this kind of hovers & completions
Most sublime approach i’ve ever seen
!!!
I like the idea, especially the destructuring example. However I have mixed feelings when it comes to naming those new segments with exprLast
and exprRest
. It's kind of hardcoded to solve those two specific problems you have had but this is not too flexible. This time you need last segment and the rest segment but other time you might need first segment and rest (but then rest will be everything from second to last).
I came up with another idea which is just a small extension to what you have already done. Just instead of exprLast
and the others why not make this flexible by design? Since this basically only makes sense for custom templates it should probably be always driven by configuration regex per template so for instance the examples above could look like this:
{
"name": "destruct",
"body": "const { {{expr:$last}}$1 } = {{expr:$rest}}",
"groupsRegex": "(?<rest>.*)\\.(?<last>.*)(?:\\(\\))?",
// alternatively:
"groups": {
"last": "\\.([^().]+)(?=$|\\(\\)$)",
"rest": ".*(?=\\.)"
},
"when": [
"expression",
]
},
{
"name": "log2",
"body": "console.log('{{expr:$last}}', {{expr}})",
"groupsRegex": "\\.(?<last>[^().]*)(?:\\(\\))?$",
"when": [
"identifier",
"expression",
"function-call"
]
},
It matches pretty well:
There is one flaw in that though. It might require quite advanced reg exps to be able to handle it and won't be as reliable as getting the last part from AST. Those were relatively easy examples but I can imagine it gets harder with more complex expressions.
However we could mix those two solutions so for instance there could be few predefined segments, for instance $last
could be handled by AST and maybe few others as well but the rest we can leave to regular expressions.
What do you think?
Wow, I actually have a lot of snippets (not postfixes) that use some kind of "groupsRegex", so I like the idea. on the other hand with these predefined placeholders we can not only avoid user of thinking how to handle complex expression but also reuse our code.
Also tbh I can't imagine for now other use cases, where other placeholders would be useful, but again I like this level of flexibility.
However, @ipatalas what do you think of merging this feature with exprRegex and exprLastRegex? (#92) It seems so logical to me (as I can imagine a lot of cases when I want to match only function name for example in function-call
's). Or you can add some other property which regex will be matched before function args. Example:
cache[user.getId()].matchAgainstMe(…).postfix
Maybe we can add some kind of general property into snippets e.g.
{
"name":…,
"body":…,
"locations":…,
"regex":{
"expr":…
}
}
Wow, I actually have a lot of snippets (not postfixes) that use some kind of "groupsRegex", so I like the idea. on the other hand with these predefined placeholders we can not only avoid user of thinking how to handle complex expression but also reuse our code.
Also tbh I can't imagine for now other use cases, where other placeholders would be useful, but again I like this level of flexibility.
Yeah, I can't imagine anything now so for now we can stay with this hardcoded ones and then when more ideas come into place we can extend that to be more flexible.
However, @ipatalas what do you think of merging this feature with exprRegex and exprLastRegex? (#92) It seems so logical to me (as I can imagine a lot of cases when I want to match only function name for example in
function-call
's).
Absolutely, it makes sense. It will allow more tailored postfixes which can be only valid for very specific use cases.