ajalt / mordant

Multiplatform text styling for Kotlin command-line applications
https://ajalt.github.io/mordant/
Apache License 2.0
957 stars 34 forks source link

Progress bar not working correctly? #105

Closed dkim19375 closed 1 year ago

dkim19375 commented 1 year ago

Code:

fun main() {
    val terminal = Terminal(AnsiLevel.TRUECOLOR, interactive = true)

    val progress = terminal.progressAnimation {
        spinner(Spinner.Dots(brightBlue))
        text("my-file.bin")
        percentage()
        progressBar()
        completed()
        speed("B/s")
        timeRemaining()
    }

    progress.start()

    // Sleep for a few seconds to show the indeterminate state
    Thread.sleep(1000)

    // Update the progress as the download progresses
    progress.updateTotal(50)
    repeat(50) {
        progress.advance(1)
        Thread.sleep(100)
    }

    progress.stop()
    terminal.println(brightYellow("Done!"))
}

Results

Colors are all correct

Terminal(AnsiLevel.TRUECOLOR, interactive = true)

In IntelliJ, if I click the green play button next to the fun main(), it gives this output:

   my-file.bin   98%  ━━━━━━━━━━━━━━━━━━━     49.0/50.0     8.3B/s  eta 0:00:00
   my-file.bin   98%  ━━━━━━━━━━━━━━━━━━━     49.0/50.0     8.3B/s  eta 0:00:00Done!

In IntelliJ, if I run gradle run, it gives me this output: https://[bytebin.lucko.me/YYX3ti3hsk](https://bytebin.lucko.me/YYX3ti3hsk) In IntelliJ, if I go into the built-in terminal and run java -jar Program.jar, I get:

   my-file.bin  100%  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━     50.0/50.0     5.5B/s  eta 0:00:00
Done!

In Windows Terminal -> Command Prompt, if I run gradlew.bat run, I get this output:

   my-file.bin   98%  ━━━━━━━━━━━━━━━━━━━     49.0/50.0     7.6B/s  eta 0:00:00
Done!

In Windows Terminal, if I run java -jar Program.jar, I get this output

   my-file.bin   98%  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━     49.0/50.0     8.3B/s  eta 0:00:00
Done!

Default Terminal

In IntelliJ, with the green play button:

   my-file.bin  100%  ━━━━━━━━━━━━━━━━━━━     50.0/50.0     8.3B/s  eta 0:00:00
   my-file.bin  100%  ━━━━━━━━━━━━━━━━━━━     50.0/50.0     8.3B/s  eta 0:00:00Done!

With gradle run, I just get a Done! (as expected from the previous github issue) With java -jar Program.jar, I get

   my-file.bin  100%  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━     50.0/50.0     0.6B/s  eta 0:00:00
Done!

In Windows Terminal, if I run gradlew.bat run, I get a Done! (as expected from the previous github issue) In Windows Terminal, if I run java -jar Program.jar, I get

   my-file.bin  100%  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━     50.0/50.0     8.3B/s  eta 0:00:00
Done!

What am I doing wrong? And why are the results so inconsistent (and not giving expected results)?

dkim19375 commented 1 year ago

Also, wanted to add that \r does work correctly (when creating my own simple progress indicator that just shows how much of the file has been downloaded), so maybe Mordant is missing a \r at the end for some reason?

And the question mark issue might not be related, but still showed it in case you had an idea of why it was happening :)

dkim19375 commented 1 year ago

Fixed the question mark issue

Fixed by setting my Windows locale thing to UTF-8 and so I'll update the results

ajalt commented 1 year ago

So the root of the issue is that IntelliJ's console doesn't support cursor movements. The fix was to stop using them when running in IntelliJ. But since we can't move the cursor, it has to stay on the same line as the progress bar after stop so that clear and update still work.

So you'll have to print the newline yourself if you want to print something after calling stop.

animation.stop()
if (terminal.info.crClearsLine) terminal.println()
terminal.println("Done!")