diff --git a/src/language-handlebars/printer-glimmer.js b/src/language-handlebars/printer-glimmer.js
index 2ab7a415..9261d0a3 100644
--- a/src/language-handlebars/printer-glimmer.js
+++ b/src/language-handlebars/printer-glimmer.js
@@ -249,7 +249,7 @@ function print(path, options, print) {
return concat([""]);
}
case "StringLiteral": {
- return `"${n.value}"`;
+ return printStringLiteral(n.value, options);
}
case "NumberLiteral": {
return String(n.value);
@@ -267,6 +267,50 @@ function print(path, options, print) {
}
}
+/**
+ * Prints a string literal with the correct surrounding quotes based on
+ * `options.singleQuote` and the number of escaped quotes contained in
+ * the string literal. This function is the glimmer equivalent of `printString`
+ * in `common/util`, but has differences because of the way escaped characters
+ * are treated in hbs string literals.
+ * @param {string} stringLiteral - the string literal value
+ * @param {object} options - the prettier options object
+ */
+function printStringLiteral(stringLiteral, options) {
+ const double = { quote: '"', regex: /"/g };
+ const single = { quote: "'", regex: /'/g };
+
+ const preferred = options.singleQuote ? single : double;
+ const alternate = preferred === single ? double : single;
+
+ let shouldUseAlternateQuote = false;
+
+ // If `stringLiteral` contains at least one of the quote preferred for
+ // enclosing the string, we might want to enclose with the alternate quote
+ // instead, to minimize the number of escaped quotes.
+ if (
+ stringLiteral.includes(preferred.quote) ||
+ stringLiteral.includes(alternate.quote)
+ ) {
+ const numPreferredQuotes = (stringLiteral.match(preferred.regex) || [])
+ .length;
+ const numAlternateQuotes = (stringLiteral.match(alternate.regex) || [])
+ .length;
+
+ shouldUseAlternateQuote = numPreferredQuotes > numAlternateQuotes;
+ }
+
+ const enclosingQuote = shouldUseAlternateQuote ? alternate : preferred;
+ const escapedStringLiteral = stringLiteral.replace(
+ enclosingQuote.regex,
+ `\\${enclosingQuote.quote}`
+ );
+
+ return `${enclosingQuote.quote}${escapedStringLiteral}${
+ enclosingQuote.quote
+ }`;
+}
+
function printPath(path, print) {
return path.call(print, "path");
}
diff --git a/tests/glimmer/__snapshots__/jsfmt.spec.js.snap b/tests/glimmer/__snapshots__/jsfmt.spec.js.snap
index d44d733f..32d26673 100644
--- a/tests/glimmer/__snapshots__/jsfmt.spec.js.snap
+++ b/tests/glimmer/__snapshots__/jsfmt.spec.js.snap
@@ -134,6 +134,140 @@ exports[`block-statement.hbs - glimmer-verify 1`] = `
`;
+exports[`block-statement.hbs - glimmer-verify 2`] = `
+{{#block param hashKey=hashValue as |blockParam|}}
+ Hello
+{{/block}}
+
+{{#block almost80CharacterLongPositionalParamThatIsFirstAlmost80Chars helloWorldParam key=here}}
+{{/block}}
+
+{{#block param param param param param param param hashKey=hashValue as |blockParam|}}
+ Hello
+{{/block}}
+
+{{#block param param param param param param param hashKey=HashValue hashKey=hashValue}}
+ Hello
+{{/block}}
+
+{{#block param param param param param param param param param param param param param}}
+ Hello
+{{/block}}
+
+{{#block hashKey=HashValue hashKey=hashValue hashKey=HashValue hashKey=hashValue hashKey=HashValue}}
+ Hello
+{{/block}}
+
+{{#block}}
+ {{#block}}
+ hello
+ {{/block}}
+{{/block}}
+
+{{#block}}
+ {{#block param}}
+ hello
+ {{/block}}
+{{/block}}
+
+{{#block param}}
+ {{#block param}}
+ hello
+ {{/block}}
+{{/block}}
+
+{{#block}}
+ hello
+{{/block}}
+
+