@@ -2,6 +2,7 @@ package iostreams
22
33import (
44 "bytes"
5+ "errors"
56 "fmt"
67 "io"
78 "io/ioutil"
@@ -40,6 +41,8 @@ type IOStreams struct {
4041 stdoutIsTTY bool
4142 stderrTTYOverride bool
4243 stderrIsTTY bool
44+ termWidthOverride int
45+ ttySize func () (int , int , error )
4346
4447 pagerCommand string
4548 pagerProcess * os.Process
@@ -232,6 +235,10 @@ func (s *IOStreams) StopProgressIndicator() {
232235}
233236
234237func (s * IOStreams ) TerminalWidth () int {
238+ if s .termWidthOverride > 0 {
239+ return s .termWidthOverride
240+ }
241+
235242 defaultWidth := 80
236243 out := s .Out
237244 if s .originalOut != nil {
@@ -259,6 +266,28 @@ func (s *IOStreams) TerminalWidth() int {
259266 return defaultWidth
260267}
261268
269+ func (s * IOStreams ) ForceTerminal (spec string ) {
270+ s .colorEnabled = ! EnvColorDisabled ()
271+ s .SetStdoutTTY (true )
272+
273+ if w , err := strconv .Atoi (spec ); err == nil {
274+ s .termWidthOverride = w
275+ return
276+ }
277+
278+ ttyWidth , _ , err := s .ttySize ()
279+ if err != nil {
280+ return
281+ }
282+ s .termWidthOverride = ttyWidth
283+
284+ if strings .HasSuffix (spec , "%" ) {
285+ if p , err := strconv .Atoi (spec [:len (spec )- 1 ]); err == nil {
286+ s .termWidthOverride = int (float64 (s .termWidthOverride ) * (float64 (p ) / 100 ))
287+ }
288+ }
289+ }
290+
262291func (s * IOStreams ) ColorScheme () * ColorScheme {
263292 return NewColorScheme (s .ColorEnabled (), s .ColorSupport256 ())
264293}
@@ -297,6 +326,7 @@ func System() *IOStreams {
297326 colorEnabled : EnvColorForced () || (! EnvColorDisabled () && stdoutIsTTY ),
298327 is256enabled : Is256ColorSupported (),
299328 pagerCommand : os .Getenv ("PAGER" ),
329+ ttySize : ttySize ,
300330 }
301331
302332 if stdoutIsTTY && stderrIsTTY {
@@ -317,6 +347,9 @@ func Test() (*IOStreams, *bytes.Buffer, *bytes.Buffer, *bytes.Buffer) {
317347 In : ioutil .NopCloser (in ),
318348 Out : out ,
319349 ErrOut : errOut ,
350+ ttySize : func () (int , int , error ) {
351+ return - 1 , - 1 , errors .New ("ttySize not implemented in tests" )
352+ },
320353 }, in , out , errOut
321354}
322355
@@ -331,6 +364,7 @@ func isCygwinTerminal(w io.Writer) bool {
331364 return false
332365}
333366
367+ // terminalSize measures the viewport of the terminal that the output stream is connected to
334368func terminalSize (w io.Writer ) (int , int , error ) {
335369 if f , isFile := w .(* os.File ); isFile {
336370 return term .GetSize (int (f .Fd ()))
0 commit comments