Skip to content

Instantly share code, notes, and snippets.

@mayankmkh
Last active October 7, 2024 21:14
Show Gist options
  • Save mayankmkh/92084bdf2b59288d3e74c3735cccbf9f to your computer and use it in GitHub Desktop.
Save mayankmkh/92084bdf2b59288d3e74c3735cccbf9f to your computer and use it in GitHub Desktop.
Pretty Print Kotlin Data Class
fun Any.prettyPrint(): String {
var indentLevel = 0
val indentWidth = 4
fun padding() = "".padStart(indentLevel * indentWidth)
val toString = toString()
val stringBuilder = StringBuilder(toString.length)
var i = 0
while (i < toString.length) {
when (val char = toString[i]) {
'(', '[', '{' -> {
indentLevel++
stringBuilder.appendLine(char).append(padding())
}
')', ']', '}' -> {
indentLevel--
stringBuilder.appendLine().append(padding()).append(char)
}
',' -> {
stringBuilder.appendLine(char).append(padding())
// ignore space after comma as we have added a newline
val nextChar = toString.getOrElse(i + 1) { char }
if (nextChar == ' ') i++
}
else -> {
stringBuilder.append(char)
}
}
i++
}
return stringBuilder.toString()
}
@thought-police-000
Copy link

thought-police-000 commented Jan 31, 2024

I cut this back and cleaned it up a little, and added some kotliny goodness, to make it a little cleaner and easier to read.

fun Any.pretty() = toString().let { toString ->
    var indentLevel = 0
    val indentWidth = 4
    var i = 0
    fun padding() = "".padStart(indentLevel * indentWidth)
    buildString {
        var ignoreSpace = false
        toString.onEach { char ->
            when (char) {
                '(', '[', '{' -> {
                    indentLevel++
                    appendLine(char)
                    append(padding())
                }

                ')', ']', '}' -> {
                    indentLevel--
                    appendLine()
                    append(padding())
                    append(char)
                }

                ',' -> {
                    appendLine(char)
                    append(padding())
                    ignoreSpace = true
                }
                ' ' -> {
                    if (!ignoreSpace) append(char)
                    ignoreSpace = false
                }

                else -> append(char)
            }
        }
    }
}

@thought-police-000
Copy link

With this method I don't think there's any way to get around a string containing a closing bracket.

data class Fish(val message: String)

Fish("bobby),otherValue=fakeData").pretty()

@jisungbin
Copy link

@thought-police-000 Thanks for sharing your awesome code!

@marctatham
Copy link

love it.

@johannesrave
Copy link

johannesrave commented Oct 7, 2024

@thought-police-000 definitely love the buildString builder, i didn't know about that!

regarding the ): you could count the " as well in a "stringLevel" to decide whether one is still inside a string or to decrement the indentation level? adds complexity obviously :/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment