mirror of
https://github.com/cheat/cheat.git
synced 2025-09-01 09:38:29 +02:00
Compare commits
146 Commits
Author | SHA1 | Date | |
---|---|---|---|
82e1c27494 | |||
45beeb2edb | |||
c2c479b36c | |||
cb0243e7fc | |||
e5d04d41ea | |||
2474ea4fb1 | |||
7467c9fbc0 | |||
dfba3da003 | |||
ad7ad64a75 | |||
c4dcfd5da0 | |||
278a5d9154 | |||
9fa0c466fd | |||
4e9b2928b3 | |||
fa5eb44be8 | |||
49afd7c16b | |||
59d5c96c24 | |||
8e602b0e93 | |||
fb04cb1fcd | |||
d42726101e | |||
93b3a711f5 | |||
9c3d41c8bd | |||
4eeec6c868 | |||
1b17ab1914 | |||
477650ee44 | |||
c4dd3b52fd | |||
e8a0ea0dc3 | |||
992ee66a56 | |||
c9840c2d6f | |||
bd53768f67 | |||
8092687956 | |||
16ade50672 | |||
62c80d76eb | |||
3e67eaa3b7 | |||
38b13655fe | |||
749d5c1182 | |||
521f83377c | |||
b15ff10537 | |||
5288bd0c1c | |||
bddbee4158 | |||
ce27cf2cc0 | |||
5733b1d6d4 | |||
2d221050d8 | |||
ce37b670c7 | |||
47a9eeb4fd | |||
be56c9cf0c | |||
7be57cb01c | |||
8453af8601 | |||
6e388c3693 | |||
b13246978a | |||
a39d36cd34 | |||
87cba04ff2 | |||
bc623da74b | |||
a6c25d4b9c | |||
e24ac2b385 | |||
e0c35a74d4 | |||
3e4c1818a9 | |||
7b4a268ebd | |||
f7183aa17a | |||
1ce6c29e6a | |||
219db679e1 | |||
53177cb09d | |||
ef7a41f9a9 | |||
008316d030 | |||
a59c019642 | |||
57225442be | |||
2c7ce48859 | |||
a3fe4f40bb | |||
506fb8be15 | |||
408e944eea | |||
8a313b92ca | |||
6912771c39 | |||
d4c6200702 | |||
9251849d23 | |||
313b5ebd27 | |||
ca91b25b02 | |||
bbf6af50b1 | |||
9f05442bce | |||
3fc4c2f89e | |||
9e88ff2642 | |||
e3764b81e7 | |||
3786ac96a5 | |||
4cb7a3b42c | |||
ff6a866abe | |||
2e7ccb2a68 | |||
126231db1f | |||
91f0d02de2 | |||
815e714fb4 | |||
bd3986a051 | |||
f47b75edc0 | |||
180ee20f77 | |||
9b86c583f8 | |||
e1f7828869 | |||
7f3ae2ab30 | |||
bbd03a1bb8 | |||
326c54147b | |||
efcedaedec | |||
301cbefb0c | |||
9a481f7e75 | |||
e2920bd922 | |||
973a1f59ea | |||
3afea0972c | |||
f86633ca1c | |||
a01a3491a4 | |||
daa43d3867 | |||
e94a1e22df | |||
5046975a0f | |||
198156a299 | |||
a7067279df | |||
a8e6fdb18a | |||
bbfa4efdb7 | |||
741ad91389 | |||
573d43a7e6 | |||
879e8f2be4 | |||
eab3c14f1f | |||
9a6130b6b7 | |||
aeaf01e1de | |||
09c29a322f | |||
0525b2331b | |||
27a4991a3a | |||
4dda412dcb | |||
bfb60764ad | |||
3a97c680bb | |||
edc0fe41ef | |||
9e49bf8e9c | |||
50dc3c8b29 | |||
e08a4f3cec | |||
d6ebe0799d | |||
51aaaf3423 | |||
197ff58796 | |||
b8f512aae8 | |||
e7a1a296e3 | |||
f7c093bec0 | |||
c47b7f81aa | |||
52081b97ac | |||
1dda796e7c | |||
67469b0afa | |||
4f8431a600 | |||
5301442f7c | |||
cd45efcdec | |||
c31786fc5b | |||
934c36ad77 | |||
2c0099c28a | |||
33ac3d34d1 | |||
749173f1f6 | |||
33e33dc7b7 | |||
201cd1d629 |
23
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
23
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Submit a bug report
|
||||
title: ''
|
||||
labels: 'bug'
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
Thanks for submitting a bug report. Please provide the following information:
|
||||
|
||||
**A description of the problem**
|
||||
Describe the problem here.
|
||||
|
||||
**cheat version info**
|
||||
Please paste the output of `cheat -v` here.
|
||||
|
||||
**cheat configuration info**
|
||||
If your bug pertains to how cheatsheets are loaded and/or displayed, please
|
||||
paste here the following information:
|
||||
|
||||
1. The output of `cheat -d`
|
||||
2. The contents of your `conf.yml` file
|
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
title: ''
|
||||
labels: 'enhancement'
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
17
.github/workflows/homebrew.yml
vendored
Normal file
17
.github/workflows/homebrew.yml
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
name: homebrew
|
||||
|
||||
on:
|
||||
push:
|
||||
tags: '*'
|
||||
|
||||
jobs:
|
||||
homebrew:
|
||||
name: Bump Homebrew formula
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: mislav/bump-homebrew-formula-action@v1
|
||||
with:
|
||||
# A PR will be sent to github.com/Homebrew/homebrew-core to update this formula:
|
||||
formula-name: cheat
|
||||
env:
|
||||
COMMITTER_TOKEN: ${{ secrets.COMMITTER_TOKEN }}
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -1 +1,2 @@
|
||||
dist
|
||||
tags
|
||||
|
13
.travis.yml
13
.travis.yml
@ -1,4 +1,15 @@
|
||||
language: go
|
||||
|
||||
go:
|
||||
- 1.13.x
|
||||
- 1.14.x
|
||||
|
||||
os:
|
||||
- linux
|
||||
- osx
|
||||
|
||||
env:
|
||||
- GO111MODULE=on
|
||||
|
||||
install: true
|
||||
|
||||
script: make ci
|
||||
|
175
Makefile
Normal file
175
Makefile
Normal file
@ -0,0 +1,175 @@
|
||||
# paths
|
||||
makefile := $(realpath $(lastword $(MAKEFILE_LIST)))
|
||||
cmd_dir := ./cmd/cheat
|
||||
dist_dir := ./dist
|
||||
|
||||
# executables
|
||||
CAT := cat
|
||||
COLUMN := column
|
||||
CTAGS := ctags
|
||||
GO := go
|
||||
GREP := grep
|
||||
GZIP := gzip --best
|
||||
LINT := revive
|
||||
MAN := man
|
||||
MKDIR := mkdir -p
|
||||
PANDOC := pandoc
|
||||
RM := rm
|
||||
SCC := scc
|
||||
SED := sed
|
||||
SORT := sort
|
||||
ZIP := zip -m
|
||||
|
||||
# build flags
|
||||
BUILD_FLAGS := -ldflags="-s -w" -mod vendor -trimpath
|
||||
GOBIN :=
|
||||
TMPDIR := /tmp
|
||||
|
||||
# release binaries
|
||||
releases := \
|
||||
$(dist_dir)/cheat-darwin-amd64 \
|
||||
$(dist_dir)/cheat-linux-386 \
|
||||
$(dist_dir)/cheat-linux-amd64 \
|
||||
$(dist_dir)/cheat-linux-arm5 \
|
||||
$(dist_dir)/cheat-linux-arm6 \
|
||||
$(dist_dir)/cheat-linux-arm7 \
|
||||
$(dist_dir)/cheat-windows-amd64.exe
|
||||
|
||||
## build: build an executable for your architecture
|
||||
.PHONY: build
|
||||
build: $(dist_dir) clean vendor generate man
|
||||
$(GO) build $(BUILD_FLAGS) -o $(dist_dir)/cheat $(cmd_dir)
|
||||
|
||||
## build-release: build release executables
|
||||
.PHONY: build-release
|
||||
build-release: $(releases)
|
||||
|
||||
## ci: build a "release" executable for the current architecture (used in ci)
|
||||
.PHONY: ci
|
||||
ci: | setup prepare build
|
||||
|
||||
# cheat-darwin-amd64
|
||||
$(dist_dir)/cheat-darwin-amd64: prepare
|
||||
GOARCH=amd64 GOOS=darwin \
|
||||
$(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
|
||||
$(dist_dir)/cheat-linux-amd64: prepare
|
||||
GOARCH=amd64 GOOS=linux \
|
||||
$(GO) build $(BUILD_FLAGS) -o $@ $(cmd_dir) && $(GZIP) $@ && chmod -x $@.gz
|
||||
|
||||
# cheat-linux-arm5
|
||||
$(dist_dir)/cheat-linux-arm5: prepare
|
||||
GOARCH=arm GOOS=linux GOARM=5 \
|
||||
$(GO) build $(BUILD_FLAGS) -o $@ $(cmd_dir) && $(GZIP) $@ && chmod -x $@.gz
|
||||
|
||||
# cheat-linux-arm6
|
||||
$(dist_dir)/cheat-linux-arm6: prepare
|
||||
GOARCH=arm GOOS=linux GOARM=6 \
|
||||
$(GO) build $(BUILD_FLAGS) -o $@ $(cmd_dir) && $(GZIP) $@ && chmod -x $@.gz
|
||||
|
||||
# cheat-linux-arm7
|
||||
$(dist_dir)/cheat-linux-arm7: prepare
|
||||
GOARCH=arm GOOS=linux GOARM=7 \
|
||||
$(GO) build $(BUILD_FLAGS) -o $@ $(cmd_dir) && $(GZIP) $@ && chmod -x $@.gz
|
||||
|
||||
# cheat-windows-amd64
|
||||
$(dist_dir)/cheat-windows-amd64.exe: prepare
|
||||
GOARCH=amd64 GOOS=windows \
|
||||
$(GO) build $(BUILD_FLAGS) -o $@ $(cmd_dir) && $(ZIP) $@.zip $@
|
||||
|
||||
# ./dist
|
||||
$(dist_dir):
|
||||
$(MKDIR) $(dist_dir)
|
||||
|
||||
.PHONY: generate
|
||||
generate:
|
||||
$(GO) generate $(cmd_dir)
|
||||
|
||||
## install: build and install cheat on your PATH
|
||||
.PHONY: install
|
||||
install: build
|
||||
$(GO) install $(BUILD_FLAGS) $(GOBIN) $(cmd_dir)
|
||||
|
||||
## clean: remove compiled executables
|
||||
.PHONY: clean
|
||||
clean: $(dist_dir)
|
||||
$(RM) -f $(dist_dir)/*
|
||||
|
||||
## distclean: remove the tags file
|
||||
.PHONY: distclean
|
||||
distclean:
|
||||
$(RM) -f tags
|
||||
|
||||
## setup: install revive (linter) and scc (sloc tool)
|
||||
.PHONY: setup
|
||||
setup:
|
||||
GO111MODULE=off $(GO) get -u github.com/boyter/scc github.com/mgechev/revive
|
||||
|
||||
## sloc: count "semantic lines of code"
|
||||
.PHONY: sloc
|
||||
sloc:
|
||||
$(SCC) --exclude-dir=vendor
|
||||
|
||||
## tags: build a tags file
|
||||
.PHONY: tags
|
||||
tags:
|
||||
$(CTAGS) -R --exclude=vendor --languages=go
|
||||
|
||||
## man: build a man page
|
||||
# NB: pandoc may not be installed, so we're ignoring this error on failure
|
||||
.PHONY: man
|
||||
man:
|
||||
-$(PANDOC) -s -t man doc/cheat.1.md -o doc/cheat.1
|
||||
|
||||
## vendor: download, tidy, and verify dependencies
|
||||
.PHONY: vendor
|
||||
vendor:
|
||||
$(GO) mod vendor && $(GO) mod tidy && $(GO) mod verify
|
||||
|
||||
## fmt: run go fmt
|
||||
.PHONY: fmt
|
||||
fmt:
|
||||
$(GO) fmt ./...
|
||||
|
||||
## lint: lint go source files
|
||||
.PHONY: lint
|
||||
lint: vendor
|
||||
$(LINT) -exclude vendor/... ./...
|
||||
|
||||
## vet: vet go source files
|
||||
.PHONY: vet
|
||||
vet:
|
||||
$(GO) vet ./...
|
||||
|
||||
## test: run unit-tests
|
||||
.PHONY: test
|
||||
test:
|
||||
$(GO) test ./...
|
||||
|
||||
## coverage: generate a test coverage report
|
||||
.PHONY: coverage
|
||||
coverage:
|
||||
$(GO) test ./... -coverprofile=$(TMPDIR)/cheat-coverage.out && \
|
||||
$(GO) tool cover -html=$(TMPDIR)/cheat-coverage.out
|
||||
|
||||
## check: format, lint, vet, vendor, and run unit-tests
|
||||
.PHONY: check
|
||||
check: | vendor fmt lint vet test
|
||||
|
||||
.PHONY: prepare
|
||||
prepare: | $(dist_dir) clean generate vendor fmt lint vet test
|
||||
|
||||
## help: display this help text
|
||||
.PHONY: help
|
||||
help:
|
||||
@$(CAT) $(makefile) | \
|
||||
$(SORT) | \
|
||||
$(GREP) "^##" | \
|
||||
$(SED) 's/## //g' | \
|
||||
$(COLUMN) -t -s ':'
|
31
README.md
31
README.md
@ -51,7 +51,9 @@ Installing
|
||||
Configuring
|
||||
-----------
|
||||
### conf.yml ###
|
||||
`cheat` is configured by a YAML file that can be generated with `cheat --init`:
|
||||
`cheat` is configured by a YAML file that will be auto-generated on first run.
|
||||
Should you need to create a config file manually, you can do
|
||||
so via:
|
||||
|
||||
```sh
|
||||
mkdir -p ~/.config/cheat && cheat --init > ~/.config/cheat/conf.yml
|
||||
@ -89,13 +91,14 @@ const squares = [1, 2, 3, 4].map(x => x * x);
|
||||
```
|
||||
|
||||
The `cheat` executable includes no cheatsheets, but [community-sourced
|
||||
cheatsheets are available][cheatsheets].
|
||||
cheatsheets are available][cheatsheets]. You will be asked if you would like to
|
||||
install the community-sourced cheatsheets the first time you run `cheat`.
|
||||
|
||||
|
||||
Cheatpaths
|
||||
----------
|
||||
Cheatsheets are stored on "cheatpaths", which are directories that contain
|
||||
cheetsheets. Cheatpaths are specified in the `conf.yml` file.
|
||||
cheatsheets. Cheatpaths are specified in the `conf.yml` file.
|
||||
|
||||
It can be useful to configure `cheat` against multiple cheatpaths. A common
|
||||
pattern is to store cheatsheets from multiple repositories on individual
|
||||
@ -125,6 +128,11 @@ If a user attempts to edit a cheatsheet on a read-only cheatpath, `cheat` will
|
||||
transparently copy that sheet to a writeable directory before opening it for
|
||||
editing.
|
||||
|
||||
### Directory-scoped Cheatpaths ###
|
||||
At times, it can be useful to closely associate cheatsheets with a directory on
|
||||
your filesystem. `cheat` facilitates this by searching for a `.cheat` folder in
|
||||
the current working directory. If found, the `.cheat` directory will
|
||||
(temporarily) be added to the cheatpaths.
|
||||
|
||||
Usage
|
||||
-----
|
||||
@ -178,21 +186,28 @@ To search (by regex) for cheatsheets that contain an IP address:
|
||||
cheat -r -s '(?:[0-9]{1,3}\.){3}[0-9]{1,3}'
|
||||
```
|
||||
|
||||
Flags may be combined in inuitive ways. Example: to search sheets on the
|
||||
Flags may be combined in intuitive ways. Example: to search sheets on the
|
||||
"personal" cheatpath that are tagged with "networking" and match a regex:
|
||||
|
||||
```sh
|
||||
cheat -p personal -t networking -s --regex '(?:[0-9]{1,3}\.){3}[0-9]{1,3}'
|
||||
cheat -p personal -t networking --regex -s '(?:[0-9]{1,3}\.){3}[0-9]{1,3}'
|
||||
```
|
||||
|
||||
|
||||
Advanced Usage
|
||||
--------------
|
||||
`cheat` may be integrated with [fzf][]. See [fzf.bash][bash] for instructions.
|
||||
(Support for other shells will be added in future releases.)
|
||||
Shell autocompletion is currently available for `bash`, `fish`, and `zsh`. Copy
|
||||
the relevant [completion script][completions] 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][]. 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
|
||||
[bash]: https://github.com/cheat/cheat/blob/master/scripts/fzf.bash
|
||||
[cheatsheets]: https://github.com/cheat/cheatsheets
|
||||
[completions]: https://github.com/cheat/cheat/tree/master/scripts
|
||||
[fzf]: https://github.com/junegunn/fzf
|
||||
|
@ -1,13 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# locate the cheat project root
|
||||
BINDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
APPDIR=$(readlink -f "$BINDIR/..")
|
||||
|
||||
# compile the executable
|
||||
cd "$APPDIR/cmd/cheat"
|
||||
go clean && go generate && go build -mod vendor
|
||||
mv "$APPDIR/cmd/cheat/cheat" "$APPDIR/dist/cheat"
|
||||
|
||||
# display a build checksum
|
||||
md5sum "$APPDIR/dist/cheat"
|
@ -1,19 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# locate the cheat project root
|
||||
BINDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
APPDIR=$(readlink -f "$BINDIR/..")
|
||||
|
||||
# build embeds
|
||||
cd "$APPDIR/cmd/cheat"
|
||||
go clean && go generate
|
||||
|
||||
# compile AMD64 for Linux, OSX, and Windows
|
||||
env GOOS=darwin GOARCH=amd64 go build -mod vendor -o \
|
||||
"$APPDIR/dist/cheat-darwin-amd64" "$APPDIR/cmd/cheat"
|
||||
|
||||
env GOOS=linux GOARCH=amd64 go build -mod vendor -o \
|
||||
"$APPDIR/dist/cheat-linux-amd64" "$APPDIR/cmd/cheat"
|
||||
|
||||
env GOOS=windows GOARCH=amd64 go build -mod vendor -o \
|
||||
"$APPDIR/dist/cheat-win-amd64.exe" "$APPDIR/cmd/cheat"
|
@ -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)
|
||||
}
|
||||
|
@ -99,8 +99,15 @@ func cmdEdit(opts map[string]interface{}, conf config.Config) {
|
||||
}
|
||||
}
|
||||
|
||||
// split `conf.Editor` into parts to separate the editor's executable from
|
||||
// any arguments it may have been passed. If this is not done, the nearby
|
||||
// call to `exec.Command` will fail.
|
||||
parts := strings.Fields(conf.Editor)
|
||||
editor := parts[0]
|
||||
args := append(parts[1:], editpath)
|
||||
|
||||
// edit the cheatsheet
|
||||
cmd := exec.Command(conf.Editor, editpath)
|
||||
cmd := exec.Command(editor, args...)
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stdin = os.Stdin
|
||||
cmd.Stderr = os.Stderr
|
||||
|
@ -2,9 +2,56 @@ package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
"github.com/mitchellh/go-homedir"
|
||||
|
||||
"github.com/cheat/cheat/internal/config"
|
||||
)
|
||||
|
||||
// cmdInit displays an example config file.
|
||||
func cmdInit() {
|
||||
fmt.Println(configs())
|
||||
|
||||
// get the user's home directory
|
||||
home, err := homedir.Dir()
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "failed to get user home directory: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// read the envvars into a map of strings
|
||||
envvars := map[string]string{}
|
||||
for _, e := range os.Environ() {
|
||||
pair := strings.SplitN(e, "=", 2)
|
||||
envvars[pair[0]] = pair[1]
|
||||
}
|
||||
|
||||
// load the config template
|
||||
configs := configs()
|
||||
|
||||
// identify the os-specifc paths at which configs may be located
|
||||
confpaths, err := config.Paths(runtime.GOOS, home, envvars)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "failed to read config paths: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// determine the appropriate paths for config data and (optional) community
|
||||
// cheatsheets based on the user's platform
|
||||
confpath := confpaths[0]
|
||||
confdir := path.Dir(confpath)
|
||||
|
||||
// create paths for community and personal cheatsheets
|
||||
community := path.Join(confdir, "/cheatsheets/community")
|
||||
personal := path.Join(confdir, "/cheatsheets/personal")
|
||||
|
||||
// template the above paths into the default configs
|
||||
configs = strings.Replace(configs, "COMMUNITY_PATH", community, -1)
|
||||
configs = strings.Replace(configs, "PERSONAL_PATH", personal, -1)
|
||||
|
||||
// output the templated configs
|
||||
fmt.Println(configs)
|
||||
}
|
||||
|
@ -1,13 +1,16 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"os"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strings"
|
||||
"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"
|
||||
)
|
||||
@ -45,16 +48,52 @@ func cmdList(opts map[string]interface{}, conf config.Config) {
|
||||
return flattened[i].Title < flattened[j].Title
|
||||
})
|
||||
|
||||
// exit early if no cheatsheets are available
|
||||
// filter if <cheatsheet> was specified
|
||||
// NB: our docopt specification is misleading here. When used in conjunction
|
||||
// with `-l`, `<cheatsheet>` is really a pattern against which to filter
|
||||
// sheet titles.
|
||||
if opts["<cheatsheet>"] != nil {
|
||||
|
||||
// initialize a slice of filtered sheets
|
||||
filtered := []sheet.Sheet{}
|
||||
|
||||
// initialize our filter pattern
|
||||
pattern := "(?i)" + opts["<cheatsheet>"].(string)
|
||||
|
||||
// compile the regex
|
||||
reg, err := regexp.Compile(pattern)
|
||||
if err != nil {
|
||||
fmt.Fprintln(
|
||||
os.Stderr,
|
||||
fmt.Sprintf("failed to compile regexp: %s, %v", pattern, err),
|
||||
)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// iterate over each cheatsheet, and pass-through those which match the
|
||||
// filter pattern
|
||||
for _, s := range flattened {
|
||||
if reg.MatchString(s.Title) {
|
||||
filtered = append(filtered, s)
|
||||
}
|
||||
}
|
||||
|
||||
flattened = filtered
|
||||
}
|
||||
|
||||
// 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",
|
||||
@ -66,4 +105,5 @@ func cmdList(opts map[string]interface{}, conf config.Config) {
|
||||
|
||||
// write columnized output to stdout
|
||||
w.Flush()
|
||||
display.Display(out.String(), conf)
|
||||
}
|
||||
|
55
cmd/cheat/cmd_remove.go
Normal file
55
cmd/cheat/cmd_remove.go
Normal file
@ -0,0 +1,55 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/cheat/cheat/internal/config"
|
||||
"github.com/cheat/cheat/internal/sheets"
|
||||
)
|
||||
|
||||
// cmdRemove opens a cheatsheet for editing (or creates it if it doesn't exist).
|
||||
func cmdRemove(opts map[string]interface{}, conf config.Config) {
|
||||
|
||||
cheatsheet := opts["--rm"].(string)
|
||||
|
||||
// load the cheatsheets
|
||||
cheatsheets, err := sheets.Load(conf.Cheatpaths)
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, fmt.Sprintf("failed to list cheatsheets: %v", err))
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// filter cheatcheats by tag if --tag was provided
|
||||
if opts["--tag"] != nil {
|
||||
cheatsheets = sheets.Filter(
|
||||
cheatsheets,
|
||||
strings.Split(opts["--tag"].(string), ","),
|
||||
)
|
||||
}
|
||||
|
||||
// consolidate the cheatsheets found on all paths into a single map of
|
||||
// `title` => `sheet` (ie, allow more local cheatsheets to override less
|
||||
// local cheatsheets)
|
||||
consolidated := sheets.Consolidate(cheatsheets)
|
||||
|
||||
// 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(2)
|
||||
}
|
||||
|
||||
// fail early if the sheet is read-only
|
||||
if sheet.ReadOnly {
|
||||
fmt.Fprintln(os.Stderr, fmt.Sprintf("cheatsheet '%s' is read-only.", cheatsheet))
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// otherwise, attempt to delete the sheet
|
||||
if err := os.Remove(sheet.Path); err != nil {
|
||||
fmt.Fprintln(os.Stderr, fmt.Sprintf("failed to delete sheet: %s, %v", sheet.Title, err))
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
@ -7,6 +7,8 @@ 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"
|
||||
)
|
||||
|
||||
@ -35,15 +37,27 @@ func cmdSearch(opts map[string]interface{}, conf config.Config) {
|
||||
// local cheatsheets)
|
||||
consolidated := sheets.Consolidate(cheatsheets)
|
||||
|
||||
// sort the cheatsheets alphabetically, and search for matches
|
||||
for _, sheet := range sheets.Sort(consolidated) {
|
||||
// if <cheatsheet> was provided, search that single sheet only
|
||||
if opts["<cheatsheet>"] != nil {
|
||||
|
||||
// colorize output?
|
||||
colorize := false
|
||||
if conf.Colorize == true || opts["--colorize"] == true {
|
||||
colorize = true
|
||||
cheatsheet := opts["<cheatsheet>"].(string)
|
||||
|
||||
// assert that the cheatsheet exists
|
||||
s, ok := consolidated[cheatsheet]
|
||||
if !ok {
|
||||
fmt.Printf("No cheatsheet found for '%s'.\n", cheatsheet)
|
||||
os.Exit(2)
|
||||
}
|
||||
|
||||
consolidated = map[string]sheet.Sheet{
|
||||
cheatsheet: s,
|
||||
}
|
||||
}
|
||||
|
||||
// sort the cheatsheets alphabetically, and search for matches
|
||||
out := ""
|
||||
for _, sheet := range sheets.Sort(consolidated) {
|
||||
|
||||
// assume that we want to perform a case-insensitive search for <phrase>
|
||||
pattern := "(?i)" + phrase
|
||||
|
||||
@ -55,21 +69,34 @@ func cmdSearch(opts map[string]interface{}, conf config.Config) {
|
||||
// compile the regex
|
||||
reg, err := regexp.Compile(pattern)
|
||||
if err != nil {
|
||||
fmt.Errorf("failed to compile regexp: %s, %v", pattern, err)
|
||||
fmt.Fprintln(os.Stderr, fmt.Sprintf("failed to compile regexp: %s, %v", pattern, err))
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// search the sheet
|
||||
matches := sheet.Search(reg, colorize)
|
||||
// `Search` will return text entries that match the search terms. We're
|
||||
// using it here to overwrite the prior cheatsheet Text, filtering it to
|
||||
// only what is relevant
|
||||
sheet.Text = sheet.Search(reg)
|
||||
|
||||
// display the results
|
||||
if len(matches) > 0 {
|
||||
fmt.Printf("%s:\n", sheet.Title)
|
||||
for _, m := range matches {
|
||||
fmt.Printf(" %d: %s\n", m.Line, m.Text)
|
||||
}
|
||||
fmt.Print("\n")
|
||||
// if the sheet did not match the search, ignore it and move on
|
||||
if sheet.Text == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
// if colorization was requested, apply it here
|
||||
if conf.Color(opts) {
|
||||
sheet.Colorize(conf)
|
||||
}
|
||||
|
||||
// output the cheatsheet title
|
||||
out += fmt.Sprintf("%s:\n", sheet.Title)
|
||||
|
||||
// indent each line of content with two spaces
|
||||
for _, line := range strings.Split(sheet.Text, "\n") {
|
||||
out += fmt.Sprintf(" %s\n", line)
|
||||
}
|
||||
}
|
||||
|
||||
// display the output
|
||||
display.Display(out, conf)
|
||||
}
|
||||
|
30
cmd/cheat/cmd_tags.go
Normal file
30
cmd/cheat/cmd_tags.go
Normal file
@ -0,0 +1,30 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/cheat/cheat/internal/config"
|
||||
"github.com/cheat/cheat/internal/display"
|
||||
"github.com/cheat/cheat/internal/sheets"
|
||||
)
|
||||
|
||||
// cmdTags lists all tags in use.
|
||||
func cmdTags(opts map[string]interface{}, conf config.Config) {
|
||||
|
||||
// load the cheatsheets
|
||||
cheatsheets, err := sheets.Load(conf.Cheatpaths)
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, fmt.Sprintf("failed to list cheatsheets: %v", err))
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// assemble the output
|
||||
out := ""
|
||||
for _, tag := range sheets.Tags(cheatsheets) {
|
||||
out += fmt.Sprintln(tag)
|
||||
}
|
||||
|
||||
// display the output
|
||||
display.Display(out, conf)
|
||||
}
|
@ -5,9 +5,8 @@ import (
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/alecthomas/chroma/quick"
|
||||
|
||||
"github.com/cheat/cheat/internal/config"
|
||||
"github.com/cheat/cheat/internal/display"
|
||||
"github.com/cheat/cheat/internal/sheets"
|
||||
)
|
||||
|
||||
@ -40,33 +39,14 @@ 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)
|
||||
}
|
||||
|
||||
// if colorization is not desired, output un-colorized text and exit
|
||||
if conf.Colorize == false && opts["--colorize"] == false {
|
||||
fmt.Print(sheet.Text)
|
||||
os.Exit(0)
|
||||
// apply colorization if requested
|
||||
if conf.Color(opts) {
|
||||
sheet.Colorize(conf)
|
||||
}
|
||||
|
||||
// otherwise, colorize the output
|
||||
// if the syntax was not specified, default to bash
|
||||
lex := sheet.Syntax
|
||||
if lex == "" {
|
||||
lex = "bash"
|
||||
}
|
||||
|
||||
// apply syntax highlighting
|
||||
err = quick.Highlight(
|
||||
os.Stdout,
|
||||
sheet.Text,
|
||||
lex,
|
||||
conf.Formatter,
|
||||
conf.Style,
|
||||
)
|
||||
|
||||
// if colorization somehow failed, output non-colorized text
|
||||
if err != nil {
|
||||
fmt.Print(sheet.Text)
|
||||
}
|
||||
// display the cheatsheet
|
||||
display.Display(sheet.Text, conf)
|
||||
}
|
||||
|
@ -2,16 +2,18 @@ Usage:
|
||||
cheat [options] [<cheatsheet>]
|
||||
|
||||
Options:
|
||||
--init Write a default config file to stdout
|
||||
-c --colorize Colorize output
|
||||
-d --directories List cheatsheet directories
|
||||
-e --edit=<sheet> Edit cheatsheet
|
||||
-l --list List cheatsheets
|
||||
-p --path=<name> Return only sheets found on path <name>
|
||||
-r --regex Treat search <phrase> as a regex
|
||||
-s --search=<phrase> Search cheatsheets for <phrase>
|
||||
-t --tag=<tag> Return only sheets matching <tag>
|
||||
-v --version Print the version number
|
||||
--init Write a default config file to stdout
|
||||
-c --colorize Colorize output
|
||||
-d --directories List cheatsheet directories
|
||||
-e --edit=<cheatsheet> Edit <cheatsheet>
|
||||
-l --list List cheatsheets
|
||||
-p --path=<name> Return only sheets found on path <name>
|
||||
-r --regex Treat search <phrase> as a regex
|
||||
-s --search=<phrase> Search cheatsheets for <phrase>
|
||||
-t --tag=<tag> Return only sheets matching <tag>
|
||||
-T --tags List all tags in use
|
||||
-v --version Print the version number
|
||||
--rm=<cheatsheet> Remove (delete) <cheatsheet>
|
||||
|
||||
Examples:
|
||||
|
||||
@ -33,6 +35,12 @@ Examples:
|
||||
To list all available cheatsheets:
|
||||
cheat -l
|
||||
|
||||
To list all cheatsheets whose titles match "apt":
|
||||
cheat -l apt
|
||||
|
||||
To list all tags in use:
|
||||
cheat -T
|
||||
|
||||
To list available cheatsheets that are tagged as "personal":
|
||||
cheat -l -t personal
|
||||
|
||||
@ -41,3 +49,6 @@ Examples:
|
||||
|
||||
To search (by regex) for cheatsheets that contain an IP address:
|
||||
cheat -c -r -s '(?:[0-9]{1,3}\.){3}[0-9]{1,3}'
|
||||
|
||||
To remove (delete) the foo/bar cheatsheet:
|
||||
cheat --rm foo/bar
|
||||
|
@ -5,15 +5,19 @@ package main
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
"github.com/docopt/docopt-go"
|
||||
"github.com/mitchellh/go-homedir"
|
||||
|
||||
"github.com/cheat/cheat/internal/cheatpath"
|
||||
"github.com/cheat/cheat/internal/config"
|
||||
"github.com/cheat/cheat/internal/installer"
|
||||
)
|
||||
|
||||
const version = "3.0.2"
|
||||
const version = "4.1.0"
|
||||
|
||||
func main() {
|
||||
|
||||
@ -31,15 +35,108 @@ func main() {
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
// load the config file
|
||||
confpath, err := config.Path(runtime.GOOS)
|
||||
// get the user's home directory
|
||||
home, err := homedir.Dir()
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, "could not locate config file")
|
||||
fmt.Fprintf(os.Stderr, "failed to get user home directory: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// read the envvars into a map of strings
|
||||
envvars := map[string]string{}
|
||||
for _, e := range os.Environ() {
|
||||
pair := strings.SplitN(e, "=", 2)
|
||||
envvars[pair[0]] = pair[1]
|
||||
}
|
||||
|
||||
// identify the os-specifc paths at which configs may be located
|
||||
confpaths, err := config.Paths(runtime.GOOS, home, envvars)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "failed to load config: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// search for the config file in the above paths
|
||||
confpath, err := config.Path(confpaths)
|
||||
if err != nil {
|
||||
// prompt the user to create a config file
|
||||
yes, err := installer.Prompt(
|
||||
"A config file was not found. Would you like to create one now? [Y/n]",
|
||||
true,
|
||||
)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "failed to create config: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// exit early on a negative answer
|
||||
if !yes {
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
// read the config template
|
||||
configs := configs()
|
||||
|
||||
// determine the appropriate paths for config data and (optional) community
|
||||
// cheatsheets based on the user's platform
|
||||
confpath = confpaths[0]
|
||||
confdir := path.Dir(confpath)
|
||||
|
||||
// create paths for community and personal cheatsheets
|
||||
community := path.Join(confdir, "/cheatsheets/community")
|
||||
personal := path.Join(confdir, "/cheatsheets/personal")
|
||||
|
||||
// template the above paths into the default configs
|
||||
configs = strings.Replace(configs, "COMMUNITY_PATH", community, -1)
|
||||
configs = strings.Replace(configs, "PERSONAL_PATH", personal, -1)
|
||||
|
||||
// prompt the user to download the community cheatsheets
|
||||
yes, err = installer.Prompt(
|
||||
"Would you like to download the community cheatsheets? [Y/n]",
|
||||
true,
|
||||
)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "failed to create config: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// clone the community cheatsheets if so instructed
|
||||
if yes {
|
||||
// clone the community cheatsheets
|
||||
if err := installer.Clone(community); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "failed to create config: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// also create a directory for personal cheatsheets
|
||||
if err := os.MkdirAll(personal, os.ModePerm); err != nil {
|
||||
fmt.Fprintf(
|
||||
os.Stderr,
|
||||
"failed to create config: failed to create directory: %s: %v\n",
|
||||
personal,
|
||||
err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
// the config file does not exist, so we'll try to create one
|
||||
if err = config.Init(confpath, configs); err != nil {
|
||||
fmt.Fprintf(
|
||||
os.Stderr,
|
||||
"failed to create config file: %s: %v\n",
|
||||
confpath,
|
||||
err,
|
||||
)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
fmt.Printf("Created config file: %s\n", confpath)
|
||||
fmt.Println("Please read this file for advanced configuration information.")
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
// initialize the configs
|
||||
conf, err := config.New(opts, confpath)
|
||||
conf, err := config.New(opts, confpath, true)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "failed to load config: %v\n", err)
|
||||
os.Exit(1)
|
||||
@ -76,12 +173,21 @@ func main() {
|
||||
case opts["--list"].(bool):
|
||||
cmd = cmdList
|
||||
|
||||
case opts["--tags"].(bool):
|
||||
cmd = cmdTags
|
||||
|
||||
case opts["--search"] != nil:
|
||||
cmd = cmdSearch
|
||||
|
||||
case opts["--rm"] != nil:
|
||||
cmd = cmdRemove
|
||||
|
||||
case opts["<cheatsheet>"] != nil:
|
||||
cmd = cmdView
|
||||
|
||||
case opts["--tag"] != nil && opts["--tag"].(string) != "":
|
||||
cmd = cmdList
|
||||
|
||||
default:
|
||||
fmt.Println(usage())
|
||||
os.Exit(0)
|
||||
|
@ -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.
|
||||
#
|
||||
@ -32,34 +35,46 @@ formatter: terminal16m
|
||||
# "upstream" cheatsheets.
|
||||
#
|
||||
# But what if you want to view the "upstream" cheatsheets instead of your own?
|
||||
# Cheatsheets may be filtered via 'cheat -f <tag>' in combination with other
|
||||
# Cheatsheets may be filtered via 'cheat -t <tag>' in combination with other
|
||||
# commands. So, if you want to view the 'tar' cheatsheet that is tagged as
|
||||
# 'community' rather than your own, you can use: cheat tar -f community
|
||||
# 'community' rather than your own, you can use: cheat tar -t community
|
||||
cheatpaths:
|
||||
|
||||
# Paths that come earlier are considered to be the most "global", and will
|
||||
# thus be overridden by more local cheatsheets. That being the case, you
|
||||
# should probably list community cheatsheets first.
|
||||
#
|
||||
# Note that the paths and tags listed below are just examples. You may freely
|
||||
# Note that the paths and tags listed below are placeholders. You may freely
|
||||
# change them to suit your needs.
|
||||
#
|
||||
# Community cheatsheets must be installed separately, though you may have
|
||||
# downloaded them automatically when installing 'cheat'. If not, 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
|
||||
path: ~/.dotfiles/cheat/community
|
||||
path: COMMUNITY_PATH
|
||||
tags: [ community ]
|
||||
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
|
||||
# precedence over the more global cheatsheets.
|
||||
- name: personal
|
||||
path: ~/.dotfiles/cheat/personal
|
||||
path: PERSONAL_PATH
|
||||
tags: [ personal ]
|
||||
readonly: false
|
||||
|
||||
# While it requires no configuration here, it's also worth noting that
|
||||
# 'cheat' will automatically append directories named '.cheat' within the
|
||||
# current working directory to the 'cheatpath'. This can be very useful if
|
||||
# you'd like to closely associate cheatsheets with, for example, a directory
|
||||
# containing source code.
|
||||
#
|
||||
# Such "directory-scoped" cheatsheets will be treated as the most "local"
|
||||
# cheatsheets, and will override less "local" cheatsheets. Likewise,
|
||||
# directory-scoped cheatsheets will always be editable ('readonly: false').
|
||||
`)
|
||||
}
|
||||
|
@ -11,16 +11,18 @@ func usage() string {
|
||||
cheat [options] [<cheatsheet>]
|
||||
|
||||
Options:
|
||||
--init Write a default config file to stdout
|
||||
-c --colorize Colorize output
|
||||
-d --directories List cheatsheet directories
|
||||
-e --edit=<sheet> Edit cheatsheet
|
||||
-l --list List cheatsheets
|
||||
-p --path=<name> Return only sheets found on path <name>
|
||||
-r --regex Treat search <phrase> as a regex
|
||||
-s --search=<phrase> Search cheatsheets for <phrase>
|
||||
-t --tag=<tag> Return only sheets matching <tag>
|
||||
-v --version Print the version number
|
||||
--init Write a default config file to stdout
|
||||
-c --colorize Colorize output
|
||||
-d --directories List cheatsheet directories
|
||||
-e --edit=<cheatsheet> Edit <cheatsheet>
|
||||
-l --list List cheatsheets
|
||||
-p --path=<name> Return only sheets found on path <name>
|
||||
-r --regex Treat search <phrase> as a regex
|
||||
-s --search=<phrase> Search cheatsheets for <phrase>
|
||||
-t --tag=<tag> Return only sheets matching <tag>
|
||||
-T --tags List all tags in use
|
||||
-v --version Print the version number
|
||||
--rm=<cheatsheet> Remove (delete) <cheatsheet>
|
||||
|
||||
Examples:
|
||||
|
||||
@ -42,6 +44,12 @@ Examples:
|
||||
To list all available cheatsheets:
|
||||
cheat -l
|
||||
|
||||
To list all cheatsheets whose titles match "apt":
|
||||
cheat -l apt
|
||||
|
||||
To list all tags in use:
|
||||
cheat -T
|
||||
|
||||
To list available cheatsheets that are tagged as "personal":
|
||||
cheat -l -t personal
|
||||
|
||||
@ -50,5 +58,8 @@ Examples:
|
||||
|
||||
To search (by regex) for cheatsheets that contain an IP address:
|
||||
cheat -c -r -s '(?:[0-9]{1,3}\.){3}[0-9]{1,3}'
|
||||
|
||||
To remove (delete) the foo/bar cheatsheet:
|
||||
cheat --rm foo/bar
|
||||
`)
|
||||
}
|
||||
|
@ -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.
|
||||
#
|
||||
@ -23,32 +26,44 @@ formatter: terminal16m
|
||||
# "upstream" cheatsheets.
|
||||
#
|
||||
# But what if you want to view the "upstream" cheatsheets instead of your own?
|
||||
# Cheatsheets may be filtered via 'cheat -f <tag>' in combination with other
|
||||
# Cheatsheets may be filtered via 'cheat -t <tag>' in combination with other
|
||||
# commands. So, if you want to view the 'tar' cheatsheet that is tagged as
|
||||
# 'community' rather than your own, you can use: cheat tar -f community
|
||||
# 'community' rather than your own, you can use: cheat tar -t community
|
||||
cheatpaths:
|
||||
|
||||
# Paths that come earlier are considered to be the most "global", and will
|
||||
# thus be overridden by more local cheatsheets. That being the case, you
|
||||
# should probably list community cheatsheets first.
|
||||
#
|
||||
# Note that the paths and tags listed below are just examples. You may freely
|
||||
# Note that the paths and tags listed below are placeholders. You may freely
|
||||
# change them to suit your needs.
|
||||
#
|
||||
# Community cheatsheets must be installed separately, though you may have
|
||||
# downloaded them automatically when installing 'cheat'. If not, 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
|
||||
path: ~/.dotfiles/cheat/community
|
||||
path: COMMUNITY_PATH
|
||||
tags: [ community ]
|
||||
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
|
||||
# precedence over the more global cheatsheets.
|
||||
- name: personal
|
||||
path: ~/.dotfiles/cheat/personal
|
||||
path: PERSONAL_PATH
|
||||
tags: [ personal ]
|
||||
readonly: false
|
||||
|
||||
# While it requires no configuration here, it's also worth noting that
|
||||
# 'cheat' will automatically append directories named '.cheat' within the
|
||||
# current working directory to the 'cheatpath'. This can be very useful if
|
||||
# you'd like to closely associate cheatsheets with, for example, a directory
|
||||
# containing source code.
|
||||
#
|
||||
# Such "directory-scoped" cheatsheets will be treated as the most "local"
|
||||
# cheatsheets, and will override less "local" cheatsheets. Likewise,
|
||||
# directory-scoped cheatsheets will always be editable ('readonly: false').
|
||||
|
221
doc/cheat.1
Normal file
221
doc/cheat.1
Normal file
@ -0,0 +1,221 @@
|
||||
.\" Automatically generated by Pandoc 1.17.2
|
||||
.\"
|
||||
.TH "CHEAT" "1" "" "" "General Commands Manual"
|
||||
.hy
|
||||
.SH NAME
|
||||
.PP
|
||||
\f[B]cheat\f[] \[em] create and view command\-line cheatsheets
|
||||
.SH SYNOPSIS
|
||||
.PP
|
||||
\f[B]cheat\f[] [options] [\f[I]CHEATSHEET\f[]]
|
||||
.SH DESCRIPTION
|
||||
.PP
|
||||
\f[B]cheat\f[] allows you to create and view interactive cheatsheets on
|
||||
the command\-line.
|
||||
It was designed to help remind *nix system administrators of options for
|
||||
commands that they use frequently, but not frequently enough to
|
||||
remember.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B \-\-init
|
||||
Print a config file to stdout.
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-c, \-\-colorize
|
||||
Colorize output.
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-d, \-\-directories
|
||||
List cheatsheet directories.
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-e, \-\-edit=\f[I]CHEATSHEET\f[]
|
||||
Open \f[I]CHEATSHEET\f[] for editing.
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-l, \-\-list
|
||||
List available cheatsheets.
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-p, \-\-path=\f[I]PATH\f[]
|
||||
Filter only to sheets found on path \f[I]PATH\f[].
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-r, \-\-regex
|
||||
Treat search \f[I]PHRASE\f[] as a regular expression.
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-s, \-\-search=\f[I]PHRASE\f[]
|
||||
Search cheatsheets for \f[I]PHRASE\f[].
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-t, \-\-tag=\f[I]TAG\f[]
|
||||
Filter only to sheets tagged with \f[I]TAG\f[].
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-T, \-\-tags
|
||||
List all tags in use.
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-v, \-\-version
|
||||
Print the version number.
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-\-rm=\f[I]CHEATSHEET\f[]
|
||||
Remove (deletes) \f[I]CHEATSHEET\f[].
|
||||
.RS
|
||||
.RE
|
||||
.SH EXAMPLES
|
||||
.TP
|
||||
.B To view the foo cheatsheet:
|
||||
cheat \f[I]foo\f[]
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B To edit (or create) the foo cheatsheet:
|
||||
cheat \-e \f[I]foo\f[]
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B To edit (or create) the foo/bar cheatsheet on the \[aq]work\[aq] cheatpath:
|
||||
cheat \-p \f[I]work\f[] \-e \f[I]foo/bar\f[]
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B To view all cheatsheet directories:
|
||||
cheat \-d
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B To list all available cheatsheets:
|
||||
cheat \-l
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B To list all cheatsheets whose titles match \[aq]apt\[aq]:
|
||||
cheat \-l \f[I]apt\f[]
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B To list all tags in use:
|
||||
cheat \-T
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B To list available cheatsheets that are tagged as \[aq]personal\[aq]:
|
||||
cheat \-l \-t \f[I]personal\f[]
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B To search for \[aq]ssh\[aq] among all cheatsheets, and colorize matches:
|
||||
cheat \-c \-s \f[I]ssh\f[]
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B To search (by regex) for cheatsheets that contain an IP address:
|
||||
cheat \-c \-r \-s \f[I]\[aq](?:[0\-9]{1,3}.){3}[0\-9]{1,3}\[aq]\f[]
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B To remove (delete) the foo/bar cheatsheet:
|
||||
cheat \-\-rm \f[I]foo/bar\f[]
|
||||
.RS
|
||||
.RE
|
||||
.SH FILES
|
||||
.SS Configuration
|
||||
.PP
|
||||
\f[B]cheat\f[] is configured via a YAML file that is conventionally
|
||||
named \f[I]conf.yaml\f[].
|
||||
\f[B]cheat\f[] will search for \f[I]conf.yaml\f[] in varying locations,
|
||||
depending upon your platform:
|
||||
.SS Linux, OSX, and other Unixes
|
||||
.IP "1." 3
|
||||
\f[B]CHEAT_CONFIG_PATH\f[]
|
||||
.IP "2." 3
|
||||
\f[B]XDG_CONFIG_HOME\f[]/cheat/conf.yaml
|
||||
.IP "3." 3
|
||||
\f[B]$HOME\f[]/.config/cheat/conf.yml
|
||||
.IP "4." 3
|
||||
\f[B]$HOME\f[]/.cheat/conf.yml
|
||||
.SS Windows
|
||||
.IP "1." 3
|
||||
\f[B]CHEAT_CONFIG_PATH\f[]
|
||||
.IP "2." 3
|
||||
\f[B]APPDATA\f[]/cheat/conf.yml
|
||||
.IP "3." 3
|
||||
\f[B]PROGRAMDATA\f[]/cheat/conf.yml
|
||||
.PP
|
||||
\f[B]cheat\f[] will search in the order specified above.
|
||||
The first \f[I]conf.yaml\f[] encountered will be respected.
|
||||
.PP
|
||||
If \f[B]cheat\f[] cannot locate a config file, it will ask if you\[aq]d
|
||||
like to generate one automatically.
|
||||
Alternatively, you may also generate a config file manually by running
|
||||
\f[B]cheat \-\-init\f[] and saving its output to the appropriate
|
||||
location for your platform.
|
||||
.SS Cheatpaths
|
||||
.PP
|
||||
\f[B]cheat\f[] reads its cheatsheets from "cheatpaths", which are the
|
||||
directories in which cheatsheets are stored.
|
||||
Cheatpaths may be configured in \f[I]conf.yaml\f[], and viewed via
|
||||
\f[B]cheat \-d\f[].
|
||||
.PP
|
||||
For detailed instructions on how to configure cheatpaths, please refer
|
||||
to the comments in conf.yml.
|
||||
.SS Autocompletion
|
||||
.PP
|
||||
Autocompletion scripts for \f[B]bash\f[], \f[B]zsh\f[], and
|
||||
\f[B]fish\f[] are available for download:
|
||||
.IP \[bu] 2
|
||||
<https://github.com/cheat/cheat/blob/master/scripts/cheat.bash>
|
||||
.IP \[bu] 2
|
||||
<https://github.com/cheat/cheat/blob/master/scripts/cheat.fish>
|
||||
.IP \[bu] 2
|
||||
<https://github.com/cheat/cheat/blob/master/scripts/cheat.zsh>
|
||||
.PP
|
||||
The \f[B]bash\f[] and \f[B]zsh\f[] scripts provide optional integration
|
||||
with \f[B]fzf\f[], if the latter is available on your \f[B]PATH\f[].
|
||||
.PP
|
||||
The installation process will vary per system and shell configuration,
|
||||
and thus will not be discussed here.
|
||||
.SH ENVIRONMENT
|
||||
.TP
|
||||
.B \f[B]CHEAT_CONFIG_PATH\f[]
|
||||
The path at which the config file is available.
|
||||
If \f[B]CHEAT_CONFIG_PATH\f[] is set, all other config paths will be
|
||||
ignored.
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \f[B]CHEAT_USE_FZF\f[]
|
||||
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>
|
||||
.SH AUTHOR
|
||||
.PP
|
||||
Christopher Allen Lane <chris@chris-allen-lane.com>
|
||||
.SH SEE ALSO
|
||||
.PP
|
||||
\f[B]fzf(1)\f[]
|
192
doc/cheat.1.md
Normal file
192
doc/cheat.1.md
Normal file
@ -0,0 +1,192 @@
|
||||
% CHEAT(1) | General Commands Manual
|
||||
|
||||
NAME
|
||||
====
|
||||
|
||||
**cheat** — create and view command-line cheatsheets
|
||||
|
||||
SYNOPSIS
|
||||
========
|
||||
|
||||
| **cheat** \[options] \[_CHEATSHEET_]
|
||||
|
||||
DESCRIPTION
|
||||
===========
|
||||
**cheat** allows you to create and view interactive cheatsheets on the
|
||||
command-line. It was designed to help remind \*nix system administrators of
|
||||
options for commands that they use frequently, but not frequently enough to
|
||||
remember.
|
||||
|
||||
OPTIONS
|
||||
=======
|
||||
|
||||
--init
|
||||
: Print a config file to stdout.
|
||||
|
||||
-c, --colorize
|
||||
: Colorize output.
|
||||
|
||||
-d, --directories
|
||||
: List cheatsheet directories.
|
||||
|
||||
-e, --edit=_CHEATSHEET_
|
||||
: Open _CHEATSHEET_ for editing.
|
||||
|
||||
-l, --list
|
||||
: List available cheatsheets.
|
||||
|
||||
-p, --path=_PATH_
|
||||
: Filter only to sheets found on path _PATH_.
|
||||
|
||||
-r, --regex
|
||||
: Treat search _PHRASE_ as a regular expression.
|
||||
|
||||
-s, --search=_PHRASE_
|
||||
: Search cheatsheets for _PHRASE_.
|
||||
|
||||
-t, --tag=_TAG_
|
||||
: Filter only to sheets tagged with _TAG_.
|
||||
|
||||
-T, --tags
|
||||
: List all tags in use.
|
||||
|
||||
-v, --version
|
||||
: Print the version number.
|
||||
|
||||
--rm=_CHEATSHEET_
|
||||
: Remove (deletes) _CHEATSHEET_.
|
||||
|
||||
|
||||
EXAMPLES
|
||||
========
|
||||
|
||||
To view the foo cheatsheet:
|
||||
: cheat _foo_
|
||||
|
||||
To edit (or create) the foo cheatsheet:
|
||||
: cheat -e _foo_
|
||||
|
||||
To edit (or create) the foo/bar cheatsheet on the 'work' cheatpath:
|
||||
: cheat -p _work_ -e _foo/bar_
|
||||
|
||||
To view all cheatsheet directories:
|
||||
: cheat -d
|
||||
|
||||
To list all available cheatsheets:
|
||||
: cheat -l
|
||||
|
||||
To list all cheatsheets whose titles match 'apt':
|
||||
: cheat -l _apt_
|
||||
|
||||
To list all tags in use:
|
||||
: cheat -T
|
||||
|
||||
To list available cheatsheets that are tagged as 'personal':
|
||||
: cheat -l -t _personal_
|
||||
|
||||
To search for 'ssh' among all cheatsheets, and colorize matches:
|
||||
: cheat -c -s _ssh_
|
||||
|
||||
To search (by regex) for cheatsheets that contain an IP address:
|
||||
: cheat -c -r -s _'(?:[0-9]{1,3}\.){3}[0-9]{1,3}'_
|
||||
|
||||
To remove (delete) the foo/bar cheatsheet:
|
||||
: cheat --rm _foo/bar_
|
||||
|
||||
|
||||
FILES
|
||||
=====
|
||||
|
||||
Configuration
|
||||
-------------
|
||||
**cheat** is configured via a YAML file that is conventionally named
|
||||
_conf.yaml_. **cheat** will search for _conf.yaml_ in varying locations,
|
||||
depending upon your platform:
|
||||
|
||||
### Linux, OSX, and other Unixes ###
|
||||
|
||||
1. **CHEAT_CONFIG_PATH**
|
||||
2. **XDG_CONFIG_HOME**/cheat/conf.yaml
|
||||
3. **$HOME**/.config/cheat/conf.yml
|
||||
4. **$HOME**/.cheat/conf.yml
|
||||
|
||||
### Windows ###
|
||||
|
||||
1. **CHEAT_CONFIG_PATH**
|
||||
2. **APPDATA**/cheat/conf.yml
|
||||
3. **PROGRAMDATA**/cheat/conf.yml
|
||||
|
||||
**cheat** will search in the order specified above. The first _conf.yaml_
|
||||
encountered will be respected.
|
||||
|
||||
If **cheat** cannot locate a config file, it will ask if you'd like to generate
|
||||
one automatically. Alternatively, you may also generate a config file manually
|
||||
by running **cheat --init** and saving its output to the appropriate location
|
||||
for your platform.
|
||||
|
||||
|
||||
Cheatpaths
|
||||
----------
|
||||
**cheat** reads its cheatsheets from "cheatpaths", which are the directories in
|
||||
which cheatsheets are stored. Cheatpaths may be configured in _conf.yaml_, and
|
||||
viewed via **cheat -d**.
|
||||
|
||||
For detailed instructions on how to configure cheatpaths, please refer to the
|
||||
comments in conf.yml.
|
||||
|
||||
|
||||
Autocompletion
|
||||
--------------
|
||||
Autocompletion scripts for **bash**, **zsh**, and **fish** are available for
|
||||
download:
|
||||
|
||||
- <https://github.com/cheat/cheat/blob/master/scripts/cheat.bash>
|
||||
- <https://github.com/cheat/cheat/blob/master/scripts/cheat.fish>
|
||||
- <https://github.com/cheat/cheat/blob/master/scripts/cheat.zsh>
|
||||
|
||||
The **bash** and **zsh** scripts provide optional integration with **fzf**, if
|
||||
the latter is available on your **PATH**.
|
||||
|
||||
The installation process will vary per system and shell configuration, and thus
|
||||
will not be discussed here.
|
||||
|
||||
|
||||
ENVIRONMENT
|
||||
===========
|
||||
|
||||
**CHEAT_CONFIG_PATH**
|
||||
|
||||
: The path at which the config file is available. If **CHEAT_CONFIG_PATH** is
|
||||
set, all other config paths will be ignored.
|
||||
|
||||
**CHEAT_USE_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
|
||||
====
|
||||
|
||||
See GitHub issues: <https://github.com/cheat/cheat/issues>
|
||||
|
||||
|
||||
AUTHOR
|
||||
======
|
||||
|
||||
Christopher Allen Lane <chris@chris-allen-lane.com>
|
||||
|
||||
|
||||
SEE ALSO
|
||||
========
|
||||
|
||||
**fzf(1)**
|
||||
|
15
go.mod
15
go.mod
@ -1,14 +1,17 @@
|
||||
module github.com/cheat/cheat
|
||||
|
||||
go 1.13
|
||||
go 1.14
|
||||
|
||||
require (
|
||||
github.com/alecthomas/chroma v0.6.7
|
||||
github.com/alecthomas/chroma v0.8.0
|
||||
github.com/davecgh/go-spew v1.1.1
|
||||
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815
|
||||
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b
|
||||
github.com/kr/text v0.2.0 // indirect
|
||||
github.com/mattn/go-isatty v0.0.12
|
||||
github.com/mitchellh/go-homedir v1.1.0
|
||||
github.com/tj/front v0.0.0-20170212063142-739be213b0a1
|
||||
gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0 // indirect
|
||||
gopkg.in/yaml.v2 v2.2.4
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect
|
||||
github.com/sergi/go-diff v1.1.0 // indirect
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect
|
||||
gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0
|
||||
gopkg.in/yaml.v2 v2.3.0
|
||||
)
|
||||
|
68
go.sum
68
go.sum
@ -1,62 +1,64 @@
|
||||
github.com/GeertJohan/go.incremental v1.0.0/go.mod h1:6fAjUhbVuX1KcMD3c8TEgVUqmo4seqhv0i0kdATSkM0=
|
||||
github.com/GeertJohan/go.rice v1.0.0/go.mod h1:eH6gbSOAUv07dQuZVnBmoDP8mgsM1rtixis4Tib9if0=
|
||||
github.com/akavel/rsrc v0.8.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c=
|
||||
github.com/alecthomas/assert v0.0.0-20170929043011-405dbfeb8e38 h1:smF2tmSOzy2Mm+0dGI2AIUHY+w0BUc+4tn40djz7+6U=
|
||||
github.com/alecthomas/assert v0.0.0-20170929043011-405dbfeb8e38/go.mod h1:r7bzyVFMNntcxPZXK3/+KdruV1H5KSlyVY0gc+NgInI=
|
||||
github.com/alecthomas/chroma v0.6.7 h1:1hKci+AyKOxJrugR9veaocu9DQGR2/GecI72BpaO0Rg=
|
||||
github.com/alecthomas/chroma v0.6.7/go.mod h1:zVlgtbRS7BJDrDY9SB238RmpoCBCYFlLmcfZ3durxTk=
|
||||
github.com/alecthomas/chroma v0.8.0 h1:HS+HE97sgcqjQGu5uVr8jIE55Mmh5UeQ7kckAhHg2pY=
|
||||
github.com/alecthomas/chroma v0.8.0/go.mod h1:sko8vR34/90zvl5QdcUdvzL3J8NKjAUx9va9jPuFNoM=
|
||||
github.com/alecthomas/colour v0.0.0-20160524082231-60882d9e2721 h1:JHZL0hZKJ1VENNfmXvHbgYlbUOvpzYzvy2aZU5gXVeo=
|
||||
github.com/alecthomas/colour v0.0.0-20160524082231-60882d9e2721/go.mod h1:QO9JBoKquHd+jz9nshCh40fOfO+JzsoXy8qTHF68zU0=
|
||||
github.com/alecthomas/kong v0.1.17-0.20190424132513-439c674f7ae0/go.mod h1:+inYUSluD+p4L8KdviBSgzcqEjUQOfC5fQDRFuc36lI=
|
||||
github.com/alecthomas/kong v0.2.1-0.20190708041108-0548c6b1afae/go.mod h1:+inYUSluD+p4L8KdviBSgzcqEjUQOfC5fQDRFuc36lI=
|
||||
github.com/alecthomas/kong-hcl v0.1.8-0.20190615233001-b21fea9723c8/go.mod h1:MRgZdU3vrFd05IQ89AxUZ0aYdF39BYoNFa324SodPCA=
|
||||
github.com/alecthomas/kong v0.2.4/go.mod h1:kQOmtJgV+Lb4aj+I2LEn40cbtawdWJ9Y8QLq+lElKxE=
|
||||
github.com/alecthomas/repr v0.0.0-20180818092828-117648cd9897 h1:p9Sln00KOTlrYkxI1zYWl1QLnEqAqEARBEYa8FQnQcY=
|
||||
github.com/alecthomas/repr v0.0.0-20180818092828-117648cd9897/go.mod h1:xTS7Pm1pD1mvyM075QCDSRqH6qRLXylzS24ZTpRiSzQ=
|
||||
github.com/daaku/go.zipexe v1.0.0/go.mod h1:z8IiR6TsVLEYKwXAoE/I+8ys/sDkgTzSL0CLnGVd57E=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/danwakefield/fnmatch v0.0.0-20160403171240-cbb64ac3d964 h1:y5HC9v93H5EPKqaS1UYVg1uYah5Xf51mBfIoWehClUQ=
|
||||
github.com/danwakefield/fnmatch v0.0.0-20160403171240-cbb64ac3d964/go.mod h1:Xd9hchkHSWYkEqJwUGisez3G1QY8Ryz0sdWrLPMGjLk=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dlclark/regexp2 v1.1.6 h1:CqB4MjHw0MFCDj+PHHjiESmHX+N7t0tJzKvC6M97BRg=
|
||||
github.com/dlclark/regexp2 v1.1.6/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
|
||||
github.com/dlclark/regexp2 v1.2.0 h1:8sAhBGEM0dRWogWqWyQeIJnxjWO6oIjl8FKqREDsGfk=
|
||||
github.com/dlclark/regexp2 v1.2.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
|
||||
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815 h1:bWDMxwH3px2JBh6AyO7hdCn/PkvCZXii8TGj7sbtEbQ=
|
||||
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
|
||||
github.com/gorilla/csrf v1.6.0/go.mod h1:7tSf8kmjNYr7IWDCYhd3U8Ck34iQ/Yw5CJu7bAkHEGI=
|
||||
github.com/gorilla/handlers v1.4.1/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ=
|
||||
github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||
github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4=
|
||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||
github.com/mattn/go-colorable v0.0.9 h1:UVL0vNpWh04HeJXV0KLcaT7r06gOH2l4OW6ddYRUIY4=
|
||||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||
github.com/mattn/go-isatty v0.0.4 h1:bnP0vzxcAdeI1zdubAl5PjU6zsERjGZb7raWodagDYs=
|
||||
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1fWh90gTKwiN4QCGoY9TWyyO4=
|
||||
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
|
||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
|
||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/nkovacs/streamquote v0.0.0-20170412213628-49af9bddb229/go.mod h1:0aYXnNPJ8l7uZxf45rWW1a/uME32OF0rhiYGNQ2oF2E=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ=
|
||||
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
||||
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
|
||||
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/tj/front v0.0.0-20170212063142-739be213b0a1 h1:lA+aPRvltlx2fwv/BnxyYSDQo3pIeqzHgMO5GvK0T9E=
|
||||
github.com/tj/front v0.0.0-20170212063142-739be213b0a1/go.mod h1:deJrtusCTptAW4EUn5vBLpl3dhNqPqUwEjWJz5UNxpQ=
|
||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||
github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
|
||||
golang.org/x/sys v0.0.0-20181128092732-4ed8d59d0b35 h1:YAFjXN64LMvktoUZH9zgY4lGc/msGN7HQfoSuKCgaDU=
|
||||
golang.org/x/sys v0.0.0-20181128092732-4ed8d59d0b35/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42 h1:vEOn+mP2zCOVzKckCZy6YsCtDblrpj/w7B9nxGNELpg=
|
||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200413165638-669c56c373c4 h1:opSr2sbRXk5X5/givKrrKj9HXxFpW2sdCiP8MJSKLQY=
|
||||
golang.org/x/sys v0.0.0-20200413165638-669c56c373c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0 h1:POO/ycCATvegFmVuPpQzZFJ+pGZeX22Ufu6fibxDVjU=
|
||||
gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0/go.mod h1:WDnlLJ4WF5VGsH/HVa3CI79GS0ol3YnhVnKP89i0kNg=
|
||||
gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
|
||||
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.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
|
||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
|
@ -2,8 +2,8 @@ package cheatpath
|
||||
|
||||
// Cheatpath encapsulates cheatsheet path information
|
||||
type Cheatpath struct {
|
||||
Name string `yaml:name`
|
||||
Path string `yaml:path`
|
||||
ReadOnly bool `yaml:readonly`
|
||||
Tags []string `yaml:tags`
|
||||
Name string `yaml:"name"`
|
||||
Path string `yaml:"path"`
|
||||
ReadOnly bool `yaml:"readonly"`
|
||||
Tags []string `yaml:"tags"`
|
||||
}
|
||||
|
26
internal/config/color.go
Normal file
26
internal/config/color.go
Normal file
@ -0,0 +1,26 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/mattn/go-isatty"
|
||||
)
|
||||
|
||||
// Color indicates whether colorization should be applied to the output
|
||||
func (c *Config) Color(opts map[string]interface{}) bool {
|
||||
|
||||
// default to the colorization specified in the configs...
|
||||
colorize := c.Colorize
|
||||
|
||||
// ... however, only apply colorization if we're writing to a tty...
|
||||
if !isatty.IsTerminal(os.Stdout.Fd()) && !isatty.IsCygwinTerminal(os.Stdout.Fd()) {
|
||||
colorize = false
|
||||
}
|
||||
|
||||
// ... *unless* the --colorize flag was passed
|
||||
if opts["--colorize"] == true {
|
||||
colorize = true
|
||||
}
|
||||
|
||||
return colorize
|
||||
}
|
@ -4,6 +4,8 @@ import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
cp "github.com/cheat/cheat/internal/cheatpath"
|
||||
|
||||
@ -13,15 +15,16 @@ import (
|
||||
|
||||
// Config encapsulates configuration parameters
|
||||
type Config struct {
|
||||
Colorize bool `yaml:colorize`
|
||||
Editor string `yaml:editor`
|
||||
Cheatpaths []cp.Cheatpath `yaml:cheatpaths`
|
||||
Style string `yaml:style`
|
||||
Formatter string `yaml:formatter`
|
||||
Colorize bool `yaml:"colorize"`
|
||||
Editor string `yaml:"editor"`
|
||||
Cheatpaths []cp.Cheatpath `yaml:"cheatpaths"`
|
||||
Style string `yaml:"style"`
|
||||
Formatter string `yaml:"formatter"`
|
||||
Pager string `yaml:"pager"`
|
||||
}
|
||||
|
||||
// New returns a new Config struct
|
||||
func New(opts map[string]interface{}, confPath string) (Config, error) {
|
||||
func New(opts map[string]interface{}, confPath string, resolve bool) (Config, error) {
|
||||
|
||||
// read the config file
|
||||
buf, err := ioutil.ReadFile(confPath)
|
||||
@ -38,14 +41,54 @@ func New(opts map[string]interface{}, confPath string) (Config, error) {
|
||||
return Config{}, fmt.Errorf("could not unmarshal yaml: %v", err)
|
||||
}
|
||||
|
||||
// expand ~ in config paths
|
||||
// if a .cheat directory exists locally, append it to the cheatpaths
|
||||
cwd, err := os.Getwd()
|
||||
if err != nil {
|
||||
return Config{}, fmt.Errorf("failed to get cwd: %v", err)
|
||||
}
|
||||
|
||||
local := filepath.Join(cwd, ".cheat")
|
||||
if _, err := os.Stat(local); err == nil {
|
||||
path := cp.Cheatpath{
|
||||
Name: "cwd",
|
||||
Path: local,
|
||||
ReadOnly: false,
|
||||
Tags: []string{},
|
||||
}
|
||||
|
||||
conf.Cheatpaths = append(conf.Cheatpaths, path)
|
||||
}
|
||||
|
||||
// process cheatpaths
|
||||
for i, cheatpath := range conf.Cheatpaths {
|
||||
|
||||
// expand ~ in config paths
|
||||
expanded, err := homedir.Expand(cheatpath.Path)
|
||||
if err != nil {
|
||||
return Config{}, fmt.Errorf("failed to expand ~: %v", err)
|
||||
}
|
||||
|
||||
// follow symlinks
|
||||
//
|
||||
// NB: `resolve` is an ugly kludge that exists for the sake of unit-tests.
|
||||
// It's necessary because `EvalSymlinks` will error if the symlink points
|
||||
// to a non-existent location on the filesystem. When unit-testing,
|
||||
// however, we don't want to have dependencies on the filesystem. As such,
|
||||
// `resolve` is a switch that allows us to turn off symlink resolution when
|
||||
// running the config tests.
|
||||
if resolve {
|
||||
evaled, err := filepath.EvalSymlinks(expanded)
|
||||
if err != nil {
|
||||
return Config{}, fmt.Errorf(
|
||||
"failed to resolve symlink: %s: %v",
|
||||
expanded,
|
||||
err,
|
||||
)
|
||||
}
|
||||
|
||||
expanded = evaled
|
||||
}
|
||||
|
||||
conf.Cheatpaths[i].Path = expanded
|
||||
}
|
||||
|
||||
@ -70,5 +113,10 @@ func New(opts map[string]interface{}, confPath string) (Config, error) {
|
||||
conf.Formatter = "terminal16m"
|
||||
}
|
||||
|
||||
// if a pager was not provided, set a default
|
||||
if strings.TrimSpace(conf.Pager) == "" {
|
||||
conf.Pager = ""
|
||||
}
|
||||
|
||||
return conf, nil
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ import (
|
||||
func TestConfigSuccessful(t *testing.T) {
|
||||
|
||||
// initialize a config
|
||||
conf, err := New(map[string]interface{}{}, mock.Path("conf/conf.yml"))
|
||||
conf, err := New(map[string]interface{}{}, mock.Path("conf/conf.yml"), false)
|
||||
if err != nil {
|
||||
t.Errorf("failed to parse config file: %v", err)
|
||||
}
|
||||
@ -69,7 +69,7 @@ func TestConfigSuccessful(t *testing.T) {
|
||||
func TestConfigFailure(t *testing.T) {
|
||||
|
||||
// attempt to read a non-existent config file
|
||||
_, err := New(map[string]interface{}{}, "/does-not-exit")
|
||||
_, err := New(map[string]interface{}{}, "/does-not-exit", false)
|
||||
if err == nil {
|
||||
t.Errorf("failed to error on unreadable config")
|
||||
}
|
||||
@ -84,14 +84,14 @@ func TestEmptyEditor(t *testing.T) {
|
||||
os.Setenv("EDITOR", "")
|
||||
|
||||
// initialize a config
|
||||
conf, err := New(map[string]interface{}{}, mock.Path("conf/empty.yml"))
|
||||
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")
|
||||
}
|
||||
|
||||
// set editor, and assert that it is respected
|
||||
os.Setenv("EDITOR", "foo")
|
||||
conf, err = New(map[string]interface{}{}, mock.Path("conf/empty.yml"))
|
||||
conf, err = New(map[string]interface{}{}, mock.Path("conf/empty.yml"), false)
|
||||
if err != nil {
|
||||
t.Errorf("failed to init configs: %v", err)
|
||||
}
|
||||
@ -101,7 +101,7 @@ func TestEmptyEditor(t *testing.T) {
|
||||
|
||||
// set visual, and assert that it overrides editor
|
||||
os.Setenv("VISUAL", "bar")
|
||||
conf, err = New(map[string]interface{}{}, mock.Path("conf/empty.yml"))
|
||||
conf, err = New(map[string]interface{}{}, mock.Path("conf/empty.yml"), false)
|
||||
if err != nil {
|
||||
t.Errorf("failed to init configs: %v", err)
|
||||
}
|
||||
|
24
internal/config/init.go
Normal file
24
internal/config/init.go
Normal 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
|
||||
}
|
@ -3,58 +3,10 @@ package config
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
|
||||
"github.com/mitchellh/go-homedir"
|
||||
)
|
||||
|
||||
// Path returns the config file path
|
||||
func Path(sys 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
|
||||
|
||||
// OSX config paths
|
||||
} else if sys == "darwin" {
|
||||
|
||||
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"),
|
||||
}
|
||||
|
||||
// Linux config paths
|
||||
} else if sys == "linux" {
|
||||
|
||||
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"),
|
||||
"/etc/cheat/conf.yml",
|
||||
}
|
||||
|
||||
// Windows config paths
|
||||
} else if sys == "windows" {
|
||||
|
||||
paths = []string{
|
||||
fmt.Sprintf("%s/cheat/conf.yml", os.Getenv("APPDATA")),
|
||||
fmt.Sprintf("%s/cheat/conf.yml", os.Getenv("PROGRAMDATA")),
|
||||
}
|
||||
|
||||
// Unsupported platforms
|
||||
} else {
|
||||
return "", fmt.Errorf("unsupported os: %s", sys)
|
||||
}
|
||||
func Path(paths []string) (string, error) {
|
||||
|
||||
// check if the config file exists on any paths
|
||||
for _, p := range paths {
|
||||
|
54
internal/config/paths.go
Normal file
54
internal/config/paths.go
Normal file
@ -0,0 +1,54 @@
|
||||
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,
|
||||
home 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"))
|
||||
}
|
||||
|
||||
paths = append(paths, []string{
|
||||
path.Join(home, ".config/cheat/conf.yml"),
|
||||
path.Join(home, ".cheat/conf.yml"),
|
||||
"/etc/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)
|
||||
}
|
||||
}
|
175
internal/config/paths_test.go
Normal file
175
internal/config/paths_test.go
Normal file
@ -0,0 +1,175 @@
|
||||
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 the user's home directory
|
||||
home := "/home/foo"
|
||||
|
||||
// mock some envvars
|
||||
envvars := map[string]string{
|
||||
"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, home, 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",
|
||||
"/etc/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 the user's home directory
|
||||
home := "/home/foo"
|
||||
|
||||
// mock some envvars
|
||||
envvars := map[string]string{}
|
||||
|
||||
// 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, home, 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",
|
||||
"/etc/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 the user's home directory
|
||||
home := "not-used-on-windows"
|
||||
|
||||
// mock some envvars
|
||||
envvars := map[string]string{
|
||||
"APPDATA": "/apps",
|
||||
"PROGRAMDATA": "/programs",
|
||||
}
|
||||
|
||||
// get the paths for the platform
|
||||
paths, err := Paths("windows", home, 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 the user's home directory
|
||||
home := "/home/foo"
|
||||
|
||||
// mock some envvars
|
||||
envvars := map[string]string{
|
||||
"XDG_CONFIG_HOME": "/home/bar",
|
||||
"CHEAT_CONFIG_PATH": "/home/baz/conf.yml",
|
||||
}
|
||||
|
||||
// get the paths for the platform
|
||||
paths, err := Paths("linux", home, 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),
|
||||
)
|
||||
}
|
||||
}
|
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)
|
||||
}
|
||||
}
|
44
internal/frontmatter/frontmatter.go
Normal file
44
internal/frontmatter/frontmatter.go
Normal file
@ -0,0 +1,44 @@
|
||||
package frontmatter
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"gopkg.in/yaml.v1"
|
||||
)
|
||||
|
||||
// Frontmatter encapsulates cheatsheet frontmatter data
|
||||
type Frontmatter struct {
|
||||
Tags []string
|
||||
Syntax string
|
||||
}
|
||||
|
||||
// Parse parses cheatsheet frontmatter
|
||||
func Parse(markdown string) (string, Frontmatter, error) {
|
||||
|
||||
// specify the frontmatter delimiter
|
||||
delim := "---"
|
||||
|
||||
// initialize a frontmatter struct
|
||||
var fm Frontmatter
|
||||
|
||||
// if the markdown does not contain frontmatter, pass it through unmodified
|
||||
if !strings.HasPrefix(markdown, delim) {
|
||||
return strings.TrimSpace(markdown), fm, nil
|
||||
}
|
||||
|
||||
// otherwise, split the frontmatter and cheatsheet text
|
||||
parts := strings.SplitN(markdown, delim, 3)
|
||||
|
||||
// return an error if the frontmatter parses into the wrong number of parts
|
||||
if len(parts) != 3 {
|
||||
return markdown, fm, fmt.Errorf("failed to delimit frontmatter")
|
||||
}
|
||||
|
||||
// return an error if the YAML cannot be unmarshalled
|
||||
if err := yaml.Unmarshal([]byte(parts[1]), &fm); err != nil {
|
||||
return markdown, fm, fmt.Errorf("failed to unmarshal frontmatter: %v", err)
|
||||
}
|
||||
|
||||
return strings.TrimSpace(parts[2]), fm, nil
|
||||
}
|
95
internal/frontmatter/frontmatter_test.go
Normal file
95
internal/frontmatter/frontmatter_test.go
Normal file
@ -0,0 +1,95 @@
|
||||
package frontmatter
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
// TestHasFrontmatter asserts that markdown is properly parsed when it contains
|
||||
// frontmatter
|
||||
func TestHasFrontmatter(t *testing.T) {
|
||||
|
||||
// stub our cheatsheet content
|
||||
markdown := `---
|
||||
syntax: go
|
||||
tags: [ test ]
|
||||
---
|
||||
To foo the bar: baz`
|
||||
|
||||
// parse the frontmatter
|
||||
text, fm, err := Parse(markdown)
|
||||
|
||||
// assert expectations
|
||||
if err != nil {
|
||||
t.Errorf("failed to parse markdown: %v", err)
|
||||
}
|
||||
|
||||
want := "To foo the bar: baz"
|
||||
if text != want {
|
||||
t.Errorf("failed to parse text: want: %s, got: %s", want, text)
|
||||
}
|
||||
|
||||
want = "go"
|
||||
if fm.Syntax != want {
|
||||
t.Errorf("failed to parse syntax: want: %s, got: %s", want, fm.Syntax)
|
||||
}
|
||||
|
||||
want = "test"
|
||||
if fm.Tags[0] != want {
|
||||
t.Errorf("failed to parse tags: want: %s, got: %s", want, fm.Tags[0])
|
||||
}
|
||||
if len(fm.Tags) != 1 {
|
||||
t.Errorf("failed to parse tags: want: len 0, got: len %d", len(fm.Tags))
|
||||
}
|
||||
}
|
||||
|
||||
// TestHasFrontmatter asserts that markdown is properly parsed when it does not
|
||||
// contain frontmatter
|
||||
func TestHasNoFrontmatter(t *testing.T) {
|
||||
|
||||
// stub our cheatsheet content
|
||||
markdown := "To foo the bar: baz"
|
||||
|
||||
// parse the frontmatter
|
||||
text, fm, err := Parse(markdown)
|
||||
|
||||
// assert expectations
|
||||
if err != nil {
|
||||
t.Errorf("failed to parse markdown: %v", err)
|
||||
}
|
||||
|
||||
if text != markdown {
|
||||
t.Errorf("failed to parse text: want: %s, got: %s", markdown, text)
|
||||
}
|
||||
|
||||
if fm.Syntax != "" {
|
||||
t.Errorf("failed to parse syntax: want: '', got: %s", fm.Syntax)
|
||||
}
|
||||
|
||||
if len(fm.Tags) != 0 {
|
||||
t.Errorf("failed to parse tags: want: len 0, got: len %d", len(fm.Tags))
|
||||
}
|
||||
}
|
||||
|
||||
// TestHasInvalidFrontmatter asserts that markdown is properly parsed when it
|
||||
// contains invalid frontmatter
|
||||
func TestHasInvalidFrontmatter(t *testing.T) {
|
||||
|
||||
// stub our cheatsheet content (with invalid frontmatter)
|
||||
markdown := `---
|
||||
syntax: go
|
||||
tags: [ test ]
|
||||
To foo the bar: baz`
|
||||
|
||||
// parse the frontmatter
|
||||
text, _, err := Parse(markdown)
|
||||
|
||||
// assert that an error was returned
|
||||
if err == nil {
|
||||
t.Error("failed to error on invalid frontmatter")
|
||||
}
|
||||
|
||||
// assert that the "raw" markdown was returned
|
||||
if text != markdown {
|
||||
t.Errorf("failed to parse text: want: %s, got: %s", markdown, text)
|
||||
}
|
||||
}
|
24
internal/installer/clone.go
Normal file
24
internal/installer/clone.go
Normal file
@ -0,0 +1,24 @@
|
||||
package installer
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
)
|
||||
|
||||
const cloneURL = "https://github.com/cheat/cheatsheets.git"
|
||||
|
||||
// Clone clones the community cheatsheets
|
||||
func Clone(path string) error {
|
||||
|
||||
// perform the clone in a shell
|
||||
cmd := exec.Command("git", "clone", cloneURL, path)
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to clone cheatsheets: %v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
37
internal/installer/prompt.go
Normal file
37
internal/installer/prompt.go
Normal file
@ -0,0 +1,37 @@
|
||||
package installer
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Prompt prompts the user for a answer
|
||||
func Prompt(prompt string, def bool) (bool, error) {
|
||||
|
||||
// initialize a line reader
|
||||
reader := bufio.NewReader(os.Stdin)
|
||||
|
||||
// display the prompt
|
||||
fmt.Print(fmt.Sprintf("%s: ", prompt))
|
||||
|
||||
// read the answer
|
||||
ans, err := reader.ReadString('\n')
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("failed to parse input: %v", err)
|
||||
}
|
||||
|
||||
// normalize the answer
|
||||
ans = strings.ToLower(strings.TrimRight(ans, "\n"))
|
||||
|
||||
// return the appropriate response
|
||||
switch ans {
|
||||
case "y":
|
||||
return true, nil
|
||||
case "":
|
||||
return def, nil
|
||||
default:
|
||||
return false, nil
|
||||
}
|
||||
}
|
37
internal/sheet/colorize.go
Normal file
37
internal/sheet/colorize.go
Normal file
@ -0,0 +1,37 @@
|
||||
package sheet
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
|
||||
"github.com/cheat/cheat/internal/config"
|
||||
|
||||
"github.com/alecthomas/chroma/quick"
|
||||
)
|
||||
|
||||
// Colorize applies syntax-highlighting to a cheatsheet's Text.
|
||||
func (s *Sheet) Colorize(conf config.Config) {
|
||||
|
||||
// if the syntax was not specified, default to bash
|
||||
lex := s.Syntax
|
||||
if lex == "" {
|
||||
lex = "bash"
|
||||
}
|
||||
|
||||
// write colorized text into a buffer
|
||||
var buf bytes.Buffer
|
||||
err := quick.Highlight(
|
||||
&buf,
|
||||
s.Text,
|
||||
lex,
|
||||
conf.Formatter,
|
||||
conf.Style,
|
||||
)
|
||||
|
||||
// if colorization somehow failed, do nothing
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// otherwise, swap the cheatsheet's Text with its colorized equivalent
|
||||
s.Text = buf.String()
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
package sheet
|
||||
|
||||
// Match encapsulates search matches within cheatsheets
|
||||
type Match struct {
|
||||
Line int
|
||||
Text string
|
||||
}
|
@ -3,43 +3,22 @@ package sheet
|
||||
import (
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/mgutz/ansi"
|
||||
)
|
||||
|
||||
// Search searches for regexp matches in a cheatsheet's text, and optionally
|
||||
// colorizes matching strings.
|
||||
func (s *Sheet) Search(reg *regexp.Regexp, colorize bool) []Match {
|
||||
// Search returns lines within a sheet's Text that match the search regex
|
||||
func (s *Sheet) Search(reg *regexp.Regexp) string {
|
||||
|
||||
// record matches
|
||||
matches := []Match{}
|
||||
matches := ""
|
||||
|
||||
// search through the cheatsheet's text line by line
|
||||
// TODO: searching line-by-line is surely the "naive" approach. Revisit this
|
||||
// later with an eye for performance improvements.
|
||||
for linenum, line := range strings.Split(s.Text, "\n") {
|
||||
for _, line := range strings.Split(s.Text, "\n\n") {
|
||||
|
||||
// exit early if the line doesn't match the regex
|
||||
if !reg.MatchString(line) {
|
||||
continue
|
||||
if reg.MatchString(line) {
|
||||
matches += line + "\n\n"
|
||||
}
|
||||
|
||||
// init the match
|
||||
m := Match{
|
||||
Line: linenum + 1,
|
||||
Text: strings.TrimSpace(line),
|
||||
}
|
||||
|
||||
// colorize the matching text if so configured
|
||||
if colorize {
|
||||
m.Text = reg.ReplaceAllStringFunc(m.Text, func(matched string) string {
|
||||
return ansi.Color(matched, "red+b")
|
||||
})
|
||||
}
|
||||
|
||||
// record the match
|
||||
matches = append(matches, m)
|
||||
}
|
||||
|
||||
return matches
|
||||
return strings.TrimSpace(matches)
|
||||
}
|
||||
|
@ -4,8 +4,6 @@ import (
|
||||
"reflect"
|
||||
"regexp"
|
||||
"testing"
|
||||
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
)
|
||||
|
||||
// TestSearchNoMatch ensures that the expected output is returned when no
|
||||
@ -24,21 +22,21 @@ func TestSearchNoMatch(t *testing.T) {
|
||||
}
|
||||
|
||||
// search the sheet
|
||||
matches := sheet.Search(reg, false)
|
||||
matches := sheet.Search(reg)
|
||||
|
||||
// assert that no matches were found
|
||||
if len(matches) != 0 {
|
||||
t.Errorf("failure: expected no matches: got: %s", spew.Sdump(matches))
|
||||
if matches != "" {
|
||||
t.Errorf("failure: expected no matches: got: %s", matches)
|
||||
}
|
||||
}
|
||||
|
||||
// TestSearchSingleMatchNoColor asserts that the expected output is returned
|
||||
// when a single match is returned, and no colorization is applied.
|
||||
func TestSearchSingleMatchNoColor(t *testing.T) {
|
||||
// TestSearchSingleMatch asserts that the expected output is returned
|
||||
// when a single match is returned
|
||||
func TestSearchSingleMatch(t *testing.T) {
|
||||
|
||||
// mock a cheatsheet
|
||||
sheet := Sheet{
|
||||
Text: "The quick brown fox\njumped over\nthe lazy dog.",
|
||||
Text: "The quick brown fox\njumped over\n\nthe lazy dog.",
|
||||
}
|
||||
|
||||
// compile the search regex
|
||||
@ -48,69 +46,28 @@ func TestSearchSingleMatchNoColor(t *testing.T) {
|
||||
}
|
||||
|
||||
// search the sheet
|
||||
matches := sheet.Search(reg, false)
|
||||
matches := sheet.Search(reg)
|
||||
|
||||
// specify the expected results
|
||||
want := []Match{
|
||||
Match{
|
||||
Line: 1,
|
||||
Text: "The quick brown fox",
|
||||
},
|
||||
}
|
||||
want := "The quick brown fox\njumped over"
|
||||
|
||||
// assert that the correct matches were returned
|
||||
if !reflect.DeepEqual(matches, want) {
|
||||
if matches != want {
|
||||
t.Errorf(
|
||||
"failed to return expected matches: want:\n%s, got:\n%s",
|
||||
spew.Sdump(want),
|
||||
spew.Sdump(matches),
|
||||
want,
|
||||
matches,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// TestSearchSingleMatchColorized asserts that the expected output is returned
|
||||
// when a single match is returned, and colorization is applied
|
||||
func TestSearchSingleMatchColorized(t *testing.T) {
|
||||
// TestSearchMultiMatch asserts that the expected output is returned
|
||||
// when a multiple matches are returned
|
||||
func TestSearchMultiMatch(t *testing.T) {
|
||||
|
||||
// mock a cheatsheet
|
||||
sheet := Sheet{
|
||||
Text: "The quick brown fox\njumped over\nthe lazy dog.",
|
||||
}
|
||||
|
||||
// compile the search regex
|
||||
reg, err := regexp.Compile("(?i)fox")
|
||||
if err != nil {
|
||||
t.Errorf("failed to compile regex: %v", err)
|
||||
}
|
||||
|
||||
// search the sheet
|
||||
matches := sheet.Search(reg, true)
|
||||
|
||||
// specify the expected results
|
||||
want := []Match{
|
||||
Match{
|
||||
Line: 1,
|
||||
Text: "The quick brown \x1b[1;31mfox\x1b[0m",
|
||||
},
|
||||
}
|
||||
|
||||
// assert that the correct matches were returned
|
||||
if !reflect.DeepEqual(matches, want) {
|
||||
t.Errorf(
|
||||
"failed to return expected matches: want:\n%s, got:\n%s",
|
||||
spew.Sdump(want),
|
||||
spew.Sdump(matches),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// TestSearchMultiMatchNoColor asserts that the expected output is returned
|
||||
// when a multiple matches are returned, and no colorization is applied
|
||||
func TestSearchMultiMatchNoColor(t *testing.T) {
|
||||
|
||||
// mock a cheatsheet
|
||||
sheet := Sheet{
|
||||
Text: "The quick brown fox\njumped over\nthe lazy dog.",
|
||||
Text: "The quick brown fox\n\njumped over\n\nthe lazy dog.",
|
||||
}
|
||||
|
||||
// compile the search regex
|
||||
@ -120,66 +77,17 @@ func TestSearchMultiMatchNoColor(t *testing.T) {
|
||||
}
|
||||
|
||||
// search the sheet
|
||||
matches := sheet.Search(reg, false)
|
||||
matches := sheet.Search(reg)
|
||||
|
||||
// specify the expected results
|
||||
want := []Match{
|
||||
Match{
|
||||
Line: 1,
|
||||
Text: "The quick brown fox",
|
||||
},
|
||||
Match{
|
||||
Line: 3,
|
||||
Text: "the lazy dog.",
|
||||
},
|
||||
}
|
||||
want := "The quick brown fox\n\nthe lazy dog."
|
||||
|
||||
// assert that the correct matches were returned
|
||||
if !reflect.DeepEqual(matches, want) {
|
||||
t.Errorf(
|
||||
"failed to return expected matches: want:\n%s, got:\n%s",
|
||||
spew.Sdump(want),
|
||||
spew.Sdump(matches),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// TestSearchMultiMatchColorized asserts that the expected output is returned
|
||||
// when a multiple matches are returned, and colorization is applied
|
||||
func TestSearchMultiMatchColorized(t *testing.T) {
|
||||
|
||||
// mock a cheatsheet
|
||||
sheet := Sheet{
|
||||
Text: "The quick brown fox\njumped over\nthe lazy dog.",
|
||||
}
|
||||
|
||||
// compile the search regex
|
||||
reg, err := regexp.Compile("(?i)the")
|
||||
if err != nil {
|
||||
t.Errorf("failed to compile regex: %v", err)
|
||||
}
|
||||
|
||||
// search the sheet
|
||||
matches := sheet.Search(reg, true)
|
||||
|
||||
// specify the expected results
|
||||
want := []Match{
|
||||
Match{
|
||||
Line: 1,
|
||||
Text: "\x1b[1;31mThe\x1b[0m quick brown fox",
|
||||
},
|
||||
Match{
|
||||
Line: 3,
|
||||
Text: "\x1b[1;31mthe\x1b[0m lazy dog.",
|
||||
},
|
||||
}
|
||||
|
||||
// assert that the correct matches were returned
|
||||
if !reflect.DeepEqual(matches, want) {
|
||||
t.Errorf(
|
||||
"failed to return expected matches: want:\n%s, got:\n%s",
|
||||
spew.Sdump(want),
|
||||
spew.Sdump(matches),
|
||||
want,
|
||||
matches,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -4,17 +4,10 @@ import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/tj/front"
|
||||
"github.com/cheat/cheat/internal/frontmatter"
|
||||
)
|
||||
|
||||
// frontmatter is an un-exported helper struct used in parsing cheatsheets
|
||||
type frontmatter struct {
|
||||
Tags []string
|
||||
Syntax string
|
||||
}
|
||||
|
||||
// Sheet encapsulates sheet information
|
||||
type Sheet struct {
|
||||
Title string
|
||||
@ -39,9 +32,8 @@ func New(
|
||||
return Sheet{}, fmt.Errorf("failed to read file: %s, %v", path, err)
|
||||
}
|
||||
|
||||
// parse the front-matter
|
||||
var fm frontmatter
|
||||
text, err := front.Unmarshal(markdown, &fm)
|
||||
// parse the cheatsheet frontmatter
|
||||
text, fm, err := frontmatter.Parse(string(markdown))
|
||||
if err != nil {
|
||||
return Sheet{}, fmt.Errorf("failed to parse front-matter: %v", err)
|
||||
}
|
||||
@ -56,7 +48,7 @@ func New(
|
||||
return Sheet{
|
||||
Title: title,
|
||||
Path: path,
|
||||
Text: strings.TrimSpace(string(text)) + "\n",
|
||||
Text: text + "\n",
|
||||
Tags: tags,
|
||||
Syntax: fm.Syntax,
|
||||
ReadOnly: readOnly,
|
||||
|
@ -33,7 +33,7 @@ func Load(cheatpaths []cp.Cheatpath) ([]map[string]sheet.Sheet, error) {
|
||||
|
||||
// fail if an error occurred while walking the directory
|
||||
if err != nil {
|
||||
return fmt.Errorf("error walking path: %v", err)
|
||||
return fmt.Errorf("failed to walk path: %v", err)
|
||||
}
|
||||
|
||||
// don't register directories as cheatsheets
|
||||
@ -45,18 +45,28 @@ func Load(cheatpaths []cp.Cheatpath) ([]map[string]sheet.Sheet, error) {
|
||||
// accessed. Eg: `cheat tar` - `tar` is the title)
|
||||
title := strings.TrimPrefix(
|
||||
strings.TrimPrefix(path, cheatpath.Path),
|
||||
"/",
|
||||
string(os.PathSeparator),
|
||||
)
|
||||
|
||||
// ignore dotfiles. Otherwise, we'll likely load .git/*
|
||||
if strings.HasPrefix(title, ".") {
|
||||
// ignore hidden files and directories. Otherwise, we'll likely load
|
||||
// .git/* and .DS_Store.
|
||||
//
|
||||
// NB: this is still somewhat brittle in that it will miss files
|
||||
// contained within hidden directories in the middle of a path, though
|
||||
// that should not realistically occur.
|
||||
if strings.HasPrefix(title, ".") || strings.HasPrefix(info.Name(), ".") {
|
||||
return nil
|
||||
}
|
||||
|
||||
// parse the cheatsheet file into a `sheet` struct
|
||||
s, err := sheet.New(title, path, cheatpath.Tags, cheatpath.ReadOnly)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not create sheet: %v", err)
|
||||
return fmt.Errorf(
|
||||
"failed to load sheet: %s, path: %s, err: %v",
|
||||
title,
|
||||
path,
|
||||
err,
|
||||
)
|
||||
}
|
||||
|
||||
// register the cheatsheet on its cheatpath, keyed by its title
|
||||
|
36
internal/sheets/tags.go
Normal file
36
internal/sheets/tags.go
Normal file
@ -0,0 +1,36 @@
|
||||
package sheets
|
||||
|
||||
import (
|
||||
"sort"
|
||||
|
||||
"github.com/cheat/cheat/internal/sheet"
|
||||
)
|
||||
|
||||
// Tags returns a slice of all tags in use in any sheet
|
||||
func Tags(cheatpaths []map[string]sheet.Sheet) []string {
|
||||
|
||||
// create a map of all tags in use in any sheet
|
||||
tags := make(map[string]bool)
|
||||
|
||||
// iterate over all tags on all sheets on all cheatpaths
|
||||
for _, path := range cheatpaths {
|
||||
for _, sheet := range path {
|
||||
for _, tag := range sheet.Tags {
|
||||
tags[tag] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// restructure the map into a slice
|
||||
sorted := []string{}
|
||||
for tag := range tags {
|
||||
sorted = append(sorted, tag)
|
||||
}
|
||||
|
||||
// sort the slice
|
||||
sort.Slice(sorted, func(i, j int) bool {
|
||||
return sorted[i] < sorted[j]
|
||||
})
|
||||
|
||||
return sorted
|
||||
}
|
51
internal/sheets/tags_test.go
Normal file
51
internal/sheets/tags_test.go
Normal file
@ -0,0 +1,51 @@
|
||||
package sheets
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
|
||||
"github.com/cheat/cheat/internal/sheet"
|
||||
)
|
||||
|
||||
// TestTags asserts that cheatsheet tags are properly returned
|
||||
func TestTags(t *testing.T) {
|
||||
|
||||
// mock cheatsheets available on multiple cheatpaths
|
||||
cheatpaths := []map[string]sheet.Sheet{
|
||||
|
||||
// mock community cheatsheets
|
||||
map[string]sheet.Sheet{
|
||||
"foo": sheet.Sheet{Title: "foo", Tags: []string{"alpha"}},
|
||||
"bar": sheet.Sheet{Title: "bar", Tags: []string{"alpha", "bravo"}},
|
||||
},
|
||||
|
||||
// mock local cheatsheets
|
||||
map[string]sheet.Sheet{
|
||||
"bar": sheet.Sheet{Title: "bar", Tags: []string{"bravo", "charlie"}},
|
||||
"baz": sheet.Sheet{Title: "baz", Tags: []string{"delta"}},
|
||||
},
|
||||
}
|
||||
|
||||
// consolidate the cheatsheets
|
||||
tags := Tags(cheatpaths)
|
||||
|
||||
// specify the expected output
|
||||
want := []string{
|
||||
"alpha",
|
||||
"bravo",
|
||||
"charlie",
|
||||
"delta",
|
||||
}
|
||||
|
||||
// assert that the cheatsheets properly consolidated
|
||||
if !reflect.DeepEqual(tags, want) {
|
||||
t.Errorf(
|
||||
"failed to return tags: want:\n%s, got:\n%s",
|
||||
spew.Sdump(want),
|
||||
spew.Sdump(tags),
|
||||
)
|
||||
}
|
||||
|
||||
}
|
74
scripts/cheat.bash
Executable file
74
scripts/cheat.bash
Executable 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
|
13
scripts/cheat.fish
Executable file
13
scripts/cheat.fish
Executable file
@ -0,0 +1,13 @@
|
||||
complete -c cheat -f -a "(cheat -l | tail -n +2 | cut -d ' ' -f 1)"
|
||||
complete -c cheat -l init -d "Write a default config file to stdout"
|
||||
complete -c cheat -s c -l colorize -d "Colorize output"
|
||||
complete -c cheat -s d -l directories -d "List cheatsheet directories"
|
||||
complete -c cheat -s e -l edit -x -a "(cheat -l | tail -n +2 | cut -d ' ' -f 1)" -d "Edit cheatsheet"
|
||||
complete -c cheat -s l -l list -d "List cheatsheets"
|
||||
complete -c cheat -s p -l path -x -a "(cheat -d | cut -d ':' -f 1)" -d "Return only sheets found on given path"
|
||||
complete -c cheat -s r -l regex -d "Treat search phrase as a regex"
|
||||
complete -c cheat -s s -l search -x -d "Search cheatsheets for given phrase"
|
||||
complete -c cheat -s t -l tag -x -a "(cheat -T)" -d "Return only sheets matching the given tag"
|
||||
complete -c cheat -s T -l tags -d "List all tags in use"
|
||||
complete -c cheat -s v -l version -d "Print the version number"
|
||||
complete -c cheat -l rm -x -a "(cheat -l | tail -n +2 | cut -d ' ' -f 1)" -d "Remove (delete) cheatsheet"
|
66
scripts/cheat.zsh
Executable file
66
scripts/cheat.zsh
Executable file
@ -0,0 +1,66 @@
|
||||
#compdef cheat
|
||||
|
||||
local cheats taglist pathlist
|
||||
|
||||
_cheat_complete_personal_cheatsheets()
|
||||
{
|
||||
cheats=("${(f)$(cheat -l -t personal | tail -n +2 | cut -d' ' -f1)}")
|
||||
_describe -t cheats 'cheats' cheats
|
||||
}
|
||||
|
||||
_cheat_complete_full_cheatsheets()
|
||||
{
|
||||
cheats=("${(f)$(cheat -l | tail -n +2 | cut -d' ' -f1)}")
|
||||
_describe -t cheats 'cheats' cheats
|
||||
}
|
||||
|
||||
_cheat_complete_tags()
|
||||
{
|
||||
taglist=("${(f)$(cheat -T)}")
|
||||
_describe -t taglist 'taglist' taglist
|
||||
}
|
||||
|
||||
_cheat_complete_paths()
|
||||
{
|
||||
pathlist=("${(f)$(cheat -d | cut -d':' -f1)}")
|
||||
_describe -t pathlist 'pathlist' pathlist
|
||||
}
|
||||
|
||||
_cheat() {
|
||||
|
||||
_arguments -C \
|
||||
'(--init)--init[Write a default config file to stdout]: :->none' \
|
||||
'(-c --colorize)'{-c,--colorize}'[Colorize output]: :->none' \
|
||||
'(-d --directories)'{-d,--directories}'[List cheatsheet directories]: :->none' \
|
||||
'(-e --edit)'{-e,--edit}'[Edit <sheet>]: :->personal' \
|
||||
'(-l --list)'{-l,--list}'[List cheatsheets]: :->full' \
|
||||
'(-p --path)'{-p,--path}'[Return only sheets found on path <name>]: :->pathlist' \
|
||||
'(-r --regex)'{-r,--regex}'[Treat search <phrase> as a regex]: :->none' \
|
||||
'(-s --search)'{-s,--search}'[Search cheatsheets for <phrase>]: :->none' \
|
||||
'(-t --tag)'{-t,--tag}'[Return only sheets matching <tag>]: :->taglist' \
|
||||
'(-T --tags)'{-T,--tags}'[List all tags in use]: :->none' \
|
||||
'(-v --version)'{-v,--version}'[Print the version number]: :->none' \
|
||||
'(--rm)--rm[Remove (delete) <sheet>]: :->personal' \
|
||||
'(-)*: :->full'
|
||||
|
||||
case $state in
|
||||
(none)
|
||||
;;
|
||||
(full)
|
||||
_cheat_complete_full_cheatsheets
|
||||
;;
|
||||
(personal)
|
||||
_cheat_complete_personal_cheatsheets
|
||||
;;
|
||||
(taglist)
|
||||
_cheat_complete_tags
|
||||
;;
|
||||
(pathlist)
|
||||
_cheat_complete_paths
|
||||
;;
|
||||
(*)
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
_cheat
|
@ -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 }'`
|
||||
}
|
15
vendor/github.com/alecthomas/chroma/.golangci.yml
generated
vendored
15
vendor/github.com/alecthomas/chroma/.golangci.yml
generated
vendored
@ -15,6 +15,16 @@ linters:
|
||||
- gocyclo
|
||||
- dupl
|
||||
- gochecknoglobals
|
||||
- funlen
|
||||
- godox
|
||||
- wsl
|
||||
- gomnd
|
||||
- gocognit
|
||||
- goerr113
|
||||
- nolintlint
|
||||
- testpackage
|
||||
- godot
|
||||
- nestif
|
||||
|
||||
linters-settings:
|
||||
govet:
|
||||
@ -43,3 +53,8 @@ issues:
|
||||
- 'Potential file inclusion via variable'
|
||||
- 'should have comment or be unexported'
|
||||
- 'comment on exported var .* should be of the form'
|
||||
- 'at least one file in a package should have a package comment'
|
||||
- 'string literal contains the Unicode'
|
||||
- 'methods on the same type should have the same receiver name'
|
||||
- '_TokenType_name should be _TokenTypeName'
|
||||
- '`_TokenType_map` should be `_TokenTypeMap`'
|
||||
|
30
vendor/github.com/alecthomas/chroma/.goreleaser.yml
generated
vendored
30
vendor/github.com/alecthomas/chroma/.goreleaser.yml
generated
vendored
@ -3,28 +3,30 @@ release:
|
||||
github:
|
||||
owner: alecthomas
|
||||
name: chroma
|
||||
brew:
|
||||
install: bin.install "chroma"
|
||||
brews:
|
||||
-
|
||||
install: bin.install "chroma"
|
||||
builds:
|
||||
- goos:
|
||||
- linux
|
||||
- darwin
|
||||
- windows
|
||||
- linux
|
||||
- darwin
|
||||
- windows
|
||||
goarch:
|
||||
- amd64
|
||||
- "386"
|
||||
- amd64
|
||||
- "386"
|
||||
goarm:
|
||||
- "6"
|
||||
- "6"
|
||||
main: ./cmd/chroma/main.go
|
||||
ldflags: -s -w -X main.version={{.Version}} -X main.commit={{.Commit}} -X main.date={{.Date}}
|
||||
binary: chroma
|
||||
archive:
|
||||
format: tar.gz
|
||||
name_template: '{{ .Binary }}-{{ .Version }}-{{ .Os }}-{{ .Arch }}{{ if .Arm }}v{{
|
||||
archives:
|
||||
-
|
||||
format: tar.gz
|
||||
name_template: '{{ .Binary }}-{{ .Version }}-{{ .Os }}-{{ .Arch }}{{ if .Arm }}v{{
|
||||
.Arm }}{{ end }}'
|
||||
files:
|
||||
- COPYING
|
||||
- README*
|
||||
files:
|
||||
- COPYING
|
||||
- README*
|
||||
snapshot:
|
||||
name_template: SNAPSHOT-{{ .Commit }}
|
||||
checksum:
|
||||
|
4
vendor/github.com/alecthomas/chroma/.travis.yml
generated
vendored
4
vendor/github.com/alecthomas/chroma/.travis.yml
generated
vendored
@ -1,8 +1,10 @@
|
||||
sudo: false
|
||||
language: go
|
||||
go:
|
||||
- "1.13.x"
|
||||
script:
|
||||
- go test -v ./...
|
||||
- curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | bash -s v1.15.0
|
||||
- curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | bash -s v1.26.0
|
||||
- ./bin/golangci-lint run
|
||||
- git clean -fdx .
|
||||
after_success:
|
||||
|
19
vendor/github.com/alecthomas/chroma/Makefile
generated
vendored
Normal file
19
vendor/github.com/alecthomas/chroma/Makefile
generated
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
.PHONY: chromad upload all
|
||||
|
||||
all: README.md tokentype_string.go
|
||||
|
||||
README.md: lexers/*/*.go
|
||||
./table.py
|
||||
|
||||
tokentype_string.go: types.go
|
||||
go generate
|
||||
|
||||
chromad:
|
||||
(cd ./cmd/chromad && go get github.com/GeertJohan/go.rice/rice@master && go install github.com/GeertJohan/go.rice/rice)
|
||||
rm -f chromad
|
||||
(export CGOENABLED=0 GOOS=linux ; cd ./cmd/chromad && go build -o ../../chromad .)
|
||||
rice append -i ./cmd/chromad --exec=./chromad
|
||||
|
||||
upload: chromad
|
||||
scp chromad root@swapoff.org: && \
|
||||
ssh root@swapoff.org 'install -m755 ./chromad /srv/http/swapoff.org/bin && service chromad restart'
|
9
vendor/github.com/alecthomas/chroma/README.md
generated
vendored
9
vendor/github.com/alecthomas/chroma/README.md
generated
vendored
@ -44,17 +44,17 @@ F | Factor, Fish, Forth, Fortran, FSharp
|
||||
G | GAS, GDScript, Genshi, Genshi HTML, Genshi Text, GLSL, Gnuplot, Go, Go HTML Template, Go Text Template, GraphQL, Groovy
|
||||
H | Handlebars, Haskell, Haxe, HCL, Hexdump, HTML, HTTP, Hy
|
||||
I | Idris, INI, Io
|
||||
J | Java, JavaScript, JSON, Julia, Jungle
|
||||
J | J, Java, JavaScript, JSON, Julia, Jungle
|
||||
K | Kotlin
|
||||
L | Lighttpd configuration file, LLVM, Lua
|
||||
M | Mako, markdown, Mason, Mathematica, Matlab, MiniZinc, Modula-2, MonkeyC, MorrowindScript, Myghty, MySQL
|
||||
M | Mako, markdown, Mason, Mathematica, Matlab, MiniZinc, MLIR, Modula-2, MonkeyC, MorrowindScript, Myghty, MySQL
|
||||
N | NASM, Newspeak, Nginx configuration file, Nim, Nix
|
||||
O | Objective-C, OCaml, Octave, OpenSCAD, Org Mode
|
||||
P | PacmanConf, Perl, PHP, Pig, PkgConfig, PL/pgSQL, plaintext, PostgreSQL SQL dialect, PostScript, POVRay, PowerShell, Prolog, Protocol Buffer, Puppet, Python, Python 3
|
||||
Q | QBasic
|
||||
R | R, Racket, Ragel, react, reg, reStructuredText, Rexx, Ruby, Rust
|
||||
S | Sass, Scala, Scheme, Scilab, SCSS, Smalltalk, Smarty, Snobol, Solidity, SPARQL, SQL, SquidConf, Swift, SYSTEMD, systemverilog
|
||||
T | TASM, Tcl, Tcsh, Termcap, Terminfo, Terraform, TeX, Thrift, TOML, TradingView, Transact-SQL, Turing, Turtle, Twig, TypeScript, TypoScript, TypoScriptCssData, TypoScriptHtmlData
|
||||
S | Sass, Scala, Scheme, Scilab, SCSS, Smalltalk, Smarty, SML, Snobol, Solidity, SPARQL, SQL, SquidConf, Swift, SYSTEMD, systemverilog
|
||||
T | TableGen, TASM, Tcl, Tcsh, Termcap, Terminfo, Terraform, TeX, Thrift, TOML, TradingView, Transact-SQL, Turing, Turtle, Twig, TypeScript, TypoScript, TypoScriptCssData, TypoScriptHtmlData
|
||||
V | VB.net, verilog, VHDL, VimL, vue
|
||||
W | WDTE
|
||||
X | XML, Xorg
|
||||
@ -183,6 +183,7 @@ following constructor options:
|
||||
- `ClassPrefix(prefix)` - prefix each generated CSS class.
|
||||
- `TabWidth(width)` - Set the rendered tab width, in characters.
|
||||
- `WithLineNumbers()` - Render line numbers (style with `LineNumbers`).
|
||||
- `LinkableLineNumbers()` - Make the line numbers linkable.
|
||||
- `HighlightLines(ranges)` - Highlight lines in these ranges (style with `LineHighlight`).
|
||||
- `LineNumbersInTable()` - Use a table for formatting line numbers and code, rather than spans.
|
||||
|
||||
|
2
vendor/github.com/alecthomas/chroma/delegate.go
generated
vendored
2
vendor/github.com/alecthomas/chroma/delegate.go
generated
vendored
@ -34,7 +34,7 @@ type insertion struct {
|
||||
tokens []Token
|
||||
}
|
||||
|
||||
func (d *delegatingLexer) Tokenise(options *TokeniseOptions, text string) (Iterator, error) {
|
||||
func (d *delegatingLexer) Tokenise(options *TokeniseOptions, text string) (Iterator, error) { // nolint: gocognit
|
||||
tokens, err := Tokenise(Coalesce(d.language), options, text)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
4
vendor/github.com/alecthomas/chroma/formatters/api.go
generated
vendored
4
vendor/github.com/alecthomas/chroma/formatters/api.go
generated
vendored
@ -6,6 +6,7 @@ import (
|
||||
|
||||
"github.com/alecthomas/chroma"
|
||||
"github.com/alecthomas/chroma/formatters/html"
|
||||
"github.com/alecthomas/chroma/formatters/svg"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -19,7 +20,8 @@ var (
|
||||
return nil
|
||||
}))
|
||||
// Default HTML formatter outputs self-contained HTML.
|
||||
htmlFull = Register("html", html.New(html.Standalone(), html.WithClasses())) // nolint
|
||||
htmlFull = Register("html", html.New(html.Standalone(true), html.WithClasses(true))) // nolint
|
||||
SVG = Register("svg", svg.New(svg.EmbedFont("Liberation Mono", svg.FontLiberationMono, svg.WOFF)))
|
||||
)
|
||||
|
||||
// Fallback formatter.
|
||||
|
155
vendor/github.com/alecthomas/chroma/formatters/html/html.go
generated
vendored
155
vendor/github.com/alecthomas/chroma/formatters/html/html.go
generated
vendored
@ -14,32 +14,59 @@ import (
|
||||
type Option func(f *Formatter)
|
||||
|
||||
// Standalone configures the HTML formatter for generating a standalone HTML document.
|
||||
func Standalone() Option { return func(f *Formatter) { f.standalone = true } }
|
||||
func Standalone(b bool) Option { return func(f *Formatter) { f.standalone = b } }
|
||||
|
||||
// ClassPrefix sets the CSS class prefix.
|
||||
func ClassPrefix(prefix string) Option { return func(f *Formatter) { f.prefix = prefix } }
|
||||
|
||||
// WithClasses emits HTML using CSS classes, rather than inline styles.
|
||||
func WithClasses() Option { return func(f *Formatter) { f.Classes = true } }
|
||||
func WithClasses(b bool) Option { return func(f *Formatter) { f.Classes = b } }
|
||||
|
||||
// WithAllClasses disables an optimisation that omits redundant CSS classes.
|
||||
func WithAllClasses(b bool) Option { return func(f *Formatter) { f.allClasses = b } }
|
||||
|
||||
// TabWidth sets the number of characters for a tab. Defaults to 8.
|
||||
func TabWidth(width int) Option { return func(f *Formatter) { f.tabWidth = width } }
|
||||
|
||||
// PreventSurroundingPre prevents the surrounding pre tags around the generated code
|
||||
func PreventSurroundingPre() Option { return func(f *Formatter) { f.preventSurroundingPre = true } }
|
||||
// PreventSurroundingPre prevents the surrounding pre tags around the generated code.
|
||||
func PreventSurroundingPre(b bool) Option {
|
||||
return func(f *Formatter) {
|
||||
if b {
|
||||
f.preWrapper = nopPreWrapper
|
||||
} else {
|
||||
f.preWrapper = defaultPreWrapper
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// WithPreWrapper allows control of the surrounding pre tags.
|
||||
func WithPreWrapper(wrapper PreWrapper) Option {
|
||||
return func(f *Formatter) {
|
||||
f.preWrapper = wrapper
|
||||
}
|
||||
}
|
||||
|
||||
// WithLineNumbers formats output with line numbers.
|
||||
func WithLineNumbers() Option {
|
||||
func WithLineNumbers(b bool) Option {
|
||||
return func(f *Formatter) {
|
||||
f.lineNumbers = true
|
||||
f.lineNumbers = b
|
||||
}
|
||||
}
|
||||
|
||||
// LineNumbersInTable will, when combined with WithLineNumbers, separate the line numbers
|
||||
// and code in table td's, which make them copy-and-paste friendly.
|
||||
func LineNumbersInTable() Option {
|
||||
func LineNumbersInTable(b bool) Option {
|
||||
return func(f *Formatter) {
|
||||
f.lineNumbersInTable = true
|
||||
f.lineNumbersInTable = b
|
||||
}
|
||||
}
|
||||
|
||||
// LinkableLineNumbers decorates the line numbers HTML elements with an "id"
|
||||
// attribute so they can be linked.
|
||||
func LinkableLineNumbers(b bool, prefix string) Option {
|
||||
return func(f *Formatter) {
|
||||
f.linkableLineNumbers = b
|
||||
f.lineNumbersIDPrefix = prefix
|
||||
}
|
||||
}
|
||||
|
||||
@ -64,6 +91,7 @@ func BaseLineNumber(n int) Option {
|
||||
func New(options ...Option) *Formatter {
|
||||
f := &Formatter{
|
||||
baseLineNumber: 1,
|
||||
preWrapper: defaultPreWrapper,
|
||||
}
|
||||
for _, option := range options {
|
||||
option(f)
|
||||
@ -71,17 +99,60 @@ func New(options ...Option) *Formatter {
|
||||
return f
|
||||
}
|
||||
|
||||
// PreWrapper defines the operations supported in WithPreWrapper.
|
||||
type PreWrapper interface {
|
||||
// Start is called to write a start <pre> element.
|
||||
// The code flag tells whether this block surrounds
|
||||
// highlighted code. This will be false when surrounding
|
||||
// line numbers.
|
||||
Start(code bool, styleAttr string) string
|
||||
|
||||
// End is called to write the end </pre> element.
|
||||
End(code bool) string
|
||||
}
|
||||
|
||||
type preWrapper struct {
|
||||
start func(code bool, styleAttr string) string
|
||||
end func(code bool) string
|
||||
}
|
||||
|
||||
func (p preWrapper) Start(code bool, styleAttr string) string {
|
||||
return p.start(code, styleAttr)
|
||||
}
|
||||
|
||||
func (p preWrapper) End(code bool) string {
|
||||
return p.end(code)
|
||||
}
|
||||
|
||||
var (
|
||||
nopPreWrapper = preWrapper{
|
||||
start: func(code bool, styleAttr string) string { return "" },
|
||||
end: func(code bool) string { return "" },
|
||||
}
|
||||
defaultPreWrapper = preWrapper{
|
||||
start: func(code bool, styleAttr string) string {
|
||||
return fmt.Sprintf("<pre%s>", styleAttr)
|
||||
},
|
||||
end: func(code bool) string {
|
||||
return "</pre>"
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
// Formatter that generates HTML.
|
||||
type Formatter struct {
|
||||
standalone bool
|
||||
prefix string
|
||||
Classes bool // Exported field to detect when classes are being used
|
||||
preventSurroundingPre bool
|
||||
tabWidth int
|
||||
lineNumbers bool
|
||||
lineNumbersInTable bool
|
||||
highlightRanges highlightRanges
|
||||
baseLineNumber int
|
||||
standalone bool
|
||||
prefix string
|
||||
Classes bool // Exported field to detect when classes are being used
|
||||
allClasses bool
|
||||
preWrapper PreWrapper
|
||||
tabWidth int
|
||||
lineNumbers bool
|
||||
lineNumbersInTable bool
|
||||
linkableLineNumbers bool
|
||||
lineNumbersIDPrefix string
|
||||
highlightRanges highlightRanges
|
||||
baseLineNumber int
|
||||
}
|
||||
|
||||
type highlightRanges [][2]int
|
||||
@ -91,11 +162,6 @@ func (h highlightRanges) Swap(i, j int) { h[i], h[j] = h[j], h[i] }
|
||||
func (h highlightRanges) Less(i, j int) bool { return h[i][0] < h[j][0] }
|
||||
|
||||
func (f *Formatter) Format(w io.Writer, style *chroma.Style, iterator chroma.Iterator) (err error) {
|
||||
defer func() {
|
||||
if perr := recover(); perr != nil {
|
||||
err = perr.(error)
|
||||
}
|
||||
}()
|
||||
return f.writeHTML(w, style, iterator.Tokens())
|
||||
}
|
||||
|
||||
@ -126,7 +192,7 @@ func (f *Formatter) writeHTML(w io.Writer, style *chroma.Style, tokens []chroma.
|
||||
wrapInTable := f.lineNumbers && f.lineNumbersInTable
|
||||
|
||||
lines := chroma.SplitTokensIntoLines(tokens)
|
||||
lineDigits := len(fmt.Sprintf("%d", len(lines)))
|
||||
lineDigits := len(fmt.Sprintf("%d", f.baseLineNumber+len(lines)-1))
|
||||
highlightIndex := 0
|
||||
|
||||
if wrapInTable {
|
||||
@ -134,9 +200,7 @@ func (f *Formatter) writeHTML(w io.Writer, style *chroma.Style, tokens []chroma.
|
||||
fmt.Fprintf(w, "<div%s>\n", f.styleAttr(css, chroma.Background))
|
||||
fmt.Fprintf(w, "<table%s><tr>", f.styleAttr(css, chroma.LineTable))
|
||||
fmt.Fprintf(w, "<td%s>\n", f.styleAttr(css, chroma.LineTableTD))
|
||||
if !f.preventSurroundingPre {
|
||||
fmt.Fprintf(w, "<pre%s>", f.styleAttr(css, chroma.Background))
|
||||
}
|
||||
fmt.Fprintf(w, f.preWrapper.Start(false, f.styleAttr(css, chroma.Background)))
|
||||
for index := range lines {
|
||||
line := f.baseLineNumber + index
|
||||
highlight, next := f.shouldHighlight(highlightIndex, line)
|
||||
@ -147,22 +211,19 @@ func (f *Formatter) writeHTML(w io.Writer, style *chroma.Style, tokens []chroma.
|
||||
fmt.Fprintf(w, "<span%s>", f.styleAttr(css, chroma.LineHighlight))
|
||||
}
|
||||
|
||||
fmt.Fprintf(w, "<span%s>%*d\n</span>", f.styleAttr(css, chroma.LineNumbersTable), lineDigits, line)
|
||||
fmt.Fprintf(w, "<span%s%s>%*d\n</span>", f.styleAttr(css, chroma.LineNumbersTable), f.lineIDAttribute(line), lineDigits, line)
|
||||
|
||||
if highlight {
|
||||
fmt.Fprintf(w, "</span>")
|
||||
}
|
||||
}
|
||||
if !f.preventSurroundingPre {
|
||||
fmt.Fprint(w, "</pre>")
|
||||
}
|
||||
fmt.Fprint(w, f.preWrapper.End(false))
|
||||
fmt.Fprint(w, "</td>\n")
|
||||
fmt.Fprintf(w, "<td%s>\n", f.styleAttr(css, chroma.LineTableTD, "width:100%"))
|
||||
}
|
||||
|
||||
if !f.preventSurroundingPre {
|
||||
fmt.Fprintf(w, "<pre%s>", f.styleAttr(css, chroma.Background))
|
||||
}
|
||||
fmt.Fprintf(w, f.preWrapper.Start(true, f.styleAttr(css, chroma.Background)))
|
||||
|
||||
highlightIndex = 0
|
||||
for index, tokens := range lines {
|
||||
// 1-based line number.
|
||||
@ -176,7 +237,7 @@ func (f *Formatter) writeHTML(w io.Writer, style *chroma.Style, tokens []chroma.
|
||||
}
|
||||
|
||||
if f.lineNumbers && !wrapInTable {
|
||||
fmt.Fprintf(w, "<span%s>%*d</span>", f.styleAttr(css, chroma.LineNumbers), lineDigits, line)
|
||||
fmt.Fprintf(w, "<span%s%s>%*d</span>", f.styleAttr(css, chroma.LineNumbers), f.lineIDAttribute(line), lineDigits, line)
|
||||
}
|
||||
|
||||
for _, token := range tokens {
|
||||
@ -192,9 +253,7 @@ func (f *Formatter) writeHTML(w io.Writer, style *chroma.Style, tokens []chroma.
|
||||
}
|
||||
}
|
||||
|
||||
if !f.preventSurroundingPre {
|
||||
fmt.Fprint(w, "</pre>")
|
||||
}
|
||||
fmt.Fprintf(w, f.preWrapper.End(true))
|
||||
|
||||
if wrapInTable {
|
||||
fmt.Fprint(w, "</td></tr></table>\n")
|
||||
@ -209,6 +268,13 @@ func (f *Formatter) writeHTML(w io.Writer, style *chroma.Style, tokens []chroma.
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *Formatter) lineIDAttribute(line int) string {
|
||||
if !f.linkableLineNumbers {
|
||||
return ""
|
||||
}
|
||||
return fmt.Sprintf(" id=\"%s%d\"", f.lineNumbersIDPrefix, line)
|
||||
}
|
||||
|
||||
func (f *Formatter) shouldHighlight(highlightIndex, line int) (bool, bool) {
|
||||
next := false
|
||||
for highlightIndex < len(f.highlightRanges) && line > f.highlightRanges[highlightIndex][1] {
|
||||
@ -283,6 +349,13 @@ func (f *Formatter) WriteCSS(w io.Writer, style *chroma.Style) error {
|
||||
return err
|
||||
}
|
||||
}
|
||||
// Special-case line number highlighting when targeted.
|
||||
if f.lineNumbers || f.lineNumbersInTable {
|
||||
targetedLineCSS := StyleEntryToCSS(style.Get(chroma.LineHighlight))
|
||||
for _, tt := range []chroma.TokenType{chroma.LineNumbers, chroma.LineNumbersTable} {
|
||||
fmt.Fprintf(w, "/* %s targeted by URL anchor */ .%schroma .%s:target { %s }\n", tt, f.prefix, f.class(tt), targetedLineCSS)
|
||||
}
|
||||
}
|
||||
tts := []int{}
|
||||
for tt := range css {
|
||||
tts = append(tts, int(tt))
|
||||
@ -293,8 +366,12 @@ func (f *Formatter) WriteCSS(w io.Writer, style *chroma.Style) error {
|
||||
if tt == chroma.Background {
|
||||
continue
|
||||
}
|
||||
class := f.class(tt)
|
||||
if class == "" {
|
||||
continue
|
||||
}
|
||||
styles := css[tt]
|
||||
if _, err := fmt.Fprintf(w, "/* %s */ .%schroma .%s { %s }\n", tt, f.prefix, f.class(tt), styles); err != nil {
|
||||
if _, err := fmt.Fprintf(w, "/* %s */ .%schroma .%s { %s }\n", tt, f.prefix, class, styles); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@ -310,7 +387,7 @@ func (f *Formatter) styleToCSS(style *chroma.Style) map[chroma.TokenType]string
|
||||
if t != chroma.Background {
|
||||
entry = entry.Sub(bg)
|
||||
}
|
||||
if entry.IsZero() {
|
||||
if !f.allClasses && entry.IsZero() {
|
||||
continue
|
||||
}
|
||||
classes[t] = StyleEntryToCSS(entry)
|
||||
|
51
vendor/github.com/alecthomas/chroma/formatters/svg/font_liberation_mono.go
generated
vendored
Normal file
51
vendor/github.com/alecthomas/chroma/formatters/svg/font_liberation_mono.go
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
222
vendor/github.com/alecthomas/chroma/formatters/svg/svg.go
generated
vendored
Normal file
222
vendor/github.com/alecthomas/chroma/formatters/svg/svg.go
generated
vendored
Normal file
@ -0,0 +1,222 @@
|
||||
// Package svg contains an SVG formatter.
|
||||
package svg
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"github.com/alecthomas/chroma"
|
||||
)
|
||||
|
||||
// Option sets an option of the SVG formatter.
|
||||
type Option func(f *Formatter)
|
||||
|
||||
// FontFamily sets the font-family.
|
||||
func FontFamily(fontFamily string) Option { return func(f *Formatter) { f.fontFamily = fontFamily } }
|
||||
|
||||
// EmbedFontFile embeds given font file
|
||||
func EmbedFontFile(fontFamily string, fileName string) (option Option, err error) {
|
||||
var format FontFormat
|
||||
switch path.Ext(fileName) {
|
||||
case ".woff":
|
||||
format = WOFF
|
||||
case ".woff2":
|
||||
format = WOFF2
|
||||
case ".ttf":
|
||||
format = TRUETYPE
|
||||
default:
|
||||
return nil, errors.New("unexpected font file suffix")
|
||||
}
|
||||
|
||||
var content []byte
|
||||
if content, err = ioutil.ReadFile(fileName); err == nil {
|
||||
option = EmbedFont(fontFamily, base64.StdEncoding.EncodeToString(content), format)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// EmbedFont embeds given base64 encoded font
|
||||
func EmbedFont(fontFamily string, font string, format FontFormat) Option {
|
||||
return func(f *Formatter) { f.fontFamily = fontFamily; f.embeddedFont = font; f.fontFormat = format }
|
||||
}
|
||||
|
||||
// New SVG formatter.
|
||||
func New(options ...Option) *Formatter {
|
||||
f := &Formatter{fontFamily: "Consolas, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono, Bitstream Vera Sans Mono, Courier New, monospace"}
|
||||
for _, option := range options {
|
||||
option(f)
|
||||
}
|
||||
return f
|
||||
}
|
||||
|
||||
// Formatter that generates SVG.
|
||||
type Formatter struct {
|
||||
fontFamily string
|
||||
embeddedFont string
|
||||
fontFormat FontFormat
|
||||
}
|
||||
|
||||
func (f *Formatter) Format(w io.Writer, style *chroma.Style, iterator chroma.Iterator) (err error) {
|
||||
f.writeSVG(w, style, iterator.Tokens())
|
||||
return err
|
||||
}
|
||||
|
||||
var svgEscaper = strings.NewReplacer(
|
||||
`&`, "&",
|
||||
`<`, "<",
|
||||
`>`, ">",
|
||||
`"`, """,
|
||||
` `, " ",
|
||||
` `, "    ",
|
||||
)
|
||||
|
||||
// EscapeString escapes special characters.
|
||||
func escapeString(s string) string {
|
||||
return svgEscaper.Replace(s)
|
||||
}
|
||||
|
||||
func (f *Formatter) writeSVG(w io.Writer, style *chroma.Style, tokens []chroma.Token) { // nolint: gocyclo
|
||||
svgStyles := f.styleToSVG(style)
|
||||
lines := chroma.SplitTokensIntoLines(tokens)
|
||||
|
||||
fmt.Fprint(w, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
|
||||
fmt.Fprint(w, "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.0//EN\" \"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd\">\n")
|
||||
fmt.Fprintf(w, "<svg width=\"%dpx\" height=\"%dpx\" xmlns=\"http://www.w3.org/2000/svg\">\n", 8*maxLineWidth(lines), 10+int(16.8*float64(len(lines)+1)))
|
||||
|
||||
if f.embeddedFont != "" {
|
||||
f.writeFontStyle(w)
|
||||
}
|
||||
|
||||
fmt.Fprintf(w, "<rect width=\"100%%\" height=\"100%%\" fill=\"%s\"/>\n", style.Get(chroma.Background).Background.String())
|
||||
fmt.Fprintf(w, "<g font-family=\"%s\" font-size=\"14px\" fill=\"%s\">\n", f.fontFamily, style.Get(chroma.Text).Colour.String())
|
||||
|
||||
f.writeTokenBackgrounds(w, lines, style)
|
||||
|
||||
for index, tokens := range lines {
|
||||
fmt.Fprintf(w, "<text x=\"0\" y=\"%fem\" xml:space=\"preserve\">", 1.2*float64(index+1))
|
||||
|
||||
for _, token := range tokens {
|
||||
text := escapeString(token.String())
|
||||
attr := f.styleAttr(svgStyles, token.Type)
|
||||
if attr != "" {
|
||||
text = fmt.Sprintf("<tspan %s>%s</tspan>", attr, text)
|
||||
}
|
||||
fmt.Fprint(w, text)
|
||||
}
|
||||
fmt.Fprint(w, "</text>")
|
||||
}
|
||||
|
||||
fmt.Fprint(w, "\n</g>\n")
|
||||
fmt.Fprint(w, "</svg>\n")
|
||||
}
|
||||
|
||||
func maxLineWidth(lines [][]chroma.Token) int {
|
||||
maxWidth := 0
|
||||
for _, tokens := range lines {
|
||||
length := 0
|
||||
for _, token := range tokens {
|
||||
length += len(strings.Replace(token.String(), ` `, " ", -1))
|
||||
}
|
||||
if length > maxWidth {
|
||||
maxWidth = length
|
||||
}
|
||||
}
|
||||
return maxWidth
|
||||
}
|
||||
|
||||
// There is no background attribute for text in SVG so simply calculate the position and text
|
||||
// of tokens with a background color that differs from the default and add a rectangle for each before
|
||||
// adding the token.
|
||||
func (f *Formatter) writeTokenBackgrounds(w io.Writer, lines [][]chroma.Token, style *chroma.Style) {
|
||||
for index, tokens := range lines {
|
||||
lineLength := 0
|
||||
for _, token := range tokens {
|
||||
length := len(strings.Replace(token.String(), ` `, " ", -1))
|
||||
tokenBackground := style.Get(token.Type).Background
|
||||
if tokenBackground.IsSet() && tokenBackground != style.Get(chroma.Background).Background {
|
||||
fmt.Fprintf(w, "<rect id=\"%s\" x=\"%dch\" y=\"%fem\" width=\"%dch\" height=\"1.2em\" fill=\"%s\" />\n", escapeString(token.String()), lineLength, 1.2*float64(index)+0.25, length, style.Get(token.Type).Background.String())
|
||||
}
|
||||
lineLength += length
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type FontFormat int
|
||||
|
||||
// https://transfonter.org/formats
|
||||
const (
|
||||
WOFF FontFormat = iota
|
||||
WOFF2
|
||||
TRUETYPE
|
||||
)
|
||||
|
||||
var fontFormats = [...]string{
|
||||
"woff",
|
||||
"woff2",
|
||||
"truetype",
|
||||
}
|
||||
|
||||
func (f *Formatter) writeFontStyle(w io.Writer) {
|
||||
fmt.Fprintf(w, `<style>
|
||||
@font-face {
|
||||
font-family: '%s';
|
||||
src: url(data:application/x-font-%s;charset=utf-8;base64,%s) format('%s');'
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
</style>`, f.fontFamily, fontFormats[f.fontFormat], f.embeddedFont, fontFormats[f.fontFormat])
|
||||
}
|
||||
|
||||
func (f *Formatter) styleAttr(styles map[chroma.TokenType]string, tt chroma.TokenType) string {
|
||||
if _, ok := styles[tt]; !ok {
|
||||
tt = tt.SubCategory()
|
||||
if _, ok := styles[tt]; !ok {
|
||||
tt = tt.Category()
|
||||
if _, ok := styles[tt]; !ok {
|
||||
return ""
|
||||
}
|
||||
}
|
||||
}
|
||||
return styles[tt]
|
||||
}
|
||||
|
||||
func (f *Formatter) styleToSVG(style *chroma.Style) map[chroma.TokenType]string {
|
||||
converted := map[chroma.TokenType]string{}
|
||||
bg := style.Get(chroma.Background)
|
||||
// Convert the style.
|
||||
for t := range chroma.StandardTypes {
|
||||
entry := style.Get(t)
|
||||
if t != chroma.Background {
|
||||
entry = entry.Sub(bg)
|
||||
}
|
||||
if entry.IsZero() {
|
||||
continue
|
||||
}
|
||||
converted[t] = StyleEntryToSVG(entry)
|
||||
}
|
||||
return converted
|
||||
}
|
||||
|
||||
// StyleEntryToSVG converts a chroma.StyleEntry to SVG attributes.
|
||||
func StyleEntryToSVG(e chroma.StyleEntry) string {
|
||||
var styles []string
|
||||
|
||||
if e.Colour.IsSet() {
|
||||
styles = append(styles, "fill=\""+e.Colour.String()+"\"")
|
||||
}
|
||||
if e.Bold == chroma.Yes {
|
||||
styles = append(styles, "font-weight=\"bold\"")
|
||||
}
|
||||
if e.Italic == chroma.Yes {
|
||||
styles = append(styles, "font-style=\"italic\"")
|
||||
}
|
||||
if e.Underline == chroma.Yes {
|
||||
styles = append(styles, "text-decoration=\"underline\"")
|
||||
}
|
||||
return strings.Join(styles, " ")
|
||||
}
|
17
vendor/github.com/alecthomas/chroma/formatters/tty_indexed.go
generated
vendored
17
vendor/github.com/alecthomas/chroma/formatters/tty_indexed.go
generated
vendored
@ -200,6 +200,7 @@ func findClosest(table *ttyTable, seeking chroma.Colour) chroma.Colour {
|
||||
}
|
||||
|
||||
func styleToEscapeSequence(table *ttyTable, style *chroma.Style) map[chroma.TokenType]string {
|
||||
style = clearBackground(style)
|
||||
out := map[chroma.TokenType]string{}
|
||||
for _, ttype := range style.Types() {
|
||||
entry := style.Get(ttype)
|
||||
@ -208,16 +209,22 @@ func styleToEscapeSequence(table *ttyTable, style *chroma.Style) map[chroma.Toke
|
||||
return out
|
||||
}
|
||||
|
||||
// Clear the background colour.
|
||||
func clearBackground(style *chroma.Style) *chroma.Style {
|
||||
builder := style.Builder()
|
||||
bg := builder.Get(chroma.Background)
|
||||
bg.Background = 0
|
||||
bg.NoInherit = true
|
||||
builder.AddEntry(chroma.Background, bg)
|
||||
style, _ = builder.Build()
|
||||
return style
|
||||
}
|
||||
|
||||
type indexedTTYFormatter struct {
|
||||
table *ttyTable
|
||||
}
|
||||
|
||||
func (c *indexedTTYFormatter) Format(w io.Writer, style *chroma.Style, it chroma.Iterator) (err error) {
|
||||
defer func() {
|
||||
if perr := recover(); perr != nil {
|
||||
err = perr.(error)
|
||||
}
|
||||
}()
|
||||
theme := styleToEscapeSequence(c.table, style)
|
||||
for token := it(); token != chroma.EOF; token = it() {
|
||||
// TODO: Cache token lookups?
|
||||
|
1
vendor/github.com/alecthomas/chroma/formatters/tty_truecolour.go
generated
vendored
1
vendor/github.com/alecthomas/chroma/formatters/tty_truecolour.go
generated
vendored
@ -11,6 +11,7 @@ import (
|
||||
var TTY16m = Register("terminal16m", chroma.FormatterFunc(trueColourFormatter))
|
||||
|
||||
func trueColourFormatter(w io.Writer, style *chroma.Style, it chroma.Iterator) error {
|
||||
style = clearBackground(style)
|
||||
for token := it(); token != chroma.EOF; token = it() {
|
||||
entry := style.Get(token.Type)
|
||||
if !entry.IsZero() {
|
||||
|
22
vendor/github.com/alecthomas/chroma/go.mod
generated
vendored
22
vendor/github.com/alecthomas/chroma/go.mod
generated
vendored
@ -1,22 +1,18 @@
|
||||
module github.com/alecthomas/chroma
|
||||
|
||||
go 1.13
|
||||
|
||||
require (
|
||||
github.com/GeertJohan/go.rice v1.0.0
|
||||
github.com/alecthomas/assert v0.0.0-20170929043011-405dbfeb8e38
|
||||
github.com/alecthomas/colour v0.0.0-20160524082231-60882d9e2721 // indirect
|
||||
github.com/alecthomas/kong v0.2.1-0.20190708041108-0548c6b1afae
|
||||
github.com/alecthomas/kong-hcl v0.1.8-0.20190615233001-b21fea9723c8
|
||||
github.com/alecthomas/kong v0.2.4
|
||||
github.com/alecthomas/repr v0.0.0-20180818092828-117648cd9897 // indirect
|
||||
github.com/danwakefield/fnmatch v0.0.0-20160403171240-cbb64ac3d964
|
||||
github.com/dlclark/regexp2 v1.1.6
|
||||
github.com/gorilla/csrf v1.6.0
|
||||
github.com/gorilla/handlers v1.4.1
|
||||
github.com/gorilla/mux v1.7.3
|
||||
github.com/mattn/go-colorable v0.0.9
|
||||
github.com/mattn/go-isatty v0.0.4
|
||||
github.com/dlclark/regexp2 v1.2.0
|
||||
github.com/mattn/go-colorable v0.1.6
|
||||
github.com/mattn/go-isatty v0.0.12
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/sergi/go-diff v1.0.0 // indirect
|
||||
github.com/stretchr/testify v1.3.0
|
||||
golang.org/x/sys v0.0.0-20181128092732-4ed8d59d0b35 // indirect
|
||||
github.com/stretchr/testify v1.3.0 // indirect
|
||||
golang.org/x/sys v0.0.0-20200413165638-669c56c373c4 // indirect
|
||||
)
|
||||
|
||||
replace github.com/GeertJohan/go.rice => github.com/alecthomas/go.rice v1.0.1-0.20190719113735-961b99d742e7
|
||||
|
50
vendor/github.com/alecthomas/chroma/go.sum
generated
vendored
50
vendor/github.com/alecthomas/chroma/go.sum
generated
vendored
@ -1,48 +1,26 @@
|
||||
github.com/GeertJohan/go.incremental v1.0.0/go.mod h1:6fAjUhbVuX1KcMD3c8TEgVUqmo4seqhv0i0kdATSkM0=
|
||||
github.com/akavel/rsrc v0.8.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c=
|
||||
github.com/alecthomas/assert v0.0.0-20170929043011-405dbfeb8e38 h1:smF2tmSOzy2Mm+0dGI2AIUHY+w0BUc+4tn40djz7+6U=
|
||||
github.com/alecthomas/assert v0.0.0-20170929043011-405dbfeb8e38/go.mod h1:r7bzyVFMNntcxPZXK3/+KdruV1H5KSlyVY0gc+NgInI=
|
||||
github.com/alecthomas/colour v0.0.0-20160524082231-60882d9e2721 h1:JHZL0hZKJ1VENNfmXvHbgYlbUOvpzYzvy2aZU5gXVeo=
|
||||
github.com/alecthomas/colour v0.0.0-20160524082231-60882d9e2721/go.mod h1:QO9JBoKquHd+jz9nshCh40fOfO+JzsoXy8qTHF68zU0=
|
||||
github.com/alecthomas/go.rice v1.0.1-0.20190719113735-961b99d742e7 h1:0cMlP9evwgTzs5JUe2C/3rLttYjmRm0kbz9fdGBIV1E=
|
||||
github.com/alecthomas/go.rice v1.0.1-0.20190719113735-961b99d742e7/go.mod h1:af5vUNlDNkCjOZeSGFgIJxDje9qdjsO6hshx0gTmZt4=
|
||||
github.com/alecthomas/kong v0.1.17-0.20190424132513-439c674f7ae0/go.mod h1:+inYUSluD+p4L8KdviBSgzcqEjUQOfC5fQDRFuc36lI=
|
||||
github.com/alecthomas/kong v0.2.1-0.20190708041108-0548c6b1afae h1:C4Q9m+oXOxcSWwYk9XzzafY2xAVAaeubZbUHJkw3PlY=
|
||||
github.com/alecthomas/kong v0.2.1-0.20190708041108-0548c6b1afae/go.mod h1:+inYUSluD+p4L8KdviBSgzcqEjUQOfC5fQDRFuc36lI=
|
||||
github.com/alecthomas/kong-hcl v0.1.8-0.20190615233001-b21fea9723c8 h1:atLL+K8Hg0e8863K2X+k7qu+xz3M2a/mWFIACAPf55M=
|
||||
github.com/alecthomas/kong-hcl v0.1.8-0.20190615233001-b21fea9723c8/go.mod h1:MRgZdU3vrFd05IQ89AxUZ0aYdF39BYoNFa324SodPCA=
|
||||
github.com/alecthomas/kong v0.2.4 h1:Y0ZBCHAvHhTHw7FFJ2FzCAAG4pkbTgA45nc7BpMhDNk=
|
||||
github.com/alecthomas/kong v0.2.4/go.mod h1:kQOmtJgV+Lb4aj+I2LEn40cbtawdWJ9Y8QLq+lElKxE=
|
||||
github.com/alecthomas/repr v0.0.0-20180818092828-117648cd9897 h1:p9Sln00KOTlrYkxI1zYWl1QLnEqAqEARBEYa8FQnQcY=
|
||||
github.com/alecthomas/repr v0.0.0-20180818092828-117648cd9897/go.mod h1:xTS7Pm1pD1mvyM075QCDSRqH6qRLXylzS24ZTpRiSzQ=
|
||||
github.com/daaku/go.zipexe v1.0.0 h1:VSOgZtH418pH9L16hC/JrgSNJbbAL26pj7lmD1+CGdY=
|
||||
github.com/daaku/go.zipexe v1.0.0/go.mod h1:z8IiR6TsVLEYKwXAoE/I+8ys/sDkgTzSL0CLnGVd57E=
|
||||
github.com/danwakefield/fnmatch v0.0.0-20160403171240-cbb64ac3d964 h1:y5HC9v93H5EPKqaS1UYVg1uYah5Xf51mBfIoWehClUQ=
|
||||
github.com/danwakefield/fnmatch v0.0.0-20160403171240-cbb64ac3d964/go.mod h1:Xd9hchkHSWYkEqJwUGisez3G1QY8Ryz0sdWrLPMGjLk=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dlclark/regexp2 v1.1.6 h1:CqB4MjHw0MFCDj+PHHjiESmHX+N7t0tJzKvC6M97BRg=
|
||||
github.com/dlclark/regexp2 v1.1.6/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
|
||||
github.com/gorilla/csrf v1.6.0 h1:60oN1cFdncCE8tjwQ3QEkFND5k37lQPcRjnlvm7CIJ0=
|
||||
github.com/gorilla/csrf v1.6.0/go.mod h1:7tSf8kmjNYr7IWDCYhd3U8Ck34iQ/Yw5CJu7bAkHEGI=
|
||||
github.com/gorilla/handlers v1.4.1 h1:BHvcRGJe/TrL+OqFxoKQGddTgeibiOjaBssV5a/N9sw=
|
||||
github.com/gorilla/handlers v1.4.1/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ=
|
||||
github.com/gorilla/mux v1.7.3 h1:gnP5JzjVOuiZD07fKKToCAOjS0yOpj/qPETTXCCS6hw=
|
||||
github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||
github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyCS8BvQ=
|
||||
github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4=
|
||||
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
|
||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||
github.com/mattn/go-colorable v0.0.9 h1:UVL0vNpWh04HeJXV0KLcaT7r06gOH2l4OW6ddYRUIY4=
|
||||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||
github.com/mattn/go-isatty v0.0.4 h1:bnP0vzxcAdeI1zdubAl5PjU6zsERjGZb7raWodagDYs=
|
||||
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/nkovacs/streamquote v1.0.0/go.mod h1:BN+NaZ2CmdKqUuTUXUEm9j95B2TRbpOWpxbJYzzgUsc=
|
||||
github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/dlclark/regexp2 v1.2.0 h1:8sAhBGEM0dRWogWqWyQeIJnxjWO6oIjl8FKqREDsGfk=
|
||||
github.com/dlclark/regexp2 v1.2.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
|
||||
github.com/mattn/go-colorable v0.1.6 h1:6Su7aK7lXmJ/U79bYtBjLNaha4Fs1Rg9plHpcH+vvnE=
|
||||
github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ=
|
||||
@ -52,7 +30,7 @@ github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||
github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
|
||||
golang.org/x/sys v0.0.0-20181128092732-4ed8d59d0b35 h1:YAFjXN64LMvktoUZH9zgY4lGc/msGN7HQfoSuKCgaDU=
|
||||
golang.org/x/sys v0.0.0-20181128092732-4ed8d59d0b35/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200413165638-669c56c373c4 h1:opSr2sbRXk5X5/givKrrKj9HXxFpW2sdCiP8MJSKLQY=
|
||||
golang.org/x/sys v0.0.0-20200413165638-669c56c373c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
|
7
vendor/github.com/alecthomas/chroma/lexer.go
generated
vendored
7
vendor/github.com/alecthomas/chroma/lexer.go
generated
vendored
@ -6,7 +6,8 @@ import (
|
||||
|
||||
var (
|
||||
defaultOptions = &TokeniseOptions{
|
||||
State: "root",
|
||||
State: "root",
|
||||
EnsureLF: true,
|
||||
}
|
||||
)
|
||||
|
||||
@ -80,6 +81,10 @@ type TokeniseOptions struct {
|
||||
State string
|
||||
// Nested tokenisation.
|
||||
Nested bool
|
||||
|
||||
// If true, all EOLs are converted into LF
|
||||
// by replacing CRLF and CR
|
||||
EnsureLF bool
|
||||
}
|
||||
|
||||
// A Lexer for tokenising source code.
|
||||
|
22
vendor/github.com/alecthomas/chroma/lexers/README.md
generated
vendored
22
vendor/github.com/alecthomas/chroma/lexers/README.md
generated
vendored
@ -10,10 +10,28 @@ Run the tests as normal:
|
||||
go test ./lexers
|
||||
```
|
||||
|
||||
## Updating the existing tests
|
||||
## Update existing tests
|
||||
When you add a new test data file (`*.actual`), you need to regenerate all tests. That's how Chroma creates the `*.expected` test file based on the corresponding lexer.
|
||||
|
||||
You can regenerate all the test outputs
|
||||
To regenerate all tests, type in your terminal:
|
||||
|
||||
```go
|
||||
RECORD=true go test ./lexers
|
||||
```
|
||||
|
||||
This first sets the `RECORD` environment variable to `true`. Then it runs `go test` on the `./lexers` directory of the Chroma project.
|
||||
|
||||
(That environment variable tells Chroma it needs to output test data. After running `go test ./lexers` you can remove or reset that variable.)
|
||||
|
||||
### Windows users
|
||||
Windows users will find that the `RECORD=true go test ./lexers` command fails in both the standard command prompt terminal and in PowerShell.
|
||||
|
||||
Instead we have to perform both steps separately:
|
||||
|
||||
- Set the `RECORD` environment variable to `true`.
|
||||
+ In the regular command prompt window, the `set` command sets an environment variable for the current session: `set RECORD=true`. See [this page](https://superuser.com/questions/212150/how-to-set-env-variable-in-windows-cmd-line) for more.
|
||||
+ In PowerShell, you can use the `$env:RECORD = 'true'` command for that. See [this article](https://mcpmag.com/articles/2019/03/28/environment-variables-in-powershell.aspx) for more.
|
||||
+ You can also make a persistent environment variable by hand in the Windows computer settings. See [this article](https://www.computerhope.com/issues/ch000549.htm) for how.
|
||||
- When the environment variable is set, run `go tests ./lexers`.
|
||||
|
||||
Chroma will now regenerate the test files and print its results to the console window.
|
||||
|
2
vendor/github.com/alecthomas/chroma/lexers/a/applescript.go
generated
vendored
2
vendor/github.com/alecthomas/chroma/lexers/a/applescript.go
generated
vendored
@ -31,7 +31,7 @@ var Applescript = internal.Register(MustNewLexer(
|
||||
{`\b(as )(alias |application |boolean |class |constant |date |file |integer |list |number |POSIX file |real |record |reference |RGB color |script |text |unit types|(?:Unicode )?text|string)\b`, ByGroups(Keyword, NameClass), nil},
|
||||
{`\b(AppleScript|current application|false|linefeed|missing value|pi|quote|result|return|space|tab|text item delimiters|true|version)\b`, NameConstant, nil},
|
||||
{`\b(ASCII (character|number)|activate|beep|choose URL|choose application|choose color|choose file( name)?|choose folder|choose from list|choose remote application|clipboard info|close( access)?|copy|count|current date|delay|delete|display (alert|dialog)|do shell script|duplicate|exists|get eof|get volume settings|info for|launch|list (disks|folder)|load script|log|make|mount volume|new|offset|open( (for access|location))?|path to|print|quit|random number|read|round|run( script)?|say|scripting components|set (eof|the clipboard to|volume)|store script|summarize|system attribute|system info|the clipboard|time to GMT|write|quoted form)\b`, NameBuiltin, nil},
|
||||
{`\b(considering|else|error|exit|from|if|ignoring|in|repeat|tell|then|times|to|try|until|using terms from|while|whith|with timeout( of)?|with transaction|by|continue|end|its?|me|my|return|of|as)\b`, Keyword, nil},
|
||||
{`\b(considering|else|error|exit|from|if|ignoring|in|repeat|tell|then|times|to|try|until|using terms from|while|with|with timeout( of)?|with transaction|by|continue|end|its?|me|my|return|of|as)\b`, Keyword, nil},
|
||||
{`\b(global|local|prop(erty)?|set|get)\b`, Keyword, nil},
|
||||
{`\b(but|put|returning|the)\b`, NameBuiltin, nil},
|
||||
{`\b(attachment|attribute run|character|day|month|paragraph|word|year)s?\b`, NameBuiltin, nil},
|
||||
|
2
vendor/github.com/alecthomas/chroma/lexers/b/ballerina.go
generated
vendored
2
vendor/github.com/alecthomas/chroma/lexers/b/ballerina.go
generated
vendored
@ -25,7 +25,7 @@ var Ballerina = internal.Register(MustNewLexer(
|
||||
{`(annotation|bind|but|endpoint|error|function|object|private|public|returns|service|type|var|with|worker)\b`, KeywordDeclaration, nil},
|
||||
{`(boolean|byte|decimal|float|int|json|map|nil|record|string|table|xml)\b`, KeywordType, nil},
|
||||
{`(true|false|null)\b`, KeywordConstant, nil},
|
||||
{`import(\s+)`, ByGroups(KeywordNamespace, Text), Push("import")},
|
||||
{`(import)(\s+)`, ByGroups(KeywordNamespace, Text), Push("import")},
|
||||
{`"(\\\\|\\"|[^"])*"`, LiteralString, nil},
|
||||
{`'\\.'|'[^\\]'|'\\u[0-9a-fA-F]{4}'`, LiteralStringChar, nil},
|
||||
{`(\.)((?:[^\W\d]|\$)[\w$]*)`, ByGroups(Operator, NameAttribute), nil},
|
||||
|
4
vendor/github.com/alecthomas/chroma/lexers/b/bash.go
generated
vendored
4
vendor/github.com/alecthomas/chroma/lexers/b/bash.go
generated
vendored
@ -36,7 +36,7 @@ var Bash = internal.Register(MustNewLexer(
|
||||
{`\b(if|fi|else|while|do|done|for|then|return|function|case|select|continue|until|esac|elif)(\s*)\b`, ByGroups(Keyword, Text), nil},
|
||||
{"\\b(alias|bg|bind|break|builtin|caller|cd|command|compgen|complete|declare|dirs|disown|echo|enable|eval|exec|exit|export|false|fc|fg|getopts|hash|help|history|jobs|kill|let|local|logout|popd|printf|pushd|pwd|read|readonly|set|shift|shopt|source|suspend|test|time|times|trap|true|type|typeset|ulimit|umask|unalias|unset|wait)(?=[\\s)`])", NameBuiltin, nil},
|
||||
{`\A#!.+\n`, CommentPreproc, nil},
|
||||
{`#.*\S`, CommentSingle, nil},
|
||||
{`#.*(\S|$)`, CommentSingle, nil},
|
||||
{`\\[\w\W]`, LiteralStringEscape, nil},
|
||||
{`(\b\w+)(\s*)(\+?=)`, ByGroups(NameVariable, Text, Operator), nil},
|
||||
{`[\[\]{}()=]`, Operator, nil},
|
||||
@ -53,7 +53,7 @@ var Bash = internal.Register(MustNewLexer(
|
||||
{`&`, Punctuation, nil},
|
||||
{`\|`, Punctuation, nil},
|
||||
{`\s+`, Text, nil},
|
||||
{`\d+\b`, LiteralNumber, nil},
|
||||
{`\d+(?= |$)`, LiteralNumber, nil},
|
||||
{"[^=\\s\\[\\]{}()$\"\\'`\\\\<&|;]+", Text, nil},
|
||||
{`<`, Text, nil},
|
||||
},
|
||||
|
76
vendor/github.com/alecthomas/chroma/lexers/b/bibtex.go
generated
vendored
Normal file
76
vendor/github.com/alecthomas/chroma/lexers/b/bibtex.go
generated
vendored
Normal file
@ -0,0 +1,76 @@
|
||||
package b
|
||||
|
||||
import (
|
||||
. "github.com/alecthomas/chroma" // nolint
|
||||
"github.com/alecthomas/chroma/lexers/internal"
|
||||
)
|
||||
|
||||
// Bibtex lexer.
|
||||
var Bibtex = internal.Register(MustNewLexer(
|
||||
&Config{
|
||||
Name: "BibTeX",
|
||||
Aliases: []string{"bib", "bibtex"},
|
||||
Filenames: []string{"*.bib"},
|
||||
MimeTypes: []string{"text/x-bibtex"},
|
||||
NotMultiline: true,
|
||||
CaseInsensitive: true,
|
||||
},
|
||||
Rules{
|
||||
"root": {
|
||||
Include("whitespace"),
|
||||
{`@comment`, Comment, nil},
|
||||
{`@preamble`, NameClass, Push("closing-brace", "value", "opening-brace")},
|
||||
{`@string`, NameClass, Push("closing-brace", "field", "opening-brace")},
|
||||
{"@[a-z_@!$&*+\\-./:;<>?\\[\\\\\\]^`|~][\\w@!$&*+\\-./:;<>?\\[\\\\\\]^`|~]*", NameClass, Push("closing-brace", "command-body", "opening-brace")},
|
||||
{`.+`, Comment, nil},
|
||||
},
|
||||
"opening-brace": {
|
||||
Include("whitespace"),
|
||||
{`[{(]`, Punctuation, Pop(1)},
|
||||
},
|
||||
"closing-brace": {
|
||||
Include("whitespace"),
|
||||
{`[})]`, Punctuation, Pop(1)},
|
||||
},
|
||||
"command-body": {
|
||||
Include("whitespace"),
|
||||
{`[^\s\,\}]+`, NameLabel, Push("#pop", "fields")},
|
||||
},
|
||||
"fields": {
|
||||
Include("whitespace"),
|
||||
{`,`, Punctuation, Push("field")},
|
||||
Default(Pop(1)),
|
||||
},
|
||||
"field": {
|
||||
Include("whitespace"),
|
||||
{"[a-z_@!$&*+\\-./:;<>?\\[\\\\\\]^`|~][\\w@!$&*+\\-./:;<>?\\[\\\\\\]^`|~]*", NameAttribute, Push("value", "=")},
|
||||
Default(Pop(1)),
|
||||
},
|
||||
"=": {
|
||||
Include("whitespace"),
|
||||
{`=`, Punctuation, Pop(1)},
|
||||
},
|
||||
"value": {
|
||||
Include("whitespace"),
|
||||
{"[a-z_@!$&*+\\-./:;<>?\\[\\\\\\]^`|~][\\w@!$&*+\\-./:;<>?\\[\\\\\\]^`|~]*", NameVariable, nil},
|
||||
{`"`, LiteralString, Push("quoted-string")},
|
||||
{`\{`, LiteralString, Push("braced-string")},
|
||||
{`[\d]+`, LiteralNumber, nil},
|
||||
{`#`, Punctuation, nil},
|
||||
Default(Pop(1)),
|
||||
},
|
||||
"quoted-string": {
|
||||
{`\{`, LiteralString, Push("braced-string")},
|
||||
{`"`, LiteralString, Pop(1)},
|
||||
{`[^\{\"]+`, LiteralString, nil},
|
||||
},
|
||||
"braced-string": {
|
||||
{`\{`, LiteralString, Push()},
|
||||
{`\}`, LiteralString, Pop(1)},
|
||||
{`[^\{\}]+`, LiteralString, nil},
|
||||
},
|
||||
"whitespace": {
|
||||
{`\s+`, Text, nil},
|
||||
},
|
||||
},
|
||||
))
|
206
vendor/github.com/alecthomas/chroma/lexers/c/caddyfile.go
generated
vendored
Normal file
206
vendor/github.com/alecthomas/chroma/lexers/c/caddyfile.go
generated
vendored
Normal file
@ -0,0 +1,206 @@
|
||||
package c
|
||||
|
||||
import (
|
||||
. "github.com/alecthomas/chroma" // nolint
|
||||
"github.com/alecthomas/chroma/lexers/internal"
|
||||
)
|
||||
|
||||
// caddyfileCommon are the rules common to both of the lexer variants
|
||||
var caddyfileCommon = Rules{
|
||||
"site_block_common": {
|
||||
// Import keyword
|
||||
{`(import)(\s+)([^\s]+)`, ByGroups(Keyword, Text, NameVariableMagic), nil},
|
||||
// Matcher definition
|
||||
{`@[^\s]+(?=\s)`, NameDecorator, Push("matcher")},
|
||||
// Matcher token stub for docs
|
||||
{`\[\<matcher\>\]`, NameDecorator, Push("matcher")},
|
||||
// These cannot have matchers but may have things that look like
|
||||
// matchers in their arguments, so we just parse as a subdirective.
|
||||
{`try_files`, Keyword, Push("subdirective")},
|
||||
// These are special, they can nest more directives
|
||||
{`handle_errors|handle|route|handle_path|not`, Keyword, Push("nested_directive")},
|
||||
// Any other directive
|
||||
{`[^\s#]+`, Keyword, Push("directive")},
|
||||
Include("base"),
|
||||
},
|
||||
"matcher": {
|
||||
{`\{`, Punctuation, Push("block")},
|
||||
// Not can be one-liner
|
||||
{`not`, Keyword, Push("deep_not_matcher")},
|
||||
// Any other same-line matcher
|
||||
{`[^\s#]+`, Keyword, Push("arguments")},
|
||||
// Terminators
|
||||
{`\n`, Text, Pop(1)},
|
||||
{`\}`, Punctuation, Pop(1)},
|
||||
Include("base"),
|
||||
},
|
||||
"block": {
|
||||
{`\}`, Punctuation, Pop(2)},
|
||||
// Not can be one-liner
|
||||
{`not`, Keyword, Push("not_matcher")},
|
||||
// Any other subdirective
|
||||
{`[^\s#]+`, Keyword, Push("subdirective")},
|
||||
Include("base"),
|
||||
},
|
||||
"nested_block": {
|
||||
{`\}`, Punctuation, Pop(2)},
|
||||
// Matcher definition
|
||||
{`@[^\s]+(?=\s)`, NameDecorator, Push("matcher")},
|
||||
// Something that starts with literally < is probably a docs stub
|
||||
{`\<[^#]+\>`, Keyword, Push("nested_directive")},
|
||||
// Any other directive
|
||||
{`[^\s#]+`, Keyword, Push("nested_directive")},
|
||||
Include("base"),
|
||||
},
|
||||
"not_matcher": {
|
||||
{`\}`, Punctuation, Pop(2)},
|
||||
{`\{(?=\s)`, Punctuation, Push("block")},
|
||||
{`[^\s#]+`, Keyword, Push("arguments")},
|
||||
{`\s+`, Text, nil},
|
||||
},
|
||||
"deep_not_matcher": {
|
||||
{`\}`, Punctuation, Pop(2)},
|
||||
{`\{(?=\s)`, Punctuation, Push("block")},
|
||||
{`[^\s#]+`, Keyword, Push("deep_subdirective")},
|
||||
{`\s+`, Text, nil},
|
||||
},
|
||||
"directive": {
|
||||
{`\{(?=\s)`, Punctuation, Push("block")},
|
||||
Include("matcher_token"),
|
||||
Include("comments_pop_1"),
|
||||
{`\n`, Text, Pop(1)},
|
||||
Include("base"),
|
||||
},
|
||||
"nested_directive": {
|
||||
{`\{(?=\s)`, Punctuation, Push("nested_block")},
|
||||
Include("matcher_token"),
|
||||
Include("comments_pop_1"),
|
||||
{`\n`, Text, Pop(1)},
|
||||
Include("base"),
|
||||
},
|
||||
"subdirective": {
|
||||
{`\{(?=\s)`, Punctuation, Push("block")},
|
||||
Include("comments_pop_1"),
|
||||
{`\n`, Text, Pop(1)},
|
||||
Include("base"),
|
||||
},
|
||||
"arguments": {
|
||||
{`\{(?=\s)`, Punctuation, Push("block")},
|
||||
Include("comments_pop_2"),
|
||||
{`\\\n`, Text, nil}, // Skip escaped newlines
|
||||
{`\n`, Text, Pop(2)},
|
||||
Include("base"),
|
||||
},
|
||||
"deep_subdirective": {
|
||||
{`\{(?=\s)`, Punctuation, Push("block")},
|
||||
Include("comments_pop_3"),
|
||||
{`\n`, Text, Pop(3)},
|
||||
Include("base"),
|
||||
},
|
||||
"matcher_token": {
|
||||
{`@[^\s]+`, NameDecorator, Push("arguments")}, // Named matcher
|
||||
{`/[^\s]+`, NameDecorator, Push("arguments")}, // Path matcher
|
||||
{`\*`, NameDecorator, Push("arguments")}, // Wildcard path matcher
|
||||
{`\[\<matcher\>\]`, NameDecorator, Push("arguments")}, // Matcher token stub for docs
|
||||
},
|
||||
"comments": {
|
||||
{`^#.*\n`, CommentSingle, nil}, // Comment at start of line
|
||||
{`\s+#.*\n`, CommentSingle, nil}, // Comment preceded by whitespace
|
||||
},
|
||||
"comments_pop_1": {
|
||||
{`^#.*\n`, CommentSingle, Pop(1)}, // Comment at start of line
|
||||
{`\s+#.*\n`, CommentSingle, Pop(1)}, // Comment preceded by whitespace
|
||||
},
|
||||
"comments_pop_2": {
|
||||
{`^#.*\n`, CommentSingle, Pop(2)}, // Comment at start of line
|
||||
{`\s+#.*\n`, CommentSingle, Pop(2)}, // Comment preceded by whitespace
|
||||
},
|
||||
"comments_pop_3": {
|
||||
{`^#.*\n`, CommentSingle, Pop(3)}, // Comment at start of line
|
||||
{`\s+#.*\n`, CommentSingle, Pop(3)}, // Comment preceded by whitespace
|
||||
},
|
||||
"base": {
|
||||
Include("comments"),
|
||||
{`(on|off|first|last|before|after|internal|strip_prefix|strip_suffix|replace)\b`, NameConstant, nil},
|
||||
{`(https?://)?([a-z0-9.-]+)(:)([0-9]+)`, ByGroups(Name, Name, Punctuation, LiteralNumberInteger), nil},
|
||||
{`[a-z-]+/[a-z-+]+`, LiteralString, nil},
|
||||
{`[0-9]+[km]?\b`, LiteralNumberInteger, nil},
|
||||
{`\{[\w+.\$-]+\}`, LiteralStringEscape, nil}, // Placeholder
|
||||
{`\[(?=[^#{}$]+\])`, Punctuation, nil},
|
||||
{`\]|\|`, Punctuation, nil},
|
||||
{`[^\s#{}$\]]+`, LiteralString, nil},
|
||||
{`/[^\s#]*`, Name, nil},
|
||||
{`\s+`, Text, nil},
|
||||
},
|
||||
}
|
||||
|
||||
// Caddyfile lexer.
|
||||
var Caddyfile = internal.Register(MustNewLexer(
|
||||
&Config{
|
||||
Name: "Caddyfile",
|
||||
Aliases: []string{"caddyfile", "caddy"},
|
||||
Filenames: []string{"Caddyfile*"},
|
||||
MimeTypes: []string{},
|
||||
},
|
||||
Rules{
|
||||
"root": {
|
||||
Include("comments"),
|
||||
// Global options block
|
||||
{`^\s*(\{)\s*$`, ByGroups(Punctuation), Push("globals")},
|
||||
// Snippets
|
||||
{`(\([^\s#]+\))(\s*)(\{)`, ByGroups(NameVariableAnonymous, Text, Punctuation), Push("snippet")},
|
||||
// Site label
|
||||
{`[^#{(\s,]+`, GenericHeading, Push("label")},
|
||||
// Site label with placeholder
|
||||
{`\{[\w+.\$-]+\}`, LiteralStringEscape, Push("label")},
|
||||
{`\s+`, Text, nil},
|
||||
},
|
||||
"globals": {
|
||||
{`\}`, Punctuation, Pop(1)},
|
||||
{`[^\s#]+`, Keyword, Push("directive")},
|
||||
Include("base"),
|
||||
},
|
||||
"snippet": {
|
||||
{`\}`, Punctuation, Pop(1)},
|
||||
// Matcher definition
|
||||
{`@[^\s]+(?=\s)`, NameDecorator, Push("matcher")},
|
||||
// Any directive
|
||||
{`[^\s#]+`, Keyword, Push("directive")},
|
||||
Include("base"),
|
||||
},
|
||||
"label": {
|
||||
// Allow multiple labels, comma separated, newlines after
|
||||
// a comma means another label is coming
|
||||
{`,\s*\n?`, Text, nil},
|
||||
{` `, Text, nil},
|
||||
// Site label with placeholder
|
||||
{`\{[\w+.\$-]+\}`, LiteralStringEscape, nil},
|
||||
// Site label
|
||||
{`[^#{(\s,]+`, GenericHeading, nil},
|
||||
// Comment after non-block label (hack because comments end in \n)
|
||||
{`#.*\n`, CommentSingle, Push("site_block")},
|
||||
// Note: if \n, we'll never pop out of the site_block, it's valid
|
||||
{`\{(?=\s)|\n`, Punctuation, Push("site_block")},
|
||||
},
|
||||
"site_block": {
|
||||
{`\}`, Punctuation, Pop(2)},
|
||||
Include("site_block_common"),
|
||||
},
|
||||
}.Merge(caddyfileCommon),
|
||||
))
|
||||
|
||||
// Caddyfile directive-only lexer.
|
||||
var CaddyfileDirectives = internal.Register(MustNewLexer(
|
||||
&Config{
|
||||
Name: "Caddyfile Directives",
|
||||
Aliases: []string{"caddyfile-directives", "caddyfile-d", "caddy-d"},
|
||||
Filenames: []string{},
|
||||
MimeTypes: []string{},
|
||||
},
|
||||
Rules{
|
||||
// Same as "site_block" in Caddyfile
|
||||
"root": {
|
||||
Include("site_block_common"),
|
||||
},
|
||||
}.Merge(caddyfileCommon),
|
||||
))
|
3
vendor/github.com/alecthomas/chroma/lexers/c/cpp.go
generated
vendored
3
vendor/github.com/alecthomas/chroma/lexers/c/cpp.go
generated
vendored
@ -24,7 +24,8 @@ var CPP = internal.Register(MustNewLexer(
|
||||
{`(u8|u|U)(")`, ByGroups(LiteralStringAffix, LiteralString), Push("string")},
|
||||
{`(L?)(")`, ByGroups(LiteralStringAffix, LiteralString), Push("string")},
|
||||
{`(L?)(')(\\.|\\[0-7]{1,3}|\\x[a-fA-F0-9]{1,2}|[^\\\'\n])(')`, ByGroups(LiteralStringAffix, LiteralStringChar, LiteralStringChar, LiteralStringChar), nil},
|
||||
{`(\.([0-9](?:'?[0-9]+)*)([eE][+-]?([0-9]('?[0-9]+)*))?|([0-9]('?[0-9]+)*)(([eE][+-]?([0-9]('?[0-9]+)*))|\.([0-9]('?[0-9]+)*)?([eE][+-]?([0-9]('?[0-9]+)*))?)|0[xX](\.([0-9A-Fa-f]('?[0-9A-Fa-f]+)*)([pP][-+]?([0-9]('?[0-9]+)*))?|([0-9A-Fa-f]('?[0-9A-Fa-f]+)*)(([pP][-+]?([0-9]('?[0-9]+)*))|\.([0-9A-Fa-f]('?[0-9A-Fa-f]+)*)?([pP][-+]?([0-9]('?[0-9]+)*))?)))[fFLlUu]*`, LiteralNumberFloat, nil},
|
||||
{`(\d+\.\d*|\.\d+|\d+)[eE][+-]?\d+[LlUu]*`, LiteralNumberFloat, nil},
|
||||
{`(\d+\.\d*|\.\d+|\d+[fF])[fF]?`, LiteralNumberFloat, nil},
|
||||
{`0[xX]([0-9A-Fa-f]('?[0-9A-Fa-f]+)*)[LlUu]*`, LiteralNumberHex, nil},
|
||||
{`0('?[0-7]+)+[LlUu]*`, LiteralNumberOct, nil},
|
||||
{`0[Bb][01]('?[01]+)*[LlUu]*`, LiteralNumberBin, nil},
|
||||
|
137
vendor/github.com/alecthomas/chroma/lexers/circular/php.go
generated
vendored
137
vendor/github.com/alecthomas/chroma/lexers/circular/php.go
generated
vendored
@ -1,15 +1,12 @@
|
||||
package circular
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
. "github.com/alecthomas/chroma" // nolint
|
||||
"github.com/alecthomas/chroma/lexers/h"
|
||||
"github.com/alecthomas/chroma/lexers/internal"
|
||||
)
|
||||
|
||||
// PHP lexer.
|
||||
var PHP = internal.Register(DelegatingLexer(h.HTML, MustNewLexer(
|
||||
// PHP lexer for pure PHP code (not embedded in HTML).
|
||||
var PHP = internal.Register(MustNewLexer(
|
||||
&Config{
|
||||
Name: "PHP",
|
||||
Aliases: []string{"php", "php3", "php4", "php5"},
|
||||
@ -19,73 +16,65 @@ var PHP = internal.Register(DelegatingLexer(h.HTML, MustNewLexer(
|
||||
CaseInsensitive: true,
|
||||
EnsureNL: true,
|
||||
},
|
||||
Rules{
|
||||
"root": {
|
||||
{`<\?(php)?`, CommentPreproc, Push("php")},
|
||||
{`[^<]+`, Other, nil},
|
||||
{`<`, Other, nil},
|
||||
},
|
||||
"php": {
|
||||
{`\?>`, CommentPreproc, Pop(1)},
|
||||
{`(<<<)([\'"]?)((?:[\\_a-z]|[^\x00-\x7f])(?:[\\\w]|[^\x00-\x7f])*)(\2\n.*?\n\s*)(\3)(;?)(\n)`, ByGroups(LiteralString, LiteralString, LiteralStringDelimiter, LiteralString, LiteralStringDelimiter, Punctuation, Text), nil},
|
||||
{`\s+`, Text, nil},
|
||||
{`#.*?\n`, CommentSingle, nil},
|
||||
{`//.*?\n`, CommentSingle, nil},
|
||||
{`/\*\*/`, CommentMultiline, nil},
|
||||
{`/\*\*.*?\*/`, LiteralStringDoc, nil},
|
||||
{`/\*.*?\*/`, CommentMultiline, nil},
|
||||
{`(->|::)(\s*)((?:[\\_a-z]|[^\x00-\x7f])(?:[\\\w]|[^\x00-\x7f])*)`, ByGroups(Operator, Text, NameAttribute), nil},
|
||||
{`[~!%^&*+=|:.<>/@-]+`, Operator, nil},
|
||||
{`\?`, Operator, nil},
|
||||
{`[\[\]{}();,]+`, Punctuation, nil},
|
||||
{`(class)(\s+)`, ByGroups(Keyword, Text), Push("classname")},
|
||||
{`(function)(\s*)(?=\()`, ByGroups(Keyword, Text), nil},
|
||||
{`(function)(\s+)(&?)(\s*)`, ByGroups(Keyword, Text, Operator, Text), Push("functionname")},
|
||||
{`(const)(\s+)((?:[\\_a-z]|[^\x00-\x7f])(?:[\\\w]|[^\x00-\x7f])*)`, ByGroups(Keyword, Text, NameConstant), nil},
|
||||
{`(and|E_PARSE|old_function|E_ERROR|or|as|E_WARNING|parent|eval|PHP_OS|break|exit|case|extends|PHP_VERSION|cfunction|FALSE|print|for|require|continue|foreach|require_once|declare|return|default|static|do|switch|die|stdClass|echo|else|TRUE|elseif|var|empty|if|xor|enddeclare|include|virtual|endfor|include_once|while|endforeach|global|endif|list|endswitch|new|endwhile|not|array|E_ALL|NULL|final|php_user_filter|interface|implements|public|private|protected|abstract|clone|try|catch|throw|this|use|namespace|trait|yield|finally)\b`, Keyword, nil},
|
||||
{`(true|false|null)\b`, KeywordConstant, nil},
|
||||
Include("magicconstants"),
|
||||
{`\$\{\$+(?:[\\_a-z]|[^\x00-\x7f])(?:[\\\w]|[^\x00-\x7f])*\}`, NameVariable, nil},
|
||||
{`\$+(?:[\\_a-z]|[^\x00-\x7f])(?:[\\\w]|[^\x00-\x7f])*`, NameVariable, nil},
|
||||
{`(?:[\\_a-z]|[^\x00-\x7f])(?:[\\\w]|[^\x00-\x7f])*`, NameOther, nil},
|
||||
{`(\d+\.\d*|\d*\.\d+)(e[+-]?[0-9]+)?`, LiteralNumberFloat, nil},
|
||||
{`\d+e[+-]?[0-9]+`, LiteralNumberFloat, nil},
|
||||
{`0[0-7]+`, LiteralNumberOct, nil},
|
||||
{`0x[a-f0-9]+`, LiteralNumberHex, nil},
|
||||
{`\d+`, LiteralNumberInteger, nil},
|
||||
{`0b[01]+`, LiteralNumberBin, nil},
|
||||
{`'([^'\\]*(?:\\.[^'\\]*)*)'`, LiteralStringSingle, nil},
|
||||
{"`([^`\\\\]*(?:\\\\.[^`\\\\]*)*)`", LiteralStringBacktick, nil},
|
||||
{`"`, LiteralStringDouble, Push("string")},
|
||||
},
|
||||
"magicfuncs": {
|
||||
{Words(``, `\b`, `__construct`, `__destruct`, `__call`, `__callStatic`, `__get`, `__set`, `__isset`, `__unset`, `__sleep`, `__wakeup`, `__toString`, `__invoke`, `__set_state`, `__clone`, `__debugInfo`), NameFunctionMagic, nil},
|
||||
},
|
||||
"magicconstants": {
|
||||
{Words(``, `\b`, `__LINE__`, `__FILE__`, `__DIR__`, `__FUNCTION__`, `__CLASS__`, `__TRAIT__`, `__METHOD__`, `__NAMESPACE__`), NameConstant, nil},
|
||||
},
|
||||
"classname": {
|
||||
{`(?:[\\_a-z]|[^\x00-\x7f])(?:[\\\w]|[^\x00-\x7f])*`, NameClass, Pop(1)},
|
||||
},
|
||||
"functionname": {
|
||||
Include("magicfuncs"),
|
||||
{`(?:[\\_a-z]|[^\x00-\x7f])(?:[\\\w]|[^\x00-\x7f])*`, NameFunction, Pop(1)},
|
||||
Default(Pop(1)),
|
||||
},
|
||||
"string": {
|
||||
{`"`, LiteralStringDouble, Pop(1)},
|
||||
{`[^{$"\\]+`, LiteralStringDouble, nil},
|
||||
{`\\([nrt"$\\]|[0-7]{1,3}|x[0-9a-f]{1,2})`, LiteralStringEscape, nil},
|
||||
{`\$(?:[\\_a-z]|[^\x00-\x7f])(?:[\\\w]|[^\x00-\x7f])*(\[\S+?\]|->(?:[\\_a-z]|[^\x00-\x7f])(?:[\\\w]|[^\x00-\x7f])*)?`, LiteralStringInterpol, nil},
|
||||
{`(\{\$\{)(.*?)(\}\})`, ByGroups(LiteralStringInterpol, UsingSelf("root"), LiteralStringInterpol), nil},
|
||||
{`(\{)(\$.*?)(\})`, ByGroups(LiteralStringInterpol, UsingSelf("root"), LiteralStringInterpol), nil},
|
||||
{`(\$\{)(\S+)(\})`, ByGroups(LiteralStringInterpol, NameVariable, LiteralStringInterpol), nil},
|
||||
{`[${\\]`, LiteralStringDouble, nil},
|
||||
},
|
||||
phpCommonRules.Rename("php", "root"),
|
||||
))
|
||||
|
||||
var phpCommonRules = Rules{
|
||||
"php": {
|
||||
{`\?>`, CommentPreproc, Pop(1)},
|
||||
{`(<<<)([\'"]?)((?:[\\_a-z]|[^\x00-\x7f])(?:[\\\w]|[^\x00-\x7f])*)(\2\n.*?\n\s*)(\3)(;?)(\n)`, ByGroups(LiteralString, LiteralString, LiteralStringDelimiter, LiteralString, LiteralStringDelimiter, Punctuation, Text), nil},
|
||||
{`\s+`, Text, nil},
|
||||
{`#.*?\n`, CommentSingle, nil},
|
||||
{`//.*?\n`, CommentSingle, nil},
|
||||
{`/\*\*/`, CommentMultiline, nil},
|
||||
{`/\*\*.*?\*/`, LiteralStringDoc, nil},
|
||||
{`/\*.*?\*/`, CommentMultiline, nil},
|
||||
{`(->|::)(\s*)((?:[\\_a-z]|[^\x00-\x7f])(?:[\\\w]|[^\x00-\x7f])*)`, ByGroups(Operator, Text, NameAttribute), nil},
|
||||
{`[~!%^&*+=|:.<>/@-]+`, Operator, nil},
|
||||
{`\?`, Operator, nil},
|
||||
{`[\[\]{}();,]+`, Punctuation, nil},
|
||||
{`(class)(\s+)`, ByGroups(Keyword, Text), Push("classname")},
|
||||
{`(function)(\s*)(?=\()`, ByGroups(Keyword, Text), nil},
|
||||
{`(function)(\s+)(&?)(\s*)`, ByGroups(Keyword, Text, Operator, Text), Push("functionname")},
|
||||
{`(const)(\s+)((?:[\\_a-z]|[^\x00-\x7f])(?:[\\\w]|[^\x00-\x7f])*)`, ByGroups(Keyword, Text, NameConstant), nil},
|
||||
{`(and|E_PARSE|old_function|E_ERROR|or|as|E_WARNING|parent|eval|PHP_OS|break|exit|case|extends|PHP_VERSION|cfunction|FALSE|print|for|require|continue|foreach|require_once|declare|return|default|static|do|switch|die|stdClass|echo|else|TRUE|elseif|var|empty|if|xor|enddeclare|include|virtual|endfor|include_once|while|endforeach|global|endif|list|endswitch|new|endwhile|not|array|E_ALL|NULL|final|php_user_filter|interface|implements|public|private|protected|abstract|clone|try|catch|throw|this|use|namespace|trait|yield|finally)\b`, Keyword, nil},
|
||||
{`(true|false|null)\b`, KeywordConstant, nil},
|
||||
Include("magicconstants"),
|
||||
{`\$\{\$+(?:[\\_a-z]|[^\x00-\x7f])(?:[\\\w]|[^\x00-\x7f])*\}`, NameVariable, nil},
|
||||
{`\$+(?:[\\_a-z]|[^\x00-\x7f])(?:[\\\w]|[^\x00-\x7f])*`, NameVariable, nil},
|
||||
{`(?:[\\_a-z]|[^\x00-\x7f])(?:[\\\w]|[^\x00-\x7f])*`, NameOther, nil},
|
||||
{`(\d+\.\d*|\d*\.\d+)(e[+-]?[0-9]+)?`, LiteralNumberFloat, nil},
|
||||
{`\d+e[+-]?[0-9]+`, LiteralNumberFloat, nil},
|
||||
{`0[0-7]+`, LiteralNumberOct, nil},
|
||||
{`0x[a-f0-9]+`, LiteralNumberHex, nil},
|
||||
{`\d+`, LiteralNumberInteger, nil},
|
||||
{`0b[01]+`, LiteralNumberBin, nil},
|
||||
{`'([^'\\]*(?:\\.[^'\\]*)*)'`, LiteralStringSingle, nil},
|
||||
{"`([^`\\\\]*(?:\\\\.[^`\\\\]*)*)`", LiteralStringBacktick, nil},
|
||||
{`"`, LiteralStringDouble, Push("string")},
|
||||
},
|
||||
).SetAnalyser(func(text string) float32 {
|
||||
if strings.Contains(text, "<?php") {
|
||||
return 0.5
|
||||
}
|
||||
return 0.0
|
||||
})))
|
||||
"magicfuncs": {
|
||||
{Words(``, `\b`, `__construct`, `__destruct`, `__call`, `__callStatic`, `__get`, `__set`, `__isset`, `__unset`, `__sleep`, `__wakeup`, `__toString`, `__invoke`, `__set_state`, `__clone`, `__debugInfo`), NameFunctionMagic, nil},
|
||||
},
|
||||
"magicconstants": {
|
||||
{Words(``, `\b`, `__LINE__`, `__FILE__`, `__DIR__`, `__FUNCTION__`, `__CLASS__`, `__TRAIT__`, `__METHOD__`, `__NAMESPACE__`), NameConstant, nil},
|
||||
},
|
||||
"classname": {
|
||||
{`(?:[\\_a-z]|[^\x00-\x7f])(?:[\\\w]|[^\x00-\x7f])*`, NameClass, Pop(1)},
|
||||
},
|
||||
"functionname": {
|
||||
Include("magicfuncs"),
|
||||
{`(?:[\\_a-z]|[^\x00-\x7f])(?:[\\\w]|[^\x00-\x7f])*`, NameFunction, Pop(1)},
|
||||
Default(Pop(1)),
|
||||
},
|
||||
"string": {
|
||||
{`"`, LiteralStringDouble, Pop(1)},
|
||||
{`[^{$"\\]+`, LiteralStringDouble, nil},
|
||||
{`\\([nrt"$\\]|[0-7]{1,3}|x[0-9a-f]{1,2})`, LiteralStringEscape, nil},
|
||||
{`\$(?:[\\_a-z]|[^\x00-\x7f])(?:[\\\w]|[^\x00-\x7f])*(\[\S+?\]|->(?:[\\_a-z]|[^\x00-\x7f])(?:[\\\w]|[^\x00-\x7f])*)?`, LiteralStringInterpol, nil},
|
||||
{`(\{\$\{)(.*?)(\}\})`, ByGroups(LiteralStringInterpol, UsingSelf("root"), LiteralStringInterpol), nil},
|
||||
{`(\{)(\$.*?)(\})`, ByGroups(LiteralStringInterpol, UsingSelf("root"), LiteralStringInterpol), nil},
|
||||
{`(\$\{)(\S+)(\})`, ByGroups(LiteralStringInterpol, NameVariable, LiteralStringInterpol), nil},
|
||||
{`[${\\]`, LiteralStringDouble, nil},
|
||||
},
|
||||
}
|
||||
|
34
vendor/github.com/alecthomas/chroma/lexers/circular/phtml.go
generated
vendored
Normal file
34
vendor/github.com/alecthomas/chroma/lexers/circular/phtml.go
generated
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
package circular
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
. "github.com/alecthomas/chroma" // nolint
|
||||
"github.com/alecthomas/chroma/lexers/h"
|
||||
"github.com/alecthomas/chroma/lexers/internal"
|
||||
)
|
||||
|
||||
// PHTML lexer is PHP in HTML.
|
||||
var PHTML = internal.Register(DelegatingLexer(h.HTML, MustNewLexer(
|
||||
&Config{
|
||||
Name: "PHTML",
|
||||
Aliases: []string{"phtml"},
|
||||
Filenames: []string{"*.phtml"},
|
||||
MimeTypes: []string{"application/x-php", "application/x-httpd-php", "application/x-httpd-php3", "application/x-httpd-php4", "application/x-httpd-php5"},
|
||||
DotAll: true,
|
||||
CaseInsensitive: true,
|
||||
EnsureNL: true,
|
||||
},
|
||||
Rules{
|
||||
"root": {
|
||||
{`<\?(php)?`, CommentPreproc, Push("php")},
|
||||
{`[^<]+`, Other, nil},
|
||||
{`<`, Other, nil},
|
||||
},
|
||||
}.Merge(phpCommonRules),
|
||||
).SetAnalyser(func(text string) float32 {
|
||||
if strings.Contains(text, "<?php") {
|
||||
return 0.5
|
||||
}
|
||||
return 0.0
|
||||
})))
|
2
vendor/github.com/alecthomas/chroma/lexers/d/docker.go
generated
vendored
2
vendor/github.com/alecthomas/chroma/lexers/d/docker.go
generated
vendored
@ -22,7 +22,7 @@ var Docker = internal.Register(MustNewLexer(
|
||||
{`(ONBUILD)((?:\s*\\?\s*))`, ByGroups(Keyword, Using(b.Bash)), nil},
|
||||
{`(HEALTHCHECK)(((?:\s*\\?\s*)--\w+=\w+(?:\s*\\?\s*))*)`, ByGroups(Keyword, Using(b.Bash)), nil},
|
||||
{`(VOLUME|ENTRYPOINT|CMD|SHELL)((?:\s*\\?\s*))(\[.*?\])`, ByGroups(Keyword, Using(b.Bash), Using(j.JSON)), nil},
|
||||
{`(LABEL|ENV|ARG)(((?:\s*\\?\s*)\w+=\w+(?:\s*\\?\s*))*)`, ByGroups(Keyword, Using(b.Bash)), nil},
|
||||
{`(LABEL|ENV|ARG)((?:(?:\s*\\?\s*)\w+=\w+(?:\s*\\?\s*))*)`, ByGroups(Keyword, Using(b.Bash)), nil},
|
||||
{`((?:FROM|MAINTAINER|EXPOSE|WORKDIR|USER|STOPSIGNAL)|VOLUME)\b(.*)`, ByGroups(Keyword, LiteralString), nil},
|
||||
{`((?:RUN|CMD|ENTRYPOINT|ENV|ARG|LABEL|ADD|COPY))`, Keyword, nil},
|
||||
{`(.*\\\n)*.+`, Using(b.Bash), nil},
|
||||
|
118
vendor/github.com/alecthomas/chroma/lexers/g/gherkin.go
generated
vendored
Normal file
118
vendor/github.com/alecthomas/chroma/lexers/g/gherkin.go
generated
vendored
Normal file
@ -0,0 +1,118 @@
|
||||
package g
|
||||
|
||||
import (
|
||||
. "github.com/alecthomas/chroma" // nolint
|
||||
"github.com/alecthomas/chroma/lexers/internal"
|
||||
)
|
||||
|
||||
var stepKeywords = `^(\s*)(하지만|조건|먼저|만일|만약|단|그리고|그러면|那麼|那么|而且|當|当|前提|假設|假设|假如|假定|但是|但し|並且|并且|同時|同时|もし|ならば|ただし|しかし|かつ|و |متى |لكن |عندما |ثم |بفرض |اذاً |כאשר |וגם |בהינתן |אזי |אז |אבל |Якщо |Унда |То |Припустимо, що |Припустимо |Онда |Но |Нехай |Лекин |Когато |Када |Кад |К тому же |И |Задато |Задати |Задате |Если |Допустим |Дадено |Ва |Бирок |Аммо |Али |Але |Агар |А |І |Și |És |Zatati |Zakładając |Zadato |Zadate |Zadano |Zadani |Zadan |Youse know when youse got |Youse know like when |Yna |Ya know how |Ya gotta |Y |Wun |Wtedy |When y'all |When |Wenn |WEN |Và |Ve |Und |Un |Thì |Then y'all |Then |Tapi |Tak |Tada |Tad |Så |Stel |Soit |Siis |Si |Sed |Se |Quando |Quand |Quan |Pryd |Pokud |Pokiaľ |Però |Pero |Pak |Oraz |Onda |Ond |Oletetaan |Og |Och |O zaman |Når |När |Niin |Nhưng |N |Mutta |Men |Mas |Maka |Majd |Mais |Maar |Ma |Lorsque |Lorsqu'|Kun |Kuid |Kui |Khi |Keď |Ketika |Když |Kaj |Kai |Kada |Kad |Jeżeli |Ja |Ir |I CAN HAZ |I |Ha |Givun |Givet |Given y'all |Given |Gitt |Gegeven |Gegeben sei |Fakat |Eğer ki |Etant donné |Et |Então |Entonces |Entao |En |Eeldades |E |Duota |Dun |Donitaĵo |Donat |Donada |Do |Diyelim ki |Dengan |Den youse gotta |De |Dato |Dar |Dann |Dan |Dado |Dacă |Daca |DEN |Când |Cuando |Cho |Cept |Cand |Cal |But y'all |But |Buh |Biết |Bet |BUT |Atès |Atunci |Atesa |Anrhegedig a |Angenommen |And y'all |And |An |Ama |Als |Alors |Allora |Ali |Aleshores |Ale |Akkor |Aber |AN |A také |A |\* )`
|
||||
|
||||
var featureKeywords = `^(기능|機能|功能|フィーチャ|خاصية|תכונה|Функціонал|Функционалност|Функционал|Фича|Особина|Могућност|Özellik|Właściwość|Tính năng|Trajto|Savybė|Požiadavka|Požadavek|Osobina|Ominaisuus|Omadus|OH HAI|Mogućnost|Mogucnost|Jellemző|Fīča|Funzionalità|Funktionalität|Funkcionalnost|Funkcionalitāte|Funcționalitate|Functionaliteit|Functionalitate|Funcionalitat|Funcionalidade|Fonctionnalité|Fitur|Feature|Egenskap|Egenskab|Crikey|Característica|Arwedd)(:)(.*)$`
|
||||
|
||||
var featureElementKeywords = `^(\s*)(시나리오 개요|시나리오|배경|背景|場景大綱|場景|场景大纲|场景|劇本大綱|劇本|剧本大纲|剧本|テンプレ|シナリオテンプレート|シナリオテンプレ|シナリオアウトライン|シナリオ|سيناريو مخطط|سيناريو|الخلفية|תרחיש|תבנית תרחיש|רקע|Тарих|Сценарій|Сценарио|Сценарий структураси|Сценарий|Структура сценарію|Структура сценарија|Структура сценария|Скица|Рамка на сценарий|Пример|Предыстория|Предистория|Позадина|Передумова|Основа|Концепт|Контекст|Założenia|Wharrimean is|Tình huống|The thing of it is|Tausta|Taust|Tapausaihio|Tapaus|Szenariogrundriss|Szenario|Szablon scenariusza|Stsenaarium|Struktura scenarija|Skica|Skenario konsep|Skenario|Situācija|Senaryo taslağı|Senaryo|Scénář|Scénario|Schema dello scenario|Scenārijs pēc parauga|Scenārijs|Scenár|Scenaro|Scenariusz|Scenariul de şablon|Scenariul de sablon|Scenariu|Scenario Outline|Scenario Amlinellol|Scenario|Scenarijus|Scenarijaus šablonas|Scenarij|Scenarie|Rerefons|Raamstsenaarium|Primer|Pozadí|Pozadina|Pozadie|Plan du scénario|Plan du Scénario|Osnova scénáře|Osnova|Náčrt Scénáře|Náčrt Scenáru|Mate|MISHUN SRSLY|MISHUN|Kịch bản|Konturo de la scenaro|Kontext|Konteksts|Kontekstas|Kontekst|Koncept|Khung tình huống|Khung kịch bản|Háttér|Grundlage|Geçmiş|Forgatókönyv vázlat|Forgatókönyv|Fono|Esquema do Cenário|Esquema do Cenario|Esquema del escenario|Esquema de l'escenari|Escenario|Escenari|Dis is what went down|Dasar|Contexto|Contexte|Contesto|Condiţii|Conditii|Cenário|Cenario|Cefndir|Bối cảnh|Blokes|Bakgrunn|Bakgrund|Baggrund|Background|B4|Antecedents|Antecedentes|All y'all|Achtergrond|Abstrakt Scenario|Abstract Scenario)(:)(.*)$`
|
||||
|
||||
var examplesKeywords = `^(\s*)(예|例子|例|サンプル|امثلة|דוגמאות|Сценарији|Примери|Приклади|Мисоллар|Значения|Örnekler|Voorbeelden|Variantai|Tapaukset|Scenarios|Scenariji|Scenarijai|Příklady|Példák|Príklady|Przykłady|Primjeri|Primeri|Piemēri|Pavyzdžiai|Paraugs|Juhtumid|Exemplos|Exemples|Exemplele|Exempel|Examples|Esempi|Enghreifftiau|Ekzemploj|Eksempler|Ejemplos|EXAMPLZ|Dữ liệu|Contoh|Cobber|Beispiele)(:)(.*)$`
|
||||
|
||||
// Gherkin lexer.
|
||||
var Gherkin = internal.Register(MustNewLexer(
|
||||
&Config{
|
||||
Name: "Gherkin",
|
||||
Aliases: []string{"cucumber", "Cucumber", "gherkin", "Gherkin"},
|
||||
Filenames: []string{"*.feature", "*.FEATURE"},
|
||||
MimeTypes: []string{"text/x-gherkin"},
|
||||
},
|
||||
Rules{
|
||||
"comments": {
|
||||
{`\s*#.*$`, Comment, nil},
|
||||
},
|
||||
"featureElements": {
|
||||
{stepKeywords, Keyword, Push("stepContentStack")},
|
||||
Include("comments"),
|
||||
{`(\s|.)`, NameFunction, nil},
|
||||
},
|
||||
"featureElementsOnStack": {
|
||||
{stepKeywords, Keyword, Pop(2)},
|
||||
Include("comments"),
|
||||
{`(\s|.)`, NameFunction, nil},
|
||||
},
|
||||
"examplesTable": {
|
||||
{`\s+\|`, Keyword, Push("examplesTableHeader")},
|
||||
Include("comments"),
|
||||
{`(\s|.)`, NameFunction, nil},
|
||||
},
|
||||
"examplesTableHeader": {
|
||||
{`\s+\|\s*$`, Keyword, Pop(2)},
|
||||
Include("comments"),
|
||||
{`\\\|`, NameVariable, nil},
|
||||
{`\s*\|`, Keyword, nil},
|
||||
{`[^|]`, NameVariable, nil},
|
||||
},
|
||||
"scenarioSectionsOnStack": {
|
||||
{featureElementKeywords, ByGroups(NameFunction, Keyword, Keyword, NameFunction), Push("featureElementsOnStack")},
|
||||
},
|
||||
"narrative": {
|
||||
Include("scenarioSectionsOnStack"),
|
||||
{`(\s|.)`, NameFunction, nil},
|
||||
},
|
||||
"tableVars": {
|
||||
{`(<[^>]+>)`, NameVariable, nil},
|
||||
},
|
||||
"numbers": {
|
||||
{`(\d+\.?\d*|\d*\.\d+)([eE][+-]?[0-9]+)?`, LiteralString, nil},
|
||||
},
|
||||
"string": {
|
||||
Include("tableVars"),
|
||||
{`(\s|.)`, LiteralString, nil},
|
||||
},
|
||||
"pyString": {
|
||||
{`"""`, Keyword, Pop(1)},
|
||||
Include("string"),
|
||||
},
|
||||
"stepContentRoot": {
|
||||
{`$`, Keyword, Pop(1)},
|
||||
Include("stepContent"),
|
||||
},
|
||||
"stepContentStack": {
|
||||
{`$`, Keyword, Pop(2)},
|
||||
Include("stepContent"),
|
||||
},
|
||||
"stepContent": {
|
||||
{`"`, NameFunction, Push("doubleString")},
|
||||
Include("tableVars"),
|
||||
Include("numbers"),
|
||||
Include("comments"),
|
||||
{`(\s|.)`, NameFunction, nil},
|
||||
},
|
||||
"tableContent": {
|
||||
{`\s+\|\s*$`, Keyword, Pop(1)},
|
||||
Include("comments"),
|
||||
{`\\\|`, LiteralString, nil},
|
||||
{`\s*\|`, Keyword, nil},
|
||||
{`"`, LiteralString, Push("doubleStringTable")},
|
||||
Include("string"),
|
||||
},
|
||||
"doubleString": {
|
||||
{`"`, NameFunction, Pop(1)},
|
||||
Include("string"),
|
||||
},
|
||||
"doubleStringTable": {
|
||||
{`"`, LiteralString, Pop(1)},
|
||||
Include("string"),
|
||||
},
|
||||
"root": {
|
||||
{`\n`, NameFunction, nil},
|
||||
Include("comments"),
|
||||
{`"""`, Keyword, Push("pyString")},
|
||||
{`\s+\|`, Keyword, Push("tableContent")},
|
||||
{`"`, NameFunction, Push("doubleString")},
|
||||
Include("tableVars"),
|
||||
Include("numbers"),
|
||||
{`(\s*)(@[^@\r\n\t ]+)`, ByGroups(NameFunction, NameTag), nil},
|
||||
{stepKeywords, ByGroups(NameFunction, Keyword), Push("stepContentRoot")},
|
||||
{featureKeywords, ByGroups(Keyword, Keyword, NameFunction), Push("narrative")},
|
||||
{featureElementKeywords, ByGroups(NameFunction, Keyword, Keyword, NameFunction), Push("featureElements")},
|
||||
{examplesKeywords, ByGroups(NameFunction, Keyword, Keyword, NameFunction), Push("examplesTable")},
|
||||
{`(\s|.)`, NameFunction, nil},
|
||||
},
|
||||
},
|
||||
))
|
1
vendor/github.com/alecthomas/chroma/lexers/g/go.go
generated
vendored
1
vendor/github.com/alecthomas/chroma/lexers/g/go.go
generated
vendored
@ -15,6 +15,7 @@ var Go = internal.Register(MustNewLexer(
|
||||
Aliases: []string{"go", "golang"},
|
||||
Filenames: []string{"*.go"},
|
||||
MimeTypes: []string{"text/x-gosrc"},
|
||||
EnsureNL: true,
|
||||
},
|
||||
Rules{
|
||||
"root": {
|
||||
|
9
vendor/github.com/alecthomas/chroma/lexers/h/http.go
generated
vendored
9
vendor/github.com/alecthomas/chroma/lexers/h/http.go
generated
vendored
@ -19,8 +19,8 @@ var HTTP = internal.Register(httpBodyContentTypeLexer(MustNewLexer(
|
||||
},
|
||||
Rules{
|
||||
"root": {
|
||||
{`(GET|POST|PUT|DELETE|HEAD|OPTIONS|TRACE|PATCH|CONNECT)( +)([^ ]+)( +)(HTTP)(/)(1\.[01])(\r?\n|\Z)`, ByGroups(NameFunction, Text, NameNamespace, Text, KeywordReserved, Operator, LiteralNumber, Text), Push("headers")},
|
||||
{`(HTTP)(/)(1\.[01])( +)(\d{3})( +)([^\r\n]+)(\r?\n|\Z)`, ByGroups(KeywordReserved, Operator, LiteralNumber, Text, LiteralNumber, Text, NameException, Text), Push("headers")},
|
||||
{`(GET|POST|PUT|DELETE|HEAD|OPTIONS|TRACE|PATCH|CONNECT)( +)([^ ]+)( +)(HTTP)(/)([12]\.[01])(\r?\n|\Z)`, ByGroups(NameFunction, Text, NameNamespace, Text, KeywordReserved, Operator, LiteralNumber, Text), Push("headers")},
|
||||
{`(HTTP)(/)([12]\.[01])( +)(\d{3})( +)([^\r\n]+)(\r?\n|\Z)`, ByGroups(KeywordReserved, Operator, LiteralNumber, Text, LiteralNumber, Text, NameException, Text), Push("headers")},
|
||||
},
|
||||
"headers": {
|
||||
{`([^\s:]+)( *)(:)( *)([^\r\n]+)(\r?\n|\Z)`, EmitterFunc(httpHeaderBlock), nil},
|
||||
@ -38,7 +38,6 @@ func httpContentBlock(groups []string, lexer Lexer) Iterator {
|
||||
{Generic, groups[0]},
|
||||
}
|
||||
return Literator(tokens...)
|
||||
|
||||
}
|
||||
|
||||
func httpHeaderBlock(groups []string, lexer Lexer) Iterator {
|
||||
@ -66,7 +65,7 @@ func httpBodyContentTypeLexer(lexer Lexer) Lexer { return &httpBodyContentTyper{
|
||||
|
||||
type httpBodyContentTyper struct{ Lexer }
|
||||
|
||||
func (d *httpBodyContentTyper) Tokenise(options *TokeniseOptions, text string) (Iterator, error) {
|
||||
func (d *httpBodyContentTyper) Tokenise(options *TokeniseOptions, text string) (Iterator, error) { // nolint: gocognit
|
||||
var contentType string
|
||||
var isContentType bool
|
||||
var subIterator Iterator
|
||||
@ -123,9 +122,7 @@ func (d *httpBodyContentTyper) Tokenise(options *TokeniseOptions, text string) (
|
||||
return EOF
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return token
|
||||
|
||||
}, nil
|
||||
}
|
||||
|
54
vendor/github.com/alecthomas/chroma/lexers/hlb.go
generated
vendored
Normal file
54
vendor/github.com/alecthomas/chroma/lexers/hlb.go
generated
vendored
Normal file
@ -0,0 +1,54 @@
|
||||
package lexers
|
||||
|
||||
import (
|
||||
. "github.com/alecthomas/chroma" // nolint
|
||||
"github.com/alecthomas/chroma/lexers/internal"
|
||||
)
|
||||
|
||||
// HLB lexer.
|
||||
var HLB = internal.Register(MustNewLexer(
|
||||
&Config{
|
||||
Name: "HLB",
|
||||
Aliases: []string{"hlb"},
|
||||
Filenames: []string{"*.hlb"},
|
||||
MimeTypes: []string{},
|
||||
},
|
||||
Rules{
|
||||
"root": {
|
||||
{`(#.*)`, ByGroups(CommentSingle), nil},
|
||||
{`((\b(0(b|B|o|O|x|X)[a-fA-F0-9]+)\b)|(\b(0|[1-9][0-9]*)\b))`, ByGroups(LiteralNumber), nil},
|
||||
{`((\b(true|false)\b))`, ByGroups(NameBuiltin), nil},
|
||||
{`(\bstring\b|\bint\b|\bbool\b|\bfs\b|\boption\b)`, ByGroups(KeywordType), nil},
|
||||
{`(\b[a-zA-Z_][a-zA-Z0-9]*\b)(\()`, ByGroups(NameFunction, Punctuation), Push("params")},
|
||||
{`(\{)`, ByGroups(Punctuation), Push("block")},
|
||||
{`(\n|\r|\r\n)`, Text, nil},
|
||||
{`.`, Text, nil},
|
||||
},
|
||||
"string": {
|
||||
{`"`, LiteralString, Pop(1)},
|
||||
{`\\"`, LiteralString, nil},
|
||||
{`[^\\"]+`, LiteralString, nil},
|
||||
},
|
||||
"block": {
|
||||
{`(\})`, ByGroups(Punctuation), Pop(1)},
|
||||
{`(#.*)`, ByGroups(CommentSingle), nil},
|
||||
{`((\b(0(b|B|o|O|x|X)[a-fA-F0-9]+)\b)|(\b(0|[1-9][0-9]*)\b))`, ByGroups(LiteralNumber), nil},
|
||||
{`((\b(true|false)\b))`, ByGroups(KeywordConstant), nil},
|
||||
{`"`, LiteralString, Push("string")},
|
||||
{`(with)`, ByGroups(KeywordReserved), nil},
|
||||
{`(as)([\t ]+)(\b[a-zA-Z_][a-zA-Z0-9]*\b)`, ByGroups(KeywordReserved, Text, NameFunction), nil},
|
||||
{`(\bstring\b|\bint\b|\bbool\b|\bfs\b|\boption\b)([\t ]+)(\{)`, ByGroups(KeywordType, Text, Punctuation), Push("block")},
|
||||
{`(?!\b(?:scratch|image|resolve|http|checksum|chmod|filename|git|keepGitDir|local|includePatterns|excludePatterns|followPaths|generate|frontendInput|shell|run|readonlyRootfs|env|dir|user|network|security|host|ssh|secret|mount|target|localPath|uid|gid|mode|readonly|tmpfs|sourcePath|cache|mkdir|createParents|chown|createdTime|mkfile|rm|allowNotFound|allowWildcards|copy|followSymlinks|contentsOnly|unpack|createDestPath)\b)(\b[a-zA-Z_][a-zA-Z0-9]*\b)`, ByGroups(NameOther), nil},
|
||||
{`(\n|\r|\r\n)`, Text, nil},
|
||||
{`.`, Text, nil},
|
||||
},
|
||||
"params": {
|
||||
{`(\))`, ByGroups(Punctuation), Pop(1)},
|
||||
{`(variadic)`, ByGroups(Keyword), nil},
|
||||
{`(\bstring\b|\bint\b|\bbool\b|\bfs\b|\boption\b)`, ByGroups(KeywordType), nil},
|
||||
{`(\b[a-zA-Z_][a-zA-Z0-9]*\b)`, ByGroups(NameOther), nil},
|
||||
{`(\n|\r|\r\n)`, Text, nil},
|
||||
{`.`, Text, nil},
|
||||
},
|
||||
},
|
||||
))
|
2
vendor/github.com/alecthomas/chroma/lexers/i/ini.go
generated
vendored
2
vendor/github.com/alecthomas/chroma/lexers/i/ini.go
generated
vendored
@ -10,7 +10,7 @@ var Ini = internal.Register(MustNewLexer(
|
||||
&Config{
|
||||
Name: "INI",
|
||||
Aliases: []string{"ini", "cfg", "dosini"},
|
||||
Filenames: []string{"*.ini", "*.cfg", "*.inf", ".gitconfig"},
|
||||
Filenames: []string{"*.ini", "*.cfg", "*.inf", ".gitconfig", ".editorconfig"},
|
||||
MimeTypes: []string{"text/x-ini", "text/inf"},
|
||||
},
|
||||
Rules{
|
||||
|
12
vendor/github.com/alecthomas/chroma/lexers/internal/api.go
generated
vendored
12
vendor/github.com/alecthomas/chroma/lexers/internal/api.go
generated
vendored
@ -1,3 +1,4 @@
|
||||
// Package internal contains common API functions and structures shared between lexer packages.
|
||||
package internal
|
||||
|
||||
import (
|
||||
@ -36,19 +37,20 @@ func Names(withAliases bool) []string {
|
||||
|
||||
// Get a Lexer by name, alias or file extension.
|
||||
func Get(name string) chroma.Lexer {
|
||||
candidates := chroma.PrioritisedLexers{}
|
||||
if lexer := Registry.byName[name]; lexer != nil {
|
||||
candidates = append(candidates, lexer)
|
||||
return lexer
|
||||
}
|
||||
if lexer := Registry.byAlias[name]; lexer != nil {
|
||||
candidates = append(candidates, lexer)
|
||||
return lexer
|
||||
}
|
||||
if lexer := Registry.byName[strings.ToLower(name)]; lexer != nil {
|
||||
candidates = append(candidates, lexer)
|
||||
return lexer
|
||||
}
|
||||
if lexer := Registry.byAlias[strings.ToLower(name)]; lexer != nil {
|
||||
candidates = append(candidates, lexer)
|
||||
return lexer
|
||||
}
|
||||
|
||||
candidates := chroma.PrioritisedLexers{}
|
||||
// Try file extension.
|
||||
if lexer := Match("filename." + name); lexer != nil {
|
||||
candidates = append(candidates, lexer)
|
||||
|
73
vendor/github.com/alecthomas/chroma/lexers/j/j.go
generated
vendored
Normal file
73
vendor/github.com/alecthomas/chroma/lexers/j/j.go
generated
vendored
Normal file
@ -0,0 +1,73 @@
|
||||
package j
|
||||
|
||||
import (
|
||||
. "github.com/alecthomas/chroma" // nolint
|
||||
"github.com/alecthomas/chroma/lexers/internal"
|
||||
)
|
||||
|
||||
// J lexer.
|
||||
var J = internal.Register(MustNewLexer(
|
||||
&Config{
|
||||
Name: "J",
|
||||
Aliases: []string{"j"},
|
||||
Filenames: []string{"*.ijs"},
|
||||
MimeTypes: []string{"text/x-j"},
|
||||
},
|
||||
Rules{
|
||||
"root": {
|
||||
{`#!.*$`, CommentPreproc, nil},
|
||||
{`NB\..*`, CommentSingle, nil},
|
||||
{`\n+\s*Note`, CommentMultiline, Push("comment")},
|
||||
{`\s*Note.*`, CommentSingle, nil},
|
||||
{`\s+`, Text, nil},
|
||||
{`'`, LiteralString, Push("singlequote")},
|
||||
{`0\s+:\s*0|noun\s+define\s*$`, NameEntity, Push("nounDefinition")},
|
||||
{`(([1-4]|13)\s+:\s*0|(adverb|conjunction|dyad|monad|verb)\s+define)\b`, NameFunction, Push("explicitDefinition")},
|
||||
{Words(``, `\b[a-zA-Z]\w*\.`, `for_`, `goto_`, `label_`), NameLabel, nil},
|
||||
{Words(``, `\.`, `assert`, `break`, `case`, `catch`, `catchd`, `catcht`, `continue`, `do`, `else`, `elseif`, `end`, `fcase`, `for`, `if`, `return`, `select`, `throw`, `try`, `while`, `whilst`), NameLabel, nil},
|
||||
{`\b[a-zA-Z]\w*`, NameVariable, nil},
|
||||
{Words(``, ``, `ARGV`, `CR`, `CRLF`, `DEL`, `Debug`, `EAV`, `EMPTY`, `FF`, `JVERSION`, `LF`, `LF2`, `Note`, `TAB`, `alpha17`, `alpha27`, `apply`, `bind`, `boxopen`, `boxxopen`, `bx`, `clear`, `cutLF`, `cutopen`, `datatype`, `def`, `dfh`, `drop`, `each`, `echo`, `empty`, `erase`, `every`, `evtloop`, `exit`, `expand`, `fetch`, `file2url`, `fixdotdot`, `fliprgb`, `getargs`, `getenv`, `hfd`, `inv`, `inverse`, `iospath`, `isatty`, `isutf8`, `items`, `leaf`, `list`, `nameclass`, `namelist`, `names`, `nc`, `nl`, `on`, `pick`, `rows`, `script`, `scriptd`, `sign`, `sminfo`, `smoutput`, `sort`, `split`, `stderr`, `stdin`, `stdout`, `table`, `take`, `timespacex`, `timex`, `tmoutput`, `toCRLF`, `toHOST`, `toJ`, `tolower`, `toupper`, `type`, `ucp`, `ucpcount`, `usleep`, `utf8`, `uucp`), NameFunction, nil},
|
||||
{`=[.:]`, Operator, nil},
|
||||
{"[-=+*#$%@!~`^&\";:.,<>{}\\[\\]\\\\|/]", Operator, nil},
|
||||
{`[abCdDeEfHiIjLMoprtT]\.`, KeywordReserved, nil},
|
||||
{`[aDiLpqsStux]\:`, KeywordReserved, nil},
|
||||
{`(_[0-9])\:`, KeywordConstant, nil},
|
||||
{`\(`, Punctuation, Push("parentheses")},
|
||||
Include("numbers"),
|
||||
},
|
||||
"comment": {
|
||||
{`[^)]`, CommentMultiline, nil},
|
||||
{`^\)`, CommentMultiline, Pop(1)},
|
||||
{`[)]`, CommentMultiline, nil},
|
||||
},
|
||||
"explicitDefinition": {
|
||||
{`\b[nmuvxy]\b`, NameDecorator, nil},
|
||||
Include("root"),
|
||||
{`[^)]`, Name, nil},
|
||||
{`^\)`, NameLabel, Pop(1)},
|
||||
{`[)]`, Name, nil},
|
||||
},
|
||||
"numbers": {
|
||||
{`\b_{1,2}\b`, LiteralNumber, nil},
|
||||
{`_?\d+(\.\d+)?(\s*[ejr]\s*)_?\d+(\.?=\d+)?`, LiteralNumber, nil},
|
||||
{`_?\d+\.(?=\d+)`, LiteralNumberFloat, nil},
|
||||
{`_?\d+x`, LiteralNumberIntegerLong, nil},
|
||||
{`_?\d+`, LiteralNumberInteger, nil},
|
||||
},
|
||||
"nounDefinition": {
|
||||
{`[^)]`, LiteralString, nil},
|
||||
{`^\)`, NameLabel, Pop(1)},
|
||||
{`[)]`, LiteralString, nil},
|
||||
},
|
||||
"parentheses": {
|
||||
{`\)`, Punctuation, Pop(1)},
|
||||
Include("explicitDefinition"),
|
||||
Include("root"),
|
||||
},
|
||||
"singlequote": {
|
||||
{`[^']`, LiteralString, nil},
|
||||
{`''`, LiteralString, nil},
|
||||
{`'`, LiteralString, Pop(1)},
|
||||
},
|
||||
},
|
||||
))
|
7
vendor/github.com/alecthomas/chroma/lexers/j/java.go
generated
vendored
7
vendor/github.com/alecthomas/chroma/lexers/j/java.go
generated
vendored
@ -20,7 +20,7 @@ var Java = internal.Register(MustNewLexer(
|
||||
{`//.*?\n`, CommentSingle, nil},
|
||||
{`/\*.*?\*/`, CommentMultiline, nil},
|
||||
{`(assert|break|case|catch|continue|default|do|else|finally|for|if|goto|instanceof|new|return|switch|this|throw|try|while)\b`, Keyword, nil},
|
||||
{`((?:(?:[^\W\d]|\$)[\w.\[\]$<>]*\s+)+?)((?:[^\W\d]|\$)[\w$]*)(\s*)`, ByGroups(UsingSelf("root"), NameFunction, Text, Operator), nil},
|
||||
{`((?:(?:[^\W\d]|\$)[\w.\[\]$<>]*\s+)+?)((?:[^\W\d]|\$)[\w$]*)(\s*)(\()`, ByGroups(UsingSelf("root"), NameFunction, Text, Operator), nil},
|
||||
{`@[^\W\d][\w.]*`, NameDecorator, nil},
|
||||
{`(abstract|const|enum|extends|final|implements|native|private|protected|public|static|strictfp|super|synchronized|throws|transient|volatile)\b`, KeywordDeclaration, nil},
|
||||
{`(boolean|byte|char|double|float|int|long|short|void)\b`, KeywordType, nil},
|
||||
@ -30,7 +30,7 @@ var Java = internal.Register(MustNewLexer(
|
||||
{`(import(?:\s+static)?)(\s+)`, ByGroups(KeywordNamespace, Text), Push("import")},
|
||||
{`"(\\\\|\\"|[^"])*"`, LiteralString, nil},
|
||||
{`'\\.'|'[^\\]'|'\\u[0-9a-fA-F]{4}'`, LiteralStringChar, nil},
|
||||
{`(\.)((?:[^\W\d]|\$)[\w$]*)`, ByGroups(Punctuation, NameAttribute), nil},
|
||||
{`(\.)((?:[^\W\d]|\$)[\w$]*)`, ByGroups(Operator, NameAttribute), nil},
|
||||
{`^\s*([^\W\d]|\$)[\w$]*:`, NameLabel, nil},
|
||||
{`([^\W\d]|\$)[\w$]*`, Name, nil},
|
||||
{`([0-9][0-9_]*\.([0-9][0-9_]*)?|\.[0-9][0-9_]*)([eE][+\-]?[0-9][0-9_]*)?[fFdD]?|[0-9][eE][+\-]?[0-9][0-9_]*[fFdD]?|[0-9]([eE][+\-]?[0-9][0-9_]*)?[fFdD]|0[xX]([0-9a-fA-F][0-9a-fA-F_]*\.?|([0-9a-fA-F][0-9a-fA-F_]*)?\.[0-9a-fA-F][0-9a-fA-F_]*)[pP][+\-]?[0-9][0-9_]*[fFdD]?`, LiteralNumberFloat, nil},
|
||||
@ -38,8 +38,7 @@ var Java = internal.Register(MustNewLexer(
|
||||
{`0[bB][01][01_]*[lL]?`, LiteralNumberBin, nil},
|
||||
{`0[0-7_]+[lL]?`, LiteralNumberOct, nil},
|
||||
{`0|[1-9][0-9_]*[lL]?`, LiteralNumberInteger, nil},
|
||||
{`[~^*!%&<>|+=:/?-]`, Operator, nil},
|
||||
{`[\[\](){};,.]`, Punctuation, nil},
|
||||
{`[~^*!%&\[\](){}<>|+=:;,./?-]`, Operator, nil},
|
||||
{`\n`, Text, nil},
|
||||
},
|
||||
"class": {
|
||||
|
5
vendor/github.com/alecthomas/chroma/lexers/j/jsx.go
generated
vendored
5
vendor/github.com/alecthomas/chroma/lexers/j/jsx.go
generated
vendored
@ -69,8 +69,9 @@ var JSX = internal.Register(MustNewLexer(
|
||||
Include("root"),
|
||||
},
|
||||
"jsx": {
|
||||
{`(<)([\w]+)`, ByGroups(Punctuation, NameTag), Push("tag")},
|
||||
{`(<)(/)([\w]+)(>)`, ByGroups(Punctuation, Punctuation, NameTag, Punctuation), nil},
|
||||
{`(<)(/?)(>)`, ByGroups(Punctuation, Punctuation, Punctuation), nil},
|
||||
{`(<)([\w\.]+)`, ByGroups(Punctuation, NameTag), Push("tag")},
|
||||
{`(<)(/)([\w\.]+)(>)`, ByGroups(Punctuation, Punctuation, NameTag, Punctuation), nil},
|
||||
},
|
||||
"tag": {
|
||||
{`\s+`, Text, nil},
|
||||
|
1
vendor/github.com/alecthomas/chroma/lexers/lexers.go
generated
vendored
1
vendor/github.com/alecthomas/chroma/lexers/lexers.go
generated
vendored
@ -32,6 +32,7 @@ import (
|
||||
_ "github.com/alecthomas/chroma/lexers/w"
|
||||
_ "github.com/alecthomas/chroma/lexers/x"
|
||||
_ "github.com/alecthomas/chroma/lexers/y"
|
||||
_ "github.com/alecthomas/chroma/lexers/z"
|
||||
)
|
||||
|
||||
// Registry of Lexers.
|
||||
|
9
vendor/github.com/alecthomas/chroma/lexers/m/markdown.go
generated
vendored
9
vendor/github.com/alecthomas/chroma/lexers/m/markdown.go
generated
vendored
@ -2,11 +2,12 @@ package m
|
||||
|
||||
import (
|
||||
. "github.com/alecthomas/chroma" // nolint
|
||||
"github.com/alecthomas/chroma/lexers/h"
|
||||
"github.com/alecthomas/chroma/lexers/internal"
|
||||
)
|
||||
|
||||
// Markdown lexer.
|
||||
var Markdown = internal.Register(MustNewLexer(
|
||||
var Markdown = internal.Register(DelegatingLexer(h.HTML, MustNewLexer(
|
||||
&Config{
|
||||
Name: "markdown",
|
||||
Aliases: []string{"md", "mkd"},
|
||||
@ -40,8 +41,8 @@ var Markdown = internal.Register(MustNewLexer(
|
||||
{"`[^`]+`", LiteralStringBacktick, nil},
|
||||
{`[@#][\w/:]+`, NameEntity, nil},
|
||||
{`(!?\[)([^]]+)(\])(\()([^)]+)(\))`, ByGroups(Text, NameTag, Text, Text, NameAttribute, Text), nil},
|
||||
{`[^\\\s]+`, Text, nil},
|
||||
{`.|\n`, Text, nil},
|
||||
{`[^\\\s]+`, Other, nil},
|
||||
{`.|\n`, Other, nil},
|
||||
},
|
||||
},
|
||||
))
|
||||
)))
|
||||
|
43
vendor/github.com/alecthomas/chroma/lexers/m/mlir.go
generated
vendored
Normal file
43
vendor/github.com/alecthomas/chroma/lexers/m/mlir.go
generated
vendored
Normal file
@ -0,0 +1,43 @@
|
||||
package m
|
||||
|
||||
import (
|
||||
. "github.com/alecthomas/chroma" // nolint
|
||||
"github.com/alecthomas/chroma/lexers/internal"
|
||||
)
|
||||
|
||||
// MLIR lexer.
|
||||
var Mlir = internal.Register(MustNewLexer(
|
||||
&Config{
|
||||
Name: "MLIR",
|
||||
Aliases: []string{"mlir"},
|
||||
Filenames: []string{"*.mlir"},
|
||||
MimeTypes: []string{"text/x-mlir"},
|
||||
},
|
||||
Rules{
|
||||
"root": {
|
||||
Include("whitespace"),
|
||||
{`c?"[^"]*?"`, LiteralString, nil},
|
||||
{`\^([-a-zA-Z$._][\w\-$.0-9]*)\s*`, NameLabel, nil},
|
||||
{`([\w\d_$.]+)\s*=`, NameLabel, nil},
|
||||
Include("keyword"),
|
||||
{`->`, Punctuation, nil},
|
||||
{`@([\w_][\w\d_$.]*)`, NameFunction, nil},
|
||||
{`[%#][\w\d_$.]+`, NameVariable, nil},
|
||||
{`([1-9?][\d?]*\s*x)+`, LiteralNumber, nil},
|
||||
{`0[xX][a-fA-F0-9]+`, LiteralNumber, nil},
|
||||
{`-?\d+(?:[.]\d+)?(?:[eE][-+]?\d+(?:[.]\d+)?)?`, LiteralNumber, nil},
|
||||
{`[=<>{}\[\]()*.,!:]|x\b`, Punctuation, nil},
|
||||
{`[\w\d]+`, Text, nil},
|
||||
},
|
||||
"whitespace": {
|
||||
{`(\n|\s)+`, Text, nil},
|
||||
{`//.*?\n`, Comment, nil},
|
||||
},
|
||||
"keyword": {
|
||||
{Words(``, ``, `constant`, `return`), KeywordType, nil},
|
||||
{Words(``, ``, `func`, `loc`, `memref`, `tensor`, `vector`), KeywordType, nil},
|
||||
{`bf16|f16|f32|f64|index`, Keyword, nil},
|
||||
{`i[1-9]\d*`, Keyword, nil},
|
||||
},
|
||||
},
|
||||
))
|
2
vendor/github.com/alecthomas/chroma/lexers/m/mysql.go
generated
vendored
2
vendor/github.com/alecthomas/chroma/lexers/m/mysql.go
generated
vendored
@ -26,7 +26,7 @@ var MySQL = internal.Register(MustNewLexer(
|
||||
{`((?:_[a-z0-9]+)?)(")`, ByGroups(LiteralStringAffix, LiteralStringDouble), Push("double-string")},
|
||||
{"[+*/<>=~!@#%^&|`?-]", Operator, nil},
|
||||
{`\b(tinyint|smallint|mediumint|int|integer|bigint|date|datetime|time|bit|bool|tinytext|mediumtext|longtext|text|tinyblob|mediumblob|longblob|blob|float|double|double\s+precision|real|numeric|dec|decimal|timestamp|year|char|varchar|varbinary|varcharacter|enum|set)(\b\s*)(\()?`, ByGroups(KeywordType, Text, Punctuation), nil},
|
||||
{`\b(add|all|alter|analyze|and|as|asc|asensitive|before|between|bigint|binary|blob|both|by|call|cascade|case|change|char|character|check|collate|column|condition|constraint|continue|convert|create|cross|current_date|current_time|current_timestamp|current_user|cursor|database|databases|day_hour|day_microsecond|day_minute|day_second|dec|decimal|declare|default|delayed|delete|desc|describe|deterministic|distinct|distinctrow|div|double|drop|dual|each|else|elseif|enclosed|escaped|exists|exit|explain|fetch|flush|float|float4|float8|for|force|foreign|from|fulltext|grant|group|having|high_priority|hour_microsecond|hour_minute|hour_second|if|ignore|in|index|infile|inner|inout|insensitive|insert|int|int1|int2|int3|int4|int8|integer|interval|into|is|iterate|join|key|keys|kill|leading|leave|left|like|limit|lines|load|localtime|localtimestamp|lock|long|loop|low_priority|match|minute_microsecond|minute_second|mod|modifies|natural|no_write_to_binlog|not|numeric|on|optimize|option|optionally|or|order|out|outer|outfile|precision|primary|procedure|purge|raid0|read|reads|real|references|regexp|release|rename|repeat|replace|require|restrict|return|revoke|right|rlike|schema|schemas|second_microsecond|select|sensitive|separator|set|show|smallint|soname|spatial|specific|sql|sql_big_result|sql_calc_found_rows|sql_small_result|sqlexception|sqlstate|sqlwarning|ssl|starting|straight_join|table|terminated|then|to|trailing|trigger|undo|union|unique|unlock|unsigned|update|usage|use|using|utc_date|utc_time|utc_timestamp|values|varying|when|where|while|with|write|x509|xor|year_month|zerofill)\b`, Keyword, nil},
|
||||
{`\b(add|all|alter|analyze|and|as|asc|asensitive|before|between|bigint|binary|blob|both|by|call|cascade|case|change|char|character|check|collate|column|condition|constraint|continue|convert|create|cross|current_date|current_time|current_timestamp|current_user|cursor|database|databases|day_hour|day_microsecond|day_minute|day_second|dec|decimal|declare|default|delayed|delete|desc|describe|deterministic|distinct|distinctrow|div|double|drop|dual|each|else|elseif|enclosed|escaped|exists|exit|explain|fetch|flush|float|float4|float8|for|force|foreign|from|fulltext|grant|group|having|high_priority|hour_microsecond|hour_minute|hour_second|identified|if|ignore|in|index|infile|inner|inout|insensitive|insert|int|int1|int2|int3|int4|int8|integer|interval|into|is|iterate|join|key|keys|kill|leading|leave|left|like|limit|lines|load|localtime|localtimestamp|lock|long|loop|low_priority|match|minute_microsecond|minute_second|mod|modifies|natural|no_write_to_binlog|not|numeric|on|optimize|option|optionally|or|order|out|outer|outfile|precision|primary|privileges|procedure|purge|raid0|read|reads|real|references|regexp|release|rename|repeat|replace|require|restrict|return|revoke|right|rlike|schema|schemas|second_microsecond|select|sensitive|separator|set|show|smallint|soname|spatial|specific|sql|sql_big_result|sql_calc_found_rows|sql_small_result|sqlexception|sqlstate|sqlwarning|ssl|starting|straight_join|table|terminated|then|to|trailing|trigger|undo|union|unique|unlock|unsigned|update|usage|use|user|using|utc_date|utc_time|utc_timestamp|values|varying|when|where|while|with|write|x509|xor|year_month|zerofill)\b`, Keyword, nil},
|
||||
{`\b(auto_increment|engine|charset|tables)\b`, KeywordPseudo, nil},
|
||||
{`(true|false|null)`, NameConstant, nil},
|
||||
{`([a-z_]\w*)(\s*)(\()`, ByGroups(NameFunction, Text, Punctuation), nil},
|
||||
|
1
vendor/github.com/alecthomas/chroma/lexers/n/nim.go
generated
vendored
1
vendor/github.com/alecthomas/chroma/lexers/n/nim.go
generated
vendored
@ -16,6 +16,7 @@ var Nim = internal.Register(MustNewLexer(
|
||||
},
|
||||
Rules{
|
||||
"root": {
|
||||
{`#\[[\s\S]*?\]#`, CommentMultiline, nil},
|
||||
{`##.*$`, LiteralStringDoc, nil},
|
||||
{`#.*$`, Comment, nil},
|
||||
{`[*=><+\-/@$~&%!?|\\\[\]]`, Operator, nil},
|
||||
|
1
vendor/github.com/alecthomas/chroma/lexers/p/plaintext.go
generated
vendored
1
vendor/github.com/alecthomas/chroma/lexers/p/plaintext.go
generated
vendored
@ -11,6 +11,7 @@ var Plaintext = internal.Register(MustNewLexer(
|
||||
Aliases: []string{"text", "plain", "no-highlight"},
|
||||
Filenames: []string{"*.txt"},
|
||||
MimeTypes: []string{"text/plain"},
|
||||
Priority: 0.1,
|
||||
},
|
||||
internal.PlaintextRules,
|
||||
))
|
||||
|
59
vendor/github.com/alecthomas/chroma/lexers/p/pony.go
generated
vendored
Normal file
59
vendor/github.com/alecthomas/chroma/lexers/p/pony.go
generated
vendored
Normal file
@ -0,0 +1,59 @@
|
||||
package p
|
||||
|
||||
import (
|
||||
. "github.com/alecthomas/chroma" // nolint
|
||||
"github.com/alecthomas/chroma/lexers/internal"
|
||||
)
|
||||
|
||||
// Pony lexer.
|
||||
var Pony = internal.Register(MustNewLexer(
|
||||
&Config{
|
||||
Name: "Pony",
|
||||
Aliases: []string{"pony"},
|
||||
Filenames: []string{"*.pony"},
|
||||
MimeTypes: []string{},
|
||||
},
|
||||
Rules{
|
||||
"root": {
|
||||
{`\n`, Text, nil},
|
||||
{`[^\S\n]+`, Text, nil},
|
||||
{`//.*\n`, CommentSingle, nil},
|
||||
{`/\*`, CommentMultiline, Push("nested_comment")},
|
||||
{`"""(?:.|\n)*?"""`, LiteralStringDoc, nil},
|
||||
{`"`, LiteralString, Push("string")},
|
||||
{`\'.*\'`, LiteralStringChar, nil},
|
||||
{`=>|[]{}:().~;,|&!^?[]`, Punctuation, nil},
|
||||
{Words(``, `\b`, `addressof`, `and`, `as`, `consume`, `digestof`, `is`, `isnt`, `not`, `or`), OperatorWord, nil},
|
||||
{`!=|==|<<|>>|[-+/*%=<>]`, Operator, nil},
|
||||
{Words(``, `\b`, `box`, `break`, `compile_error`, `compile_intrinsic`, `continue`, `do`, `else`, `elseif`, `embed`, `end`, `error`, `for`, `if`, `ifdef`, `in`, `iso`, `lambda`, `let`, `match`, `object`, `recover`, `ref`, `repeat`, `return`, `tag`, `then`, `this`, `trn`, `try`, `until`, `use`, `var`, `val`, `where`, `while`, `with`, `#any`, `#read`, `#send`, `#share`), Keyword, nil},
|
||||
{`(actor|class|struct|primitive|interface|trait|type)((?:\s)+)`, ByGroups(Keyword, Text), Push("typename")},
|
||||
{`(new|fun|be)((?:\s)+)`, ByGroups(Keyword, Text), Push("methodname")},
|
||||
{Words(``, `\b`, `U8`, `U16`, `U32`, `U64`, `ULong`, `USize`, `U128`, `Unsigned`, `Stringable`, `String`, `StringBytes`, `StringRunes`, `InputNotify`, `InputStream`, `Stdin`, `ByteSeq`, `ByteSeqIter`, `OutStream`, `StdStream`, `SourceLoc`, `I8`, `I16`, `I32`, `I64`, `ILong`, `ISize`, `I128`, `Signed`, `Seq`, `RuntimeOptions`, `Real`, `Integer`, `SignedInteger`, `UnsignedInteger`, `FloatingPoint`, `Number`, `Int`, `ReadSeq`, `ReadElement`, `Pointer`, `Platform`, `NullablePointer`, `None`, `Iterator`, `F32`, `F64`, `Float`, `Env`, `DoNotOptimise`, `DisposableActor`, `Less`, `Equal`, `Greater`, `Compare`, `HasEq`, `Equatable`, `Comparable`, `Bool`, `AsioEventID`, `AsioEventNotify`, `AsioEvent`, `Array`, `ArrayKeys`, `ArrayValues`, `ArrayPairs`, `Any`, `AmbientAuth`), KeywordType, nil},
|
||||
{`_?[A-Z]\w*`, NameClass, nil},
|
||||
{`string\(\)`, NameOther, nil},
|
||||
{`(\d+\.\d*|\.\d+|\d+)[eE][+-]?\d+`, LiteralNumberFloat, nil},
|
||||
{`0x[0-9a-fA-F]+`, LiteralNumberHex, nil},
|
||||
{`\d+`, LiteralNumberInteger, nil},
|
||||
{`(true|false)\b`, Keyword, nil},
|
||||
{`_\d*`, Name, nil},
|
||||
{`_?[a-z][\w\'_]*`, Name, nil},
|
||||
},
|
||||
"typename": {
|
||||
{`(iso|trn|ref|val|box|tag)?((?:\s)*)(_?[A-Z]\w*)`, ByGroups(Keyword, Text, NameClass), Pop(1)},
|
||||
},
|
||||
"methodname": {
|
||||
{`(iso|trn|ref|val|box|tag)?((?:\s)*)(_?[a-z]\w*)`, ByGroups(Keyword, Text, NameFunction), Pop(1)},
|
||||
},
|
||||
"nested_comment": {
|
||||
{`[^*/]+`, CommentMultiline, nil},
|
||||
{`/\*`, CommentMultiline, Push()},
|
||||
{`\*/`, CommentMultiline, Pop(1)},
|
||||
{`[*/]`, CommentMultiline, nil},
|
||||
},
|
||||
"string": {
|
||||
{`"`, LiteralString, Pop(1)},
|
||||
{`\\"`, LiteralString, nil},
|
||||
{`[^\\"]+`, LiteralString, nil},
|
||||
},
|
||||
},
|
||||
))
|
4
vendor/github.com/alecthomas/chroma/lexers/p/powershell.go
generated
vendored
4
vendor/github.com/alecthomas/chroma/lexers/p/powershell.go
generated
vendored
@ -22,6 +22,7 @@ var Powershell = internal.Register(MustNewLexer(
|
||||
{`^(\s*#[#\s]*)(\.(?:component|description|example|externalhelp|forwardhelpcategory|forwardhelptargetname|functionality|inputs|link|notes|outputs|parameter|remotehelprunspace|role|synopsis))([^\n]*$)`, ByGroups(Comment, LiteralStringDoc, Comment), nil},
|
||||
{`#[^\n]*?$`, Comment, nil},
|
||||
{`(<|<)#`, CommentMultiline, Push("multline")},
|
||||
{`(?i)([A-Z]:)`, Name, nil},
|
||||
{`@"\n`, LiteralStringHeredoc, Push("heredoc-double")},
|
||||
{`@'\n.*?\n'@`, LiteralStringHeredoc, nil},
|
||||
{"`[\\'\"$@-]", Punctuation, nil},
|
||||
@ -30,7 +31,8 @@ var Powershell = internal.Register(MustNewLexer(
|
||||
{`(\$|@@|@)((global|script|private|env):)?\w+`, NameVariable, nil},
|
||||
{`(while|validateset|validaterange|validatepattern|validatelength|validatecount|until|trap|switch|return|ref|process|param|parameter|in|if|global:|function|foreach|for|finally|filter|end|elseif|else|dynamicparam|do|default|continue|cmdletbinding|break|begin|alias|\?|%|#script|#private|#local|#global|mandatory|parametersetname|position|valuefrompipeline|valuefrompipelinebypropertyname|valuefromremainingarguments|helpmessage|try|catch|throw)\b`, Keyword, nil},
|
||||
{`-(and|as|band|bnot|bor|bxor|casesensitive|ccontains|ceq|cge|cgt|cle|clike|clt|cmatch|cne|cnotcontains|cnotlike|cnotmatch|contains|creplace|eq|exact|f|file|ge|gt|icontains|ieq|ige|igt|ile|ilike|ilt|imatch|ine|inotcontains|inotlike|inotmatch|ireplace|is|isnot|le|like|lt|match|ne|not|notcontains|notlike|notmatch|or|regex|replace|wildcard)\b`, Operator, nil},
|
||||
{`(write|where|wait|use|update|unregister|undo|trace|test|tee|take|suspend|stop|start|split|sort|skip|show|set|send|select|scroll|resume|restore|restart|resolve|resize|reset|rename|remove|register|receive|read|push|pop|ping|out|new|move|measure|limit|join|invoke|import|group|get|format|foreach|export|expand|exit|enter|enable|disconnect|disable|debug|cxnew|copy|convertto|convertfrom|convert|connect|complete|compare|clear|checkpoint|aggregate|add)-[a-z_]\w*\b`, NameBuiltin, nil},
|
||||
{`(write|where|watch|wait|use|update|unregister|unpublish|unprotect|unlock|uninstall|undo|unblock|trace|test|tee|take|sync|switch|suspend|submit|stop|step|start|split|sort|skip|show|set|send|select|search|scroll|save|revoke|resume|restore|restart|resolve|resize|reset|request|repair|rename|remove|register|redo|receive|read|push|publish|protect|pop|ping|out|optimize|open|new|move|mount|merge|measure|lock|limit|join|invoke|install|initialize|import|hide|group|grant|get|format|foreach|find|export|expand|exit|enter|enable|edit|dismount|disconnect|disable|deny|debug|cxnew|copy|convertto|convertfrom|convert|connect|confirm|compress|complete|compare|close|clear|checkpoint|block|backup|assert|approve|aggregate|add)-[a-z_]\w*\b`, NameBuiltin, nil},
|
||||
{`(ac|asnp|cat|cd|cfs|chdir|clc|clear|clhy|cli|clp|cls|clv|cnsn|compare|copy|cp|cpi|cpp|curl|cvpa|dbp|del|diff|dir|dnsn|ebp|echo|epal|epcsv|epsn|erase|etsn|exsn|fc|fhx|fl|foreach|ft|fw|gal|gbp|gc|gci|gcm|gcs|gdr|ghy|gi|gjb|gl|gm|gmo|gp|gps|gpv|group|gsn|gsnp|gsv|gu|gv|gwmi|h|history|icm|iex|ihy|ii|ipal|ipcsv|ipmo|ipsn|irm|ise|iwmi|iwr|kill|lp|ls|man|md|measure|mi|mount|move|mp|mv|nal|ndr|ni|nmo|npssc|nsn|nv|ogv|oh|popd|ps|pushd|pwd|r|rbp|rcjb|rcsn|rd|rdr|ren|ri|rjb|rm|rmdir|rmo|rni|rnp|rp|rsn|rsnp|rujb|rv|rvpa|rwmi|sajb|sal|saps|sasv|sbp|sc|select|set|shcm|si|sl|sleep|sls|sort|sp|spjb|spps|spsv|start|sujb|sv|swmi|tee|trcm|type|wget|where|wjb|write)\s`, NameBuiltin, nil},
|
||||
{"\\[[a-z_\\[][\\w. `,\\[\\]]*\\]", NameConstant, nil},
|
||||
{`-[a-z_]\w*`, Name, nil},
|
||||
{`\w+`, Name, nil},
|
||||
|
67
vendor/github.com/alecthomas/chroma/lexers/r/reasonml.go
generated
vendored
Normal file
67
vendor/github.com/alecthomas/chroma/lexers/r/reasonml.go
generated
vendored
Normal file
@ -0,0 +1,67 @@
|
||||
package r
|
||||
|
||||
import (
|
||||
. "github.com/alecthomas/chroma" // nolint
|
||||
"github.com/alecthomas/chroma/lexers/internal"
|
||||
)
|
||||
|
||||
// Reasonml lexer.
|
||||
var Reasonml = internal.Register(MustNewLexer(
|
||||
&Config{
|
||||
Name: "ReasonML",
|
||||
Aliases: []string{"reason", "reasonml"},
|
||||
Filenames: []string{"*.re", "*.rei"},
|
||||
MimeTypes: []string{"text/x-reasonml"},
|
||||
},
|
||||
Rules{
|
||||
"escape-sequence": {
|
||||
{`\\[\\"\'ntbr]`, LiteralStringEscape, nil},
|
||||
{`\\[0-9]{3}`, LiteralStringEscape, nil},
|
||||
{`\\x[0-9a-fA-F]{2}`, LiteralStringEscape, nil},
|
||||
},
|
||||
"root": {
|
||||
{`\s+`, Text, nil},
|
||||
{`false|true|\(\)|\[\]`, NameBuiltinPseudo, nil},
|
||||
{`\b([A-Z][\w\']*)(?=\s*\.)`, NameNamespace, Push("dotted")},
|
||||
{`\b([A-Z][\w\']*)`, NameClass, nil},
|
||||
{`//.*?\n`, CommentSingle, nil},
|
||||
{`\/\*(?![\/])`, CommentMultiline, Push("comment")},
|
||||
{`\b(as|assert|begin|class|constraint|do|done|downto|else|end|exception|external|false|for|fun|esfun|function|functor|if|in|include|inherit|initializer|lazy|let|switch|module|pub|mutable|new|nonrec|object|of|open|pri|rec|sig|struct|then|to|true|try|type|val|virtual|when|while|with)\b`, Keyword, nil},
|
||||
{"(~|\\}|\\|]|\\||\\|\\||\\{<|\\{|`|_|]|\\[\\||\\[>|\\[<|\\[|\\?\\?|\\?|>\\}|>]|>|=|<-|<|;;|;|:>|:=|::|:|\\.\\.\\.|\\.\\.|\\.|=>|-\\.|-|,|\\+|\\*|\\)|\\(|&&|&|#|!=)", OperatorWord, nil},
|
||||
{`([=<>@^|&+\*/$%-]|[!?~])?[!$%&*+\./:<=>?@^|~-]`, Operator, nil},
|
||||
{`\b(and|asr|land|lor|lsl|lsr|lxor|mod|or)\b`, OperatorWord, nil},
|
||||
{`\b(unit|int|float|bool|string|char|list|array)\b`, KeywordType, nil},
|
||||
{`[^\W\d][\w']*`, Name, nil},
|
||||
{`-?\d[\d_]*(.[\d_]*)?([eE][+\-]?\d[\d_]*)`, LiteralNumberFloat, nil},
|
||||
{`0[xX][\da-fA-F][\da-fA-F_]*`, LiteralNumberHex, nil},
|
||||
{`0[oO][0-7][0-7_]*`, LiteralNumberOct, nil},
|
||||
{`0[bB][01][01_]*`, LiteralNumberBin, nil},
|
||||
{`\d[\d_]*`, LiteralNumberInteger, nil},
|
||||
{`'(?:(\\[\\\"'ntbr ])|(\\[0-9]{3})|(\\x[0-9a-fA-F]{2}))'`, LiteralStringChar, nil},
|
||||
{`'.'`, LiteralStringChar, nil},
|
||||
{`'`, Keyword, nil},
|
||||
{`"`, LiteralStringDouble, Push("string")},
|
||||
{`[~?][a-z][\w\']*:`, NameVariable, nil},
|
||||
},
|
||||
"comment": {
|
||||
{`[^\/*]+`, CommentMultiline, nil},
|
||||
{`\/\*`, CommentMultiline, Push()},
|
||||
{`\*\/`, CommentMultiline, Pop(1)},
|
||||
{`[\*]`, CommentMultiline, nil},
|
||||
},
|
||||
"string": {
|
||||
{`[^\\"]+`, LiteralStringDouble, nil},
|
||||
Include("escape-sequence"),
|
||||
{`\\\n`, LiteralStringDouble, nil},
|
||||
{`"`, LiteralStringDouble, Pop(1)},
|
||||
},
|
||||
"dotted": {
|
||||
{`\s+`, Text, nil},
|
||||
{`\.`, Punctuation, nil},
|
||||
{`[A-Z][\w\']*(?=\s*\.)`, NameNamespace, nil},
|
||||
{`[A-Z][\w\']*`, NameClass, Pop(1)},
|
||||
{`[a-z_][\w\']*`, Name, Pop(1)},
|
||||
Default(Pop(1)),
|
||||
},
|
||||
},
|
||||
))
|
2
vendor/github.com/alecthomas/chroma/lexers/r/rust.go
generated
vendored
2
vendor/github.com/alecthomas/chroma/lexers/r/rust.go
generated
vendored
@ -58,7 +58,7 @@ var Rust = internal.Register(MustNewLexer(
|
||||
{`'[a-zA-Z_]\w*`, NameAttribute, nil},
|
||||
{`[{}()\[\],.;]`, Punctuation, nil},
|
||||
{`[+\-*/%&|<>^!~@=:?]`, Operator, nil},
|
||||
{`[a-zA-Z_]\w*`, Name, nil},
|
||||
{`(r#)?[a-zA-Z_]\w*`, Name, nil},
|
||||
{`#!?\[`, CommentPreproc, Push("attribute[")},
|
||||
{`([A-Za-z_]\w*)(!)(\s*)([A-Za-z_]\w*)?(\s*)(\{)`, ByGroups(CommentPreproc, Punctuation, TextWhitespace, Name, TextWhitespace, Punctuation), Push("macro{")},
|
||||
{`([A-Za-z_]\w*)(!)(\s*)([A-Za-z_]\w*)?(\()`, ByGroups(CommentPreproc, Punctuation, TextWhitespace, Name, Punctuation), Push("macro(")},
|
||||
|
94
vendor/github.com/alecthomas/chroma/lexers/s/sas.go
generated
vendored
Normal file
94
vendor/github.com/alecthomas/chroma/lexers/s/sas.go
generated
vendored
Normal file
@ -0,0 +1,94 @@
|
||||
package s
|
||||
|
||||
import (
|
||||
. "github.com/alecthomas/chroma" // nolint
|
||||
"github.com/alecthomas/chroma/lexers/internal"
|
||||
)
|
||||
|
||||
// Sas lexer.
|
||||
var Sas = internal.Register(MustNewLexer(
|
||||
&Config{
|
||||
Name: "SAS",
|
||||
Aliases: []string{"sas"},
|
||||
Filenames: []string{"*.SAS", "*.sas"},
|
||||
MimeTypes: []string{"text/x-sas", "text/sas", "application/x-sas"},
|
||||
CaseInsensitive: true,
|
||||
},
|
||||
Rules{
|
||||
"root": {
|
||||
Include("comments"),
|
||||
Include("proc-data"),
|
||||
Include("cards-datalines"),
|
||||
Include("logs"),
|
||||
Include("general"),
|
||||
{`.`, Text, nil},
|
||||
{`\\\n`, Text, nil},
|
||||
{`\n`, Text, nil},
|
||||
},
|
||||
"comments": {
|
||||
{`^\s*\*.*?;`, Comment, nil},
|
||||
{`/\*.*?\*/`, Comment, nil},
|
||||
{`^\s*\*(.|\n)*?;`, CommentMultiline, nil},
|
||||
{`/[*](.|\n)*?[*]/`, CommentMultiline, nil},
|
||||
},
|
||||
"proc-data": {
|
||||
{`(^|;)\s*(proc \w+|data|run|quit)[\s;]`, KeywordReserved, nil},
|
||||
},
|
||||
"cards-datalines": {
|
||||
{`^\s*(datalines|cards)\s*;\s*$`, Keyword, Push("data")},
|
||||
},
|
||||
"data": {
|
||||
{`(.|\n)*^\s*;\s*$`, Other, Pop(1)},
|
||||
},
|
||||
"logs": {
|
||||
{`\n?^\s*%?put `, Keyword, Push("log-messages")},
|
||||
},
|
||||
"log-messages": {
|
||||
{`NOTE(:|-).*`, Generic, Pop(1)},
|
||||
{`WARNING(:|-).*`, GenericEmph, Pop(1)},
|
||||
{`ERROR(:|-).*`, GenericError, Pop(1)},
|
||||
Include("general"),
|
||||
},
|
||||
"general": {
|
||||
Include("keywords"),
|
||||
Include("vars-strings"),
|
||||
Include("special"),
|
||||
Include("numbers"),
|
||||
},
|
||||
"keywords": {
|
||||
{Words(`\b`, `\b`, `abort`, `array`, `attrib`, `by`, `call`, `cards`, `cards4`, `catname`, `continue`, `datalines`, `datalines4`, `delete`, `delim`, `delimiter`, `display`, `dm`, `drop`, `endsas`, `error`, `file`, `filename`, `footnote`, `format`, `goto`, `in`, `infile`, `informat`, `input`, `keep`, `label`, `leave`, `length`, `libname`, `link`, `list`, `lostcard`, `merge`, `missing`, `modify`, `options`, `output`, `out`, `page`, `put`, `redirect`, `remove`, `rename`, `replace`, `retain`, `return`, `select`, `set`, `skip`, `startsas`, `stop`, `title`, `update`, `waitsas`, `where`, `window`, `x`, `systask`), Keyword, nil},
|
||||
{Words(`\b`, `\b`, `add`, `and`, `alter`, `as`, `cascade`, `check`, `create`, `delete`, `describe`, `distinct`, `drop`, `foreign`, `from`, `group`, `having`, `index`, `insert`, `into`, `in`, `key`, `like`, `message`, `modify`, `msgtype`, `not`, `null`, `on`, `or`, `order`, `primary`, `references`, `reset`, `restrict`, `select`, `set`, `table`, `unique`, `update`, `validate`, `view`, `where`), Keyword, nil},
|
||||
{Words(`\b`, `\b`, `do`, `if`, `then`, `else`, `end`, `until`, `while`), Keyword, nil},
|
||||
{Words(`%`, `\b`, `bquote`, `nrbquote`, `cmpres`, `qcmpres`, `compstor`, `datatyp`, `display`, `do`, `else`, `end`, `eval`, `global`, `goto`, `if`, `index`, `input`, `keydef`, `label`, `left`, `length`, `let`, `local`, `lowcase`, `macro`, `mend`, `nrquote`, `nrstr`, `put`, `qleft`, `qlowcase`, `qscan`, `qsubstr`, `qsysfunc`, `qtrim`, `quote`, `qupcase`, `scan`, `str`, `substr`, `superq`, `syscall`, `sysevalf`, `sysexec`, `sysfunc`, `sysget`, `syslput`, `sysprod`, `sysrc`, `sysrput`, `then`, `to`, `trim`, `unquote`, `until`, `upcase`, `verify`, `while`, `window`), NameBuiltin, nil},
|
||||
{Words(`\b`, `\(`, `abs`, `addr`, `airy`, `arcos`, `arsin`, `atan`, `attrc`, `attrn`, `band`, `betainv`, `blshift`, `bnot`, `bor`, `brshift`, `bxor`, `byte`, `cdf`, `ceil`, `cexist`, `cinv`, `close`, `cnonct`, `collate`, `compbl`, `compound`, `compress`, `cos`, `cosh`, `css`, `curobs`, `cv`, `daccdb`, `daccdbsl`, `daccsl`, `daccsyd`, `dacctab`, `dairy`, `date`, `datejul`, `datepart`, `datetime`, `day`, `dclose`, `depdb`, `depdbsl`, `depsl`, `depsyd`, `deptab`, `dequote`, `dhms`, `dif`, `digamma`, `dim`, `dinfo`, `dnum`, `dopen`, `doptname`, `doptnum`, `dread`, `dropnote`, `dsname`, `erf`, `erfc`, `exist`, `exp`, `fappend`, `fclose`, `fcol`, `fdelete`, `fetch`, `fetchobs`, `fexist`, `fget`, `fileexist`, `filename`, `fileref`, `finfo`, `finv`, `fipname`, `fipnamel`, `fipstate`, `floor`, `fnonct`, `fnote`, `fopen`, `foptname`, `foptnum`, `fpoint`, `fpos`, `fput`, `fread`, `frewind`, `frlen`, `fsep`, `fuzz`, `fwrite`, `gaminv`, `gamma`, `getoption`, `getvarc`, `getvarn`, `hbound`, `hms`, `hosthelp`, `hour`, `ibessel`, `index`, `indexc`, `indexw`, `input`, `inputc`, `inputn`, `int`, `intck`, `intnx`, `intrr`, `irr`, `jbessel`, `juldate`, `kurtosis`, `lag`, `lbound`, `left`, `length`, `lgamma`, `libname`, `libref`, `log`, `log10`, `log2`, `logpdf`, `logpmf`, `logsdf`, `lowcase`, `max`, `mdy`, `mean`, `min`, `minute`, `mod`, `month`, `mopen`, `mort`, `n`, `netpv`, `nmiss`, `normal`, `note`, `npv`, `open`, `ordinal`, `pathname`, `pdf`, `peek`, `peekc`, `pmf`, `point`, `poisson`, `poke`, `probbeta`, `probbnml`, `probchi`, `probf`, `probgam`, `probhypr`, `probit`, `probnegb`, `probnorm`, `probt`, `put`, `putc`, `putn`, `qtr`, `quote`, `ranbin`, `rancau`, `ranexp`, `rangam`, `range`, `rank`, `rannor`, `ranpoi`, `rantbl`, `rantri`, `ranuni`, `repeat`, `resolve`, `reverse`, `rewind`, `right`, `round`, `saving`, `scan`, `sdf`, `second`, `sign`, `sin`, `sinh`, `skewness`, `soundex`, `spedis`, `sqrt`, `std`, `stderr`, `stfips`, `stname`, `stnamel`, `substr`, `sum`, `symget`, `sysget`, `sysmsg`, `sysprod`, `sysrc`, `system`, `tan`, `tanh`, `time`, `timepart`, `tinv`, `tnonct`, `today`, `translate`, `tranwrd`, `trigamma`, `trim`, `trimn`, `trunc`, `uniform`, `upcase`, `uss`, `var`, `varfmt`, `varinfmt`, `varlabel`, `varlen`, `varname`, `varnum`, `varray`, `varrayx`, `vartype`, `verify`, `vformat`, `vformatd`, `vformatdx`, `vformatn`, `vformatnx`, `vformatw`, `vformatwx`, `vformatx`, `vinarray`, `vinarrayx`, `vinformat`, `vinformatd`, `vinformatdx`, `vinformatn`, `vinformatnx`, `vinformatw`, `vinformatwx`, `vinformatx`, `vlabel`, `vlabelx`, `vlength`, `vlengthx`, `vname`, `vnamex`, `vtype`, `vtypex`, `weekday`, `year`, `yyq`, `zipfips`, `zipname`, `zipnamel`, `zipstate`), NameBuiltin, nil},
|
||||
},
|
||||
"vars-strings": {
|
||||
{`&[a-z_]\w{0,31}\.?`, NameVariable, nil},
|
||||
{`%[a-z_]\w{0,31}`, NameFunction, nil},
|
||||
{`\'`, LiteralString, Push("string_squote")},
|
||||
{`"`, LiteralString, Push("string_dquote")},
|
||||
},
|
||||
"string_squote": {
|
||||
{`'`, LiteralString, Pop(1)},
|
||||
{`\\\\|\\"|\\\n`, LiteralStringEscape, nil},
|
||||
{`[^$\'\\]+`, LiteralString, nil},
|
||||
{`[$\'\\]`, LiteralString, nil},
|
||||
},
|
||||
"string_dquote": {
|
||||
{`"`, LiteralString, Pop(1)},
|
||||
{`\\\\|\\"|\\\n`, LiteralStringEscape, nil},
|
||||
{`&`, NameVariable, Push("validvar")},
|
||||
{`[^$&"\\]+`, LiteralString, nil},
|
||||
{`[$"\\]`, LiteralString, nil},
|
||||
},
|
||||
"validvar": {
|
||||
{`[a-z_]\w{0,31}\.?`, NameVariable, Pop(1)},
|
||||
},
|
||||
"numbers": {
|
||||
{`\b[+-]?([0-9]+(\.[0-9]+)?|\.[0-9]+|\.)(E[+-]?[0-9]+)?i?\b`, LiteralNumber, nil},
|
||||
},
|
||||
"special": {
|
||||
{`(null|missing|_all_|_automatic_|_character_|_n_|_infile_|_name_|_null_|_numeric_|_user_|_webout_)`, KeywordConstant, nil},
|
||||
},
|
||||
},
|
||||
))
|
200
vendor/github.com/alecthomas/chroma/lexers/s/sml.go
generated
vendored
Normal file
200
vendor/github.com/alecthomas/chroma/lexers/s/sml.go
generated
vendored
Normal file
@ -0,0 +1,200 @@
|
||||
package s
|
||||
|
||||
import (
|
||||
. "github.com/alecthomas/chroma" // nolint
|
||||
"github.com/alecthomas/chroma/lexers/internal"
|
||||
)
|
||||
|
||||
// Standard ML lexer.
|
||||
var StandardML = internal.Register(MustNewLexer(
|
||||
&Config{
|
||||
Name: "Standard ML",
|
||||
Aliases: []string{"sml"},
|
||||
Filenames: []string{"*.sml", "*.sig", "*.fun"},
|
||||
MimeTypes: []string{"text/x-standardml", "application/x-standardml"},
|
||||
},
|
||||
Rules{
|
||||
"whitespace": {
|
||||
{`\s+`, Text, nil},
|
||||
{`\(\*`, CommentMultiline, Push("comment")},
|
||||
},
|
||||
"delimiters": {
|
||||
{`\(|\[|\{`, Punctuation, Push("main")},
|
||||
{`\)|\]|\}`, Punctuation, Pop(1)},
|
||||
{`\b(let|if|local)\b(?!\')`, KeywordReserved, Push("main", "main")},
|
||||
{`\b(struct|sig|while)\b(?!\')`, KeywordReserved, Push("main")},
|
||||
{`\b(do|else|end|in|then)\b(?!\')`, KeywordReserved, Pop(1)},
|
||||
},
|
||||
"core": {
|
||||
{`(_|\}|\{|\)|;|,|\[|\(|\]|\.\.\.)`, Punctuation, nil},
|
||||
{`#"`, LiteralStringChar, Push("char")},
|
||||
{`"`, LiteralStringDouble, Push("string")},
|
||||
{`~?0x[0-9a-fA-F]+`, LiteralNumberHex, nil},
|
||||
{`0wx[0-9a-fA-F]+`, LiteralNumberHex, nil},
|
||||
{`0w\d+`, LiteralNumberInteger, nil},
|
||||
{`~?\d+\.\d+[eE]~?\d+`, LiteralNumberFloat, nil},
|
||||
{`~?\d+\.\d+`, LiteralNumberFloat, nil},
|
||||
{`~?\d+[eE]~?\d+`, LiteralNumberFloat, nil},
|
||||
{`~?\d+`, LiteralNumberInteger, nil},
|
||||
{`#\s*[1-9][0-9]*`, NameLabel, nil},
|
||||
{`#\s*([a-zA-Z][\w']*)`, NameLabel, nil},
|
||||
{"#\\s+([!%&$#+\\-/:<=>?@\\\\~`^|*]+)", NameLabel, nil},
|
||||
{`\b(datatype|abstype)\b(?!\')`, KeywordReserved, Push("dname")},
|
||||
{`(?=\b(exception)\b(?!\'))`, Text, Push("ename")},
|
||||
{`\b(functor|include|open|signature|structure)\b(?!\')`, KeywordReserved, Push("sname")},
|
||||
{`\b(type|eqtype)\b(?!\')`, KeywordReserved, Push("tname")},
|
||||
{`\'[\w\']*`, NameDecorator, nil},
|
||||
{`([a-zA-Z][\w']*)(\.)`, NameNamespace, Push("dotted")},
|
||||
{`\b(abstype|and|andalso|as|case|datatype|do|else|end|exception|fn|fun|handle|if|in|infix|infixr|let|local|nonfix|of|op|open|orelse|raise|rec|then|type|val|with|withtype|while|eqtype|functor|include|sharing|sig|signature|struct|structure|where)\b`, KeywordReserved, nil},
|
||||
{`([a-zA-Z][\w']*)`, Name, nil},
|
||||
{`\b(:|\|,=|=>|->|#|:>)\b`, KeywordReserved, nil},
|
||||
{"([!%&$#+\\-/:<=>?@\\\\~`^|*]+)", Name, nil},
|
||||
},
|
||||
"dotted": {
|
||||
{`([a-zA-Z][\w']*)(\.)`, NameNamespace, nil},
|
||||
// ignoring reserved words
|
||||
{`([a-zA-Z][\w']*)`, Name, Pop(1)},
|
||||
// ignoring reserved words
|
||||
{"([!%&$#+\\-/:<=>?@\\\\~`^|*]+)", Name, Pop(1)},
|
||||
{`\s+`, Error, nil},
|
||||
{`\S+`, Error, nil},
|
||||
},
|
||||
"root": {
|
||||
Default(Push("main")),
|
||||
},
|
||||
"main": {
|
||||
Include("whitespace"),
|
||||
{`\b(val|and)\b(?!\')`, KeywordReserved, Push("vname")},
|
||||
{`\b(fun)\b(?!\')`, KeywordReserved, Push("#pop", "main-fun", "fname")},
|
||||
Include("delimiters"),
|
||||
Include("core"),
|
||||
{`\S+`, Error, nil},
|
||||
},
|
||||
"main-fun": {
|
||||
Include("whitespace"),
|
||||
{`\s`, Text, nil},
|
||||
{`\(\*`, CommentMultiline, Push("comment")},
|
||||
{`\b(fun|and)\b(?!\')`, KeywordReserved, Push("fname")},
|
||||
{`\b(val)\b(?!\')`, KeywordReserved, Push("#pop", "main", "vname")},
|
||||
{`\|`, Punctuation, Push("fname")},
|
||||
{`\b(case|handle)\b(?!\')`, KeywordReserved, Push("#pop", "main")},
|
||||
Include("delimiters"),
|
||||
Include("core"),
|
||||
{`\S+`, Error, nil},
|
||||
},
|
||||
"char": {
|
||||
{`[^"\\]`, LiteralStringChar, nil},
|
||||
{`\\[\\"abtnvfr]`, LiteralStringEscape, nil},
|
||||
{`\\\^[\x40-\x5e]`, LiteralStringEscape, nil},
|
||||
{`\\[0-9]{3}`, LiteralStringEscape, nil},
|
||||
{`\\u[0-9a-fA-F]{4}`, LiteralStringEscape, nil},
|
||||
{`\\\s+\\`, LiteralStringInterpol, nil},
|
||||
{`"`, LiteralStringChar, Pop(1)},
|
||||
},
|
||||
"string": {
|
||||
{`[^"\\]`, LiteralStringDouble, nil},
|
||||
{`\\[\\"abtnvfr]`, LiteralStringEscape, nil},
|
||||
{`\\\^[\x40-\x5e]`, LiteralStringEscape, nil},
|
||||
{`\\[0-9]{3}`, LiteralStringEscape, nil},
|
||||
{`\\u[0-9a-fA-F]{4}`, LiteralStringEscape, nil},
|
||||
{`\\\s+\\`, LiteralStringInterpol, nil},
|
||||
{`"`, LiteralStringDouble, Pop(1)},
|
||||
},
|
||||
"breakout": {
|
||||
{`(?=\b(where|do|handle|if|sig|op|while|case|as|else|signature|andalso|struct|infixr|functor|in|structure|then|local|rec|end|fun|of|orelse|val|include|fn|with|exception|let|and|infix|sharing|datatype|type|abstype|withtype|eqtype|nonfix|raise|open)\b(?!\'))`, Text, Pop(1)},
|
||||
},
|
||||
"sname": {
|
||||
Include("whitespace"),
|
||||
Include("breakout"),
|
||||
{`([a-zA-Z][\w']*)`, NameNamespace, nil},
|
||||
Default(Pop(1)),
|
||||
},
|
||||
"fname": {
|
||||
Include("whitespace"),
|
||||
{`\'[\w\']*`, NameDecorator, nil},
|
||||
{`\(`, Punctuation, Push("tyvarseq")},
|
||||
{`([a-zA-Z][\w']*)`, NameFunction, Pop(1)},
|
||||
{"([!%&$#+\\-/:<=>?@\\\\~`^|*]+)", NameFunction, Pop(1)},
|
||||
Default(Pop(1)),
|
||||
},
|
||||
"vname": {
|
||||
Include("whitespace"),
|
||||
{`\'[\w\']*`, NameDecorator, nil},
|
||||
{`\(`, Punctuation, Push("tyvarseq")},
|
||||
{"([a-zA-Z][\\w']*)(\\s*)(=(?![!%&$#+\\-/:<=>?@\\\\~`^|*]+))", ByGroups(NameVariable, Text, Punctuation), Pop(1)},
|
||||
{"([!%&$#+\\-/:<=>?@\\\\~`^|*]+)(\\s*)(=(?![!%&$#+\\-/:<=>?@\\\\~`^|*]+))", ByGroups(NameVariable, Text, Punctuation), Pop(1)},
|
||||
{`([a-zA-Z][\w']*)`, NameVariable, Pop(1)},
|
||||
{"([!%&$#+\\-/:<=>?@\\\\~`^|*]+)", NameVariable, Pop(1)},
|
||||
Default(Pop(1)),
|
||||
},
|
||||
"tname": {
|
||||
Include("whitespace"),
|
||||
Include("breakout"),
|
||||
{`\'[\w\']*`, NameDecorator, nil},
|
||||
{`\(`, Punctuation, Push("tyvarseq")},
|
||||
{"=(?![!%&$#+\\-/:<=>?@\\\\~`^|*]+)", Punctuation, Push("#pop", "typbind")},
|
||||
{`([a-zA-Z][\w']*)`, KeywordType, nil},
|
||||
{"([!%&$#+\\-/:<=>?@\\\\~`^|*]+)", KeywordType, nil},
|
||||
{`\S+`, Error, Pop(1)},
|
||||
},
|
||||
"typbind": {
|
||||
Include("whitespace"),
|
||||
{`\b(and)\b(?!\')`, KeywordReserved, Push("#pop", "tname")},
|
||||
Include("breakout"),
|
||||
Include("core"),
|
||||
{`\S+`, Error, Pop(1)},
|
||||
},
|
||||
"dname": {
|
||||
Include("whitespace"),
|
||||
Include("breakout"),
|
||||
{`\'[\w\']*`, NameDecorator, nil},
|
||||
{`\(`, Punctuation, Push("tyvarseq")},
|
||||
{`(=)(\s*)(datatype)`, ByGroups(Punctuation, Text, KeywordReserved), Pop(1)},
|
||||
{"=(?![!%&$#+\\-/:<=>?@\\\\~`^|*]+)", Punctuation, Push("#pop", "datbind", "datcon")},
|
||||
{`([a-zA-Z][\w']*)`, KeywordType, nil},
|
||||
{"([!%&$#+\\-/:<=>?@\\\\~`^|*]+)", KeywordType, nil},
|
||||
{`\S+`, Error, Pop(1)},
|
||||
},
|
||||
"datbind": {
|
||||
Include("whitespace"),
|
||||
{`\b(and)\b(?!\')`, KeywordReserved, Push("#pop", "dname")},
|
||||
{`\b(withtype)\b(?!\')`, KeywordReserved, Push("#pop", "tname")},
|
||||
{`\b(of)\b(?!\')`, KeywordReserved, nil},
|
||||
{`(\|)(\s*)([a-zA-Z][\w']*)`, ByGroups(Punctuation, Text, NameClass), nil},
|
||||
{"(\\|)(\\s+)([!%&$#+\\-/:<=>?@\\\\~`^|*]+)", ByGroups(Punctuation, Text, NameClass), nil},
|
||||
Include("breakout"),
|
||||
Include("core"),
|
||||
{`\S+`, Error, nil},
|
||||
},
|
||||
"ename": {
|
||||
Include("whitespace"),
|
||||
{`(exception|and)\b(\s+)([a-zA-Z][\w']*)`, ByGroups(KeywordReserved, Text, NameClass), nil},
|
||||
{"(exception|and)\\b(\\s*)([!%&$#+\\-/:<=>?@\\\\~`^|*]+)", ByGroups(KeywordReserved, Text, NameClass), nil},
|
||||
{`\b(of)\b(?!\')`, KeywordReserved, nil},
|
||||
Include("breakout"),
|
||||
Include("core"),
|
||||
{`\S+`, Error, nil},
|
||||
},
|
||||
"datcon": {
|
||||
Include("whitespace"),
|
||||
{`([a-zA-Z][\w']*)`, NameClass, Pop(1)},
|
||||
{"([!%&$#+\\-/:<=>?@\\\\~`^|*]+)", NameClass, Pop(1)},
|
||||
{`\S+`, Error, Pop(1)},
|
||||
},
|
||||
"tyvarseq": {
|
||||
{`\s`, Text, nil},
|
||||
{`\(\*`, CommentMultiline, Push("comment")},
|
||||
{`\'[\w\']*`, NameDecorator, nil},
|
||||
{`[a-zA-Z][\w']*`, Name, nil},
|
||||
{`,`, Punctuation, nil},
|
||||
{`\)`, Punctuation, Pop(1)},
|
||||
{"[!%&$#+\\-/:<=>?@\\\\~`^|*]+", Name, nil},
|
||||
},
|
||||
"comment": {
|
||||
{`[^(*)]`, CommentMultiline, nil},
|
||||
{`\(\*`, CommentMultiline, Push()},
|
||||
{`\*\)`, CommentMultiline, Pop(1)},
|
||||
{`[(*)]`, CommentMultiline, nil},
|
||||
},
|
||||
},
|
||||
))
|
2
vendor/github.com/alecthomas/chroma/lexers/s/sql.go
generated
vendored
2
vendor/github.com/alecthomas/chroma/lexers/s/sql.go
generated
vendored
File diff suppressed because one or more lines are too long
42
vendor/github.com/alecthomas/chroma/lexers/t/tablegen.go
generated
vendored
Normal file
42
vendor/github.com/alecthomas/chroma/lexers/t/tablegen.go
generated
vendored
Normal file
@ -0,0 +1,42 @@
|
||||
package t
|
||||
|
||||
import (
|
||||
. "github.com/alecthomas/chroma" // nolint
|
||||
"github.com/alecthomas/chroma/lexers/internal"
|
||||
)
|
||||
|
||||
// TableGen lexer.
|
||||
var Tablegen = internal.Register(MustNewLexer(
|
||||
&Config{
|
||||
Name: "TableGen",
|
||||
Aliases: []string{"tablegen"},
|
||||
Filenames: []string{"*.td"},
|
||||
MimeTypes: []string{"text/x-tablegen"},
|
||||
},
|
||||
Rules{
|
||||
"root": {
|
||||
Include("macro"),
|
||||
Include("whitespace"),
|
||||
{`c?"[^"]*?"`, LiteralString, nil},
|
||||
Include("keyword"),
|
||||
{`\$[_a-zA-Z][_\w]*`, NameVariable, nil},
|
||||
{`\d*[_a-zA-Z][_\w]*`, NameVariable, nil},
|
||||
{`\[\{[\w\W]*?\}\]`, LiteralString, nil},
|
||||
{`[+-]?\d+|0x[\da-fA-F]+|0b[01]+`, LiteralNumber, nil},
|
||||
{`[=<>{}\[\]()*.,!:;]`, Punctuation, nil},
|
||||
},
|
||||
"macro": {
|
||||
{`(#include\s+)("[^"]*")`, ByGroups(CommentPreproc, LiteralString), nil},
|
||||
{`^\s*#(ifdef|ifndef)\s+[_\w][_\w\d]*`, CommentPreproc, nil},
|
||||
{`^\s*#define\s+[_\w][_\w\d]*`, CommentPreproc, nil},
|
||||
{`^\s*#endif`, CommentPreproc, nil},
|
||||
},
|
||||
"whitespace": {
|
||||
{`(\n|\s)+`, Text, nil},
|
||||
{`//.*?\n`, Comment, nil},
|
||||
},
|
||||
"keyword": {
|
||||
{Words(``, `\b`, `bit`, `bits`, `class`, `code`, `dag`, `def`, `defm`, `field`, `foreach`, `in`, `int`, `let`, `list`, `multiclass`, `string`), Keyword, nil},
|
||||
},
|
||||
},
|
||||
))
|
81
vendor/github.com/alecthomas/chroma/lexers/t/terraform.go
generated
vendored
81
vendor/github.com/alecthomas/chroma/lexers/t/terraform.go
generated
vendored
@ -15,55 +15,46 @@ var Terraform = internal.Register(MustNewLexer(
|
||||
},
|
||||
Rules{
|
||||
"root": {
|
||||
Include("string"),
|
||||
Include("punctuation"),
|
||||
Include("curly"),
|
||||
Include("basic"),
|
||||
Include("whitespace"),
|
||||
{`[0-9]+`, LiteralNumber, nil},
|
||||
{`[\[\](),.{}]`, Punctuation, nil},
|
||||
{`-?[0-9]+`, LiteralNumber, nil},
|
||||
{`=>`, Punctuation, nil},
|
||||
{Words(``, `\b`, `true`, `false`), KeywordConstant, nil},
|
||||
{`/(?s)\*(((?!\*/).)*)\*/`, CommentMultiline, nil},
|
||||
{`\s*(#|//).*\n`, CommentSingle, nil},
|
||||
{`([a-zA-Z]\w*)(\s*)(=(?!>))`, ByGroups(NameAttribute, Text, Text), nil},
|
||||
{Words(`^\s*`, `\b`, `variable`, `data`, `resource`, `provider`, `provisioner`, `module`, `output`), KeywordReserved, nil},
|
||||
{Words(``, `\b`, `for`, `in`), Keyword, nil},
|
||||
{Words(``, ``, `count`, `data`, `var`, `module`, `each`), NameBuiltin, nil},
|
||||
{Words(``, `\b`, `abs`, `ceil`, `floor`, `log`, `max`, `min`, `parseint`, `pow`, `signum`), NameBuiltin, nil},
|
||||
{Words(``, `\b`, `chomp`, `format`, `formatlist`, `indent`, `join`, `lower`, `regex`, `regexall`, `replace`, `split`, `strrev`, `substr`, `title`, `trim`, `trimprefix`, `trimsuffix`, `trimspace`, `upper`), NameBuiltin, nil},
|
||||
{Words(`[^.]`, `\b`, `chunklist`, `coalesce`, `coalescelist`, `compact`, `concat`, `contains`, `distinct`, `element`, `flatten`, `index`, `keys`, `length`, `list`, `lookup`, `map`, `matchkeys`, `merge`, `range`, `reverse`, `setintersection`, `setproduct`, `setsubtract`, `setunion`, `slice`, `sort`, `transpose`, `values`, `zipmap`), NameBuiltin, nil},
|
||||
{Words(`[^.]`, `\b`, `base64decode`, `base64encode`, `base64gzip`, `csvdecode`, `jsondecode`, `jsonencode`, `urlencode`, `yamldecode`, `yamlencode`), NameBuiltin, nil},
|
||||
{Words(``, `\b`, `abspath`, `dirname`, `pathexpand`, `basename`, `file`, `fileexists`, `fileset`, `filebase64`, `templatefile`), NameBuiltin, nil},
|
||||
{Words(``, `\b`, `formatdate`, `timeadd`, `timestamp`), NameBuiltin, nil},
|
||||
{Words(``, `\b`, `base64sha256`, `base64sha512`, `bcrypt`, `filebase64sha256`, `filebase64sha512`, `filemd5`, `filesha1`, `filesha256`, `filesha512`, `md5`, `rsadecrypt`, `sha1`, `sha256`, `sha512`, `uuid`, `uuidv5`), NameBuiltin, nil},
|
||||
{Words(``, `\b`, `cidrhost`, `cidrnetmask`, `cidrsubnet`), NameBuiltin, nil},
|
||||
{Words(``, `\b`, `can`, `tobool`, `tolist`, `tomap`, `tonumber`, `toset`, `tostring`, `try`), NameBuiltin, nil},
|
||||
{`=(?!>)|\+|-|\*|\/|:|!|%|>|<(?!<)|>=|<=|==|!=|&&|\||\?`, Operator, nil},
|
||||
{`\n|\s+|\\\n`, Text, nil},
|
||||
{`[a-zA-Z]\w*`, NameOther, nil},
|
||||
{`"`, LiteralStringDouble, Push("string")},
|
||||
{`(?s)(<<-?)(\w+)(\n\s*(?:(?!\2).)*\s*\n\s*)(\2)`, ByGroups(Operator, Operator, String, Operator), nil},
|
||||
},
|
||||
"basic": {
|
||||
{Words(`\b`, `\b`, `true`, `false`), KeywordType, nil},
|
||||
{`\s*/\*`, CommentMultiline, Push("comment")},
|
||||
{`\s*#.*\n`, CommentSingle, nil},
|
||||
{`(.*?)(\s*)(=)`, ByGroups(NameAttribute, Text, Operator), nil},
|
||||
{Words(`\b`, `\b`, `variable`, `resource`, `provider`, `provisioner`, `module`), KeywordReserved, Push("function")},
|
||||
{Words(`\b`, `\b`, `ingress`, `egress`, `listener`, `default`, `connection`, `alias`), KeywordDeclaration, nil},
|
||||
{`\$\{`, LiteralStringInterpol, Push("var_builtin")},
|
||||
},
|
||||
"function": {
|
||||
{`(\s+)(".*")(\s+)`, ByGroups(Text, LiteralString, Text), nil},
|
||||
Include("punctuation"),
|
||||
Include("curly"),
|
||||
},
|
||||
"var_builtin": {
|
||||
{`\$\{`, LiteralStringInterpol, Push()},
|
||||
{Words(`\b`, `\b`, `concat`, `file`, `join`, `lookup`, `element`), NameBuiltin, nil},
|
||||
Include("string"),
|
||||
Include("punctuation"),
|
||||
{`\s+`, Text, nil},
|
||||
{`\}`, LiteralStringInterpol, Pop(1)},
|
||||
"declaration": {
|
||||
{`(\s*)("(?:\\\\|\\"|[^"])*")(\s*)`, ByGroups(Text, NameVariable, Text), nil},
|
||||
{`\{`, Punctuation, Pop(1)},
|
||||
},
|
||||
"string": {
|
||||
{`(".*")`, ByGroups(LiteralStringDouble), nil},
|
||||
{`"`, LiteralStringDouble, Pop(1)},
|
||||
{`\\\\`, LiteralStringDouble, nil},
|
||||
{`\\\\"`, LiteralStringDouble, nil},
|
||||
{`\$\{`, LiteralStringInterpol, Push("interp-inside")},
|
||||
{`\$`, LiteralStringDouble, nil},
|
||||
{`[^"\\\\$]+`, LiteralStringDouble, nil},
|
||||
},
|
||||
"punctuation": {
|
||||
{`[\[\](),.]`, Punctuation, nil},
|
||||
},
|
||||
"curly": {
|
||||
{`\{`, TextPunctuation, nil},
|
||||
{`\}`, TextPunctuation, nil},
|
||||
},
|
||||
"comment": {
|
||||
{`[^*/]`, CommentMultiline, nil},
|
||||
{`/\*`, CommentMultiline, Push()},
|
||||
{`\*/`, CommentMultiline, Pop(1)},
|
||||
{`[*/]`, CommentMultiline, nil},
|
||||
},
|
||||
"whitespace": {
|
||||
{`\n`, Text, nil},
|
||||
{`\s+`, Text, nil},
|
||||
{`\\\n`, Text, nil},
|
||||
"interp-inside": {
|
||||
{`\}`, LiteralStringInterpol, Pop(1)},
|
||||
Include("root"),
|
||||
},
|
||||
},
|
||||
))
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user