diff --git a/cwriter/util_bsd.go b/cwriter/util_bsd.go new file mode 100644 index 0000000..4e3564e --- /dev/null +++ b/cwriter/util_bsd.go @@ -0,0 +1,7 @@ +// +build darwin dragonfly freebsd netbsd openbsd + +package cwriter + +import "golang.org/x/sys/unix" + +const ioctlReadTermios = unix.TIOCGETA diff --git a/cwriter/util_linux.go b/cwriter/util_linux.go new file mode 100644 index 0000000..253f12d --- /dev/null +++ b/cwriter/util_linux.go @@ -0,0 +1,7 @@ +// +build aix linux + +package cwriter + +import "golang.org/x/sys/unix" + +const ioctlReadTermios = unix.TCGETS diff --git a/cwriter/util_solaris.go b/cwriter/util_solaris.go new file mode 100644 index 0000000..4b29ff5 --- /dev/null +++ b/cwriter/util_solaris.go @@ -0,0 +1,7 @@ +// +build solaris + +package cwriter + +import "golang.org/x/sys/unix" + +const ioctlReadTermios = unix.TCGETA diff --git a/cwriter/writer.go b/cwriter/writer.go index 7d15717..6f57875 100644 --- a/cwriter/writer.go +++ b/cwriter/writer.go @@ -6,8 +6,6 @@ "io" "os" "strconv" - - "github.com/mattn/go-isatty" ) // NotATTY not a TeleTYpewriter error. @@ -25,7 +23,7 @@ out io.Writer buf bytes.Buffer lineCount int - fd uintptr + fd int isTerminal bool } @@ -33,8 +31,8 @@ func New(out io.Writer) *Writer { w := &Writer{out: out} if f, ok := out.(*os.File); ok { - w.fd = f.Fd() - w.isTerminal = isatty.IsTerminal(w.fd) + w.fd = int(f.Fd()) + w.isTerminal = IsTerminal(w.fd) } return w } diff --git a/cwriter/writer_posix.go b/cwriter/writer_posix.go index da4b215..f54a5d0 100644 --- a/cwriter/writer_posix.go +++ b/cwriter/writer_posix.go @@ -11,10 +11,16 @@ } // GetSize returns the dimensions of the given terminal. -func GetSize(fd uintptr) (width, height int, err error) { - ws, err := unix.IoctlGetWinsize(int(fd), unix.TIOCGWINSZ) +func GetSize(fd int) (width, height int, err error) { + ws, err := unix.IoctlGetWinsize(fd, unix.TIOCGWINSZ) if err != nil { return -1, -1, err } return int(ws.Col), int(ws.Row), nil } + +// IsTerminal returns whether the given file descriptor is a terminal. +func IsTerminal(fd int) bool { + _, err := unix.IoctlGetTermios(fd, ioctlReadTermios) + return err == nil +} diff --git a/cwriter/writer_windows.go b/cwriter/writer_windows.go index c04754b..1a69c81 100644 --- a/cwriter/writer_windows.go +++ b/cwriter/writer_windows.go @@ -5,7 +5,6 @@ import ( "unsafe" - "github.com/mattn/go-isatty" "golang.org/x/sys/windows" ) @@ -17,7 +16,8 @@ ) func (w *Writer) clearLines() error { - if !w.isTerminal && isatty.IsCygwinTerminal(w.fd) { + if !w.isTerminal { + // hope it's cygwin or similar return w.ansiCuuAndEd() } @@ -31,7 +31,7 @@ info.CursorPosition.Y = 0 } _, _, _ = procSetConsoleCursorPosition.Call( - w.fd, + uintptr(w.fd), uintptr(uint32(uint16(info.CursorPosition.Y))<<16|uint32(uint16(info.CursorPosition.X))), ) @@ -42,7 +42,7 @@ } count := uint32(info.Size.X) * uint32(w.lineCount) _, _, _ = procFillConsoleOutputCharacter.Call( - w.fd, + uintptr(w.fd), uintptr(' '), uintptr(count), *(*uintptr)(unsafe.Pointer(cursor)), @@ -54,7 +54,7 @@ // GetSize returns the visible dimensions of the given terminal. // // These dimensions don't include any scrollback buffer height. -func GetSize(fd uintptr) (width, height int, err error) { +func GetSize(fd int) (width, height int, err error) { var info windows.ConsoleScreenBufferInfo if err := windows.GetConsoleScreenBufferInfo(windows.Handle(fd), &info); err != nil { return 0, 0, err @@ -64,3 +64,10 @@ // but looks like this is a root cause of issue #66, so removing both "+ 1" have fixed it. return int(info.Window.Right - info.Window.Left), int(info.Window.Bottom - info.Window.Top), nil } + +// IsTerminal returns whether the given file descriptor is a terminal. +func IsTerminal(fd int) bool { + var st uint32 + err := windows.GetConsoleMode(windows.Handle(fd), &st) + return err == nil +}