From b58f4be7c1727871c46818abeecbfcdcc49378ba Mon Sep 17 00:00:00 2001 From: Nick Lockwood Date: Tue, 15 Nov 2016 22:02:29 +0000 Subject: [PATCH] Added inference for indent level --- SwiftFormat/Options.swift | 30 +++++++++++++++++++++++++++++ SwiftFormatTests/OptionsTests.swift | 6 ++++++ 2 files changed, 36 insertions(+) diff --git a/SwiftFormat/Options.swift b/SwiftFormat/Options.swift index d800e04b..ce379649 100644 --- a/SwiftFormat/Options.swift +++ b/SwiftFormat/Options.swift @@ -105,6 +105,36 @@ public func inferOptions(_ tokens: [Token]) -> FormatOptions { let formatter = Formatter(tokens) var options = FormatOptions() + options.indent = { + var indents = [(indent: String, count: Int)]() + func increment(_ indent: String) { + for (i, element) in indents.enumerated() { + if element.indent == indent { + indents[i] = (indent, element.count + 1) + return + } + } + indents.append((indent, 0)) + } + formatter.forEachToken({ $0.isLinebreak }) { i, token in + let start = formatter.startOfLine(atIndex: i) + if case .whitespace(let string) = formatter.tokens[start] { + if string.hasPrefix("\t") { + increment("\t") + } else { + let length = string.characters.count + for i in [8, 4, 3, 2, 1] { + if length % i == 0 { + increment(String(repeating: " ", count: i)) + break + } + } + } + } + } + return indents.sorted(by: { $0.count > $1.count }).first.map({ $0.indent }) ?? options.indent + }() + options.linebreak = { var cr: Int = 0, lf: Int = 0, crlf: Int = 0 formatter.forEachToken { i, token in diff --git a/SwiftFormatTests/OptionsTests.swift b/SwiftFormatTests/OptionsTests.swift index d593d516..aea676f4 100644 --- a/SwiftFormatTests/OptionsTests.swift +++ b/SwiftFormatTests/OptionsTests.swift @@ -11,6 +11,12 @@ import XCTest class OptionsTests: XCTestCase { + func testInferIndentLevel() { + let input = "\t\nclass Foo {\n func bar() {\n //baz\n}\n}" + let options = inferOptions(tokenize(input)) + XCTAssertEqual(options.indent, " ") + } + func testInferLinebreaks() { let input = "foo\nbar\r\nbaz\rquux\r\n" let output = "\r\n"