Skip to content

Commit

Permalink
feat(pagination): implement paginated output
Browse files Browse the repository at this point in the history
Implement a `pager` config option. If configured, `cheat` will
automatically pipe output through the configured pager (where
appropriate).
  • Loading branch information
chrisallenlane committed Jun 25, 2020
1 parent 8e602b0 commit 59d5c96
Show file tree
Hide file tree
Showing 9 changed files with 78 additions and 10 deletions.
7 changes: 5 additions & 2 deletions cmd/cheat/cmd_directories.go
@@ -1,18 +1,20 @@
package main

import (
"bytes"
"fmt"
"os"
"text/tabwriter"

"github.com/cheat/cheat/internal/config"
"github.com/cheat/cheat/internal/display"
)

// cmdDirectories lists the configured cheatpaths.
func cmdDirectories(opts map[string]interface{}, conf config.Config) {

// initialize a tabwriter to produce cleanly columnized output
w := tabwriter.NewWriter(os.Stdout, 0, 0, 1, ' ', 0)
var out bytes.Buffer
w := tabwriter.NewWriter(&out, 0, 0, 1, ' ', 0)

// generate sorted, columnized output
for _, path := range conf.Cheatpaths {
Expand All @@ -25,4 +27,5 @@ func cmdDirectories(opts map[string]interface{}, conf config.Config) {

// write columnized output to stdout
w.Flush()
display.Display(out.String(), conf)
}
10 changes: 8 additions & 2 deletions cmd/cheat/cmd_list.go
@@ -1,6 +1,7 @@
package main

import (
"bytes"
"fmt"
"os"
"regexp"
Expand All @@ -9,6 +10,7 @@ import (
"text/tabwriter"

"github.com/cheat/cheat/internal/config"
"github.com/cheat/cheat/internal/display"
"github.com/cheat/cheat/internal/sheet"
"github.com/cheat/cheat/internal/sheets"
)
Expand Down Expand Up @@ -85,10 +87,13 @@ func cmdList(opts map[string]interface{}, conf config.Config) {
}

// initialize a tabwriter to produce cleanly columnized output
w := tabwriter.NewWriter(os.Stdout, 0, 0, 1, ' ', 0)
var out bytes.Buffer
w := tabwriter.NewWriter(&out, 0, 0, 1, ' ', 0)

// generate sorted, columnized output
// write a header row
fmt.Fprintln(w, "title:\tfile:\ttags:")

// generate sorted, columnized output
for _, sheet := range flattened {
fmt.Fprintln(w, fmt.Sprintf(
"%s\t%s\t%s",
Expand All @@ -100,4 +105,5 @@ func cmdList(opts map[string]interface{}, conf config.Config) {

// write columnized output to stdout
w.Flush()
display.Display(out.String(), conf)
}
9 changes: 6 additions & 3 deletions cmd/cheat/cmd_search.go
Expand Up @@ -7,6 +7,7 @@ import (
"strings"

"github.com/cheat/cheat/internal/config"
"github.com/cheat/cheat/internal/display"
"github.com/cheat/cheat/internal/sheet"
"github.com/cheat/cheat/internal/sheets"
)
Expand Down Expand Up @@ -87,12 +88,14 @@ func cmdSearch(opts map[string]interface{}, conf config.Config) {
}

// output the cheatsheet title
fmt.Printf("%s:\n", sheet.Title)
out := fmt.Sprintf("%s:\n", sheet.Title)

// indent each line of content with two spaces
for _, line := range strings.Split(sheet.Text, "\n") {
fmt.Printf(" %s\n", line)
out += fmt.Sprintf(" %s\n", line)
}
fmt.Println("")

// display the output
display.Display(out, conf)
}
}
9 changes: 7 additions & 2 deletions cmd/cheat/cmd_tags.go
Expand Up @@ -5,6 +5,7 @@ import (
"os"

"github.com/cheat/cheat/internal/config"
"github.com/cheat/cheat/internal/display"
"github.com/cheat/cheat/internal/sheets"
)

Expand All @@ -18,8 +19,12 @@ func cmdTags(opts map[string]interface{}, conf config.Config) {
os.Exit(1)
}

// write sheet tags to stdout
// assemble the output
out := ""
for _, tag := range sheets.Tags(cheatsheets) {
fmt.Println(tag)
out += fmt.Sprintln(tag)
}

// display the output
display.Display(out, conf)
}
3 changes: 2 additions & 1 deletion cmd/cheat/cmd_view.go
Expand Up @@ -6,6 +6,7 @@ import (
"strings"

"github.com/cheat/cheat/internal/config"
"github.com/cheat/cheat/internal/display"
"github.com/cheat/cheat/internal/sheets"
)

Expand Down Expand Up @@ -47,5 +48,5 @@ func cmdView(opts map[string]interface{}, conf config.Config) {
}

// display the cheatsheet
fmt.Print(sheet.Text)
display.Display(sheet.Text, conf)
}
3 changes: 3 additions & 0 deletions cmd/cheat/str_config.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions configs/conf.yml
Expand Up @@ -14,6 +14,9 @@ style: monokai
# One of: "terminal", "terminal256", "terminal16m"
formatter: terminal16m

# Through which pager should output be piped? (Unset this key for no pager.)
pager: less -FRX

# The paths at which cheatsheets are available. Tags associated with a cheatpath
# are automatically attached to all cheatsheets residing on that path.
#
Expand Down
7 changes: 7 additions & 0 deletions internal/config/config.go
Expand Up @@ -5,6 +5,7 @@ import (
"io/ioutil"
"os"
"path/filepath"
"strings"

cp "github.com/cheat/cheat/internal/cheatpath"

Expand All @@ -19,6 +20,7 @@ type Config struct {
Cheatpaths []cp.Cheatpath `yaml:"cheatpaths"`
Style string `yaml:"style"`
Formatter string `yaml:"formatter"`
Pager string `yaml:"pager"`
}

// New returns a new Config struct
Expand Down Expand Up @@ -111,5 +113,10 @@ func New(opts map[string]interface{}, confPath string, resolve bool) (Config, er
conf.Formatter = "terminal16m"
}

// if a pager was not provided, set a default
if strings.TrimSpace(conf.Pager) == "" {
conf.Pager = ""
}

return conf, nil
}
37 changes: 37 additions & 0 deletions internal/display/display.go
@@ -0,0 +1,37 @@
package display

import (
"fmt"
"os"
"os/exec"
"strings"

"github.com/cheat/cheat/internal/config"
)

// Display writes output either directly to stdout, or through a pager,
// depending upon configuration.
func Display(out string, conf config.Config) {
// if no pager was configured, print the output to stdout and exit
if conf.Pager == "" {
fmt.Print(out)
os.Exit(0)
}

// otherwise, pipe output through the pager
parts := strings.Split(conf.Pager, " ")
pager := parts[0]
args := parts[1:]

// run the pager
cmd := exec.Command(pager, args...)
cmd.Stdin = strings.NewReader(out)
cmd.Stdout = os.Stdout

// handle errors
err := cmd.Run()
if err != nil {
fmt.Fprintln(os.Stderr, fmt.Sprintf("failed to write to pager: %v", err))
os.Exit(1)
}
}

0 comments on commit 59d5c96

Please sign in to comment.