【发布时间】:2021-10-18 22:23:23
【问题描述】:
背景
我正在尝试编写一个用于创建终端任务列表的 Go 库,灵感来自 Node 库 listr。
我的库 golist 在后台 goroutine 中打印任务列表,并使用 ANSI 转义序列更新文本和状态字符。
问题
存在一个问题,即列表的最终打印偶尔会包含额外的空格,从而导致出现一些空格或重复行。这里有两个例子——一个正确,一个不正确——都来自完全相同的代码(here's a link to the code)的运行。
示例
这是一个应该是什么样子的示例:
(Here's a gist of the raw text output for the correct output)
下面是它有时看起来的示例:
(Here's a gist of the raw text output for the incorrect output)
如果您查看lines 184 and 185 in the gist of the incorrect version,有两个空白行不在正确的版本中。
为什么会发生这种情况,为什么只会发生有时?
代码
我在以下循环中将列表打印到终端:
go func() {
defer donePrinting() // Tell the Stop function that we're done printing
ts := l.getTaskStates()
l.print(ts)
for {
select {
case <-ctx.Done(): // Check if the print loop should stop
// Perform a final clear and an optional print depending on `ClearOnComplete`
ts := l.getTaskStates()
if l.ClearOnComplete {
l.clear(ts)
return
}
l.clearThenPrint(ts)
return
case s := <-l.printQ: // Check if there's a message to print
fmt.Fprintln(l.Writer, s)
default: // Otherwise, print the list
ts := l.getTaskStates()
l.clearThenPrint(ts)
l.StatusIndicator.Next()
time.Sleep(l.Delay)
}
}
}()
列表被格式化为字符串,然后打印。以下函数格式化字符串:
// fmtPrint returns the formatted list of messages
// and statuses, using the supplied TaskStates
func (l *List) fmtPrint(ts []*TaskState) string {
s := make([]string, 0)
for _, t := range ts {
s = append(s, l.formatMessage(t))
}
return strings.Join(s, "\n")
}
下面的函数构建 ANSI 转义字符串以清除行:
// fmtClear returns a string of ANSI escape characters
// to clear the `n` lines previously printed.
func (l *List) fmtClear(n int) string {
s := "\033[1A" // Move up a line
s += "\033[K" // Clear the line
s += "\r" // Move back to the beginning of the line
return strings.Repeat(s, n)
}
我使用this site 作为 ANSI 代码的参考。
提前感谢您对为什么会发生这种情况的任何建议!
如果有任何其他可以提供帮助的信息,请告诉我。
【问题讨论】:
标签: go terminal command-line-interface goroutine cursor-position