func (s *StatusChart) lengthOfOutput() int { ts, err := ttyutils.Winsize(os.Stdout) if err != nil { // This can happen when the output is redirected to a device // that blows up on the ioctl Winsize uses. We don't care about fancy drawing in this case. return 0 } width := int(ts.Columns) if width == 0 { // output has been redirected return 0 } lines := strings.Split(s.extraOutput, "\n") numLines := 0 for _, line := range lines { n := (len(line) + width - 1) / width if n == 0 { n = 1 } numLines += n } return numLines - 1 }
// SetupRawTerminal will set terminal to RAW mode and return function to // restore normal terminal. func SetupRawTerminal(setSize func(cols, row uint16) error) func() { // Switch terminal to raw mode state, err := ttyutils.MakeTerminalRaw(os.Stdout.Fd()) if err != nil { // If we can't do it just continue as we were return func() {} } // Get TTY size size, err := ttyutils.Winsize(os.Stdout) if err == nil && setSize != nil { setSize(size.Columns, size.Lines) } // Handle SIGWINCH signals (window resize signals from graphical terminals) sigWinch := make(chan os.Signal, 1) signal.Notify(sigWinch, syscall.SIGWINCH) go func() { for range sigWinch { size, err := ttyutils.Winsize(os.Stdout) if err == nil && setSize != nil { setSize(size.Columns, size.Lines) } } }() // Return a function to cleanup return func() { // Stop handling SIGWINCH, and close channel to clean up go routine signal.Stop(sigWinch) close(sigWinch) // Restore terminal state ttyutils.RestoreTerminalState(os.Stdout.Fd(), state) fmt.Println("") } }
func TestWinSize(t *testing.T) { mpty, mtty, err := pty.Open() if err != nil { t.Fatal(err) } defer mtty.Close() defer mpty.Close() size, err := ttyutils.Winsize(mtty) if err != nil { t.Fatal(err) } if !reflect.DeepEqual(size, ttyutils.Ttysize{Lines: 0, Columns: 0}) { t.Errorf("expected 0x0 terminal, got %#v", size) } }
func (s *StatusChart) lengthOfOutput() int { ts, err := ttyutils.Winsize(os.Stdout) if err != nil { slog.Error(err) } width := int(ts.Columns) lines := strings.Split(s.extraOutput, "\n") numLines := 0 for _, line := range lines { n := (len(line) + width - 1) / width if n == 0 { n = 1 } numLines += n } return numLines - 1 }