Skip to content

Instantly share code, notes, and snippets.

@padurean
Created October 4, 2025 13:47
Show Gist options
  • Save padurean/92ab414e33faf8eed91b204ac605946d to your computer and use it in GitHub Desktop.
Save padurean/92ab414e33faf8eed91b204ac605946d to your computer and use it in GitHub Desktop.
Go pagination for CLI app output - detect if terminal and if it is use the available pager (e.g. less) #GoLang #CLI
package main
import (
"fmt"
"io"
"os"
"os/exec"
"syscall"
"golang.org/x/term"
)
// usePager attempts to pipe output to $PAGER if available and stdout is a TTY
// Returns a writer and a cleanup function
func usePager() (io.Writer, func() error) {
// Don't use pager if output is redirected/piped
if !term.IsTerminal(int(syscall.Stdout)) {
return os.Stdout, func() error { return nil }
}
pager := os.Getenv("PAGER")
if pager == "" {
// Fallback to common pagers
pager = "less"
if _, err := exec.LookPath(pager); err != nil {
pager = "more"
if _, err := exec.LookPath(pager); err != nil {
// No pager available, use stdout
return os.Stdout, func() error { return nil }
}
}
}
cmd := exec.Command(pager)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
// Set better defaults for less if it's being used
if pager == "less" || (pager != "more" && os.Getenv("LESS") == "") {
// -F: exit if content fits on one screen
// -R: allow ANSI color codes
// -X: don't clear screen on exit
// -K: exit on Ctrl-C
cmd.Env = append(os.Environ(), "LESS=-FRX")
}
stdin, err := cmd.StdinPipe()
if err != nil {
return os.Stdout, func() error { return nil }
}
if err := cmd.Start(); err != nil {
return os.Stdout, func() error { return nil }
}
cleanup := func() error {
stdin.Close()
return cmd.Wait()
}
return stdin, cleanup
}
func main() {
w, cleanupPager := usePager()
defer cleanupPager()
// Write your output to w instead of os.Stdout
// ANSI colors will work properly with the -R flag
for i := 1; i <= 100; i++ {
if i%10 == 0 {
fmt.Fprintf(w, "\033[1;32mLine %d: Highlighted output\033[0m\n", i)
} else {
fmt.Fprintf(w, "Line %d: Some output here\n", i)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment