mirror of
https://github.com/cheat/cheat.git
synced 2025-09-04 11:08:29 +02:00
Compare commits
8 Commits
Author | SHA1 | Date | |
---|---|---|---|
278a5d9154 | |||
9fa0c466fd | |||
4e9b2928b3 | |||
fa5eb44be8 | |||
49afd7c16b | |||
59d5c96c24 | |||
8e602b0e93 | |||
fb04cb1fcd |
6
Makefile
6
Makefile
@ -28,6 +28,7 @@ TMPDIR := /tmp
|
|||||||
# release binaries
|
# release binaries
|
||||||
releases := \
|
releases := \
|
||||||
$(dist_dir)/cheat-darwin-amd64 \
|
$(dist_dir)/cheat-darwin-amd64 \
|
||||||
|
$(dist_dir)/cheat-linux-386 \
|
||||||
$(dist_dir)/cheat-linux-amd64 \
|
$(dist_dir)/cheat-linux-amd64 \
|
||||||
$(dist_dir)/cheat-linux-arm5 \
|
$(dist_dir)/cheat-linux-arm5 \
|
||||||
$(dist_dir)/cheat-linux-arm6 \
|
$(dist_dir)/cheat-linux-arm6 \
|
||||||
@ -52,6 +53,11 @@ $(dist_dir)/cheat-darwin-amd64: prepare
|
|||||||
GOARCH=amd64 GOOS=darwin \
|
GOARCH=amd64 GOOS=darwin \
|
||||||
$(GO) build $(BUILD_FLAGS) -o $@ $(cmd_dir) && $(GZIP) $@ && chmod -x $@.gz
|
$(GO) build $(BUILD_FLAGS) -o $@ $(cmd_dir) && $(GZIP) $@ && chmod -x $@.gz
|
||||||
|
|
||||||
|
# cheat-linux-386
|
||||||
|
$(dist_dir)/cheat-linux-386: prepare
|
||||||
|
GOARCH=386 GOOS=linux \
|
||||||
|
$(GO) build $(BUILD_FLAGS) -o $@ $(cmd_dir) && $(GZIP) $@ && chmod -x $@.gz
|
||||||
|
|
||||||
# cheat-linux-amd64
|
# cheat-linux-amd64
|
||||||
$(dist_dir)/cheat-linux-amd64: prepare
|
$(dist_dir)/cheat-linux-amd64: prepare
|
||||||
GOARCH=amd64 GOOS=linux \
|
GOARCH=amd64 GOOS=linux \
|
||||||
|
@ -1,18 +1,20 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
|
||||||
"text/tabwriter"
|
"text/tabwriter"
|
||||||
|
|
||||||
"github.com/cheat/cheat/internal/config"
|
"github.com/cheat/cheat/internal/config"
|
||||||
|
"github.com/cheat/cheat/internal/display"
|
||||||
)
|
)
|
||||||
|
|
||||||
// cmdDirectories lists the configured cheatpaths.
|
// cmdDirectories lists the configured cheatpaths.
|
||||||
func cmdDirectories(opts map[string]interface{}, conf config.Config) {
|
func cmdDirectories(opts map[string]interface{}, conf config.Config) {
|
||||||
|
|
||||||
// initialize a tabwriter to produce cleanly columnized output
|
// 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
|
// generate sorted, columnized output
|
||||||
for _, path := range conf.Cheatpaths {
|
for _, path := range conf.Cheatpaths {
|
||||||
@ -25,4 +27,5 @@ func cmdDirectories(opts map[string]interface{}, conf config.Config) {
|
|||||||
|
|
||||||
// write columnized output to stdout
|
// write columnized output to stdout
|
||||||
w.Flush()
|
w.Flush()
|
||||||
|
display.Display(out.String(), conf)
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"regexp"
|
"regexp"
|
||||||
@ -9,6 +10,7 @@ import (
|
|||||||
"text/tabwriter"
|
"text/tabwriter"
|
||||||
|
|
||||||
"github.com/cheat/cheat/internal/config"
|
"github.com/cheat/cheat/internal/config"
|
||||||
|
"github.com/cheat/cheat/internal/display"
|
||||||
"github.com/cheat/cheat/internal/sheet"
|
"github.com/cheat/cheat/internal/sheet"
|
||||||
"github.com/cheat/cheat/internal/sheets"
|
"github.com/cheat/cheat/internal/sheets"
|
||||||
)
|
)
|
||||||
@ -79,16 +81,19 @@ func cmdList(opts map[string]interface{}, conf config.Config) {
|
|||||||
flattened = filtered
|
flattened = filtered
|
||||||
}
|
}
|
||||||
|
|
||||||
// exit early if no cheatsheets are available
|
// return exit code 2 if no cheatsheets are available
|
||||||
if len(flattened) == 0 {
|
if len(flattened) == 0 {
|
||||||
os.Exit(0)
|
os.Exit(2)
|
||||||
}
|
}
|
||||||
|
|
||||||
// initialize a tabwriter to produce cleanly columnized output
|
// 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)
|
||||||
|
|
||||||
|
// write a header row
|
||||||
|
fmt.Fprintln(w, "title:\tfile:\ttags:")
|
||||||
|
|
||||||
// generate sorted, columnized output
|
// generate sorted, columnized output
|
||||||
fmt.Fprintln(w, "title:\tfile:\ttags:")
|
|
||||||
for _, sheet := range flattened {
|
for _, sheet := range flattened {
|
||||||
fmt.Fprintln(w, fmt.Sprintf(
|
fmt.Fprintln(w, fmt.Sprintf(
|
||||||
"%s\t%s\t%s",
|
"%s\t%s\t%s",
|
||||||
@ -100,4 +105,5 @@ func cmdList(opts map[string]interface{}, conf config.Config) {
|
|||||||
|
|
||||||
// write columnized output to stdout
|
// write columnized output to stdout
|
||||||
w.Flush()
|
w.Flush()
|
||||||
|
display.Display(out.String(), conf)
|
||||||
}
|
}
|
||||||
|
@ -37,8 +37,8 @@ func cmdRemove(opts map[string]interface{}, conf config.Config) {
|
|||||||
// fail early if the requested cheatsheet does not exist
|
// fail early if the requested cheatsheet does not exist
|
||||||
sheet, ok := consolidated[cheatsheet]
|
sheet, ok := consolidated[cheatsheet]
|
||||||
if !ok {
|
if !ok {
|
||||||
fmt.Fprintln(os.Stderr, fmt.Sprintf("no cheatsheet found for '%s'.\n", cheatsheet))
|
fmt.Fprintln(os.Stderr, fmt.Sprintf("No cheatsheet found for '%s'.\n", cheatsheet))
|
||||||
os.Exit(1)
|
os.Exit(2)
|
||||||
}
|
}
|
||||||
|
|
||||||
// fail early if the sheet is read-only
|
// fail early if the sheet is read-only
|
||||||
|
@ -7,6 +7,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/cheat/cheat/internal/config"
|
"github.com/cheat/cheat/internal/config"
|
||||||
|
"github.com/cheat/cheat/internal/display"
|
||||||
"github.com/cheat/cheat/internal/sheet"
|
"github.com/cheat/cheat/internal/sheet"
|
||||||
"github.com/cheat/cheat/internal/sheets"
|
"github.com/cheat/cheat/internal/sheets"
|
||||||
)
|
)
|
||||||
@ -45,7 +46,7 @@ func cmdSearch(opts map[string]interface{}, conf config.Config) {
|
|||||||
s, ok := consolidated[cheatsheet]
|
s, ok := consolidated[cheatsheet]
|
||||||
if !ok {
|
if !ok {
|
||||||
fmt.Printf("No cheatsheet found for '%s'.\n", cheatsheet)
|
fmt.Printf("No cheatsheet found for '%s'.\n", cheatsheet)
|
||||||
os.Exit(0)
|
os.Exit(2)
|
||||||
}
|
}
|
||||||
|
|
||||||
consolidated = map[string]sheet.Sheet{
|
consolidated = map[string]sheet.Sheet{
|
||||||
@ -54,6 +55,7 @@ func cmdSearch(opts map[string]interface{}, conf config.Config) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// sort the cheatsheets alphabetically, and search for matches
|
// sort the cheatsheets alphabetically, and search for matches
|
||||||
|
out := ""
|
||||||
for _, sheet := range sheets.Sort(consolidated) {
|
for _, sheet := range sheets.Sort(consolidated) {
|
||||||
|
|
||||||
// assume that we want to perform a case-insensitive search for <phrase>
|
// assume that we want to perform a case-insensitive search for <phrase>
|
||||||
@ -87,12 +89,14 @@ func cmdSearch(opts map[string]interface{}, conf config.Config) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// output the cheatsheet title
|
// 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
|
// indent each line of content with two spaces
|
||||||
for _, line := range strings.Split(sheet.Text, "\n") {
|
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)
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/cheat/cheat/internal/config"
|
"github.com/cheat/cheat/internal/config"
|
||||||
|
"github.com/cheat/cheat/internal/display"
|
||||||
"github.com/cheat/cheat/internal/sheets"
|
"github.com/cheat/cheat/internal/sheets"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -18,8 +19,12 @@ func cmdTags(opts map[string]interface{}, conf config.Config) {
|
|||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// write sheet tags to stdout
|
// assemble the output
|
||||||
|
out := ""
|
||||||
for _, tag := range sheets.Tags(cheatsheets) {
|
for _, tag := range sheets.Tags(cheatsheets) {
|
||||||
fmt.Println(tag)
|
out += fmt.Sprintln(tag)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// display the output
|
||||||
|
display.Display(out, conf)
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/cheat/cheat/internal/config"
|
"github.com/cheat/cheat/internal/config"
|
||||||
|
"github.com/cheat/cheat/internal/display"
|
||||||
"github.com/cheat/cheat/internal/sheets"
|
"github.com/cheat/cheat/internal/sheets"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -38,7 +39,7 @@ func cmdView(opts map[string]interface{}, conf config.Config) {
|
|||||||
sheet, ok := consolidated[cheatsheet]
|
sheet, ok := consolidated[cheatsheet]
|
||||||
if !ok {
|
if !ok {
|
||||||
fmt.Printf("No cheatsheet found for '%s'.\n", cheatsheet)
|
fmt.Printf("No cheatsheet found for '%s'.\n", cheatsheet)
|
||||||
os.Exit(0)
|
os.Exit(2)
|
||||||
}
|
}
|
||||||
|
|
||||||
// apply colorization if requested
|
// apply colorization if requested
|
||||||
@ -47,5 +48,5 @@ func cmdView(opts map[string]interface{}, conf config.Config) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// display the cheatsheet
|
// display the cheatsheet
|
||||||
fmt.Print(sheet.Text)
|
display.Display(sheet.Text, conf)
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@ import (
|
|||||||
"github.com/cheat/cheat/internal/installer"
|
"github.com/cheat/cheat/internal/installer"
|
||||||
)
|
)
|
||||||
|
|
||||||
const version = "3.10.0"
|
const version = "4.0.1"
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|
||||||
|
@ -23,6 +23,9 @@ style: monokai
|
|||||||
# One of: "terminal", "terminal256", "terminal16m"
|
# One of: "terminal", "terminal256", "terminal16m"
|
||||||
formatter: 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
|
# The paths at which cheatsheets are available. Tags associated with a cheatpath
|
||||||
# are automatically attached to all cheatsheets residing on that path.
|
# are automatically attached to all cheatsheets residing on that path.
|
||||||
#
|
#
|
||||||
|
@ -14,6 +14,9 @@ style: monokai
|
|||||||
# One of: "terminal", "terminal256", "terminal16m"
|
# One of: "terminal", "terminal256", "terminal16m"
|
||||||
formatter: 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
|
# The paths at which cheatsheets are available. Tags associated with a cheatpath
|
||||||
# are automatically attached to all cheatsheets residing on that path.
|
# are automatically attached to all cheatsheets residing on that path.
|
||||||
#
|
#
|
||||||
|
@ -203,6 +203,13 @@ If set, autocompletion scripts will attempt to integrate with
|
|||||||
\f[B]fzf\f[].
|
\f[B]fzf\f[].
|
||||||
.RS
|
.RS
|
||||||
.RE
|
.RE
|
||||||
|
.SH RETURN VALUES
|
||||||
|
.IP "0." 3
|
||||||
|
Successful termination
|
||||||
|
.IP "1." 3
|
||||||
|
Application error
|
||||||
|
.IP "2." 3
|
||||||
|
Cheatsheet(s) not found
|
||||||
.SH BUGS
|
.SH BUGS
|
||||||
.PP
|
.PP
|
||||||
See GitHub issues: <https://github.com/cheat/cheat/issues>
|
See GitHub issues: <https://github.com/cheat/cheat/issues>
|
||||||
|
@ -163,6 +163,15 @@ set, all other config paths will be ignored.
|
|||||||
|
|
||||||
: If set, autocompletion scripts will attempt to integrate with **fzf**.
|
: If set, autocompletion scripts will attempt to integrate with **fzf**.
|
||||||
|
|
||||||
|
RETURN VALUES
|
||||||
|
=============
|
||||||
|
|
||||||
|
0. Successful termination
|
||||||
|
|
||||||
|
1. Application error
|
||||||
|
|
||||||
|
2. Cheatsheet(s) not found
|
||||||
|
|
||||||
|
|
||||||
BUGS
|
BUGS
|
||||||
====
|
====
|
||||||
|
2
go.mod
2
go.mod
@ -13,5 +13,5 @@ require (
|
|||||||
github.com/sergi/go-diff v1.1.0 // indirect
|
github.com/sergi/go-diff v1.1.0 // indirect
|
||||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect
|
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect
|
||||||
gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0
|
gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0
|
||||||
gopkg.in/yaml.v2 v2.2.8
|
gopkg.in/yaml.v2 v2.3.0
|
||||||
)
|
)
|
||||||
|
4
go.sum
4
go.sum
@ -60,5 +60,5 @@ gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0 h1:POO/ycCATvegFmVuPpQzZFJ+p
|
|||||||
gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0/go.mod h1:WDnlLJ4WF5VGsH/HVa3CI79GS0ol3YnhVnKP89i0kNg=
|
gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0/go.mod h1:WDnlLJ4WF5VGsH/HVa3CI79GS0ol3YnhVnKP89i0kNg=
|
||||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
|
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
|
||||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
|
||||||
cp "github.com/cheat/cheat/internal/cheatpath"
|
cp "github.com/cheat/cheat/internal/cheatpath"
|
||||||
|
|
||||||
@ -19,6 +20,7 @@ type Config struct {
|
|||||||
Cheatpaths []cp.Cheatpath `yaml:"cheatpaths"`
|
Cheatpaths []cp.Cheatpath `yaml:"cheatpaths"`
|
||||||
Style string `yaml:"style"`
|
Style string `yaml:"style"`
|
||||||
Formatter string `yaml:"formatter"`
|
Formatter string `yaml:"formatter"`
|
||||||
|
Pager string `yaml:"pager"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// New returns a new Config struct
|
// New returns a new Config struct
|
||||||
@ -111,5 +113,10 @@ func New(opts map[string]interface{}, confPath string, resolve bool) (Config, er
|
|||||||
conf.Formatter = "terminal16m"
|
conf.Formatter = "terminal16m"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if a pager was not provided, set a default
|
||||||
|
if strings.TrimSpace(conf.Pager) == "" {
|
||||||
|
conf.Pager = ""
|
||||||
|
}
|
||||||
|
|
||||||
return conf, nil
|
return conf, nil
|
||||||
}
|
}
|
||||||
|
37
internal/display/display.go
Normal file
37
internal/display/display.go
Normal file
@ -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)
|
||||||
|
}
|
||||||
|
}
|
1
vendor/gopkg.in/yaml.v2/apic.go
generated
vendored
1
vendor/gopkg.in/yaml.v2/apic.go
generated
vendored
@ -86,6 +86,7 @@ func yaml_emitter_initialize(emitter *yaml_emitter_t) {
|
|||||||
raw_buffer: make([]byte, 0, output_raw_buffer_size),
|
raw_buffer: make([]byte, 0, output_raw_buffer_size),
|
||||||
states: make([]yaml_emitter_state_t, 0, initial_stack_size),
|
states: make([]yaml_emitter_state_t, 0, initial_stack_size),
|
||||||
events: make([]yaml_event_t, 0, initial_queue_size),
|
events: make([]yaml_event_t, 0, initial_queue_size),
|
||||||
|
best_width: -1,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
2
vendor/modules.txt
vendored
2
vendor/modules.txt
vendored
@ -63,6 +63,6 @@ golang.org/x/sys/unix
|
|||||||
# gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0
|
# gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0
|
||||||
## explicit
|
## explicit
|
||||||
gopkg.in/yaml.v1
|
gopkg.in/yaml.v1
|
||||||
# gopkg.in/yaml.v2 v2.2.8
|
# gopkg.in/yaml.v2 v2.3.0
|
||||||
## explicit
|
## explicit
|
||||||
gopkg.in/yaml.v2
|
gopkg.in/yaml.v2
|
||||||
|
Reference in New Issue
Block a user