diff --git a/crates/ruff_formatter/src/format_element/document.rs b/crates/ruff_formatter/src/format_element/document.rs index 42bc2b1f39..69fef71adf 100644 --- a/crates/ruff_formatter/src/format_element/document.rs +++ b/crates/ruff_formatter/src/format_element/document.rs @@ -4,7 +4,7 @@ use crate::prelude::tag::GroupMode; use crate::prelude::*; use crate::printer::LineEnding; use crate::source_code::SourceCode; -use crate::{format, write}; +use crate::{format, write, TabWidth}; use crate::{ BufferExtensions, Format, FormatContext, FormatElement, FormatOptions, FormatResult, Formatter, IndentStyle, LineWidth, PrinterOptions, @@ -215,13 +215,17 @@ impl FormatOptions for IrFormatOptions { IndentStyle::Space(2) } + fn tab_width(&self) -> TabWidth { + TabWidth::default() + } + fn line_width(&self) -> LineWidth { LineWidth(80) } fn as_print_options(&self) -> PrinterOptions { PrinterOptions { - tab_width: 2, + tab_width: TabWidth::default(), print_width: self.line_width().into(), line_ending: LineEnding::LineFeed, indent_style: IndentStyle::Space(2), diff --git a/crates/ruff_formatter/src/lib.rs b/crates/ruff_formatter/src/lib.rs index 086d917212..3a6dc8cd6d 100644 --- a/crates/ruff_formatter/src/lib.rs +++ b/crates/ruff_formatter/src/lib.rs @@ -51,7 +51,7 @@ pub use crate::diagnostics::{ActualStart, FormatError, InvalidDocumentError, Pri pub use format_element::{normalize_newlines, FormatElement, LINE_TERMINATORS}; pub use group_id::GroupId; use ruff_text_size::{TextRange, TextSize}; -use std::num::ParseIntError; +use std::num::{NonZeroU8, ParseIntError, TryFromIntError}; use std::str::FromStr; #[derive(Debug, Eq, PartialEq, Clone, Copy, Hash)] @@ -108,6 +108,33 @@ impl std::fmt::Display for IndentStyle { } } +/// The visual width of a `\t` character. +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] +pub struct TabWidth(NonZeroU8); + +impl TabWidth { + /// Return the numeric value for this [`LineWidth`] + pub const fn value(&self) -> u32 { + self.0.get() as u32 + } +} + +impl Default for TabWidth { + fn default() -> Self { + Self(NonZeroU8::new(2).unwrap()) + } +} + +impl TryFrom for TabWidth { + type Error = TryFromIntError; + + fn try_from(value: u8) -> Result { + NonZeroU8::try_from(value).map(Self) + } +} + /// Validated value for the `line_width` formatter options /// /// The allowed range of values is 1..=320 @@ -213,6 +240,17 @@ pub trait FormatOptions { /// The indent style. fn indent_style(&self) -> IndentStyle; + /// The visual width of a tab character. + fn tab_width(&self) -> TabWidth; + + /// The visual width of an indent + fn indent_width(&self) -> u32 { + match self.indent_style() { + IndentStyle::Tab => self.tab_width().value(), + IndentStyle::Space(spaces) => u32::from(spaces), + } + } + /// What's the max width of a line. Defaults to 80. fn line_width(&self) -> LineWidth; @@ -264,6 +302,10 @@ impl FormatOptions for SimpleFormatOptions { self.indent_style } + fn tab_width(&self) -> TabWidth { + TabWidth::default() + } + fn line_width(&self) -> LineWidth { self.line_width } @@ -271,6 +313,7 @@ impl FormatOptions for SimpleFormatOptions { fn as_print_options(&self) -> PrinterOptions { PrinterOptions::default() .with_indent(self.indent_style) + .with_tab_width(self.tab_width()) .with_print_width(self.line_width.into()) } } diff --git a/crates/ruff_formatter/src/printer/mod.rs b/crates/ruff_formatter/src/printer/mod.rs index 57e6d1a010..d3f535f7e4 100644 --- a/crates/ruff_formatter/src/printer/mod.rs +++ b/crates/ruff_formatter/src/printer/mod.rs @@ -732,7 +732,7 @@ impl<'a> Printer<'a> { #[allow(clippy::cast_possible_truncation)] let char_width = if char == '\t' { - u32::from(self.options.tab_width) + self.options.tab_width.value() } else { // SAFETY: A u32 is sufficient to represent the width of a file <= 4GB char.width().unwrap_or(0) as u32 @@ -1283,13 +1283,12 @@ impl<'a, 'print> FitsMeasurer<'a, 'print> { fn fits_text(&mut self, text: &str, args: PrintElementArgs) -> Fits { let indent = std::mem::take(&mut self.state.pending_indent); - self.state.line_width += u32::from(indent.level()) - * u32::from(self.options().indent_width()) - + u32::from(indent.align()); + self.state.line_width += + u32::from(indent.level()) * self.options().indent_width() + u32::from(indent.align()); for c in text.chars() { let char_width = match c { - '\t' => u32::from(self.options().tab_width), + '\t' => self.options().tab_width.value(), '\n' => { if self.must_be_flat { return Fits::No; @@ -1428,7 +1427,9 @@ mod tests { use crate::prelude::*; use crate::printer::{LineEnding, PrintWidth, Printer, PrinterOptions}; use crate::source_code::SourceCode; - use crate::{format_args, write, Document, FormatState, IndentStyle, Printed, VecBuffer}; + use crate::{ + format_args, write, Document, FormatState, IndentStyle, Printed, TabWidth, VecBuffer, + }; fn format(root: &dyn Format) -> Printed { format_with_options( @@ -1578,7 +1579,7 @@ two lines`, fn it_use_the_indent_character_specified_in_the_options() { let options = PrinterOptions { indent_style: IndentStyle::Tab, - tab_width: 4, + tab_width: TabWidth::try_from(4).unwrap(), print_width: PrintWidth::new(19), ..PrinterOptions::default() }; diff --git a/crates/ruff_formatter/src/printer/printer_options/mod.rs b/crates/ruff_formatter/src/printer/printer_options/mod.rs index d68f60ef2e..756d8c8a9a 100644 --- a/crates/ruff_formatter/src/printer/printer_options/mod.rs +++ b/crates/ruff_formatter/src/printer/printer_options/mod.rs @@ -1,10 +1,10 @@ -use crate::{FormatOptions, IndentStyle, LineWidth}; +use crate::{FormatOptions, IndentStyle, LineWidth, TabWidth}; /// Options that affect how the [`crate::Printer`] prints the format tokens -#[derive(Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq, Default)] pub struct PrinterOptions { /// Width of a single tab character (does it equal 2, 4, ... spaces?) - pub tab_width: u8, + pub tab_width: TabWidth, /// What's the max width of a line. Defaults to 80 pub print_width: PrintWidth, @@ -74,23 +74,31 @@ impl PrinterOptions { self } + #[must_use] + pub fn with_tab_width(mut self, width: TabWidth) -> Self { + self.tab_width = width; + + self + } + pub(crate) fn indent_style(&self) -> IndentStyle { self.indent_style } /// Width of an indent in characters. - pub(super) const fn indent_width(&self) -> u8 { + pub(super) const fn indent_width(&self) -> u32 { match self.indent_style { - IndentStyle::Tab => self.tab_width, - IndentStyle::Space(count) => count, + IndentStyle::Tab => self.tab_width.value(), + IndentStyle::Space(count) => count as u32, } } } #[allow(dead_code)] -#[derive(Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq, Default)] pub enum LineEnding { /// Line Feed only (\n), common on Linux and macOS as well as inside git repos + #[default] LineFeed, /// Carriage Return + Line Feed characters (\r\n), common on Windows @@ -110,14 +118,3 @@ impl LineEnding { } } } - -impl Default for PrinterOptions { - fn default() -> Self { - PrinterOptions { - tab_width: 2, - print_width: PrintWidth::default(), - indent_style: IndentStyle::default(), - line_ending: LineEnding::LineFeed, - } - } -} diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/docstring.options.json b/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/docstring.options.json new file mode 100644 index 0000000000..1c76291bcc --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/docstring.options.json @@ -0,0 +1,3 @@ +{ + "tab_width": 8 +} diff --git a/crates/ruff_python_formatter/resources/test/fixtures/ruff/docstring.options.json b/crates/ruff_python_formatter/resources/test/fixtures/ruff/docstring.options.json index 4a3e3c6dd7..932f00f7e8 100644 --- a/crates/ruff_python_formatter/resources/test/fixtures/ruff/docstring.options.json +++ b/crates/ruff_python_formatter/resources/test/fixtures/ruff/docstring.options.json @@ -2,14 +2,21 @@ { "indent_style": { "Space": 4 - } + }, + "tab_width": 8 }, { "indent_style": { "Space": 2 - } + }, + "tab_width": 8 }, { - "indent_style": "Tab" + "indent_style": "Tab", + "tab_width": 8 + }, + { + "indent_style": "Tab", + "tab_width": 4 } ] diff --git a/crates/ruff_python_formatter/resources/test/fixtures/ruff/tab_width.options.json b/crates/ruff_python_formatter/resources/test/fixtures/ruff/tab_width.options.json new file mode 100644 index 0000000000..772a750723 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/ruff/tab_width.options.json @@ -0,0 +1,8 @@ +[ + { + "tab_width": 2 + }, + { + "tab_width": 4 + } +] diff --git a/crates/ruff_python_formatter/resources/test/fixtures/ruff/tab_width.py b/crates/ruff_python_formatter/resources/test/fixtures/ruff/tab_width.py new file mode 100644 index 0000000000..33276e786d --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/ruff/tab_width.py @@ -0,0 +1,8 @@ +# Fits with tab width 2 +1 + " 012345678901234567890123456789012345678901234567890123456789012345678901234567890" + +# Fits with tab width 4 +1 + " 0123456789012345678901234567890123456789012345678901234567890123456789012345678" + +# Fits with tab width 8 +1 + " 012345678901234567890123456789012345678901234567890123456789012345678901234" diff --git a/crates/ruff_python_formatter/src/expression/parentheses.rs b/crates/ruff_python_formatter/src/expression/parentheses.rs index 0ba3bc2a70..ed6dd49fb7 100644 --- a/crates/ruff_python_formatter/src/expression/parentheses.rs +++ b/crates/ruff_python_formatter/src/expression/parentheses.rs @@ -43,7 +43,10 @@ where // of 5 characters to avoid it exceeding the line width by 1 reduces the readability. // * The text is know to never fit: The text can never fit even when parenthesizing if it is longer // than the configured line width (minus indent). - text_len > 5 && text_len < context.options().line_width().value() as usize + text_len > 5 + && text_len + <= context.options().line_width().value() as usize + - context.options().indent_width() as usize } pub(crate) trait NeedsParentheses { diff --git a/crates/ruff_python_formatter/src/expression/string.rs b/crates/ruff_python_formatter/src/expression/string.rs index 8762fc69ce..49319f9389 100644 --- a/crates/ruff_python_formatter/src/expression/string.rs +++ b/crates/ruff_python_formatter/src/expression/string.rs @@ -2,7 +2,7 @@ use std::borrow::Cow; use bitflags::bitflags; -use ruff_formatter::{format_args, write, FormatError}; +use ruff_formatter::{format_args, write, FormatError, FormatOptions, TabWidth}; use ruff_python_ast::node::AnyNodeRef; use ruff_python_ast::{self as ast, ExprConstant, ExprFString, Ranged}; use ruff_python_parser::lexer::{lex_starts_at, LexicalError, LexicalErrorType}; @@ -682,13 +682,14 @@ fn normalize_string( /// to the next multiple of 8. This is effectively a port of /// [`str.expandtabs`](https://docs.python.org/3/library/stdtypes.html#str.expandtabs), /// which black [calls with the default tab width of 8](https://github.com/psf/black/blob/c36e468794f9256d5e922c399240d49782ba04f1/src/black/strings.py#L61) -fn count_indentation_like_black(line: &str) -> TextSize { - let tab_width: u32 = 8; +fn count_indentation_like_black(line: &str, tab_width: TabWidth) -> TextSize { let mut indentation = TextSize::default(); for char in line.chars() { if char == '\t' { // Pad to the next multiple of tab_width - indentation += TextSize::from(tab_width - (indentation.to_u32().rem_euclid(tab_width))); + indentation += TextSize::from( + tab_width.value() - (indentation.to_u32().rem_euclid(tab_width.value())), + ); } else if char.is_whitespace() { indentation += char.text_len(); } else { @@ -868,7 +869,7 @@ fn format_docstring(string_part: &FormatStringPart, f: &mut PyFormatter) -> Form .clone() // We don't want to count whitespace-only lines as miss-indented .filter(|line| !line.trim().is_empty()) - .map(count_indentation_like_black) + .map(|line| count_indentation_like_black(line, f.options().tab_width())) .min() .unwrap_or_default(); @@ -943,7 +944,8 @@ fn format_docstring_line( // overindented, in which case we strip the additional whitespace (see example in // [`format_docstring`] doc comment). We then prepend the in-docstring indentation to the // string. - let indent_len = count_indentation_like_black(trim_end) - stripped_indentation; + let indent_len = + count_indentation_like_black(trim_end, f.options().tab_width()) - stripped_indentation; let in_docstring_indent = " ".repeat(indent_len.to_usize()) + trim_end.trim_start(); dynamic_text(&in_docstring_indent, Some(offset)).fmt(f)?; } else { @@ -976,12 +978,23 @@ fn format_docstring_line( #[cfg(test)] mod tests { use crate::expression::string::count_indentation_like_black; + use ruff_formatter::TabWidth; #[test] fn test_indentation_like_black() { - assert_eq!(count_indentation_like_black("\t \t \t").to_u32(), 24); - assert_eq!(count_indentation_like_black("\t \t").to_u32(), 24); - assert_eq!(count_indentation_like_black("\t\t\t").to_u32(), 24); - assert_eq!(count_indentation_like_black(" ").to_u32(), 4); + let tab_width = TabWidth::try_from(8).unwrap(); + assert_eq!( + count_indentation_like_black("\t \t \t", tab_width).to_u32(), + 24 + ); + assert_eq!( + count_indentation_like_black("\t \t", tab_width).to_u32(), + 24 + ); + assert_eq!( + count_indentation_like_black("\t\t\t", tab_width).to_u32(), + 24 + ); + assert_eq!(count_indentation_like_black(" ", tab_width).to_u32(), 4); } } diff --git a/crates/ruff_python_formatter/src/options.rs b/crates/ruff_python_formatter/src/options.rs index ee427fd312..c255c0fd0e 100644 --- a/crates/ruff_python_formatter/src/options.rs +++ b/crates/ruff_python_formatter/src/options.rs @@ -1,5 +1,5 @@ use ruff_formatter::printer::{LineEnding, PrinterOptions}; -use ruff_formatter::{FormatOptions, IndentStyle, LineWidth}; +use ruff_formatter::{FormatOptions, IndentStyle, LineWidth, TabWidth}; use ruff_python_ast::PySourceType; use std::path::Path; use std::str::FromStr; @@ -24,6 +24,10 @@ pub struct PyFormatOptions { #[cfg_attr(feature = "serde", serde(default = "default_line_width"))] line_width: LineWidth, + /// The visual width of a tab character. + #[cfg_attr(feature = "serde", serde(default = "default_tab_width"))] + tab_width: TabWidth, + /// The preferred quote style to use (single vs double quotes). quote_style: QuoteStyle, @@ -39,12 +43,17 @@ fn default_indent_style() -> IndentStyle { IndentStyle::Space(4) } +fn default_tab_width() -> TabWidth { + TabWidth::try_from(4).unwrap() +} + impl Default for PyFormatOptions { fn default() -> Self { Self { source_type: PySourceType::default(), indent_style: default_indent_style(), line_width: default_line_width(), + tab_width: default_tab_width(), quote_style: QuoteStyle::default(), magic_trailing_comma: MagicTrailingComma::default(), } @@ -106,13 +115,17 @@ impl FormatOptions for PyFormatOptions { self.indent_style } + fn tab_width(&self) -> TabWidth { + self.tab_width + } + fn line_width(&self) -> LineWidth { self.line_width } fn as_print_options(&self) -> PrinterOptions { PrinterOptions { - tab_width: 4, + tab_width: self.tab_width, print_width: self.line_width.into(), line_ending: LineEnding::LineFeed, indent_style: self.indent_style, diff --git a/crates/ruff_python_formatter/tests/fixtures.rs b/crates/ruff_python_formatter/tests/fixtures.rs index 1991b838f4..a14b4c7193 100644 --- a/crates/ruff_python_formatter/tests/fixtures.rs +++ b/crates/ruff_python_formatter/tests/fixtures.rs @@ -253,9 +253,11 @@ impl fmt::Display for DisplayPyOptions<'_> { f, r#"indent-style = {indent_style} line-width = {line_width} +tab-width = {tab_width} quote-style = {quote_style:?} magic-trailing-comma = {magic_trailing_comma:?}"#, indent_style = self.0.indent_style(), + tab_width = self.0.tab_width().value(), line_width = self.0.line_width().value(), quote_style = self.0.quote_style(), magic_trailing_comma = self.0.magic_trailing_comma() diff --git a/crates/ruff_python_formatter/tests/snapshots/format@docstring.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@docstring.py.snap index 0a3c9a62a6..e4916db81d 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@docstring.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@docstring.py.snap @@ -113,6 +113,7 @@ class TabbedIndent: ``` indent-style = Spaces, size: 4 line-width = 88 +tab-width = 8 quote-style = Double magic-trailing-comma = Respect ``` @@ -225,6 +226,7 @@ class TabbedIndent: ``` indent-style = Spaces, size: 2 line-width = 88 +tab-width = 8 quote-style = Double magic-trailing-comma = Respect ``` @@ -337,6 +339,7 @@ class TabbedIndent: ``` indent-style = Tab line-width = 88 +tab-width = 8 quote-style = Double magic-trailing-comma = Respect ``` @@ -445,4 +448,117 @@ class TabbedIndent: ``` +### Output 4 +``` +indent-style = Tab +line-width = 88 +tab-width = 4 +quote-style = Double +magic-trailing-comma = Respect +``` + +```py +def single_line_backslashes1(): + """content\ """ + return + + +def single_line_backslashes2(): + """content\\""" + return + + +def single_line_backslashes3(): + """content\\\ """ + return + + +def multiline_backslashes1(): + """This is a docstring with + some lines of text\ """ + return + + +def multiline_backslashes2(): + """This is a docstring with + some lines of text\\""" + return + + +def multiline_backslashes3(): + """This is a docstring with + some lines of text\\\ """ + return + + +def multiple_negatively_indented_docstring_lines(): + """a + b + c + d + e + """ + + +def overindentend_docstring(): + """a + over-indented + """ + + +def comment_before_docstring(): + # don't lose this function comment ... + """Does nothing. + + But it has comments + """ # ... neither lose this function comment + + +class CommentBeforeDocstring: + # don't lose this class comment ... + """Empty class. + + But it has comments + """ # ... neither lose this class comment + + +class IndentMeSome: + def doc_string_without_linebreak_after_colon(self): + """This is somewhat strange + a + b + We format this a is the docstring had started properly indented on the next + line if the target indentation. This may we incorrect since source and target + indentation can be incorrect, but this is also an edge case. + """ + + +class IgnoreImplicitlyConcatenatedStrings: + """""" "" + + +def docstring_that_ends_with_quote_and_a_line_break1(): + """ + he said "the news of my death have been greatly exaggerated" + """ + + +def docstring_that_ends_with_quote_and_a_line_break2(): + """he said "the news of my death have been greatly exaggerated" """ + + +def docstring_that_ends_with_quote_and_a_line_break3(): + """he said "the news of my death have been greatly exaggerated" """ + + +class TabbedIndent: + def tabbed_indent(self): + """check for correct tabbed formatting + ^^^^^^^^^^ + Normal indented line + - autor + """ +``` + + diff --git a/crates/ruff_python_formatter/tests/snapshots/format@expression__bytes.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@expression__bytes.py.snap index 51f3792371..e8bf4b5546 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@expression__bytes.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@expression__bytes.py.snap @@ -131,6 +131,7 @@ test_particular = [ ``` indent-style = Spaces, size: 4 line-width = 88 +tab-width = 4 quote-style = Double magic-trailing-comma = Respect ``` @@ -279,6 +280,7 @@ test_particular = [ ``` indent-style = Spaces, size: 4 line-width = 88 +tab-width = 4 quote-style = Single magic-trailing-comma = Respect ``` diff --git a/crates/ruff_python_formatter/tests/snapshots/format@expression__string.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@expression__string.py.snap index 099fbb24a1..9046b6740f 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@expression__string.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@expression__string.py.snap @@ -143,6 +143,7 @@ x = (b"""aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa""" b"""bbbbbbbbbbbbbbbbbbbbbbbbbbb ``` indent-style = Spaces, size: 4 line-width = 88 +tab-width = 4 quote-style = Double magic-trailing-comma = Respect ``` @@ -312,6 +313,7 @@ x = ( ``` indent-style = Spaces, size: 4 line-width = 88 +tab-width = 4 quote-style = Single magic-trailing-comma = Respect ``` diff --git a/crates/ruff_python_formatter/tests/snapshots/format@fmt_on_off__fmt_off_docstring.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@fmt_on_off__fmt_off_docstring.py.snap index dd1d9c6714..8a78898651 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@fmt_on_off__fmt_off_docstring.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@fmt_on_off__fmt_off_docstring.py.snap @@ -30,6 +30,7 @@ def test(): ``` indent-style = Spaces, size: 4 line-width = 88 +tab-width = 4 quote-style = Double magic-trailing-comma = Respect ``` @@ -61,6 +62,7 @@ def test(): ``` indent-style = Spaces, size: 2 line-width = 88 +tab-width = 4 quote-style = Double magic-trailing-comma = Respect ``` diff --git a/crates/ruff_python_formatter/tests/snapshots/format@fmt_on_off__indent.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@fmt_on_off__indent.py.snap index 37ea15222f..d373b18048 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@fmt_on_off__indent.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@fmt_on_off__indent.py.snap @@ -66,6 +66,7 @@ formatted; ``` indent-style = Spaces, size: 4 line-width = 88 +tab-width = 4 quote-style = Double magic-trailing-comma = Respect ``` @@ -135,6 +136,7 @@ formatted ``` indent-style = Spaces, size: 1 line-width = 88 +tab-width = 4 quote-style = Double magic-trailing-comma = Respect ``` @@ -204,6 +206,7 @@ formatted ``` indent-style = Tab line-width = 88 +tab-width = 4 quote-style = Double magic-trailing-comma = Respect ``` diff --git a/crates/ruff_python_formatter/tests/snapshots/format@fmt_on_off__mixed_space_and_tab.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@fmt_on_off__mixed_space_and_tab.py.snap index 1027b24e41..8bc61fd6cb 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@fmt_on_off__mixed_space_and_tab.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@fmt_on_off__mixed_space_and_tab.py.snap @@ -26,6 +26,7 @@ not_fixed ``` indent-style = Spaces, size: 4 line-width = 88 +tab-width = 4 quote-style = Double magic-trailing-comma = Respect ``` @@ -52,6 +53,7 @@ not_fixed ``` indent-style = Spaces, size: 2 line-width = 88 +tab-width = 4 quote-style = Double magic-trailing-comma = Respect ``` @@ -78,6 +80,7 @@ not_fixed ``` indent-style = Tab line-width = 88 +tab-width = 4 quote-style = Double magic-trailing-comma = Respect ``` diff --git a/crates/ruff_python_formatter/tests/snapshots/format@skip_magic_trailing_comma.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@skip_magic_trailing_comma.py.snap index a799ac9bc6..08d17e970d 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@skip_magic_trailing_comma.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@skip_magic_trailing_comma.py.snap @@ -44,6 +44,7 @@ with (a,): # magic trailing comma ``` indent-style = Spaces, size: 4 line-width = 88 +tab-width = 4 quote-style = Double magic-trailing-comma = Respect ``` @@ -95,6 +96,7 @@ with ( ``` indent-style = Spaces, size: 4 line-width = 88 +tab-width = 4 quote-style = Double magic-trailing-comma = Ignore ``` diff --git a/crates/ruff_python_formatter/tests/snapshots/format@tab_width.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@tab_width.py.snap new file mode 100644 index 0000000000..6e46ff92f0 --- /dev/null +++ b/crates/ruff_python_formatter/tests/snapshots/format@tab_width.py.snap @@ -0,0 +1,69 @@ +--- +source: crates/ruff_python_formatter/tests/fixtures.rs +input_file: crates/ruff_python_formatter/resources/test/fixtures/ruff/tab_width.py +--- +## Input +```py +# Fits with tab width 2 +1 + " 012345678901234567890123456789012345678901234567890123456789012345678901234567890" + +# Fits with tab width 4 +1 + " 0123456789012345678901234567890123456789012345678901234567890123456789012345678" + +# Fits with tab width 8 +1 + " 012345678901234567890123456789012345678901234567890123456789012345678901234" +``` + +## Outputs +### Output 1 +``` +indent-style = Spaces, size: 4 +line-width = 88 +tab-width = 2 +quote-style = Double +magic-trailing-comma = Respect +``` + +```py +# Fits with tab width 2 +( + 1 + + " 012345678901234567890123456789012345678901234567890123456789012345678901234567890" +) + +# Fits with tab width 4 +1 + " 0123456789012345678901234567890123456789012345678901234567890123456789012345678" + +# Fits with tab width 8 +1 + " 012345678901234567890123456789012345678901234567890123456789012345678901234" +``` + + +### Output 2 +``` +indent-style = Spaces, size: 4 +line-width = 88 +tab-width = 4 +quote-style = Double +magic-trailing-comma = Respect +``` + +```py +# Fits with tab width 2 +( + 1 + + " 012345678901234567890123456789012345678901234567890123456789012345678901234567890" +) + +# Fits with tab width 4 +( + 1 + + " 0123456789012345678901234567890123456789012345678901234567890123456789012345678" +) + +# Fits with tab width 8 +1 + " 012345678901234567890123456789012345678901234567890123456789012345678901234" +``` + + +