varabyte / kotter

A declarative, Kotlin-idiomatic API for writing dynamic console applications.
Apache License 2.0
567 stars 16 forks source link

can't write to last row of terminal #103

Closed stephentalley closed 8 months ago

stephentalley commented 9 months ago

A simple attempt at putting "line \<i>" in every row of the terminal:

session {
    section {
        for (i in 0..<height) {
            textLine("line $i")
        }
    }.runUntilKeyPressed(Keys.Q, Keys.ESC) {
    }
}

…unexpectedly results in the terminal contents being scrolled up one line, leaving the last line blank:

screenshot-2023 12 17 14 20 39

I thought maybe the newline in the last line was causing this, so I changed the code to:

session {
    section {
        for (i in 0..<height) {
            if (i == height - 1) {
                text("line $i")
            } else {
                textLine("line $i")
            }
        }
    }.runUntilKeyPressed(Keys.Q, Keys.ESC) {
    }
}

…but the issue remains.

What I expect/am hoping for:

screenshot-2023 12 17 14 37 12

Apologies if I'm just misunderstanding the API, but I was unable to find any documentation or code that addressed this.

Desktop (please complete the following information):

bitspittle commented 8 months ago

Really sorry for not responding to this earlier! I never saw any notification....

Yeah this is working as intended. The idea is that a section is an isolated block of text.

Otherwise this would cause big problems due to how terminal repainting works:

 section { text("bad ") }.run()
 section { text("case ") }.run()
 section { text("example ") }.run()
 var count by liveVarOf(0)
 section {
    text("Count #${count + 1}")
 }.runUntilKeyPressed(ESC) {
    onTimer(100.ms) { ++count }
 }

How could I know where to start repainting from? The terminal APIs are very simple and very limited. All I can do consistently is wipe the whole line.

I hope this helps explain the reasoning behind the API design here.