Repository: sveltejs/prettier-plugin-svelte (ts)

Issue:
Prettier's `requirePragma` is not respected
Given the file `test.svelte`:

```svelte
<script>
  const foo =        "bar";
</script>

{foo}
```

Prettier won't ignore the file even though the pragma is not present:

```sh
$ npx prettier --require-pragma --check test.svelte 
	[warn] test.svelte
    [warn] Code style issues found in the above file. Forgot to run Prettier?
```

See also: https://prettier.io/docs/en/options.html#require-pragma

Pull request description:
feat: support insert/require pragma options
closes #350

Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0830db0..837d1aa 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,9 @@
 # prettier-plugin-svelte changelog
 
+## 2.10.0 (unreleased)
+
+-   (feat) support `requirePragma` and `insertPragma` options
+
 ## 2.9.0
 
 -   (feat) support style modifiers ([#330](https://github.com/sveltejs/prettier-plugin-svelte/issues/330))
diff --git a/src/index.ts b/src/index.ts
index 1b84f11..c773511 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -1,5 +1,5 @@
 import { SupportLanguage, Parser, Printer } from 'prettier';
-import { print } from './print';
+import { hasPragma, print } from './print';
 import { ASTNode } from './print/nodes';
 import { embed } from './embed';
 import { snipScriptAndStyleTagContent } from './lib/snipTagContent';
@@ -23,6 +23,7 @@ export const languages: Partial<SupportLanguage>[] = [
 
 export const parsers: Record<string, Parser> = {
     svelte: {
+        hasPragma,
         parse: (text) => {
             try {
                 return <ASTNode>{ ...require(`svelte/compiler`).parse(text), __isRoot: true };
diff --git a/src/print/index.ts b/src/print/index.ts
index 66514be..692d19d 100644
--- a/src/print/index.ts
+++ b/src/print/index.ts
@@ -83,6 +83,10 @@ declare module 'prettier' {
     }
 }
 
+export function hasPragma(text: string) {
+    return /^\s*<!--\s*@(format|prettier)\W/.test(text);
+}
+
 let ignoreNext = false;
 let ignoreRange = false;
 let svelteOptionsDoc: Doc | undefined;
@@ -772,7 +776,13 @@ function printTopLevelParts(
                 delete topLevelPartsByEnd[node.start];
             }
         }
-        return path.call(print, 'html');
+
+        const result = path.call(print, 'html');
+        if (options.insertPragma && !hasPragma(options.originalText)) {
+            return concat([`<!-- @format -->`, hardline, result]);
+        } else {
+            return result;
+        }
     }
 
     const parts: Record<SortOrderPart, Doc[]> = {
@@ -826,7 +836,11 @@ function printTopLevelParts(
         trimRight([lastDoc], isLine);
     }
 
-    return groupConcat([join(hardline, docs)]);
+    if (options.insertPragma && !hasPragma(options.originalText)) {
+        return concat([`<!-- @format -->`, hardline, groupConcat(docs)]);
+    } else {
+        return groupConcat([join(hardline, docs)]);
+    }
 }
 
 function printAttributeNodeValue(


Test patch:
diff --git a/test/formatting/samples/insert-pragma/input.html b/test/formatting/samples/insert-pragma/input.html
new file mode 100644
index 0000000..77e7173
--- /dev/null
+++ b/test/formatting/samples/insert-pragma/input.html
@@ -0,0 +1,4 @@
+<p>
+    format
+    me
+</p>
\ No newline at end of file
diff --git a/test/formatting/samples/insert-pragma/options.json b/test/formatting/samples/insert-pragma/options.json
new file mode 100644
index 0000000..a23c02d
--- /dev/null
+++ b/test/formatting/samples/insert-pragma/options.json
@@ -0,0 +1,3 @@
+{
+    "insertPragma": true
+}
diff --git a/test/formatting/samples/insert-pragma/output.html b/test/formatting/samples/insert-pragma/output.html
new file mode 100644
index 0000000..22c5387
--- /dev/null
+++ b/test/formatting/samples/insert-pragma/output.html
@@ -0,0 +1,2 @@
+<!-- @format -->
+<p>format me</p>
diff --git a/test/formatting/samples/require-pragma-present/input.html b/test/formatting/samples/require-pragma-present/input.html
new file mode 100644
index 0000000..c418ccf
--- /dev/null
+++ b/test/formatting/samples/require-pragma-present/input.html
@@ -0,0 +1,5 @@
+<!-- @format -->
+<p>
+    format
+    me
+</p>
\ No newline at end of file
diff --git a/test/formatting/samples/require-pragma-present/options.json b/test/formatting/samples/require-pragma-present/options.json
new file mode 100644
index 0000000..b6729a6
--- /dev/null
+++ b/test/formatting/samples/require-pragma-present/options.json
@@ -0,0 +1,3 @@
+{
+    "requirePragma": true
+}
diff --git a/test/formatting/samples/require-pragma-present/output.html b/test/formatting/samples/require-pragma-present/output.html
new file mode 100644
index 0000000..22c5387
--- /dev/null
+++ b/test/formatting/samples/require-pragma-present/output.html
@@ -0,0 +1,2 @@
+<!-- @format -->
+<p>format me</p>
diff --git a/test/printer/samples/insert-pragma-present.html b/test/printer/samples/insert-pragma-present.html
new file mode 100644
index 0000000..fcbef3c
--- /dev/null
+++ b/test/printer/samples/insert-pragma-present.html
@@ -0,0 +1,2 @@
+<!-- @format -->
+<p>already formatted</p>
diff --git a/test/printer/samples/insert-pragma-present.options.json b/test/printer/samples/insert-pragma-present.options.json
new file mode 100644
index 0000000..a23c02d
--- /dev/null
+++ b/test/printer/samples/insert-pragma-present.options.json
@@ -0,0 +1,3 @@
+{
+    "insertPragma": true
+}
diff --git a/test/printer/samples/require-pragma-missing.html b/test/printer/samples/require-pragma-missing.html
new file mode 100644
index 0000000..bccad2d
--- /dev/null
+++ b/test/printer/samples/require-pragma-missing.html
@@ -0,0 +1,5 @@
+<p>
+
+
+    nope
+</p>
\ No newline at end of file
diff --git a/test/printer/samples/require-pragma-missing.options.json b/test/printer/samples/require-pragma-missing.options.json
new file mode 100644
index 0000000..b6729a6
--- /dev/null
+++ b/test/printer/samples/require-pragma-missing.options.json
@@ -0,0 +1,3 @@
+{
+    "requirePragma": true
+}