mirror of
				https://github.com/cheat/cheat.git
				synced 2025-11-04 07:45:28 +01:00 
			
		
		
		
	@@ -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 {
 | 
			
		||||
@@ -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)
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,7 @@
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"bytes"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"os"
 | 
			
		||||
	"regexp"
 | 
			
		||||
@@ -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"
 | 
			
		||||
)
 | 
			
		||||
@@ -79,16 +81,19 @@ func cmdList(opts map[string]interface{}, conf config.Config) {
 | 
			
		||||
		flattened = filtered
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// exit early if no cheatsheets are available
 | 
			
		||||
	// return exit code 2 if no cheatsheets are available
 | 
			
		||||
	if len(flattened) == 0 {
 | 
			
		||||
		os.Exit(0)
 | 
			
		||||
		os.Exit(2)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 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
 | 
			
		||||
	fmt.Fprintln(w, "title:\tfile:\ttags:")
 | 
			
		||||
	for _, sheet := range flattened {
 | 
			
		||||
		fmt.Fprintln(w, fmt.Sprintf(
 | 
			
		||||
			"%s\t%s\t%s",
 | 
			
		||||
@@ -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)
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -37,8 +37,8 @@ func cmdRemove(opts map[string]interface{}, conf config.Config) {
 | 
			
		||||
	// fail early if the requested cheatsheet does not exist
 | 
			
		||||
	sheet, ok := consolidated[cheatsheet]
 | 
			
		||||
	if !ok {
 | 
			
		||||
		fmt.Fprintln(os.Stderr, fmt.Sprintf("no cheatsheet found for '%s'.\n", cheatsheet))
 | 
			
		||||
		os.Exit(1)
 | 
			
		||||
		fmt.Fprintln(os.Stderr, fmt.Sprintf("No cheatsheet found for '%s'.\n", cheatsheet))
 | 
			
		||||
		os.Exit(2)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// fail early if the sheet is read-only
 | 
			
		||||
 
 | 
			
		||||
@@ -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"
 | 
			
		||||
)
 | 
			
		||||
@@ -45,7 +46,7 @@ func cmdSearch(opts map[string]interface{}, conf config.Config) {
 | 
			
		||||
		s, ok := consolidated[cheatsheet]
 | 
			
		||||
		if !ok {
 | 
			
		||||
			fmt.Printf("No cheatsheet found for '%s'.\n", cheatsheet)
 | 
			
		||||
			os.Exit(0)
 | 
			
		||||
			os.Exit(2)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		consolidated = map[string]sheet.Sheet{
 | 
			
		||||
@@ -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)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,7 @@ import (
 | 
			
		||||
	"os"
 | 
			
		||||
 | 
			
		||||
	"github.com/cheat/cheat/internal/config"
 | 
			
		||||
	"github.com/cheat/cheat/internal/display"
 | 
			
		||||
	"github.com/cheat/cheat/internal/sheets"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
@@ -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)
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -6,6 +6,7 @@ import (
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
	"github.com/cheat/cheat/internal/config"
 | 
			
		||||
	"github.com/cheat/cheat/internal/display"
 | 
			
		||||
	"github.com/cheat/cheat/internal/sheets"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
@@ -38,7 +39,7 @@ func cmdView(opts map[string]interface{}, conf config.Config) {
 | 
			
		||||
	sheet, ok := consolidated[cheatsheet]
 | 
			
		||||
	if !ok {
 | 
			
		||||
		fmt.Printf("No cheatsheet found for '%s'.\n", cheatsheet)
 | 
			
		||||
		os.Exit(0)
 | 
			
		||||
		os.Exit(2)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// apply colorization if requested
 | 
			
		||||
@@ -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)
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -17,7 +17,7 @@ import (
 | 
			
		||||
	"github.com/cheat/cheat/internal/installer"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const version = "3.10.1"
 | 
			
		||||
const version = "4.0.0"
 | 
			
		||||
 | 
			
		||||
func main() {
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -23,6 +23,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.
 | 
			
		||||
#
 | 
			
		||||
 
 | 
			
		||||
@@ -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.
 | 
			
		||||
#
 | 
			
		||||
 
 | 
			
		||||
@@ -203,6 +203,13 @@ If set, autocompletion scripts will attempt to integrate with
 | 
			
		||||
\f[B]fzf\f[].
 | 
			
		||||
.RS
 | 
			
		||||
.RE
 | 
			
		||||
.SH RETURN VALUES
 | 
			
		||||
.IP "0." 3
 | 
			
		||||
Successful termination
 | 
			
		||||
.IP "1." 3
 | 
			
		||||
Application error
 | 
			
		||||
.IP "2." 3
 | 
			
		||||
Cheatsheet(s) not found
 | 
			
		||||
.SH BUGS
 | 
			
		||||
.PP
 | 
			
		||||
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**.
 | 
			
		||||
 | 
			
		||||
RETURN VALUES
 | 
			
		||||
=============
 | 
			
		||||
 | 
			
		||||
0. Successful termination
 | 
			
		||||
 | 
			
		||||
1. Application error
 | 
			
		||||
 | 
			
		||||
2. Cheatsheet(s) not found
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
BUGS
 | 
			
		||||
====
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,7 @@ import (
 | 
			
		||||
	"io/ioutil"
 | 
			
		||||
	"os"
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
	cp "github.com/cheat/cheat/internal/cheatpath"
 | 
			
		||||
 | 
			
		||||
@@ -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
 | 
			
		||||
@@ -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
									
								
								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)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user