Conversation
747401e to
9e88e75
Compare
1006c3b to
758655b
Compare
|
Hi! This is ready for review. I'd be happy to fix any issues that there are with it. Thank you! |
58e04f4 to
4e74616
Compare
|
I've been debugging this for a couple of hours and I'm getting a couple of errors. First of all, Secondly, |
|
Take a look at
|
4e74616 to
581318c
Compare
src/cli-constant.js
Outdated
| "less", | ||
| "scss", | ||
| "json", | ||
| "glimmer", |
There was a problem hiding this comment.
Just comment this line out and update snapshots for now. When we release it we'll uncomment.
|
|
||
| <div {{hello param param param param hashPair=value hashPair=value hashPair=value hashPair=value hashPair=value}}> | ||
| Hello | ||
| </div> No newline at end of file |
There was a problem hiding this comment.
Newline here (there's a handful more, could you run through all of them?)
|
I added new lines to the test files and commented out the line you referenced. @azz |
1c2cf86 to
1525612
Compare
|
@robert-j-webb how did you solve the whitespace handling issues that are inherited from HTML? |
|
I trim away all white space. At some point, I want to preserve the users’ extra line breaks between elements. However, I scoped this pr to be a much more manageable pretty printer by dealing with that problem later, preferably with lots of community feedback. |
|
There was a massive refactor in #3536 that caused some conflicts here. Would you be able to solve them? Go with |
|
Yeah I'll start working on it! I love the plugin approach. |
Polished Support for Sub Expressions Added test cases for glimmer primitives Added support for concat statements Attempted to make element nodes work Attempted block statements Element Nodes are OK Added support for block elements that are not else-if related Added support for Else/If Cleaning up Rebase Switch node 4 syntax Update build
1525612 to
01cb048
Compare
01cb048 to
c7177f5
Compare
|
Ok I got the rebase to work @azz. I think so at least! It's really good that there's a solid plugin system now. |
vjeux
left a comment
There was a problem hiding this comment.
This is awesome, thanks for doing that! As soon as it is green we can merge it and iterate from there.
| Go to bed! | ||
| {{/if}} | ||
| </h1> | ||
| <h2> |
There was a problem hiding this comment.
We'll want to preserve the empty line above.
| <div class="entry"> | ||
| <h1> | ||
| {{title}} | ||
| </h1> |
There was a problem hiding this comment.
It seems overkill to always break
| {{if goodbye true}} | ||
| {{if goodbye false}} | ||
| {{if goodbye true}}" | ||
| > |
There was a problem hiding this comment.
Does it respect the jsx-bracket-same-line option?
There was a problem hiding this comment.
No it doesn't. I think a ternary in a few places would fix that though. I didn't write any support for options! :(
There was a problem hiding this comment.
It would be great to support it :)
Adding a new language to prettier works in two phases. The first one is to print everything in a correct way, which you mostly did here. The second one is to make all the things than can be thrown at it look good.
You’re now entering the second phase :) So expect to do a lot of tweaks everywhere.
There was a problem hiding this comment.
I expected this! I'm really happy to do this part too. I figured that it would need tweaking because a lot of the decisions I made were based off asking a few people in the community and then picking from what is available. I will be in airplane for a few hours next week so I'll have plenty of time to implement whatever is decided upon.
| A long enough string to trigger a line break that would prevent wrapping more. | ||
| </div> | ||
| <div> | ||
| A long enough string to trigger a line break that would prevent wrapping more and more. |
There was a problem hiding this comment.
This is one the tricky ones to decide. You wouldn't break this string up to multiple lines:
const hello = 'A string that is over 80 chars long';I could take text and break on space, but I think that's against what I would expect from prettier.
There was a problem hiding this comment.
I would recommend looking at what prettier outputs for jsx and try to be as close as possible. This has been battle tested over time and it hasn’t been a big source of issues.
| A long enough string to trigger a line break that would prevent wrapping more and more. | ||
| </div> | ||
| <div> | ||
| {{#block}}{{hello}}{{/block}} |
There was a problem hiding this comment.
I don't understand the heuristics you chose. Sometimes it is in one line, sometimes it breaks, for things that look similar.
There was a problem hiding this comment.
I would prefer that HTML tags would break as frequently as block elements, but I remember running into some situations where that would cause some very ugly formatting.
Perhaps block elements should also always break? What would be best?
There was a problem hiding this comment.
Here's a small example for JSX: Playground link
Input:
<div>
{a}
</div>;
<div>{a}</div>;
<div a>{a}</div>;
<div a b>{a}</div>;
<div>{a}{b}</div>;Output:
<div>{a}</div>;
<div>{a}</div>;
<div a>{a}</div>;
<div a b>
{a}
</div>;
<div>
{a}
{b}
</div>;It always break if there's >2 attributes or >2 values and inlines otherwise.
This is a small example but you should look at the JSX source code and see all the heuristics it does to make it look good.
| "less", | ||
| "scss", | ||
| "json", | ||
| // "glimmer", |
There was a problem hiding this comment.
I would name all those "handlebars". Except for JavaScript, we started naming the parser after the language it parses and not the actual name of the parser. This is easier for people to figure out which to use. It would be nice to rename it to --language at some point but we'll see.
There was a problem hiding this comment.
I agree that renaming from glimmer to handlebars would make sense. It's just that at this moment, glimmer doesn't support partial statements, which handlebars does support. So it's kind of a specific caveat that they're different.
There was a problem hiding this comment.
Do you know if there's a list of the differences between the two?
There was a problem hiding this comment.
I'm not sure, I'll ask the maintainers of the project. @mmun
There was a problem hiding this comment.
Handlebars is a plain text templating language. In practice it is often used as an HTML templating language, but it is also commonly used for templating configuration files (toml, ini, yaml, etc).
Glimmer is only used for templating HTML/DOM. There are a couple differences from vanilla HTML:
- The parser will hard error if non-void tags aren't balanced. It also only attempts to handle "content" HTML, e.g. it doesn't correctly handle <script> parsing. I don't think we plan to change that any time soon.
- There are a few extensions we've added to HTML that let us differentiate HTML attributes from component arguments:
You can also pass blocks as arguments (I believe they are commonly called render props in React)
There was a problem hiding this comment.
@mmun isn't it technically "HTMLBars" instead of "Glimmer" with "Glimmer" just implementing a parser for "HTMLBars"?
There was a problem hiding this comment.
@Turbo87 It's true that that is how we launched it but it was always for lack of a better name. You won't find references to HTMLBars in the guides/API docs anymore. The Glimmer brand now encompasses a DOM templating language, a runtime VM, and an experimental application framework (http://glimmerjs.com)
There was a problem hiding this comment.
@vjeux Let me start by saying thank you very much for working on prettier and for reviewing this PR! And thanks to @robert-j-webb for working on it!
I completely agree with you that we should minimize confusion with the configuration. Taking a step back away from Glimmer for a second, what configuration would you propose to differentiate between .txt.hbs, .md.hbs, .html.hbs, .toml.hbs, etc? Each variant would need different formatting for the non-Handlebars parts. It's also plausible to me that the stuff inside the curlies ({{ ... }}) might be slightly formatted differently depending on the variant as well.
I think that answering this question may shed some light on how to deal with Glimmer.
There was a problem hiding this comment.
I’m not super familiar with handlebars but the philosophy we followed with prettier so far is to take use cases one by one and make them really good. So my recommendation would be to make it work perfectly for Ember and then we can figure out how to handle more use cases. My guy feeling is that there’s a big market for people eager to get prettier to work for the html variant and low interest in the other variants right now.
|
|
||
| </body> | ||
| </html> | ||
| `; |
There was a problem hiding this comment.
The html parser/output seems to be completely broken :p
There was a problem hiding this comment.
Yeah it's not great. I could fix (it's very similar to handlebars) it but I wanted to scope my PR around just getting handlebars working because it's already so much code.
There was a problem hiding this comment.
Yeah, don’t worry about the html printer
|
I just want to be explicit about what the next steps are. Prettier has been successful because it doesn’t just prints code but because it prints it extremely well. In order to achieve this level of quality, we need to add a bunch of complexity in the printer. The good news is that we have already done a lot of similar work for JSX so you should steal as much as possible. This way it has already been battle tested and we know it works well, and if people switch between React and Ember projects using prettier, they will already be familiar with the way code is formatted. In order to make sure that things are well formatted, we want to run it in as many codebases as possible and go through the diffs and try to make all the outputs look as good as possible as well as running —debug-check to make sure that we’re printing correct code. Once it’s in a really good shape, then we can release it to everyone. At this point it’s likely going to get a lot of people to try it out and give good feedback that needs to be acted on. After a while it’ll stabilize and it’ll just work and save people a bunch of time :) I hope that it makes sense. Let me know if you have any questions. |
|
I absolutely understand! I'll look more into how JSX is doing things and try to mirror it. I don't know if it will be possible to reuse the JSX code itself, but I'll look into that. I'm excited to make this work extremely well! |
|
Awesome! It’s going to be so good :) For reusing code, I wouldn’t spend too much time, if it’s easy then do it but otherwise it’s not a big deal. It’s better for the behavior to be similar. |
|
@robert-j-webb A while ago @karl tried to come up with a intermediate representation that JSX, Handlebars and others would translate to and then apply the rules to that representation, if you're interested |
|
Quick question as a very interested consumer: is the easiest way to try this out just installing |
yarn add prettier/prettier
yarn prettier **/*.hbs --parser glimmer |
|
I tried running this at work (it's $ echo '{{^something}}{{/something}}' | node_modules/.bin/prettier --parser glimmer
[error] stdin: TypeError: Cannot read property 'blockParams' of undefined
[error] at TokenizerEventHandlers.Program (/Users/simbekkh/repos/mfinn/node_modules/@glimmer/syntax/dist/commonjs/es5/lib/parser/handlebars-node-visitors.js:67:61)
[error] at TokenizerEventHandlers.BlockStatement (/Users/simbekkh/repos/mfinn/node_modules/@glimmer/syntax/dist/commonjs/es5/lib/parser/handlebars-node-visitors.js:100:28)
[error] at TokenizerEventHandlers.acceptNode (/Users/simbekkh/repos/mfinn/node_modules/@glimmer/syntax/dist/commonjs/es5/lib/parser.js:64:31)
[error] at TokenizerEventHandlers.Program (/Users/simbekkh/repos/mfinn/node_modules/@glimmer/syntax/dist/commonjs/es5/lib/parser/handlebars-node-visitors.js:75:18)
[error] at TokenizerEventHandlers.acceptNode (/Users/simbekkh/repos/mfinn/node_modules/@glimmer/syntax/dist/commonjs/es5/lib/parser.js:64:31)
[error] at preprocess (/Users/simbekkh/repos/mfinn/node_modules/@glimmer/syntax/dist/commonjs/es5/lib/parser/tokenizer-event-handlers.js:336:61)
[error] at Object.parse (/Users/simbekkh/repos/mfinn/node_modules/prettier/src/language-handlebars/parser-glimmer.js:27:12)
[error] at Object.parse (/Users/simbekkh/repos/mfinn/node_modules/prettier/src/main/parser.js:61:19)
[error] at formatWithCursor (/Users/simbekkh/repos/mfinn/node_modules/prettier/index.js:100:22)
[error] at Object.formatWithCursor (/Users/simbekkh/repos/mfinn/node_modules/prettier/index.js:389:12)
[error] at format (/Users/simbekkh/repos/mfinn/node_modules/prettier/src/cli/util.js:154:19)
[error] at thirdParty.getStream.then.input (/Users/simbekkh/repos/mfinn/node_modules/prettier/src/cli/util.js:258:19)
[error] at <anonymous>
[error] at process._tickCallback (internal/process/next_tick.js:188:7) |
|
It also doesn't support partials, which is sad :( (glimmerjs/glimmer-vm#397) Another thing is that the column in the syntax errors are Yet another issue is that it says that <input {{#checked}}checked{{/checked}}>This also works just fine in http://tryhandlebarsjs.com/ That's all I've got for now. Not sure which, if any, are fixable. If this is aimed solely at ember, I suppose all of these are ok? 🤷♂️ I've never touched ember before, but I've used both handlebars and mustache |
|
@SimenB Thanks for the report! Yeah, we don't intend to support cases like |


This work is me picking off where @azz left. This is his pr and my starting point: here.
#1882 is the issue related to this.
Feedback is extremely welcome. I'm doing my best and I have a good deal of hours to dedicate to this.