Skip to content

Commit

Permalink
Move help printing into a file of its own
Browse files Browse the repository at this point in the history
  • Loading branch information
walles committed Oct 27, 2024
1 parent d5f1cbd commit 8a27ed1
Show file tree
Hide file tree
Showing 2 changed files with 249 additions and 236 deletions.
236 changes: 0 additions & 236 deletions moar.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,8 @@ import (
"fmt"
"io"
"os"
"os/exec"
"path/filepath"
"runtime"
"runtime/debug"
"sort"
"strconv"
"strings"
"time"
Expand Down Expand Up @@ -39,239 +36,6 @@ const defaultLightTheme = "tango"

var versionString = ""

func renderLessTermcapEnvVar(envVarName string, description string, colors twin.ColorCount) string {
value := os.Getenv(envVarName)
if len(value) == 0 {
return ""
}

style, err := m.TermcapToStyle(value)
if err != nil {
bold := twin.StyleDefault.WithAttr(twin.AttrBold).RenderUpdateFrom(twin.StyleDefault, colors)
notBold := twin.StyleDefault.RenderUpdateFrom(twin.StyleDefault.WithAttr(twin.AttrBold), colors)
return fmt.Sprintf(" %s (%s): %s %s<- Error: %v%s\n",
envVarName,
description,
strings.ReplaceAll(value, "\x1b", "ESC"),
bold,
err,
notBold,
)
}

prefix := style.RenderUpdateFrom(twin.StyleDefault, colors)
suffix := twin.StyleDefault.RenderUpdateFrom(style, colors)
return fmt.Sprintf(" %s (%s): %s\n",
envVarName,
description,
prefix+strings.ReplaceAll(value, "\x1b", "ESC")+suffix,
)
}

func renderPagerEnvVar(name string, colors twin.ColorCount) string {
bold := twin.StyleDefault.WithAttr(twin.AttrBold).RenderUpdateFrom(twin.StyleDefault, colors)
notBold := twin.StyleDefault.RenderUpdateFrom(twin.StyleDefault.WithAttr(twin.AttrBold), colors)

value, isSet := os.LookupEnv(name)
if value == "" {
what := "unset"
if isSet {
what = "empty"
}

return fmt.Sprintf(" %s is %s %s<- Should be %s%s\n",
name,
what,
bold,
getMoarPath(),
notBold,
)
}

absMoarPath, err := absLookPath(os.Args[0])
if err != nil {
log.Warn("Unable to find absolute moar path: ", err)
return ""
}

absEnvValue, err := absLookPath(value)
if err != nil {
// This can happen if this is set to some outdated value
absEnvValue = value
}

if absEnvValue == absMoarPath {
return fmt.Sprintf(" %s=%s\n", name, value)
}

return fmt.Sprintf(" %s=%s %s<- Should be %s%s\n",
name,
value,
bold,
getMoarPath(),
notBold,
)
}

// If the environment variable is set, render it as APA=bepa indented two
// spaces, plus a newline at the end. Otherwise, return an empty string.
func renderPlainEnvVar(envVarName string) string {
value := os.Getenv(envVarName)
if value == "" {
return ""
}

return fmt.Sprintf(" %s=%s\n", envVarName, value)
}

func printCommandline(output io.Writer) {
fmt.Fprintln(output, "Commandline: moar", strings.Join(os.Args[1:], " "))
fmt.Fprintf(output, "Environment: MOAR=\"%v\"\n", os.Getenv("MOAR"))
fmt.Fprintln(output)
}

func heading(text string, colors twin.ColorCount) string {
style := twin.StyleDefault.WithAttr(twin.AttrItalic)
prefix := style.RenderUpdateFrom(twin.StyleDefault, colors)
suffix := twin.StyleDefault.RenderUpdateFrom(style, colors)
return prefix + text + suffix
}

func printUsage(flagSet *flag.FlagSet, colors twin.ColorCount) {
// This controls where PrintDefaults() prints, see below
flagSet.SetOutput(os.Stdout)

// FIXME: Log if any printouts fail?

fmt.Println(heading("Usage", colors))
fmt.Println(" moar [options] <file>")
fmt.Println(" ... | moar")
fmt.Println(" moar < file")
fmt.Println()
fmt.Println("Shows file contents. Compressed files will be transparently decompressed.")
fmt.Println("Input is expected to be (possibly compressed) UTF-8 encoded text. Invalid /")
fmt.Println("non-printable characters are by default rendered as '?'.")
fmt.Println()
fmt.Println("More information + source code:")
fmt.Println(" <https://github.com/walles/moar#readme>")
fmt.Println()
fmt.Println(heading("Environment", colors))

moarEnv := os.Getenv("MOAR")
if len(moarEnv) == 0 {
fmt.Println(" Additional options are read from the MOAR environment variable if set.")
fmt.Println(" But currently, the MOAR environment variable is not set.")
} else {
fmt.Println(" Additional options are read from the MOAR environment variable.")
fmt.Printf(" Current setting: MOAR=\"%s\"\n", moarEnv)
}

envSection := ""
envSection += renderLessTermcapEnvVar("LESS_TERMCAP_md", "man page bold style", colors)
envSection += renderLessTermcapEnvVar("LESS_TERMCAP_us", "man page underline style", colors)
envSection += renderLessTermcapEnvVar("LESS_TERMCAP_so", "search hits and footer style", colors)

envSection += renderPagerEnvVar("PAGER", colors)
envVars := os.Environ()
sort.Strings(envVars)
for _, env := range envVars {
split := strings.SplitN(env, "=", 2)
if len(split) != 2 {
continue
}

name := split[0]
if name == "PAGER" {
// Already done above
continue
}
if !strings.HasSuffix(name, "PAGER") {
continue
}

envSection += renderPagerEnvVar(name, colors)
}

envSection += renderPlainEnvVar("TERM")
envSection += renderPlainEnvVar("TERM_PROGRAM")
envSection += renderPlainEnvVar("COLORTERM")

// Requested here: https://github.com/walles/moar/issues/170#issuecomment-1891154661
envSection += renderPlainEnvVar("MANROFFOPT")

if envSection != "" {
fmt.Println()

// Not Println since the section already ends with a newline
fmt.Print(envSection)
}

absMoarPath, err := absLookPath(os.Args[0])
if err == nil {
absPagerValue, err := absLookPath(os.Getenv("PAGER"))
if err != nil {
absPagerValue = ""
}
if absPagerValue != absMoarPath {
// We're not the default pager
fmt.Println()
fmt.Println(heading("Making moar Your Default Pager", colors))
fmt.Println(" Put the following line in your ~/.bashrc, ~/.bash_profile or ~/.zshrc")
fmt.Println(" and moar will be used as the default pager in all new terminal windows:")
fmt.Println()
fmt.Printf(" export PAGER=%s\n", getMoarPath())
}
} else {
log.Warn("Unable to find moar binary ", err)
}

fmt.Println()
fmt.Println(heading("Options", colors))

flagSet.PrintDefaults()

fmt.Println(" +1234")
fmt.Println(" \tImmediately scroll to line 1234")
}

// "moar" if we're in the $PATH, otherwise an absolute path
func getMoarPath() string {
moarPath := os.Args[0]
if filepath.IsAbs(moarPath) {
return moarPath
}

if strings.Contains(moarPath, string(os.PathSeparator)) {
// Relative path
moarPath, err := filepath.Abs(moarPath)
if err != nil {
panic(err)
}
return moarPath
}

// Neither absolute nor relative, try PATH
_, err := exec.LookPath(moarPath)
if err != nil {
panic("Unable to find in $PATH: " + moarPath)
}
return moarPath
}

func absLookPath(path string) (string, error) {
lookedPath, err := exec.LookPath(path)
if err != nil {
return "", err
}

absLookedPath, err := filepath.Abs(lookedPath)
if err != nil {
return "", err
}

return absLookedPath, err
}

// printProblemsHeader prints bug reporting information to stderr
func printProblemsHeader() {
fmt.Fprintln(os.Stderr, "Please post the following report at <https://github.com/walles/moar/issues>,")
Expand Down
Loading

0 comments on commit 8a27ed1

Please sign in to comment.