1
Fork 0

Merge pull request #68 from marcusklaas/import-breaks

Keep import lists on a single line when possible
This commit is contained in:
Nick Cameron 2015-05-12 09:39:22 +12:00
commit e2a5d94e3f
4 changed files with 44 additions and 30 deletions

View file

@ -23,10 +23,11 @@ impl<'a> FmtVisitor<'a> {
// Basically just pretty prints a multi-item import. // Basically just pretty prints a multi-item import.
pub fn rewrite_use_list(&mut self, pub fn rewrite_use_list(&mut self,
block_indent: usize, block_indent: usize,
budget: usize, // excluding indentation one_line_budget: usize, // excluding indentation
multi_line_budget: usize,
path: &ast::Path, path: &ast::Path,
path_list: &[ast::PathListItem], path_list: &[ast::PathListItem],
visibility: ast::Visibility) -> Option<String> { visibility: ast::Visibility) -> String {
let path_str = pprust::path_to_string(&path); let path_str = pprust::path_to_string(&path);
let vis = match visibility { let vis = match visibility {
@ -41,10 +42,16 @@ impl<'a> FmtVisitor<'a> {
// 2 = } + ; // 2 = } + ;
let used_width = indent + 2; let used_width = indent + 2;
let remaining_budget = if used_width >= budget { // Break as early as possible when we've blown our budget.
return None; let remaining_line_budget = if used_width > one_line_budget {
0
} else { } else {
budget - used_width one_line_budget - used_width
};
let remaining_multi_budget = if used_width > multi_line_budget {
0
} else {
multi_line_budget - used_width
}; };
let fmt = ListFormatting { let fmt = ListFormatting {
@ -52,8 +59,8 @@ impl<'a> FmtVisitor<'a> {
separator: ",", separator: ",",
trailing_separator: SeparatorTactic::Never, trailing_separator: SeparatorTactic::Never,
indent: block_indent + indent, indent: block_indent + indent,
h_width: remaining_budget, h_width: remaining_line_budget,
v_width: remaining_budget, v_width: remaining_multi_budget,
}; };
// TODO handle any comments inbetween items. // TODO handle any comments inbetween items.
@ -79,10 +86,10 @@ impl<'a> FmtVisitor<'a> {
ast::PathListItem_::PathListMod{ .. } => None, ast::PathListItem_::PathListMod{ .. } => None,
} }
})).collect(); })).collect();
Some(if path_str.len() == 0 { if path_str.len() == 0 {
format!("{}use {{{}}};", vis, write_list(&items, &fmt)) format!("{}use {{{}}};", vis, write_list(&items, &fmt))
} else { } else {
format!("{}use {}::{{{}}};", vis, path_str, write_list(&items, &fmt)) format!("{}use {}::{{{}}};", vis, path_str, write_list(&items, &fmt))
}) }
} }
} }

View file

@ -58,18 +58,24 @@ pub fn write_list<'b>(items: &[(String, String)], formatting: &ListFormatting<'b
}; };
let sep_len = formatting.separator.len(); let sep_len = formatting.separator.len();
let total_sep_len = (sep_len + 1) * sep_count; let total_sep_len = (sep_len + 1) * sep_count;
let total_width = calculate_width(items); let total_width = calculate_width(items);
let fits_single = total_width + total_sep_len <= formatting.h_width;
// Check if we need to fallback from horizontal listing, if possible. // Check if we need to fallback from horizontal listing, if possible.
if tactic == ListTactic::HorizontalVertical { if tactic == ListTactic::HorizontalVertical {
debug!("write_list: total_width: {}, total_sep_len: {}, h_width: {}", debug!("write_list: total_width: {}, total_sep_len: {}, h_width: {}",
total_width, total_sep_len, formatting.h_width); total_width, total_sep_len, formatting.h_width);
if total_width + total_sep_len > formatting.h_width { tactic = if fits_single {
tactic = ListTactic::Vertical; ListTactic::Horizontal
} else { } else {
tactic = ListTactic::Horizontal; ListTactic::Vertical
} };
}
// Check if we can fit everything on a single line in mixed mode.
// The horizontal tactic does not break after v_width columns.
if tactic == ListTactic::Mixed && fits_single {
tactic = ListTactic::Horizontal;
} }
// Now that we know how we will layout, we can decide for sure if there // Now that we know how we will layout, we can decide for sure if there

View file

@ -149,15 +149,16 @@ impl<'a, 'v> visit::Visitor<'v> for FmtVisitor<'a> {
match vp.node { match vp.node {
ast::ViewPath_::ViewPathList(ref path, ref path_list) => { ast::ViewPath_::ViewPathList(ref path, ref path_list) => {
let block_indent = self.block_indent; let block_indent = self.block_indent;
let budget = IDEAL_WIDTH - block_indent; let one_line_budget = MAX_WIDTH - block_indent;
if let Some(new_str) = self.rewrite_use_list(block_indent, let multi_line_budget = IDEAL_WIDTH - block_indent;
budget, let new_str = self.rewrite_use_list(block_indent,
path, one_line_budget,
path_list, multi_line_budget,
item.vis) { path,
self.changes.push_str_span(item.span, &new_str); path_list,
self.last_pos = item.span.hi; item.vis);
} self.changes.push_str_span(item.span, &new_str);
self.last_pos = item.span.hi;
} }
ast::ViewPath_::ViewPathGlob(_) => { ast::ViewPath_::ViewPathGlob(_) => {
// FIXME convert to list? // FIXME convert to list?

View file

@ -1,20 +1,20 @@
// Imports. // Imports.
// Long import. // Long import.
use syntax::ast::{ItemForeignMod, ItemImpl, ItemMac, ItemMod, ItemStatic, use syntax::ast::{ItemForeignMod, ItemImpl, ItemMac, ItemMod, ItemStatic, ItemDefaultImpl};
ItemDefaultImpl}; use exceedingly::looooooooooooooooooooooooooooooooooooooooooooooooooooooooooong::import::path::{ItemA,
ItemB};
use {Foo, Bar}; use {Foo, Bar};
use Foo::{Bar, Baz}; use Foo::{Bar, Baz};
pub use syntax::ast::{Expr_, Expr, ExprAssign, ExprCall, ExprMethodCall, pub use syntax::ast::{Expr_, Expr, ExprAssign, ExprCall, ExprMethodCall, ExprPath};
ExprPath};
mod Foo { mod Foo {
pub use syntax::ast::{Expr_, ExprEval, ToExpr, ExprMethodCall, ToExprPath}; pub use syntax::ast::{ItemForeignMod, ItemImpl, ItemMac, ItemMod, ItemStatic, ItemDefaultImpl};
mod Foo2 { mod Foo2 {
pub use syntax::ast::{Expr_, ExprEval, ToExpr, ExprMethodCall, pub use syntax::ast::{ItemForeignMod, ItemImpl, ItemMac, ItemMod,
ToExprPath}; ItemStatic, ItemDefaultImpl};
} }
} }