diff --git a/src/dfmt/ast_info.d b/src/dfmt/ast_info.d index 83082d1..961b8f9 100644 --- a/src/dfmt/ast_info.d +++ b/src/dfmt/ast_info.d @@ -95,6 +95,12 @@ struct ASTInformation /// Closing braces of function literals size_t[] funLitEndLocations; + /// Locations of aggregate bodies (struct, class, union) + size_t[] aggregateBodyLocations; + + /// Locations of function bodies + size_t[] funBodyLocations; + /// Conditional statements that have matching "else" statements size_t[] conditionalWithElseLocations; @@ -200,6 +206,15 @@ final class FormatVisitor : ASTVisitor destructor.accept(this); } + override void visit (const FunctionBody functionBody) + { + if (auto bd = functionBody.specifiedFunctionBody) + { + astInformation.funBodyLocations ~= bd.blockStatement.startLocation; + } + functionBody.accept(this); + } + override void visit(const ConditionalDeclaration dec) { if (dec.hasElse) @@ -313,6 +328,7 @@ final class FormatVisitor : ASTVisitor override void visit(const StructBody structBody) { + astInformation.aggregateBodyLocations ~= structBody.startLocation; astInformation.doubleNewlineLocations ~= structBody.endLocation; structBody.accept(this); } diff --git a/src/dfmt/config.d b/src/dfmt/config.d index 86706d1..64e80d0 100644 --- a/src/dfmt/config.d +++ b/src/dfmt/config.d @@ -16,7 +16,9 @@ enum BraceStyle /// $(LINK https://en.wikipedia.org/wiki/Indent_style#Variant:_1TBS) otbs, /// $(LINK https://en.wikipedia.org/wiki/Indent_style#Variant:_Stroustrup) - stroustrup + stroustrup, + /// $(LINK https://en.wikipedia.org/wiki/Indentation_style#K&R_style) + knr, } enum TemplateConstraintStyle diff --git a/src/dfmt/formatter.d b/src/dfmt/formatter.d index f8883da..f66ac1b 100644 --- a/src/dfmt/formatter.d +++ b/src/dfmt/formatter.d @@ -15,6 +15,7 @@ import dfmt.indentation; import dfmt.tokens; import dfmt.wrapping; import std.array; +import std.algorithm.comparison : among; /** * Formats the code contained in `buffer` into `output`. @@ -963,6 +964,10 @@ private: if (config.dfmt_brace_style == BraceStyle.allman || peekBackIsOneOf(true, tok!"{", tok!"}")) newline(); + else if (config.dfmt_brace_style == BraceStyle.knr + && astInformation.funBodyLocations.canFindIndex(tIndex) + && (peekBackIs(tok!")") || (!peekBackIs(tok!"do") && peekBack().text != "body"))) + newline(); else if (!peekBackIsOneOf(true, tok!"{", tok!"}", tok!";")) write(" "); writeToken(); @@ -1031,7 +1036,7 @@ private: currentLineLength = 0; justAddedExtraNewline = true; } - if (config.dfmt_brace_style == BraceStyle.otbs + if (config.dfmt_brace_style.among(BraceStyle.otbs, BraceStyle.knr) && ((peekIs(tok!"else") && !indents.topAre(tok!"static", tok!"if") && !indents.topIs(tok!"foreach") && !indents.topIs(tok!"for")