From eaab592cb80c8b32b5f047955ca2cec073e6ace2 Mon Sep 17 00:00:00 2001 From: topecongiro Date: Fri, 9 Mar 2018 17:10:20 +0900 Subject: [PATCH] Avoid unindenting code block in comment with unformattable macro `format_code_block` formats the given `code_snippet` by enclosing it inside `fn main` block. Previously we did not add indentation to the `code_snippet` before formatting it. This works fine as long as we can format the given `code_snippet`, but when the code block has unformattable macro, they gets unindented. This commit fixes it by adding proper indentation before formatting the `code_snippet`. For example, when formatting the following code block, ```rust some_macro!(pub fn foo() { println!("Don't unindent me!"); }); ``` previously we enclosed it like this: ```rust fn main() { some_macro!(pub fn foo() { println!("Don't unindent me!"); }); } ``` with this PR, we will enclose it like this: ```rust fn main() { some_macro!(pub fn foo() { println!("Don't unindent me!"); }); } ``` Closes #2523. --- src/lib.rs | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index fe08b68c7821..310cce4bbeca 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -596,14 +596,23 @@ pub fn format_snippet(snippet: &str, config: &Config) -> Option { } } +const FN_MAIN_PREFIX: &str = "fn main() {\n"; + +fn enclose_in_main_block(s: &str, config: &Config) -> String { + let indent = Indent::from_width(config, config.tab_spaces()); + FN_MAIN_PREFIX.to_owned() + &indent.to_string(config) + + &s.lines() + .collect::>() + .join(&indent.to_string_with_newline(config)) + "\n}" +} + /// Format the given code block. Mainly targeted for code block in comment. /// The code block may be incomplete (i.e. parser may be unable to parse it). /// To avoid panic in parser, we wrap the code block with a dummy function. /// The returned code block does *not* end with newline. pub fn format_code_block(code_snippet: &str, config: &Config) -> Option { // Wrap the given code block with `fn main()` if it does not have one. - let fn_main_prefix = "fn main() {\n"; - let snippet = fn_main_prefix.to_owned() + code_snippet + "\n}"; + let snippet = enclose_in_main_block(code_snippet, config); let mut result = String::with_capacity(snippet.len()); let mut is_first = true; @@ -612,7 +621,7 @@ pub fn format_code_block(code_snippet: &str, config: &Config) -> Option let formatted = format_snippet(&snippet, config)?; // 2 = "}\n" let block_len = formatted.len().checked_sub(2).unwrap_or(0); - for line in formatted[fn_main_prefix.len()..block_len].lines() { + for line in formatted[FN_MAIN_PREFIX.len()..block_len].lines() { if !is_first { result.push('\n'); } else {