Skip to content
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

Tabbed indenting #454

Closed
arcnmx opened this issue Oct 13, 2015 · 5 comments
Closed

Tabbed indenting #454

arcnmx opened this issue Oct 13, 2015 · 5 comments

Comments

@arcnmx
Copy link

arcnmx commented Oct 13, 2015

Visual indenting seems to be sneaking in and I can't quite get the style I want... Apologies in advance for how bad this issue report is going to be.

test.rs

Generally, I'd want rustfmt to leave the source roughly as it's currently formatted, except that it would fix up and wrap some of the long lines. (note this is hard-tabbed)

use a;
use c;
use b;
use std::{
    SomeType, Something, More, Stuff,
    And, Maybe, Something, Else,
    AndMore, Long, Things, Go, Here, Please,
    Dont, Make, this, one, line,
};

fn some_func(arg1: u32, arg2: u32, arg3: u32, arg4: u32, arg5: u32, arg6: i32,
    arg7: u32, arg8: u32, arg9: u32, arg10: u32) -> u32 {
    stuff
}

struct S {
    inner: (),
}

fn main() {
    some_call(s.inner, s.some_long_expr, and_some, more,
        please(and_thank_you));

    some_chain().of_really_long(|| methods_that_do_things())
        .will_go_here().collect();
}

diff

What it actually does is introduce visual indenting in various places...

Diff at line 1:
 use a;⏎
 use c;⏎
 use b;⏎
+use std::{And, AndMore, Dont, Else, Go, Here, Long, Make, Maybe, More, Please, SomeType, Something,⏎
+          Something, Stuff, Things, line, one, this};⏎
-use std::{⏎
-   SomeType, Something, More, Stuff,⏎
-   And, Maybe, Something, Else,⏎
-   AndMore, Long, Things, Go, Here, Please,⏎
-   Dont, Make, this, one, line,⏎
-};⏎+fn some_func(arg1: u32, arg2: u32, arg3: u32, arg4: u32, arg5: u32, arg6: i32, arg7: u32, arg8: u32,⏎
+   arg9: u32, arg10: u32)⏎
+             -> u32 {⏎
-fn some_func(arg1: u32, arg2: u32, arg3: u32, arg4: u32, arg5: u32, arg6: i32,⏎
-   arg7: u32, arg8: u32, arg9: u32, arg10: u32) -> u32 {⏎
    stuff⏎
 }⏎
 ⏎

Diff at line 15:
 }⏎
 ⏎
 fn main() {⏎
+   some_call(s.inner,⏎
+             s.some_long_expr,⏎
+             and_some,⏎
+             more,⏎
+             please(and_thank_you));⏎
-   some_call(s.inner, s.some_long_expr, and_some, more,⏎
-       please(and_thank_you));⏎+   some_chain()⏎
+       .of_really_long(|| methods_that_do_things())⏎
+       .will_go_here()⏎
+       .collect();⏎
-   some_chain().of_really_long(|| methods_that_do_things())⏎
-       .will_go_here().collect();⏎
 }⏎

rustfmt.toml

max_width = 100
ideal_width = 80
tab_spaces = 4
fn_call_width = 60
struct_lit_width = 16
newline_style = "Unix"
fn_brace_style = "PreferSameLine"
fn_return_indent = "WithArgs"
fn_args_paren_newline = true
fn_args_density = "Compressed"
fn_args_layout = "Visual"
fn_arg_indent = "Tabbed"
where_density = "Compressed"
where_indent = "Tabbed"
where_layout = "Horizontal"
where_pred_indent = "Tabbed"
generics_indent = "Tabbed"
struct_trailing_comma = "Vertical"
struct_lit_trailing_comma = "Vertical"
struct_lit_style = "Block"
struct_lit_multiline_style = "PreferSingle"
enum_trailing_comma = true
report_todo = "Always"
report_fixme = "Always"
reorder_imports = true
single_line_if_else = true
format_strings = true
chains_overflow_last = true
take_source_hints = true
hard_tabs = true

Notes

  • The a, b, and c use lines are not alphabetically reordered or otherwise fixed. I assume that's just not implemented? Is there an issue for that?
  • The use std::{...} line gets visually indented rather than block/tabbed. There doesn't seem to be a config option for this?
    • It's also excessively long, not line-breaking until it hits the hard width limit of 100.
  • fn some_func declaration formatting starts off fine, but then it goes and indents the -> return part visually.
  • some_call visually indents its arguments.
  • I'm using fn_args_layout = "Visual" because Block is too vertical. Tabbed probably describes what I'm looking for best. Also note that Block doesn't even affect some_call for some reason?
    • Block would be what I'm looking for if it compressed more aggressively. Not necessarily a newline right after the opening bracket, etc.
  • some_chain at least seems to be indenting in tabbed style, but it indents with spaces rather than hard tabs.
@marcusklaas
Copy link
Contributor

There is an issue for reordering use statements. It's a fun one, too.

Agreed on the longness of the use statements. We should probably once again wrap on ideal width. We should do the same for functions whenever possible.

Note that fn_args_layout influences the layout of function definitions, not function calls.

The chains using spaces instead of tabs seems to be a proper bug and deserves its own issue.

About using visual indentation: you're correct that it's not possible to switch to block indentation in a lot of places. I'm sure this will be added at some point, I just don't know how prioritized it is for the other contributors. Personally, I'm focusing on formatting additional items more than the configurability of things.

@nrc
Copy link
Member

nrc commented Oct 13, 2015

I don't want to go back to using ideal width for stuff - it looked weird when a whole file was one width except some odd bits and pieces. I found that I didn't like the long import lines at first, but got used to them.

Yeah, we should add configurability for stuff like block indent in more places, but its not a priority for me either - I'd rather focus on getting the defaults looking really good and being able to avoid crashes, etc. Patches welcome for this stuff though! At some point I'll work on RFCs for more stuff and if there is demand then for certain options I'll work on them (like I did for function defs).

@nrc
Copy link
Member

nrc commented Oct 13, 2015

I started out trying to make rustfmt work with the philosophy of "it ain't broke, don't fix it". But other than for line length, it turned out to be really difficult to judge if code obeys a set of rules, rather than reformatting it. Even with line length, it is a bit of a pain because of the mapping you have to do from lines to AST nodes in order to see if you should reformat or not. I fear that this implementation of rustfmt will never be able to operate in a mode where it leaves stuff alone unless it overflows. Two possible solutions: you only run rustfmt on small bits of code at a time (there's an issue for this already, and it shouldn't be difficult to implement); or we implement enough options that you can find a set close enough to what you want and always format everything (maybe with a dusting of #[rustfmt_skip]).

@arcnmx
Copy link
Author

arcnmx commented Oct 13, 2015

Thanks for clearing that up, maybe I'll take a look at implementing some config options if I can get the time. When I said "roughly as it's currently formatted", I simply meant that I wanted a config that would result in similarly formatted code - I certainly like that rustfmt is opinionated and will reformat whatever it sees, I just very much dislike visual indenting in any form :p

I wasn't able to find the issue for the use/import statements, could someone link that for me?

Also, side question... Using #[rustfmt_skip] presumably means your source will only compile on unstable, is there any way to make use of it without sacrificing the ability to compile with stable?

@nrc
Copy link
Member

nrc commented Oct 13, 2015

https://github.com/nrc/rustfmt/issues/298

I guess so. I think the only way round it is scoped attributes, I should make an RFC for that...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants