summaryrefslogtreecommitdiffstats
path: root/cwriter/writer.go
diff options
context:
space:
mode:
Diffstat (limited to 'cwriter/writer.go')
-rw-r--r--cwriter/writer.go59
1 files changed, 59 insertions, 0 deletions
diff --git a/cwriter/writer.go b/cwriter/writer.go
new file mode 100644
index 0000000..23a72d3
--- /dev/null
+++ b/cwriter/writer.go
@@ -0,0 +1,59 @@
+package cwriter
+
+import (
+ "bytes"
+ "errors"
+ "io"
+ "os"
+ "strconv"
+)
+
+// https://github.com/dylanaraps/pure-sh-bible#cursor-movement
+const (
+ escOpen = "\x1b["
+ cuuAndEd = "A\x1b[J"
+)
+
+// ErrNotTTY not a TeleTYpewriter error.
+var ErrNotTTY = errors.New("not a terminal")
+
+// New returns a new Writer with defaults.
+func New(out io.Writer) *Writer {
+ w := &Writer{
+ Buffer: new(bytes.Buffer),
+ out: out,
+ termSize: func(_ int) (int, int, error) {
+ return -1, -1, ErrNotTTY
+ },
+ }
+ if f, ok := out.(*os.File); ok {
+ w.fd = int(f.Fd())
+ if IsTerminal(w.fd) {
+ w.terminal = true
+ w.termSize = func(fd int) (int, int, error) {
+ return GetSize(fd)
+ }
+ }
+ }
+ bb := make([]byte, 16)
+ w.ew = escWriter(bb[:copy(bb, []byte(escOpen))])
+ return w
+}
+
+// IsTerminal tells whether underlying io.Writer is terminal.
+func (w *Writer) IsTerminal() bool {
+ return w.terminal
+}
+
+// GetTermSize returns WxH of underlying terminal.
+func (w *Writer) GetTermSize() (width, height int, err error) {
+ return w.termSize(w.fd)
+}
+
+type escWriter []byte
+
+func (b escWriter) ansiCuuAndEd(out io.Writer, n int) error {
+ b = strconv.AppendInt(b, int64(n), 10)
+ _, err := out.Write(append(b, []byte(cuuAndEd)...))
+ return err
+}