diff --git a/README.md b/README.md index cf3bb15..2f842da 100644 --- a/README.md +++ b/README.md @@ -158,6 +158,8 @@ The `-w` flag lets you set a maximum width at which the output will be wrapped: glow -w 60 ``` +When `-w` is not provided, Glow will use your terminal's current width when possible. + ### Paging CLI output can be displayed in your preferred pager with the `-p` flag. This defaults diff --git a/main.go b/main.go index b31ca15..91d68af 100644 --- a/main.go +++ b/main.go @@ -164,6 +164,22 @@ func validateStyle(style string) error { return nil } +func resolveWidth(isTerminal bool, configuredWidth uint, widthFlagChanged bool, getTerminalWidth func() (int, error)) uint { + width := configuredWidth + if !widthFlagChanged { + if isTerminal && width == 0 { + w, err := getTerminalWidth() + if err == nil && w > 0 { + width = uint(w) //nolint:gosec + } + } + if width == 0 { + width = 80 + } + } + return width +} + func validateOptions(cmd *cobra.Command) error { // grab config values from Viper width = viper.GetUint("width") @@ -191,22 +207,13 @@ func validateOptions(cmd *cobra.Command) error { style = "notty" } - // Detect terminal width - if !cmd.Flags().Changed("width") { //nolint:nestif - if isTerminal && width == 0 { - w, _, err := term.GetSize(int(os.Stdout.Fd())) - if err == nil { - width = uint(w) //nolint:gosec - } - - if width > 120 { - width = 120 - } + width = resolveWidth(isTerminal, width, cmd.Flags().Changed("width"), func() (int, error) { + w, _, err := term.GetSize(int(os.Stdout.Fd())) + if err != nil { + return 0, err } - if width == 0 { - width = 80 - } - } + return w, nil + }) return nil } diff --git a/main_width_test.go b/main_width_test.go new file mode 100644 index 0000000..5068831 --- /dev/null +++ b/main_width_test.go @@ -0,0 +1,78 @@ +package main + +import ( + "errors" + "testing" +) + +func TestResolveWidth(t *testing.T) { + tt := []struct { + name string + isTerminal bool + configuredWidth uint + flagChanged bool + detectedWidth int + detectErr error + want uint + }{ + { + name: "explicit width keeps configured value", + isTerminal: true, + configuredWidth: 40, + flagChanged: true, + detectedWidth: 180, + want: 40, + }, + { + name: "explicit zero width is preserved", + isTerminal: true, + configuredWidth: 0, + flagChanged: true, + detectedWidth: 180, + want: 0, + }, + { + name: "auto width uses detected terminal width", + isTerminal: true, + configuredWidth: 0, + flagChanged: false, + detectedWidth: 100, + want: 100, + }, + { + name: "auto width no longer caps terminal width", + isTerminal: true, + configuredWidth: 0, + flagChanged: false, + detectedWidth: 180, + want: 180, + }, + { + name: "auto width falls back when detection fails", + isTerminal: true, + configuredWidth: 0, + flagChanged: false, + detectErr: errors.New("boom"), + want: 80, + }, + { + name: "non-tty fallback remains 80", + isTerminal: false, + configuredWidth: 0, + flagChanged: false, + want: 80, + }, + } + + for _, tc := range tt { + t.Run(tc.name, func(t *testing.T) { + got := resolveWidth(tc.isTerminal, tc.configuredWidth, tc.flagChanged, func() (int, error) { + return tc.detectedWidth, tc.detectErr + }) + + if got != tc.want { + t.Fatalf("resolveWidth() = %d, want %d", got, tc.want) + } + }) + } +}