tty-spinner
tty-spinner copied to clipboard
Spinner breaks into multiple lines in a small terminal window
Great gem, love it.
Only problem is that when the terminal window is smaller than the spinner label, the spinner starts printing out on separate lines, instead of redrawing the same line:
s = TTY::Spinner.new('[:spinner] This text is longer than the terminal window and it breaks the spinner')
s.run { sleep 3 }
output on a narrow terminal window:
[|] This text is longer than the terminal window and it breaks the
[/] This text is longer than the terminal window and it breaks the
[-] This text is longer than the terminal window and it breaks the
[\] This text is longer than the terminal window and it breaks the
[|] This text is longer than the terminal window and it breaks the
[/] This text is longer than the terminal window and it breaks the
Hi Vlad,
Thanks for using the gem!
This is not surprising behaviour given how tty-spinner works; it only clears the current terminal line it is displayed on. By default, a terminal console shrinkwraps content when it overflows the terminal width. For example, let's say we have a very long string that wraps on 7 terminal lines. This will place the current cursor position down 7 lines below where it originally started. So the spinner clears output from the 7th line only and displays another frame of animation. What you're saying is that you would expect the spinner to figure out this and trackback 7 console lines up and repaint itself.
Let's say I implement a solution in this library to tackle this problem. This would require the use of tty-screen dependency to measure terminal width. The thing is, this would convolute the implementation a bit more and introduce an extra dependency. This gem has been around for few years and is dependent on by many libraries. I'm kind of reluctant to introduce this as it doesn't appear to be a common problem. Welcome to the maintainer's world of managing complexity! I need to think about it....
In the meantime, here is a quick example with multiline text to help you out:
text = <<-TEXT
for there is no folly of the beast
of the earth which
is not infinitely
outdone by the madness of men
TEXT
spinner = TTY::Spinner.new("[:spinner] :text")
20.times do
spinner.spin
spinner.update(text: text)
sleep(0.2)
print TTY::Cursor.clear_lines(text.lines.size + 1, :up)
end