mirror of
https://github.com/walles/moar.git
synced 2024-10-26 13:00:40 +03:00
Allow passing through multiple files
With this change in place you can invoke moar like this: moar file1 file2 file3 | wc -l Note that I believe this is a corner case, and I will on purpose leave this undocumented. Fixes #187
This commit is contained in:
parent
c44f1e0a0b
commit
f4af673d3c
64
moar.go
64
moar.go
@ -309,25 +309,26 @@ func parseMouseMode(mouseMode string) (twin.MouseMode, error) {
|
||||
return twin.MouseModeAuto, fmt.Errorf("Valid modes are auto, select and scroll")
|
||||
}
|
||||
|
||||
func pumpToStdout(inputFilename *string) error {
|
||||
if inputFilename != nil {
|
||||
// If we get both redirected stdin and an input filename, we must prefer
|
||||
// to copy the file, because that's how less works. That's why we go for
|
||||
// the filename first.
|
||||
inputFile, err := m.ZOpen(*inputFilename)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failed to open %s: %w", *inputFilename, err)
|
||||
func pumpToStdout(inputFilenames ...string) error {
|
||||
if len(inputFilenames) > 0 {
|
||||
// If we get both redirected stdin and an input filenames, should only
|
||||
// copy the files and ignore stdin, because that's how less works.
|
||||
for _, inputFilename := range inputFilenames {
|
||||
inputFile, err := m.ZOpen(inputFilename)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failed to open %s: %w", inputFilename, err)
|
||||
}
|
||||
|
||||
_, err = io.Copy(os.Stdout, inputFile)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failed to copy %s to stdout: %w", inputFilename, err)
|
||||
}
|
||||
}
|
||||
|
||||
_, err = io.Copy(os.Stdout, inputFile)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failed to copy %s to stdout: %w", *inputFilename, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Must be done after trying to pump the input filename to stdout to be
|
||||
// compatible with less, see above.
|
||||
// No input filenames, pump stdin to stdout
|
||||
_, err := io.Copy(os.Stdout, os.Stdin)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failed to copy stdin to stdout: %w", err)
|
||||
@ -519,7 +520,10 @@ func main() {
|
||||
TimestampFormat: time.StampMicro,
|
||||
})
|
||||
|
||||
if len(flagSet.Args()) > 1 {
|
||||
stdinIsRedirected := !term.IsTerminal(int(os.Stdin.Fd()))
|
||||
stdoutIsRedirected := !term.IsTerminal(int(os.Stdout.Fd()))
|
||||
|
||||
if len(flagSet.Args()) > 1 && !stdoutIsRedirected {
|
||||
fmt.Fprintln(os.Stderr, "ERROR: Expected exactly one filename, or data piped from stdin")
|
||||
fmt.Fprintln(os.Stderr)
|
||||
printCommandline(os.Stderr)
|
||||
@ -528,23 +532,17 @@ func main() {
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
stdinIsRedirected := !term.IsTerminal(int(os.Stdin.Fd()))
|
||||
stdoutIsRedirected := !term.IsTerminal(int(os.Stdout.Fd()))
|
||||
var inputFilename *string
|
||||
if len(flagSet.Args()) == 1 {
|
||||
word := flagSet.Args()[0]
|
||||
inputFilename = &word
|
||||
|
||||
for _, inputFilename := range flagSet.Args() {
|
||||
// Need to check before twin.NewScreen() below, otherwise the screen
|
||||
// will be cleared before we print the "No such file" error.
|
||||
err := tryOpen(*inputFilename)
|
||||
err := tryOpen(inputFilename)
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, "ERROR:", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
if inputFilename == nil && !stdinIsRedirected {
|
||||
if len(flagSet.Args()) == 0 && !stdinIsRedirected {
|
||||
fmt.Fprintln(os.Stderr, "ERROR: Filename or input pipe required")
|
||||
fmt.Fprintln(os.Stderr)
|
||||
printCommandline(os.Stderr)
|
||||
@ -553,7 +551,7 @@ func main() {
|
||||
}
|
||||
|
||||
if stdoutIsRedirected {
|
||||
err := pumpToStdout(inputFilename)
|
||||
err := pumpToStdout(flagSet.Args()...)
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, "ERROR:", err)
|
||||
os.Exit(1)
|
||||
@ -572,7 +570,7 @@ func main() {
|
||||
if err != nil {
|
||||
// Ref: https://github.com/walles/moar/issues/149
|
||||
log.Debug("Failed to set up screen for paging, pumping to stdout instead: ", err)
|
||||
err := pumpToStdout(inputFilename)
|
||||
err := pumpToStdout(flagSet.Args()...)
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, "ERROR:", err)
|
||||
os.Exit(1)
|
||||
@ -580,6 +578,15 @@ func main() {
|
||||
return
|
||||
}
|
||||
|
||||
if len(flagSet.Args()) > 1 {
|
||||
fmt.Fprintln(os.Stderr, "ERROR: Expected exactly one filename, or data piped from stdin")
|
||||
fmt.Fprintln(os.Stderr)
|
||||
printCommandline(os.Stderr)
|
||||
fmt.Fprintln(os.Stderr, "For help, run: \x1b[1mmoar --help\x1b[m")
|
||||
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
formatter := formatters.TTY256
|
||||
if *terminalColorsCount == twin.ColorType8 {
|
||||
formatter = formatters.TTY8
|
||||
@ -626,7 +633,10 @@ func main() {
|
||||
reader = m.NewReaderFromStream("", os.Stdin, style, formatter, *lexer)
|
||||
} else {
|
||||
// Display the input file contents
|
||||
reader, err = m.NewReaderFromFilename(*inputFilename, style, formatter, *lexer)
|
||||
if len(flagSet.Args()) > 0 {
|
||||
panic("Invariant broken: Expected exactly one filename")
|
||||
}
|
||||
reader, err = m.NewReaderFromFilename(flagSet.Args()[0], style, formatter, *lexer)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "ERROR: %v\n", err)
|
||||
os.Exit(1)
|
||||
|
5
test.sh
5
test.sh
@ -55,6 +55,11 @@ echo Test redirecting a file by name into file by redirecting stdout...
|
||||
./moar moar.go >"${RESULT}"
|
||||
diff -u moar.go "${RESULT}"
|
||||
|
||||
# Ref: https://github.com/walles/moar/issues/187
|
||||
echo Test redirecting multiple files by name into redirected stdout...
|
||||
./moar moar.go moar.go >"${RESULT}"
|
||||
diff -u <(cat moar.go moar.go) "${RESULT}"
|
||||
|
||||
echo Test redirecting non-existing file by name into redirected stdout...
|
||||
if ./moar does-not-exist >&/dev/null; then
|
||||
echo ERROR: Should have failed on non-existing input file name
|
||||
|
Loading…
Reference in New Issue
Block a user