Repository: sveltejs/prettier-plugin-svelte
Pull request #184 (2021-01-07 13:24:09)

(fix) inline formatting when there's a line 


Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 76fe80e..4a70352 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,9 @@
 # prettier-plugin-svelte changelog
 
+## 2.0.1 (Unreleased)
+
+* Fix formatting of inline element when there's a line at the start/end ([#183](https://github.com/sveltejs/prettier-plugin-svelte/issues/183))
+
 ## 2.0.0
 
 This release comes with a rewrite of the HTML formatting. The output is now much more in line with how standard Prettier formats HTML. This is also why `svelteBracketNewLine` now defaults to `true`. Another notable default change is the sort order: `svelte:options` is now part of the sort order and the default changed to `options-scripts-markup-styles`, which is in line with how the majority of users like to order the code blocks.
diff --git a/src/print/index.ts b/src/print/index.ts
index 962c2b2..bc039a0 100644
--- a/src/print/index.ts
+++ b/src/print/index.ts
@@ -259,11 +259,42 @@ export function print(path: FastPath, options: ParserOptions, print: PrintFn): D
                 ]);
             }
 
+            // No hugging of content means it's either a block element and/or there's whitespace at the start/end
+            let noHugSeparatorStart: Doc = softline;
+            let noHugSeparatorEnd: Doc = softline;
+            if (isPreTagContent(path)) {
+                noHugSeparatorStart = '';
+                noHugSeparatorEnd = '';
+            } else {
+                let didSetEndSeparator = false;
+
+                if (!hugStart && firstChild && firstChild.type === 'Text') {
+                    if (
+                        isTextNodeStartingWithLinebreak(firstChild) &&
+                        firstChild !== lastChild &&
+                        (!isInlineElement(path, node) || isTextNodeEndingWithWhitespace(lastChild))
+                    ) {
+                        noHugSeparatorStart = hardline;
+                        noHugSeparatorEnd = hardline;
+                        didSetEndSeparator = true;
+                    } else if (isInlineElement(path, node)) {
+                        noHugSeparatorStart = line;
+                    }
+                    trimTextNodeLeft(firstChild);
+                }
+                if (!hugEnd && lastChild && lastChild.type === 'Text') {
+                    if (isInlineElement(path, node) && !didSetEndSeparator) {
+                        noHugSeparatorEnd = line;
+                    }
+                    trimTextNodeRight(lastChild);
+                }
+            }
+
             if (hugStart) {
                 return groupConcat([
                     ...openingTag,
                     group(indent(concat([softline, groupConcat(['>', body()])]))),
-                    softline,
+                    noHugSeparatorEnd,
                     `</${node.name}>`,
                 ]);
             }
@@ -272,7 +303,11 @@ export function print(path: FastPath, options: ParserOptions, print: PrintFn): D
                 return groupConcat([
                     ...openingTag,
                     '>',
-                    group(indent(concat([softline, groupConcat([body(), `</${node.name}`])]))),
+                    group(
+                        indent(
+                            concat([noHugSeparatorStart, groupConcat([body(), `</${node.name}`])]),
+                        ),
+                    ),
                     softline,
                     '>',
                 ]);
@@ -282,34 +317,10 @@ export function print(path: FastPath, options: ParserOptions, print: PrintFn): D
                 return groupConcat([...openingTag, '>', body(), `</${node.name}>`]);
             }
 
-            // No hugging of content means it's either a block element and/or there's whitespace at the start/end
-            let separatorStart: Doc = softline;
-            let separatorEnd: Doc = softline;
-            if (isPreTagContent(path)) {
-                separatorStart = '';
-                separatorEnd = '';
-            } else {
-                if (firstChild && firstChild.type === 'Text') {
-                    if (isTextNodeStartingWithLinebreak(firstChild) && firstChild !== lastChild) {
-                        separatorStart = hardline;
-                        separatorEnd = hardline;
-                    } else if (isInlineElement(path, node)) {
-                        separatorStart = line;
-                    }
-                    trimTextNodeLeft(firstChild);
-                }
-                if (lastChild && lastChild.type === 'Text') {
-                    if (isInlineElement(path, node)) {
-                        separatorEnd = line;
-                    }
-                    trimTextNodeRight(lastChild);
-                }
-            }
-
             return groupConcat([
                 ...openingTag,
                 '>',
-                groupConcat([indent(concat([separatorStart, body()])), separatorEnd]),
+                groupConcat([indent(concat([noHugSeparatorStart, body()])), noHugSeparatorEnd]),
                 `</${node.name}>`,
             ]);
         }


Test patch:
diff --git a/test/formatting/samples/inline-element-with-hardline/input.html b/test/formatting/samples/inline-element-with-hardline/input.html
new file mode 100644
index 0000000..bfba889
--- /dev/null
+++ b/test/formatting/samples/inline-element-with-hardline/input.html
@@ -0,0 +1,13 @@
+<a>
+    asd</a
+>
+
+<a>
+    asd<span>asd</span></a
+>
+
+<a>asd
+</a>
+
+<a>asd<span>asd</span>
+</a>
\ No newline at end of file
diff --git a/test/formatting/samples/inline-element-with-hardline/output.html b/test/formatting/samples/inline-element-with-hardline/output.html
new file mode 100644
index 0000000..917baf5
--- /dev/null
+++ b/test/formatting/samples/inline-element-with-hardline/output.html
@@ -0,0 +1,7 @@
+<a> asd</a>
+
+<a> asd<span>asd</span></a>
+
+<a>asd </a>
+
+<a>asd<span>asd</span> </a>