-
Notifications
You must be signed in to change notification settings - Fork 102
Conversation
The date and time specification in this comment is interesting. It's possible to do with custom resolvers, but quite clunky (a resolver-variable pair per format). Also possible to do purely with regex transformations? Could be worth adding direct support for though. |
Here's a fun test snippet for all the official variables
TM_DIRECTORY and TM_FILEPATH both are supposed to return TM_SELECTED_TEXT refers to the text selected by each individual cursor. I believe it's only really used when selecting arbitrary text and running the command to expand a specific snippet (so the prefix doesn't need to match). I'm not sure if I'm getting the cursor word right (using language specific word characters) so some input on that would help. The various date formats are as VS Code does them, at least in English. Localisation is possible, but is currently hardcoded to Finally, the BLOCK_COMMENT_START and friends are more like placeholders right now, while atom/atom#18812 is in progress. It can be marginally improved, to detect the declared block or line delims, but complete support requires the grammar to declare all it's delims. |
lib/snippet-body.pegjs
Outdated
|
||
escapedForwardSlash = pair:'\\/' { return pair; } | ||
// Transform is applied when tabbed off |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this comment accurate? Looks like the transformation code is largely unchanged, and current behavior is to apply the transform immediately and upon every change to the input text.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
VS Code applies when tabbed off. But I guess leaving the existing behaviour also works.
I think I left that comment to remind me that whatever you're typing while filling it out doesn't matter, as only what you leave it as matters.
Proposed way to handle choices: Register as an autocomplete provider (ideally as needed, and not constantly). When going to show choices, select the default value (cursor to right) and show all options in an autocomplete popup (with some nice looking unique icons). The provider will set priority to a very high value and disable lower priority suggestions to keep the popup clear. The user can then
I can't think of a better way right now. I'll update when I get a working demo |
For the following snippet "*":
t1:
prefix: "bar"
body: """
Hello ${1|one,two,three|} world $0
""" but it's all smoke and mirrors. Current issues:
In summary, |
I’m curious to know whether there’s prior art in VSCode (or elsewhere) on what to do with the “choice” syntax when no autocompleter is present. The bare minimum, I think, would be to treat the first choice as the placeholder and ignore the others. I consider the choice syntax to be an annotation for convenience and that a snippet can degrade gracefully if the IDE doesn’t know a way to present the choices to the user, but maybe there are those who think it should be a stronger contract. |
I think this is a concern for |
Just now noticed this in your checklist:
Somehow this didn't click until one of my own snippets broke today. I have a snippet for banner comments:
The intent is to produce a row of But the latter behavior is correct. To achieve what I want, I need a To confirm my mistake, I tried this snippet in TextMate 2; it needed the Anyway, you know all of this, @Aerijo, and I'm just catching up. But to think out loud for a minute, I see a couple problems:
I don't know how large these two groups of affected users are. Probably pretty small, since we didn't get any bugs filed on this behavior. There is a third group of affected users, and it is exactly one person large: me. The person wrote several snippets relying on this faulty transformation behavior but didn't realize it was faulty because he was the one who wrote the feature. Anyway, (a) this is a break of backward compatibility; (b) it should be, because the pain of breaking backward compatibility is larger than the pain of deviating from the standard behavior; (c) there's not much we can do to cushion the (probably few) users who will be affected by this behavior change, since we won't be able to fix old snippets automatically. I suppose all there is to do is respond promptly with the fix if someone files a bug about the new correct behavior. (I had regretted that I never added any Flight Manual docs for the transform feature; now I'm regretting that less, since it would've introduced more people to a feature that was subtly broken. My penance, I think, will be to write that documentation in anticipation of the next release.) |
@savetheclocktower I can add a setting for that. |
It's up to you, and I'd give my 👍 (for whatever that's worth) whether or not you implemented a setting for it, but my vote would be no. If it were a setting, we'd have to support that wrong behavior indefinitely. A “use legacy transform behavior” setting would help group 2, but not group 1, and the only way it would help group 2 is if we defaulted the setting to |
*I’ll write some documentation instead |
} | ||
|
||
|
||
// TODO: Use correct locale |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is VSCode's behavior here? I can't think of anyplace in Atom that envisions non-English locales, but I'm curious about what would need to happen for this TODO
to be done.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Really, I have no idea how any locale stuff works. So that was to make sure any final result is intentional, not accidental
Describes functionality that will be present once atom/snippets#288 lands.
Here's my first draft of some comprehensive docs for the new stuff. |
I just added support for an alternative if-else format string syntax. Now I'm more familiar with the TextMate docs, it looks like their format string definition is more flexible than ours; it allows recursive variables and such. I also think the if and else rules are supposed to be recursively resolved, and not just treated as plain text. I don't know if it's worth working on that for this PR, or can be left for a later PR. The LSP doesn't seem to require it, so I'm happy not including it. I added the |
My vote would be to move it into its own PR and keep this one to the LSP stuff. That way it'll get merged sooner and people can start using it. |
@Aerijo, what's the status of this one? If the if-else syntax is moved into its own PR, are you happy with the rest of it as it stands? |
I'm happy with this PR as is. It's quite big, so I've sort of left gaps between commits to see if anything weird breaks, but I haven't exactly stress tested it either. Anything else now, besides review changes & bug fixes can wait for a new PR. I'm thinking it would be best to get it in Nightly, so we can see how (if at all) disruptive it will be. |
@lkashef Would you be able to consider merging this PR? I've got a lot of time right now to iron out any bugs that get discovered in nightly and beta. There are a couple of TODO comments for the resolver functionality (locales and comment delimiters), but I don't consider them blocking. |
@aviatesk Progress is happening; we're aiming to split it into smaller, more manageable PRs. The decaffeination of the remaining files is the first step. |
This PR was too big. I tried splitting it off into smaller PRs, but it was still much easier to just write a new package from the ground up. Many of the changes in this PR have already been added to the new package, and things like cleaner undo/redo are on my radar. Once (if) it matures, I may revisit making changes to this package, but for now I'm focusing all my snippet efforts on the new package. |
NOTE: Ready for review
Requirements
Description of the Change
Redoes a lot of stuff. Basic idea is to comply with the VS Code spec (based on TextMate spec; also used by Sublime Text) as much as possible, because that's the spec language servers are supposed to use. With this, we'll fully support well formed LSP snippets. The added features are also useful anyway, and following an existing spec means we don't have to define our own (though I believe it's all based off of TextMate anyway).
Putting this up now for feedback and trying it out while it's still being worked on.
Added
Changed
g
flag from transformation regex. If users want it, they can add it explicitly. And now, if they don't want it, they have a choice.\
only escapes the characters$
,}
, and\
(and a few others depending on context).g
flag where the implicit one was relied upon.SnippetExpansion
, which is a temporary representation for the expanded snippet.snippet.getTabStops
into something more modular. Currently renamed totoString
, but it will make the insertion string and tab stops.editor.transact
calls; these appeared to only make the undo behaviour fail in strange ways.Open Questions
[ ] Should\
escape everything? It would make it easier to remember what it does, but subtly break VS Code compatibility (which is slightly different in a few areas anyway). It would also simplify the grammar.Alternate Designs
Would have removed
\u
and co flags entirely, but they appear to be supported by TextMate too and so are worth keeping.Benefits
99% backwards compatible, and adds much more advanced and dynamic capabilities. With custom variable resolvers, users can do pretty much anything with the provided text editor (and any other relevant params).
Possible Drawbacks
Bodies that contained text like
${1|one,two,three|}
will now be interpreted, instead of being a literal. But 1. the fix is to escape the$
like this\\${1|one,two,three|}
(as the raw CSON value), and 2. no one* would be doing that unless they wanted a choice placeholder anyway.*me
Applicable Issues
Closes #287 (this also contains the decaffeination changes)
Closes #285
Also closes #41 I think
Closes atom/apm#213. That conversion uses alternate replacement syntax
(?1:=:=)
that now has support added here too.