Compare commits

...

20 Commits
3.3.2 ... 3.5.0

Author SHA1 Message Date
219db679e1 Merge pull request #535 from chrisallenlane/master
chore: bumps version to 3.5.0
2020-02-02 14:54:46 -05:00
53177cb09d chore: bumps version to 3.5.0
Squashed commit of the following:

commit 8b74d50f1f
Author: Chris Lane <chris@chris-allen-lane.com>
Date:   Sun Feb 2 14:40:23 2020 -0500

    chore: updates README

    Edits the `README` to provid updated information regarding the shell
    autocompletion scripts and `fzf` integration.

commit 9868ba2d68
Author: Chris Lane <chris@chris-allen-lane.com>
Date:   Sun Feb 2 14:39:04 2020 -0500

    chore: modifies envvar check

    Modifies the `CHEAT_USE_FZF` envvar check within the bash autocompletion
    script for clarity.

commit ac1012f743
Author: Chris Lane <chris@chris-allen-lane.com>
Date:   Sun Feb 2 14:25:34 2020 -0500

    chore: renames autocompletion scripts

    Renames autocompletion scripts to conform with the conventions
    established in `scop/bash-completion`.

commit c8747bd91d
Author: Chris Lane <chris@chris-allen-lane.com>
Date:   Sun Feb 2 14:23:03 2020 -0500

    feat: improved bash autocompletions

    - Dramatically improves quality of bash autocompletions

    - Provides optional integration with `fzf`

commit 825bd0139d
Author: Chris Lane <chris@chris-allen-lane.com>
Date:   Sun Feb 2 09:19:46 2020 -0500

    chore: deletes `fzf.bash`

    Deletes `fzf.bash`, which was always intended to be a temporary
    placeholder anticipating future improvements.
2020-02-02 14:50:16 -05:00
ef7a41f9a9 Merge pull request #533 from chrisallenlane/master
chore: creates `make coverage` target
2020-01-31 14:07:20 -05:00
008316d030 chore: creates make coverage target
Creates a `make coverage` target that generates a unit-testing coverage
report.
2020-01-31 14:01:57 -05:00
a59c019642 chore: removes bin directory
Removes the `bin` directory. It has been obsoleted by the `Makefile`,
and no downstream packages appeared to depend on it.
2020-01-31 13:30:21 -05:00
57225442be Merge pull request #532 from chrisallenlane/auto-config-bugfix
fix(config generation): issue #501
2020-01-30 20:12:24 -05:00
2c7ce48859 chore: multi-os builds on travis
Modifies `.travis.yml` to specify that builds be performed on both Linux
and MacOSX. Experimental.
2020-01-30 20:08:11 -05:00
a3fe4f40bb chore: bumps version to 3.4.1 2020-01-30 20:06:06 -05:00
506fb8be15 fix: XDG_CONFIG_HOME mishandling
Attempts to resolve an issue regarding automatic config file generation,
as referenced in #501. This issue is believed occur when
`XDG_CONFIG_HOME` is unset.
2020-01-30 19:59:35 -05:00
408e944eea chore: refactors config.path (small)
Performs a minor refactoring on `config.Paths` to consistently use
`path.Join` when computing config directory paths. Previously, both
`path.Join` and `fmt.Sprintf` were being used, strictly due to an
oversight.
2020-01-30 19:45:02 -05:00
8a313b92ca chore: implements unit-tests for config.Paths 2020-01-30 19:25:53 -05:00
6912771c39 chore: refactors config.Paths
Refactors the reading of multiple envvars out of `config.Paths` in order
to facilitate cleaner unit-testing.
2020-01-30 18:48:36 -05:00
d4c6200702 Merge pull request #531 from chrisallenlane/auto-config
feat(configs): config auto-generation
2020-01-29 14:22:12 -05:00
9251849d23 chore: bumps version to 3.4.0 2020-01-29 14:17:06 -05:00
313b5ebd27 feat: config auto-generation
`cheat` now attempts to auto-generate a config file if one cannot be
found on the filesystem.
2020-01-29 14:08:03 -05:00
ca91b25b02 fix: logging on failed configs
Fixes an issue whereby the error message generated when a config file
could not be loaded (due to a symlink resolution failure) would fail to
print the config file path to `stderr`.
2020-01-29 14:05:27 -05:00
bbf6af50b1 chore: modifies example config
- Generally reduces the complexity demonstrated in the example configs.
  The prior complexity appears to have confused some new users.

