...
1
16
17 package term
18
19 import (
20 "errors"
21 "io"
22 "os"
23
24 wordwrap "github.com/mitchellh/go-wordwrap"
25 "github.com/moby/term"
26
27 "k8s.io/client-go/tools/remotecommand"
28 )
29
30 type wordWrapWriter struct {
31 limit uint
32 writer io.Writer
33 }
34
35
36
37
38
39
40
41
42
43
44
45 func NewResponsiveWriter(w io.Writer) io.Writer {
46 file, ok := w.(*os.File)
47 if !ok {
48 return w
49 }
50 fd := file.Fd()
51 if !term.IsTerminal(fd) {
52 return w
53 }
54
55 terminalSize := GetSize(fd)
56 if terminalSize == nil {
57 return w
58 }
59 limit := getTerminalLimitWidth(terminalSize)
60
61 return NewWordWrapWriter(w, limit)
62 }
63
64
65
66 func NewWordWrapWriter(w io.Writer, limit uint) io.Writer {
67 return &wordWrapWriter{
68 limit: limit,
69 writer: w,
70 }
71 }
72
73 func getTerminalLimitWidth(terminalSize *remotecommand.TerminalSize) uint {
74 var limit uint
75 switch {
76 case terminalSize.Width >= 120:
77 limit = 120
78 case terminalSize.Width >= 100:
79 limit = 100
80 case terminalSize.Width >= 80:
81 limit = 80
82 }
83 return limit
84 }
85
86 func GetWordWrapperLimit() (uint, error) {
87 stdout := os.Stdout
88 fd := stdout.Fd()
89 if !term.IsTerminal(fd) {
90 return 0, errors.New("file descriptor is not a terminal")
91 }
92 terminalSize := GetSize(fd)
93 if terminalSize == nil {
94 return 0, errors.New("terminal size is nil")
95 }
96 return getTerminalLimitWidth(terminalSize), nil
97 }
98
99 func (w wordWrapWriter) Write(p []byte) (nn int, err error) {
100 if w.limit == 0 {
101 return w.writer.Write(p)
102 }
103 original := string(p)
104 wrapped := wordwrap.WrapString(original, w.limit)
105 return w.writer.Write([]byte(wrapped))
106 }
107
108
109 func NewPunchCardWriter(w io.Writer) io.Writer {
110 return NewWordWrapWriter(w, 80)
111 }
112
113 type maxWidthWriter struct {
114 maxWidth uint
115 currentWidth uint
116 written uint
117 writer io.Writer
118 }
119
120
121
122 func NewMaxWidthWriter(w io.Writer, maxWidth uint) io.Writer {
123 return &maxWidthWriter{
124 maxWidth: maxWidth,
125 writer: w,
126 }
127 }
128
129 func (m maxWidthWriter) Write(p []byte) (nn int, err error) {
130 for _, b := range p {
131 if m.currentWidth == m.maxWidth {
132 m.writer.Write([]byte{'\n'})
133 m.currentWidth = 0
134 }
135 if b == '\n' {
136 m.currentWidth = 0
137 }
138 _, err := m.writer.Write([]byte{b})
139 if err != nil {
140 return int(m.written), err
141 }
142 m.written++
143 m.currentWidth++
144 }
145 return len(p), nil
146 }
147
View as plain text