将就地更新的多行文本与控制台中的可滚动行混合(进度条)

Mixing multiple lines of text updated in place with scrollable lines in console (progress bar)

提问人:MrVocabulary 提问时间:11/3/2023 最后编辑:MrVocabulary 更新时间:11/6/2023 访问量:49

问:

我正在尝试实现我自己的进度条解决方案(用于学习和定制目的),但我被卡住了。

期望的行为:我想更新任意数量的行以粘在控制台底部并不断更新它们,但我无法可靠地超过一行并保持其他消息滚动而不出现非典型终端行为(溢出、滚动方向错误或就地更新)。问题本质上是将粘性行(即就地更新)与可滚动行分开设置。

下面是最小的几乎有效的示例(但为了简单起见没有进度条),但它复制了最上面的粘性行:

require 'io/console'

# This function overwrites the two bottom lines and clears the lines before writing.
def overwrite_bottom_two_lines(iteration)
  rows, columns = IO.console.winsize

  # Move to the second-last line and clear it before writing
  print "\e[#{rows - 1};1H\e[2K"
  puts "Sticky line 1: iteration #{iteration}"

  # Move to the last line and clear it before writing
  print "\e[#{rows};1H\e[2K"
  puts "Sticky line 2: iteration #{iteration}"
end

# Clears the terminal
print "\e[2J"

# Initialize the bottom two lines
overwrite_bottom_two_lines(0)

# Start the iterations
20.times do |iteration|
  # Go back up to right above the bottom two lines and clear the line before writing
  rows, columns = IO.console.winsize
  print "\e[#{rows - 3};1H\e[2K"
  puts "iteration: #{iteration}"

  # Overwrite the bottom two lines
  overwrite_bottom_two_lines(iteration)

  # Sleep for demonstration purposes
  sleep(1)
end

如何避免此处出现重复的粘滞行错误?

Ruby 进度

评论

2赞 Mike Szyndel 11/3/2023
不是那个人,但这不是一个最小的可重复的例子
0赞 MrVocabulary 11/3/2023
我@MikeSzyndel更新了缺少测试场景的第一个代码片段,除非您指的是其他部分?这些都应该是独立的。
1赞 Mike Szyndel 11/3/2023
您发布了超过 300 行代码(令人眼花缭乱)。这还不是最低限度的。您不是在提出一个特定的问题,而是在寻找代码审查。
1赞 anothermh 11/4/2023
@MikeSzyndel是对的。我实际上并没有对这篇文章投反对票(因为你似乎在认真寻求答案),但我建议阅读 idownvotedbecau.se 以更好地理解批评。
1赞 anothermh 11/4/2023
提出问题的一个好方法是:我想完成单一而特定的任务 A,我编写了这个特定的代码 B,但是当特定事件 C 发生时,我得到了确切的响应 X,而我期望得到响应 D。如何使 C 返回 D 而不是 X?但像这样的问题往往很难回答:我想实现多个广泛的目标。我已经完成了应用程序 N,但它并没有真正起作用。我已经完成了应用程序 O,这是一个完全重写,但并没有以其他方式真正工作。然后我有不完整的应用程序 P,可以做其他事情。我的多重目标的解决方案是什么?

答: 暂无答案