Skip to content

Commit

Permalink
Take terminal width and auto-wrapping into account
Browse files Browse the repository at this point in the history
... when doing "repaint the active block" calculations.

Bug #34
  • Loading branch information
bitspittle committed Sep 13, 2021
1 parent e9b2a23 commit b69ffdc
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -101,12 +101,24 @@ class KonsoleBlock internal constructor(val app: KonsoleApp, private val block:

val clearBlockCommand = buildString {
if (!renderer.textArea.isEmpty()) {
// Note: Terminals auto-wrap lines, which is nice for the user but screws up our "erase the lines"
// calculations. We make a best effort to figure out where extra newlines would be added, here,
// although note that if the user keeps resizing their terminal while our app is running, it seems
// like the width value we get doesn't update. See also: bug #34
val extraNumLines = renderer.textArea.toRawText()
.split("\n")
// The line gets an implicit newline once it goes ONE over the terminal width - or in other
// words, a 20 character line fits perfectly in a 20 column terminal, so don't treat that case
// as an extra newline
.sumOf { line -> (line.length - 1) / app.terminal.width }
val totalNumLines = renderer.textArea.numLines + extraNumLines

// To clear an existing block of 'n' lines, completely delete all but one of them, and then delete the
// last one down to the beginning (in other words, don't consume the \n of the previous line)
for (i in 0 until renderer.textArea.numLines) {
for (i in 0 until totalNumLines) {
append('\r')
append(Ansi.Csi.Codes.Erase.CURSOR_TO_LINE_END.toFullEscapeCode())
if (i < renderer.textArea.numLines - 1) {
if (i < totalNumLines - 1) {
append(Ansi.Csi.Codes.Cursor.MOVE_TO_PREV_LINE.toFullEscapeCode())
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import kotlinx.coroutines.flow.Flow
* An interface for abstracting input and output for various terminal implementations.
*/
interface Terminal : AutoCloseable {
val width: Int get() = Int.MAX_VALUE
fun write(text: String)
fun read(): Flow<Int>
}
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ class SystemTerminal : Terminal {
puts(InfoCmp.Capability.cursor_invisible)
}

override val width: Int
get() = terminal.width

override fun write(text: String) {
terminal.writer().print(text)
terminal.writer().flush()
Expand Down

0 comments on commit b69ffdc

Please sign in to comment.