SwiftFormat icon indicating copy to clipboard operation
SwiftFormat copied to clipboard

Organise by type first then by category in organizeDeclarations rule

Open FranzBusch opened this issue 4 years ago • 12 comments

First of, really awesome to see this rule land. This has been something we wished for a long time. Right now this rule is sorting based on the category first (public, internal, private, etc) and then by the type (method, property, etc.). For our formatting rules, we would prefer to have the reverse be true. That means sorting by type first and then by category. That means all properties are at the top sorted from public-> internal -> private, then lifecycle methods and then instance methods.

FranzBusch avatar Sep 06 '20 11:09 FranzBusch

@FranzBusch this seems like a reasonable request. The organizeDeclarations rule was implemented by @calda specifically to meet Airbnb's style guide, so your best chance of getting this done quickly would be to extend the rule yourself.

It seems like you'd need two changes - one for the order itself and one for the subheadings, assuming you'd want to label them "// MARK: Properties, // MARK: Functions, etc" rather than having two "//MARK: Public" headers.

The most flexible way to do this would probably to add two new configuration arguments:

  1. --declarationorder to control the total ordering of members. This would probably be an ordered list like static,var,func,public,internal,private that would sort based on type and modifier. E.g a private var would come before a public function (I guess let would be treated the same as var unless added explicitly).

  2. --groupheadings to control which groups get headings. This would again be an ordered list like lifecycle,properties,functions.

(This is just a first guess at how this might work. It's also possible that there are only a handful of reasonable organization structures and it would make more sense just to have a single property like --declarationorder by-category/by-access-level or --declarationstyle airbnb/...)

nicklockwood avatar Sep 07 '20 08:09 nicklockwood

👍 Subscribing, really interested in seeing this! For now I'll have to keep this rule disabled until I have some time to poke around extending this rule myself 🙈

rogerluan avatar May 17 '21 04:05 rogerluan

It's also possible that there are only a handful of reasonable organization structures and it would make more sense just to have a single property like --declarationorder by-category/by-access-level

This sounds really reasonable to me -- it would also probably be the easiest approach to implement.

calda avatar May 17 '21 14:05 calda

Interesting, I'd love to have this feature. I kinda want static,var,func,public,internal,private as well

kkharji avatar Jun 20 '21 13:06 kkharji

--declarationorder to control the total ordering of members. This would probably be an ordered list like static,var,func,public,internal,private that would sort based on type and modifier. E.g a private var would come before a public function (I guess let would be treated the same as var unless added explicitly).

--groupheadings to control which groups get headings. This would again be an ordered list like lifecycle,properties,functions.

That would be awesome! Then we could configure it to the existing standard for our project. And no more manual sorting. No more complains in the merge requests for wrong order.

oonoo avatar Aug 22 '23 14:08 oonoo

Interesting !

pboulch avatar Sep 12 '23 07:09 pboulch

+1 on this. Grouping the entirety of the file contents by access control and then sorting is quite an odd convention. It would be much more useful to still have the ability to sort by access control within the scope of method/property/etc types.

ThePragmaticArt avatar Nov 01 '23 14:11 ThePragmaticArt

@nicklockwood any news about these?

--declarationorder
--groupheadings

For now, I just have to disable 'organizeDeclarations' because it's moving my code to somewhere else at the bottom of the class, which I find really unfortunate..

Before:

struct ContentView: View {
    @State private var animate = false
    @State private var endSplash = false
    var body: some View {
        Text(Constants.Main.download)
            .padding()
    }
}

After:

struct ContentView: View {
    // MARK: Internal
    var body: some View {
        Text(Constants.Main.download)
            .padding()
    }

    // MARK: Private
    @State private var animate = false
    @State private var endSplash = false
}

Volodymyr-13 avatar Nov 19 '23 13:11 Volodymyr-13

@calda any updates?

Volodymyr-13 avatar Jun 05 '24 11:06 Volodymyr-13

@oiuhr landed an implementation of this in https://github.com/nicklockwood/SwiftFormat/pull/1678

calda avatar Jun 05 '24 13:06 calda

@calda thanks, so this will be available in some near future release?

Volodymyr-13 avatar Jun 05 '24 14:06 Volodymyr-13

@Volodymyr-13 it should be in the next release (within a week or two) unless I need to do a bug fix release to address an urgent issue before then

nicklockwood avatar Jun 05 '24 14:06 nicklockwood