1
Fork 0

Compute indent never relative to current column

Previously the pretty printer would compute indentation always relative
to whatever column a block begins at, like this:

    fn demo(arg1: usize,
            arg2: usize);

This is never the thing to do in the dominant contemporary Rust style.
Rustfmt's default and the style used by the vast majority of Rust
codebases is block indentation:

    fn demo(
        arg1: usize,
        arg2: usize,
    );

where every indentation level is a multiple of 4 spaces and each level
is indented relative to the indentation of the previous line, not the
position that the block starts in.
This commit is contained in:
David Tolnay 2022-01-21 01:34:19 -08:00
parent e58e7b10e1
commit cb93e9c0ec
No known key found for this signature in database
GPG key ID: F9BA143B95FF6D82
2 changed files with 22 additions and 19 deletions

View file

@ -178,7 +178,7 @@ impl Token {
#[derive(Copy, Clone)]
enum PrintFrame {
Fits,
Broken { offset: isize, breaks: Breaks },
Broken { indent: usize, breaks: Breaks },
}
const SIZE_INFINITY: isize = 0xffff;
@ -204,6 +204,8 @@ pub struct Printer {
scan_stack: VecDeque<usize>,
/// Stack of blocks-in-progress being flushed by print
print_stack: Vec<PrintFrame>,
/// Level of indentation of current line
indent: usize,
/// Buffered indentation to avoid writing trailing whitespace
pending_indentation: isize,
/// The token most recently popped from the left boundary of the
@ -229,6 +231,7 @@ impl Printer {
right_total: 0,
scan_stack: VecDeque::new(),
print_stack: Vec::new(),
indent: 0,
pending_indentation: 0,
last_printed: None,
}
@ -368,38 +371,38 @@ impl Printer {
*self
.print_stack
.last()
.unwrap_or(&PrintFrame::Broken { offset: 0, breaks: Breaks::Inconsistent })
.unwrap_or(&PrintFrame::Broken { indent: 0, breaks: Breaks::Inconsistent })
}
fn print_begin(&mut self, token: BeginToken, size: isize) {
if size > self.space {
let col = self.margin - self.space + token.offset;
self.print_stack.push(PrintFrame::Broken { offset: col, breaks: token.breaks });
self.print_stack.push(PrintFrame::Broken { indent: self.indent, breaks: token.breaks });
self.indent = (self.indent as isize + token.offset) as usize;
} else {
self.print_stack.push(PrintFrame::Fits);
}
}
fn print_end(&mut self) {
self.print_stack.pop().unwrap();
if let PrintFrame::Broken { indent, .. } = self.print_stack.pop().unwrap() {
self.indent = indent;
}
}
fn print_break(&mut self, token: BreakToken, size: isize) {
let break_offset =
match self.get_top() {
PrintFrame::Fits => None,
PrintFrame::Broken { offset, breaks: Breaks::Consistent } => Some(offset),
PrintFrame::Broken { offset, breaks: Breaks::Inconsistent } => {
if size > self.space { Some(offset) } else { None }
}
let fits = match self.get_top() {
PrintFrame::Fits => true,
PrintFrame::Broken { breaks: Breaks::Consistent, .. } => false,
PrintFrame::Broken { breaks: Breaks::Inconsistent, .. } => size <= self.space,
};
if let Some(offset) = break_offset {
self.out.push('\n');
self.pending_indentation = offset + token.offset;
self.space = self.margin - (offset + token.offset);
} else {
if fits {
self.pending_indentation += token.blank_space;
self.space -= token.blank_space;
} else {
self.out.push('\n');
let indent = self.indent as isize + token.offset;
self.pending_indentation = indent;
self.space = self.margin - indent;
}
}

View file

@ -655,7 +655,7 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
// Outer-box is consistent.
self.cbox(INDENT_UNIT);
// Head-box is inconsistent.
self.ibox(w.len() + 1);
self.ibox(0);
// Keyword that starts the head.
if !w.is_empty() {
self.word_nbsp(w);