Skip to content

Options for formatting struct literals #137

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jul 16, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions src/changes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,11 @@ pub struct ChangeSet<'a> {
impl<'a> ChangeSet<'a> {
// Create a new ChangeSet for a given libsyntax CodeMap.
pub fn from_codemap(codemap: &'a CodeMap) -> ChangeSet<'a> {
let mut result = ChangeSet { file_map: HashMap::new(),
codemap: codemap,
file_spans: Vec::with_capacity(codemap.files.borrow().len()), };
let mut result = ChangeSet {
file_map: HashMap::new(),
codemap: codemap,
file_spans: Vec::with_capacity(codemap.files.borrow().len()),
};

for f in codemap.files.borrow().iter() {
// Use the length of the file as a heuristic for how much space we
Expand Down
16 changes: 9 additions & 7 deletions src/comment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,15 @@ pub fn rewrite_comment(orig: &str, block_style: bool, width: usize, offset: usiz
let max_chars = width.checked_sub(closer.len()).unwrap_or(1)
.checked_sub(opener.len()).unwrap_or(1);

let fmt = StringFormat { opener: "",
closer: "",
line_start: line_start,
line_end: "",
width: max_chars,
offset: offset + opener.len() - line_start.len(),
trim_end: true, };
let fmt = StringFormat {
opener: "",
closer: "",
line_start: line_start,
line_end: "",
width: max_chars,
offset: offset + opener.len() - line_start.len(),
trim_end: true,
};

let indent_str = make_indent(offset);
let line_breaks = s.chars().filter(|&c| c == '\n').count();
Expand Down
13 changes: 11 additions & 2 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

extern crate toml;

use {NewlineStyle, BraceStyle, ReturnIndent};
use {NewlineStyle, BraceStyle, ReturnIndent, StructLitStyle};
use lists::SeparatorTactic;
use issues::ReportTactic;

Expand All @@ -26,6 +26,7 @@ pub struct Config {
pub fn_args_paren_newline: bool,
pub struct_trailing_comma: SeparatorTactic,
pub struct_lit_trailing_comma: SeparatorTactic,
pub struct_lit_style: StructLitStyle,
pub enum_trailing_comma: bool,
pub report_todo: ReportTactic,
pub report_fixme: ReportTactic,
Expand All @@ -35,6 +36,14 @@ pub struct Config {
impl Config {
pub fn from_toml(toml: &str) -> Config {
let parsed = toml.parse().unwrap();
toml::decode(parsed).unwrap()
match toml::decode(parsed) {
Some(decoded) => decoded,
None => {
println!("Decoding config file failed. Config:\n{}", toml);
let parsed: toml::Value = toml.parse().unwrap();
println!("\n\nParsed:\n{:?}", parsed);
panic!();
}
}
}
}
1 change: 1 addition & 0 deletions src/default.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ fn_brace_style = "SameLineWhere"
fn_return_indent = "WithArgs"
fn_args_paren_newline = true
struct_trailing_comma = "Vertical"
struct_lit_style = "BlockIndent"
struct_lit_trailing_comma = "Vertical"
enum_trailing_comma = true
report_todo = "Always"
Expand Down
101 changes: 63 additions & 38 deletions src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use rewrite::{Rewrite, RewriteContext};
use lists::{write_list, itemize_list, ListFormatting, SeparatorTactic, ListTactic};
use string::{StringFormat, rewrite_string};
use StructLitStyle;
use utils::{span_after, make_indent};
use visitor::FmtVisitor;

Expand Down Expand Up @@ -100,13 +101,15 @@ fn rewrite_string_lit(context: &RewriteContext,
if l_loc.line == r_loc.line && r_loc.col.to_usize() <= context.config.max_width {
return context.codemap.span_to_snippet(span).ok();
}
let fmt = StringFormat { opener: "\"",
closer: "\"",
line_start: " ",
line_end: "\\",
width: width,
offset: offset,
trim_end: false, };
let fmt = StringFormat {
opener: "\"",
closer: "\"",
line_start: " ",
line_end: "\\",
width: width,
offset: offset,
trim_end: false,
};

Some(rewrite_string(&s.escape_default(), &fmt))
}
Expand Down Expand Up @@ -146,13 +149,15 @@ fn rewrite_call(context: &RewriteContext,
callee.span.hi + BytePos(1),
span.hi);

let fmt = ListFormatting { tactic: ListTactic::HorizontalVertical,
separator: ",",
trailing_separator: SeparatorTactic::Never,
indent: offset,
h_width: remaining_width,
v_width: remaining_width,
ends_with_newline: true, };
let fmt = ListFormatting {
tactic: ListTactic::HorizontalVertical,
separator: ",",
trailing_separator: SeparatorTactic::Never,
indent: offset,
h_width: remaining_width,
v_width: remaining_width,
ends_with_newline: true,
};

Some(format!("{}({})", callee_str, write_list(&items, &fmt)))
}
Expand Down Expand Up @@ -187,9 +192,19 @@ fn rewrite_struct_lit<'a>(context: &RewriteContext,
}

let path_str = pprust::path_to_string(path);
// Foo { a: Foo } - indent is +3, width is -5.
let indent = offset + path_str.len() + 3;
let budget = width - (path_str.len() + 5);
let (indent, h_budget, v_budget) = match context.config.struct_lit_style {
StructLitStyle::VisualIndent => {
// Foo { a: Foo } - indent is +3, width is -5.
let budget = width - (path_str.len() + 5);
(offset + path_str.len() + 3, budget, budget)
}
StructLitStyle::BlockIndent => {
// If we are all on one line, then we'll ignore the indent, and we
// have a smaller budget.
let indent = context.block_indent + context.config.tab_spaces;
(indent, width - (path_str.len() + 5), width - indent)
}
};

let field_iter = fields.into_iter().map(StructLitField::Regular)
.chain(base.into_iter().map(StructLitField::Base));
Expand All @@ -215,13 +230,13 @@ fn rewrite_struct_lit<'a>(context: &RewriteContext,
|item| {
match *item {
StructLitField::Regular(ref field) => {
rewrite_field(context, &field, budget, indent)
rewrite_field(context, &field, h_budget, indent)
.unwrap_or(context.codemap.span_to_snippet(field.span)
.unwrap())
},
StructLitField::Base(ref expr) => {
// 2 = ..
expr.rewrite(context, budget - 2, indent + 2)
expr.rewrite(context, h_budget - 2, indent + 2)
.map(|s| format!("..{}", s))
.unwrap_or(context.codemap.span_to_snippet(expr.span)
.unwrap())
Expand All @@ -231,24 +246,32 @@ fn rewrite_struct_lit<'a>(context: &RewriteContext,
span_after(span, "{", context.codemap),
span.hi);

let fmt = ListFormatting { tactic: ListTactic::HorizontalVertical,
separator: ",",
trailing_separator: if base.is_some() {
let fmt = ListFormatting {
tactic: ListTactic::HorizontalVertical,
separator: ",",
trailing_separator: if base.is_some() {
SeparatorTactic::Never
} else {
context.config.struct_lit_trailing_comma
},
indent: indent,
h_width: budget,
v_width: budget,
ends_with_newline: true, };
indent: indent,
h_width: h_budget,
v_width: v_budget,
ends_with_newline: true,
};
let fields_str = write_list(&items, &fmt);
Some(format!("{} {{ {} }}", path_str, fields_str))

// FIXME if the usual multi-line layout is too wide, we should fall back to
// Foo {
// a: ...,
// }
match context.config.struct_lit_style {
StructLitStyle::BlockIndent if fields_str.contains('\n') => {
let inner_indent = make_indent(context.block_indent + context.config.tab_spaces);
let outer_indent = make_indent(context.block_indent);
Some(format!("{} {{\n{}{}\n{}}}", path_str, inner_indent, fields_str, outer_indent))
}
_ => Some(format!("{} {{ {} }}", path_str, fields_str)),
}

// FIXME if context.config.struct_lit_style == VisualIndent, but we run out
// of space, we should fall back to BlockIndent.
}

fn rewrite_field(context: &RewriteContext,
Expand Down Expand Up @@ -291,13 +314,15 @@ fn rewrite_tuple_lit(context: &RewriteContext,
span.lo + BytePos(1), // Remove parens
span.hi - BytePos(1));

let fmt = ListFormatting { tactic: ListTactic::HorizontalVertical,
separator: ",",
trailing_separator: SeparatorTactic::Never,
indent: indent,
h_width: width - 2,
v_width: width - 2,
ends_with_newline: true, };
let fmt = ListFormatting {
tactic: ListTactic::HorizontalVertical,
separator: ",",
trailing_separator: SeparatorTactic::Never,
indent: indent,
h_width: width - 2,
v_width: width - 2,
ends_with_newline: true,
};

Some(format!("({})", write_list(&items, &fmt)))
}
Expand Down
16 changes: 9 additions & 7 deletions src/imports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,13 +71,15 @@ impl<'a> FmtVisitor<'a> {
let remaining_line_budget = one_line_budget.checked_sub(used_width).unwrap_or(0);
let remaining_multi_budget = multi_line_budget.checked_sub(used_width).unwrap_or(0);

let fmt = ListFormatting { tactic: ListTactic::Mixed,
separator: ",",
trailing_separator: SeparatorTactic::Never,
indent: block_indent + indent,
h_width: remaining_line_budget,
v_width: remaining_multi_budget,
ends_with_newline: true, };
let fmt = ListFormatting {
tactic: ListTactic::Mixed,
separator: ",",
trailing_separator: SeparatorTactic::Never,
indent: block_indent + indent,
h_width: remaining_line_budget,
v_width: remaining_multi_budget,
ends_with_newline: true,
};

let mut items = itemize_list(self.codemap,
vec![ListItem::from_str("")], /* Dummy value, explanation
Expand Down
8 changes: 5 additions & 3 deletions src/issues.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,9 +96,11 @@ pub struct BadIssueSeeker {

impl BadIssueSeeker {
pub fn new(report_todo: ReportTactic, report_fixme: ReportTactic) -> BadIssueSeeker {
BadIssueSeeker { state: Seeking::Issue { todo_idx: 0, fixme_idx: 0 },
report_todo: report_todo,
report_fixme: report_fixme, }
BadIssueSeeker {
state: Seeking::Issue { todo_idx: 0, fixme_idx: 0 },
report_todo: report_todo,
report_fixme: report_fixme,
}
}

// Check whether or not the current char is conclusive evidence for an
Expand Down
64 changes: 36 additions & 28 deletions src/items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -305,13 +305,15 @@ impl<'a> FmtVisitor<'a> {
item.item = arg;
}

let fmt = ListFormatting { tactic: ListTactic::HorizontalVertical,
separator: ",",
trailing_separator: SeparatorTactic::Never,
indent: arg_indent,
h_width: one_line_budget,
v_width: multi_line_budget,
ends_with_newline: true, };
let fmt = ListFormatting {
tactic: ListTactic::HorizontalVertical,
separator: ",",
trailing_separator: SeparatorTactic::Never,
indent: arg_indent,
h_width: one_line_budget,
v_width: multi_line_budget,
ends_with_newline: true,
};

write_list(&arg_items, &fmt)
}
Expand Down Expand Up @@ -566,13 +568,15 @@ impl<'a> FmtVisitor<'a> {

// 1 = ,
let budget = self.config.ideal_width - offset + self.config.tab_spaces - 1;
let fmt = ListFormatting { tactic: tactic,
separator: ",",
trailing_separator: self.config.struct_trailing_comma,
indent: offset + self.config.tab_spaces,
h_width: self.config.max_width,
v_width: budget,
ends_with_newline: false, };
let fmt = ListFormatting {
tactic: tactic,
separator: ",",
trailing_separator: self.config.struct_trailing_comma,
indent: offset + self.config.tab_spaces,
h_width: self.config.max_width,
v_width: budget,
ends_with_newline: false,
};

result.push_str(&write_list(&items, &fmt));

Expand Down Expand Up @@ -707,13 +711,15 @@ impl<'a> FmtVisitor<'a> {
item.item = ty;
}

let fmt = ListFormatting { tactic: ListTactic::HorizontalVertical,
separator: ",",
trailing_separator: SeparatorTactic::Never,
indent: offset + 1,
h_width: budget,
v_width: budget,
ends_with_newline: true, };
let fmt = ListFormatting {
tactic: ListTactic::HorizontalVertical,
separator: ",",
trailing_separator: SeparatorTactic::Never,
indent: offset + 1,
h_width: budget,
v_width: budget,
ends_with_newline: true,
};
result.push_str(&write_list(&items, &fmt));

result.push('>');
Expand Down Expand Up @@ -748,13 +754,15 @@ impl<'a> FmtVisitor<'a> {
span_end);

let budget = self.config.ideal_width + self.config.leeway - indent - 10;
let fmt = ListFormatting { tactic: ListTactic::Vertical,
separator: ",",
trailing_separator: SeparatorTactic::Never,
indent: indent + 10,
h_width: budget,
v_width: budget,
ends_with_newline: true, };
let fmt = ListFormatting {
tactic: ListTactic::Vertical,
separator: ",",
trailing_separator: SeparatorTactic::Never,
indent: indent + 10,
h_width: budget,
v_width: budget,
ends_with_newline: true,
};
result.push_str(&write_list(&items, &fmt));

result
Expand Down
13 changes: 13 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,19 @@ pub enum ReturnIndent {

impl_enum_decodable!(ReturnIndent, WithArgs, WithWhereClause);

// How to stle a struct literal.
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
pub enum StructLitStyle {
// First line on the same line as the opening brace, all lines aligned with
// the first line.
VisualIndent,
// First line is on a new line and all lines align with block indent.
BlockIndent,
// FIXME Maybe we should also have an option to align types.
}

impl_enum_decodable!(StructLitStyle, VisualIndent, BlockIndent);

enum ErrorKind {
// Line has exceeded character limit
LineOverflow,
Expand Down
Loading