Extension sometimes adds an extra closing tag when formatting
See original GitHub issueSummary
Under some circumstances, Prettier will erroneously add an extra closing tag when formatting. From my testing, when it does this is inconsistent — I had to change my code a few times to get a simple example reproducing. I don’t have a solid idea of when it does or does not happen, but for a given input it is deterministic.
This issue does not occur when running prettier via the command line.
I confirmed that it was this extension in particular (or the extension interacting with VS Code itself) by disabling Prettier, starting Extension bisect (to disable all other extensions), then enabling Prettier (so it was the only extension enabled now) and testing the behavior.
Github Repository to Reproduce Issue
https://github.com/phoenixeliot/prettier-vscode-closing-tag-bug
Steps To Reproduce:
- Clone and open the demo repo in VS Code
- Open demo.html
- With the command palette, run “Format Document With…”, then select “Prettier”
Alternate Steps to Reproduce:
These steps match my actual use case, but are equivalent to the above using the demo repo.
- Start with this code:
<!DOCTYPE html>
<html lang="en">
<body>
<a class="footer-link" href="https://google.com">Words words words words words words words words words words</a>
</body>
</html>
- Format it with prettier. This generates:
<!DOCTYPE html>
<html lang="en">
<body>
<a class="footer-link" href="https://google.com"
>Words words words words words words words words words words</a
>
</body>
</html>
- Add spaces before and after the text to assist the formatter to not have those awkward line-broken open/close tags:
<!DOCTYPE html>
<html lang="en">
<body>
<a class="footer-link" href="https://google.com"
> Words words words words words words words words words words </a
>
</body>
</html>
- Format the code using prettier again
Expected result
Formatted code should be this:
<!DOCTYPE html>
<html lang="en">
<body>
<a class="footer-link" href="https://google.com">
Words words words words words words words words words words
</a>
</body>
</html>
Note that npx prettier ./demo.html
(using prettier v2.3.1, same as the extension I think) produces this correct output, where the VS Code extension does not.
Actual result
Formatted code is actually this, with an extra inserted (and invalid) </a>
on line 4.
<!DOCTYPE html>
<html lang="en">
<body>
<a class="footer-link" href="https://google.com"></a>
Words words words words words words words words words words
</a>
</body>
</html>
Note: If you use cmd-Z, it appears that this happened in two ‘undo steps’ — the first undo removes the </a>
and the second undo undoes the initial formatting.
Additional information
N/A
VS Code Version: Version: 1.59.0 (Universal)
Prettier Extension Version: v8.1.0
OS and version: macOS 11.5 (20G71)
Extra examples
These code samples do trigger the bug behavior:
<!DOCTYPE html>
<html lang="en">
<body>
<a class="footer-link" href="https://google.com"
> Words words words words words words words words words words </a
>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<body>
<div></div>
<a class="footer-link" href="https://google.com"
> Words words words words words words words words words words </a
>
</body>
</html>
These code samples below do not trigger this bug behavior, and behave correctly:
<!DOCTYPE html>
<html lang="en">
<body>
<a class="footer-link" href="https://google.com"
> Words words words words words words words words words words </a
>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<body>
<div>
<a class="footer-link" href="https://google.com"
> Words words words words words words words words words words </a
>
</div>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<body>
<div>
<div></div>
<a class="footer-link" href="https://google.com"
> Words words words words words words words words words words </a
>
</div>
</body>
</html>
Using newlines instead of spaces to space it out:
<!DOCTYPE html>
<html lang="en">
<body>
<a class="footer-link" href="https://google.com"
>
Words words words words words words words words words words
</a
>
</body>
</html>
Prettier Log Output
Debug logs
["INFO" - 3:27:35 PM] Extension Name: esbenp.prettier-vscode.
["INFO" - 3:27:35 PM] Extension Version: 8.1.0.
["DEBUG" - 3:27:35 PM] Enabling Prettier globally
{
"languageSelector": [
{
"language": "javascript",
"scheme": "file"
},
{
"language": "mongo",
"scheme": "file"
},
{
"language": "javascriptreact",
"scheme": "file"
},
{
"language": "typescript",
"scheme": "file"
},
{
"language": "typescriptreact",
"scheme": "file"
},
{
"language": "json",
"scheme": "file"
},
{
"language": "jsonc",
"scheme": "file"
},
{
"language": "json5",
"scheme": "file"
},
{
"language": "css",
"scheme": "file"
},
{
"language": "postcss",
"scheme": "file"
},
{
"language": "less",
"scheme": "file"
},
{
"language": "scss",
"scheme": "file"
},
{
"language": "handlebars",
"scheme": "file"
},
{
"language": "graphql",
"scheme": "file"
},
{
"language": "markdown",
"scheme": "file"
},
{
"language": "mdx",
"scheme": "file"
},
{
"language": "html",
"scheme": "file"
},
{
"language": "vue",
"scheme": "file"
},
{
"language": "yaml",
"scheme": "file"
},
{
"language": "ansible",
"scheme": "file"
},
{
"language": "home-assistant",
"scheme": "file"
},
{
"language": "javascript",
"scheme": "untitled"
},
{
"language": "mongo",
"scheme": "untitled"
},
{
"language": "javascriptreact",
"scheme": "untitled"
},
{
"language": "typescript",
"scheme": "untitled"
},
{
"language": "typescriptreact",
"scheme": "untitled"
},
{
"language": "json",
"scheme": "untitled"
},
{
"language": "jsonc",
"scheme": "untitled"
},
{
"language": "json5",
"scheme": "untitled"
},
{
"language": "css",
"scheme": "untitled"
},
{
"language": "postcss",
"scheme": "untitled"
},
{
"language": "less",
"scheme": "untitled"
},
{
"language": "scss",
"scheme": "untitled"
},
{
"language": "handlebars",
"scheme": "untitled"
},
{
"language": "graphql",
"scheme": "untitled"
},
{
"language": "markdown",
"scheme": "untitled"
},
{
"language": "mdx",
"scheme": "untitled"
},
{
"language": "html",
"scheme": "untitled"
},
{
"language": "vue",
"scheme": "untitled"
},
{
"language": "yaml",
"scheme": "untitled"
},
{
"language": "ansible",
"scheme": "untitled"
},
{
"language": "home-assistant",
"scheme": "untitled"
},
{
"language": "jsonc",
"scheme": "vscode-userdata"
}
],
"rangeLanguageSelector": [
{
"language": "javascript",
"scheme": "file"
},
{
"language": "javascriptreact",
"scheme": "file"
},
{
"language": "typescript",
"scheme": "file"
},
{
"language": "typescriptreact",
"scheme": "file"
},
{
"language": "json",
"scheme": "file"
},
{
"language": "graphql",
"scheme": "file"
},
{
"language": "javascript",
"scheme": "untitled"
},
{
"language": "javascriptreact",
"scheme": "untitled"
},
{
"language": "typescript",
"scheme": "untitled"
},
{
"language": "typescriptreact",
"scheme": "untitled"
},
{
"language": "json",
"scheme": "untitled"
},
{
"language": "graphql",
"scheme": "untitled"
}
]
}
["DEBUG" - 3:27:35 PM] Enabling Prettier for Workspace /Users/phoenix/Code/bugreports/prettier-closing-tag-bug
{
"languageSelector": [
{
"pattern": "/Users/phoenix/Code/bugreports/prettier-closing-tag-bug/**/*.{js,_js,bones,cjs,es,es6,frag,gs,jake,jsb,jscad,jsfl,jsm,jss,mjs,njs,pac,sjs,ssjs,xsjs,xsjslib,wxs,js.flow,jsx,ts,tsx,json,avsc,geojson,gltf,har,ice,JSON-tmLanguage,mcmeta,tfstate,tfstate.backup,topojson,webapp,webmanifest,yy,yyp,jsonc,sublime-build,sublime-commands,sublime-completions,sublime-keymap,sublime-macro,sublime-menu,sublime-mousemap,sublime-project,sublime-settings,sublime-theme,sublime-workspace,sublime_metrics,sublime_session,json5,css,wxss,pcss,postcss,less,scss,handlebars,hbs,graphql,gql,graphqls,md,markdown,mdown,mdwn,mkd,mkdn,mkdown,ronn,scd,workbook,mdx,component.html,html,htm,html.hl,inc,xht,xhtml,mjml,vue,yml,mir,reek,rviz,sublime-syntax,syntax,yaml,yaml-tmlanguage,yaml.sed,yml.mysql}",
"scheme": "file"
},
{
"language": "javascript",
"scheme": "file"
},
{
"language": "mongo",
"scheme": "file"
},
{
"language": "javascriptreact",
"scheme": "file"
},
{
"language": "typescript",
"scheme": "file"
},
{
"language": "typescriptreact",
"scheme": "file"
},
{
"language": "json",
"scheme": "file"
},
{
"language": "jsonc",
"scheme": "file"
},
{
"language": "json5",
"scheme": "file"
},
{
"language": "css",
"scheme": "file"
},
{
"language": "postcss",
"scheme": "file"
},
{
"language": "less",
"scheme": "file"
},
{
"language": "scss",
"scheme": "file"
},
{
"language": "handlebars",
"scheme": "file"
},
{
"language": "graphql",
"scheme": "file"
},
{
"language": "markdown",
"scheme": "file"
},
{
"language": "mdx",
"scheme": "file"
},
{
"language": "html",
"scheme": "file"
},
{
"language": "vue",
"scheme": "file"
},
{
"language": "yaml",
"scheme": "file"
},
{
"language": "ansible",
"scheme": "file"
},
{
"language": "home-assistant",
"scheme": "file"
},
{
"language": "javascript",
"scheme": "untitled"
},
{
"language": "mongo",
"scheme": "untitled"
},
{
"language": "javascriptreact",
"scheme": "untitled"
},
{
"language": "typescript",
"scheme": "untitled"
},
{
"language": "typescriptreact",
"scheme": "untitled"
},
{
"language": "json",
"scheme": "untitled"
},
{
"language": "jsonc",
"scheme": "untitled"
},
{
"language": "json5",
"scheme": "untitled"
},
{
"language": "css",
"scheme": "untitled"
},
{
"language": "postcss",
"scheme": "untitled"
},
{
"language": "less",
"scheme": "untitled"
},
{
"language": "scss",
"scheme": "untitled"
},
{
"language": "handlebars",
"scheme": "untitled"
},
{
"language": "graphql",
"scheme": "untitled"
},
{
"language": "markdown",
"scheme": "untitled"
},
{
"language": "mdx",
"scheme": "untitled"
},
{
"language": "html",
"scheme": "untitled"
},
{
"language": "vue",
"scheme": "untitled"
},
{
"language": "yaml",
"scheme": "untitled"
},
{
"language": "ansible",
"scheme": "untitled"
},
{
"language": "home-assistant",
"scheme": "untitled"
},
{
"language": "jsonc",
"scheme": "vscode-userdata"
}
],
"rangeLanguageSelector": [
{
"language": "javascript",
"scheme": "file"
},
{
"language": "javascriptreact",
"scheme": "file"
},
{
"language": "typescript",
"scheme": "file"
},
{
"language": "typescriptreact",
"scheme": "file"
},
{
"language": "json",
"scheme": "file"
},
{
"language": "graphql",
"scheme": "file"
},
{
"language": "javascript",
"scheme": "untitled"
},
{
"language": "javascriptreact",
"scheme": "untitled"
},
{
"language": "typescript",
"scheme": "untitled"
},
{
"language": "typescriptreact",
"scheme": "untitled"
},
{
"language": "json",
"scheme": "untitled"
},
{
"language": "graphql",
"scheme": "untitled"
}
]
}
["INFO" - 3:27:42 PM] Formatting /Users/phoenix/Code/bugreports/prettier-closing-tag-bug/demo.html
["INFO" - 3:27:42 PM] Using ignore file (if present) at /Users/phoenix/Code/bugreports/prettier-closing-tag-bug/.prettierignore
["INFO" - 3:27:42 PM] File Info:
{
"ignored": false,
"inferredParser": "html"
}
["INFO" - 3:27:42 PM] No local configuration (i.e. .prettierrc or .editorconfig) detected, falling back to VS Code configuration
["INFO" - 3:27:42 PM] Prettier Options:
{
"arrowParens": "always",
"bracketSpacing": true,
"endOfLine": "lf",
"htmlWhitespaceSensitivity": "css",
"insertPragma": false,
"jsxBracketSameLine": false,
"jsxSingleQuote": false,
"printWidth": 80,
"proseWrap": "preserve",
"quoteProps": "as-needed",
"requirePragma": false,
"semi": true,
"singleQuote": false,
"tabWidth": 2,
"trailingComma": "es5",
"useTabs": false,
"vueIndentScriptAndStyle": false,
"filepath": "/Users/phoenix/Code/bugreports/prettier-closing-tag-bug/demo.html",
"parser": "html"
}
["INFO" - 3:27:42 PM] Formatting completed in 48.765625ms.
Issue Analytics
- State:
- Created 2 years ago
- Reactions:2
- Comments:5
Top GitHub Comments
Awesome, thank you for doing that investigation 😃
I think it might be better vscode handle this issue because prettier-vscode returns right value from provideDocumentFormattingEdits method and there aren’t many things to do to fix it. So, I created an issue about it. https://github.com/microsoft/vscode/issues/137938