Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[display] Overwrite terminal contents #11695

Merged
merged 4 commits into from Dec 20, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
@@ -0,0 +1,4 @@
changes:
- type: fix
scope: cli/display
description: Fix flickering in the interactive display
24 changes: 24 additions & 0 deletions pkg/backend/display/internal/terminal/info.go
Expand Up @@ -10,9 +10,12 @@ import (
type Info interface {
Parse(attr string, params ...interface{}) (string, error)

ClearEnd(out io.Writer)
ClearLine(out io.Writer)
CursorUp(out io.Writer, count int)
CursorDown(out io.Writer, count int)
HideCursor(out io.Writer)
ShowCursor(out io.Writer)
}

/* Satisfied by gotty.TermInfo as well as noTermInfo from below */
Expand Down Expand Up @@ -56,6 +59,15 @@ func (i info) ClearLine(out io.Writer) {
}
}

func (i info) ClearEnd(out io.Writer) {
// clear line from cursor to end
if attr, err := i.Parse("el"); err == nil {
fmt.Fprintf(out, "%s", attr)
} else {
fmt.Fprintf(out, "\x1b[K")
}
}

func (i info) CursorUp(out io.Writer, count int) {
if count == 0 { // Should never be the case, but be tolerant
return
Expand All @@ -77,3 +89,15 @@ func (i info) CursorDown(out io.Writer, count int) {
fmt.Fprintf(out, "\x1b[%dB", count)
}
}

func (i info) HideCursor(out io.Writer) {
if attr, err := i.Parse("civis"); err == nil {
fmt.Fprintf(out, "%s", attr)
}
}

func (i info) ShowCursor(out io.Writer) {
if attr, err := i.Parse("cnorm"); err == nil {
fmt.Fprintf(out, "%s", attr)
}
}
12 changes: 12 additions & 0 deletions pkg/backend/display/internal/terminal/mock.go
Expand Up @@ -52,6 +52,10 @@ func (t *MockTerminal) ClearLine() {
t.info.ClearLine(t)
}

func (t *MockTerminal) ClearEnd() {
t.info.ClearEnd(t)
}

func (t *MockTerminal) CursorUp(count int) {
t.info.CursorUp(t, count)
}
Expand All @@ -60,6 +64,14 @@ func (t *MockTerminal) CursorDown(count int) {
t.info.CursorDown(t, count)
}

func (t *MockTerminal) HideCursor() {
t.info.HideCursor(t)
}

func (t *MockTerminal) ShowCursor() {
t.info.ShowCursor(t)
}

func (t *MockTerminal) ReadKey() (string, error) {
k, ok := <-t.keys
if !ok {
Expand Down
15 changes: 15 additions & 0 deletions pkg/backend/display/internal/terminal/term.go
Expand Up @@ -18,8 +18,11 @@ type Terminal interface {
Size() (width, height int, err error)

ClearLine()
ClearEnd()
CursorUp(count int)
CursorDown(count int)
HideCursor()
ShowCursor()

ReadKey() (string, error)
}
Expand Down Expand Up @@ -131,6 +134,10 @@ func (t *terminal) ClearLine() {
t.info.ClearLine(t.out)
}

func (t *terminal) ClearEnd() {
t.info.ClearEnd(t.out)
}

func (t *terminal) CursorUp(count int) {
t.info.CursorUp(t.out, count)
}
Expand All @@ -139,6 +146,14 @@ func (t *terminal) CursorDown(count int) {
t.info.CursorDown(t.out, count)
}

func (t *terminal) HideCursor() {
t.info.HideCursor(t.out)
}

func (t *terminal) ShowCursor() {
t.info.ShowCursor(t.out)
}

func (t *terminal) ReadKey() (string, error) {
if t.in == nil {
return "", io.EOF
Expand Down

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

35 changes: 25 additions & 10 deletions pkg/backend/display/tree.go
Expand Up @@ -58,6 +58,7 @@ func newInteractiveRenderer(term terminal.Terminal, opts Options) progressRender
if !term.IsRaw() {
return newInteractiveMessageRenderer(term, opts)
}
term.HideCursor()

r := &treeRenderer{
opts: opts,
Expand All @@ -75,6 +76,7 @@ func newInteractiveRenderer(term terminal.Terminal, opts Options) progressRender
}

func (r *treeRenderer) Close() error {
r.term.ShowCursor()
return r.term.Close()
}

Expand Down Expand Up @@ -110,6 +112,16 @@ func (r *treeRenderer) println(display *ProgressDisplay, text string) {
r.print("\n")
}

func (r *treeRenderer) over(text string) {
r.print(text)
r.term.ClearEnd()
}

func (r *treeRenderer) overln(text string) {
r.over(text)
r.print("\n")
}

func (r *treeRenderer) render(display *ProgressDisplay) {
r.m.Lock()
defer r.m.Unlock()
Expand Down Expand Up @@ -222,7 +234,7 @@ func (r *treeRenderer) frame(locked, done bool) {
}

treeTableHeight = termHeight - systemMessagesHeight - 1
r.maxTreeTableOffset = len(treeTableRows) - treeTableHeight - 1
r.maxTreeTableOffset = len(treeTableRows) - treeTableHeight + 1

treeTableRows = treeTableRows[r.treeTableOffset : r.treeTableOffset+treeTableHeight-1]

Expand All @@ -239,37 +251,40 @@ func (r *treeRenderer) frame(locked, done bool) {
footer := fmt.Sprintf("%smore%s", upArrow, downArrow)
padding := termWidth - uniseg.GraphemeClusterCount(footer)
treeTableFooter = strings.Repeat(" ", padding) + footer

if systemMessagesHeight > 0 {
treeTableFooter += "\n"
}
}

// Re-home the cursor.
r.term.ClearLine()
r.print("\r")
for ; r.rewind > 0; r.rewind-- {
r.term.CursorUp(1)
r.term.ClearLine()
}
r.rewind = totalHeight - 1

// Render the tree table.
r.println(nil, r.clampLine(treeTableHeader, termWidth))
r.overln(r.clampLine(treeTableHeader, termWidth))
for _, row := range treeTableRows {
r.println(nil, r.clampLine(row, termWidth))
r.overln(r.clampLine(row, termWidth))
}
if treeTableFooter != "" {
r.print(treeTableFooter)
r.over(treeTableFooter)
}

// Render the system messages.
if systemMessagesHeight > 0 {
r.println(nil, "")
r.println(nil, colors.Yellow+"System Messages"+colors.Reset)
r.overln("")
r.overln(colors.Yellow + "System Messages" + colors.Reset)

for _, line := range systemMessages {
r.println(nil, " "+line)
r.overln(" " + line)
}
}

if done && totalHeight > 0 {
r.println(nil, "")
r.overln("")
}
}

Expand Down