nicklockwood / SwiftFormat

A command-line tool and Xcode Extension for formatting Swift code
MIT License
7.9k stars 640 forks source link

Custom formatting rules #1402

Open dankinsoid opened 1 year ago

dankinsoid commented 1 year ago

SwiftFormat is well suited for projects where there is a prescribed code style, but sometimes a code style may contain rules that are not provided for in SwiftFormat. For example, in my projects, I always add an empty line after a type declaration, but there is no way to automate this. I suggest, by analogy with SwiftLint, allow to specify regex for custom rules. For my example, it will be:

([ \n]|^)(extension|enum|struct|class|actor) ([^{]+)\{[ \t]*(\n)([ \t]*)([^\n \t])

replace with

$1$2 $3{$4$4$5$6
nicklockwood commented 1 year ago

@dankinsoid I've considered adding this (and may do so), but in practice the rules would be rather limited because parsing and manipulating source code with regular expressions is much less powerful than AST-level processing. It would probably be fine for things like whitespace or header comments, but that's about it.

objectmethod commented 1 week ago

Hey Nick. First, awesome work! Love SwiftFormat.

I wanted to throw in my bid for this feature. I definitely get that string-parsing would never be as reliable as AST. However, I still believe having the ability to provide custom rules as described above would be very useful.

As an example: the issue that brought me to this thread: In relation to issue #623, we could search and replace all instances of enum Action with // swiftformat:sort enum Action so that all of the actions in our TCA Reducer would be automatically sorted.

Also, we've already been using SwiftLint. And now that we're adding SwiftFormat, it would be nice to be able to replace SwiftLint alltogether with just one tool to rule them all 🧙

Thanks in advance for your listening to me complain and your consideration!! 🙏

nicklockwood commented 1 week ago

@objectmethod I'm open to adding this feature.

Could you supply some working examples of regex replacement rules that you would use with such a feature if it existed (you can test them using a text editor or whatever) so I can validate that whatever solution I come up with is actually of practical use?