From 345481253940f2a90c0d9d903a3208de4edfa942 Mon Sep 17 00:00:00 2001 From: Wim Looman Date: Sun, 22 Oct 2023 03:14:27 +0200 Subject: [PATCH 1/4] Partition `wrap_comments` into `normal` or `doc` settings --- Configurations.md | 12 +-- src/comment.rs | 31 ++++--- src/config/mod.rs | 4 +- src/config/options.rs | 91 ++++++++++++++++++++ tests/source/configs/wrap_comments/all.rs | 17 ++++ tests/source/configs/wrap_comments/doc.rs | 17 ++++ tests/source/configs/wrap_comments/false.rs | 10 +++ tests/source/configs/wrap_comments/normal.rs | 18 ++++ tests/source/configs/wrap_comments/off.rs | 18 ++++ tests/source/configs/wrap_comments/true.rs | 2 + tests/target/configs/wrap_comments/all.rs | 27 ++++++ tests/target/configs/wrap_comments/doc.rs | 22 +++++ tests/target/configs/wrap_comments/false.rs | 10 +++ tests/target/configs/wrap_comments/normal.rs | 23 +++++ tests/target/configs/wrap_comments/off.rs | 18 ++++ tests/target/configs/wrap_comments/true.rs | 7 ++ 16 files changed, 304 insertions(+), 23 deletions(-) create mode 100644 tests/source/configs/wrap_comments/all.rs create mode 100644 tests/source/configs/wrap_comments/doc.rs create mode 100644 tests/source/configs/wrap_comments/normal.rs create mode 100644 tests/source/configs/wrap_comments/off.rs create mode 100644 tests/target/configs/wrap_comments/all.rs create mode 100644 tests/target/configs/wrap_comments/doc.rs create mode 100644 tests/target/configs/wrap_comments/normal.rs create mode 100644 tests/target/configs/wrap_comments/off.rs diff --git a/Configurations.md b/Configurations.md index 2d01fb3bb3b..ffc0dddc95c 100644 --- a/Configurations.md +++ b/Configurations.md @@ -3096,11 +3096,11 @@ Note that no wrapping will happen if: 1. The comment is the start of a markdown header doc comment 2. An URL was found in the comment -- **Default value**: `false` -- **Possible values**: `true`, `false` +- **Default value**: `"off"` +- **Possible values**: `"doc"`, `"normal"`, `"all"` (alias `true`), `"off"` (alias `false`) - **Stable**: No (tracking issue: [#3347](https://github.com/rust-lang/rustfmt/issues/3347)) -#### `false` (default): +#### `"off"` (default): ```rust // Lorem ipsum dolor sit amet, consectetur adipiscing elit, @@ -3112,12 +3112,10 @@ Note that no wrapping will happen if: // Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. // Information on the lorem ipsum can be found at the following url: https://en.wikipedia.org/wiki/Lorem_ipsum. Its text is: lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. - -/// # This doc comment is a very long header (it starts with a '#'). Had it not been a header it would have been wrapped. But because it is a header, it will not be. That is because wrapping a markdown header breaks it. struct Foo {} ``` -#### `true`: +#### `"all"`: ```rust // Lorem ipsum dolor sit amet, consectetur adipiscing elit, @@ -3133,8 +3131,6 @@ struct Foo {} // commodo consequat. // Information on the lorem ipsum can be found at the following url: https://en.wikipedia.org/wiki/Lorem_ipsum. Its text is: lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. - -/// # This doc comment is a very long header (it starts with a '#'). Had it not been a header it would have been wrapped. But because it is a header, it will not be. That is because wrapping a markdown header breaks it. struct Foo {} ``` diff --git a/src/comment.rs b/src/comment.rs index 55e710bd27d..71058ad0058 100644 --- a/src/comment.rs +++ b/src/comment.rs @@ -7,7 +7,7 @@ use lazy_static::lazy_static; use regex::Regex; use rustc_span::Span; -use crate::config::Config; +use crate::config::{Config, WrapComments}; use crate::rewrite::RewriteContext; use crate::shape::{Indent, Shape}; use crate::string::{rewrite_string, StringFormat}; @@ -361,12 +361,11 @@ fn identify_comment( if !config.normalize_comments() && has_bare_lines && style.is_block_comment() { trim_left_preserve_layout(first_group, shape.indent, config)? } else if !config.normalize_comments() - && !config.wrap_comments() - && !( - // `format_code_in_doc_comments` should only take effect on doc comments, - // so we only consider it when this comment block is a doc comment block. - is_doc_comment && config.format_code_in_doc_comments() - ) + && (if is_doc_comment { + !config.wrap_comments().is_doc() && !config.format_code_in_doc_comments() + } else { + !config.wrap_comments().is_normal() + }) { light_rewrite_comment(first_group, shape.indent, config, is_doc_comment) } else { @@ -770,7 +769,7 @@ impl<'a> CommentRewrite<'a> { && !self.code_block_buffer.trim().is_empty() => { let mut config = self.fmt.config.clone(); - config.set().wrap_comments(false); + config.set().wrap_comments(WrapComments::Off); let comment_max_width = config .doc_comment_code_block_width() .min(config.max_width()); @@ -802,11 +801,17 @@ impl<'a> CommentRewrite<'a> { return false; } + let config_wrap_comments = if is_doc_comment { + self.fmt.config.wrap_comments().is_doc() + } else { + self.fmt.config.wrap_comments().is_normal() + }; + self.code_block_attr = None; self.item_block = None; if let Some(stripped) = line.strip_prefix("```") { self.code_block_attr = Some(CodeBlockAttribute::new(stripped)) - } else if self.fmt.config.wrap_comments() { + } else if config_wrap_comments { if let Some(ib) = ItemizedBlock::new(line) { self.item_block = Some(ib); return false; @@ -845,7 +850,7 @@ impl<'a> CommentRewrite<'a> { // 4) No URLS were found in the comment // If this changes, the documentation in ../Configurations.md#wrap_comments // should be changed accordingly. - let should_wrap_comment = self.fmt.config.wrap_comments() + let should_wrap_comment = config_wrap_comments && !is_markdown_header_doc_comment && unicode_str_width(line) > self.fmt.shape.width && !has_url(line) @@ -1903,13 +1908,13 @@ mod test { #[test] #[rustfmt::skip] - fn format_doc_comments() { + fn format_comments() { let mut wrap_normalize_config: crate::config::Config = Default::default(); - wrap_normalize_config.set().wrap_comments(true); + wrap_normalize_config.set().wrap_comments(WrapComments::All); wrap_normalize_config.set().normalize_comments(true); let mut wrap_config: crate::config::Config = Default::default(); - wrap_config.set().wrap_comments(true); + wrap_config.set().wrap_comments(WrapComments::All); let comment = rewrite_comment(" //test", true, diff --git a/src/config/mod.rs b/src/config/mod.rs index 9484b2e5829..616d9348013 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -63,7 +63,7 @@ create_config! { over multiple lines."; // Comments. macros, and strings - wrap_comments: bool, false, false, "Break comments to fit on the line"; + wrap_comments: WrapComments, WrapComments::Off, false, "Break comments to fit on the line"; format_code_in_doc_comments: bool, false, false, "Format the code snippet in doc comments."; doc_comment_code_block_width: usize, 100, false, "Maximum width for code snippets in doc \ comments. No effect unless format_code_in_doc_comments = true"; @@ -634,7 +634,7 @@ array_width = 60 chain_width = 60 single_line_if_else_max_width = 50 single_line_let_else_max_width = 50 -wrap_comments = false +wrap_comments = "Off" format_code_in_doc_comments = false doc_comment_code_block_width = 100 comment_width = 80 diff --git a/src/config/options.rs b/src/config/options.rs index 3c5c713a33a..a4ec228b8c9 100644 --- a/src/config/options.rs +++ b/src/config/options.rs @@ -216,6 +216,97 @@ pub enum Verbosity { Quiet, } +/// Which comments to wrap +#[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize)] +pub enum WrapComments { + /// Don't wrap comments + Off, + /// Wrap all kinds of comments + All, + /// Only wrap doc comments + Doc, + /// Only wrap normal comments + Normal, +} + +impl WrapComments { + pub(crate) fn is_normal(self) -> bool { + matches!(self, WrapComments::All | WrapComments::Normal) + } + + pub(crate) fn is_doc(self) -> bool { + matches!(self, WrapComments::All | WrapComments::Doc) + } +} + +impl fmt::Display for WrapComments { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + WrapComments::Off => f.write_str("Off"), + WrapComments::All => f.write_str("All"), + WrapComments::Doc => f.write_str("Doc"), + WrapComments::Normal => f.write_str("Normal"), + } + } +} + +impl super::ConfigType for WrapComments { + fn doc_hint() -> String { + "[Off|All|Doc|Normal]".to_owned() + } + + fn stable_variant(&self) -> bool { + true + } +} + +impl std::str::FromStr for WrapComments { + type Err = &'static str; + + fn from_str(s: &str) -> Result { + match s.to_lowercase().as_str() { + "off" | "false" => Ok(WrapComments::Off), + "all" | "true" => Ok(WrapComments::All), + "doc" => Ok(WrapComments::Doc), + "normal" => Ok(WrapComments::Normal), + _ => Err("Bad variant, expected one of: `Off` `All` `Doc` `Normal`"), + } + } +} + +impl<'de> serde::de::Deserialize<'de> for WrapComments { + fn deserialize(d: D) -> Result + where + D: serde::Deserializer<'de>, + { + use serde::de::Error; + + struct StringOrBoolVisitor; + + impl<'de> Visitor<'de> for StringOrBoolVisitor { + type Value = String; + + fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { + formatter.write_str("string") + } + + fn visit_str(self, value: &str) -> Result { + Ok(String::from(value)) + } + + fn visit_bool(self, value: bool) -> Result { + Ok(value.to_string()) + } + } + + let s = d.deserialize_string(StringOrBoolVisitor)?; + s.parse().map_err(|_| { + static ALLOWED: &'static [&str] = &["Off", "All", "Doc", "Normal"]; + D::Error::unknown_variant(&s, ALLOWED) + }) + } +} + #[derive(Deserialize, Serialize, Clone, Debug, PartialEq)] pub struct WidthHeuristics { // Maximum width of the args of a function call before falling back diff --git a/tests/source/configs/wrap_comments/all.rs b/tests/source/configs/wrap_comments/all.rs new file mode 100644 index 00000000000..621636b86b8 --- /dev/null +++ b/tests/source/configs/wrap_comments/all.rs @@ -0,0 +1,17 @@ +// rustfmt-wrap_comments: all +// rustfmt-max_width: 50 +// Wrap comments + +fn main() { + //! Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. + + // Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. +} + +fn code_block() { + // ```rust + // let x = 3; + // + // println!("x = {}", x); + // ``` +} diff --git a/tests/source/configs/wrap_comments/doc.rs b/tests/source/configs/wrap_comments/doc.rs new file mode 100644 index 00000000000..abbfd5cb76c --- /dev/null +++ b/tests/source/configs/wrap_comments/doc.rs @@ -0,0 +1,17 @@ +// rustfmt-wrap_comments: doc +// rustfmt-max_width: 50 +/// Wrap comments + +fn main() { + //! Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. + + // Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. +} + +fn code_block() { + // ```rust + // let x = 3; + // + // println!("x = {}", x); + // ``` +} diff --git a/tests/source/configs/wrap_comments/false.rs b/tests/source/configs/wrap_comments/false.rs index 48ecd88accb..0e89ff13c05 100644 --- a/tests/source/configs/wrap_comments/false.rs +++ b/tests/source/configs/wrap_comments/false.rs @@ -4,5 +4,15 @@ // Wrap comments fn main() { + //! Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. + // Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. } + +fn code_block() { + //! ```rust + //! let x = 3; + //! + //! println!("x = {}", x); + //! ``` +} diff --git a/tests/source/configs/wrap_comments/normal.rs b/tests/source/configs/wrap_comments/normal.rs new file mode 100644 index 00000000000..fd3735bc250 --- /dev/null +++ b/tests/source/configs/wrap_comments/normal.rs @@ -0,0 +1,18 @@ +// rustfmt-wrap_comments: normal +// rustfmt-max_width: 50 +// rustfmt-error_on_line_overflow: false +// Wrap comments + +fn main() { + //! Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. + + // Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. +} + +fn code_block() { + //! ```rust + //! let x = 3; + //! + //! println!("x = {}", x); + //! ``` +} diff --git a/tests/source/configs/wrap_comments/off.rs b/tests/source/configs/wrap_comments/off.rs new file mode 100644 index 00000000000..c9fb79cc613 --- /dev/null +++ b/tests/source/configs/wrap_comments/off.rs @@ -0,0 +1,18 @@ +// rustfmt-wrap_comments: off +// rustfmt-max_width: 50 +// rustfmt-error_on_line_overflow: false +// Wrap comments + +fn main() { + //! Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. + + // Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. +} + +fn code_block() { + //! ```rust + //! let x = 3; + //! + //! println!("x = {}", x); + //! ``` +} diff --git a/tests/source/configs/wrap_comments/true.rs b/tests/source/configs/wrap_comments/true.rs index 39a79a4cacc..12a67af9219 100644 --- a/tests/source/configs/wrap_comments/true.rs +++ b/tests/source/configs/wrap_comments/true.rs @@ -3,6 +3,8 @@ // Wrap comments fn main() { + //! Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. + // Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. } diff --git a/tests/target/configs/wrap_comments/all.rs b/tests/target/configs/wrap_comments/all.rs new file mode 100644 index 00000000000..b6f41fe032a --- /dev/null +++ b/tests/target/configs/wrap_comments/all.rs @@ -0,0 +1,27 @@ +// rustfmt-wrap_comments: all +// rustfmt-max_width: 50 +// Wrap comments + +fn main() { + //! Lorem ipsum dolor sit amet, consectetur + //! adipiscing elit, sed do eiusmod tempor + //! incididunt ut labore et dolore magna + //! aliqua. Ut enim ad minim veniam, quis + //! nostrud exercitation ullamco laboris nisi + //! ut aliquip ex ea commodo consequat. + + // Lorem ipsum dolor sit amet, consectetur + // adipiscing elit, sed do eiusmod tempor + // incididunt ut labore et dolore magna + // aliqua. Ut enim ad minim veniam, quis + // nostrud exercitation ullamco laboris nisi + // ut aliquip ex ea commodo consequat. +} + +fn code_block() { + // ```rust + // let x = 3; + // + // println!("x = {}", x); + // ``` +} diff --git a/tests/target/configs/wrap_comments/doc.rs b/tests/target/configs/wrap_comments/doc.rs new file mode 100644 index 00000000000..bb4431cbab3 --- /dev/null +++ b/tests/target/configs/wrap_comments/doc.rs @@ -0,0 +1,22 @@ +// rustfmt-wrap_comments: doc +// rustfmt-max_width: 50 +/// Wrap comments + +fn main() { + //! Lorem ipsum dolor sit amet, consectetur + //! adipiscing elit, sed do eiusmod tempor + //! incididunt ut labore et dolore magna + //! aliqua. Ut enim ad minim veniam, quis + //! nostrud exercitation ullamco laboris nisi + //! ut aliquip ex ea commodo consequat. + + // Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. +} + +fn code_block() { + // ```rust + // let x = 3; + // + // println!("x = {}", x); + // ``` +} diff --git a/tests/target/configs/wrap_comments/false.rs b/tests/target/configs/wrap_comments/false.rs index 48ecd88accb..0e89ff13c05 100644 --- a/tests/target/configs/wrap_comments/false.rs +++ b/tests/target/configs/wrap_comments/false.rs @@ -4,5 +4,15 @@ // Wrap comments fn main() { + //! Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. + // Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. } + +fn code_block() { + //! ```rust + //! let x = 3; + //! + //! println!("x = {}", x); + //! ``` +} diff --git a/tests/target/configs/wrap_comments/normal.rs b/tests/target/configs/wrap_comments/normal.rs new file mode 100644 index 00000000000..7053174a12e --- /dev/null +++ b/tests/target/configs/wrap_comments/normal.rs @@ -0,0 +1,23 @@ +// rustfmt-wrap_comments: normal +// rustfmt-max_width: 50 +// rustfmt-error_on_line_overflow: false +// Wrap comments + +fn main() { + //! Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. + + // Lorem ipsum dolor sit amet, consectetur + // adipiscing elit, sed do eiusmod tempor + // incididunt ut labore et dolore magna + // aliqua. Ut enim ad minim veniam, quis + // nostrud exercitation ullamco laboris nisi + // ut aliquip ex ea commodo consequat. +} + +fn code_block() { + //! ```rust + //! let x = 3; + //! + //! println!("x = {}", x); + //! ``` +} diff --git a/tests/target/configs/wrap_comments/off.rs b/tests/target/configs/wrap_comments/off.rs new file mode 100644 index 00000000000..c9fb79cc613 --- /dev/null +++ b/tests/target/configs/wrap_comments/off.rs @@ -0,0 +1,18 @@ +// rustfmt-wrap_comments: off +// rustfmt-max_width: 50 +// rustfmt-error_on_line_overflow: false +// Wrap comments + +fn main() { + //! Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. + + // Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. +} + +fn code_block() { + //! ```rust + //! let x = 3; + //! + //! println!("x = {}", x); + //! ``` +} diff --git a/tests/target/configs/wrap_comments/true.rs b/tests/target/configs/wrap_comments/true.rs index 4096fd4d89d..6dd85dd45f2 100644 --- a/tests/target/configs/wrap_comments/true.rs +++ b/tests/target/configs/wrap_comments/true.rs @@ -3,6 +3,13 @@ // Wrap comments fn main() { + //! Lorem ipsum dolor sit amet, consectetur + //! adipiscing elit, sed do eiusmod tempor + //! incididunt ut labore et dolore magna + //! aliqua. Ut enim ad minim veniam, quis + //! nostrud exercitation ullamco laboris nisi + //! ut aliquip ex ea commodo consequat. + // Lorem ipsum dolor sit amet, consectetur // adipiscing elit, sed do eiusmod tempor // incididunt ut labore et dolore magna From 21719e234f34ba68aa39c867405cc45d680ee57e Mon Sep 17 00:00:00 2001 From: Wim Looman Date: Fri, 9 Feb 2024 12:21:35 +0100 Subject: [PATCH 2/4] Move `WrapComments` into own module, include aliases in all errors --- src/config/config_type.rs | 7 +++ src/config/mod.rs | 2 + src/config/options.rs | 91 ------------------------------------- src/config/wrap_comments.rs | 84 ++++++++++++++++++++++++++++++++++ 4 files changed, 93 insertions(+), 91 deletions(-) create mode 100644 src/config/wrap_comments.rs diff --git a/src/config/config_type.rs b/src/config/config_type.rs index f7cff1a1729..fe57d6ae6de 100644 --- a/src/config/config_type.rs +++ b/src/config/config_type.rs @@ -1,6 +1,7 @@ use crate::config::file_lines::FileLines; use crate::config::macro_names::MacroSelectors; use crate::config::options::{IgnoreList, WidthHeuristics}; +use crate::config::WrapComments; /// Trait for types that can be used in `Config`. pub(crate) trait ConfigType: Sized { @@ -65,6 +66,12 @@ impl ConfigType for IgnoreList { } } +impl ConfigType for WrapComments { + fn doc_hint() -> String { + "[ Off (false) | All (true) | Doc | Normal ]".to_owned() + } +} + macro_rules! create_config { // Options passed into the macro. // diff --git a/src/config/mod.rs b/src/config/mod.rs index 616d9348013..f6a0c418712 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -15,6 +15,7 @@ pub use crate::config::lists::*; pub use crate::config::macro_names::{MacroSelector, MacroSelectors}; #[allow(unreachable_pub)] pub use crate::config::options::*; +pub(crate) use crate::config::wrap_comments::WrapComments; #[macro_use] pub(crate) mod config_type; @@ -27,6 +28,7 @@ pub(crate) mod file_lines; pub(crate) mod lists; pub(crate) mod macro_names; pub(crate) mod style_edition; +mod wrap_comments; // This macro defines configuration options used in rustfmt. Each option // is defined as follows: diff --git a/src/config/options.rs b/src/config/options.rs index a4ec228b8c9..3c5c713a33a 100644 --- a/src/config/options.rs +++ b/src/config/options.rs @@ -216,97 +216,6 @@ pub enum Verbosity { Quiet, } -/// Which comments to wrap -#[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize)] -pub enum WrapComments { - /// Don't wrap comments - Off, - /// Wrap all kinds of comments - All, - /// Only wrap doc comments - Doc, - /// Only wrap normal comments - Normal, -} - -impl WrapComments { - pub(crate) fn is_normal(self) -> bool { - matches!(self, WrapComments::All | WrapComments::Normal) - } - - pub(crate) fn is_doc(self) -> bool { - matches!(self, WrapComments::All | WrapComments::Doc) - } -} - -impl fmt::Display for WrapComments { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - WrapComments::Off => f.write_str("Off"), - WrapComments::All => f.write_str("All"), - WrapComments::Doc => f.write_str("Doc"), - WrapComments::Normal => f.write_str("Normal"), - } - } -} - -impl super::ConfigType for WrapComments { - fn doc_hint() -> String { - "[Off|All|Doc|Normal]".to_owned() - } - - fn stable_variant(&self) -> bool { - true - } -} - -impl std::str::FromStr for WrapComments { - type Err = &'static str; - - fn from_str(s: &str) -> Result { - match s.to_lowercase().as_str() { - "off" | "false" => Ok(WrapComments::Off), - "all" | "true" => Ok(WrapComments::All), - "doc" => Ok(WrapComments::Doc), - "normal" => Ok(WrapComments::Normal), - _ => Err("Bad variant, expected one of: `Off` `All` `Doc` `Normal`"), - } - } -} - -impl<'de> serde::de::Deserialize<'de> for WrapComments { - fn deserialize(d: D) -> Result - where - D: serde::Deserializer<'de>, - { - use serde::de::Error; - - struct StringOrBoolVisitor; - - impl<'de> Visitor<'de> for StringOrBoolVisitor { - type Value = String; - - fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { - formatter.write_str("string") - } - - fn visit_str(self, value: &str) -> Result { - Ok(String::from(value)) - } - - fn visit_bool(self, value: bool) -> Result { - Ok(value.to_string()) - } - } - - let s = d.deserialize_string(StringOrBoolVisitor)?; - s.parse().map_err(|_| { - static ALLOWED: &'static [&str] = &["Off", "All", "Doc", "Normal"]; - D::Error::unknown_variant(&s, ALLOWED) - }) - } -} - #[derive(Deserialize, Serialize, Clone, Debug, PartialEq)] pub struct WidthHeuristics { // Maximum width of the args of a function call before falling back diff --git a/src/config/wrap_comments.rs b/src/config/wrap_comments.rs new file mode 100644 index 00000000000..7f70f2cd9ce --- /dev/null +++ b/src/config/wrap_comments.rs @@ -0,0 +1,84 @@ +use std::fmt; + +/// Which comments to wrap +#[derive(Copy, Clone, Debug, Eq, PartialEq, serde::Serialize)] +pub enum WrapComments { + /// Don't wrap comments + Off, + /// Wrap all kinds of comments + All, + /// Only wrap doc comments + Doc, + /// Only wrap normal comments + Normal, +} + +impl WrapComments { + pub(crate) fn is_normal(self) -> bool { + matches!(self, WrapComments::All | WrapComments::Normal) + } + + pub(crate) fn is_doc(self) -> bool { + matches!(self, WrapComments::All | WrapComments::Doc) + } +} + +impl fmt::Display for WrapComments { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + WrapComments::Off => f.write_str("Off"), + WrapComments::All => f.write_str("All"), + WrapComments::Doc => f.write_str("Doc"), + WrapComments::Normal => f.write_str("Normal"), + } + } +} + +impl std::str::FromStr for WrapComments { + type Err = &'static str; + + fn from_str(s: &str) -> Result { + match s.to_lowercase().as_str() { + "off" | "false" => Ok(WrapComments::Off), + "all" | "true" => Ok(WrapComments::All), + "doc" => Ok(WrapComments::Doc), + "normal" => Ok(WrapComments::Normal), + _ => { + Err("Bad variant, expected one of: `Off`, `false`, `All`, `true`, `Doc`, `Normal`") + } + } + } +} + +impl<'de> serde::de::Deserialize<'de> for WrapComments { + fn deserialize(d: D) -> Result + where + D: serde::Deserializer<'de>, + { + use serde::de::Error; + + struct StringOrBoolVisitor; + + impl<'de> serde::de::Visitor<'de> for StringOrBoolVisitor { + type Value = String; + + fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { + formatter.write_str("string") + } + + fn visit_str(self, value: &str) -> Result { + Ok(String::from(value)) + } + + fn visit_bool(self, value: bool) -> Result { + Ok(value.to_string()) + } + } + + let s = d.deserialize_string(StringOrBoolVisitor)?; + s.parse().map_err(|_| { + static ALLOWED: &'static [&str] = &["Off", "false", "All", "true", "Doc", "Normal"]; + D::Error::unknown_variant(&s, ALLOWED) + }) + } +} From d64fb779017f1c0bb1984fa831b71ee358ce9d94 Mon Sep 17 00:00:00 2001 From: Wim Looman Date: Fri, 9 Feb 2024 12:22:43 +0100 Subject: [PATCH 3/4] Include examples of all `wrap_comments` settings and header handling --- Configurations.md | 78 +++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 69 insertions(+), 9 deletions(-) diff --git a/Configurations.md b/Configurations.md index ffc0dddc95c..2c7f1dc44dc 100644 --- a/Configurations.md +++ b/Configurations.md @@ -3096,34 +3096,88 @@ Note that no wrapping will happen if: 1. The comment is the start of a markdown header doc comment 2. An URL was found in the comment -- **Default value**: `"off"` -- **Possible values**: `"doc"`, `"normal"`, `"all"` (alias `true`), `"off"` (alias `false`) +- **Default value**: `"Off"` +- **Possible values**: `"Off"` (alias `false`), `"All"` (alias `true`), `"Doc"`, `"Normal"` - **Stable**: No (tracking issue: [#3347](https://github.com/rust-lang/rustfmt/issues/3347)) -#### `"off"` (default): +#### `"Off"` (default): + +Can also be specified as `wrap_comments = false`. ```rust -// Lorem ipsum dolor sit amet, consectetur adipiscing elit, -// sed do eiusmod tempor incididunt ut labore et dolore -// magna aliqua. Ut enim ad minim veniam, quis nostrud -// exercitation ullamco laboris nisi ut aliquip ex ea -// commodo consequat. +// # This comment looks like a very long header (it starts with a '#'). Had it been a doc comment it would not have been wrapped, because wrapping a markdown header breaks it. But because it is a normal comment, it will be. // Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. // Information on the lorem ipsum can be found at the following url: https://en.wikipedia.org/wiki/Lorem_ipsum. Its text is: lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. + +/// # This doc comment is a very long header (it starts with a '#'). Had it not been a header it would have been wrapped. But because it is a header, it will not be. That is because wrapping a markdown header breaks it. +/// +/// Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. +/// +/// Information on the lorem ipsum can be found at the following url: https://en.wikipedia.org/wiki/Lorem_ipsum. Its text is: lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. struct Foo {} ``` -#### `"all"`: +#### `"All"`: + +Can also be specified as `wrap_comments = true`. ```rust +// # This comment looks like a very long header (it starts +// with a '#'). Had it been a doc comment it would not have +// been wrapped, because wrapping a markdown header breaks +// it. But because it is a normal comment, it will be. + // Lorem ipsum dolor sit amet, consectetur adipiscing elit, // sed do eiusmod tempor incididunt ut labore et dolore // magna aliqua. Ut enim ad minim veniam, quis nostrud // exercitation ullamco laboris nisi ut aliquip ex ea // commodo consequat. +// Information on the lorem ipsum can be found at the following url: https://en.wikipedia.org/wiki/Lorem_ipsum. Its text is: lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. + +/// # This doc comment is a very long header (it starts with a '#'). Had it not been a header it would have been wrapped. But because it is a header, it will not be. That is because wrapping a markdown header breaks it. +/// +/// Lorem ipsum dolor sit amet, consectetur adipiscing elit, +/// sed do eiusmod tempor incididunt ut labore et dolore +/// magna aliqua. Ut enim ad minim veniam, quis nostrud +/// exercitation ullamco laboris nisi ut aliquip ex ea +/// commodo consequat. +/// +/// Information on the lorem ipsum can be found at the following url: https://en.wikipedia.org/wiki/Lorem_ipsum. Its text is: lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. +struct Foo {} +``` + +#### `"Doc"`: + +```rust +// # This comment looks like a very long header (it starts with a '#'). Had it been a doc comment it would not have been wrapped, because wrapping a markdown header breaks it. But because it is a normal comment, it will be. + +// Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. + +// Information on the lorem ipsum can be found at the following url: https://en.wikipedia.org/wiki/Lorem_ipsum. Its text is: lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. + +/// # This doc comment is a very long header (it starts with a '#'). Had it not been a header it would have been wrapped. But because it is a header, it will not be. That is because wrapping a markdown header breaks it. +/// +/// Lorem ipsum dolor sit amet, consectetur adipiscing elit, +/// sed do eiusmod tempor incididunt ut labore et dolore +/// magna aliqua. Ut enim ad minim veniam, quis nostrud +/// exercitation ullamco laboris nisi ut aliquip ex ea +/// commodo consequat. +/// +/// Information on the lorem ipsum can be found at the following url: https://en.wikipedia.org/wiki/Lorem_ipsum. Its text is: lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. +struct Foo {} +``` + +#### `"Normal"`: + +```rust +// # This comment looks like a very long header (it starts +// with a '#'). Had it been a doc comment it would not have +// been wrapped, because wrapping a markdown header breaks +// it. But because it is a normal comment, it will be. + // Lorem ipsum dolor sit amet, consectetur adipiscing elit, // sed do eiusmod tempor incididunt ut labore et dolore // magna aliqua. Ut enim ad minim veniam, quis nostrud @@ -3131,6 +3185,12 @@ struct Foo {} // commodo consequat. // Information on the lorem ipsum can be found at the following url: https://en.wikipedia.org/wiki/Lorem_ipsum. Its text is: lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. + +/// # This doc comment is a very long header (it starts with a '#'). Had it not been a header it would have been wrapped. But because it is a header, it will not be. That is because wrapping a markdown header breaks it. +/// +/// Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. +/// +/// Information on the lorem ipsum can be found at the following url: https://en.wikipedia.org/wiki/Lorem_ipsum. Its text is: lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. struct Foo {} ``` From 0111775cd5ba627d130380702e8a7677648e2c4e Mon Sep 17 00:00:00 2001 From: Wim Looman Date: Fri, 9 Feb 2024 12:24:33 +0100 Subject: [PATCH 4/4] Capitalize wrap-comments settings in tests --- tests/source/configs/wrap_comments/all.rs | 2 +- tests/source/configs/wrap_comments/doc.rs | 2 +- tests/source/configs/wrap_comments/normal.rs | 2 +- tests/source/configs/wrap_comments/off.rs | 2 +- tests/target/configs/wrap_comments/all.rs | 2 +- tests/target/configs/wrap_comments/doc.rs | 2 +- tests/target/configs/wrap_comments/normal.rs | 2 +- tests/target/configs/wrap_comments/off.rs | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/source/configs/wrap_comments/all.rs b/tests/source/configs/wrap_comments/all.rs index 621636b86b8..3f0b62c4a57 100644 --- a/tests/source/configs/wrap_comments/all.rs +++ b/tests/source/configs/wrap_comments/all.rs @@ -1,4 +1,4 @@ -// rustfmt-wrap_comments: all +// rustfmt-wrap_comments: All // rustfmt-max_width: 50 // Wrap comments diff --git a/tests/source/configs/wrap_comments/doc.rs b/tests/source/configs/wrap_comments/doc.rs index abbfd5cb76c..04728963e2b 100644 --- a/tests/source/configs/wrap_comments/doc.rs +++ b/tests/source/configs/wrap_comments/doc.rs @@ -1,4 +1,4 @@ -// rustfmt-wrap_comments: doc +// rustfmt-wrap_comments: Doc // rustfmt-max_width: 50 /// Wrap comments diff --git a/tests/source/configs/wrap_comments/normal.rs b/tests/source/configs/wrap_comments/normal.rs index fd3735bc250..6ea3b58552b 100644 --- a/tests/source/configs/wrap_comments/normal.rs +++ b/tests/source/configs/wrap_comments/normal.rs @@ -1,4 +1,4 @@ -// rustfmt-wrap_comments: normal +// rustfmt-wrap_comments: Normal // rustfmt-max_width: 50 // rustfmt-error_on_line_overflow: false // Wrap comments diff --git a/tests/source/configs/wrap_comments/off.rs b/tests/source/configs/wrap_comments/off.rs index c9fb79cc613..cb07fa81afe 100644 --- a/tests/source/configs/wrap_comments/off.rs +++ b/tests/source/configs/wrap_comments/off.rs @@ -1,4 +1,4 @@ -// rustfmt-wrap_comments: off +// rustfmt-wrap_comments: Off // rustfmt-max_width: 50 // rustfmt-error_on_line_overflow: false // Wrap comments diff --git a/tests/target/configs/wrap_comments/all.rs b/tests/target/configs/wrap_comments/all.rs index b6f41fe032a..d612f978fa5 100644 --- a/tests/target/configs/wrap_comments/all.rs +++ b/tests/target/configs/wrap_comments/all.rs @@ -1,4 +1,4 @@ -// rustfmt-wrap_comments: all +// rustfmt-wrap_comments: All // rustfmt-max_width: 50 // Wrap comments diff --git a/tests/target/configs/wrap_comments/doc.rs b/tests/target/configs/wrap_comments/doc.rs index bb4431cbab3..c6ad9fe4a48 100644 --- a/tests/target/configs/wrap_comments/doc.rs +++ b/tests/target/configs/wrap_comments/doc.rs @@ -1,4 +1,4 @@ -// rustfmt-wrap_comments: doc +// rustfmt-wrap_comments: Doc // rustfmt-max_width: 50 /// Wrap comments diff --git a/tests/target/configs/wrap_comments/normal.rs b/tests/target/configs/wrap_comments/normal.rs index 7053174a12e..e08ac3acfab 100644 --- a/tests/target/configs/wrap_comments/normal.rs +++ b/tests/target/configs/wrap_comments/normal.rs @@ -1,4 +1,4 @@ -// rustfmt-wrap_comments: normal +// rustfmt-wrap_comments: Normal // rustfmt-max_width: 50 // rustfmt-error_on_line_overflow: false // Wrap comments diff --git a/tests/target/configs/wrap_comments/off.rs b/tests/target/configs/wrap_comments/off.rs index c9fb79cc613..cb07fa81afe 100644 --- a/tests/target/configs/wrap_comments/off.rs +++ b/tests/target/configs/wrap_comments/off.rs @@ -1,4 +1,4 @@ -// rustfmt-wrap_comments: off +// rustfmt-wrap_comments: Off // rustfmt-max_width: 50 // rustfmt-error_on_line_overflow: false // Wrap comments