mirror of
https://github.com/charmbracelet/glow.git
synced 2026-08-21 15:44:17 +02:00
fix: use /dev/tty for width autodetect; default config width: 0
This commit is contained in:
parent
53788271b3
commit
ec374d7d06
3 changed files with 69 additions and 6 deletions
|
|
@ -19,8 +19,8 @@ style: "auto"
|
|||
mouse: false
|
||||
# use pager to display markdown
|
||||
pager: false
|
||||
# word-wrap at width
|
||||
width: 80
|
||||
# word-wrap at width (0 = autodetect terminal width)
|
||||
width: 0
|
||||
# show all files, including hidden and ignored.
|
||||
all: false
|
||||
`
|
||||
|
|
|
|||
37
glow_test.go
37
glow_test.go
|
|
@ -1,6 +1,7 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
|
|
@ -39,3 +40,39 @@ func TestGlowFlags(t *testing.T) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TestTerminalWidthFromFdRejectsPipe ensures that a pipe (the canonical
|
||||
// non-tty fd type) is reported as "not a terminal" rather than e.g.
|
||||
// returning a stale or zero width as success. This is the regression we
|
||||
// care about for `glow x.md | less`: the pager's pipe must not be
|
||||
// mistaken for a terminal.
|
||||
func TestTerminalWidthFromFdRejectsPipe(t *testing.T) {
|
||||
r, w, err := os.Pipe()
|
||||
if err != nil {
|
||||
t.Fatalf("os.Pipe: %v", err)
|
||||
}
|
||||
t.Cleanup(func() {
|
||||
_ = r.Close()
|
||||
_ = w.Close()
|
||||
})
|
||||
|
||||
for name, fd := range map[string]uintptr{"read end": r.Fd(), "write end": w.Fd()} {
|
||||
if gotW, ok := terminalWidthFromFd(fd); ok {
|
||||
t.Errorf("%s: expected (_, false), got (%d, true)", name, gotW)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TestTerminalWidthFromFdRejectsRegularFile guards the other common
|
||||
// non-tty case: stdout redirected to a file (`glow x.md > out`).
|
||||
func TestTerminalWidthFromFdRejectsRegularFile(t *testing.T) {
|
||||
f, err := os.CreateTemp(t.TempDir(), "glow-width-*")
|
||||
if err != nil {
|
||||
t.Fatalf("CreateTemp: %v", err)
|
||||
}
|
||||
t.Cleanup(func() { _ = f.Close() })
|
||||
|
||||
if gotW, ok := terminalWidthFromFd(f.Fd()); ok {
|
||||
t.Errorf("regular file: expected (_, false), got (%d, true)", gotW)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
34
main.go
34
main.go
|
|
@ -191,12 +191,17 @@ func validateOptions(cmd *cobra.Command) error {
|
|||
style = "notty"
|
||||
}
|
||||
|
||||
// Detect terminal width
|
||||
// Detect terminal width. Prefer /dev/tty so that `glow <x.md` and
|
||||
// `glow x.md | less` still get the real terminal size; fall back to
|
||||
// stdout (the original behaviour) when /dev/tty isn't available.
|
||||
if !cmd.Flags().Changed("width") { //nolint:nestif
|
||||
if isTerminal && width == 0 {
|
||||
w, _, err := term.GetSize(int(os.Stdout.Fd()))
|
||||
if err == nil {
|
||||
if width == 0 {
|
||||
if w, ok := terminalWidthFromTTY(); ok {
|
||||
width = uint(w) //nolint:gosec
|
||||
} else if isTerminal {
|
||||
if w, ok := terminalWidthFromFd(os.Stdout.Fd()); ok {
|
||||
width = uint(w) //nolint:gosec
|
||||
}
|
||||
}
|
||||
|
||||
if width > 120 {
|
||||
|
|
@ -210,6 +215,27 @@ func validateOptions(cmd *cobra.Command) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// terminalWidthFromTTY reads the controlling terminal's width via
|
||||
// /dev/tty, so pipes and stdin redirection don't fool the autodetector.
|
||||
func terminalWidthFromTTY() (int, bool) {
|
||||
tty, err := os.Open("/dev/tty")
|
||||
if err != nil {
|
||||
return 0, false
|
||||
}
|
||||
defer tty.Close() //nolint:errcheck
|
||||
return terminalWidthFromFd(tty.Fd())
|
||||
}
|
||||
|
||||
// terminalWidthFromFd returns the terminal width for the given fd, or
|
||||
// (0, false) when fd is not a terminal or the ioctl fails.
|
||||
func terminalWidthFromFd(fd uintptr) (int, bool) {
|
||||
w, _, err := term.GetSize(int(fd)) //nolint:gosec
|
||||
if err != nil || w <= 0 {
|
||||
return 0, false
|
||||
}
|
||||
return w, true
|
||||
}
|
||||
|
||||
func stdinIsPipe() (bool, error) {
|
||||
stat, err := os.Stdin.Stat()
|
||||
if err != nil {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue