diff --git a/Makefile b/Makefile index 796606a..8f81521 100644 --- a/Makefile +++ b/Makefile @@ -86,7 +86,7 @@ $(dist_dir)/cheat-linux-arm64: prepare # cheat-windows-amd64 $(dist_dir)/cheat-windows-amd64.exe: prepare GOARCH=amd64 GOOS=windows \ - $(GO) build $(BUILD_FLAGS) -o $@ $(cmd_dir) && $(ZIP) $@.zip $@ + $(GO) build $(BUILD_FLAGS) -o $@ $(cmd_dir) && $(ZIP) $@.zip $@ -j # ./dist $(dist_dir): @@ -180,6 +180,11 @@ prepare: | $(dist_dir) clean generate vendor fmt lint vet test docker-setup: $(DOCKER) build -t $(docker_image) -f Dockerfile . +## docker-run: shell into the development docker container +.PHONY: docker-run +docker-run: + $(DOCKER) run -v `pwd`:/app -ti $(docker_image) sh + ## docker-sh: shell into the docker development container .PHONY: docker-sh docker-sh: diff --git a/cmd/cheat/cmd_edit.go b/cmd/cheat/cmd_edit.go index 7ab2b0e..ee17399 100644 --- a/cmd/cheat/cmd_edit.go +++ b/cmd/cheat/cmd_edit.go @@ -4,7 +4,7 @@ import ( "fmt" "os" "os/exec" - "path" + "path/filepath" "strings" "github.com/cheat/cheat/internal/cheatpath" @@ -58,10 +58,10 @@ func cmdEdit(opts map[string]interface{}, conf config.Config) { } // compute the new edit path - editpath = path.Join(writepath.Path, sheet.Title) + editpath = filepath.Join(writepath.Path, sheet.Title) // create any necessary subdirectories - dirs := path.Dir(editpath) + dirs := filepath.Dir(editpath) if dirs != "." { if err := os.MkdirAll(dirs, 0755); err != nil { fmt.Fprintf(os.Stderr, "failed to create directory: %s, %v\n", dirs, err) @@ -87,10 +87,10 @@ func cmdEdit(opts map[string]interface{}, conf config.Config) { } // compute the new edit path - editpath = path.Join(writepath.Path, cheatsheet) + editpath = filepath.Join(writepath.Path, cheatsheet) // create any necessary subdirectories - dirs := path.Dir(editpath) + dirs := filepath.Dir(editpath) if dirs != "." { if err := os.MkdirAll(dirs, 0755); err != nil { fmt.Fprintf(os.Stderr, "failed to create directory: %s, %v\n", dirs, err) diff --git a/cmd/cheat/cmd_init.go b/cmd/cheat/cmd_init.go index 1c2891e..47bdde7 100644 --- a/cmd/cheat/cmd_init.go +++ b/cmd/cheat/cmd_init.go @@ -3,7 +3,7 @@ package main import ( "fmt" "os" - "path" + "path/filepath" "runtime" "strings" @@ -42,11 +42,11 @@ func cmdInit() { // determine the appropriate paths for config data and (optional) community // cheatsheets based on the user's platform confpath := confpaths[0] - confdir := path.Dir(confpath) + confdir := filepath.Dir(confpath) // create paths for community and personal cheatsheets - community := path.Join(confdir, "/cheatsheets/community") - personal := path.Join(confdir, "/cheatsheets/personal") + community := filepath.Join(confdir, "cheatsheets", "community") + personal := filepath.Join(confdir, "cheatsheets", "personal") // template the above paths into the default configs configs = strings.Replace(configs, "COMMUNITY_PATH", community, -1) diff --git a/cmd/cheat/main.go b/cmd/cheat/main.go index 608cf41..b3ec86a 100755 --- a/cmd/cheat/main.go +++ b/cmd/cheat/main.go @@ -16,7 +16,7 @@ import ( "github.com/cheat/cheat/internal/installer" ) -const version = "4.2.3" +const version = "4.2.4" func main() { diff --git a/cmd/cheat/str_config.go b/cmd/cheat/str_config.go index f903eb6..4970017 100644 --- a/cmd/cheat/str_config.go +++ b/cmd/cheat/str_config.go @@ -9,22 +9,23 @@ import ( func configs() string { return strings.TrimSpace(`--- # The editor to use with 'cheat -e '. Defaults to $EDITOR or $VISUAL. -editor: vim +# editor: vim # Should 'cheat' always colorize output? -colorize: true +colorize: false # Which 'chroma' colorscheme should be applied to the output? # Options are available here: # https://github.com/alecthomas/chroma/tree/master/styles -style: monokai +# style: monokai # Which 'chroma' "formatter" should be applied? # One of: "terminal", "terminal256", "terminal16m" -formatter: terminal16m +formatter: terminal # Through which pager should output be piped? (Unset this key for no pager.) -pager: less -FRX +pager: more +# pager: less -FRX # <- recommended where available # The paths at which cheatsheets are available. Tags associated with a cheatpath # are automatically attached to all cheatsheets residing on that path. diff --git a/configs/conf.yml b/configs/conf.yml index 8b9bfca..31565bd 100644 --- a/configs/conf.yml +++ b/configs/conf.yml @@ -1,21 +1,22 @@ --- # The editor to use with 'cheat -e '. Defaults to $EDITOR or $VISUAL. -editor: vim +# editor: vim # Should 'cheat' always colorize output? -colorize: true +colorize: false # Which 'chroma' colorscheme should be applied to the output? # Options are available here: # https://github.com/alecthomas/chroma/tree/master/styles -style: monokai +# style: monokai # Which 'chroma' "formatter" should be applied? # One of: "terminal", "terminal256", "terminal16m" -formatter: terminal16m +formatter: terminal # Through which pager should output be piped? (Unset this key for no pager.) -pager: less -FRX +pager: more +# pager: less -FRX # <- recommended where available # The paths at which cheatsheets are available. Tags associated with a cheatpath # are automatically attached to all cheatsheets residing on that path. diff --git a/internal/config/config.go b/internal/config/config.go index 7ae0901..1a068fd 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -4,7 +4,9 @@ import ( "fmt" "io/ioutil" "os" + "os/exec" "path/filepath" + "runtime" "strings" cp "github.com/cheat/cheat/internal/cheatpath" @@ -98,8 +100,22 @@ func New(opts map[string]interface{}, confPath string, resolve bool) (Config, er conf.Editor = os.Getenv("VISUAL") } else if os.Getenv("EDITOR") != "" { conf.Editor = os.Getenv("EDITOR") + } else if runtime.GOOS == "windows" { + conf.Editor = "notepad" } else { - return Config{}, fmt.Errorf("no editor set") + // try to fall back to `nano` + path, err := exec.LookPath("nano") + if err != nil { + return Config{}, fmt.Errorf("failed to locate nano: %s", err) + } + + // use `nano` if we found it + if path != "" { + conf.Editor = "nano" + // otherwise, give up + } else { + return Config{}, fmt.Errorf("no editor set") + } } } @@ -110,12 +126,13 @@ func New(opts map[string]interface{}, confPath string, resolve bool) (Config, er // if a chroma formatter was not provided, set a default if conf.Formatter == "" { - conf.Formatter = "terminal16m" + conf.Formatter = "terminal" } - // if a pager was not provided, set a default - if strings.TrimSpace(conf.Pager) == "" { - conf.Pager = "" + // attempt to fall back to `PAGER` if a pager is not specified in configs + conf.Pager = strings.TrimSpace(conf.Pager) + if conf.Pager == "" && os.Getenv("PAGER") != "" { + conf.Pager = os.Getenv("PAGER") } return conf, nil diff --git a/internal/config/config_test.go b/internal/config/config_test.go index c6a1dac..9bb7f31 100644 --- a/internal/config/config_test.go +++ b/internal/config/config_test.go @@ -39,17 +39,17 @@ func TestConfigSuccessful(t *testing.T) { // assert that the cheatpaths are correct want := []cheatpath.Cheatpath{ cheatpath.Cheatpath{ - Path: filepath.Join(home, ".dotfiles/cheat/community"), + Path: filepath.Join(home, ".dotfiles", "cheat", "community"), ReadOnly: true, Tags: []string{"community"}, }, cheatpath.Cheatpath{ - Path: filepath.Join(home, ".dotfiles/cheat/work"), + Path: filepath.Join(home, ".dotfiles", "cheat", "work"), ReadOnly: false, Tags: []string{"work"}, }, cheatpath.Cheatpath{ - Path: filepath.Join(home, ".dotfiles/cheat/personal"), + Path: filepath.Join(home, ".dotfiles", "cheat", "personal"), ReadOnly: false, Tags: []string{"personal"}, }, @@ -85,8 +85,8 @@ func TestEmptyEditor(t *testing.T) { // initialize a config conf, err := New(map[string]interface{}{}, mock.Path("conf/empty.yml"), false) - if err == nil { - t.Errorf("failed to return an error on empty editor") + if err != nil { + t.Errorf("failed to initialize test: %v", err) } // set editor, and assert that it is respected diff --git a/internal/config/paths.go b/internal/config/paths.go index 8ce34bc..7818fbd 100644 --- a/internal/config/paths.go +++ b/internal/config/paths.go @@ -33,20 +33,20 @@ func Paths( // don't include the `XDG_CONFIG_HOME` path if that envvar is not set if xdgpath, ok := envvars["XDG_CONFIG_HOME"]; ok { - paths = append(paths, filepath.Join(xdgpath, "/cheat/conf.yml")) + paths = append(paths, filepath.Join(xdgpath, "cheat", "conf.yml")) } paths = append(paths, []string{ - filepath.Join(home, ".config/cheat/conf.yml"), - filepath.Join(home, ".cheat/conf.yml"), + filepath.Join(home, ".config", "cheat", "conf.yml"), + filepath.Join(home, ".cheat", "conf.yml"), "/etc/cheat/conf.yml", }...) return paths, nil case "windows": return []string{ - filepath.Join(envvars["APPDATA"], "/cheat/conf.yml"), - filepath.Join(envvars["PROGRAMDATA"], "/cheat/conf.yml"), + filepath.Join(envvars["APPDATA"], "cheat", "conf.yml"), + filepath.Join(envvars["PROGRAMDATA"], "cheat", "conf.yml"), }, nil default: return []string{}, fmt.Errorf("unsupported os: %s", sys) diff --git a/internal/installer/run.go b/internal/installer/run.go index 50267bf..02133b6 100644 --- a/internal/installer/run.go +++ b/internal/installer/run.go @@ -3,7 +3,7 @@ package installer import ( "fmt" "os" - "path" + "path/filepath" "strings" "github.com/cheat/cheat/internal/config" @@ -14,11 +14,11 @@ func Run(configs string, confpath string) error { // determine the appropriate paths for config data and (optional) community // cheatsheets based on the user's platform - confdir := path.Dir(confpath) + confdir := filepath.Dir(confpath) // create paths for community and personal cheatsheets - community := path.Join(confdir, "/cheatsheets/community") - personal := path.Join(confdir, "/cheatsheets/personal") + community := filepath.Join(confdir, "cheatsheets", "community") + personal := filepath.Join(confdir, "cheatsheets", "personal") // template the above paths into the default configs configs = strings.Replace(configs, "COMMUNITY_PATH", community, -1) @@ -36,11 +36,13 @@ func Run(configs string, confpath string) error { // clone the community cheatsheets if so instructed if yes { // clone the community cheatsheets + fmt.Printf("Cloning community cheatsheets to %s.\n", community) if err := clone(community); err != nil { return fmt.Errorf("failed to clone cheatsheets: %v", err) } // also create a directory for personal cheatsheets + fmt.Printf("Cloning personal cheatsheets to %s.\n", personal) if err := os.MkdirAll(personal, os.ModePerm); err != nil { return fmt.Errorf("failed to create directory: %v", err) } diff --git a/internal/sheet/copy.go b/internal/sheet/copy.go index 30a206f..47cf491 100644 --- a/internal/sheet/copy.go +++ b/internal/sheet/copy.go @@ -4,7 +4,7 @@ import ( "fmt" "io" "os" - "path" + "path/filepath" ) // Copy copies a cheatsheet to a new location @@ -22,7 +22,7 @@ func (s *Sheet) Copy(dest string) error { defer infile.Close() // create any necessary subdirectories - dirs := path.Dir(dest) + dirs := filepath.Dir(dest) if dirs != "." { if err := os.MkdirAll(dirs, 0755); err != nil { return fmt.Errorf("failed to create directory: %s, %v", dirs, err)