- Removes the `dotfiles` references in the example configs. This idiom
  likewise appears to have confused some new users.

- Adds some instruction regarding how to download and configure the
  "community" cheatsheets (`cheat/cheatsheets`).
2020-01-29 14:01:19 -05:00
9f05442bce fix: Makefile
Resolves an error whereby `make build` would fail to call `go generate`
prior to calling `go build`.
2020-01-29 13:59:31 -05:00
3fc4c2f89e chore: Makefile
Makes some adjustments to the behaviors of `make tags` and `make
distclean`.
2020-01-29 09:36:59 -05:00
9e88ff2642 chore: Makefile adjustment
Previously, `build-release` would produce `.gz` files which had the
execute permission set. This modifies the `Makefile` to `chmod -x` the
`.gz` files after compression.
2020-01-29 09:11:06 -05:00
16 changed files with 401 additions and 103 deletions

View File

@ -3,6 +3,10 @@ language: go
go: go:
- 1.13.x - 1.13.x
os:
- linux
- osx
env: env:
- GO111MODULE=on - GO111MODULE=on

View File

@ -21,6 +21,7 @@ ZIP := zip -m
# build flags # build flags
BUILD_FLAGS := -ldflags="-s -w" -mod vendor -trimpath BUILD_FLAGS := -ldflags="-s -w" -mod vendor -trimpath
GOBIN := GOBIN :=
TMPDIR := /tmp
# release binaries # release binaries
releases := \ releases := \
@ -33,7 +34,7 @@ releases := \
## build: builds an executable for your architecture ## build: builds an executable for your architecture
.PHONY: build .PHONY: build
build: $(dist_dir) build: $(dist_dir) clean generate
$(GO) build $(BUILD_FLAGS) -o $(dist_dir)/cheat $(cmd_dir) $(GO) build $(BUILD_FLAGS) -o $(dist_dir)/cheat $(cmd_dir)
## build-release: builds release executables ## build-release: builds release executables
@ -47,27 +48,27 @@ ci: | setup prepare build
# cheat-darwin-amd64 # cheat-darwin-amd64
$(dist_dir)/cheat-darwin-amd64: prepare $(dist_dir)/cheat-darwin-amd64: prepare
GOARCH=amd64 GOOS=darwin \ GOARCH=amd64 GOOS=darwin \
$(GO) build $(BUILD_FLAGS) -o $@ $(cmd_dir) && $(GZIP) $@ $(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 \
$(GO) build $(BUILD_FLAGS) -o $@ $(cmd_dir) && $(GZIP) $@ $(GO) build $(BUILD_FLAGS) -o $@ $(cmd_dir) && $(GZIP) $@ && chmod -x $@.gz
# cheat-linux-arm5 # cheat-linux-arm5
$(dist_dir)/cheat-linux-arm5: prepare $(dist_dir)/cheat-linux-arm5: prepare
GOARCH=arm GOOS=linux GOARM=5 \ GOARCH=arm GOOS=linux GOARM=5 \
$(GO) build $(BUILD_FLAGS) -o $@ $(cmd_dir) && $(GZIP) $@ $(GO) build $(BUILD_FLAGS) -o $@ $(cmd_dir) && $(GZIP) $@ && chmod -x $@.gz
# cheat-linux-arm6 # cheat-linux-arm6
$(dist_dir)/cheat-linux-arm6: prepare $(dist_dir)/cheat-linux-arm6: prepare
GOARCH=arm GOOS=linux GOARM=6 \ GOARCH=arm GOOS=linux GOARM=6 \
$(GO) build $(BUILD_FLAGS) -o $@ $(cmd_dir) && $(GZIP) $@ $(GO) build $(BUILD_FLAGS) -o $@ $(cmd_dir) && $(GZIP) $@ && chmod -x $@.gz
# cheat-linux-arm7 # cheat-linux-arm7
$(dist_dir)/cheat-linux-arm7: prepare $(dist_dir)/cheat-linux-arm7: prepare
GOARCH=arm GOOS=linux GOARM=7 \ GOARCH=arm GOOS=linux GOARM=7 \
$(GO) build $(BUILD_FLAGS) -o $@ $(cmd_dir) && $(GZIP) $@ $(GO) build $(BUILD_FLAGS) -o $@ $(cmd_dir) && $(GZIP) $@ && chmod -x $@.gz
# cheat-windows-amd64 # cheat-windows-amd64
$(dist_dir)/cheat-windows-amd64.exe: prepare $(dist_dir)/cheat-windows-amd64.exe: prepare
@ -95,7 +96,7 @@ clean: $(dist_dir)
## distclean: removes the tags file ## distclean: removes the tags file
.PHONY: distclean .PHONY: distclean
distclean: distclean:
$(RM) tags $(RM) -f tags
## setup: installs revive (linter) and scc (sloc tool) ## setup: installs revive (linter) and scc (sloc tool)
.PHONY: setup .PHONY: setup
@ -110,7 +111,7 @@ sloc:
## tags: builds a tags file ## tags: builds a tags file
.PHONY: tags .PHONY: tags
tags: tags:
$(CTAGS) -R . --exclude=vendor $(CTAGS) -R --exclude=vendor --languages=go
## vendor: downloads, tidies, and verifies dependencies ## vendor: downloads, tidies, and verifies dependencies
.PHONY: vendor .PHONY: vendor
@ -137,6 +138,12 @@ vet:
test: test:
$(GO) test ./... $(GO) test ./...
## coverage: generates a test coverage report
.PHONY: coverage
coverage:
$(GO) test ./... -coverprofile=$(TMPDIR)/cheat-coverage.out && \
$(GO) tool cover -html=$(TMPDIR)/cheat-coverage.out
## check: formats, lints, vets, vendors, and run unit-tests ## check: formats, lints, vets, vendors, and run unit-tests
.PHONY: check .PHONY: check
check: | vendor fmt lint vet test check: | vendor fmt lint vet test

View File

@ -193,9 +193,17 @@ cheat -p personal -t networking --regex -s '(?:[0-9]{1,3}\.){3}[0-9]{1,3}'
Advanced Usage Advanced Usage
-------------- --------------
`cheat` may be integrated with [fzf][]. See [fzf.bash][bash] for instructions. Shell autocompletion is currently available for the `bash` and `fish` shells.
(Support for other shells will be added in future releases.) Copy the relevant [completion script][completion-scripts] into the appropriate
directory on your filesystem to enable autocompletion. (This directory will
vary depending on operating system and shell specifics.)
Additionally, `cheat` supports enhanced autocompletion via integration with
[fzf][]. (This feature is currently available on bash only.) To enable `fzf`
integration:
1. Ensure that `fzf` is available on your `$PATH`
2. Set an envvar: `export CHEAT_USE_FZF=true`
[Releases]: https://github.com/cheat/cheat/releases [Releases]: https://github.com/cheat/cheat/releases
[bash]: https://github.com/cheat/cheat/blob/master/scripts/fzf.bash [bash]: https://github.com/cheat/cheat/blob/master/scripts/fzf.bash

View File

@ -1,15 +0,0 @@
#!/bin/bash
# TODO: this script has been made obsolete by the Makefile, yet downstream
# package managers plausibly rely on it for compiling locally. Remove this file
# after downstream maintainers have had time to modify their packages to simply
# invoke `make` in the project root.
# locate the cheat project root
BINDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
APPDIR=$(readlink -f "$BINDIR/..")
# compile the executable
cd $APPDIR
make

View File

@ -6,6 +6,7 @@ import (
"fmt" "fmt"
"os" "os"
"runtime" "runtime"
"strings"
"github.com/docopt/docopt-go" "github.com/docopt/docopt-go"
@ -13,7 +14,7 @@ import (
"github.com/cheat/cheat/internal/config" "github.com/cheat/cheat/internal/config"
) )
const version = "3.3.2" const version = "3.5.0"
func main() { func main() {
@ -31,13 +32,42 @@ func main() {
os.Exit(0) os.Exit(0)
} }
// load the config file // read the envvars into a map of strings
confpath, err := config.Path(runtime.GOOS) envvars := map[string]string{}
for _, e := range os.Environ() {
pair := strings.SplitN(e, "=", 2)
envvars[pair[0]] = pair[1]
}
// load the os-specifc paths at which the config file may be located
confpaths, err := config.Paths(runtime.GOOS, envvars)
if err != nil { if err != nil {
fmt.Fprintln(os.Stderr, "could not locate config file") fmt.Fprintf(os.Stderr, "failed to load config: %v\n", err)
os.Exit(1) os.Exit(1)
} }
// search for the config file in the above paths
confpath, err := config.Path(confpaths)
if err != nil {
// the config file does not exist, so we'll try to create one
if err = config.Init(confpaths[0], configs()); err != nil {
fmt.Fprintf(
os.Stderr,
"failed to create config file: %s: %v\n",
confpaths[0],
err,
)
os.Exit(1)
}
confpath = confpaths[0]
fmt.Printf("Created config file: %s\n", confpath)
fmt.Println("Please edit this file now to configure cheat.")
os.Exit(0)
}
// initialize the configs // initialize the configs
conf, err := config.New(opts, confpath, true) conf, err := config.New(opts, confpath, true)
if err != nil { if err != nil {

View File

@ -43,22 +43,23 @@ cheatpaths:
# #
# Note that the paths and tags listed below are just examples. You may freely # Note that the paths and tags listed below are just examples. You may freely
# change them to suit your needs. # change them to suit your needs.
#
# TODO: regarding community cheatsheets: these must be installed separately.
# You may download them here:
#
# https://github.com/cheat/cheatsheets
#
# Once downloaded, ensure that 'path' below points to the location at which
# you downloaded the community cheatsheets.
- name: community - name: community
path: ~/.dotfiles/cheat/community path: ~/cheat/cheatsheets/community
tags: [ community ] tags: [ community ]
readonly: true readonly: true
# Maybe your company or department maintains a repository of cheatsheets as
# well. It's probably sensible to list those second.
- name: work
path: ~/.dotfiles/cheat/work
tags: [ work ]
readonly: false
# If you have personalized cheatsheets, list them last. They will take # If you have personalized cheatsheets, list them last. They will take
# precedence over the more global cheatsheets. # precedence over the more global cheatsheets.
- name: personal - name: personal
path: ~/.dotfiles/cheat/personal path: ~/cheat/cheatsheets/personal
tags: [ personal ] tags: [ personal ]
readonly: false readonly: false

View File

@ -34,22 +34,23 @@ cheatpaths:
# #
# Note that the paths and tags listed below are just examples. You may freely # Note that the paths and tags listed below are just examples. You may freely
# change them to suit your needs. # change them to suit your needs.
#
# TODO: regarding community cheatsheets: these must be installed separately.
# You may download them here:
#
# https://github.com/cheat/cheatsheets
#
# Once downloaded, ensure that 'path' below points to the location at which
# you downloaded the community cheatsheets.
- name: community - name: community
path: ~/.dotfiles/cheat/community path: ~/cheat/cheatsheets/community
tags: [ community ] tags: [ community ]
readonly: true readonly: true
# Maybe your company or department maintains a repository of cheatsheets as
# well. It's probably sensible to list those second.
- name: work
path: ~/.dotfiles/cheat/work
tags: [ work ]
readonly: false
# If you have personalized cheatsheets, list them last. They will take # If you have personalized cheatsheets, list them last. They will take
# precedence over the more global cheatsheets. # precedence over the more global cheatsheets.
- name: personal - name: personal
path: ~/.dotfiles/cheat/personal path: ~/cheat/cheatsheets/personal
tags: [ personal ] tags: [ personal ]
readonly: false readonly: false

View File

@ -75,14 +75,16 @@ func New(opts map[string]interface{}, confPath string, resolve bool) (Config, er
// `resolve` is a switch that allows us to turn off symlink resolution when // `resolve` is a switch that allows us to turn off symlink resolution when
// running the config tests. // running the config tests.
if resolve { if resolve {
expanded, err = filepath.EvalSymlinks(expanded) evaled, err := filepath.EvalSymlinks(expanded)
if err != nil { if err != nil {
return Config{}, fmt.Errorf( return Config{}, fmt.Errorf(
"failed to resolve symlink: %s, %v", "failed to resolve symlink: %s: %v",
expanded, expanded,
err, err,
) )
} }
expanded = evaled
} }
conf.Cheatpaths[i].Path = expanded conf.Cheatpaths[i].Path = expanded

24
internal/config/init.go Normal file
View File

@ -0,0 +1,24 @@
package config
import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
)
// Init initializes a config file
func Init(confpath string, configs string) error {
// assert that the config directory exists
if err := os.MkdirAll(filepath.Dir(confpath), 0755); err != nil {
return fmt.Errorf("failed to create directory: %v", err)
}
// write the config file
if err := ioutil.WriteFile(confpath, []byte(configs), 0644); err != nil {
return fmt.Errorf("failed to create file: %v", err)
}
return nil
}

View File

@ -3,43 +3,10 @@ package config
import ( import (
"fmt" "fmt"
"os" "os"
"path"
"github.com/mitchellh/go-homedir"
) )
// Path returns the config file path // Path returns the config file path
func Path(sys string) (string, error) { func Path(paths []string) (string, error) {
var paths []string
// if CHEAT_CONFIG_PATH is set, return it
if os.Getenv("CHEAT_CONFIG_PATH") != "" {
// expand ~
expanded, err := homedir.Expand(os.Getenv("CHEAT_CONFIG_PATH"))
if err != nil {
return "", fmt.Errorf("failed to expand ~: %v", err)
}
return expanded, nil
}
switch sys {
case "darwin", "linux", "freebsd":
paths = []string{
path.Join(os.Getenv("XDG_CONFIG_HOME"), "/cheat/conf.yml"),
path.Join(os.Getenv("HOME"), ".config/cheat/conf.yml"),
path.Join(os.Getenv("HOME"), ".cheat/conf.yml"),
}
case "windows":
paths = []string{
fmt.Sprintf("%s/cheat/conf.yml", os.Getenv("APPDATA")),
fmt.Sprintf("%s/cheat/conf.yml", os.Getenv("PROGRAMDATA")),
}
default:
return "", fmt.Errorf("unsupported os: %s", sys)
}
// check if the config file exists on any paths // check if the config file exists on any paths
for _, p := range paths { for _, p := range paths {

50
internal/config/paths.go Normal file
View File

@ -0,0 +1,50 @@
package config
import (
"fmt"
"path"
"github.com/mitchellh/go-homedir"
)
// Paths returns config file paths that are appropriate for the operating
// system
func Paths(sys string, envvars map[string]string) ([]string, error) {
// if `CHEAT_CONFIG_PATH` is set, expand ~ and return it
if confpath, ok := envvars["CHEAT_CONFIG_PATH"]; ok {
// expand ~
expanded, err := homedir.Expand(confpath)
if err != nil {
return []string{}, fmt.Errorf("failed to expand ~: %v", err)
}
return []string{expanded}, nil
}
switch sys {
case "darwin", "linux", "freebsd":
paths := []string{}
// 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, path.Join(xdgpath, "/cheat/conf.yml"))
}
// `HOME` will always be set on a POSIX-compliant system, though
paths = append(paths, []string{
path.Join(envvars["HOME"], ".config/cheat/conf.yml"),
path.Join(envvars["HOME"], ".cheat/conf.yml"),
}...)
return paths, nil
case "windows":
return []string{
path.Join(envvars["APPDATA"], "/cheat/conf.yml"),
path.Join(envvars["PROGRAMDATA"], "/cheat/conf.yml"),
}, nil
default:
return []string{}, fmt.Errorf("unsupported os: %s", sys)
}
}

View File

@ -0,0 +1,165 @@
package config
import (
"reflect"
"testing"
"github.com/davecgh/go-spew/spew"
)
// TestValidatePathsNix asserts that the proper config paths are returned on
// *nix platforms
func TestValidatePathsNix(t *testing.T) {
// mock some envvars
envvars := map[string]string{
"HOME": "/home/foo",
"XDG_CONFIG_HOME": "/home/bar",
}
// specify the platforms to test
oses := []string{
"darwin",
"freebsd",
"linux",
}
// test each *nix os
for _, os := range oses {
// get the paths for the platform
paths, err := Paths(os, envvars)
if err != nil {
t.Errorf("paths returned an error: %v", err)
}
// specify the expected output
want := []string{
"/home/bar/cheat/conf.yml",
"/home/foo/.config/cheat/conf.yml",
"/home/foo/.cheat/conf.yml",
}
// assert that output matches expectations
if !reflect.DeepEqual(paths, want) {
t.Errorf(
"failed to return expected paths: want:\n%s, got:\n%s",
spew.Sdump(want),
spew.Sdump(paths),
)
}
}
}
// TestValidatePathsNixNoXDG asserts that the proper config paths are returned
// on *nix platforms when `XDG_CONFIG_HOME is not set
func TestValidatePathsNixNoXDG(t *testing.T) {
// mock some envvars
envvars := map[string]string{
"HOME": "/home/foo",
}
// specify the platforms to test
oses := []string{
"darwin",
"freebsd",
"linux",
}
// test each *nix os
for _, os := range oses {
// get the paths for the platform
paths, err := Paths(os, envvars)
if err != nil {
t.Errorf("paths returned an error: %v", err)
}
// specify the expected output
want := []string{
"/home/foo/.config/cheat/conf.yml",
"/home/foo/.cheat/conf.yml",
}
// assert that output matches expectations
if !reflect.DeepEqual(paths, want) {
t.Errorf(
"failed to return expected paths: want:\n%s, got:\n%s",
spew.Sdump(want),
spew.Sdump(paths),
)
}
}
}
// TestValidatePathsWindows asserts that the proper config paths are returned
// on Windows platforms
func TestValidatePathsWindows(t *testing.T) {
// mock some envvars
envvars := map[string]string{
"APPDATA": "/apps",
"PROGRAMDATA": "/programs",
}
// get the paths for the platform
paths, err := Paths("windows", envvars)
if err != nil {
t.Errorf("paths returned an error: %v", err)
}
// specify the expected output
want := []string{
"/apps/cheat/conf.yml",
"/programs/cheat/conf.yml",
}
// assert that output matches expectations
if !reflect.DeepEqual(paths, want) {
t.Errorf(
"failed to return expected paths: want:\n%s, got:\n%s",
spew.Sdump(want),
spew.Sdump(paths),
)
}
}
// TestValidatePathsUnsupported asserts that an error is returned on
// unsupported platforms
func TestValidatePathsUnsupported(t *testing.T) {
_, err := Paths("unsupported", map[string]string{})
if err == nil {
t.Errorf("failed to return error on unsupported platform")
}
}
// TestValidatePathsCheatConfigPath asserts that the proper config path is
// returned when `CHEAT_CONFIG_PATH` is explicitly specified.
func TestValidatePathsCheatConfigPath(t *testing.T) {
// mock some envvars
envvars := map[string]string{
"HOME": "/home/foo",
"XDG_CONFIG_HOME": "/home/bar",
"CHEAT_CONFIG_PATH": "/home/baz/conf.yml",
}
// get the paths for the platform
paths, err := Paths("linux", envvars)
if err != nil {
t.Errorf("paths returned an error: %v", err)
}
// specify the expected output
want := []string{
"/home/baz/conf.yml",
}
// assert that output matches expectations
if !reflect.DeepEqual(paths, want) {
t.Errorf(
"failed to return expected paths: want:\n%s, got:\n%s",
spew.Sdump(want),
spew.Sdump(paths),
)
}
}

View File

@ -1,9 +0,0 @@
function _cheat_autocomplete {
sheets=$(cheat -l | sed -n '2,$p'|cut -d' ' -f1)
COMPREPLY=()
if [ $COMP_CWORD = 1 ]; then
COMPREPLY=(`compgen -W "$sheets" -- $2`)
fi
}
complete -F _cheat_autocomplete cheat

74
scripts/cheat.bash Executable file
View File

@ -0,0 +1,74 @@
# cheat(1) completion -*- shell-script -*-
# generate cheatsheet completions, optionally using `fzf`
_cheat_complete_cheatsheets()
{
if [[ "$CHEAT_USE_FZF" = true ]]; then
FZF_COMPLETION_TRIGGER='' _fzf_complete "--no-multi" "$@" < <(
cheat -l | tail -n +2 | cut -d' ' -f1
)
else
COMPREPLY=( $(compgen -W "$(cheat -l | tail -n +2 | cut -d' ' -f1)" -- "$cur") )
fi
}
# generate tag completions, optionally using `fzf`
_cheat_complete_tags()
{
if [ "$CHEAT_USE_FZF" = true ]; then
FZF_COMPLETION_TRIGGER='' _fzf_complete "--no-multi" "$@" < <(cheat -T)
else
COMPREPLY=( $(compgen -W "$(cheat -T)" -- "$cur") )
fi
}
# implement the `cheat` autocompletions
_cheat()
{
local cur prev words cword split
_init_completion -s || return
# complete options that are currently being typed: `--col` => `--colorize`
if [[ $cur == -* ]]; then
COMPREPLY=( $(compgen -W '$(_parse_help "$1" | sed "s/=//g")' -- "$cur") )
[[ $COMPREPLY == *= ]] && compopt -o nospace
return
fi
# implement completions
case $prev in
--colorize|-c|\
--directories|-d|\
--init|\
--regex|-r|\
--search|-s|\
--tags|-T|\
--version|-v)
# noop the above, which should implement no completions
;;
--edit|-e)
_cheat_complete_cheatsheets
;;
--list|-l)
_cheat_complete_cheatsheets
;;
--path|-p)
COMPREPLY=( $(compgen -W "$(cheat -d | cut -d':' -f1)" -- "$cur") )
;;
--rm)
_cheat_complete_cheatsheets
;;
--tag|-t)
_cheat_complete_tags
;;
*)
_cheat_complete_cheatsheets
;;
esac
$split && return
} &&
complete -F _cheat cheat
# ex: filetype=sh

View File

@ -1,11 +0,0 @@
#!/bin/bash
# This function enables you to choose a cheatsheet to view by selecting output
# from `cheat -l`. `source` it in your shell to enable it. (Consider renaming
# or aliasing it to something convenient.)
# Arguments passed to this function (like --color) will be passed to the second
# invokation of `cheat`.
function cheat-fzf {
eval `cheat -l | tail -n +2 | fzf | awk -v vars="$*" '{ print "cheat " $1 " -t " $3, vars }'`
}