Add tab width option (#6848)

This commit is contained in:
Micha Reiser 2023-08-26 12:29:58 +02:00 committed by GitHub
parent f91bacbb94
commit 9d77552e18
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
20 changed files with 345 additions and 44 deletions

View file

@ -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<SimpleFormatContext>) -> 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()
};

View file

@ -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,
}
}
}