diff --git a/src/ModuleResolverNode.ts b/src/ModuleResolverNode.ts index 4bb04eda8..685fa7f18 100644 --- a/src/ModuleResolverNode.ts +++ b/src/ModuleResolverNode.ts @@ -218,6 +218,29 @@ export class ModuleResolver implements ModuleResolverInterface { return; } + /** + * Determines if a document is an untitled (unsaved) document. + * Untitled documents have a scheme other than "file" (e.g., "untitled"). + */ + private isUntitledDocument(doc: TextDocument): boolean { + return doc.uri.scheme !== "file"; + } + + /** + * Gets the appropriate base path for config file searches. + * For untitled documents, uses the workspace folder path. + * For regular files, uses the file path itself. + */ + private getConfigSearchPath(doc: TextDocument): string { + if (this.isUntitledDocument(doc)) { + const workspaceFolder = workspace.getWorkspaceFolder(doc.uri); + if (workspaceFolder) { + return workspaceFolder.uri.fsPath; + } + } + return doc.fileName; + } + public async getResolvedConfig( doc: TextDocument, vscodeConfig: PrettierVSCodeConfig, @@ -227,7 +250,11 @@ export class ModuleResolver implements ModuleResolverInterface { (await this.getPrettierInstance(fileName)) ?? (await getBundledPrettier()); - return this.resolveConfig(prettier, fileName, vscodeConfig); + // For untitled documents (unsaved files), use workspace folder as base for config search + // This allows untitled documents to use workspace prettier configs when requireConfig is enabled + const configSearchPath = this.getConfigSearchPath(doc); + + return this.resolveConfig(prettier, configSearchPath, vscodeConfig); } public async clearModuleCache(filePath: string): Promise { diff --git a/src/test/suite/untitled.test.ts b/src/test/suite/untitled.test.ts new file mode 100644 index 000000000..1089054dc --- /dev/null +++ b/src/test/suite/untitled.test.ts @@ -0,0 +1,70 @@ +import * as assert from "assert"; +import * as vscode from "vscode"; +import { ensureExtensionActivated } from "./testUtils.js"; + +/** + * Tests for untitled documents (unsaved files) + */ +describe("Test untitled documents", () => { + before(async () => { + await ensureExtensionActivated(); + }); + + it("formats untitled JavaScript document", async () => { + // Create an untitled document with ugly JavaScript + const uglyCode = 'const x = 1 ; console.log( x ) ;'; + const doc = await vscode.workspace.openTextDocument({ + language: "javascript", + content: uglyCode, + }); + + const editor = await vscode.window.showTextDocument(doc); + + // Format the document + await vscode.commands.executeCommand("editor.action.formatDocument"); + + // The document should be formatted + const formattedText = editor.document.getText(); + + assert.notEqual( + formattedText, + uglyCode, + "Untitled document should have been formatted", + ); + + // Should not have excessive spacing + assert.ok( + !formattedText.includes(" "), + "Formatted code should not have excessive spacing", + ); + }); + + it("formats untitled TypeScript document", async () => { + // Create an untitled document with ugly TypeScript + const uglyCode = 'function test ( a : number ) : number { return a * 2 ; }'; + const doc = await vscode.workspace.openTextDocument({ + language: "typescript", + content: uglyCode, + }); + + const editor = await vscode.window.showTextDocument(doc); + + // Format the document + await vscode.commands.executeCommand("editor.action.formatDocument"); + + // The document should be formatted + const formattedText = editor.document.getText(); + + assert.notEqual( + formattedText, + uglyCode, + "Untitled TypeScript document should have been formatted", + ); + + // Should not have excessive spacing + assert.ok( + !formattedText.includes(" "), + "Formatted code should not have excessive spacing", + ); + }); +}); diff --git a/test-fixtures/require-config/.prettierrc b/test-fixtures/require-config/.prettierrc new file mode 100644 index 000000000..b2095be81 --- /dev/null +++ b/test-fixtures/require-config/.prettierrc @@ -0,0 +1,4 @@ +{ + "semi": false, + "singleQuote": true +} diff --git a/test-fixtures/require-config/.vscode/settings.json b/test-fixtures/require-config/.vscode/settings.json new file mode 100644 index 000000000..05d385f01 --- /dev/null +++ b/test-fixtures/require-config/.vscode/settings.json @@ -0,0 +1,4 @@ +{ + "prettier.requireConfig": true, + "files.eol": "\n" +} diff --git a/test-fixtures/require-config/package.json b/test-fixtures/require-config/package.json new file mode 100644 index 000000000..e2a8e287b --- /dev/null +++ b/test-fixtures/require-config/package.json @@ -0,0 +1,3 @@ +{ + "name": "require-config-test" +} diff --git a/test-fixtures/test.code-workspace b/test-fixtures/test.code-workspace index c155f35e2..4d585f944 100644 --- a/test-fixtures/test.code-workspace +++ b/test-fixtures/test.code-workspace @@ -65,6 +65,9 @@ }, { "path": "monorepo-subfolder" + }, + { + "path": "require-config" } ], "settings": {