summaryrefslogtreecommitdiff
path: root/vendor/github.com/manifoldco/promptui/screenbuf/screenbuf.go
diff options
context:
space:
mode:
authorOpenShift Merge Robot <openshift-merge-robot@users.noreply.github.com>2020-11-13 18:28:17 +0100
committerGitHub <noreply@github.com>2020-11-13 18:28:17 +0100
commit738d62ea960af439bd545820e1853cbd73464493 (patch)
tree61a859c039565897f865db052ad7c3bee8b03bfb /vendor/github.com/manifoldco/promptui/screenbuf/screenbuf.go
parent2993e97dec9d998d2eca7c5aee918b1429596a85 (diff)
parent8e4a42aa429c6dec0d5face7c69554d8a0677e96 (diff)
downloadpodman-738d62ea960af439bd545820e1853cbd73464493.tar.gz
podman-738d62ea960af439bd545820e1853cbd73464493.tar.bz2
podman-738d62ea960af439bd545820e1853cbd73464493.zip
Merge pull request #7964 from vrothberg/shortnames
short-name aliasing
Diffstat (limited to 'vendor/github.com/manifoldco/promptui/screenbuf/screenbuf.go')
-rw-r--r--vendor/github.com/manifoldco/promptui/screenbuf/screenbuf.go151
1 files changed, 151 insertions, 0 deletions
diff --git a/vendor/github.com/manifoldco/promptui/screenbuf/screenbuf.go b/vendor/github.com/manifoldco/promptui/screenbuf/screenbuf.go
new file mode 100644
index 000000000..861390045
--- /dev/null
+++ b/vendor/github.com/manifoldco/promptui/screenbuf/screenbuf.go
@@ -0,0 +1,151 @@
+package screenbuf
+
+import (
+ "bytes"
+ "fmt"
+ "io"
+)
+
+const esc = "\033["
+
+var (
+ clearLine = []byte(esc + "2K\r")
+ moveUp = []byte(esc + "1A")
+ moveDown = []byte(esc + "1B")
+)
+
+// ScreenBuf is a convenient way to write to terminal screens. It creates,
+// clears and, moves up or down lines as needed to write the output to the
+// terminal using ANSI escape codes.
+type ScreenBuf struct {
+ w io.Writer
+ buf *bytes.Buffer
+ reset bool
+ cursor int
+ height int
+}
+
+// New creates and initializes a new ScreenBuf.
+func New(w io.Writer) *ScreenBuf {
+ return &ScreenBuf{buf: &bytes.Buffer{}, w: w}
+}
+
+// Reset truncates the underlining buffer and marks all its previous lines to be
+// cleared during the next Write.
+func (s *ScreenBuf) Reset() {
+ s.buf.Reset()
+ s.reset = true
+}
+
+// Clear clears all previous lines and the output starts from the top.
+func (s *ScreenBuf) Clear() error {
+ for i := 0; i < s.height; i++ {
+ _, err := s.buf.Write(moveUp)
+ if err != nil {
+ return err
+ }
+ _, err = s.buf.Write(clearLine)
+ if err != nil {
+ return err
+ }
+ }
+ s.cursor = 0
+ s.height = 0
+ s.reset = false
+ return nil
+}
+
+// Write writes a single line to the underlining buffer. If the ScreenBuf was
+// previously reset, all previous lines are cleared and the output starts from
+// the top. Lines with \r or \n will cause an error since they can interfere with the
+// terminal ability to move between lines.
+func (s *ScreenBuf) Write(b []byte) (int, error) {
+ if bytes.ContainsAny(b, "\r\n") {
+ return 0, fmt.Errorf("%q should not contain either \\r or \\n", b)
+ }
+
+ if s.reset {
+ if err := s.Clear(); err != nil {
+ return 0, err
+ }
+ }
+
+ switch {
+ case s.cursor == s.height:
+ n, err := s.buf.Write(clearLine)
+ if err != nil {
+ return n, err
+ }
+
+ n, err = s.buf.Write(b)
+ if err != nil {
+ return n, err
+ }
+
+ _, err = s.buf.Write([]byte("\n"))
+ if err != nil {
+ return n, err
+ }
+
+ s.height++
+ s.cursor++
+ return n, nil
+ case s.cursor < s.height:
+ n, err := s.buf.Write(clearLine)
+ if err != nil {
+ return n, err
+ }
+ n, err = s.buf.Write(b)
+ if err != nil {
+ return n, err
+ }
+ n, err = s.buf.Write(moveDown)
+ if err != nil {
+ return n, err
+ }
+ s.cursor++
+ return n, nil
+ default:
+ return 0, fmt.Errorf("Invalid write cursor position (%d) exceeded line height: %d", s.cursor, s.height)
+ }
+}
+
+// Flush writes any buffered data to the underlying io.Writer, ensuring that any pending data is displayed.
+func (s *ScreenBuf) Flush() error {
+ for i := s.cursor; i < s.height; i++ {
+ if i < s.height {
+ _, err := s.buf.Write(clearLine)
+ if err != nil {
+ return err
+ }
+ }
+ _, err := s.buf.Write(moveDown)
+ if err != nil {
+ return err
+ }
+ }
+
+ _, err := s.buf.WriteTo(s.w)
+ if err != nil {
+ return err
+ }
+
+ s.buf.Reset()
+
+ for i := 0; i < s.height; i++ {
+ _, err := s.buf.Write(moveUp)
+ if err != nil {
+ return err
+ }
+ }
+
+ s.cursor = 0
+
+ return nil
+}
+
+// WriteString is a convenient function to write a new line passing a string.
+// Check ScreenBuf.Write() for a detailed explanation of the function behaviour.
+func (s *ScreenBuf) WriteString(str string) (int, error) {
+ return s.Write([]byte(str))
+}