From ea3def922cd9186adb889b85ff3b157b1dd3d7ad Mon Sep 17 00:00:00 2001 From: Pig Fang Date: Sun, 25 Aug 2024 18:17:28 +0800 Subject: [PATCH] feat(fmt): add `forceDouble`/`forceSingle` to `quotes` option (close #3) --- docs/src/config/quotes.md | 20 ++++++++- dprint_plugin/deployment/schema.json | 10 ++++- dprint_plugin/src/config.rs | 2 + pretty_yaml/src/config.rs | 6 +++ pretty_yaml/src/printer.rs | 36 ++++++++++++---- pretty_yaml/tests/fmt/quote/config.toml | 6 +++ .../fmt/quote/multiline.force-double.snap | 41 +++++++++++++++++++ .../fmt/quote/multiline.force-single.snap | 41 +++++++++++++++++++ .../tests/fmt/quote/quote.force-double.snap | 12 ++++++ .../tests/fmt/quote/quote.force-single.snap | 12 ++++++ .../tests/fmt/quote/quote.prefer-double.snap | 2 +- .../tests/fmt/quote/quote.prefer-single.snap | 2 +- .../spec-example-2.17-quoted-scalars.snap | 2 +- 13 files changed, 177 insertions(+), 15 deletions(-) create mode 100644 pretty_yaml/tests/fmt/quote/multiline.force-double.snap create mode 100644 pretty_yaml/tests/fmt/quote/multiline.force-single.snap create mode 100644 pretty_yaml/tests/fmt/quote/quote.force-double.snap create mode 100644 pretty_yaml/tests/fmt/quote/quote.force-single.snap diff --git a/docs/src/config/quotes.md b/docs/src/config/quotes.md index 5dbfa38..4d4b976 100644 --- a/docs/src/config/quotes.md +++ b/docs/src/config/quotes.md @@ -4,8 +4,10 @@ Control the quotes. Possible options: -- `"preferDouble"`: Use double quotes as possible. However if there're escaped characters in strings, quotes will be kept as-is. -- `"preferSingle"`: Use single quotes as possible. However if there're `\` char or `"` char in strings, quotes will be kept as-is. +- `"preferDouble"`: Use double quotes as possible. However if there're quotes or escaped characters in strings, quotes will be kept as-is. +- `"preferSingle"`: Use single quotes as possible. However if there're quotes or `\` characters in strings, quotes will be kept as-is. +- `"forceDouble"`: Use double quotes. However if there're escaped characters in strings, quotes will be kept as-is. +- `"forceSingle"`: Use single quotes. However if there're `\` char or `"` char in strings, quotes will be kept as-is. Default option is `"preferDouble"`. We recommend to use double quotes because behavior in single quoted scalars is counter-intuitive. @@ -14,10 +16,24 @@ We recommend to use double quotes because behavior in single quoted scalars is c ```yaml - "text" +- '"' ``` ## Example for `"preferSingle"` +```yaml +- 'text' +- "'" +``` + +## Example for `"forceDouble"` + +```yaml +- "text" +``` + +## Example for `"forceSingle"` + ```yaml - 'text' ``` diff --git a/dprint_plugin/deployment/schema.json b/dprint_plugin/deployment/schema.json index 28c6992..599f402 100644 --- a/dprint_plugin/deployment/schema.json +++ b/dprint_plugin/deployment/schema.json @@ -36,10 +36,18 @@ "oneOf": [ { "const": "preferDouble", - "description": "Use double quotes as possible. However if there're escaped characters in strings, quotes will be kept as-is. (Recommended)" + "description": "Use double quotes as possible. However if there're quotes or escaped characters in strings, quotes will be kept as-is." }, { "const": "preferSingle", + "description": "Use single quotes as possible. However if there're quotes or `\\` characters in strings, quotes will be kept as-is." + }, + { + "const": "forceDouble", + "description": "Use double quotes as possible. However if there're escaped characters in strings, quotes will be kept as-is. (Recommended)" + }, + { + "const": "forceSingle", "description": "Use single quotes as possible. However if there're `\\` char or `\"` char in strings, quotes will be kept as-is." } ], diff --git a/dprint_plugin/src/config.rs b/dprint_plugin/src/config.rs index e4634b9..2f731d6 100644 --- a/dprint_plugin/src/config.rs +++ b/dprint_plugin/src/config.rs @@ -54,6 +54,8 @@ pub(crate) fn resolve_config( ) { "preferDouble" => Quotes::PreferDouble, "preferSingle" => Quotes::PreferSingle, + "forceDouble" => Quotes::ForceDouble, + "forceSingle" => Quotes::ForceSingle, _ => { diagnostics.push(ConfigurationDiagnostic { property_name: "quotes".into(), diff --git a/pretty_yaml/src/config.rs b/pretty_yaml/src/config.rs index 4e89f04..edcc315 100644 --- a/pretty_yaml/src/config.rs +++ b/pretty_yaml/src/config.rs @@ -149,6 +149,12 @@ pub enum Quotes { #[cfg_attr(feature = "config_serde", serde(alias = "preferSingle"))] /// Make string to single quoted unless it contains double quotes inside. PreferSingle, + + #[cfg_attr(feature = "config_serde", serde(alias = "forceDouble"))] + ForceDouble, + + #[cfg_attr(feature = "config_serde", serde(alias = "forceSingle"))] + ForceSingle, } #[derive(Clone, Debug, Default)] diff --git a/pretty_yaml/src/printer.rs b/pretty_yaml/src/printer.rs index 8fc0ef0..35b8e46 100644 --- a/pretty_yaml/src/printer.rs +++ b/pretty_yaml/src/printer.rs @@ -337,11 +337,20 @@ impl DocGen for Flow { let text = text .get(1..text.len() - 1) .expect("expected double quoted scalar"); - let is_double_preferred = matches!(ctx.options.quotes, Quotes::PreferDouble); - let (quotes_option, quote) = if is_double_preferred || text.contains('\\') { + let (quotes_option, quote) = if text.contains('\\') { (None, "\"") } else { - (Some(&ctx.options.quotes), "'") + match &ctx.options.quotes { + Quotes::PreferSingle => { + if text.contains(['\'', '"']) { + (None, "\"") + } else { + (Some(&ctx.options.quotes), "'") + } + } + Quotes::PreferDouble | Quotes::ForceDouble => (None, "\""), + Quotes::ForceSingle => (Some(&ctx.options.quotes), "'"), + } }; docs.push(Doc::text(quote)); format_quoted_scalar(text, quotes_option, &mut docs, ctx); @@ -351,11 +360,20 @@ impl DocGen for Flow { let text = text .get(1..text.len() - 1) .expect("expected single quoted scalar"); - let is_single_preferred = matches!(ctx.options.quotes, Quotes::PreferSingle); - let (quotes_option, quote) = if is_single_preferred || text.contains(['\\', '"']) { + let (quotes_option, quote) = if text.contains(['\\', '"']) { (None, "'") } else { - (Some(&ctx.options.quotes), "\"") + match &ctx.options.quotes { + Quotes::PreferDouble => { + if text.contains(['\'', '"']) { + (None, "'") + } else { + (Some(&ctx.options.quotes), "\"") + } + } + Quotes::PreferSingle | Quotes::ForceSingle => (None, "'"), + Quotes::ForceDouble => (Some(&ctx.options.quotes), "\""), + } }; docs.push(Doc::text(quote)); format_quoted_scalar(text, quotes_option, &mut docs, ctx); @@ -1207,9 +1225,9 @@ fn format_quoted_scalar( } fn format_quoted_scalar_line(s: &str, quotes_option: Option<&Quotes>) -> String { match quotes_option { - Some(Quotes::PreferDouble) => s.replace("''", "'"), - Some(Quotes::PreferSingle) => s.replace('\'', "''"), - None => s.to_owned(), + Some(Quotes::ForceDouble) => s.replace("''", "'"), + Some(Quotes::ForceSingle) => s.replace('\'', "''"), + Some(Quotes::PreferDouble | Quotes::PreferSingle) | None => s.to_owned(), } } diff --git a/pretty_yaml/tests/fmt/quote/config.toml b/pretty_yaml/tests/fmt/quote/config.toml index c5da14a..3c43a0b 100644 --- a/pretty_yaml/tests/fmt/quote/config.toml +++ b/pretty_yaml/tests/fmt/quote/config.toml @@ -3,3 +3,9 @@ quotes = "preferDouble" [prefer-single] quotes = "preferSingle" + +[force-double] +quotes = "forceDouble" + +[force-single] +quotes = "forceSingle" diff --git a/pretty_yaml/tests/fmt/quote/multiline.force-double.snap b/pretty_yaml/tests/fmt/quote/multiline.force-double.snap new file mode 100644 index 0000000..bee4e93 --- /dev/null +++ b/pretty_yaml/tests/fmt/quote/multiline.force-double.snap @@ -0,0 +1,41 @@ +--- +source: pretty_yaml/tests/fmt.rs +--- +a: " + 123123123123123123123123123 + 123123123123123123123123123 + 123123123123123123123123123 + 123123123123123123123123123 + 123123123123123123123123123 + 123123123123123123123123123 + 123123123123123123123123123 + + 123123123123123123123123123 + + + 123123123123123123123123123 + + + + + 123123123123123123123123123 +" +b: " + 123123123123123123123123123 + 123123123123123123123123123 + 123123123123123123123123123 + 123123123123123123123123123 + 123123123123123123123123123 + 123123123123123123123123123 + 123123123123123123123123123 + + 123123123123123123123123123 + + + 123123123123123123123123123 + + + + + 123123123123123123123123123 +" diff --git a/pretty_yaml/tests/fmt/quote/multiline.force-single.snap b/pretty_yaml/tests/fmt/quote/multiline.force-single.snap new file mode 100644 index 0000000..e2008b2 --- /dev/null +++ b/pretty_yaml/tests/fmt/quote/multiline.force-single.snap @@ -0,0 +1,41 @@ +--- +source: pretty_yaml/tests/fmt.rs +--- +a: ' + 123123123123123123123123123 + 123123123123123123123123123 + 123123123123123123123123123 + 123123123123123123123123123 + 123123123123123123123123123 + 123123123123123123123123123 + 123123123123123123123123123 + + 123123123123123123123123123 + + + 123123123123123123123123123 + + + + + 123123123123123123123123123 +' +b: ' + 123123123123123123123123123 + 123123123123123123123123123 + 123123123123123123123123123 + 123123123123123123123123123 + 123123123123123123123123123 + 123123123123123123123123123 + 123123123123123123123123123 + + 123123123123123123123123123 + + + 123123123123123123123123123 + + + + + 123123123123123123123123123 +' diff --git a/pretty_yaml/tests/fmt/quote/quote.force-double.snap b/pretty_yaml/tests/fmt/quote/quote.force-double.snap new file mode 100644 index 0000000..7172132 --- /dev/null +++ b/pretty_yaml/tests/fmt/quote/quote.force-double.snap @@ -0,0 +1,12 @@ +--- +source: pretty_yaml/tests/fmt.rs +--- +- "123" +- "123" +- "''" +- '""' +- "'" +- "\"\"" +- '\n123' +- "\n123" +- "'a\"b" diff --git a/pretty_yaml/tests/fmt/quote/quote.force-single.snap b/pretty_yaml/tests/fmt/quote/quote.force-single.snap new file mode 100644 index 0000000..85518f0 --- /dev/null +++ b/pretty_yaml/tests/fmt/quote/quote.force-single.snap @@ -0,0 +1,12 @@ +--- +source: pretty_yaml/tests/fmt.rs +--- +- '123' +- '123' +- '''''' +- '""' +- '''' +- "\"\"" +- '\n123' +- "\n123" +- "'a\"b" diff --git a/pretty_yaml/tests/fmt/quote/quote.prefer-double.snap b/pretty_yaml/tests/fmt/quote/quote.prefer-double.snap index 7172132..ee36963 100644 --- a/pretty_yaml/tests/fmt/quote/quote.prefer-double.snap +++ b/pretty_yaml/tests/fmt/quote/quote.prefer-double.snap @@ -5,7 +5,7 @@ source: pretty_yaml/tests/fmt.rs - "123" - "''" - '""' -- "'" +- '''' - "\"\"" - '\n123' - "\n123" diff --git a/pretty_yaml/tests/fmt/quote/quote.prefer-single.snap b/pretty_yaml/tests/fmt/quote/quote.prefer-single.snap index 85518f0..45b07b4 100644 --- a/pretty_yaml/tests/fmt/quote/quote.prefer-single.snap +++ b/pretty_yaml/tests/fmt/quote/quote.prefer-single.snap @@ -3,7 +3,7 @@ source: pretty_yaml/tests/fmt.rs --- - '123' - '123' -- '''''' +- "''" - '""' - '''' - "\"\"" diff --git a/pretty_yaml/tests/fmt/spec/spec-example-2.17-quoted-scalars.snap b/pretty_yaml/tests/fmt/spec/spec-example-2.17-quoted-scalars.snap index 7f5ccd1..4ef869c 100644 --- a/pretty_yaml/tests/fmt/spec/spec-example-2.17-quoted-scalars.snap +++ b/pretty_yaml/tests/fmt/spec/spec-example-2.17-quoted-scalars.snap @@ -6,5 +6,5 @@ control: "\b1998\t1999\t2000\n" hex esc: "\x0d\x0a is \r\n" single: '"Howdy!" he cried.' -quoted: " # Not a 'comment'." +quoted: ' # Not a ''comment''.' tie-fighter: '|\-*-/|'