diff --git a/apps/oxfmt/src/lsp/server_formatter.rs b/apps/oxfmt/src/lsp/server_formatter.rs index 256ea1e683e9f..156a196011b86 100644 --- a/apps/oxfmt/src/lsp/server_formatter.rs +++ b/apps/oxfmt/src/lsp/server_formatter.rs @@ -257,15 +257,7 @@ impl Tool for ServerFormatter { content: Option<&str>, ) -> Result, String> { let file_content; - let (result, source_text) = if uri.as_str().starts_with("untitled:") { - let source_text = - content.ok_or_else(|| "In-memory formatting requires content".to_string())?; - - let Some(result) = self.format_in_memory(uri, source_text, language_id) else { - return Ok(vec![]); // currently not supported - }; - (result, source_text) - } else { + let (result, source_text) = if uri.scheme().as_str() == "file" { let Some(path) = uri.to_file_path() else { return Err("Invalid file URI".to_string()) }; let source_text = if let Some(c) = content { @@ -280,6 +272,14 @@ impl Tool for ServerFormatter { return Ok(vec![]); // No formatting for this file (unsupported or ignored) }; + (result, source_text) + } else { + let source_text = + content.ok_or_else(|| "In-memory formatting requires content".to_string())?; + + let Some(result) = self.format_in_memory(uri, source_text, language_id) else { + return Ok(vec![]); // currently not supported + }; (result, source_text) }; diff --git a/apps/oxfmt/test/lsp/format/__snapshots__/format.test.ts.snap b/apps/oxfmt/test/lsp/format/__snapshots__/format.test.ts.snap index f8657fdf3d25d..386b403e32ce0 100644 --- a/apps/oxfmt/test/lsp/format/__snapshots__/format.test.ts.snap +++ b/apps/oxfmt/test/lsp/format/__snapshots__/format.test.ts.snap @@ -277,21 +277,163 @@ const x = 1 --------------------" `; -exports[`LSP formatting > initializationOptions > should use custom config path from fmt.configPath 1`] = ` +exports[`LSP formatting > in-memory document > should format ccsettings file format/formatted.ts 1`] = ` "--- FILE ----------- -custom_config_path/semicolons-as-needed.ts +format/formatted.ts --- BEFORE --------- -// semicolon is on character 8-9, which will be removed -debugger; +const x = 1; --- AFTER ---------- -// semicolon is on character 8-9, which will be removed -debugger +const x = 1; + +--------------------" +`; + +exports[`LSP formatting > in-memory document > should format ccsettings file format/test.json 1`] = ` +"--- FILE ----------- +format/test.json +--- BEFORE --------- +{"name":"test","version":"1.0.0"} + +--- AFTER ---------- +{ "name": "test", "version": "1.0.0" } + +--------------------" +`; + +exports[`LSP formatting > in-memory document > should format ccsettings file format/test.toml 1`] = ` +"--- FILE ----------- +format/test.toml +--- BEFORE --------- +[package] +name="test" +version="1.0.0" + +--- AFTER ---------- +[package] +name = "test" +version = "1.0.0" + +--------------------" +`; + +exports[`LSP formatting > in-memory document > should format ccsettings file format/test.tsx 1`] = ` +"--- FILE ----------- +format/test.tsx +--- BEFORE --------- +const App: React.FC = () =>
Hello
+ +--- AFTER ---------- +const App: React.FC = () =>
Hello
; + +--------------------" +`; + +exports[`LSP formatting > in-memory document > should format ccsettings file format/test.txt 1`] = ` +"--- FILE ----------- +format/test.txt +--- BEFORE --------- +hello world + +--- AFTER ---------- +hello world + +--------------------" +`; + +exports[`LSP formatting > in-memory document > should format ccsettings file format/test.vue 1`] = ` +"--- FILE ----------- +format/test.vue +--- BEFORE --------- + + +--- AFTER ---------- + + +--------------------" +`; + +exports[`LSP formatting > in-memory document > should format untitled file format/formatted.ts 1`] = ` +"--- FILE ----------- +format/formatted.ts +--- BEFORE --------- +const x = 1; + +--- AFTER ---------- +const x = 1; + +--------------------" +`; + +exports[`LSP formatting > in-memory document > should format untitled file format/test.json 1`] = ` +"--- FILE ----------- +format/test.json +--- BEFORE --------- +{"name":"test","version":"1.0.0"} + +--- AFTER ---------- +{ "name": "test", "version": "1.0.0" } + +--------------------" +`; + +exports[`LSP formatting > in-memory document > should format untitled file format/test.toml 1`] = ` +"--- FILE ----------- +format/test.toml +--- BEFORE --------- +[package] +name="test" +version="1.0.0" + +--- AFTER ---------- +[package] +name = "test" +version = "1.0.0" + +--------------------" +`; + +exports[`LSP formatting > in-memory document > should format untitled file format/test.tsx 1`] = ` +"--- FILE ----------- +format/test.tsx +--- BEFORE --------- +const App: React.FC = () =>
Hello
+ +--- AFTER ---------- +const App: React.FC = () =>
Hello
; + +--------------------" +`; + +exports[`LSP formatting > in-memory document > should format untitled file format/test.txt 1`] = ` +"--- FILE ----------- +format/test.txt +--- BEFORE --------- +hello world + +--- AFTER ---------- +hello world --------------------" `; -exports[`LSP formatting > unsaved document > should format unsaved file format/formatted.ts 1`] = ` +exports[`LSP formatting > in-memory document > should format untitled file format/test.vue 1`] = ` +"--- FILE ----------- +format/test.vue +--- BEFORE --------- + + +--- AFTER ---------- + + +--------------------" +`; + +exports[`LSP formatting > in-memory document > should format vscode-userdata file format/formatted.ts 1`] = ` "--- FILE ----------- format/formatted.ts --- BEFORE --------- @@ -303,7 +445,7 @@ const x = 1; --------------------" `; -exports[`LSP formatting > unsaved document > should format unsaved file format/test.json 1`] = ` +exports[`LSP formatting > in-memory document > should format vscode-userdata file format/test.json 1`] = ` "--- FILE ----------- format/test.json --- BEFORE --------- @@ -315,7 +457,7 @@ format/test.json --------------------" `; -exports[`LSP formatting > unsaved document > should format unsaved file format/test.toml 1`] = ` +exports[`LSP formatting > in-memory document > should format vscode-userdata file format/test.toml 1`] = ` "--- FILE ----------- format/test.toml --- BEFORE --------- @@ -331,7 +473,7 @@ version = "1.0.0" --------------------" `; -exports[`LSP formatting > unsaved document > should format unsaved file format/test.tsx 1`] = ` +exports[`LSP formatting > in-memory document > should format vscode-userdata file format/test.tsx 1`] = ` "--- FILE ----------- format/test.tsx --- BEFORE --------- @@ -343,7 +485,7 @@ const App: React.FC = () =>
Hello
; --------------------" `; -exports[`LSP formatting > unsaved document > should format unsaved file format/test.txt 1`] = ` +exports[`LSP formatting > in-memory document > should format vscode-userdata file format/test.txt 1`] = ` "--- FILE ----------- format/test.txt --- BEFORE --------- @@ -355,7 +497,7 @@ hello world --------------------" `; -exports[`LSP formatting > unsaved document > should format unsaved file format/test.vue 1`] = ` +exports[`LSP formatting > in-memory document > should format vscode-userdata file format/test.vue 1`] = ` "--- FILE ----------- format/test.vue --- BEFORE --------- @@ -368,3 +510,17 @@ const x = 1; --------------------" `; + +exports[`LSP formatting > initializationOptions > should use custom config path from fmt.configPath 1`] = ` +"--- FILE ----------- +custom_config_path/semicolons-as-needed.ts +--- BEFORE --------- +// semicolon is on character 8-9, which will be removed +debugger; + +--- AFTER ---------- +// semicolon is on character 8-9, which will be removed +debugger + +--------------------" +`; diff --git a/apps/oxfmt/test/lsp/format/format.test.ts b/apps/oxfmt/test/lsp/format/format.test.ts index a46d66fd23f21..bcd3eaf501cd5 100644 --- a/apps/oxfmt/test/lsp/format/format.test.ts +++ b/apps/oxfmt/test/lsp/format/format.test.ts @@ -65,7 +65,7 @@ describe("LSP formatting", () => { }); }); - describe("unsaved document", () => { + describe("in-memory document", () => { it.each([ ["format/test.tsx", "typescriptreact"], ["format/test.json", "json"], @@ -73,7 +73,7 @@ describe("LSP formatting", () => { ["format/test.toml", "toml"], ["format/formatted.ts", "typescript"], ["format/test.txt", "plaintext"], - ])("should format unsaved file %s", async (path, languageId) => { + ])("should format untitled file %s", async (path, languageId) => { expect( await formatFixtureContent( FIXTURES_DIR, @@ -83,6 +83,37 @@ describe("LSP formatting", () => { ), ).toMatchSnapshot(); }); + + it.each([ + ["format/test.tsx", "typescriptreact"], + ["format/test.json", "json"], + ["format/test.vue", "vue"], + ["format/test.toml", "toml"], + ["format/formatted.ts", "typescript"], + ["format/test.txt", "plaintext"], + ])("should format vscode-userdata file %s", async (path, languageId) => { + expect( + await formatFixtureContent( + FIXTURES_DIR, + path, + "vscode-userdata://" + languageId, + languageId, + ), + ).toMatchSnapshot(); + }); + + it.each([ + ["format/test.tsx", "typescriptreact"], + ["format/test.json", "json"], + ["format/test.vue", "vue"], + ["format/test.toml", "toml"], + ["format/formatted.ts", "typescript"], + ["format/test.txt", "plaintext"], + ])("should format ccsettings file %s", async (path, languageId) => { + expect( + await formatFixtureContent(FIXTURES_DIR, path, "ccsettings://" + languageId, languageId), + ).toMatchSnapshot(); + }); }); describe("ignore patterns", () => {