Skip to content

Instantly share code, notes, and snippets.

@umutbasal
Last active May 8, 2022 02:45
Show Gist options
  • Save umutbasal/407e871b3ceb18a49acee9760ff2a23c to your computer and use it in GitHub Desktop.
Save umutbasal/407e871b3ceb18a49acee9760ff2a23c to your computer and use it in GitHub Desktop.
prefixing with tty colors
package main
import (
"io"
"log"
"os"
"os/exec"
"os/signal"
"syscall"
"bufio"
"github.com/creack/pty"
"golang.org/x/term"
)
// https://github.com/goware/prefixer
// https://github.com/creack/pty
var prefix = []byte("prefix: ")
type Reader struct {
reader *bufio.Reader
unread []byte
eof bool
}
func (r *Reader) Read(p []byte) (n int, err error) {
for {
if len(r.unread) > 0 {
m := copy(p[n:], r.unread)
n += m
r.unread = r.unread[m:]
if len(r.unread) > 0 {
return n, nil
}
}
if r.eof {
return n, io.EOF
}
r.unread, err = r.reader.ReadBytes('\n')
if err == io.EOF {
r.eof = true
}
if len(r.unread) == 0 {
return n, err
}
r.unread = append(prefix, r.unread...)
if err != nil {
if err == io.EOF && len(r.unread) > 0 {
return n, nil
}
return n, err
}
}
}
func (r *Reader) WriteTo(w io.Writer) (n int64, err error) {
for {
if len(r.unread) > 0 {
m, err := w.Write(r.unread)
n += int64(m)
if err != nil {
return n, err
}
r.unread = r.unread[m:]
if len(r.unread) > 0 {
return n, nil
}
}
if r.eof {
return n, io.EOF
}
r.unread, err = r.reader.ReadBytes('\n')
if err == io.EOF {
r.eof = true
}
if len(r.unread) == 0 {
return n, err
}
r.unread = append(prefix, r.unread...)
if err != nil {
if err == io.EOF && len(r.unread) > 0 {
return n, nil
}
return n, err
}
}
}
func main() {
c := exec.Command("bat", "main.go")
ptmx, err := pty.Start(c)
if err != nil {
log.Fatal(err)
}
defer func() { _ = ptmx.Close() }()
ch := make(chan os.Signal, 1)
signal.Notify(ch, syscall.SIGWINCH)
go func() {
for range ch {
if err := pty.InheritSize(os.Stdin, ptmx); err != nil {
log.Printf("error resizing pty: %s", err)
}
}
}()
ch <- syscall.SIGWINCH
defer func() { signal.Stop(ch); close(ch) }()
oldState, err := term.MakeRaw(int(os.Stdin.Fd()))
if err != nil {
panic(err)
}
defer func() { _ = term.Restore(int(os.Stdin.Fd()), oldState) }()
go func() { _, _ = io.Copy(ptmx, os.Stdin) }()
prefixReader := Reader{
reader: bufio.NewReader(ptmx),
}
_, _ = io.Copy(os.Stdout, &prefixReader)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment