github.com/myhau/pulumi/pkg/v3@v3.70.2-0.20221116134521-f2775972e587/backend/display/internal/terminal/info.go (about)

     1  package terminal
     2  
     3  import (
     4  	"fmt"
     5  	"io"
     6  
     7  	gotty "github.com/ijc/Gotty"
     8  )
     9  
    10  type Info interface {
    11  	Parse(attr string, params ...interface{}) (string, error)
    12  
    13  	ClearLine(out io.Writer)
    14  	CursorUp(out io.Writer, count int)
    15  	CursorDown(out io.Writer, count int)
    16  }
    17  
    18  /* Satisfied by gotty.TermInfo as well as noTermInfo from below */
    19  type termInfo interface {
    20  	Parse(attr string, params ...interface{}) (string, error)
    21  }
    22  
    23  type noTermInfo int // canary used when no terminfo.
    24  
    25  func (ti noTermInfo) Parse(attr string, params ...interface{}) (string, error) {
    26  	return "", fmt.Errorf("noTermInfo")
    27  }
    28  
    29  type info struct {
    30  	termInfo
    31  }
    32  
    33  var _ = Info(info{})
    34  
    35  func OpenInfo(terminal string) Info {
    36  	if i, err := gotty.OpenTermInfo(terminal); err == nil {
    37  		return info{i}
    38  	}
    39  	return info{noTermInfo(0)}
    40  }
    41  
    42  func (i info) ClearLine(out io.Writer) {
    43  	// el2 (clear whole line) is not exposed by terminfo.
    44  
    45  	// First clear line from beginning to cursor
    46  	if attr, err := i.Parse("el1"); err == nil {
    47  		fmt.Fprintf(out, "%s", attr)
    48  	} else {
    49  		fmt.Fprintf(out, "\x1b[1K")
    50  	}
    51  	// Then clear line from cursor to end
    52  	if attr, err := i.Parse("el"); err == nil {
    53  		fmt.Fprintf(out, "%s", attr)
    54  	} else {
    55  		fmt.Fprintf(out, "\x1b[K")
    56  	}
    57  }
    58  
    59  func (i info) CursorUp(out io.Writer, count int) {
    60  	if count == 0 { // Should never be the case, but be tolerant
    61  		return
    62  	}
    63  	if attr, err := i.Parse("cuu", count); err == nil {
    64  		fmt.Fprintf(out, "%s", attr)
    65  	} else {
    66  		fmt.Fprintf(out, "\x1b[%dA", count)
    67  	}
    68  }
    69  
    70  func (i info) CursorDown(out io.Writer, count int) {
    71  	if count == 0 { // Should never be the case, but be tolerant
    72  		return
    73  	}
    74  	if attr, err := i.Parse("cud", count); err == nil {
    75  		fmt.Fprintf(out, "%s", attr)
    76  	} else {
    77  		fmt.Fprintf(out, "\x1b[%dB", count)
    78  	}
    79  }