mirror of
https://github.com/cloudflare/cloudflared.git
synced 2026-08-07 23:31:56 +00:00
Compare commits
28 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 607dcff697 | |||
| 1d1cf6a827 | |||
| 61f3fab757 | |||
| e2ff7f65fc | |||
| da0792a321 | |||
| fa061ab54e | |||
| 197d65659a | |||
| 85d0afd3b0 | |||
| 20623255dd | |||
| afa5e68fe5 | |||
| 747427f816 | |||
| f99b6c6421 | |||
| 250bc54110 | |||
| bb530b87dd | |||
| 02587c1edc | |||
| 26fc20d406 | |||
| 8a829b773a | |||
| 71b98e6111 | |||
| fee13dc62f | |||
| 094e0c7592 | |||
| b57a953caa | |||
| d8ebde37ca | |||
| 0708a49848 | |||
| b26f3082e6 | |||
| cb6d424765 | |||
| 5753aa9f18 | |||
| bfae12008d | |||
| c52e0dc8ef |
@@ -5,6 +5,7 @@ guide/public
|
||||
/.GOPATH
|
||||
/bin
|
||||
.idea
|
||||
.build
|
||||
.vscode
|
||||
\#*\#
|
||||
cscope.*
|
||||
@@ -12,6 +13,7 @@ cloudflared
|
||||
cloudflared.pkg
|
||||
cloudflared.exe
|
||||
cloudflared.msi
|
||||
cloudflared-x86-64*
|
||||
!cmd/cloudflared/
|
||||
.DS_Store
|
||||
*-session.log
|
||||
|
||||
Vendored
+12
-14
@@ -1,7 +1,5 @@
|
||||
#!/bin/bash
|
||||
|
||||
#set -euo pipefail
|
||||
|
||||
if [[ "$(uname)" != "Darwin" ]] ; then
|
||||
echo "This should be run on macOS"
|
||||
exit 1
|
||||
@@ -31,8 +29,8 @@ cd ../src/github.com/cloudflare/cloudflared
|
||||
GOCACHE="$PWD/../../../../" GOPATH="$PWD/../../../../" CGO_ENABLED=1 make cloudflared
|
||||
|
||||
# Add code signing private key to the key chain
|
||||
if [[ -n "${CFD_CODE_SIGN_KEY:-}" ]]; then
|
||||
if [[ -n "${CFD_CODE_SIGN_PASS:-}" ]]; then
|
||||
if [[ ! -z "$CFD_CODE_SIGN_KEY" ]]; then
|
||||
if [[ ! -z "$CFD_CODE_SIGN_PASS" ]]; then
|
||||
# write private key to disk and then import it keychain
|
||||
echo -n -e ${CFD_CODE_SIGN_KEY} | base64 -D > ${CODE_SIGN_PRIV}
|
||||
out=$(security import ${CODE_SIGN_PRIV} -A -P "${CFD_CODE_SIGN_PASS}" 2>&1)
|
||||
@@ -52,7 +50,7 @@ if [[ -n "${CFD_CODE_SIGN_KEY:-}" ]]; then
|
||||
fi
|
||||
|
||||
# Add code signing certificate to the key chain
|
||||
if [[ -n "${CFD_CODE_SIGN_CERT:-}" ]]; then
|
||||
if [[ ! -z "$CFD_CODE_SIGN_CERT" ]]; then
|
||||
# write certificate to disk and then import it keychain
|
||||
echo -n -e ${CFD_CODE_SIGN_CERT} | base64 -D > ${CODE_SIGN_CERT}
|
||||
out1=$(security import ${CODE_SIGN_CERT} -A 2>&1)
|
||||
@@ -73,8 +71,8 @@ if [[ -n "${CFD_CODE_SIGN_CERT:-}" ]]; then
|
||||
fi
|
||||
|
||||
# Add package signing private key to the key chain
|
||||
if [[ -n "${CFD_INSTALLER_KEY:-}" ]]; then
|
||||
if [[ -n "${CFD_INSTALLER_PASS:-}" ]]; then
|
||||
if [[ ! -z "$CFD_INSTALLER_KEY" ]]; then
|
||||
if [[ ! -z "$CFD_INSTALLER_PASS" ]]; then
|
||||
# write private key to disk and then import it into the keychain
|
||||
echo -n -e ${CFD_INSTALLER_KEY} | base64 -D > ${INSTALLER_PRIV}
|
||||
out2=$(security import ${INSTALLER_PRIV} -A -P "${CFD_INSTALLER_PASS}" 2>&1)
|
||||
@@ -94,7 +92,7 @@ if [[ -n "${CFD_INSTALLER_KEY:-}" ]]; then
|
||||
fi
|
||||
|
||||
# Add package signing certificate to the key chain
|
||||
if [[ -n "${CFD_INSTALLER_CERT:-}" ]]; then
|
||||
if [[ ! -z "$CFD_INSTALLER_CERT" ]]; then
|
||||
# write certificate to disk and then import it keychain
|
||||
echo -n -e ${CFD_INSTALLER_CERT} | base64 -D > ${INSTALLER_CERT}
|
||||
out3=$(security import ${INSTALLER_CERT} -A 2>&1)
|
||||
@@ -115,7 +113,7 @@ if [[ -n "${CFD_INSTALLER_CERT:-}" ]]; then
|
||||
fi
|
||||
|
||||
# get the code signing certificate name
|
||||
if [[ -n "${CFD_CODE_SIGN_NAME:-}" ]]; then
|
||||
if [[ ! -z "$CFD_CODE_SIGN_NAME" ]]; then
|
||||
CODE_SIGN_NAME="${CFD_CODE_SIGN_NAME}"
|
||||
else
|
||||
if [[ -n "$(security find-certificate -c "Developer ID Application" | cut -d'"' -f 4 -s | grep "Developer ID Application:" | head -1)" ]]; then
|
||||
@@ -126,7 +124,7 @@ else
|
||||
fi
|
||||
|
||||
# get the package signing certificate name
|
||||
if [[ -n "${CFD_INSTALLER_NAME:-}" ]]; then
|
||||
if [[ ! -z "$CFD_INSTALLER_NAME" ]]; then
|
||||
PKG_SIGN_NAME="${CFD_INSTALLER_NAME}"
|
||||
else
|
||||
if [[ -n "$(security find-certificate -c "Developer ID Installer" | cut -d'"' -f 4 -s | grep "Developer ID Installer:" | head -1)" ]]; then
|
||||
@@ -137,11 +135,11 @@ else
|
||||
fi
|
||||
|
||||
# sign the cloudflared binary
|
||||
if [[ -n "${CODE_SIGN_NAME:-}" ]]; then
|
||||
if [[ ! -z "$CODE_SIGN_NAME" ]]; then
|
||||
codesign -s "${CODE_SIGN_NAME}" -f -v --timestamp --options runtime ${BINARY_NAME}
|
||||
|
||||
# notarize the binary
|
||||
if [[ -n "${CFD_NOTE_PASSWORD:-}" ]]; then
|
||||
if [[ ! -z "$CFD_NOTE_PASSWORD" ]]; then
|
||||
zip "${BINARY_NAME}.zip" ${BINARY_NAME}
|
||||
xcrun altool --notarize-app -f "${BINARY_NAME}.zip" -t osx -u ${CFD_NOTE_USERNAME} -p ${CFD_NOTE_PASSWORD} --primary-bundle-id ${BUNDLE_ID}
|
||||
fi
|
||||
@@ -161,7 +159,7 @@ cp ${BINARY_NAME} "${TARGET_DIRECTORY}/contents/${PRODUCT}"
|
||||
tar czf "$FILENAME" "${BINARY_NAME}"
|
||||
|
||||
# build the installer package
|
||||
if [[ -n "${PKG_SIGN_NAME:-}" ]]; then
|
||||
if [[ ! -z "$PKG_SIGN_NAME" ]]; then
|
||||
pkgbuild --identifier com.cloudflare.${PRODUCT} \
|
||||
--version ${VERSION} \
|
||||
--scripts ${TARGET_DIRECTORY}/scripts \
|
||||
@@ -171,7 +169,7 @@ if [[ -n "${PKG_SIGN_NAME:-}" ]]; then
|
||||
${PKGNAME}
|
||||
|
||||
# notarize the package
|
||||
if [[ -n "${CFD_NOTE_PASSWORD:-}" ]]; then
|
||||
if [[ ! -z "$CFD_NOTE_PASSWORD" ]]; then
|
||||
xcrun altool --notarize-app -f ${PKGNAME} -t osx -u ${CFD_NOTE_USERNAME} -p ${CFD_NOTE_PASSWORD} --primary-bundle-id ${BUNDLE_ID}
|
||||
xcrun stapler staple ${PKGNAME}
|
||||
fi
|
||||
|
||||
@@ -2,7 +2,7 @@ VERSION := $(shell git describe --tags --always --dirty="-dev" --match "[0
|
||||
DATE := $(shell date -u '+%Y-%m-%d-%H%M UTC')
|
||||
VERSION_FLAGS := -ldflags='-X "main.Version=$(VERSION)" -X "main.BuildTime=$(DATE)"'
|
||||
MSI_VERSION := $(shell git tag -l --sort=v:refname | grep "w" | tail -1 | cut -c2-)
|
||||
#MSI_VERSION expects the format of the tag to be: (wX.X.X). Starts with the w character to not break cfsetup.
|
||||
#MSI_VERSION expects the format of the tag to be: (wX.X.X). Starts with the w character to not break cfsetup.
|
||||
#e.g. w3.0.1 or w4.2.10. It trims off the w character when creating the MSI.
|
||||
|
||||
IMPORT_PATH := github.com/cloudflare/cloudflared
|
||||
@@ -44,6 +44,8 @@ else ifeq ($(LOCAL_OS),darwin)
|
||||
TARGET_OS ?= darwin
|
||||
else ifeq ($(LOCAL_OS),windows)
|
||||
TARGET_OS ?= windows
|
||||
else ifeq ($(LOCAL_OS),freebsd)
|
||||
TARGET_OS ?= freebsd
|
||||
else
|
||||
$(error This system's OS $(LOCAL_OS) isn't supported)
|
||||
endif
|
||||
@@ -125,6 +127,58 @@ cloudflared-darwin-amd64.tgz: cloudflared
|
||||
tar czf cloudflared-darwin-amd64.tgz cloudflared
|
||||
rm cloudflared
|
||||
|
||||
.PHONY: cloudflared-junos
|
||||
cloudflared-junos: cloudflared jetez-certificate.pem jetez-key.pem
|
||||
jetez --source . \
|
||||
-j jet.yaml \
|
||||
--key jetez-key.pem \
|
||||
--cert jetez-certificate.pem \
|
||||
--version $(VERSION)
|
||||
rm jetez-*.pem
|
||||
|
||||
jetez-certificate.pem:
|
||||
ifndef JETEZ_CERT
|
||||
$(error JETEZ_CERT not defined)
|
||||
endif
|
||||
@echo "Writing JetEZ certificate"
|
||||
@echo "$$JETEZ_CERT" > jetez-certificate.pem
|
||||
|
||||
jetez-key.pem:
|
||||
ifndef JETEZ_KEY
|
||||
$(error JETEZ_KEY not defined)
|
||||
endif
|
||||
@echo "Writing JetEZ key"
|
||||
@echo "$$JETEZ_KEY" > jetez-key.pem
|
||||
|
||||
.PHONY: publish-cloudflared-junos
|
||||
publish-cloudflared-junos: cloudflared-junos cloudflared-x86-64.latest.s3
|
||||
ifndef S3_ENDPOINT
|
||||
$(error S3_HOST not defined)
|
||||
endif
|
||||
ifndef S3_URI
|
||||
$(error S3_URI not defined)
|
||||
endif
|
||||
ifndef S3_ACCESS_KEY
|
||||
$(error S3_ACCESS_KEY not defined)
|
||||
endif
|
||||
ifndef S3_SECRET_KEY
|
||||
$(error S3_SECRET_KEY not defined)
|
||||
endif
|
||||
sha256sum cloudflared-x86-64-$(VERSION).tgz | awk '{printf $$1}' > cloudflared-x86-64-$(VERSION).tgz.shasum
|
||||
s4cmd --endpoint-url $(S3_ENDPOINT) --force --API-GrantRead=uri=http://acs.amazonaws.com/groups/global/AllUsers \
|
||||
put cloudflared-x86-64-$(VERSION).tgz $(S3_URI)/cloudflared-x86-64-$(VERSION).tgz
|
||||
s4cmd --endpoint-url $(S3_ENDPOINT) --force --API-GrantRead=uri=http://acs.amazonaws.com/groups/global/AllUsers \
|
||||
put cloudflared-x86-64-$(VERSION).tgz.shasum $(S3_URI)/cloudflared-x86-64-$(VERSION).tgz.shasum
|
||||
dpkg --compare-versions "$(VERSION)" gt "$(shell cat cloudflared-x86-64.latest.s3)" && \
|
||||
echo -n "$(VERSION)" > cloudflared-x86-64.latest && \
|
||||
s4cmd --endpoint-url $(S3_ENDPOINT) --force --API-GrantRead=uri=http://acs.amazonaws.com/groups/global/AllUsers \
|
||||
put cloudflared-x86-64.latest $(S3_URI)/cloudflared-x86-64.latest || \
|
||||
echo "Latest version not updated"
|
||||
|
||||
cloudflared-x86-64.latest.s3:
|
||||
s4cmd --endpoint-url $(S3_ENDPOINT) --force \
|
||||
get $(S3_URI)/cloudflared-x86-64.latest cloudflared-x86-64.latest.s3
|
||||
|
||||
.PHONY: homebrew-upload
|
||||
homebrew-upload: cloudflared-darwin-amd64.tgz
|
||||
aws s3 --endpoint-url $(S3_ENDPOINT) cp --acl public-read $$^ $(S3_URI)/cloudflared-$$(VERSION)-$1.tgz
|
||||
@@ -148,8 +202,8 @@ github-message:
|
||||
|
||||
.PHONY: github-mac-upload
|
||||
github-mac-upload:
|
||||
python3 github_release.py --path .artifacts/cloudflared-darwin-amd64.tgz --release-version $(VERSION) --name cloudflared-darwin-amd64.tgz
|
||||
python3 github_release.py --path .artifacts/cloudflared-amd64.pkg --release-version $(VERSION) --name cloudflared-amd64.pkg
|
||||
python3 github_release.py --path artifacts/cloudflared-darwin-amd64.tgz --release-version $(VERSION) --name cloudflared-darwin-amd64.tgz
|
||||
python3 github_release.py --path artifacts/cloudflared-amd64.pkg --release-version $(VERSION) --name cloudflared-amd64.pkg
|
||||
|
||||
bin/equinox:
|
||||
mkdir -p bin
|
||||
|
||||
@@ -1,3 +1,39 @@
|
||||
2020.9.3
|
||||
- 2020-09-22 TRAFFIC-448: build cloudflare for junos and publish to s3
|
||||
- 2020-09-22 TUN-3410: Request the v1 Tunnelstore API
|
||||
- 2020-09-23 Release 2020.9.2
|
||||
- 2020-09-17 updater service exit code should be 11
|
||||
- 2020-09-18 AUTH-3109 upload the checksum to workers kv on github releases
|
||||
|
||||
2020.9.2
|
||||
- 2020-09-22 TRAFFIC-448: build cloudflare for junos and publish to s3
|
||||
- 2020-09-22 TUN-3410: Request the v1 Tunnelstore API
|
||||
- 2020-09-17 AUTH-3103 CI build fixes
|
||||
- 2020-09-18 AUTH-3110-use-cfsetup-precache
|
||||
- 2020-09-17 TUN-3295: Show route command results
|
||||
- 2020-09-16 TUN-3291: cloudflared tunnel run -h explains how to use flags from parent command
|
||||
- 2020-09-18 AUTH-3109 upload the checksum to workers kv on github releases
|
||||
- 2020-09-17 updater service exit code should be 11
|
||||
- 2020-09-01 TUN-3216: UI improvements
|
||||
- 2020-08-25 Rebased and passed TunnelEventChan to LogServerInfo in new ReconnectTunnel function
|
||||
- 2020-08-25 TUN-3321: Add box around logs on UI
|
||||
- 2020-08-26 TUN-3328: Filter out free tunnel has started log from UI
|
||||
- 2020-08-27 TUN-3333: Add text to UI explaining how to exit
|
||||
- 2020-08-27 TUN-3335: Dynamically set connection table size for UI
|
||||
- 2020-08-10 TUN-3238: Update UI when connection re-connects
|
||||
- 2020-08-17 TUN-3261: Display connections on UI for free classic tunnels
|
||||
- 2020-07-24 TUN-3201: Create base cloudflared UI structure
|
||||
- 2020-07-29 TUN-3200: Add connection information to UI
|
||||
- 2020-07-24 TUN-3255: Update UI to display URL instead of hostname
|
||||
- 2020-07-29 TUN-3198: Handle errors while running tunnel UI
|
||||
|
||||
2020.9.1
|
||||
- 2020-09-14 TUN-3395: Unhide named tunnel subcommands, tweak help
|
||||
- 2020-09-15 TUN-3395: Improve help for list command
|
||||
- 2020-09-14 TUN-3294: Perform basic validation on arguments of route command; remove default pool name which wasn't valid
|
||||
- 2020-09-15 TUN-3395: Improve help for list command
|
||||
- 2020-09-16 Use Go 1.15.2
|
||||
|
||||
2020.9.0
|
||||
- 2020-09-11 TUN-3293: Try to use error information from the body of a failed tunnelstore reresponse if available
|
||||
- 2020-09-04 AUTH-2653 renabled signing
|
||||
|
||||
+47
-15
@@ -1,4 +1,4 @@
|
||||
pinned_go: &pinned_go go=1.14.7-1
|
||||
pinned_go: &pinned_go go=1.15.2-1
|
||||
build_dir: &build_dir /cfsetup_build
|
||||
default-flavor: stretch
|
||||
stretch: &stretch
|
||||
@@ -61,8 +61,9 @@ stretch: &stretch
|
||||
- build-essential
|
||||
- python3-setuptools
|
||||
- python3-pip
|
||||
post-cache:
|
||||
pre-cache: &install_pygithub
|
||||
- pip3 install pygithub
|
||||
post-cache:
|
||||
- export GOOS=linux
|
||||
- export GOARCH=amd64
|
||||
- make github-release
|
||||
@@ -85,8 +86,8 @@ stretch: &stretch
|
||||
- gcc-arm-linux-gnueabihf
|
||||
- python3-setuptools
|
||||
- python3-pip
|
||||
pre-cache: *install_pygithub
|
||||
post-cache:
|
||||
- pip3 install pygithub
|
||||
- export GOOS=linux
|
||||
- export GOARCH=arm
|
||||
- export CC=arm-linux-gnueabihf-gcc
|
||||
@@ -107,8 +108,8 @@ stretch: &stretch
|
||||
- gcc-multilib
|
||||
- python3-setuptools
|
||||
- python3-pip
|
||||
pre-cache: *install_pygithub
|
||||
post-cache:
|
||||
- pip3 install pygithub
|
||||
- export GOOS=linux
|
||||
- export GOARCH=386
|
||||
- make github-release
|
||||
@@ -129,8 +130,8 @@ stretch: &stretch
|
||||
- gcc-mingw-w64
|
||||
- python3-setuptools
|
||||
- python3-pip
|
||||
pre-cache: *install_pygithub
|
||||
post-cache:
|
||||
- pip3 install pygithub
|
||||
- export GOOS=windows
|
||||
- export GOARCH=amd64
|
||||
- export CC=x86_64-w64-mingw32-gcc
|
||||
@@ -152,8 +153,8 @@ stretch: &stretch
|
||||
- gcc-mingw-w64
|
||||
- python3-setuptools
|
||||
- python3-pip
|
||||
pre-cache: *install_pygithub
|
||||
post-cache:
|
||||
- pip3 install pygithub
|
||||
- export GOOS=windows
|
||||
- export GOARCH=386
|
||||
- export CC=i686-w64-mingw32-gcc-win32
|
||||
@@ -166,8 +167,8 @@ stretch: &stretch
|
||||
- g++-aarch64-linux-gnu
|
||||
- python3-setuptools
|
||||
- python3-pip
|
||||
pre-cache: *install_pygithub
|
||||
post-cache:
|
||||
- pip3 install pygithub
|
||||
- export GOOS=linux
|
||||
- export GOARCH=arm64
|
||||
- export CC=aarch64-linux-gnu-gcc
|
||||
@@ -178,8 +179,8 @@ stretch: &stretch
|
||||
- *pinned_go
|
||||
- python3-setuptools
|
||||
- python3-pip
|
||||
pre-cache: *install_pygithub
|
||||
post-cache:
|
||||
- pip3 install pygithub
|
||||
- make github-mac-upload
|
||||
test:
|
||||
build_dir: *build_dir
|
||||
@@ -205,9 +206,38 @@ stretch: &stretch
|
||||
- *pinned_go
|
||||
- python3-setuptools
|
||||
- python3-pip
|
||||
pre-cache: *install_pygithub
|
||||
post-cache:
|
||||
- pip3 install pygithub
|
||||
- make github-message
|
||||
build-junos:
|
||||
build_dir: *build_dir
|
||||
builddeps:
|
||||
- *pinned_go
|
||||
- build-essential
|
||||
- python3
|
||||
- genisoimage
|
||||
- jetez
|
||||
pre-cache:
|
||||
- ln -s /usr/bin/genisoimage /usr/bin/mkisofs
|
||||
post-cache:
|
||||
- export GOOS=freebsd
|
||||
- export GOARCH=amd64
|
||||
- make cloudflared-junos
|
||||
publish-junos:
|
||||
build_dir: *build_dir
|
||||
builddeps:
|
||||
- *pinned_go
|
||||
- build-essential
|
||||
- python3
|
||||
- genisoimage
|
||||
- jetez
|
||||
- s4cmd
|
||||
pre-cache:
|
||||
- ln -s /usr/bin/genisoimage /usr/bin/mkisofs
|
||||
post-cache:
|
||||
- export GOOS=freebsd
|
||||
- export GOARCH=amd64
|
||||
- make publish-cloudflared-junos
|
||||
|
||||
jessie: *stretch
|
||||
|
||||
@@ -218,10 +248,11 @@ centos-7:
|
||||
build_dir: *build_dir
|
||||
builddeps: &el7_builddeps
|
||||
- https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
|
||||
pre-cache:
|
||||
- yum install -y fakeroot
|
||||
- wget https://golang.org/dl/go1.15.2.linux-amd64.tar.gz -P /tmp/
|
||||
- tar -C /usr/local -xzf /tmp/go1.15.2.linux-amd64.tar.gz
|
||||
post-cache:
|
||||
- sudo yum install -y fakeroot
|
||||
- wget https://golang.org/dl/go1.14.7.linux-amd64.tar.gz -P /tmp/
|
||||
- sudo tar -C /usr/local -xzf /tmp/go1.14.7.linux-amd64.tar.gz
|
||||
- export PATH=$PATH:/usr/local/go/bin
|
||||
- export GOOS=linux
|
||||
- export GOARCH=amd64
|
||||
@@ -229,10 +260,11 @@ centos-7:
|
||||
build-rpm:
|
||||
build_dir: *build_dir
|
||||
builddeps: *el7_builddeps
|
||||
pre-cache:
|
||||
- yum install -y fakeroot
|
||||
- wget https://golang.org/dl/go1.15.2.linux-amd64.tar.gz -P /tmp/
|
||||
- tar -C /usr/local -xzf /tmp/go1.15.2.linux-amd64.tar.gz
|
||||
post-cache:
|
||||
- sudo yum install -y fakeroot
|
||||
- wget https://golang.org/dl/go1.14.7.linux-amd64.tar.gz -P /tmp/
|
||||
- sudo tar -C /usr/local -xzf /tmp/go1.14.7.linux-amd64.tar.gz
|
||||
- export PATH=$PATH:/usr/local/go/bin
|
||||
- export GOOS=linux
|
||||
- export GOARCH=amd64
|
||||
|
||||
@@ -67,7 +67,7 @@ Description=Update Argo Tunnel
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
ExecStart=/bin/bash -c '{{ .Path }} update; code=$?; if [ $code -eq 64 ]; then systemctl restart cloudflared; exit 0; fi; exit $code'
|
||||
ExecStart=/bin/bash -c '{{ .Path }} update; code=$?; if [ $code -eq 11 ]; then systemctl restart cloudflared; exit 0; fi; exit $code'
|
||||
`,
|
||||
},
|
||||
{
|
||||
|
||||
@@ -80,7 +80,7 @@ func runCommand(command string, args ...string) error {
|
||||
return fmt.Errorf("error starting %s: %v", command, err)
|
||||
}
|
||||
|
||||
ioutil.ReadAll(stderr)
|
||||
_, _ = ioutil.ReadAll(stderr)
|
||||
err = cmd.Wait()
|
||||
if err != nil {
|
||||
return fmt.Errorf("%s returned with error: %v", command, err)
|
||||
|
||||
+184
-105
@@ -20,6 +20,7 @@ import (
|
||||
"github.com/cloudflare/cloudflared/cmd/cloudflared/buildinfo"
|
||||
"github.com/cloudflare/cloudflared/cmd/cloudflared/cliutil"
|
||||
"github.com/cloudflare/cloudflared/cmd/cloudflared/config"
|
||||
"github.com/cloudflare/cloudflared/cmd/cloudflared/ui"
|
||||
"github.com/cloudflare/cloudflared/cmd/cloudflared/updater"
|
||||
"github.com/cloudflare/cloudflared/dbconnect"
|
||||
"github.com/cloudflare/cloudflared/h2mux"
|
||||
@@ -91,6 +92,9 @@ const (
|
||||
// bastionFlag is to enable bastion, or jump host, operation
|
||||
bastionFlag = "bastion"
|
||||
|
||||
// uiFlag is to enable launching cloudflared in interactive UI mode
|
||||
uiFlag = "ui"
|
||||
|
||||
logDirectoryFlag = "log-directory"
|
||||
|
||||
debugLevelWarning = "At debug level, request URL, method, protocol, content legnth and header will be logged. " +
|
||||
@@ -178,7 +182,13 @@ func Commands() []*cli.Command {
|
||||
subcommands = append(subcommands, buildCleanupCommand())
|
||||
subcommands = append(subcommands, buildRouteCommand())
|
||||
|
||||
cmds = append(cmds, &cli.Command{
|
||||
cmds = append(cmds, buildTunnelCommand(subcommands))
|
||||
|
||||
return cmds
|
||||
}
|
||||
|
||||
func buildTunnelCommand(subcommands []*cli.Command) *cli.Command {
|
||||
return &cli.Command{
|
||||
Name: "tunnel",
|
||||
Action: cliutil.ErrorHandler(TunnelCommand),
|
||||
Before: Before,
|
||||
@@ -194,31 +204,26 @@ func Commands() []*cli.Command {
|
||||
|
||||
To use, begin by calling login to download a certificate:
|
||||
|
||||
cloudflared tunnel login
|
||||
$ cloudflared tunnel login
|
||||
|
||||
With your certificate installed you can then launch your first tunnel,
|
||||
replacing my.site.com with a subdomain of your site:
|
||||
|
||||
cloudflared tunnel --hostname my.site.com --url http://localhost:8080
|
||||
$ cloudflared tunnel --hostname my.site.com --url http://localhost:8080
|
||||
|
||||
If you have a web server running on port 8080 (in this example), it will be available on
|
||||
the internet!`,
|
||||
Subcommands: subcommands,
|
||||
Flags: tunnelFlags(false),
|
||||
})
|
||||
|
||||
return cmds
|
||||
}
|
||||
}
|
||||
|
||||
func TunnelCommand(c *cli.Context) error {
|
||||
if name := c.String("name"); name != "" {
|
||||
if name := c.String("name"); name != "" { // Start a named tunnel
|
||||
return adhocNamedTunnel(c, name)
|
||||
} else { // Start a classic tunnel
|
||||
return classicTunnel(c)
|
||||
}
|
||||
logger, err := createLogger(c, false)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "error setting up logger")
|
||||
}
|
||||
return StartServer(c, version, shutdownC, graceShutdownC, nil, logger)
|
||||
}
|
||||
|
||||
func Init(v string, s, g chan struct{}) {
|
||||
@@ -242,11 +247,11 @@ func adhocNamedTunnel(c *cli.Context, name string) error {
|
||||
sc.logger.Infof("Tunnel already created with ID %s", tunnel.ID)
|
||||
}
|
||||
|
||||
if r, ok := routeFromFlag(c, tunnel.ID); ok {
|
||||
if err := sc.route(tunnel.ID, r); err != nil {
|
||||
if r, ok := routeFromFlag(c); ok {
|
||||
if res, err := sc.route(tunnel.ID, r); err != nil {
|
||||
sc.logger.Errorf("failed to create route, please create it manually. err: %v.", err)
|
||||
} else {
|
||||
sc.logger.Infof(r.SuccessSummary())
|
||||
sc.logger.Infof(res.SuccessSummary())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -257,7 +262,17 @@ func adhocNamedTunnel(c *cli.Context, name string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func routeFromFlag(c *cli.Context, tunnelID uuid.UUID) (tunnelstore.Route, bool) {
|
||||
// classicTunnel creates a "classic" non-named tunnel
|
||||
func classicTunnel(c *cli.Context) error {
|
||||
sc, err := newSubcommandContext(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return StartServer(c, version, shutdownC, graceShutdownC, nil, sc.logger, sc.isUIEnabled)
|
||||
}
|
||||
|
||||
func routeFromFlag(c *cli.Context) (tunnelstore.Route, bool) {
|
||||
if hostname := c.String("hostname"); hostname != "" {
|
||||
if lbPool := c.String("lb-pool"); lbPool != "" {
|
||||
return tunnelstore.NewLBRoute(hostname, lbPool), true
|
||||
@@ -267,8 +282,8 @@ func routeFromFlag(c *cli.Context, tunnelID uuid.UUID) (tunnelstore.Route, bool)
|
||||
return nil, false
|
||||
}
|
||||
|
||||
func createLogger(c *cli.Context, isTransport bool) (logger.Service, error) {
|
||||
loggerOpts := []logger.Option{}
|
||||
func createLogger(c *cli.Context, isTransport bool, disableTerminal bool) (*logger.OutputWriter, error) {
|
||||
var loggerOpts []logger.Option
|
||||
|
||||
logPath := c.String("logfile")
|
||||
if logPath == "" {
|
||||
@@ -288,10 +303,28 @@ func createLogger(c *cli.Context, isTransport bool) (logger.Service, error) {
|
||||
}
|
||||
loggerOpts = append(loggerOpts, logger.LogLevelString(logLevel))
|
||||
|
||||
return logger.New(loggerOpts...)
|
||||
if disableTerminal {
|
||||
disableOption := logger.DisableTerminal(true)
|
||||
loggerOpts = append(loggerOpts, disableOption)
|
||||
}
|
||||
|
||||
l, err := logger.New(loggerOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return l, nil
|
||||
}
|
||||
|
||||
func StartServer(c *cli.Context, version string, shutdownC, graceShutdownC chan struct{}, namedTunnel *origin.NamedTunnelConfig, logger logger.Service) error {
|
||||
func StartServer(
|
||||
c *cli.Context,
|
||||
version string,
|
||||
shutdownC,
|
||||
graceShutdownC chan struct{},
|
||||
namedTunnel *origin.NamedTunnelConfig,
|
||||
log logger.Service,
|
||||
isUIEnabled bool,
|
||||
) error {
|
||||
_ = raven.SetDSN(sentryDSN)
|
||||
var wg sync.WaitGroup
|
||||
listeners := gracenet.Net{}
|
||||
@@ -300,45 +333,49 @@ func StartServer(c *cli.Context, version string, shutdownC, graceShutdownC chan
|
||||
dnsReadySignal := make(chan struct{})
|
||||
|
||||
if c.String("config") == "" {
|
||||
logger.Infof("Cannot determine default configuration path. No file %v in %v", config.DefaultConfigFiles, config.DefaultConfigSearchDirectories())
|
||||
log.Infof(
|
||||
"Cannot determine default configuration path. No file %v in %v",
|
||||
config.DefaultConfigFiles,
|
||||
config.DefaultConfigSearchDirectories(),
|
||||
)
|
||||
}
|
||||
|
||||
if c.IsSet("trace-output") {
|
||||
tmpTraceFile, err := ioutil.TempFile("", "trace")
|
||||
if err != nil {
|
||||
logger.Errorf("Failed to create new temporary file to save trace output: %s", err)
|
||||
log.Errorf("Failed to create new temporary file to save trace output: %s", err)
|
||||
}
|
||||
|
||||
defer func() {
|
||||
if err := tmpTraceFile.Close(); err != nil {
|
||||
logger.Errorf("Failed to close trace output file %s with error: %s", tmpTraceFile.Name(), err)
|
||||
log.Errorf("Failed to close trace output file %s with error: %s", tmpTraceFile.Name(), err)
|
||||
}
|
||||
if err := os.Rename(tmpTraceFile.Name(), c.String("trace-output")); err != nil {
|
||||
logger.Errorf("Failed to rename temporary trace output file %s to %s with error: %s", tmpTraceFile.Name(), c.String("trace-output"), err)
|
||||
log.Errorf("Failed to rename temporary trace output file %s to %s with error: %s", tmpTraceFile.Name(), c.String("trace-output"), err)
|
||||
} else {
|
||||
err := os.Remove(tmpTraceFile.Name())
|
||||
if err != nil {
|
||||
logger.Errorf("Failed to remove the temporary trace file %s with error: %s", tmpTraceFile.Name(), err)
|
||||
log.Errorf("Failed to remove the temporary trace file %s with error: %s", tmpTraceFile.Name(), err)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
if err := trace.Start(tmpTraceFile); err != nil {
|
||||
logger.Errorf("Failed to start trace: %s", err)
|
||||
log.Errorf("Failed to start trace: %s", err)
|
||||
return errors.Wrap(err, "Error starting tracing")
|
||||
}
|
||||
defer trace.Stop()
|
||||
}
|
||||
|
||||
buildInfo := buildinfo.GetBuildInfo(version)
|
||||
buildInfo.Log(logger)
|
||||
logClientOptions(c, logger)
|
||||
buildInfo.Log(log)
|
||||
logClientOptions(c, log)
|
||||
|
||||
if c.IsSet("proxy-dns") {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
errC <- runDNSProxyServer(c, dnsReadySignal, shutdownC, logger)
|
||||
errC <- runDNSProxyServer(c, dnsReadySignal, shutdownC, log)
|
||||
}()
|
||||
} else {
|
||||
close(dnsReadySignal)
|
||||
@@ -349,24 +386,24 @@ func StartServer(c *cli.Context, version string, shutdownC, graceShutdownC chan
|
||||
|
||||
metricsListener, err := listeners.Listen("tcp", c.String("metrics"))
|
||||
if err != nil {
|
||||
logger.Errorf("Error opening metrics server listener: %s", err)
|
||||
log.Errorf("Error opening metrics server listener: %s", err)
|
||||
return errors.Wrap(err, "Error opening metrics server listener")
|
||||
}
|
||||
defer metricsListener.Close()
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
errC <- metrics.ServeMetrics(metricsListener, shutdownC, logger)
|
||||
errC <- metrics.ServeMetrics(metricsListener, shutdownC, log)
|
||||
}()
|
||||
|
||||
go notifySystemd(connectedSignal)
|
||||
if c.IsSet("pidfile") {
|
||||
go writePidFile(connectedSignal, c.String("pidfile"), logger)
|
||||
go writePidFile(connectedSignal, c.String("pidfile"), log)
|
||||
}
|
||||
|
||||
cloudflaredID, err := uuid.NewRandom()
|
||||
if err != nil {
|
||||
logger.Errorf("Cannot generate cloudflared ID: %s", err)
|
||||
log.Errorf("Cannot generate cloudflared ID: %s", err)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -377,12 +414,12 @@ func StartServer(c *cli.Context, version string, shutdownC, graceShutdownC chan
|
||||
}()
|
||||
|
||||
// update needs to be after DNS proxy is up to resolve equinox server address
|
||||
if updater.IsAutoupdateEnabled(c, logger) {
|
||||
logger.Infof("Autoupdate frequency is set to %v", c.Duration("autoupdate-freq"))
|
||||
if updater.IsAutoupdateEnabled(c, log) {
|
||||
log.Infof("Autoupdate frequency is set to %v", c.Duration("autoupdate-freq"))
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
autoupdater := updater.NewAutoUpdater(c.Duration("autoupdate-freq"), &listeners, logger)
|
||||
autoupdater := updater.NewAutoUpdater(c.Duration("autoupdate-freq"), &listeners, log)
|
||||
errC <- autoupdater.Run(ctx)
|
||||
}()
|
||||
}
|
||||
@@ -391,21 +428,21 @@ func StartServer(c *cli.Context, version string, shutdownC, graceShutdownC chan
|
||||
if dnsProxyStandAlone(c) {
|
||||
connectedSignal.Notify()
|
||||
// no grace period, handle SIGINT/SIGTERM immediately
|
||||
return waitToShutdown(&wg, errC, shutdownC, graceShutdownC, 0, logger)
|
||||
return waitToShutdown(&wg, errC, shutdownC, graceShutdownC, 0, log)
|
||||
}
|
||||
|
||||
if c.IsSet("hello-world") {
|
||||
logger.Infof("hello-world set")
|
||||
log.Infof("hello-world set")
|
||||
helloListener, err := hello.CreateTLSListener("127.0.0.1:")
|
||||
if err != nil {
|
||||
logger.Errorf("Cannot start Hello World Server: %s", err)
|
||||
log.Errorf("Cannot start Hello World Server: %s", err)
|
||||
return errors.Wrap(err, "Cannot start Hello World Server")
|
||||
}
|
||||
defer helloListener.Close()
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
hello.StartHelloWorldServer(logger, helloListener, shutdownC)
|
||||
_ = hello.StartHelloWorldServer(log, helloListener, shutdownC)
|
||||
}()
|
||||
forceSetFlag(c, "url", "https://"+helloListener.Addr().String())
|
||||
}
|
||||
@@ -413,11 +450,11 @@ func StartServer(c *cli.Context, version string, shutdownC, graceShutdownC chan
|
||||
if c.IsSet(sshServerFlag) {
|
||||
if runtime.GOOS != "darwin" && runtime.GOOS != "linux" {
|
||||
msg := fmt.Sprintf("--ssh-server is not supported on %s", runtime.GOOS)
|
||||
logger.Error(msg)
|
||||
log.Error(msg)
|
||||
return errors.New(msg)
|
||||
}
|
||||
|
||||
logger.Infof("ssh-server set")
|
||||
log.Infof("ssh-server set")
|
||||
|
||||
logManager := sshlog.NewEmptyManager()
|
||||
if c.IsSet(bucketNameFlag) && c.IsSet(regionNameFlag) && c.IsSet(accessKeyIDFlag) && c.IsSet(secretIDFlag) {
|
||||
@@ -425,34 +462,34 @@ func StartServer(c *cli.Context, version string, shutdownC, graceShutdownC chan
|
||||
c.String(accessKeyIDFlag), c.String(secretIDFlag), c.String(sessionTokenIDFlag), c.String(s3URLFlag))
|
||||
if err != nil {
|
||||
msg := "Cannot create uploader for SSH Server"
|
||||
logger.Errorf("%s: %s", msg, err)
|
||||
log.Errorf("%s: %s", msg, err)
|
||||
return errors.Wrap(err, msg)
|
||||
}
|
||||
|
||||
if err := os.MkdirAll(sshLogFileDirectory, 0700); err != nil {
|
||||
msg := fmt.Sprintf("Cannot create SSH log file directory %s", sshLogFileDirectory)
|
||||
logger.Errorf("%s: %s", msg, err)
|
||||
log.Errorf("%s: %s", msg, err)
|
||||
return errors.Wrap(err, msg)
|
||||
}
|
||||
|
||||
logManager = sshlog.New(sshLogFileDirectory)
|
||||
|
||||
uploadManager := awsuploader.NewDirectoryUploadManager(logger, uploader, sshLogFileDirectory, 30*time.Minute, shutdownC)
|
||||
uploadManager := awsuploader.NewDirectoryUploadManager(log, uploader, sshLogFileDirectory, 30*time.Minute, shutdownC)
|
||||
uploadManager.Start()
|
||||
}
|
||||
|
||||
localServerAddress := "127.0.0.1:" + c.String(sshPortFlag)
|
||||
server, err := sshserver.New(logManager, logger, version, localServerAddress, c.String("hostname"), c.Path(hostKeyPath), shutdownC, c.Duration(sshIdleTimeoutFlag), c.Duration(sshMaxTimeoutFlag))
|
||||
server, err := sshserver.New(logManager, log, version, localServerAddress, c.String("hostname"), c.Path(hostKeyPath), shutdownC, c.Duration(sshIdleTimeoutFlag), c.Duration(sshMaxTimeoutFlag))
|
||||
if err != nil {
|
||||
msg := "Cannot create new SSH Server"
|
||||
logger.Errorf("%s: %s", msg, err)
|
||||
log.Errorf("%s: %s", msg, err)
|
||||
return errors.Wrap(err, msg)
|
||||
}
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
if err = server.Start(); err != nil && err != ssh.ErrServerClosed {
|
||||
logger.Errorf("SSH server error: %s", err)
|
||||
log.Errorf("SSH server error: %s", err)
|
||||
// TODO: remove when declarative tunnels are implemented.
|
||||
close(shutdownC)
|
||||
}
|
||||
@@ -464,14 +501,14 @@ func StartServer(c *cli.Context, version string, shutdownC, graceShutdownC chan
|
||||
hostname := c.String("hostname")
|
||||
if url == hostname && url != "" && hostname != "" {
|
||||
errText := "hostname and url shouldn't match. See --help for more information"
|
||||
logger.Error(errText)
|
||||
log.Error(errText)
|
||||
return fmt.Errorf(errText)
|
||||
}
|
||||
|
||||
if staticHost := hostnameFromURI(c.String("url")); isProxyDestinationConfigured(staticHost, c) {
|
||||
listener, err := net.Listen("tcp", "127.0.0.1:")
|
||||
if err != nil {
|
||||
logger.Errorf("Cannot start Websocket Proxy Server: %s", err)
|
||||
log.Errorf("Cannot start Websocket Proxy Server: %s", err)
|
||||
return errors.Wrap(err, "Cannot start Websocket Proxy Server")
|
||||
}
|
||||
wg.Add(1)
|
||||
@@ -479,7 +516,7 @@ func StartServer(c *cli.Context, version string, shutdownC, graceShutdownC chan
|
||||
defer wg.Done()
|
||||
streamHandler := websocket.DefaultStreamHandler
|
||||
if c.IsSet(socks5Flag) {
|
||||
logger.Info("SOCKS5 server started")
|
||||
log.Info("SOCKS5 server started")
|
||||
streamHandler = func(wsConn *websocket.Conn, remoteConn net.Conn, _ http.Header) {
|
||||
dialer := socks.NewConnDialer(remoteConn)
|
||||
requestHandler := socks.NewRequestHandler(dialer)
|
||||
@@ -492,32 +529,32 @@ func StartServer(c *cli.Context, version string, shutdownC, graceShutdownC chan
|
||||
if finalDestination := requestHeaders.Get(h2mux.CFJumpDestinationHeader); finalDestination != "" {
|
||||
token := requestHeaders.Get(h2mux.CFAccessTokenHeader)
|
||||
if err := websocket.SendSSHPreamble(remoteConn, finalDestination, token); err != nil {
|
||||
logger.Errorf("Failed to send SSH preamble: %s", err)
|
||||
log.Errorf("Failed to send SSH preamble: %s", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
websocket.DefaultStreamHandler(wsConn, remoteConn, requestHeaders)
|
||||
}
|
||||
}
|
||||
errC <- websocket.StartProxyServer(logger, listener, staticHost, shutdownC, streamHandler)
|
||||
errC <- websocket.StartProxyServer(log, listener, staticHost, shutdownC, streamHandler)
|
||||
}()
|
||||
forceSetFlag(c, "url", "http://"+listener.Addr().String())
|
||||
}
|
||||
|
||||
transportLogger, err := createLogger(c, true)
|
||||
transportLogger, err := createLogger(c, true, false)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "error setting up transport logger")
|
||||
}
|
||||
|
||||
tunnelConfig, err := prepareTunnelConfig(c, buildInfo, version, logger, transportLogger, namedTunnel)
|
||||
tunnelConfig, err := prepareTunnelConfig(c, buildInfo, version, log, transportLogger, namedTunnel)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
reconnectCh := make(chan origin.ReconnectSignal, 1)
|
||||
if c.IsSet("stdin-control") {
|
||||
logger.Info("Enabling control through stdin")
|
||||
go stdinControl(reconnectCh, logger)
|
||||
log.Info("Enabling control through stdin")
|
||||
go stdinControl(reconnectCh, log)
|
||||
}
|
||||
|
||||
wg.Add(1)
|
||||
@@ -526,7 +563,26 @@ func StartServer(c *cli.Context, version string, shutdownC, graceShutdownC chan
|
||||
errC <- origin.StartTunnelDaemon(ctx, tunnelConfig, connectedSignal, cloudflaredID, reconnectCh)
|
||||
}()
|
||||
|
||||
return waitToShutdown(&wg, errC, shutdownC, graceShutdownC, c.Duration("grace-period"), logger)
|
||||
if isUIEnabled {
|
||||
const tunnelEventChanBufferSize = 16
|
||||
tunnelEventChan := make(chan ui.TunnelEvent, tunnelEventChanBufferSize)
|
||||
tunnelConfig.TunnelEventChan = tunnelEventChan
|
||||
|
||||
tunnelInfo := ui.NewUIModel(
|
||||
version,
|
||||
hostname,
|
||||
metricsListener.Addr().String(),
|
||||
tunnelConfig.OriginUrl,
|
||||
tunnelConfig.HAConnections,
|
||||
)
|
||||
logLevels, err := logger.ParseLevelString(c.String("loglevel"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
tunnelInfo.LaunchUI(ctx, log, logLevels, tunnelEventChan)
|
||||
}
|
||||
|
||||
return waitToShutdown(&wg, errC, shutdownC, graceShutdownC, c.Duration("grace-period"), log)
|
||||
}
|
||||
|
||||
// forceSetFlag attempts to set the given flag value in the closest context that has it defined
|
||||
@@ -539,7 +595,7 @@ func forceSetFlag(c *cli.Context, name, value string) {
|
||||
}
|
||||
|
||||
func Before(c *cli.Context) error {
|
||||
logger, err := createLogger(c, false)
|
||||
logger, err := createLogger(c, false, false)
|
||||
if err != nil {
|
||||
return cliutil.PrintLoggerSetupError("error setting up logger", err)
|
||||
}
|
||||
@@ -696,7 +752,7 @@ func appendFlags(flags []cli.Flag, extraFlags ...cli.Flag) []cli.Flag {
|
||||
}
|
||||
|
||||
func tunnelFlags(shouldHide bool) []cli.Flag {
|
||||
return []cli.Flag{
|
||||
flags := []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "config",
|
||||
Usage: "Specifies a config file in YAML format.",
|
||||
@@ -753,13 +809,6 @@ func tunnelFlags(shouldHide bool) []cli.Flag {
|
||||
EnvVars: []string{"TUNNEL_ORIGIN_CA_POOL"},
|
||||
Hidden: shouldHide,
|
||||
}),
|
||||
altsrc.NewStringFlag(&cli.StringFlag{
|
||||
Name: "url",
|
||||
Value: "http://localhost:8080",
|
||||
Usage: "Connect to the local webserver at `URL`.",
|
||||
EnvVars: []string{"TUNNEL_URL"},
|
||||
Hidden: shouldHide,
|
||||
}),
|
||||
altsrc.NewStringFlag(&cli.StringFlag{
|
||||
Name: "unix-socket",
|
||||
Usage: "Path to unix socket to use instead of --url",
|
||||
@@ -875,20 +924,6 @@ func tunnelFlags(shouldHide bool) []cli.Flag {
|
||||
EnvVars: []string{"TUNNEL_RETRIES"},
|
||||
Hidden: shouldHide,
|
||||
}),
|
||||
altsrc.NewBoolFlag(&cli.BoolFlag{
|
||||
Name: "hello-world",
|
||||
Value: false,
|
||||
Usage: "Run Hello World Server",
|
||||
EnvVars: []string{"TUNNEL_HELLO_WORLD"},
|
||||
Hidden: shouldHide,
|
||||
}),
|
||||
altsrc.NewBoolFlag(&cli.BoolFlag{
|
||||
Name: sshServerFlag,
|
||||
Value: false,
|
||||
Usage: "Run an SSH Server",
|
||||
EnvVars: []string{"TUNNEL_SSH_SERVER"},
|
||||
Hidden: true, // TODO: remove when feature is complete
|
||||
}),
|
||||
altsrc.NewStringFlag(&cli.StringFlag{
|
||||
Name: "pidfile",
|
||||
Usage: "Write the application's PID to this file after first successful connection.",
|
||||
@@ -1033,6 +1068,54 @@ func tunnelFlags(shouldHide bool) []cli.Flag {
|
||||
EnvVars: []string{"DIAL_EDGE_TIMEOUT"},
|
||||
Hidden: true,
|
||||
}),
|
||||
altsrc.NewBoolFlag(&cli.BoolFlag{
|
||||
Name: "stdin-control",
|
||||
Usage: "Control the process using commands sent through stdin",
|
||||
EnvVars: []string{"STDIN-CONTROL"},
|
||||
Hidden: true,
|
||||
Value: false,
|
||||
}),
|
||||
altsrc.NewStringFlag(&cli.StringFlag{
|
||||
Name: "name",
|
||||
Aliases: []string{"n"},
|
||||
EnvVars: []string{"TUNNEL_NAME"},
|
||||
Usage: "Stable name to identify the tunnel. Using this flag will create, route and run a tunnel. For production usage, execute each command separately",
|
||||
}),
|
||||
altsrc.NewBoolFlag(&cli.BoolFlag{
|
||||
Name: uiFlag,
|
||||
Usage: "Launch tunnel UI. Tunnel logs are scrollable via 'j', 'k', or arrow keys.",
|
||||
Value: false,
|
||||
Hidden: shouldHide,
|
||||
}),
|
||||
urlFlag(shouldHide),
|
||||
helloWorldFlag(shouldHide),
|
||||
createSocks5Flag(shouldHide),
|
||||
}
|
||||
return append(flags, sshFlags(shouldHide)...)
|
||||
}
|
||||
|
||||
func urlFlag(shouldHide bool) cli.Flag {
|
||||
return altsrc.NewStringFlag(&cli.StringFlag{
|
||||
Name: "url",
|
||||
Value: "http://localhost:8080",
|
||||
Usage: "Connect to the local webserver at `URL`.",
|
||||
EnvVars: []string{"TUNNEL_URL"},
|
||||
Hidden: shouldHide,
|
||||
})
|
||||
}
|
||||
|
||||
func helloWorldFlag(shouldHide bool) cli.Flag {
|
||||
return altsrc.NewBoolFlag(&cli.BoolFlag{
|
||||
Name: "hello-world",
|
||||
Value: false,
|
||||
Usage: "Run Hello World Server",
|
||||
EnvVars: []string{"TUNNEL_HELLO_WORLD"},
|
||||
Hidden: shouldHide,
|
||||
})
|
||||
}
|
||||
|
||||
func sshFlags(shouldHide bool) []cli.Flag {
|
||||
return []cli.Flag{
|
||||
altsrc.NewStringFlag(&cli.StringFlag{
|
||||
Name: sshPortFlag,
|
||||
Usage: "Localhost port that cloudflared SSH server will run on",
|
||||
@@ -1064,18 +1147,18 @@ func tunnelFlags(shouldHide bool) []cli.Flag {
|
||||
EnvVars: []string{"REGION_ID"},
|
||||
Hidden: true,
|
||||
}),
|
||||
altsrc.NewStringFlag(&cli.StringFlag{
|
||||
Name: accessKeyIDFlag,
|
||||
Usage: "Access Key ID of where to upload SSH logs",
|
||||
EnvVars: []string{"ACCESS_CLIENT_ID"},
|
||||
Hidden: true,
|
||||
}),
|
||||
altsrc.NewStringFlag(&cli.StringFlag{
|
||||
Name: secretIDFlag,
|
||||
Usage: "Secret ID of where to upload SSH logs",
|
||||
EnvVars: []string{"SECRET_ID"},
|
||||
Hidden: true,
|
||||
}),
|
||||
altsrc.NewStringFlag(&cli.StringFlag{
|
||||
Name: accessKeyIDFlag,
|
||||
Usage: "Access Key ID of where to upload SSH logs",
|
||||
EnvVars: []string{"ACCESS_CLIENT_ID"},
|
||||
Hidden: true,
|
||||
}),
|
||||
altsrc.NewStringFlag(&cli.StringFlag{
|
||||
Name: sessionTokenIDFlag,
|
||||
Usage: "Session Token to use in the configuration of SSH logs uploading",
|
||||
@@ -1095,18 +1178,11 @@ func tunnelFlags(shouldHide bool) []cli.Flag {
|
||||
Hidden: true,
|
||||
}),
|
||||
altsrc.NewBoolFlag(&cli.BoolFlag{
|
||||
Name: "stdin-control",
|
||||
Usage: "Control the process using commands sent through stdin",
|
||||
EnvVars: []string{"STDIN-CONTROL"},
|
||||
Hidden: true,
|
||||
Name: sshServerFlag,
|
||||
Value: false,
|
||||
}),
|
||||
altsrc.NewBoolFlag(&cli.BoolFlag{
|
||||
Name: socks5Flag,
|
||||
Usage: "specify if this tunnel is running as a SOCK5 Server",
|
||||
EnvVars: []string{"TUNNEL_SOCKS"},
|
||||
Value: false,
|
||||
Hidden: shouldHide,
|
||||
Usage: "Run an SSH Server",
|
||||
EnvVars: []string{"TUNNEL_SSH_SERVER"},
|
||||
Hidden: true, // TODO: remove when feature is complete
|
||||
}),
|
||||
altsrc.NewBoolFlag(&cli.BoolFlag{
|
||||
Name: bastionFlag,
|
||||
@@ -1115,16 +1191,19 @@ func tunnelFlags(shouldHide bool) []cli.Flag {
|
||||
EnvVars: []string{"TUNNEL_BASTION"},
|
||||
Hidden: shouldHide,
|
||||
}),
|
||||
altsrc.NewStringFlag(&cli.StringFlag{
|
||||
Name: "name",
|
||||
Aliases: []string{"n"},
|
||||
EnvVars: []string{"TUNNEL_NAME"},
|
||||
Usage: "Stable name to identify the tunnel. Using this flag will create, route and run a tunnel. For production usage, execute each command separately",
|
||||
Hidden: true,
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
func createSocks5Flag(shouldHide bool) cli.Flag {
|
||||
return altsrc.NewBoolFlag(&cli.BoolFlag{
|
||||
Name: socks5Flag,
|
||||
Usage: "specify if this tunnel is running as a SOCK5 Server",
|
||||
EnvVars: []string{"TUNNEL_SOCKS"},
|
||||
Value: false,
|
||||
Hidden: shouldHide,
|
||||
})
|
||||
}
|
||||
|
||||
func stdinControl(reconnectCh chan origin.ReconnectSignal, logger logger.Service) {
|
||||
for {
|
||||
scanner := bufio.NewScanner(os.Stdin)
|
||||
|
||||
@@ -19,8 +19,8 @@ import (
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
// subcommandContext carries structs shared between subcommands, to reduce number of arguments needed to pass between subcommands,
|
||||
// and make sure they are only initialized once
|
||||
// subcommandContext carries structs shared between subcommands, to reduce number of arguments needed to
|
||||
// pass between subcommands, and make sure they are only initialized once
|
||||
type subcommandContext struct {
|
||||
c *cli.Context
|
||||
logger logger.Service
|
||||
@@ -28,16 +28,23 @@ type subcommandContext struct {
|
||||
// These fields should be accessed using their respective Getter
|
||||
tunnelstoreClient tunnelstore.Client
|
||||
userCredential *userCredential
|
||||
|
||||
isUIEnabled bool
|
||||
}
|
||||
|
||||
func newSubcommandContext(c *cli.Context) (*subcommandContext, error) {
|
||||
logger, err := createLogger(c, false)
|
||||
isUIEnabled := c.IsSet(uiFlag) && c.String("name") != ""
|
||||
|
||||
// If UI is enabled, terminal log output should be disabled -- log should be written into a UI log window instead
|
||||
logger, err := createLogger(c, false, isUIEnabled)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "error setting up logger")
|
||||
}
|
||||
|
||||
return &subcommandContext{
|
||||
c: c,
|
||||
logger: logger,
|
||||
c: c,
|
||||
logger: logger,
|
||||
isUIEnabled: isUIEnabled,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -237,7 +244,16 @@ func (sc *subcommandContext) run(tunnelID uuid.UUID) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return StartServer(sc.c, version, shutdownC, graceShutdownC, &origin.NamedTunnelConfig{Auth: *credentials, ID: tunnelID}, sc.logger)
|
||||
|
||||
return StartServer(
|
||||
sc.c,
|
||||
version,
|
||||
shutdownC,
|
||||
graceShutdownC,
|
||||
&origin.NamedTunnelConfig{Auth: *credentials, ID: tunnelID},
|
||||
sc.logger,
|
||||
sc.isUIEnabled,
|
||||
)
|
||||
}
|
||||
|
||||
func (sc *subcommandContext) cleanupConnections(tunnelIDs []uuid.UUID) error {
|
||||
@@ -254,17 +270,13 @@ func (sc *subcommandContext) cleanupConnections(tunnelIDs []uuid.UUID) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (sc *subcommandContext) route(tunnelID uuid.UUID, r tunnelstore.Route) error {
|
||||
func (sc *subcommandContext) route(tunnelID uuid.UUID, r tunnelstore.Route) (tunnelstore.RouteResult, error) {
|
||||
client, err := sc.client()
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := client.RouteTunnel(tunnelID, r); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
return client.RouteTunnel(tunnelID, r)
|
||||
}
|
||||
|
||||
func (sc *subcommandContext) tunnelActive(name string) (*tunnelstore.Tunnel, bool, error) {
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strings"
|
||||
"text/tabwriter"
|
||||
@@ -16,6 +17,7 @@ import (
|
||||
"github.com/mitchellh/go-homedir"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/urfave/cli/v2"
|
||||
"golang.org/x/net/idna"
|
||||
"gopkg.in/yaml.v2"
|
||||
|
||||
"github.com/cloudflare/cloudflared/cmd/cloudflared/cliutil"
|
||||
@@ -37,18 +39,19 @@ var (
|
||||
listNameFlag = &cli.StringFlag{
|
||||
Name: "name",
|
||||
Aliases: []string{"n"},
|
||||
Usage: "List tunnels with the given name",
|
||||
Usage: "List tunnels with the given `NAME`",
|
||||
}
|
||||
listExistedAtFlag = &cli.TimestampFlag{
|
||||
Name: "when",
|
||||
Aliases: []string{"w"},
|
||||
Usage: fmt.Sprintf("List tunnels that are active at the given time, expect format in RFC3339 (%s)", time.Now().Format(tunnelstore.TimeLayout)),
|
||||
Layout: tunnelstore.TimeLayout,
|
||||
Name: "when",
|
||||
Aliases: []string{"w"},
|
||||
Usage: "List tunnels that are active at the given `TIME` in RFC3339 format",
|
||||
Layout: tunnelstore.TimeLayout,
|
||||
DefaultText: fmt.Sprintf("current time, %s", time.Now().Format(tunnelstore.TimeLayout)),
|
||||
}
|
||||
listIDFlag = &cli.StringFlag{
|
||||
Name: "id",
|
||||
Aliases: []string{"i"},
|
||||
Usage: "List tunnel by ID",
|
||||
Usage: "List tunnel by `ID`",
|
||||
}
|
||||
showRecentlyDisconnected = &cli.BoolFlag{
|
||||
Name: "show-recently-disconnected",
|
||||
@@ -80,15 +83,12 @@ var (
|
||||
}
|
||||
)
|
||||
|
||||
const hideSubcommands = true
|
||||
|
||||
func buildCreateCommand() *cli.Command {
|
||||
return &cli.Command{
|
||||
Name: "create",
|
||||
Action: cliutil.ErrorHandler(createCommand),
|
||||
Usage: "Create a new tunnel with given name",
|
||||
ArgsUsage: "TUNNEL-NAME",
|
||||
Hidden: hideSubcommands,
|
||||
Flags: []cli.Flag{outputFormatFlag},
|
||||
}
|
||||
}
|
||||
@@ -153,7 +153,6 @@ func buildListCommand() *cli.Command {
|
||||
Action: cliutil.ErrorHandler(listCommand),
|
||||
Usage: "List existing tunnels",
|
||||
ArgsUsage: " ",
|
||||
Hidden: hideSubcommands,
|
||||
Flags: []cli.Flag{outputFormatFlag, showDeletedFlag, listNameFlag, listExistedAtFlag, listIDFlag, showRecentlyDisconnected},
|
||||
}
|
||||
}
|
||||
@@ -209,6 +208,7 @@ func fmtAndPrintTunnelList(tunnels []*tunnelstore.Tunnel, showRecentlyDisconnect
|
||||
)
|
||||
|
||||
writer := tabwriter.NewWriter(os.Stdout, minWidth, tabWidth, padding, padChar, flags)
|
||||
defer writer.Flush()
|
||||
|
||||
// Print column headers with tabbed columns
|
||||
fmt.Fprintln(writer, "ID\tNAME\tCREATED\tCONNECTIONS\t")
|
||||
@@ -224,9 +224,6 @@ func fmtAndPrintTunnelList(tunnels []*tunnelstore.Tunnel, showRecentlyDisconnect
|
||||
)
|
||||
fmt.Fprintln(writer, formattedStr)
|
||||
}
|
||||
|
||||
// Write data buffered in tabwriter to output
|
||||
writer.Flush()
|
||||
}
|
||||
|
||||
func fmtConnections(connections []tunnelstore.Connection, showRecentlyDisconnected bool) string {
|
||||
@@ -258,9 +255,8 @@ func buildDeleteCommand() *cli.Command {
|
||||
return &cli.Command{
|
||||
Name: "delete",
|
||||
Action: cliutil.ErrorHandler(deleteCommand),
|
||||
Usage: "Delete existing tunnel with given IDs",
|
||||
ArgsUsage: "TUNNEL-ID",
|
||||
Hidden: hideSubcommands,
|
||||
Usage: "Delete existing tunnel by UUID or name",
|
||||
ArgsUsage: "TUNNEL",
|
||||
Flags: []cli.Flag{credentialsFileFlag, forceDeleteFlag},
|
||||
}
|
||||
}
|
||||
@@ -297,17 +293,48 @@ func renderOutput(format string, v interface{}) error {
|
||||
}
|
||||
|
||||
func buildRunCommand() *cli.Command {
|
||||
flags := []cli.Flag{
|
||||
forceFlag,
|
||||
credentialsFileFlag,
|
||||
urlFlag(false),
|
||||
helloWorldFlag(false),
|
||||
createSocks5Flag(false),
|
||||
}
|
||||
flags = append(flags, sshFlags(false)...)
|
||||
var runCommandHelpTemplate = `NAME:
|
||||
{{.HelpName}} - {{.Usage}}
|
||||
|
||||
USAGE:
|
||||
{{.UsageText}}
|
||||
|
||||
DESCRIPTION:
|
||||
{{.Description}}
|
||||
|
||||
TUNNEL COMMAND OPTIONS:
|
||||
See cloudflared tunnel -h
|
||||
|
||||
RUN COMMAND OPTIONS:
|
||||
{{range .VisibleFlags}}{{.}}
|
||||
{{end}}
|
||||
`
|
||||
return &cli.Command{
|
||||
Name: "run",
|
||||
Action: cliutil.ErrorHandler(runCommand),
|
||||
Usage: "Proxy a local web server by running the given tunnel",
|
||||
ArgsUsage: "TUNNEL-ID",
|
||||
Description: "Runs the tunnel, creating a high-availability connection between your server and the Cloudflare " +
|
||||
"edge. This command requires the tunnel credentials file created when `cloudflared tunnel create` was run, but " +
|
||||
"does not require the cert.pem from `cloudflared login`. If you experience problems running the tunnel, " +
|
||||
"`cloudflared tunnel cleanup` may help by removing any old connection records.",
|
||||
Hidden: hideSubcommands,
|
||||
Flags: []cli.Flag{forceFlag, credentialsFileFlag},
|
||||
UsageText: "cloudflared tunnel [tunnel command options] run [run command options]",
|
||||
ArgsUsage: "TUNNEL",
|
||||
Description: `Runs the tunnel identified by name or UUUD, creating a highly available connection
|
||||
between your server and the Cloudflare edge.
|
||||
|
||||
This command requires the tunnel credentials file created when "cloudflared tunnel create" was run,
|
||||
however it does not need access to cert.pem from "cloudflared login". If you experience problems running
|
||||
the tunnel, "cloudflared tunnel cleanup" may help by removing any old connection records.
|
||||
|
||||
All the flags from the tunnel command are available, note that they have to be specified before the run command. There are flags defined both in tunnel and run command. The one in run command will take precedence.
|
||||
For example cloudflared tunnel --url localhost:3000 run --url localhost:5000 <TUNNEL ID> will proxy requests to localhost:5000.
|
||||
`,
|
||||
Flags: flags,
|
||||
CustomHelpTemplate: runCommandHelpTemplate,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -332,9 +359,8 @@ func buildCleanupCommand() *cli.Command {
|
||||
return &cli.Command{
|
||||
Name: "cleanup",
|
||||
Action: cliutil.ErrorHandler(cleanupCommand),
|
||||
Usage: "Cleanup connections for the tunnel with given IDs",
|
||||
ArgsUsage: "TUNNEL-IDS",
|
||||
Hidden: hideSubcommands,
|
||||
Usage: "Cleanup tunnel connections",
|
||||
ArgsUsage: "TUNNEL",
|
||||
}
|
||||
}
|
||||
|
||||
@@ -361,51 +387,75 @@ func buildRouteCommand() *cli.Command {
|
||||
Name: "route",
|
||||
Action: cliutil.ErrorHandler(routeCommand),
|
||||
Usage: "Define what hostname or load balancer can route to this tunnel",
|
||||
Description: `The route defines what hostname or load balancer can route to this tunnel.
|
||||
To route a hostname: cloudflared tunnel route dns <tunnel ID> <hostname>
|
||||
To route a load balancer: cloudflared tunnel route lb <tunnel ID> <load balancer name> <load balancer pool>
|
||||
If you don't specify a load balancer pool, we will create a new pool called tunnel:<tunnel ID>`,
|
||||
ArgsUsage: "dns|lb TUNNEL-ID HOSTNAME [LB-POOL]",
|
||||
Hidden: hideSubcommands,
|
||||
Description: `The route defines what hostname or load balancer will proxy requests to this tunnel.
|
||||
|
||||
To route a hostname by creating a CNAME to tunnel's address:
|
||||
cloudflared tunnel route dns <tunnel ID> <hostname>
|
||||
To use this tunnel as a load balancer origin, creating pool and load balancer if necessary:
|
||||
cloudflared tunnel route lb <tunnel ID> <load balancer name> <load balancer pool>`,
|
||||
ArgsUsage: "dns|lb TUNNEL HOSTNAME [LB-POOL]",
|
||||
}
|
||||
}
|
||||
|
||||
func dnsRouteFromArg(c *cli.Context, tunnelID uuid.UUID) (tunnelstore.Route, error) {
|
||||
func dnsRouteFromArg(c *cli.Context) (tunnelstore.Route, error) {
|
||||
const (
|
||||
userHostnameIndex = 2
|
||||
expectArgs = 3
|
||||
expectedNArgs = 3
|
||||
)
|
||||
if c.NArg() != expectArgs {
|
||||
return nil, cliutil.UsageError("Expect %d arguments, got %d", expectArgs, c.NArg())
|
||||
if c.NArg() != expectedNArgs {
|
||||
return nil, cliutil.UsageError("Expected %d arguments, got %d", expectedNArgs, c.NArg())
|
||||
}
|
||||
userHostname := c.Args().Get(userHostnameIndex)
|
||||
if userHostname == "" {
|
||||
return nil, cliutil.UsageError("The third argument should be the hostname")
|
||||
} else if !validateHostname(userHostname) {
|
||||
return nil, errors.Errorf("%s is not a valid hostname", userHostname)
|
||||
}
|
||||
return tunnelstore.NewDNSRoute(userHostname), nil
|
||||
}
|
||||
|
||||
func lbRouteFromArg(c *cli.Context, tunnelID uuid.UUID) (tunnelstore.Route, error) {
|
||||
func lbRouteFromArg(c *cli.Context) (tunnelstore.Route, error) {
|
||||
const (
|
||||
lbNameIndex = 2
|
||||
lbPoolIndex = 3
|
||||
expectMinArgs = 3
|
||||
expectedNArgs = 4
|
||||
)
|
||||
if c.NArg() < expectMinArgs {
|
||||
return nil, cliutil.UsageError("Expect at least %d arguments, got %d", expectMinArgs, c.NArg())
|
||||
if c.NArg() != expectedNArgs {
|
||||
return nil, cliutil.UsageError("Expected %d arguments, got %d", expectedNArgs, c.NArg())
|
||||
}
|
||||
lbName := c.Args().Get(lbNameIndex)
|
||||
if lbName == "" {
|
||||
return nil, cliutil.UsageError("The third argument should be the load balancer name")
|
||||
} else if !validateHostname(lbName) {
|
||||
return nil, errors.Errorf("%s is not a valid load balancer name", lbName)
|
||||
}
|
||||
|
||||
lbPool := c.Args().Get(lbPoolIndex)
|
||||
if lbPool == "" {
|
||||
lbPool = defaultPoolName(tunnelID)
|
||||
return nil, cliutil.UsageError("The fourth argument should be the pool name")
|
||||
} else if !validateName(lbPool) {
|
||||
return nil, errors.Errorf("%s is not a valid pool name", lbPool)
|
||||
}
|
||||
|
||||
return tunnelstore.NewLBRoute(lbName, lbPool), nil
|
||||
}
|
||||
|
||||
var nameRegex = regexp.MustCompile("^[_a-zA-Z0-9][-_.a-zA-Z0-9]*$")
|
||||
|
||||
func validateName(s string) bool {
|
||||
return nameRegex.MatchString(s)
|
||||
}
|
||||
|
||||
func validateHostname(s string) bool {
|
||||
// Slightly stricter than PunyCodeProfile
|
||||
idnaProfile := idna.New(
|
||||
idna.ValidateLabels(true),
|
||||
idna.VerifyDNSLength(true))
|
||||
|
||||
puny, err := idnaProfile.ToASCII(s)
|
||||
return err == nil && validateName(puny)
|
||||
}
|
||||
|
||||
func routeCommand(c *cli.Context) error {
|
||||
if c.NArg() < 2 {
|
||||
return cliutil.UsageError(`"cloudflared tunnel route" requires the first argument to be the route type(dns or lb), followed by the ID or name of the tunnel`)
|
||||
@@ -418,7 +468,7 @@ func routeCommand(c *cli.Context) error {
|
||||
const tunnelIDIndex = 1
|
||||
|
||||
routeType := c.Args().First()
|
||||
var r tunnelstore.Route
|
||||
var route tunnelstore.Route
|
||||
var tunnelID uuid.UUID
|
||||
switch routeType {
|
||||
case "dns":
|
||||
@@ -426,7 +476,7 @@ func routeCommand(c *cli.Context) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
r, err = dnsRouteFromArg(c, tunnelID)
|
||||
route, err = dnsRouteFromArg(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -435,7 +485,7 @@ func routeCommand(c *cli.Context) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
r, err = lbRouteFromArg(c, tunnelID)
|
||||
route, err = lbRouteFromArg(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -443,13 +493,11 @@ func routeCommand(c *cli.Context) error {
|
||||
return cliutil.UsageError("%s is not a recognized route type. Supported route types are dns and lb", routeType)
|
||||
}
|
||||
|
||||
if err := sc.route(tunnelID, r); err != nil {
|
||||
res, err := sc.route(tunnelID, route)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sc.logger.Infof(r.SuccessSummary())
|
||||
|
||||
sc.logger.Infof(res.SuccessSummary())
|
||||
return nil
|
||||
}
|
||||
|
||||
func defaultPoolName(tunnelID uuid.UUID) string {
|
||||
return fmt.Sprintf("tunnel:%v", tunnelID)
|
||||
}
|
||||
|
||||
@@ -98,3 +98,27 @@ func TestTunnelfilePath(t *testing.T) {
|
||||
expected := fmt.Sprintf("%s/.cloudflared/%v.json", homeDir, tunnelID)
|
||||
assert.Equal(t, expected, actual)
|
||||
}
|
||||
|
||||
func TestValidateName(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
want bool
|
||||
}{
|
||||
{name: "", want: false},
|
||||
{name: "-", want: false},
|
||||
{name: ".", want: false},
|
||||
{name: "a b", want: false},
|
||||
{name: "a+b", want: false},
|
||||
{name: "-ab", want: false},
|
||||
|
||||
{name: "ab", want: true},
|
||||
{name: "ab-c", want: true},
|
||||
{name: "abc.def", want: true},
|
||||
{name: "_ab_c.-d-ef", want: true},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
if got := validateName(tt.name); got != tt.want {
|
||||
t.Errorf("validateName() = %v, want %v", got, tt.want)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,236 @@
|
||||
package ui
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/cloudflare/cloudflared/logger"
|
||||
|
||||
"github.com/gdamore/tcell"
|
||||
"github.com/rivo/tview"
|
||||
)
|
||||
|
||||
type connState struct {
|
||||
location string
|
||||
state status
|
||||
}
|
||||
|
||||
type status int
|
||||
|
||||
const (
|
||||
Disconnected status = iota
|
||||
Connected
|
||||
Reconnecting
|
||||
SetUrl
|
||||
RegisteringTunnel
|
||||
)
|
||||
|
||||
type TunnelEvent struct {
|
||||
Index uint8
|
||||
EventType status
|
||||
Location string
|
||||
Url string
|
||||
}
|
||||
|
||||
type uiModel struct {
|
||||
version string
|
||||
edgeURL string
|
||||
metricsURL string
|
||||
proxyURL string
|
||||
connections []connState
|
||||
}
|
||||
|
||||
type palette struct {
|
||||
url string
|
||||
connected string
|
||||
defaultText string
|
||||
disconnected string
|
||||
reconnecting string
|
||||
}
|
||||
|
||||
func NewUIModel(version, hostname, metricsURL, proxyURL string, haConnections int) *uiModel {
|
||||
return &uiModel{
|
||||
version: version,
|
||||
edgeURL: hostname,
|
||||
metricsURL: metricsURL,
|
||||
proxyURL: proxyURL,
|
||||
connections: make([]connState, haConnections),
|
||||
}
|
||||
}
|
||||
|
||||
func (data *uiModel) LaunchUI(
|
||||
ctx context.Context,
|
||||
log logger.Service,
|
||||
logLevels []logger.Level,
|
||||
tunnelEventChan <-chan TunnelEvent,
|
||||
) {
|
||||
// Configure the logger to stream logs into the textview
|
||||
|
||||
// Add TextView as a group to write output to
|
||||
logTextView := NewDynamicColorTextView()
|
||||
log.Add(logTextView, logger.NewUIFormatter(time.RFC3339), logLevels...)
|
||||
|
||||
// Construct the UI
|
||||
palette := palette{
|
||||
url: "lightblue",
|
||||
connected: "lime",
|
||||
defaultText: "white",
|
||||
disconnected: "red",
|
||||
reconnecting: "orange",
|
||||
}
|
||||
|
||||
app := tview.NewApplication()
|
||||
|
||||
grid := tview.NewGrid().SetGap(1, 0)
|
||||
frame := tview.NewFrame(grid)
|
||||
header := fmt.Sprintf("cloudflared [::b]%s", data.version)
|
||||
|
||||
frame.AddText(header, true, tview.AlignLeft, tcell.ColorWhite)
|
||||
|
||||
// Create table to store connection info and status
|
||||
connTable := tview.NewTable()
|
||||
// SetColumns takes a value for each column, representing the size of the column
|
||||
// Numbers <= 0 represent proportional widths and positive numbers represent absolute widths
|
||||
grid.SetColumns(20, 0)
|
||||
|
||||
// SetRows takes a value for each row, representing the size of the row
|
||||
grid.SetRows(1, 1, len(data.connections), 1, 0)
|
||||
|
||||
// AddItem takes a primitive tview type, row, column, rowSpan, columnSpan, minGridHeight, minGridWidth, and focus
|
||||
grid.AddItem(tview.NewTextView().SetText("Tunnel:"), 0, 0, 1, 1, 0, 0, false)
|
||||
grid.AddItem(tview.NewTextView().SetText("Status:"), 1, 0, 1, 1, 0, 0, false)
|
||||
grid.AddItem(tview.NewTextView().SetText("Connections:"), 2, 0, 1, 1, 0, 0, false)
|
||||
|
||||
grid.AddItem(tview.NewTextView().SetText("Metrics:"), 3, 0, 1, 1, 0, 0, false)
|
||||
|
||||
tunnelHostText := tview.NewTextView().SetText(data.edgeURL)
|
||||
|
||||
grid.AddItem(tunnelHostText, 0, 1, 1, 1, 0, 0, false)
|
||||
grid.AddItem(NewDynamicColorTextView().SetText(fmt.Sprintf("[%s]\u2022[%s] Proxying to [%s::b]%s", palette.connected, palette.defaultText, palette.url, data.proxyURL)), 1, 1, 1, 1, 0, 0, false)
|
||||
|
||||
grid.AddItem(connTable, 2, 1, 1, 1, 0, 0, false)
|
||||
|
||||
grid.AddItem(NewDynamicColorTextView().SetText(fmt.Sprintf("Metrics at [%s::b]http://%s/metrics", palette.url, data.metricsURL)), 3, 1, 1, 1, 0, 0, false)
|
||||
|
||||
// Add TextView to stream logs
|
||||
// Logs are displayed in a new grid so a border can be set around them
|
||||
logGrid := tview.NewGrid().SetBorders(true).AddItem(logTextView.SetChangedFunc(handleNewText(app, logTextView)), 0, 0, 5, 2, 0, 0, false)
|
||||
// LogFrame holds the Logs header as well as the grid with the textView for streamed logs
|
||||
logFrame := tview.NewFrame(logGrid).AddText("[::b]Logs:[::-]", true, tview.AlignLeft, tcell.ColorWhite).SetBorders(0, 0, 0, 0, 0, 0)
|
||||
// Footer for log frame
|
||||
logFrame.AddText("[::d]Use Ctrl+C to exit[::-]", false, tview.AlignRight, tcell.ColorWhite)
|
||||
grid.AddItem(logFrame, 4, 0, 5, 2, 0, 0, false)
|
||||
|
||||
go func() {
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
app.Stop()
|
||||
return
|
||||
case event := <-tunnelEventChan:
|
||||
switch event.EventType {
|
||||
case Connected:
|
||||
data.setConnTableCell(event, connTable, palette)
|
||||
case Disconnected, Reconnecting:
|
||||
data.changeConnStatus(event, connTable, log, palette)
|
||||
case SetUrl:
|
||||
tunnelHostText.SetText(event.Url)
|
||||
data.edgeURL = event.Url
|
||||
case RegisteringTunnel:
|
||||
if data.edgeURL == "" {
|
||||
tunnelHostText.SetText("Registering tunnel...")
|
||||
}
|
||||
}
|
||||
}
|
||||
app.Draw()
|
||||
}
|
||||
}()
|
||||
|
||||
go func() {
|
||||
if err := app.SetRoot(frame, true).Run(); err != nil {
|
||||
log.Errorf("Error launching UI: %s", err)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
func NewDynamicColorTextView() *tview.TextView {
|
||||
return tview.NewTextView().SetDynamicColors(true)
|
||||
}
|
||||
|
||||
// Re-draws application when new logs are streamed to UI
|
||||
func handleNewText(app *tview.Application, logTextView *tview.TextView) func() {
|
||||
return func() {
|
||||
app.Draw()
|
||||
// SetFocus to enable scrolling in textview
|
||||
app.SetFocus(logTextView)
|
||||
}
|
||||
}
|
||||
|
||||
func (data *uiModel) changeConnStatus(event TunnelEvent, table *tview.Table, logger logger.Service, palette palette) {
|
||||
index := int(event.Index)
|
||||
// Get connection location and state
|
||||
connState := data.getConnState(index)
|
||||
// Check if connection is already displayed in UI
|
||||
if connState == nil {
|
||||
logger.Info("Connection is not in the UI table")
|
||||
return
|
||||
}
|
||||
|
||||
locationState := event.Location
|
||||
|
||||
if event.EventType == Disconnected {
|
||||
connState.state = Disconnected
|
||||
} else if event.EventType == Reconnecting {
|
||||
connState.state = Reconnecting
|
||||
locationState = "Reconnecting..."
|
||||
}
|
||||
|
||||
connectionNum := index + 1
|
||||
// Get table cell
|
||||
cell := table.GetCell(index, 0)
|
||||
// Change dot color in front of text as well as location state
|
||||
text := newCellText(palette, connectionNum, locationState, event.EventType)
|
||||
cell.SetText(text)
|
||||
}
|
||||
|
||||
// Return connection location and row in UI table
|
||||
func (data *uiModel) getConnState(connID int) *connState {
|
||||
if connID < len(data.connections) {
|
||||
return &data.connections[connID]
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (data *uiModel) setConnTableCell(event TunnelEvent, table *tview.Table, palette palette) {
|
||||
index := int(event.Index)
|
||||
connectionNum := index + 1
|
||||
|
||||
// Update slice to keep track of connection location and state in UI table
|
||||
data.connections[index].state = Connected
|
||||
data.connections[index].location = event.Location
|
||||
|
||||
// Update text in table cell to show disconnected state
|
||||
text := newCellText(palette, connectionNum, event.Location, event.EventType)
|
||||
cell := tview.NewTableCell(text)
|
||||
table.SetCell(index, 0, cell)
|
||||
}
|
||||
|
||||
func newCellText(palette palette, connectionNum int, location string, connectedStatus status) string {
|
||||
// HA connection indicator formatted as: "• #<CONNECTION_INDEX>: <COLO>",
|
||||
// where the left middle dot's color depends on the status of the connection
|
||||
const connFmtString = "[%s]\u2022[%s] #%d: %s"
|
||||
|
||||
var dotColor string
|
||||
switch connectedStatus {
|
||||
case Connected:
|
||||
dotColor = palette.connected
|
||||
case Disconnected:
|
||||
dotColor = palette.disconnected
|
||||
case Reconnecting:
|
||||
dotColor = palette.reconnecting
|
||||
}
|
||||
|
||||
return fmt.Sprintf(connFmtString, dotColor, palette.defaultText, connectionNum, location)
|
||||
}
|
||||
+1
-1
@@ -107,7 +107,7 @@ def main():
|
||||
return
|
||||
|
||||
# update the release body text
|
||||
release.update_release(args.release_version, args.release_version, msg)
|
||||
release.update_release(args.release_version, msg)
|
||||
|
||||
except Exception as e:
|
||||
logging.exception(e)
|
||||
|
||||
@@ -7,6 +7,8 @@ import argparse
|
||||
import logging
|
||||
import os
|
||||
import shutil
|
||||
import hashlib
|
||||
import requests
|
||||
|
||||
from github import Github, GithubException, UnknownObjectException
|
||||
|
||||
@@ -15,6 +17,37 @@ logging.basicConfig(format=FORMAT)
|
||||
|
||||
CLOUDFLARED_REPO = os.environ.get("GITHUB_REPO", "cloudflare/cloudflared")
|
||||
GITHUB_CONFLICT_CODE = "already_exists"
|
||||
BASE_KV_URL = 'https://api.cloudflare.com/client/v4/accounts/'
|
||||
UPDATER_PREFIX = 'update'
|
||||
|
||||
def get_sha256(filename):
|
||||
""" get the sha256 of a file """
|
||||
sha256_hash = hashlib.sha256()
|
||||
with open(filename,"rb") as f:
|
||||
for byte_block in iter(lambda: f.read(4096),b""):
|
||||
sha256_hash.update(byte_block)
|
||||
return sha256_hash.hexdigest()
|
||||
|
||||
def send_hash(pkg_hash, name, version, account, namespace, api_token):
|
||||
""" send the checksum of a file to workers kv """
|
||||
key = '{0}_{1}_{2}'.format(UPDATER_PREFIX, version, name)
|
||||
headers = {
|
||||
"Content-Type": "application/json",
|
||||
"Authorization": "Bearer " + api_token,
|
||||
}
|
||||
response = requests.put(
|
||||
BASE_KV_URL + account + "/storage/kv/namespaces/" + namespace + "/values/" + key,
|
||||
headers=headers,
|
||||
data=pkg_hash
|
||||
)
|
||||
|
||||
if response.status_code != 200:
|
||||
jsonResponse = response.json()
|
||||
errors = jsonResponse["errors"]
|
||||
if len(errors) > 0:
|
||||
raise Exception("failed to upload checksum: {0}", errors[0])
|
||||
|
||||
|
||||
|
||||
def assert_tag_exists(repo, version):
|
||||
""" Raise exception if repo does not contain a tag matching version """
|
||||
@@ -78,6 +111,15 @@ def parse_args():
|
||||
parser.add_argument(
|
||||
"--name", default=os.environ.get("ASSET_NAME"), help="Asset Name"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--namespace-id", default=os.environ.get("KV_NAMESPACE"), help="workersKV namespace id"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--kv-account-id", default=os.environ.get("KV_ACCOUNT"), help="workersKV account id"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--kv-api-token", default=os.environ.get("KV_API_TOKEN"), help="workersKV API Token"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--dry-run", action="store_true", help="Do not create release or upload asset"
|
||||
)
|
||||
@@ -99,6 +141,18 @@ def parse_args():
|
||||
if not args.api_key:
|
||||
logging.error("Missing API key")
|
||||
is_valid = False
|
||||
|
||||
if not args.namespace_id:
|
||||
logging.error("Missing KV namespace id")
|
||||
is_valid = False
|
||||
|
||||
if not args.kv_account_id:
|
||||
logging.error("Missing KV account id")
|
||||
is_valid = False
|
||||
|
||||
if not args.kv_api_token:
|
||||
logging.error("Missing KV API token")
|
||||
is_valid = False
|
||||
|
||||
if is_valid:
|
||||
return args
|
||||
@@ -121,6 +175,10 @@ def main():
|
||||
|
||||
release.upload_asset(args.path, name=args.name)
|
||||
|
||||
# send the sha256 (the checksum) to workers kv
|
||||
pkg_hash = get_sha256(args.path)
|
||||
send_hash(pkg_hash, args.name, args.release_version, args.kv_account_id, args.namespace_id, args.kv_api_token)
|
||||
|
||||
# create the artifacts directory if it doesn't exist
|
||||
artifact_path = os.path.join(os.getcwd(), 'artifacts')
|
||||
if not os.path.isdir(artifact_path):
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
module github.com/cloudflare/cloudflared
|
||||
|
||||
go 1.14
|
||||
go 1.15
|
||||
|
||||
require (
|
||||
github.com/DATA-DOG/go-sqlmock v1.3.3
|
||||
@@ -23,6 +23,7 @@ require (
|
||||
github.com/facebookgo/subset v0.0.0-20150612182917-8dac2c3c4870 // indirect
|
||||
github.com/frankban/quicktest v1.10.0 // indirect
|
||||
github.com/fsnotify/fsnotify v1.4.9
|
||||
github.com/gdamore/tcell v1.3.0
|
||||
github.com/getsentry/raven-go v0.0.0-20180517221441-ed7bcb39ff10
|
||||
github.com/gliderlabs/ssh v0.0.0-20191009160644-63518b5243e0
|
||||
github.com/go-sql-driver/mysql v1.5.0
|
||||
@@ -46,6 +47,8 @@ require (
|
||||
github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35 // indirect
|
||||
github.com/prometheus/client_golang v1.7.1
|
||||
github.com/prometheus/common v0.13.0 // indirect
|
||||
github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5 // indirect
|
||||
github.com/rivo/tview v0.0.0-20200712113419-c65badfc3d92
|
||||
github.com/stretchr/testify v1.6.0
|
||||
github.com/urfave/cli/v2 v2.2.0
|
||||
github.com/xo/dburl v0.0.0-20191005012637-293c3298d6c0
|
||||
|
||||
@@ -9,11 +9,9 @@ cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6T
|
||||
cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
|
||||
cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
|
||||
cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
|
||||
cloud.google.com/go v0.56.0 h1:WRz29PgAsVEyPSDHyk+0fpEkwEFyfhHn+JbksT6gIL4=
|
||||
cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=
|
||||
cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
|
||||
cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
|
||||
cloud.google.com/go v0.65.0 h1:Dg9iHVQfrhq82rUNu9ZxUDrJLaxFUe/HlCVaLyRruq8=
|
||||
cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
|
||||
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
|
||||
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
|
||||
@@ -35,49 +33,38 @@ cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9
|
||||
contrib.go.opencensus.io/exporter/ocagent v0.4.12/go.mod h1:450APlNTSR6FrvC3CTRqYosuDstRB9un7SOx2k/9ckA=
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
github.com/Azure/azure-sdk-for-go v32.4.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
|
||||
github.com/Azure/azure-sdk-for-go v40.6.0+incompatible h1:ULjp/a/UsBfnZcl45jjywhcBKex/k/A1cG9s9NapLFw=
|
||||
github.com/Azure/azure-sdk-for-go v40.6.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
|
||||
github.com/Azure/go-autorest/autorest v0.1.0/go.mod h1:AKyIcETwSUFxIcs/Wnq/C+kwCtlEYGUVd7FPNb2slmg=
|
||||
github.com/Azure/go-autorest/autorest v0.5.0/go.mod h1:9HLKlQjVBH6U3oDfsXOeVc56THsLPw1L03yban4xThw=
|
||||
github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI=
|
||||
github.com/Azure/go-autorest/autorest v0.9.3/go.mod h1:GsRuLYvwzLjjjRoWEIyMUaYq8GNUx2nRB378IPt/1p0=
|
||||
github.com/Azure/go-autorest/autorest v0.10.2 h1:NuSF3gXetiHyUbVdneJMEVyPUYAe5wh+aN08JYAf1tI=
|
||||
github.com/Azure/go-autorest/autorest v0.10.2/go.mod h1:/FALq9T/kS7b5J5qsQ+RSTUdAmGFqi0vUdVNNx8q630=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.1.0/go.mod h1:MeS4XhScH55IST095THyTxElntu7WqB7pNbZo8Q5G3E=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.2.0/go.mod h1:MeS4XhScH55IST095THyTxElntu7WqB7pNbZo8Q5G3E=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.8.0/go.mod h1:Z6vX6WXXuyieHAXwMj0S6HY6e6wcHn37qQMBQlvY3lc=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.8.1/go.mod h1:ZjhuQClTqx435SRJ2iMlOxPYt3d2C/T/7TiQCVZSn3Q=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.8.2 h1:O1X4oexUxnZCaEUGsvMnr8ZGj8HI37tNezwY4npRqA0=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.8.2/go.mod h1:ZjhuQClTqx435SRJ2iMlOxPYt3d2C/T/7TiQCVZSn3Q=
|
||||
github.com/Azure/go-autorest/autorest/azure/auth v0.1.0/go.mod h1:Gf7/i2FUpyb/sGBLIFxTBzrNzBo7aPXXE3ZVeDRwdpM=
|
||||
github.com/Azure/go-autorest/autorest/azure/auth v0.4.2 h1:iM6UAvjR97ZIeR93qTcwpKNMpV+/FTWjwEbuPD495Tk=
|
||||
github.com/Azure/go-autorest/autorest/azure/auth v0.4.2/go.mod h1:90gmfKdlmKgfjUpnCEpOJzsUEjrWDSLwHIG73tSXddM=
|
||||
github.com/Azure/go-autorest/autorest/azure/cli v0.1.0/go.mod h1:Dk8CUAt/b/PzkfeRsWzVG9Yj3ps8mS8ECztu43rdU8U=
|
||||
github.com/Azure/go-autorest/autorest/azure/cli v0.3.1 h1:LXl088ZQlP0SBppGFsRZonW6hSvwgL5gRByMbvUbx8U=
|
||||
github.com/Azure/go-autorest/autorest/azure/cli v0.3.1/go.mod h1:ZG5p860J94/0kI9mNJVoIoLgXcirM2gF5i2kWloofxw=
|
||||
github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA=
|
||||
github.com/Azure/go-autorest/autorest/date v0.2.0 h1:yW+Zlqf26583pE43KhfnhFcdmSWlm5Ew6bxipnr/tbM=
|
||||
github.com/Azure/go-autorest/autorest/date v0.2.0/go.mod h1:vcORJHLJEh643/Ioh9+vPmf1Ij9AEBM5FuBIXLmIy0g=
|
||||
github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0=
|
||||
github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0=
|
||||
github.com/Azure/go-autorest/autorest/mocks v0.3.0/go.mod h1:a8FDP3DYzQ4RYfVAxAN3SVSiiO77gL2j2ronKKP0syM=
|
||||
github.com/Azure/go-autorest/autorest/to v0.2.0 h1:nQOZzFCudTh+TvquAtCRjM01VEYx85e9qbwt5ncW4L8=
|
||||
github.com/Azure/go-autorest/autorest/to v0.2.0/go.mod h1:GunWKJp1AEqgMaGLV+iocmRAJWqST1wQYhyyjXJ3SJc=
|
||||
github.com/Azure/go-autorest/autorest/validation v0.1.0/go.mod h1:Ha3z/SqBeaalWQvokg3NZAlQTalVMtOIAs1aGK7G6u8=
|
||||
github.com/Azure/go-autorest/logger v0.1.0 h1:ruG4BSDXONFRrZZJ2GUXDiUyVpayPmb1GnWeHDdaNKY=
|
||||
github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc=
|
||||
github.com/Azure/go-autorest/tracing v0.1.0/go.mod h1:ROEEAFwXycQw7Sn3DXNtEedEvdeRAgDr0izn4z5Ij88=
|
||||
github.com/Azure/go-autorest/tracing v0.5.0 h1:TRn4WjSnkcSy5AEG3pnbtFSwNtwzjr4VYyQflFE619k=
|
||||
github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk=
|
||||
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
github.com/DATA-DOG/go-sqlmock v1.3.3 h1:CWUqKXe0s8A2z6qCgkP4Kru7wC11YoAnoupUKFDnH08=
|
||||
github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
|
||||
github.com/DataDog/datadog-go v3.5.0+incompatible h1:AShr9cqkF+taHjyQgcBcQUt/ZNK+iPq4ROaZwSX5c/U=
|
||||
github.com/DataDog/datadog-go v3.5.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
|
||||
github.com/DataDog/zstd v1.3.5 h1:DtpNbljikUepEPD16hD4LvIcmhnhdLTiW/5pHgbmp14=
|
||||
github.com/DataDog/zstd v1.3.5/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo=
|
||||
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
|
||||
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
|
||||
@@ -85,7 +72,6 @@ github.com/OpenDNS/vegadns2client v0.0.0-20180418235048-a3fa4a771d87/go.mod h1:i
|
||||
github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
||||
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
|
||||
github.com/Shopify/sarama v1.21.0 h1:0GKs+e8mn1RRUzfg9oUXv3v7ZieQLmOZF/bfnmmGhM8=
|
||||
github.com/Shopify/sarama v1.21.0/go.mod h1:yuqtN/pe8cXRWG5zPaO7hCfNJp5MwmkoJEoLjkm5tCQ=
|
||||
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
|
||||
github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g=
|
||||
@@ -97,7 +83,6 @@ github.com/alangpierce/go-forceexport v0.0.0-20160317203124-8f1d6941cd75/go.mod
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4 h1:Hs82Z41s6SdL1CELW+XaDYmOH4hkBN4/N9og/AsOv7E=
|
||||
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d h1:UQZhZ2O0vMHr2cI+DC1Mbh0TJxzA3RcLoMsFw+aXw7E=
|
||||
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
|
||||
@@ -106,7 +91,6 @@ github.com/aliyun/aliyun-oss-go-sdk v0.0.0-20190307165228-86c17b95fcd5/go.mod h1
|
||||
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA=
|
||||
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
|
||||
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
|
||||
github.com/apache/thrift v0.13.0 h1:5hryIiq9gtn+MiLVn0wP37kb/uTeRZgN08WoCsAhIhI=
|
||||
github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
|
||||
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
|
||||
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
|
||||
@@ -115,7 +99,6 @@ github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6l
|
||||
github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU=
|
||||
github.com/aws/aws-sdk-go v1.23.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
|
||||
github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
|
||||
github.com/aws/aws-sdk-go v1.32.1 h1:0dy5DkMKNPH9mLWveAWA9ZTiKIEEvJJA6fbe0eCs19k=
|
||||
github.com/aws/aws-sdk-go v1.32.1/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0=
|
||||
github.com/aws/aws-sdk-go v1.34.19 h1:x3MMvAJ1nfWviixEduchBSs65DgY5Y2pA2/NAcxVGOo=
|
||||
github.com/aws/aws-sdk-go v1.34.19/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0=
|
||||
@@ -126,15 +109,12 @@ github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+Ce
|
||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
|
||||
github.com/bkaradzic/go-lz4 v1.0.0 h1:RXc4wYsyz985CkXXeX04y4VnZFGG8Rd43pRaHsOXAKk=
|
||||
github.com/bkaradzic/go-lz4 v1.0.0/go.mod h1:0YdlkowM3VswSROI7qDxhRvJ3sLhlFrRRwjwegp5jy4=
|
||||
github.com/caddyserver/caddy v1.0.5 h1:5B1Hs0UF2x2tggr2X9jL2qOZtDXbIWQb9YLbmlxHSuM=
|
||||
github.com/caddyserver/caddy v1.0.5/go.mod h1:AnFHB+/MrgRC+mJAvuAgQ38ePzw+wKeW0wzENpdQQKY=
|
||||
github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ=
|
||||
github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4=
|
||||
github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
|
||||
github.com/cenkalti/backoff/v3 v3.0.0/go.mod h1:cIeZDE3IrqwwJl6VUwCN6trj1oXrTS4rc0ij+ULvLYs=
|
||||
github.com/cenkalti/backoff/v4 v4.0.2 h1:JIufpQLbh4DkbQoii76ItQIUFzevQSqOLZca4eamEDs=
|
||||
github.com/cenkalti/backoff/v4 v4.0.2/go.mod h1:eEew/i+1Q6OrCDZh3WiXYv3+nJwBASZ8Bog/87DQnVg=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
@@ -162,15 +142,12 @@ github.com/coredns/coredns v1.7.0 h1:Tm2ZSdhTk+4okgjUp4K6KYzvBI2u34cdD4fKQRC4Eeo
|
||||
github.com/coredns/coredns v1.7.0/go.mod h1:7ohsH7wAKBHd/KqwsTNv5O5lpJXbq25edA/aprpRya4=
|
||||
github.com/coreos/go-oidc v0.0.0-20171002155002-a93f71fdfe73 h1:7CNPV0LWRCa1FNmqg700pbXhzvmoaXKyfxWRkjRym7Q=
|
||||
github.com/coreos/go-oidc v0.0.0-20171002155002-a93f71fdfe73/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc=
|
||||
github.com/coreos/go-semver v0.2.0 h1:3Jm3tLmsgAYcjC+4Up7hJrFBPr+n7rAqYeSw/SZazuY=
|
||||
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||
github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf h1:iW4rZ826su+pqaw19uhpSCzhj44qo35pNgKFGqzDKkU=
|
||||
github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
github.com/coreos/go-systemd/v22 v22.0.0 h1:XJIw/+VlJ+87J+doOxznsAWIdmWuViOVhkQamW5YV28=
|
||||
github.com/coreos/go-systemd/v22 v22.0.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk=
|
||||
github.com/coreos/license-bill-of-materials v0.0.0-20190913234955-13baff47494e/go.mod h1:4xMOusJ7xxc84WclVxKT8+lNfGYDwojOUC2OQNCwcj4=
|
||||
github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf h1:CAKfRE2YtTUIjjh1bkBtyYFaUT/WmOqsJjgtihT0vMI=
|
||||
github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||
github.com/cpu/goacmedns v0.0.1/go.mod h1:sesf/pNnCYwUevQEQfEwY0Y3DydlQWSGZbaMElOWxok=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY=
|
||||
@@ -183,22 +160,16 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
|
||||
github.com/decker502/dnspod-go v0.2.0/go.mod h1:qsurYu1FgxcDwfSwXJdLt4kRsBLZeosEb9uq4Sy+08g=
|
||||
github.com/denisenkom/go-mssqldb v0.0.0-20191001013358-cfbb681360f0 h1:epsH3lb7KVbXHYk7LYGN5EiE0MxcevHU85CKITJ0wUY=
|
||||
github.com/denisenkom/go-mssqldb v0.0.0-20191001013358-cfbb681360f0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||
github.com/dimchansky/utfbom v1.1.0 h1:FcM3g+nofKgUteL8dm/UpdRXNC9KmADgTpLKsu0TRo4=
|
||||
github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8=
|
||||
github.com/dnaeon/go-vcr v0.0.0-20180814043457-aafff18a5cc2/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E=
|
||||
github.com/dnsimple/dnsimple-go v0.30.0/go.mod h1:O5TJ0/U6r7AfT8niYNlmohpLbCSG+c71tQlGr9SeGrg=
|
||||
github.com/dnstap/golang-dnstap v0.2.0 h1:+NrmP4mkaTeKYV7xJ5FXpUxRn0RpcgoQcsOCTS8WQPk=
|
||||
github.com/dnstap/golang-dnstap v0.2.0/go.mod h1:s1PfVYYVmTMgCSPtho4LKBDecEHJWtiVDPNv78Z985U=
|
||||
github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM=
|
||||
github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/eapache/go-resiliency v1.1.0 h1:1NtRmCAqadE2FN4ZcN6g90TP3uk8cg9rn9eNK2197aU=
|
||||
github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
|
||||
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21 h1:YEetp8/yCZMuEPMUDHG0CW/brkkEp8mzqk2+ODEitlw=
|
||||
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
|
||||
github.com/eapache/queue v1.1.0 h1:YOEu7KNc61ntiQlcEeUIoDTJ2o8mQznoNvUhiigpIqc=
|
||||
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
|
||||
github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
|
||||
github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
|
||||
@@ -212,17 +183,12 @@ github.com/equinox-io/equinox v1.2.0 h1:bBS7Ou+Y7Jwgmy8TWSYxEh85WctuFn7FPlgbUzX4
|
||||
github.com/equinox-io/equinox v1.2.0/go.mod h1:6s3HJB0PYUNgs0mxmI8fHdfVl3TQ25ieA/PVfr+eyVo=
|
||||
github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
||||
github.com/exoscale/egoscale v0.18.1/go.mod h1:Z7OOdzzTOz1Q1PjQXumlz9Wn/CddH0zSYdCF3rnBKXE=
|
||||
github.com/facebookgo/ensure v0.0.0-20160127193407-b4ab57deab51 h1:0JZ+dUmQeA8IIVUMzysrX4/AKuQwWhV2dYQuPZdvdSQ=
|
||||
github.com/facebookgo/ensure v0.0.0-20160127193407-b4ab57deab51/go.mod h1:Yg+htXGokKKdzcwhuNDwVvN+uBxDGXJ7G/VN1d8fa64=
|
||||
github.com/facebookgo/freeport v0.0.0-20150612182905-d4adf43b75b9 h1:wWke/RUCl7VRjQhwPlR/v0glZXNYzBHdNUzf/Am2Nmg=
|
||||
github.com/facebookgo/freeport v0.0.0-20150612182905-d4adf43b75b9/go.mod h1:uPmAp6Sws4L7+Q/OokbWDAK1ibXYhB3PXFP1kol5hPg=
|
||||
github.com/facebookgo/grace v0.0.0-20180706040059-75cf19382434 h1:mOp33BLbcbJ8fvTAmZacbBiOASfxN+MLcLxymZCIrGE=
|
||||
github.com/facebookgo/grace v0.0.0-20180706040059-75cf19382434/go.mod h1:KigFdumBXUPSwzLDbeuzyt0elrL7+CP7TKuhrhT4bcU=
|
||||
github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 h1:JWuenKqqX8nojtoVVWjGfOF9635RETekkoH6Cc9SX0A=
|
||||
github.com/facebookgo/stack v0.0.0-20160209184415-751773369052/go.mod h1:UbMTZqLaRiH3MsBH8va0n7s1pQYcu3uTb8G4tygF4Zg=
|
||||
github.com/facebookgo/subset v0.0.0-20150612182917-8dac2c3c4870 h1:E2s37DuLxFhQDg5gKsWoLBOB0n+ZW8s599zru8FJ2/Y=
|
||||
github.com/facebookgo/subset v0.0.0-20150612182917-8dac2c3c4870/go.mod h1:5tD+neXqOorC30/tWg0LCSkrqj/AR6gu8yY8/fpw1q0=
|
||||
github.com/farsightsec/golang-framestream v0.0.0-20190425193708-fa4b164d59b8 h1:/iPdQppoAsTfML+yqFSq2EBChiEMnRkh5WvhFgtWwcU=
|
||||
github.com/farsightsec/golang-framestream v0.0.0-20190425193708-fa4b164d59b8/go.mod h1:eNde4IQyEiA5br02AouhEHCu3p3UzrCdFR4LuQHklMI=
|
||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
|
||||
@@ -230,11 +196,14 @@ github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BHsljHzVlRcyQhjr
|
||||
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
|
||||
github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4=
|
||||
github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20=
|
||||
github.com/frankban/quicktest v1.10.0 h1:Gfh+GAJZOAoKZsIZeZbdn2JF10kN1XHNvjsvQK8gVkE=
|
||||
github.com/frankban/quicktest v1.10.0/go.mod h1:ui7WezCLWMWxVWr1GETZY3smRy0G4KWq9vcPtJmFl7Y=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
|
||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||
github.com/gdamore/encoding v1.0.0 h1:+7OoQ1Bc6eTm5niUzBa0Ctsh6JbMW6Ra+YNuAtDBdko=
|
||||
github.com/gdamore/encoding v1.0.0/go.mod h1:alR0ol34c49FCSBLjhosxzcPHQbf2trDkoo5dl+VrEg=
|
||||
github.com/gdamore/tcell v1.3.0 h1:r35w0JBADPZCVQijYebl6YMWWtHRqVEGt7kL2eBADRM=
|
||||
github.com/gdamore/tcell v1.3.0/go.mod h1:Hjvr+Ofd+gLglo7RYKxxnzCBmev3BzsS67MebKS4zMM=
|
||||
github.com/getsentry/raven-go v0.0.0-20180517221441-ed7bcb39ff10 h1:YO10pIIBftO/kkTFdWhctH96grJ7qiy7bMdiZcIvPKs=
|
||||
github.com/getsentry/raven-go v0.0.0-20180517221441-ed7bcb39ff10/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ=
|
||||
github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
@@ -253,7 +222,6 @@ github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2
|
||||
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o=
|
||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||
github.com/go-logfmt/logfmt v0.4.0 h1:MP4Eh7ZCb31lleYCFuwm0oe4/YGak+5l1vA2NOE80nA=
|
||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
|
||||
github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
|
||||
@@ -271,19 +239,16 @@ github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFG
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
|
||||
github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls=
|
||||
github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
|
||||
github.com/goji/httpauth v0.0.0-20160601135302-2da839ab0f4d/go.mod h1:nnjvkQ9ptGaCkuDUx6wNykzzlUixGxvkme+H/lnzb+A=
|
||||
github.com/golang-collections/collections v0.0.0-20130729185459-604e922904d3 h1:zN2lZNZRflqFyxVaTIU61KNKQ9C0055u9CAfpmqUvo4=
|
||||
github.com/golang-collections/collections v0.0.0-20130729185459-604e922904d3/go.mod h1:nPpo7qLxd6XL3hWJG/O60sR8ZKfMCiIoNap5GvD12KU=
|
||||
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY=
|
||||
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY=
|
||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
@@ -296,7 +261,6 @@ github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
@@ -309,24 +273,19 @@ github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvq
|
||||
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
|
||||
github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0=
|
||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db h1:woRePGFeVFfLKN/pOkfl+p/TAqKOfFu+7KPlMVpok/w=
|
||||
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM=
|
||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g=
|
||||
github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
||||
@@ -339,19 +298,15 @@ github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hf
|
||||
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
|
||||
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y=
|
||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||
github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM=
|
||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
||||
github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
|
||||
github.com/googleapis/gnostic v0.1.0 h1:rVsPeBmXbYv4If/cumu1AzZPwV58q433hvONV1UEZoI=
|
||||
github.com/googleapis/gnostic v0.1.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
|
||||
github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8=
|
||||
github.com/gophercloud/gophercloud v0.3.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8=
|
||||
github.com/gophercloud/gophercloud v0.9.0 h1:eJHQQFguQRv2FatH2d2VXH2ueTe2XzjgjwFjFS7SGcs=
|
||||
github.com/gophercloud/gophercloud v0.9.0/go.mod h1:gmC5oQqMDOMO1t1gq5DquX/yAU808e/4mzjjDA76+Ss=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
|
||||
@@ -387,7 +342,6 @@ github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
|
||||
github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc=
|
||||
github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
|
||||
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
|
||||
github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
|
||||
@@ -398,14 +352,11 @@ github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmK
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/iij/doapi v0.0.0-20190504054126-0bbf12d6d7df/go.mod h1:QMZY7/J/KSQEhKWFeDesPjMj+wCHReeknARU3wqlyN4=
|
||||
github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
||||
github.com/imdario/mergo v0.3.9 h1:UauaLniWCFHWd+Jp9oCEkTBj8VO/9DKg3PV3VCNMDIg=
|
||||
github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
|
||||
github.com/infobloxopen/go-trees v0.0.0-20190313150506-2af4e13f9062 h1:d3VSuNcgTCn21dNMm8g412Fck/XWFmMj4nJhhHT7ZZ0=
|
||||
github.com/infobloxopen/go-trees v0.0.0-20190313150506-2af4e13f9062/go.mod h1:PcNJqIlcX/dj3DTG/+QQnRvSgTMG6CLpRMjWcv4+J6w=
|
||||
github.com/jimstudt/http-authentication v0.0.0-20140401203705-3eca13d6893a/go.mod h1:wK6yTYYcgjHE1Z1QtXACPDjcFJyBskHEdagmnq3vsP8=
|
||||
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5imkbgOkpRUYLnmbU7UEFbjtDA2hxJ1ichM=
|
||||
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
|
||||
github.com/jmespath/go-jmespath v0.3.0 h1:OS12ieG61fsCg5+qLJ+SsW9NicxNkg3b25OyT2yCeUc=
|
||||
github.com/jmespath/go-jmespath v0.3.0/go.mod h1:9QtRXoHjLGCJ5IBSaohpXITPlowMeeYCZ7fLUTSywik=
|
||||
@@ -416,7 +367,6 @@ github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX
|
||||
github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.8 h1:QiWkFLKq0T7mpzwOTu6BzNDbfTE8OLrYhVKYMLF46Ok=
|
||||
github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
@@ -433,19 +383,15 @@ github.com/kolo/xmlrpc v0.0.0-20190717152603-07c4ee3fd181/go.mod h1:o03bZfuBwAXH
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515 h1:T+h1c/A9Gawja4Y9mFVWj2vyii2bbUNDw3kt9VxK2EY=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs=
|
||||
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
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/kshvakov/clickhouse v1.3.11 h1:dtzTJY0fCA+MWkLyuKZaNPkmSwdX4gh8+Klic9NB1Lw=
|
||||
github.com/kshvakov/clickhouse v1.3.11/go.mod h1:/SVBAcqF3u7rxQ9sTWCZwf8jzzvxiZGeQvtmSF2BBEc=
|
||||
github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k=
|
||||
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
|
||||
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
||||
github.com/labbsr0x/bindman-dns-webhook v1.0.2/go.mod h1:p6b+VCXIR8NYKpDr8/dg1HKfQoRHCdcsROXKvmoehKA=
|
||||
github.com/labbsr0x/goh v1.0.1/go.mod h1:8K2UhVoaWXcCU7Lxoa2omWnC8gyW8px7/lmO61c027w=
|
||||
@@ -457,6 +403,9 @@ github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0U
|
||||
github.com/linode/linodego v0.10.0/go.mod h1:cziNP7pbvE3mXIPneHj0oRY8L1WtGEIKlZ8LANE4eXA=
|
||||
github.com/liquidweb/liquidweb-go v1.6.0/go.mod h1:UDcVnAMDkZxpw4Y7NOHkqoeiGacVLEIG/i5J9cyixzQ=
|
||||
github.com/lucas-clemente/quic-go v0.13.1/go.mod h1:Vn3/Fb0/77b02SGhQk36KzOUmXgVpFfizUfW5WMaqyU=
|
||||
github.com/lucasb-eyer/go-colorful v1.0.2/go.mod h1:0MS4r+7BZKSJ5mw4/S5MPN+qHFF1fYclkSPilDOKW0s=
|
||||
github.com/lucasb-eyer/go-colorful v1.0.3 h1:QIbQXiugsb+q10B+MI+7DI1oQLdmnep86tWFlaaUAac=
|
||||
github.com/lucasb-eyer/go-colorful v1.0.3/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
|
||||
github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ=
|
||||
github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/marten-seemann/chacha20 v0.2.0/go.mod h1:HSdjFau7GzYRj+ahFNwsO3ouVJr1HFkWoEwNDb4TMtE=
|
||||
@@ -467,6 +416,8 @@ github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNx
|
||||
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||
github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||
github.com/mattn/go-runewidth v0.0.8 h1:3tS41NlGYSmhhe/8fhGRzc+z3AYCw1Fe1WAyLuujKs0=
|
||||
github.com/mattn/go-runewidth v0.0.8/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||
github.com/mattn/go-sqlite3 v1.11.0 h1:LDdKkqtYlom37fkvqs8rMPFKAMe8+SgjbwZ6ex1/A/Q=
|
||||
github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||
@@ -476,7 +427,6 @@ github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5
|
||||
github.com/mholt/certmagic v0.8.3/go.mod h1:91uJzK5K8IWtYQqTi5R2tsxV1pCde+wdGfaRaOZi6aQ=
|
||||
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
||||
github.com/miekg/dns v1.1.15/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
||||
github.com/miekg/dns v1.1.29 h1:xHBEhR+t5RzcFJjBLJlax2daXOrTYtr9z4WdKEfWFzg=
|
||||
github.com/miekg/dns v1.1.29/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
|
||||
github.com/miekg/dns v1.1.31 h1:sJFOl9BgwbYAWOGEwr61FU28pqsBNdpRBnhGXtO06Oo=
|
||||
github.com/miekg/dns v1.1.31/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
|
||||
@@ -491,10 +441,8 @@ github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0Qu
|
||||
github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
|
||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
@@ -511,7 +459,6 @@ github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxzi
|
||||
github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w=
|
||||
github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
|
||||
github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32/go.mod h1:9wM+0iRr9ahx58uYLpLIr5fm8diHn0JbqRycJi6w0Ms=
|
||||
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/nrdcg/auroradns v1.0.0/go.mod h1:6JPXKzIRzZzMqtTDgueIhTi6rFf1QvYE/HzqidhOhjw=
|
||||
github.com/nrdcg/goinwx v0.6.1/go.mod h1:XPiut7enlbEdntAqalBIqcYcTEVhpv/dKWgDCX2SwKQ=
|
||||
@@ -528,21 +475,16 @@ github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGV
|
||||
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
|
||||
github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492 h1:lM6RxxfUMrYL/f8bWEUqdXrANWtrL7Nndbm9iFN0DlU=
|
||||
github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis=
|
||||
github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74=
|
||||
github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||
github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU=
|
||||
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||
github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs=
|
||||
github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc=
|
||||
github.com/openzipkin-contrib/zipkin-go-opentracing v0.3.5 h1:82Tnq9OJpn+h5xgGpss5/mOv3KXdjtkdorFSOUusjM8=
|
||||
github.com/openzipkin-contrib/zipkin-go-opentracing v0.3.5/go.mod h1:uVHyebswE1cCXr2A73cRM2frx5ld1RJUCJkFNZ90ZiI=
|
||||
github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5 h1:ZCnq+JUrvXcDVhX/xRolRBZifmabN1HcS1wrPSvxhrU=
|
||||
github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA=
|
||||
github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw=
|
||||
github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
|
||||
github.com/openzipkin/zipkin-go v0.2.2 h1:nY8Hti+WKaP0cRsSeQ026wU03QsM762XBeCXBb9NAWI=
|
||||
github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
|
||||
github.com/oracle/oci-go-sdk v7.0.0+incompatible/go.mod h1:VQb79nF8Z2cwLkLS35ukwStZIg5F66tcBccjip/j888=
|
||||
github.com/ovh/go-ovh v0.0.0-20181109152953-ba5adb4cf014/go.mod h1:joRatxRJaZBsY3JAOEMcoOp05CnZzsx4scTxi95DHyQ=
|
||||
@@ -551,15 +493,11 @@ github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FI
|
||||
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
|
||||
github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac=
|
||||
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
|
||||
github.com/philhofer/fwd v1.0.0 h1:UbZqGr5Y38ApvM/V/jEljVxwocdweyH+vmYvRPBnbqQ=
|
||||
github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU=
|
||||
github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc=
|
||||
github.com/pierrec/lz4 v2.0.5+incompatible h1:2xWsjqPFWcplujydGg4WmhC/6fZqK42wMM8aXeqhl0I=
|
||||
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
|
||||
github.com/pierrec/lz4 v2.5.2+incompatible h1:WCjObylUIOlKy/+7Abdn34TLIkXiA4UWUMhxq9m9ZXI=
|
||||
github.com/pierrec/lz4 v2.5.2+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
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=
|
||||
@@ -580,7 +518,6 @@ github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP
|
||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4 h1:gQz4mCbXsO+nc9n1hCxHcGA3Zx3Eo+UHZoInFGUIXNM=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M=
|
||||
@@ -590,7 +527,6 @@ github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y8
|
||||
github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc=
|
||||
github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA=
|
||||
github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4=
|
||||
github.com/prometheus/common v0.10.0 h1:RyRA7RzGXQZiW+tGMr7sxa85G1z0yOpM1qq5c8lNawc=
|
||||
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
|
||||
github.com/prometheus/common v0.13.0 h1:vJlpe9wPgDRM1Z+7Wj3zUUjY1nr6/1jNKyl7llliccg=
|
||||
github.com/prometheus/common v0.13.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s=
|
||||
@@ -598,14 +534,19 @@ github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R
|
||||
github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
|
||||
github.com/prometheus/procfs v0.0.5/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
|
||||
github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
|
||||
github.com/prometheus/procfs v0.0.11/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
||||
github.com/prometheus/procfs v0.1.3 h1:F0+tqvhOksq22sc6iCHF5WGlWjdwj92p0udFh1VFBS8=
|
||||
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
||||
github.com/prometheus/prometheus v2.5.0+incompatible/go.mod h1:oAIUtOny2rjMX0OWN5vPR5/q/twIROJvdqnQKDdil/s=
|
||||
github.com/rainycape/memcache v0.0.0-20150622160815-1031fa0ce2f2/go.mod h1:7tZKcyumwBO6qip7RNQ5r77yrssm9bfCowcLEBcU5IA=
|
||||
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a h1:9ZKAASQSHhDYGoxY8uLVpewe1GDZ2vu2Tr/vTdVAkFQ=
|
||||
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
|
||||
github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5/go.mod h1:GEXHk5HgEKCvEIIrSpFI3ozzG5xOKA2DVlEX/gGnewM=
|
||||
github.com/rivo/tview v0.0.0-20200712113419-c65badfc3d92 h1:rqaqSUdaW+OBbjnsrOoiaJv43mSRARuvsAuirmdxu7E=
|
||||
github.com/rivo/tview v0.0.0-20200712113419-c65badfc3d92/go.mod h1:6lkG1x+13OShEf0EaOCaTQYyB7d5nSbb181KtjlS+84=
|
||||
github.com/rivo/uniseg v0.1.0 h1:+2KBaVoUmb9XzDsrx/Ct0W/EYOSFf/nWTauy++DprtY=
|
||||
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/russross/blackfriday v0.0.0-20170610170232-067529f716f4 h1:S9YlS71UNJIyS61OqGAmLXv3w5zclSidN+qwr80XxKs=
|
||||
@@ -620,7 +561,6 @@ github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
|
||||
github.com/skratchdot/open-golang v0.0.0-20160302144031-75fb7ed4208c/go.mod h1:sUM3LWHvSMaG192sy56D9F7CNvL7jUJVXoqM1QKLnog=
|
||||
@@ -633,7 +573,6 @@ github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTd
|
||||
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
|
||||
github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
|
||||
github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
|
||||
@@ -641,14 +580,13 @@ github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5J
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/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/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/stretchr/testify v1.6.0 h1:jlIyCplCJFULU/01vCkhKuTyc3OorI3bJFuw6obfgho=
|
||||
github.com/stretchr/testify v1.6.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/timewasted/linode v0.0.0-20160829202747-37e84520dcf7/go.mod h1:imsgLplxEC/etjIhdr3dNzV3JeT27LbVu5pYWm0JCBY=
|
||||
github.com/tinylib/msgp v1.1.2 h1:gWmO7n0Ys2RBEb7GPYB9Ujq8Mk5p2U08lRnmMcGy6BQ=
|
||||
github.com/tinylib/msgp v1.1.0/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE=
|
||||
github.com/tinylib/msgp v1.1.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/transip/gotransip v0.0.0-20190812104329-6d8d9179b66f/go.mod h1:i0f4R4o2HM0m3DZYQWsj6/MEowD57VzoH0v3d7igeFY=
|
||||
@@ -670,30 +608,24 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de
|
||||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||
go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg=
|
||||
go.etcd.io/etcd v0.5.0-alpha.5.0.20200306183522-221f0cc107cb h1:TcJ8iNja1CH/h/3QcsydKL5krb0MIPjMJLYgzClNaSQ=
|
||||
go.etcd.io/etcd v0.5.0-alpha.5.0.20200306183522-221f0cc107cb/go.mod h1:VZB9Yx4s43MHItytoe8jcvaEFEgF2QzHDZGfQ/XQjvQ=
|
||||
go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
|
||||
go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
|
||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
||||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.3 h1:8sGtKOrtQqkN1bp2AtX+misvLIlOmsEsNd+9NIcPEm8=
|
||||
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.4 h1:LYy1Hy3MJdrCdMwwzxA/dRok4ejH+RwNGbuoD9fCjto=
|
||||
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
||||
go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk=
|
||||
go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
||||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||
go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
|
||||
go.uber.org/multierr v1.5.0 h1:KCa4XfM8CWFCpxXRGok+Q0SS/0XBhMDbHHGABQLvD2A=
|
||||
go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
|
||||
go.uber.org/ratelimit v0.0.0-20180316092928-c15da0234277/go.mod h1:2X8KaoNd1J0lZV+PxJk/5+DGbO/tpwLR1m++a7FnB/Y=
|
||||
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
|
||||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
|
||||
go.uber.org/zap v1.14.1 h1:nYDKopTbvAPq/NrUVZwT15y2lpROBiLLyoRTbXOYWOo=
|
||||
go.uber.org/zap v1.14.1/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc=
|
||||
golang.org/x/crypto v0.0.0-20180621125126-a49355c7e3f8/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
@@ -708,13 +640,11 @@ golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8U
|
||||
golang.org/x/crypto v0.0.0-20190829043050-9756ffdc2472/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191002192127-34f69633bfdc/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 h1:ObdrDkeb4kJdCP557AjRjq69pTHfNouLtWZG7j9rPN8=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191202143827-86a70503ff7e/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a h1:vclmkQCjlDX5OydZ9wv8rBCcS0QyQY66Mpf/7BZbInM=
|
||||
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
@@ -787,19 +717,15 @@ golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/
|
||||
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200625001655-4c5254603344 h1:vGXIOMxbNfDTk/aXCmfdLgkrSV+Z2tcbze+pEc3v5W4=
|
||||
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200904194848-62affa334b73 h1:MXfv8rhZWmFeqX3GNZRsd6vOLoaCHjYEX3qkRo3YBUA=
|
||||
golang.org/x/net v0.0.0-20200904194848-62affa334b73/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be h1:vEDujvNQGv4jgYKudGeI/+DAX4Jffq6hpD55MmoEvKs=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw=
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43 h1:ld7aEMNHoBnnDAX15v1T6z31v8HwR2A9FYOuAhWqkwc=
|
||||
golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
@@ -807,7 +733,6 @@ golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJ
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
@@ -833,6 +758,7 @@ golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190626150813-e07cf5db2756/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@@ -861,14 +787,12 @@ golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae h1:Ih9Yo4hSPImZOpfGuA4bR/ORKTAbhZo2AbWNRCnevdo=
|
||||
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200909081042-eff7692f9009 h1:W0lCpv29Hv0UaM1LXb9QlBHLNP8UFfcKjblhVCWftOM=
|
||||
golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
@@ -878,7 +802,6 @@ golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxb
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190921001708-c4c64cad1fd0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs=
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
@@ -908,7 +831,6 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn
|
||||
golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191203134012-c197fd4bf371/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191216052735-49a3e744a425 h1:VvQyQJN0tSuecqgcIxMWnnfG5kSmgy9KZR9sW3W5QeA=
|
||||
golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
@@ -933,9 +855,7 @@ golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc
|
||||
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=
|
||||
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
|
||||
@@ -951,19 +871,15 @@ google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/
|
||||
google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
|
||||
google.golang.org/api v0.26.0 h1:VJZ8h6E8ip82FRpQl848c5vAadxlTXrUh8RzQzSRm08=
|
||||
google.golang.org/api v0.26.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
|
||||
google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
|
||||
google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
|
||||
google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.5.0 h1:KxkO13IPW4Lslp2bz+KHP2E3gtFlrIGNThxkZQ3g+4c=
|
||||
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
|
||||
google.golang.org/appengine v1.6.5 h1:tycE03LOZYQNhDpS27tcQdAzLCVMaj7QT2SXxebnpCM=
|
||||
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/appengine v1.6.6 h1:lMO5rYAqUxkmaj76jAkRUvt5JZgFymx/+Q5Mzfivuhc=
|
||||
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
@@ -989,7 +905,6 @@ google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfG
|
||||
google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940 h1:MRHtG0U6SnaUb+s+LhNE1qt1FQ1wlhqr5E4usBKC0uA=
|
||||
google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
@@ -1016,7 +931,6 @@ google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8
|
||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
|
||||
google.golang.org/grpc v1.29.1 h1:EC2SB8S04d2r73uptxphDSUG+kTKVgjRPF+N3xpxRB4=
|
||||
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
|
||||
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||
@@ -1028,20 +942,16 @@ google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQ
|
||||
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
|
||||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
||||
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM=
|
||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
|
||||
google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c=
|
||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||
gopkg.in/DataDog/dd-trace-go.v1 v1.24.1 h1:CGQIcKZxAsFtMTUiXw0TxBWwj+l+b2bS2V8l1bIsfk4=
|
||||
gopkg.in/DataDog/dd-trace-go.v1 v1.24.1/go.mod h1:DVp8HmDh8PuTu2Z0fVVlBsyWaC++fzwVCaGWylTe3tg=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
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-20180628173108-788fd7840127/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/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
|
||||
gopkg.in/coreos/go-oidc.v2 v2.1.0 h1:E8PjVFdj/SLDKB0hvb70KTbMbYVHjqztiQdSkIg8E+I=
|
||||
@@ -1050,7 +960,6 @@ gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o=
|
||||
gopkg.in/h2non/gock.v1 v1.0.15/go.mod h1:sX4zAkdYX1TRGJ2JY156cFspQn4yRWn6p9EMdODlynE=
|
||||
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
|
||||
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||
gopkg.in/ini.v1 v1.42.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/ini.v1 v1.44.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
@@ -1067,11 +976,9 @@ gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRN
|
||||
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
|
||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
|
||||
gopkg.in/yaml.v2 v2.2.8/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=
|
||||
@@ -1086,28 +993,21 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh
|
||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
k8s.io/api v0.18.3 h1:2AJaUQdgUZLoDZHrun21PW2Nx9+ll6cUzvn3IKhSIn0=
|
||||
k8s.io/api v0.18.3/go.mod h1:UOaMwERbqJMfeeeHc8XJKawj4P9TgDRnViIqqBeH2QA=
|
||||
k8s.io/apimachinery v0.18.3 h1:pOGcbVAhxADgUYnjS08EFXs9QMl8qaH5U4fr5LGUrSk=
|
||||
k8s.io/apimachinery v0.18.3/go.mod h1:OaXp26zu/5J7p0f92ASynJa1pZo06YlV9fG7BoWbCko=
|
||||
k8s.io/client-go v0.18.3 h1:QaJzz92tsN67oorwzmoB0a9r9ZVHuD5ryjbCKP0U22k=
|
||||
k8s.io/client-go v0.18.3/go.mod h1:4a/dpQEvzAhT1BbuWW09qvIaGw6Gbu1gZYiQZIi1DMw=
|
||||
k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
|
||||
k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
|
||||
k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
|
||||
k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8=
|
||||
k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I=
|
||||
k8s.io/kube-openapi v0.0.0-20200410145947-61e04a5be9a6/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E=
|
||||
k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89 h1:d4vVOjXm687F1iLSP2q3lyPPuyvTUt3aVoBpi2DqRsU=
|
||||
k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew=
|
||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
||||
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
||||
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
||||
sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200116222232-67a7b8c61874/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw=
|
||||
sigs.k8s.io/structured-merge-diff/v3 v3.0.0 h1:dOmIZBMfhcHS09XZkMyUgkq5trg3/jRyJYFZUiaOp8E=
|
||||
sigs.k8s.io/structured-merge-diff/v3 v3.0.0/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw=
|
||||
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
|
||||
sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=
|
||||
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
|
||||
sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU=
|
||||
zombiezen.com/go/capnproto2 v2.18.0+incompatible h1:mwfXZniffG5mXokQGHUJWGnqIBggoPfT/CEwon9Yess=
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
---
|
||||
basename: "cloudflared"
|
||||
comment: "Cloudflare Argo Tunnel"
|
||||
copyright: "Cloudflare, Inc"
|
||||
arch: "x86"
|
||||
abi: "64"
|
||||
files:
|
||||
- source: cloudflared
|
||||
destination: /var/db/scripts/jet/cloudflared
|
||||
+11
-10
@@ -98,31 +98,32 @@ func Parse(opts ...Option) (*Options, error) {
|
||||
|
||||
// New setups a new logger based on the options.
|
||||
// The default behavior is to write to standard out
|
||||
func New(opts ...Option) (Service, error) {
|
||||
config, err := Parse(opts...)
|
||||
func New(opts ...Option) (*OutputWriter, error) {
|
||||
options, err := Parse(opts...)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
l := NewOutputWriter(SharedWriteManager)
|
||||
if config.logFileDirectory != "" {
|
||||
l.Add(NewFileRollingWriter(SanitizeLogPath(config.logFileDirectory),
|
||||
if options.logFileDirectory != "" {
|
||||
l.Add(NewFileRollingWriter(SanitizeLogPath(options.logFileDirectory),
|
||||
"cloudflared",
|
||||
int64(config.maxFileSize),
|
||||
config.maxFileCount),
|
||||
NewDefaultFormatter(time.RFC3339Nano), config.supportedFileLevels...)
|
||||
int64(options.maxFileSize),
|
||||
options.maxFileCount),
|
||||
NewDefaultFormatter(time.RFC3339Nano), options.supportedFileLevels...)
|
||||
}
|
||||
|
||||
if !config.terminalOutputDisabled {
|
||||
if !options.terminalOutputDisabled {
|
||||
terminalFormatter := NewTerminalFormatter(time.RFC3339)
|
||||
|
||||
if len(config.supportedTerminalLevels) == 0 {
|
||||
if len(options.supportedTerminalLevels) == 0 {
|
||||
l.Add(os.Stderr, terminalFormatter, InfoLevel, ErrorLevel, FatalLevel)
|
||||
} else {
|
||||
l.Add(os.Stderr, terminalFormatter, config.supportedTerminalLevels...)
|
||||
l.Add(os.Stderr, terminalFormatter, options.supportedTerminalLevels...)
|
||||
}
|
||||
}
|
||||
|
||||
return l, nil
|
||||
}
|
||||
|
||||
|
||||
+36
-1
@@ -63,6 +63,12 @@ type TerminalFormatter struct {
|
||||
supportsColor bool
|
||||
}
|
||||
|
||||
// UIFormatter is used for streaming logs to UI
|
||||
type UIFormatter struct {
|
||||
format string
|
||||
supportsColor bool
|
||||
}
|
||||
|
||||
// NewTerminalFormatter creates a Terminal formatter for colored output
|
||||
// format is the time format to use for timestamp formatting
|
||||
func NewTerminalFormatter(format string) Formatter {
|
||||
@@ -73,10 +79,39 @@ func NewTerminalFormatter(format string) Formatter {
|
||||
}
|
||||
}
|
||||
|
||||
func NewUIFormatter(format string) Formatter {
|
||||
supportsColor := (runtime.GOOS != "windows")
|
||||
return &UIFormatter{
|
||||
format: format,
|
||||
supportsColor: supportsColor,
|
||||
}
|
||||
}
|
||||
|
||||
// Timestamp uses formatting that is tview-specific for UI
|
||||
func (f *UIFormatter) Timestamp(l Level, d time.Time) string {
|
||||
t := ""
|
||||
dateStr := "[" + d.Format(f.format) + "] "
|
||||
switch l {
|
||||
case InfoLevel:
|
||||
t = "[#00ffff]INFO[white]"
|
||||
case ErrorLevel:
|
||||
t = "[red]ERROR[white]"
|
||||
case DebugLevel:
|
||||
t = "[yellow]DEBUG[white]"
|
||||
case FatalLevel:
|
||||
t = "[red]FATAL[white]"
|
||||
}
|
||||
return t + dateStr
|
||||
}
|
||||
|
||||
func (f *UIFormatter) Content(l Level, c string) string {
|
||||
return c
|
||||
}
|
||||
|
||||
// Timestamp returns the log level with a matching color to the log type
|
||||
func (f *TerminalFormatter) Timestamp(l Level, d time.Time) string {
|
||||
t := ""
|
||||
dateStr := "[" + d.Format(f.format) + "] "
|
||||
dateStr := "[" + d.Format(f.format) + "] "
|
||||
switch l {
|
||||
case InfoLevel:
|
||||
t = f.output("INFO", skittles.Cyan)
|
||||
|
||||
+3
-1
@@ -31,6 +31,8 @@ type Service interface {
|
||||
Infof(format string, args ...interface{})
|
||||
Debugf(format string, args ...interface{})
|
||||
Fatalf(format string, args ...interface{})
|
||||
|
||||
Add(writer io.Writer, formatter Formatter, levels ...Level)
|
||||
}
|
||||
|
||||
type sourceGroup struct {
|
||||
@@ -59,7 +61,7 @@ type OutputWriter struct {
|
||||
minLevel Level
|
||||
}
|
||||
|
||||
// NewOutputWriter create a new logger
|
||||
// NewOutputWriter creates a new logger
|
||||
func NewOutputWriter(syncWriter OutputManager) *OutputWriter {
|
||||
return &OutputWriter{
|
||||
syncWriter: syncWriter,
|
||||
|
||||
+1
-1
@@ -174,7 +174,7 @@ func ReconnectTunnel(
|
||||
serverInfoPromise := tunnelrpc.TunnelServer{Client: tunnelServer.Client}.GetServerInfo(ctx, func(tunnelrpc.TunnelServer_getServerInfo_Params) error {
|
||||
return nil
|
||||
})
|
||||
LogServerInfo(serverInfoPromise.Result(), connectionID, config.Metrics, logger)
|
||||
LogServerInfo(serverInfoPromise.Result(), connectionID, config.Metrics, logger, config.TunnelEventChan)
|
||||
registration := tunnelServer.ReconnectTunnel(
|
||||
ctx,
|
||||
token,
|
||||
|
||||
+46
-9
@@ -21,6 +21,7 @@ import (
|
||||
|
||||
"github.com/cloudflare/cloudflared/buffer"
|
||||
"github.com/cloudflare/cloudflared/cmd/cloudflared/buildinfo"
|
||||
"github.com/cloudflare/cloudflared/cmd/cloudflared/ui"
|
||||
"github.com/cloudflare/cloudflared/connection"
|
||||
"github.com/cloudflare/cloudflared/h2mux"
|
||||
"github.com/cloudflare/cloudflared/logger"
|
||||
@@ -88,6 +89,7 @@ type TunnelConfig struct {
|
||||
|
||||
NamedTunnel *NamedTunnelConfig
|
||||
ReplaceExisting bool
|
||||
TunnelEventChan chan<- ui.TunnelEvent
|
||||
}
|
||||
|
||||
type dupConnRegisterTunnelError struct{}
|
||||
@@ -184,6 +186,10 @@ func (c *TunnelConfig) SupportedFeatures() []string {
|
||||
return features
|
||||
}
|
||||
|
||||
func (c *TunnelConfig) IsTrialTunnel() bool {
|
||||
return c.Hostname == ""
|
||||
}
|
||||
|
||||
type NamedTunnelConfig struct {
|
||||
Auth pogs.TunnelAuth
|
||||
ID uuid.UUID
|
||||
@@ -234,6 +240,10 @@ func ServeTunnelLoop(ctx context.Context,
|
||||
)
|
||||
if recoverable {
|
||||
if duration, ok := backoff.GetBackoffDuration(ctx); ok {
|
||||
if config.TunnelEventChan != nil {
|
||||
config.TunnelEventChan <- ui.TunnelEvent{Index: connectionIndex, EventType: ui.Reconnecting}
|
||||
}
|
||||
|
||||
config.Logger.Infof("Retrying connection %d in %s seconds", connectionIndex, duration)
|
||||
backoff.Backoff(ctx)
|
||||
continue
|
||||
@@ -268,6 +278,13 @@ func ServeTunnel(
|
||||
}
|
||||
}()
|
||||
|
||||
// If launch-ui flag is set, send disconnect msg
|
||||
if config.TunnelEventChan != nil {
|
||||
defer func() {
|
||||
config.TunnelEventChan <- ui.TunnelEvent{Index: connectionIndex, EventType: ui.Disconnected}
|
||||
}()
|
||||
}
|
||||
|
||||
connectionTag := uint8ToString(connectionIndex)
|
||||
|
||||
// Returns error from parsing the origin URL or handshake errors
|
||||
@@ -426,6 +443,11 @@ func RegisterConnection(
|
||||
config.Metrics.regSuccess.WithLabelValues(registerConnection).Inc()
|
||||
config.Logger.Infof("Connection %d registered with %s using ID %s", connectionIndex, conn.Location, conn.UUID)
|
||||
|
||||
// If launch-ui flag is set, send connect msg
|
||||
if config.TunnelEventChan != nil {
|
||||
config.TunnelEventChan <- ui.TunnelEvent{Index: connectionIndex, EventType: ui.Connected, Location: conn.Location}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -469,6 +491,9 @@ func RegisterTunnel(
|
||||
uuid uuid.UUID,
|
||||
) error {
|
||||
config.TransportLogger.Debug("initiating RPC stream to register")
|
||||
if config.TunnelEventChan != nil {
|
||||
config.TunnelEventChan <- ui.TunnelEvent{EventType: ui.RegisteringTunnel}
|
||||
}
|
||||
tunnelServer, err := connection.NewRPCClient(ctx, muxer, config.TransportLogger, openStreamTimeout)
|
||||
if err != nil {
|
||||
// RPC stream open error
|
||||
@@ -479,7 +504,7 @@ func RegisterTunnel(
|
||||
serverInfoPromise := tunnelrpc.TunnelServer{Client: tunnelServer.Client}.GetServerInfo(ctx, func(tunnelrpc.TunnelServer_getServerInfo_Params) error {
|
||||
return nil
|
||||
})
|
||||
LogServerInfo(serverInfoPromise.Result(), connectionID, config.Metrics, logger)
|
||||
LogServerInfo(serverInfoPromise.Result(), connectionID, config.Metrics, logger, config.TunnelEventChan)
|
||||
registration := tunnelServer.RegisterTunnel(
|
||||
ctx,
|
||||
config.OriginCert,
|
||||
@@ -490,6 +515,11 @@ func RegisterTunnel(
|
||||
// RegisterTunnel RPC failure
|
||||
return processRegisterTunnelError(registrationErr, config.Metrics, register)
|
||||
}
|
||||
|
||||
// Send free tunnel URL to UI
|
||||
if config.TunnelEventChan != nil {
|
||||
config.TunnelEventChan <- ui.TunnelEvent{EventType: ui.SetUrl, Url: registration.Url}
|
||||
}
|
||||
credentialManager.SetEventDigest(connectionID, registration.EventDigest)
|
||||
return processRegistrationSuccess(config, logger, connectionID, registration, register, credentialManager)
|
||||
}
|
||||
@@ -511,15 +541,17 @@ func processRegistrationSuccess(
|
||||
logger.Infof("Each HA connection's tunnel IDs: %v", config.Metrics.tunnelsHA.String())
|
||||
}
|
||||
|
||||
// Print out the user's trial zone URL in a nice box (if they requested and got one)
|
||||
if isTrialTunnel := config.Hostname == ""; isTrialTunnel {
|
||||
if url, err := url.Parse(registration.Url); err == nil {
|
||||
for _, line := range asciiBox(trialZoneMsg(url.String()), 2) {
|
||||
logger.Info(line)
|
||||
// Print out the user's trial zone URL in a nice box (if they requested and got one and UI flag is not set)
|
||||
if config.TunnelEventChan == nil {
|
||||
if config.IsTrialTunnel() {
|
||||
if registrationURL, err := url.Parse(registration.Url); err == nil {
|
||||
for _, line := range asciiBox(trialZoneMsg(registrationURL.String()), 2) {
|
||||
logger.Info(line)
|
||||
}
|
||||
} else {
|
||||
logger.Error("Failed to connect tunnel, please try again.")
|
||||
return fmt.Errorf("empty URL in response from Cloudflare edge")
|
||||
}
|
||||
} else {
|
||||
logger.Error("Failed to connect tunnel, please try again.")
|
||||
return fmt.Errorf("empty URL in response from Cloudflare edge")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -562,6 +594,7 @@ func LogServerInfo(
|
||||
connectionID uint8,
|
||||
metrics *TunnelMetrics,
|
||||
logger logger.Service,
|
||||
tunnelEventChan chan<- ui.TunnelEvent,
|
||||
) {
|
||||
serverInfoMessage, err := promise.Struct()
|
||||
if err != nil {
|
||||
@@ -573,6 +606,10 @@ func LogServerInfo(
|
||||
logger.Errorf("Failed to retrieve server information: %s", err)
|
||||
return
|
||||
}
|
||||
// If launch-ui flag is set, send connect msg
|
||||
if tunnelEventChan != nil {
|
||||
tunnelEventChan <- ui.TunnelEvent{Index: connectionID, EventType: ui.Connected, Location: serverInfo.LocationName}
|
||||
}
|
||||
logger.Infof("Connected to %s", serverInfo.LocationName)
|
||||
metrics.registerServerLocation(uint8ToString(connectionID), serverInfo.LocationName)
|
||||
}
|
||||
|
||||
+130
-19
@@ -27,6 +27,7 @@ var (
|
||||
ErrUnauthorized = errors.New("unauthorized")
|
||||
ErrBadRequest = errors.New("incorrect request parameters")
|
||||
ErrNotFound = errors.New("not found")
|
||||
ErrAPINoSuccess = errors.New("API call failed")
|
||||
)
|
||||
|
||||
type Tunnel struct {
|
||||
@@ -39,14 +40,26 @@ type Tunnel struct {
|
||||
|
||||
type Connection struct {
|
||||
ColoName string `json:"colo_name"`
|
||||
ID uuid.UUID `json:"uuid"`
|
||||
ID uuid.UUID `json:"id"`
|
||||
IsPendingReconnect bool `json:"is_pending_reconnect"`
|
||||
}
|
||||
|
||||
type Change = string
|
||||
|
||||
const (
|
||||
ChangeNew = "new"
|
||||
ChangeUpdated = "updated"
|
||||
ChangeUnchanged = "unchanged"
|
||||
)
|
||||
|
||||
// Route represents a record type that can route to a tunnel
|
||||
type Route interface {
|
||||
json.Marshaler
|
||||
RecordType() string
|
||||
UnmarshalResult(body io.Reader) (RouteResult, error)
|
||||
}
|
||||
|
||||
type RouteResult interface {
|
||||
// SuccessSummary explains what will route to this tunnel when it's provisioned successfully
|
||||
SuccessSummary() string
|
||||
}
|
||||
@@ -55,6 +68,11 @@ type DNSRoute struct {
|
||||
userHostname string
|
||||
}
|
||||
|
||||
type DNSRouteResult struct {
|
||||
route *DNSRoute
|
||||
CName Change `json:"cname"`
|
||||
}
|
||||
|
||||
func NewDNSRoute(userHostname string) Route {
|
||||
return &DNSRoute{
|
||||
userHostname: userHostname,
|
||||
@@ -72,12 +90,28 @@ func (dr *DNSRoute) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(&s)
|
||||
}
|
||||
|
||||
func (dr *DNSRoute) UnmarshalResult(body io.Reader) (RouteResult, error) {
|
||||
var result DNSRouteResult
|
||||
err := parseResponse(body, &result)
|
||||
result.route = dr
|
||||
return &result, err
|
||||
}
|
||||
|
||||
func (dr *DNSRoute) RecordType() string {
|
||||
return "dns"
|
||||
}
|
||||
|
||||
func (dr *DNSRoute) SuccessSummary() string {
|
||||
return fmt.Sprintf("%s will route to your tunnel", dr.userHostname)
|
||||
func (res *DNSRouteResult) SuccessSummary() string {
|
||||
var msgFmt string
|
||||
switch res.CName {
|
||||
case ChangeNew:
|
||||
msgFmt = "Added CNAME %s which will route to this tunnel"
|
||||
case ChangeUpdated: // this is not currently returned by tunnelsore
|
||||
msgFmt = "%s updated to route to your tunnel"
|
||||
case ChangeUnchanged:
|
||||
msgFmt = "%s is already configured to route to your tunnel"
|
||||
}
|
||||
return fmt.Sprintf(msgFmt, res.route.userHostname)
|
||||
}
|
||||
|
||||
type LBRoute struct {
|
||||
@@ -85,6 +119,12 @@ type LBRoute struct {
|
||||
lbPool string
|
||||
}
|
||||
|
||||
type LBRouteResult struct {
|
||||
route *LBRoute
|
||||
LoadBalancer Change `json:"load_balancer"`
|
||||
Pool Change `json:"pool"`
|
||||
}
|
||||
|
||||
func NewLBRoute(lbName, lbPool string) Route {
|
||||
return &LBRoute{
|
||||
lbName: lbName,
|
||||
@@ -109,8 +149,40 @@ func (lr *LBRoute) RecordType() string {
|
||||
return "lb"
|
||||
}
|
||||
|
||||
func (lr *LBRoute) SuccessSummary() string {
|
||||
return fmt.Sprintf("Load balancer %s will route to this tunnel through pool %s", lr.lbName, lr.lbPool)
|
||||
func (lr *LBRoute) UnmarshalResult(body io.Reader) (RouteResult, error) {
|
||||
var result LBRouteResult
|
||||
err := parseResponse(body, &result)
|
||||
result.route = lr
|
||||
return &result, err
|
||||
}
|
||||
|
||||
func (res *LBRouteResult) SuccessSummary() string {
|
||||
var msg string
|
||||
switch res.LoadBalancer + "," + res.Pool {
|
||||
case "new,new":
|
||||
msg = "Created load balancer %s and added a new pool %s with this tunnel as an origin"
|
||||
case "new,updated":
|
||||
msg = "Created load balancer %s with an existing pool %s which was updated to use this tunnel as an origin"
|
||||
case "new,unchanged":
|
||||
msg = "Created load balancer %s with an existing pool %s which already has this tunnel as an origin"
|
||||
case "updated,new":
|
||||
msg = "Added new pool %[2]s with this tunnel as an origin to load balancer %[1]s"
|
||||
case "updated,updated":
|
||||
msg = "Updated pool %[2]s to use this tunnel as an origin and added it to load balancer %[1]s"
|
||||
case "updated,unchanged":
|
||||
msg = "Added pool %[2]s, which already has this tunnel as an origin, to load balancer %[1]s"
|
||||
case "unchanged,updated":
|
||||
msg = "Added this tunnel as an origin in pool %[2]s which is already used by load balancer %[1]s"
|
||||
case "unchanged,unchanged":
|
||||
msg = "Load balancer %s already uses pool %s which has this tunnel as an origin"
|
||||
case "unchanged,new":
|
||||
// this state is not possible
|
||||
fallthrough
|
||||
default:
|
||||
msg = "Something went wrong: failed to modify load balancer %s with pool %s; please check traffic manager configuration in the dashboard"
|
||||
}
|
||||
|
||||
return fmt.Sprintf(msg, res.route.lbName, res.route.lbPool)
|
||||
}
|
||||
|
||||
type Client interface {
|
||||
@@ -119,7 +191,7 @@ type Client interface {
|
||||
DeleteTunnel(tunnelID uuid.UUID) error
|
||||
ListTunnels(filter *Filter) ([]*Tunnel, error)
|
||||
CleanupConnections(tunnelID uuid.UUID) error
|
||||
RouteTunnel(tunnelID uuid.UUID, route Route) error
|
||||
RouteTunnel(tunnelID uuid.UUID, route Route) (RouteResult, error)
|
||||
}
|
||||
|
||||
type RESTClient struct {
|
||||
@@ -238,16 +310,18 @@ func (r *RESTClient) ListTunnels(filter *Filter) ([]*Tunnel, error) {
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode == http.StatusOK {
|
||||
var tunnels []*Tunnel
|
||||
if err := json.NewDecoder(resp.Body).Decode(&tunnels); err != nil {
|
||||
return nil, errors.Wrap(err, "failed to decode response")
|
||||
}
|
||||
return tunnels, nil
|
||||
return parseListTunnels(resp.Body)
|
||||
}
|
||||
|
||||
return nil, r.statusCodeToError("list tunnels", resp)
|
||||
}
|
||||
|
||||
func parseListTunnels(body io.ReadCloser) ([]*Tunnel, error) {
|
||||
var tunnels []*Tunnel
|
||||
err := parseResponse(body, &tunnels)
|
||||
return tunnels, err
|
||||
}
|
||||
|
||||
func (r *RESTClient) CleanupConnections(tunnelID uuid.UUID) error {
|
||||
endpoint := r.baseEndpoints.accountLevel
|
||||
endpoint.Path = path.Join(endpoint.Path, fmt.Sprintf("%v/connections", tunnelID))
|
||||
@@ -260,16 +334,20 @@ func (r *RESTClient) CleanupConnections(tunnelID uuid.UUID) error {
|
||||
return r.statusCodeToError("cleanup connections", resp)
|
||||
}
|
||||
|
||||
func (r *RESTClient) RouteTunnel(tunnelID uuid.UUID, route Route) error {
|
||||
func (r *RESTClient) RouteTunnel(tunnelID uuid.UUID, route Route) (RouteResult, error) {
|
||||
endpoint := r.baseEndpoints.zoneLevel
|
||||
endpoint.Path = path.Join(endpoint.Path, fmt.Sprintf("%v/routes", tunnelID))
|
||||
resp, err := r.sendRequest("PUT", endpoint, route)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "REST request failed")
|
||||
return nil, errors.Wrap(err, "REST request failed")
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
return r.statusCodeToError("add route", resp)
|
||||
if resp.StatusCode == http.StatusOK {
|
||||
return route.UnmarshalResult(resp.Body)
|
||||
}
|
||||
|
||||
return nil, r.statusCodeToError("add route", resp)
|
||||
}
|
||||
|
||||
func (r *RESTClient) sendRequest(method string, url url.URL, body interface{}) (*http.Response, error) {
|
||||
@@ -291,23 +369,56 @@ func (r *RESTClient) sendRequest(method string, url url.URL, body interface{}) (
|
||||
req.Header.Set("Content-Type", jsonContentType)
|
||||
}
|
||||
req.Header.Add("X-Auth-User-Service-Key", r.authToken)
|
||||
req.Header.Add("Accept", "application/json;version=1")
|
||||
return r.client.Do(req)
|
||||
}
|
||||
|
||||
func parseResponse(reader io.Reader, data interface{}) error {
|
||||
// Schema for Tunnelstore responses in the v1 API.
|
||||
// Roughly, it's a wrapper around a particular result that adds failures/errors/etc
|
||||
var result struct {
|
||||
Result json.RawMessage `json:"result"`
|
||||
Success bool `json:"success"`
|
||||
Errors []string `json:"errors"`
|
||||
}
|
||||
// First, parse the wrapper and check the API call succeeded
|
||||
if err := json.NewDecoder(reader).Decode(&result); err != nil {
|
||||
return errors.Wrap(err, "failed to decode response")
|
||||
}
|
||||
if err := checkErrors(result.Errors); err != nil {
|
||||
return err
|
||||
}
|
||||
if !result.Success {
|
||||
return ErrAPINoSuccess
|
||||
}
|
||||
// At this point we know the API call succeeded, so, parse out the inner
|
||||
// result into the datatype provided as a parameter.
|
||||
return json.Unmarshal(result.Result, &data)
|
||||
}
|
||||
|
||||
func unmarshalTunnel(reader io.Reader) (*Tunnel, error) {
|
||||
var tunnel Tunnel
|
||||
if err := json.NewDecoder(reader).Decode(&tunnel); err != nil {
|
||||
return nil, errors.Wrap(err, "failed to decode response")
|
||||
err := parseResponse(reader, &tunnel)
|
||||
return &tunnel, err
|
||||
}
|
||||
|
||||
func checkErrors(errs []string) error {
|
||||
if len(errs) == 0 {
|
||||
return nil
|
||||
}
|
||||
return &tunnel, nil
|
||||
if len(errs) == 1 {
|
||||
return fmt.Errorf("API error: %s", errs[0])
|
||||
}
|
||||
allErrs := strings.Join(errs, "; ")
|
||||
return fmt.Errorf("API errors: %s", allErrs)
|
||||
}
|
||||
|
||||
func (r *RESTClient) statusCodeToError(op string, resp *http.Response) error {
|
||||
if resp.Header.Get("Content-Type") == "application/json" {
|
||||
var errorsResp struct{
|
||||
var errorsResp struct {
|
||||
Error string `json:"error"`
|
||||
}
|
||||
if json.NewDecoder(resp.Body).Decode(&errorsResp) == nil && errorsResp.Error != ""{
|
||||
if json.NewDecoder(resp.Body).Decode(&errorsResp) == nil && errorsResp.Error != "" {
|
||||
return errors.Errorf("Failed to %s: %s", op, errorsResp.Error)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,207 @@
|
||||
package tunnelstore
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestDNSRouteUnmarshalResult(t *testing.T) {
|
||||
route := &DNSRoute{
|
||||
userHostname: "example.com",
|
||||
}
|
||||
|
||||
result, err := route.UnmarshalResult(strings.NewReader(`{"success": true, "result": {"cname": "new"}}`))
|
||||
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, &DNSRouteResult{
|
||||
route: route,
|
||||
CName: ChangeNew,
|
||||
}, result)
|
||||
|
||||
badJSON := []string{
|
||||
`abc`,
|
||||
`{"success": false, "result": {"cname": "new"}}`,
|
||||
`{"errors": ["foo"], "result": {"cname": "new"}}`,
|
||||
`{"errors": ["foo", "bar"], "result": {"cname": "new"}}`,
|
||||
`{"result": {"cname": "new"}}`,
|
||||
`{"result": {"cname": "new"}}`,
|
||||
}
|
||||
|
||||
for _, j := range badJSON {
|
||||
_, err = route.UnmarshalResult(strings.NewReader(j))
|
||||
assert.NotNil(t, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLBRouteUnmarshalResult(t *testing.T) {
|
||||
route := &LBRoute{
|
||||
lbName: "lb.example.com",
|
||||
lbPool: "pool",
|
||||
}
|
||||
|
||||
result, err := route.UnmarshalResult(strings.NewReader(`{"success": true, "result": {"pool": "unchanged", "load_balancer": "updated"}}`))
|
||||
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, &LBRouteResult{
|
||||
route: route,
|
||||
LoadBalancer: ChangeUpdated,
|
||||
Pool: ChangeUnchanged,
|
||||
}, result)
|
||||
|
||||
badJSON := []string{
|
||||
`abc`,
|
||||
`{"success": false, "result": {"pool": "unchanged", "load_balancer": "updated"}}`,
|
||||
`{"errors": ["foo"], "result": {"pool": "unchanged", "load_balancer": "updated"}}`,
|
||||
`{"errors": ["foo", "bar"], "result": {"pool": "unchanged", "load_balancer": "updated"}}`,
|
||||
`{"result": {"pool": "unchanged", "load_balancer": "updated"}}`,
|
||||
}
|
||||
|
||||
for _, j := range badJSON {
|
||||
_, err = route.UnmarshalResult(strings.NewReader(j))
|
||||
assert.NotNil(t, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLBRouteResultSuccessSummary(t *testing.T) {
|
||||
route := &LBRoute{
|
||||
lbName: "lb.example.com",
|
||||
lbPool: "POOL",
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
lb Change
|
||||
pool Change
|
||||
expected string
|
||||
}{
|
||||
{ChangeNew, ChangeNew, "Created load balancer lb.example.com and added a new pool POOL with this tunnel as an origin"},
|
||||
{ChangeNew, ChangeUpdated, "Created load balancer lb.example.com with an existing pool POOL which was updated to use this tunnel as an origin"},
|
||||
{ChangeNew, ChangeUnchanged, "Created load balancer lb.example.com with an existing pool POOL which already has this tunnel as an origin"},
|
||||
{ChangeUpdated, ChangeNew, "Added new pool POOL with this tunnel as an origin to load balancer lb.example.com"},
|
||||
{ChangeUpdated, ChangeUpdated, "Updated pool POOL to use this tunnel as an origin and added it to load balancer lb.example.com"},
|
||||
{ChangeUpdated, ChangeUnchanged, "Added pool POOL, which already has this tunnel as an origin, to load balancer lb.example.com"},
|
||||
{ChangeUnchanged, ChangeNew, "Something went wrong: failed to modify load balancer lb.example.com with pool POOL; please check traffic manager configuration in the dashboard"},
|
||||
{ChangeUnchanged, ChangeUpdated, "Added this tunnel as an origin in pool POOL which is already used by load balancer lb.example.com"},
|
||||
{ChangeUnchanged, ChangeUnchanged, "Load balancer lb.example.com already uses pool POOL which has this tunnel as an origin"},
|
||||
{"", "", "Something went wrong: failed to modify load balancer lb.example.com with pool POOL; please check traffic manager configuration in the dashboard"},
|
||||
{"a", "b", "Something went wrong: failed to modify load balancer lb.example.com with pool POOL; please check traffic manager configuration in the dashboard"},
|
||||
}
|
||||
for i, tt := range tests {
|
||||
res := &LBRouteResult{
|
||||
route: route,
|
||||
LoadBalancer: tt.lb,
|
||||
Pool: tt.pool,
|
||||
}
|
||||
actual := res.SuccessSummary()
|
||||
assert.Equal(t, tt.expected, actual, "case %d", i+1)
|
||||
}
|
||||
}
|
||||
|
||||
func Test_parseListTunnels(t *testing.T) {
|
||||
type args struct {
|
||||
body string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want []*Tunnel
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "empty list",
|
||||
args: args{body: `{"success": true, "result": []}`},
|
||||
want: []*Tunnel{},
|
||||
},
|
||||
{
|
||||
name: "success is false",
|
||||
args: args{body: `{"success": false, "result": []}`},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "errors are present",
|
||||
args: args{body: `{"errors": ["foo"], "result": []}`},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "invalid response",
|
||||
args: args{body: `abc`},
|
||||
wantErr: true,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
body := ioutil.NopCloser(bytes.NewReader([]byte(tt.args.body)))
|
||||
got, err := parseListTunnels(body)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("parseListTunnels() error = %v, wantErr %v", err, tt.wantErr)
|
||||
return
|
||||
}
|
||||
if !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("parseListTunnels() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_unmarshalTunnel(t *testing.T) {
|
||||
type args struct {
|
||||
reader io.Reader
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want *Tunnel
|
||||
wantErr bool
|
||||
}{
|
||||
// TODO: Add test cases.
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got, err := unmarshalTunnel(tt.args.reader)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("unmarshalTunnel() error = %v, wantErr %v", err, tt.wantErr)
|
||||
return
|
||||
}
|
||||
if !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("unmarshalTunnel() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestUnmarshalTunnelOk(t *testing.T) {
|
||||
|
||||
jsonBody := `{"success": true, "result": {"id": "00000000-0000-0000-0000-000000000000","name":"test","created_at":"0001-01-01T00:00:00Z","connections":[]}}`
|
||||
expected := Tunnel{
|
||||
ID: uuid.Nil,
|
||||
Name: "test",
|
||||
CreatedAt: time.Time{},
|
||||
Connections: []Connection{},
|
||||
}
|
||||
actual, err := unmarshalTunnel(bytes.NewReader([]byte(jsonBody)))
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, &expected, actual)
|
||||
}
|
||||
|
||||
func TestUnmarshalTunnelErr(t *testing.T) {
|
||||
|
||||
tests := []string{
|
||||
`abc`,
|
||||
`{"success": true, "result": abc}`,
|
||||
`{"success": false, "result": {"id": "00000000-0000-0000-0000-000000000000","name":"test","created_at":"0001-01-01T00:00:00Z","connections":[]}}}`,
|
||||
`{"errors": ["foo"], "result": {"id": "00000000-0000-0000-0000-000000000000","name":"test","created_at":"0001-01-01T00:00:00Z","connections":[]}}}`,
|
||||
}
|
||||
|
||||
for i, test := range tests {
|
||||
_, err := unmarshalTunnel(bytes.NewReader([]byte(test)))
|
||||
assert.Error(t, err, fmt.Sprintf("Test #%v failed", i))
|
||||
}
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
version: 1.0.{build}
|
||||
clone_folder: c:\gopath\src\github.com\gdamore\encoding
|
||||
environment:
|
||||
GOPATH: c:\gopath
|
||||
build_script:
|
||||
- go version
|
||||
- go env
|
||||
- SET PATH=%LOCALAPPDATA%\atom\bin;%GOPATH%\bin;%PATH%
|
||||
- go get -t ./...
|
||||
- go build
|
||||
- go install ./...
|
||||
test_script:
|
||||
- go test ./...
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
language: go
|
||||
|
||||
go:
|
||||
- 1.9.x
|
||||
- 1.10.x
|
||||
- 1.11.x
|
||||
- tip
|
||||
+202
@@ -0,0 +1,202 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
## encoding
|
||||
|
||||
[](https://travis-ci.org/gdamore/encoding)
|
||||
[](https://ci.appveyor.com/project/gdamore/encoding)
|
||||
[](https://github.com/gdamore/encoding/blob/master/LICENSE)
|
||||
[](https://godoc.org/github.com/gdamore/encoding)
|
||||
[](http://goreportcard.com/report/gdamore/encoding)
|
||||
|
||||
Package encoding provides a number of encodings that are missing from the
|
||||
standard Go [encoding]("https://godoc.org/golang.org/x/text/encoding") package.
|
||||
|
||||
We hope that we can contribute these to the standard Go library someday. It
|
||||
turns out that some of these are useful for dealing with I/O streams coming
|
||||
from non-UTF friendly sources.
|
||||
|
||||
The UTF8 Encoder is also useful for situations where valid UTF-8 might be
|
||||
carried in streams that contain non-valid UTF; in particular I use it for
|
||||
helping me cope with terminals that embed escape sequences in otherwise
|
||||
valid UTF-8.
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
// Copyright 2015 Garrett D'Amore
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use file except in compliance with the License.
|
||||
// You may obtain a copy of the license at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package encoding
|
||||
|
||||
import (
|
||||
"golang.org/x/text/encoding"
|
||||
)
|
||||
|
||||
// ASCII represents the 7-bit US-ASCII scheme. It decodes directly to
|
||||
// UTF-8 without change, as all ASCII values are legal UTF-8.
|
||||
// Unicode values less than 128 (i.e. 7 bits) map 1:1 with ASCII.
|
||||
// It encodes runes outside of that to 0x1A, the ASCII substitution character.
|
||||
var ASCII encoding.Encoding
|
||||
|
||||
func init() {
|
||||
amap := make(map[byte]rune)
|
||||
for i := 128; i <= 255; i++ {
|
||||
amap[byte(i)] = RuneError
|
||||
}
|
||||
|
||||
cm := &Charmap{Map: amap}
|
||||
cm.Init()
|
||||
ASCII = cm
|
||||
}
|
||||
+196
@@ -0,0 +1,196 @@
|
||||
// Copyright 2015 Garrett D'Amore
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use file except in compliance with the License.
|
||||
// You may obtain a copy of the license at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package encoding
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"unicode/utf8"
|
||||
|
||||
"golang.org/x/text/encoding"
|
||||
"golang.org/x/text/transform"
|
||||
)
|
||||
|
||||
const (
|
||||
// RuneError is an alias for the UTF-8 replacement rune, '\uFFFD'.
|
||||
RuneError = '\uFFFD'
|
||||
|
||||
// RuneSelf is the rune below which UTF-8 and the Unicode values are
|
||||
// identical. Its also the limit for ASCII.
|
||||
RuneSelf = 0x80
|
||||
|
||||
// ASCIISub is the ASCII substitution character.
|
||||
ASCIISub = '\x1a'
|
||||
)
|
||||
|
||||
// Charmap is a structure for setting up encodings for 8-bit character sets,
|
||||
// for transforming between UTF8 and that other character set. It has some
|
||||
// ideas borrowed from golang.org/x/text/encoding/charmap, but it uses a
|
||||
// different implementation. This implementation uses maps, and supports
|
||||
// user-defined maps.
|
||||
//
|
||||
// We do assume that a character map has a reasonable substitution character,
|
||||
// and that valid encodings are stable (exactly a 1:1 map) and stateless
|
||||
// (that is there is no shift character or anything like that.) Hence this
|
||||
// approach will not work for many East Asian character sets.
|
||||
//
|
||||
// Measurement shows little or no measurable difference in the performance of
|
||||
// the two approaches. The difference was down to a couple of nsec/op, and
|
||||
// no consistent pattern as to which ran faster. With the conversion to
|
||||
// UTF-8 the code takes about 25 nsec/op. The conversion in the reverse
|
||||
// direction takes about 100 nsec/op. (The larger cost for conversion
|
||||
// from UTF-8 is most likely due to the need to convert the UTF-8 byte stream
|
||||
// to a rune before conversion.
|
||||
//
|
||||
type Charmap struct {
|
||||
transform.NopResetter
|
||||
bytes map[rune]byte
|
||||
runes [256][]byte
|
||||
once sync.Once
|
||||
|
||||
// The map between bytes and runes. To indicate that a specific
|
||||
// byte value is invalid for a charcter set, use the rune
|
||||
// utf8.RuneError. Values that are absent from this map will
|
||||
// be assumed to have the identity mapping -- that is the default
|
||||
// is to assume ISO8859-1, where all 8-bit characters have the same
|
||||
// numeric value as their Unicode runes. (Not to be confused with
|
||||
// the UTF-8 values, which *will* be different for non-ASCII runes.)
|
||||
//
|
||||
// If no values less than RuneSelf are changed (or have non-identity
|
||||
// mappings), then the character set is assumed to be an ASCII
|
||||
// superset, and certain assumptions and optimizations become
|
||||
// available for ASCII bytes.
|
||||
Map map[byte]rune
|
||||
|
||||
// The ReplacementChar is the byte value to use for substitution.
|
||||
// It should normally be ASCIISub for ASCII encodings. This may be
|
||||
// unset (left to zero) for mappings that are strictly ASCII supersets.
|
||||
// In that case ASCIISub will be assumed instead.
|
||||
ReplacementChar byte
|
||||
}
|
||||
|
||||
type cmapDecoder struct {
|
||||
transform.NopResetter
|
||||
runes [256][]byte
|
||||
}
|
||||
|
||||
type cmapEncoder struct {
|
||||
transform.NopResetter
|
||||
bytes map[rune]byte
|
||||
replace byte
|
||||
}
|
||||
|
||||
// Init initializes internal values of a character map. This should
|
||||
// be done early, to minimize the cost of allocation of transforms
|
||||
// later. It is not strictly necessary however, as the allocation
|
||||
// functions will arrange to call it if it has not already been done.
|
||||
func (c *Charmap) Init() {
|
||||
c.once.Do(c.initialize)
|
||||
}
|
||||
|
||||
func (c *Charmap) initialize() {
|
||||
c.bytes = make(map[rune]byte)
|
||||
ascii := true
|
||||
|
||||
for i := 0; i < 256; i++ {
|
||||
r, ok := c.Map[byte(i)]
|
||||
if !ok {
|
||||
r = rune(i)
|
||||
}
|
||||
if r < 128 && r != rune(i) {
|
||||
ascii = false
|
||||
}
|
||||
if r != RuneError {
|
||||
c.bytes[r] = byte(i)
|
||||
}
|
||||
utf := make([]byte, utf8.RuneLen(r))
|
||||
utf8.EncodeRune(utf, r)
|
||||
c.runes[i] = utf
|
||||
}
|
||||
if ascii && c.ReplacementChar == '\x00' {
|
||||
c.ReplacementChar = ASCIISub
|
||||
}
|
||||
}
|
||||
|
||||
// NewDecoder returns a Decoder the converts from the 8-bit
|
||||
// character set to UTF-8. Unknown mappings, if any, are mapped
|
||||
// to '\uFFFD'.
|
||||
func (c *Charmap) NewDecoder() *encoding.Decoder {
|
||||
c.Init()
|
||||
return &encoding.Decoder{Transformer: &cmapDecoder{runes: c.runes}}
|
||||
}
|
||||
|
||||
// NewEncoder returns a Transformer that converts from UTF8 to the
|
||||
// 8-bit character set. Unknown mappings are mapped to 0x1A.
|
||||
func (c *Charmap) NewEncoder() *encoding.Encoder {
|
||||
c.Init()
|
||||
return &encoding.Encoder{
|
||||
Transformer: &cmapEncoder{
|
||||
bytes: c.bytes,
|
||||
replace: c.ReplacementChar,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (d *cmapDecoder) Transform(dst, src []byte, atEOF bool) (int, int, error) {
|
||||
var e error
|
||||
var ndst, nsrc int
|
||||
|
||||
for _, c := range src {
|
||||
b := d.runes[c]
|
||||
l := len(b)
|
||||
|
||||
if ndst+l > len(dst) {
|
||||
e = transform.ErrShortDst
|
||||
break
|
||||
}
|
||||
for i := 0; i < l; i++ {
|
||||
dst[ndst] = b[i]
|
||||
ndst++
|
||||
}
|
||||
nsrc++
|
||||
}
|
||||
return ndst, nsrc, e
|
||||
}
|
||||
|
||||
func (d *cmapEncoder) Transform(dst, src []byte, atEOF bool) (int, int, error) {
|
||||
var e error
|
||||
var ndst, nsrc int
|
||||
for nsrc < len(src) {
|
||||
if ndst >= len(dst) {
|
||||
e = transform.ErrShortDst
|
||||
break
|
||||
}
|
||||
|
||||
r, sz := utf8.DecodeRune(src[nsrc:])
|
||||
if r == utf8.RuneError && sz == 1 {
|
||||
// If its inconclusive due to insufficient data in
|
||||
// in the source, report it
|
||||
if !atEOF && !utf8.FullRune(src[nsrc:]) {
|
||||
e = transform.ErrShortSrc
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if c, ok := d.bytes[r]; ok {
|
||||
dst[ndst] = c
|
||||
} else {
|
||||
dst[ndst] = d.replace
|
||||
}
|
||||
nsrc += sz
|
||||
ndst++
|
||||
}
|
||||
|
||||
return ndst, nsrc, e
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
// Copyright 2015 Garrett D'Amore
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use file except in compliance with the License.
|
||||
// You may obtain a copy of the license at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Package encoding provides a few of the encoding structures that are
|
||||
// missing from the Go x/text/encoding tree.
|
||||
package encoding
|
||||
+273
@@ -0,0 +1,273 @@
|
||||
// Copyright 2015 Garrett D'Amore
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use file except in compliance with the License.
|
||||
// You may obtain a copy of the license at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package encoding
|
||||
|
||||
import (
|
||||
"golang.org/x/text/encoding"
|
||||
)
|
||||
|
||||
// EBCDIC represents the 8-bit EBCDIC scheme, found in some mainframe
|
||||
// environments. If you don't know what this is, consider yourself lucky.
|
||||
var EBCDIC encoding.Encoding
|
||||
|
||||
func init() {
|
||||
cm := &Charmap{
|
||||
ReplacementChar: '\x3f',
|
||||
Map: map[byte]rune{
|
||||
// 0x00-0x03 match
|
||||
0x04: RuneError,
|
||||
0x05: '\t',
|
||||
0x06: RuneError,
|
||||
0x07: '\x7f',
|
||||
0x08: RuneError,
|
||||
0x09: RuneError,
|
||||
0x0a: RuneError,
|
||||
// 0x0b-0x13 match
|
||||
0x14: RuneError,
|
||||
0x15: '\x85', // Not in any ISO code
|
||||
0x16: '\x08',
|
||||
0x17: RuneError,
|
||||
// 0x18-0x19 match
|
||||
0x1a: RuneError,
|
||||
0x1b: RuneError,
|
||||
// 0x1c-0x1f match
|
||||
0x20: RuneError,
|
||||
0x21: RuneError,
|
||||
0x22: RuneError,
|
||||
0x23: RuneError,
|
||||
0x24: RuneError,
|
||||
0x25: '\n',
|
||||
0x26: '\x17',
|
||||
0x27: '\x1b',
|
||||
0x28: RuneError,
|
||||
0x29: RuneError,
|
||||
0x2a: RuneError,
|
||||
0x2b: RuneError,
|
||||
0x2c: RuneError,
|
||||
0x2d: '\x05',
|
||||
0x2e: '\x06',
|
||||
0x2f: '\x07',
|
||||
0x30: RuneError,
|
||||
0x31: RuneError,
|
||||
0x32: '\x16',
|
||||
0x33: RuneError,
|
||||
0x34: RuneError,
|
||||
0x35: RuneError,
|
||||
0x36: RuneError,
|
||||
0x37: '\x04',
|
||||
0x38: RuneError,
|
||||
0x39: RuneError,
|
||||
0x3a: RuneError,
|
||||
0x3b: RuneError,
|
||||
0x3c: '\x14',
|
||||
0x3d: '\x15',
|
||||
0x3e: RuneError,
|
||||
0x3f: '\x1a', // also replacement char
|
||||
0x40: ' ',
|
||||
0x41: '\xa0',
|
||||
0x42: RuneError,
|
||||
0x43: RuneError,
|
||||
0x44: RuneError,
|
||||
0x45: RuneError,
|
||||
0x46: RuneError,
|
||||
0x47: RuneError,
|
||||
0x48: RuneError,
|
||||
0x49: RuneError,
|
||||
0x4a: RuneError,
|
||||
0x4b: '.',
|
||||
0x4c: '<',
|
||||
0x4d: '(',
|
||||
0x4e: '+',
|
||||
0x4f: '|',
|
||||
0x50: '&',
|
||||
0x51: RuneError,
|
||||
0x52: RuneError,
|
||||
0x53: RuneError,
|
||||
0x54: RuneError,
|
||||
0x55: RuneError,
|
||||
0x56: RuneError,
|
||||
0x57: RuneError,
|
||||
0x58: RuneError,
|
||||
0x59: RuneError,
|
||||
0x5a: '!',
|
||||
0x5b: '$',
|
||||
0x5c: '*',
|
||||
0x5d: ')',
|
||||
0x5e: ';',
|
||||
0x5f: '¬',
|
||||
0x60: '-',
|
||||
0x61: '/',
|
||||
0x62: RuneError,
|
||||
0x63: RuneError,
|
||||
0x64: RuneError,
|
||||
0x65: RuneError,
|
||||
0x66: RuneError,
|
||||
0x67: RuneError,
|
||||
0x68: RuneError,
|
||||
0x69: RuneError,
|
||||
0x6a: '¦',
|
||||
0x6b: ',',
|
||||
0x6c: '%',
|
||||
0x6d: '_',
|
||||
0x6e: '>',
|
||||
0x6f: '?',
|
||||
0x70: RuneError,
|
||||
0x71: RuneError,
|
||||
0x72: RuneError,
|
||||
0x73: RuneError,
|
||||
0x74: RuneError,
|
||||
0x75: RuneError,
|
||||
0x76: RuneError,
|
||||
0x77: RuneError,
|
||||
0x78: RuneError,
|
||||
0x79: '`',
|
||||
0x7a: ':',
|
||||
0x7b: '#',
|
||||
0x7c: '@',
|
||||
0x7d: '\'',
|
||||
0x7e: '=',
|
||||
0x7f: '"',
|
||||
0x80: RuneError,
|
||||
0x81: 'a',
|
||||
0x82: 'b',
|
||||
0x83: 'c',
|
||||
0x84: 'd',
|
||||
0x85: 'e',
|
||||
0x86: 'f',
|
||||
0x87: 'g',
|
||||
0x88: 'h',
|
||||
0x89: 'i',
|
||||
0x8a: RuneError,
|
||||
0x8b: RuneError,
|
||||
0x8c: RuneError,
|
||||
0x8d: RuneError,
|
||||
0x8e: RuneError,
|
||||
0x8f: '±',
|
||||
0x90: RuneError,
|
||||
0x91: 'j',
|
||||
0x92: 'k',
|
||||
0x93: 'l',
|
||||
0x94: 'm',
|
||||
0x95: 'n',
|
||||
0x96: 'o',
|
||||
0x97: 'p',
|
||||
0x98: 'q',
|
||||
0x99: 'r',
|
||||
0x9a: RuneError,
|
||||
0x9b: RuneError,
|
||||
0x9c: RuneError,
|
||||
0x9d: RuneError,
|
||||
0x9e: RuneError,
|
||||
0x9f: RuneError,
|
||||
0xa0: RuneError,
|
||||
0xa1: '~',
|
||||
0xa2: 's',
|
||||
0xa3: 't',
|
||||
0xa4: 'u',
|
||||
0xa5: 'v',
|
||||
0xa6: 'w',
|
||||
0xa7: 'x',
|
||||
0xa8: 'y',
|
||||
0xa9: 'z',
|
||||
0xaa: RuneError,
|
||||
0xab: RuneError,
|
||||
0xac: RuneError,
|
||||
0xad: RuneError,
|
||||
0xae: RuneError,
|
||||
0xaf: RuneError,
|
||||
0xb0: '^',
|
||||
0xb1: RuneError,
|
||||
0xb2: RuneError,
|
||||
0xb3: RuneError,
|
||||
0xb4: RuneError,
|
||||
0xb5: RuneError,
|
||||
0xb6: RuneError,
|
||||
0xb7: RuneError,
|
||||
0xb8: RuneError,
|
||||
0xb9: RuneError,
|
||||
0xba: '[',
|
||||
0xbb: ']',
|
||||
0xbc: RuneError,
|
||||
0xbd: RuneError,
|
||||
0xbe: RuneError,
|
||||
0xbf: RuneError,
|
||||
0xc0: '{',
|
||||
0xc1: 'A',
|
||||
0xc2: 'B',
|
||||
0xc3: 'C',
|
||||
0xc4: 'D',
|
||||
0xc5: 'E',
|
||||
0xc6: 'F',
|
||||
0xc7: 'G',
|
||||
0xc8: 'H',
|
||||
0xc9: 'I',
|
||||
0xca: '\xad', // NB: soft hyphen
|
||||
0xcb: RuneError,
|
||||
0xcc: RuneError,
|
||||
0xcd: RuneError,
|
||||
0xce: RuneError,
|
||||
0xcf: RuneError,
|
||||
0xd0: '}',
|
||||
0xd1: 'J',
|
||||
0xd2: 'K',
|
||||
0xd3: 'L',
|
||||
0xd4: 'M',
|
||||
0xd5: 'N',
|
||||
0xd6: 'O',
|
||||
0xd7: 'P',
|
||||
0xd8: 'Q',
|
||||
0xd9: 'R',
|
||||
0xda: RuneError,
|
||||
0xdb: RuneError,
|
||||
0xdc: RuneError,
|
||||
0xdd: RuneError,
|
||||
0xde: RuneError,
|
||||
0xdf: RuneError,
|
||||
0xe0: '\\',
|
||||
0xe1: '\u2007', // Non-breaking space
|
||||
0xe2: 'S',
|
||||
0xe3: 'T',
|
||||
0xe4: 'U',
|
||||
0xe5: 'V',
|
||||
0xe6: 'W',
|
||||
0xe7: 'X',
|
||||
0xe8: 'Y',
|
||||
0xe9: 'Z',
|
||||
0xea: RuneError,
|
||||
0xeb: RuneError,
|
||||
0xec: RuneError,
|
||||
0xed: RuneError,
|
||||
0xee: RuneError,
|
||||
0xef: RuneError,
|
||||
0xf0: '0',
|
||||
0xf1: '1',
|
||||
0xf2: '2',
|
||||
0xf3: '3',
|
||||
0xf4: '4',
|
||||
0xf5: '5',
|
||||
0xf6: '6',
|
||||
0xf7: '7',
|
||||
0xf8: '8',
|
||||
0xf9: '9',
|
||||
0xfa: RuneError,
|
||||
0xfb: RuneError,
|
||||
0xfc: RuneError,
|
||||
0xfd: RuneError,
|
||||
0xfe: RuneError,
|
||||
0xff: RuneError,
|
||||
}}
|
||||
cm.Init()
|
||||
EBCDIC = cm
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
module github.com/gdamore/encoding
|
||||
|
||||
go 1.9
|
||||
|
||||
require golang.org/x/text v0.3.0
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
// Copyright 2015 Garrett D'Amore
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use file except in compliance with the License.
|
||||
// You may obtain a copy of the license at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package encoding
|
||||
|
||||
import (
|
||||
"golang.org/x/text/encoding"
|
||||
)
|
||||
|
||||
// ISO8859_1 represents the 8-bit ISO8859-1 scheme. It decodes directly to
|
||||
// UTF-8 without change, as all ISO8859-1 values are legal UTF-8.
|
||||
// Unicode values less than 256 (i.e. 8 bits) map 1:1 with 8859-1.
|
||||
// It encodes runes outside of that to 0x1A, the ASCII substitution character.
|
||||
var ISO8859_1 encoding.Encoding
|
||||
|
||||
func init() {
|
||||
cm := &Charmap{}
|
||||
cm.Init()
|
||||
|
||||
// 8859-1 is the 8-bit identity map for Unicode.
|
||||
ISO8859_1 = cm
|
||||
}
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
// Copyright 2015 Garrett D'Amore
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use file except in compliance with the License.
|
||||
// You may obtain a copy of the license at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package encoding
|
||||
|
||||
import (
|
||||
"golang.org/x/text/encoding"
|
||||
)
|
||||
|
||||
// ISO8859_9 represents the 8-bit ISO8859-9 scheme.
|
||||
var ISO8859_9 encoding.Encoding
|
||||
|
||||
func init() {
|
||||
cm := &Charmap{Map: map[byte]rune{
|
||||
0xD0: 'Ğ',
|
||||
0xDD: 'İ',
|
||||
0xDE: 'Ş',
|
||||
0xF0: 'ğ',
|
||||
0xFD: 'ı',
|
||||
0xFE: 'ş',
|
||||
}}
|
||||
cm.Init()
|
||||
ISO8859_9 = cm
|
||||
}
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
// Copyright 2015 Garrett D'Amore
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use file except in compliance with the License.
|
||||
// You may obtain a copy of the license at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package encoding
|
||||
|
||||
import (
|
||||
"golang.org/x/text/encoding"
|
||||
)
|
||||
|
||||
type validUtf8 struct{}
|
||||
|
||||
// UTF8 is an encoding for UTF-8. All it does is verify that the UTF-8
|
||||
// in is valid. The main reason for its existence is that it will detect
|
||||
// and report ErrSrcShort or ErrDstShort, whereas the Nop encoding just
|
||||
// passes every byte, blithely.
|
||||
var UTF8 encoding.Encoding = validUtf8{}
|
||||
|
||||
func (validUtf8) NewDecoder() *encoding.Decoder {
|
||||
return &encoding.Decoder{Transformer: encoding.UTF8Validator}
|
||||
}
|
||||
|
||||
func (validUtf8) NewEncoder() *encoding.Encoder {
|
||||
return &encoding.Encoder{Transformer: encoding.UTF8Validator}
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
version: 1.0.{build}
|
||||
clone_folder: c:\gopath\src\github.com\gdamore\tcell
|
||||
environment:
|
||||
GOPATH: c:\gopath
|
||||
build_script:
|
||||
- go version
|
||||
- go env
|
||||
- SET PATH=%LOCALAPPDATA%\atom\bin;%GOPATH%\bin;%PATH%
|
||||
- go get -t ./...
|
||||
- go build
|
||||
- go install ./...
|
||||
test_script:
|
||||
- go test ./...
|
||||
+1
@@ -0,0 +1 @@
|
||||
coverage.txt
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
language: go
|
||||
|
||||
go:
|
||||
- 1.10.x
|
||||
- 1.11.x
|
||||
- master
|
||||
|
||||
before_install:
|
||||
- go get -t -v ./...
|
||||
|
||||
script:
|
||||
- go test -race -coverprofile=coverage.txt -covermode=atomic
|
||||
|
||||
after_success:
|
||||
- bash <(curl -s https://codecov.io/bash)
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
Garrett D'Amore <garrett@damore.org>
|
||||
Zachary Yedidia <zyedidia@gmail.com>
|
||||
Junegunn Choi <junegunn.c@gmail.com>
|
||||
Staysail Systems, Inc. <info@staysail.tech>
|
||||
+202
@@ -0,0 +1,202 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
+272
@@ -0,0 +1,272 @@
|
||||
= tcell
|
||||
|
||||
|
||||
image:https://img.shields.io/travis/gdamore/tcell.svg?label=linux[Linux Status,link="https://travis-ci.org/gdamore/tcell"]
|
||||
image:https://img.shields.io/appveyor/ci/gdamore/tcell.svg?label=windows[Windows Status,link="https://ci.appveyor.com/project/gdamore/tcell"]
|
||||
image:https://img.shields.io/badge/license-APACHE2-blue.svg[Apache License,link="https://github.com/gdamore/tcell/blob/master/LICENSE"]
|
||||
image:https://img.shields.io/badge/gitter-join-brightgreen.svg[Gitter,link="https://gitter.im/gdamore/tcell"]
|
||||
image:https://img.shields.io/badge/godoc-reference-blue.svg[GoDoc,link="https://godoc.org/github.com/gdamore/tcell"]
|
||||
image:http://goreportcard.com/badge/gdamore/tcell[Go Report Card,link="http://goreportcard.com/report/gdamore/tcell"]
|
||||
image:https://codecov.io/gh/gdamore/tcell/branch/master/graph/badge.svg[codecov,link="https://codecov.io/gh/gdamore/tcell"]
|
||||
image:https://tidelift.com/badges/github/gdamore/tcell?style=flat[Dependencies]
|
||||
|
||||
[cols="2",grid="none"]
|
||||
|===
|
||||
|_Tcell_ is a _Go_ package that provides a cell based view for text terminals, like _xterm_.
|
||||
It was inspired by _termbox_, but includes many additional improvements.
|
||||
a|[.right]
|
||||
image::logos/tcell.png[float="right"]
|
||||
|===
|
||||
|
||||
## Examples
|
||||
|
||||
* https://github.com/gdamore/proxima5[proxima5] - space shooter (https://youtu.be/jNxKTCmY_bQ[video])
|
||||
* https://github.com/gdamore/govisor[govisor] - service management UI (http://2.bp.blogspot.com/--OsvnfzSNow/Vf7aqMw3zXI/AAAAAAAAARo/uOMtOvw4Sbg/s1600/Screen%2BShot%2B2015-09-20%2Bat%2B9.08.41%2BAM.png[screenshot])
|
||||
* mouse demo - included mouse test (http://2.bp.blogspot.com/-fWvW5opT0es/VhIdItdKqJI/AAAAAAAAATE/7Ojc0L1SpB0/s1600/Screen%2BShot%2B2015-10-04%2Bat%2B11.47.13%2BPM.png[screenshot])
|
||||
* https://github.com/gdamore/gomatrix[gomatrix] - converted from Termbox
|
||||
* https://github.com/zyedidia/micro/[micro] - lightweight text editor with syntax-highlighting and themes
|
||||
* https://github.com/viktomas/godu[godu] - simple golang utility helping to discover large files/folders.
|
||||
* https://github.com/rivo/tview[tview] - rich interactive widgets for terminal UIs
|
||||
* https://github.com/marcusolsson/tui-go[tui-go] - UI library for terminal apps
|
||||
* https://github.com/rgm3/gomandelbrot[gomandelbrot] - Mandelbrot!
|
||||
* https://github.com/senorprogrammer/wtf[WTF]- Personal information dashboard for your terminal
|
||||
* https://github.com/browsh-org/browsh[browsh] - A fully-modern text-based browser, rendering to TTY and browsers (https://www.youtube.com/watch?v=HZq86XfBoRo[video])
|
||||
* https://github.com/sachaos/go-life[go-life] - Conway's Game of Life.
|
||||
* https://github.com/gcla/gowid[gowid] - compositional widgets for terminal UIs, inspired by urwid
|
||||
* https://termshark.io[termshark] - a terminal UI for tshark, inspired by Wireshark, built on gowid
|
||||
|
||||
## Pure Go Terminfo Database
|
||||
|
||||
_Tcell_ includes a full parser and expander for terminfo capability strings,
|
||||
so that it can avoid hard coding escape strings for formatting. It also favors
|
||||
portability, and includes support for all POSIX systems.
|
||||
|
||||
The database is also flexible & extensible, and can modified by either running
|
||||
a program to build the entire database, or an entry for just a single terminal.
|
||||
|
||||
## More Portable
|
||||
|
||||
_Tcell_ is portable to a wide variety of systems.
|
||||
_Tcell_ is believed
|
||||
to work with all of the systems officially supported by golang with
|
||||
the exception of nacl (which lacks any kind of a terminal interface).
|
||||
(Plan9 is not supported by _Tcell_, but it is experimental status only
|
||||
in golang.) For all of these systems *except Solaris/illumos*, _Tcell_
|
||||
is pure Go, with no need for CGO.
|
||||
|
||||
## No Async IO
|
||||
|
||||
_Tcell_ is able to operate without requiring `SIGIO` signals (unlike _termbox_),
|
||||
or asynchronous I/O, and can instead use standard Go file
|
||||
objects and Go routines.
|
||||
This means it should be safe, especially for
|
||||
use with programs that use exec, or otherwise need to manipulate the
|
||||
tty streams.
|
||||
This model is also much closer to idiomatic Go, leading
|
||||
to fewer surprises.
|
||||
|
||||
## Rich Unicode & non-Unicode support
|
||||
|
||||
_Tcell_ includes enhanced support for Unicode, including wide characters and
|
||||
combining characters, provided your terminal can support them.
|
||||
Note that
|
||||
Windows terminals generally don't support the full Unicode repertoire.
|
||||
|
||||
It will also convert to and from Unicode locales, so that the program
|
||||
can work with UTF-8 internally, and get reasonable output in other locales.
|
||||
_Tcell_ tries hard to convert to native characters on both input and output, and
|
||||
on output _Tcell_ even makes use of the alternate character set to facilitate
|
||||
drawing certain characters.
|
||||
|
||||
## More Function Keys
|
||||
|
||||
_Tcell_ also has richer support for a larger number of special keys that some terminals can send.
|
||||
|
||||
## Better Color Handling
|
||||
|
||||
_Tcell_ will respect your terminal's color space as specified within your terminfo
|
||||
entries, so that for example attempts to emit color sequences on VT100 terminals
|
||||
won't result in unintended consequences.
|
||||
|
||||
In Windows mode, _Tcell_ supports 16 colors, bold, dim, and reverse,
|
||||
instead of just termbox's 8 colors with reverse. (Note that there is some
|
||||
conflation with bold/dim and colors.)
|
||||
|
||||
_Tcell_ maps 16 colors down to 8, for terminals that need it.
|
||||
(The upper 8 colors are just brighter versions of the lower 8.)
|
||||
|
||||
## Better Mouse Support
|
||||
|
||||
_Tcell_ supports enhanced mouse tracking mode, so your application can receive
|
||||
regular mouse motion events, and wheel events, if your terminal supports it.
|
||||
|
||||
## _Termbox_ Compatibility
|
||||
|
||||
A compatibility layer for _termbox_ is provided in the `compat` directory.
|
||||
To use it, try importing `github.com/gdamore/tcell/termbox`
|
||||
instead. Most _termbox-go_ programs will probably work without further
|
||||
modification.
|
||||
|
||||
## Working With Unicode
|
||||
|
||||
Internally Tcell uses UTF-8, just like Go.
|
||||
However, Tcell understands how to
|
||||
convert to and from other character sets, using the capabilities of
|
||||
the `golang.org/x/text/encoding packages`.
|
||||
Your application must supply
|
||||
them, as the full set of the most common ones bloats the program by about 2MB.
|
||||
If you're lazy, and want them all anyway, see the `encoding` sub-directory.
|
||||
|
||||
## Wide & Combining Characters
|
||||
|
||||
The `SetContent()` API takes a primary rune, and an optional list of combining runes.
|
||||
If any of the runes is a wide (East Asian) rune occupying two cells,
|
||||
then the library will skip output from the following cell, but care must be
|
||||
taken in the application to avoid explicitly attempting to set content in the
|
||||
next cell, otherwise the results are undefined. (Normally wide character
|
||||
is displayed, and the other character is not; do not depend on that behavior.)
|
||||
|
||||
Experience has shown that the vanilla Windows 8 console application does not
|
||||
support any of these characters properly, but at least some options like
|
||||
_ConEmu_ do support Wide characters.
|
||||
|
||||
## Colors
|
||||
|
||||
_Tcell_ assumes the ANSI/XTerm color model, including the 256 color map that
|
||||
XTerm uses when it supports 256 colors. The terminfo guidance will be
|
||||
honored, with respect to the number of colors supported. Also, only
|
||||
terminals which expose ANSI style `setaf` and `setab` will support color;
|
||||
if you have a color terminal that only has `setf` and `setb`, please let me
|
||||
know; it wouldn't be hard to add that if there is need.
|
||||
|
||||
## 24-bit Color
|
||||
|
||||
_Tcell_ _supports true color_! (That is, if your terminal can support it,
|
||||
_Tcell_ can accurately display 24-bit color.)
|
||||
|
||||
To use 24-bit color, you need to use a terminal that supports it. Modern
|
||||
xterm and similar teminal emulators can support this. As terminfo lacks any
|
||||
way to describe this capability, we fabricate the capability for
|
||||
terminals with names ending in `*-truecolor`. The stock distribution ships
|
||||
with a database that defines `xterm-truecolor`.
|
||||
To try it out, set your
|
||||
`TERM` variable to `xterm-truecolor`.
|
||||
|
||||
When using TrueColor, programs will display the colors that the programmer
|
||||
intended, overriding any "`themes`" you may have set in your terminal
|
||||
emulator. (For some cases, accurate color fidelity is more important
|
||||
than respecting themes. For other cases, such as typical text apps that
|
||||
only use a few colors, its more desirable to respect the themes that
|
||||
the user has established.)
|
||||
|
||||
If you find this undesirable, you can either use a `TERM` variable
|
||||
that lacks the `TRUECOLOR` setting, or set `TCELL_TRUECOLOR=disable` in your
|
||||
environment.
|
||||
|
||||
## Performance
|
||||
|
||||
Reasonable attempts have been made to minimize sending data to terminals,
|
||||
avoiding repeated sequences or drawing the same cell on refresh updates.
|
||||
|
||||
## Terminfo
|
||||
|
||||
(Not relevent for Windows users.)
|
||||
|
||||
The Terminfo implementation operates with two forms of database. The first
|
||||
is the built-in go database, which contains a number of real database entries
|
||||
that are compiled into the program directly. This should minimize calling
|
||||
out to database file searches.
|
||||
|
||||
The second is in the form of JSON files, that contain the same information,
|
||||
which can be located either by the `$TCELLDB` environment file, `$HOME/.tcelldb`,
|
||||
or is located in the Go source directory as `database.json`.
|
||||
|
||||
These files (both the Go and the JSON files) can be generated using the
|
||||
mkinfo.go program. If you need to regnerate the entire set for some reason,
|
||||
run the mkdatabase.sh file. The generation uses the infocmp(1) program on
|
||||
the system to collect the necessary information.
|
||||
|
||||
The `mkinfo.go` program can also be used to generate specific database entries
|
||||
for named terminals, in case your favorite terminal is missing. (If you
|
||||
find that this is the case, please let me know and I'll try to add it!)
|
||||
|
||||
_Tcell_ requires that the terminal support the `cup` mode of cursor addressing.
|
||||
Terminals without absolute cursor addressability are not supported.
|
||||
This is unlikely to be a problem; such terminals have not been mass produced
|
||||
since the early 1970s.
|
||||
|
||||
## Mouse Support
|
||||
|
||||
Mouse support is detected via the `kmous` terminfo variable, however,
|
||||
enablement/disablement and decoding mouse events is done using hard coded
|
||||
sequences based on the XTerm X11 model. As of this writing all popular
|
||||
terminals with mouse tracking support this model. (Full terminfo support
|
||||
is not possible as terminfo sequences are not defined.)
|
||||
|
||||
On Windows, the mouse works normally.
|
||||
|
||||
Mouse wheel buttons on various terminals are known to work, but the support
|
||||
in terminal emulators, as well as support for various buttons and
|
||||
live mouse tracking, varies widely. Modern _xterm_, macOS _Terminal_, and _iTerm_ all work well.
|
||||
|
||||
## Testablity
|
||||
|
||||
There is a `SimulationScreen`, that can be used to simulate a real screen
|
||||
for automated testing. The supplied tests do this. The simulation contains
|
||||
event delivery, screen resizing support, and capabilities to inject events
|
||||
and examine "`physical`" screen contents.
|
||||
|
||||
## Platforms
|
||||
|
||||
### POSIX (Linux, FreeBSD, macOS, Solaris, etc.)
|
||||
|
||||
For mainstream systems with a suitably well defined system call interface
|
||||
to tty settings, everything works using pure Go.
|
||||
|
||||
For the remainder (right now means only Solaris/illumos) we use POSIX function
|
||||
calls to manage termios, which implies that CGO is required on those platforms.
|
||||
|
||||
### Windows
|
||||
|
||||
Windows console mode applications are supported. Unfortunately _mintty_
|
||||
and other _cygwin_ style applications are not supported.
|
||||
|
||||
Modern console applications like ConEmu, as well as the Windows 10
|
||||
console itself, support all the good features (resize, mouse tracking, etc.)
|
||||
|
||||
I haven't figured out how to cleanly resolve the dichotomy between cygwin
|
||||
style termios and the Windows Console API; it seems that perhaps nobody else
|
||||
has either. If anyone has suggestions, let me know! Really, if you're
|
||||
using a Windows application, you should use the native Windows console or a
|
||||
fully compatible console implementation.
|
||||
|
||||
### Plan9 and Native Client (Nacl)
|
||||
|
||||
The nacl and plan9 platforms won't work, but compilation stubs are supplied
|
||||
for folks that want to include parts of this in software targetting those
|
||||
platforms. The Simulation screen works, but as Tcell doesn't know how to
|
||||
allocate a real screen object on those platforms, `NewScreen()` will fail.
|
||||
|
||||
If anyone has wisdom about how to improve support for either of these,
|
||||
please let me know. PRs are especially welcome.
|
||||
|
||||
### Commercial Support
|
||||
|
||||
_Tcell_ is absolutely free, but if you want to obtain commercial, professional support, there are options.
|
||||
|
||||
[cols="2",align="center",frame="none", grid="none"]
|
||||
|===
|
||||
^.^|
|
||||
image:logos/tidelift.png[100,100]
|
||||
a|
|
||||
https://tidelift.com/[Tidelift] subscriptions include support for _Tcell_, as well as many other open source packages.
|
||||
|
||||
^.^|
|
||||
image:logos/staysail.png[100,100]
|
||||
a|
|
||||
mailto:info@staysail.tech[Staysail Systems, Inc.] offers direct support, and custom development around _Tcell_ on an hourly basis.
|
||||
|
||||
^.^|
|
||||
image:logos/patreon.png[100,100]
|
||||
a|I also welcome donations at https://www.patreon.com/gedamore/[Patreon], if you just want to make a contribution.
|
||||
|===
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
// Copyright 2015 The TCell Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use file except in compliance with the License.
|
||||
// You may obtain a copy of the license at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package tcell
|
||||
|
||||
// AttrMask represents a mask of text attributes, apart from color.
|
||||
// Note that support for attributes may vary widely across terminals.
|
||||
type AttrMask int
|
||||
|
||||
// Attributes are not colors, but affect the display of text. They can
|
||||
// be combined.
|
||||
const (
|
||||
AttrBold AttrMask = 1 << (25 + iota)
|
||||
AttrBlink
|
||||
AttrReverse
|
||||
AttrUnderline
|
||||
AttrDim
|
||||
AttrNone AttrMask = 0 // Just normal text.
|
||||
)
|
||||
|
||||
const attrAll = AttrBold | AttrBlink | AttrReverse | AttrUnderline | AttrDim
|
||||
+177
@@ -0,0 +1,177 @@
|
||||
// Copyright 2019 The TCell Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use file except in compliance with the License.
|
||||
// You may obtain a copy of the license at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package tcell
|
||||
|
||||
import (
|
||||
runewidth "github.com/mattn/go-runewidth"
|
||||
)
|
||||
|
||||
type cell struct {
|
||||
currMain rune
|
||||
currComb []rune
|
||||
currStyle Style
|
||||
lastMain rune
|
||||
lastStyle Style
|
||||
lastComb []rune
|
||||
width int
|
||||
}
|
||||
|
||||
// CellBuffer represents a two dimensional array of character cells.
|
||||
// This is primarily intended for use by Screen implementors; it
|
||||
// contains much of the common code they need. To create one, just
|
||||
// declare a variable of its type; no explicit initialization is necessary.
|
||||
//
|
||||
// CellBuffer is not thread safe.
|
||||
type CellBuffer struct {
|
||||
w int
|
||||
h int
|
||||
cells []cell
|
||||
}
|
||||
|
||||
// SetContent sets the contents (primary rune, combining runes,
|
||||
// and style) for a cell at a given location.
|
||||
func (cb *CellBuffer) SetContent(x int, y int,
|
||||
mainc rune, combc []rune, style Style) {
|
||||
|
||||
if x >= 0 && y >= 0 && x < cb.w && y < cb.h {
|
||||
c := &cb.cells[(y*cb.w)+x]
|
||||
|
||||
c.currComb = append([]rune{}, combc...)
|
||||
|
||||
if c.currMain != mainc {
|
||||
c.width = runewidth.RuneWidth(mainc)
|
||||
}
|
||||
c.currMain = mainc
|
||||
c.currStyle = style
|
||||
}
|
||||
}
|
||||
|
||||
// GetContent returns the contents of a character cell, including the
|
||||
// primary rune, any combining character runes (which will usually be
|
||||
// nil), the style, and the display width in cells. (The width can be
|
||||
// either 1, normally, or 2 for East Asian full-width characters.)
|
||||
func (cb *CellBuffer) GetContent(x, y int) (rune, []rune, Style, int) {
|
||||
var mainc rune
|
||||
var combc []rune
|
||||
var style Style
|
||||
var width int
|
||||
if x >= 0 && y >= 0 && x < cb.w && y < cb.h {
|
||||
c := &cb.cells[(y*cb.w)+x]
|
||||
mainc, combc, style = c.currMain, c.currComb, c.currStyle
|
||||
if width = c.width; width == 0 || mainc < ' ' {
|
||||
width = 1
|
||||
mainc = ' '
|
||||
}
|
||||
}
|
||||
return mainc, combc, style, width
|
||||
}
|
||||
|
||||
// Size returns the (width, height) in cells of the buffer.
|
||||
func (cb *CellBuffer) Size() (int, int) {
|
||||
return cb.w, cb.h
|
||||
}
|
||||
|
||||
// Invalidate marks all characters within the buffer as dirty.
|
||||
func (cb *CellBuffer) Invalidate() {
|
||||
for i := range cb.cells {
|
||||
cb.cells[i].lastMain = rune(0)
|
||||
}
|
||||
}
|
||||
|
||||
// Dirty checks if a character at the given location needs an
|
||||
// to be refreshed on the physical display. This returns true
|
||||
// if the cell content is different since the last time it was
|
||||
// marked clean.
|
||||
func (cb *CellBuffer) Dirty(x, y int) bool {
|
||||
if x >= 0 && y >= 0 && x < cb.w && y < cb.h {
|
||||
c := &cb.cells[(y*cb.w)+x]
|
||||
if c.lastMain == rune(0) {
|
||||
return true
|
||||
}
|
||||
if c.lastMain != c.currMain {
|
||||
return true
|
||||
}
|
||||
if c.lastStyle != c.currStyle {
|
||||
return true
|
||||
}
|
||||
if len(c.lastComb) != len(c.currComb) {
|
||||
return true
|
||||
}
|
||||
for i := range c.lastComb {
|
||||
if c.lastComb[i] != c.currComb[i] {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// SetDirty is normally used to indicate that a cell has
|
||||
// been displayed (in which case dirty is false), or to manually
|
||||
// force a cell to be marked dirty.
|
||||
func (cb *CellBuffer) SetDirty(x, y int, dirty bool) {
|
||||
if x >= 0 && y >= 0 && x < cb.w && y < cb.h {
|
||||
c := &cb.cells[(y*cb.w)+x]
|
||||
if dirty {
|
||||
c.lastMain = rune(0)
|
||||
} else {
|
||||
if c.currMain == rune(0) {
|
||||
c.currMain = ' '
|
||||
}
|
||||
c.lastMain = c.currMain
|
||||
c.lastComb = c.currComb
|
||||
c.lastStyle = c.currStyle
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Resize is used to resize the cells array, with different dimensions,
|
||||
// while preserving the original contents. The cells will be invalidated
|
||||
// so that they can be redrawn.
|
||||
func (cb *CellBuffer) Resize(w, h int) {
|
||||
|
||||
if cb.h == h && cb.w == w {
|
||||
return
|
||||
}
|
||||
|
||||
newc := make([]cell, w*h)
|
||||
for y := 0; y < h && y < cb.h; y++ {
|
||||
for x := 0; x < w && x < cb.w; x++ {
|
||||
oc := &cb.cells[(y*cb.w)+x]
|
||||
nc := &newc[(y*w)+x]
|
||||
nc.currMain = oc.currMain
|
||||
nc.currComb = oc.currComb
|
||||
nc.currStyle = oc.currStyle
|
||||
nc.width = oc.width
|
||||
nc.lastMain = rune(0)
|
||||
}
|
||||
}
|
||||
cb.cells = newc
|
||||
cb.h = h
|
||||
cb.w = w
|
||||
}
|
||||
|
||||
// Fill fills the entire cell buffer array with the specified character
|
||||
// and style. Normally choose ' ' to clear the screen. This API doesn't
|
||||
// support combining characters, or characters with a width larger than one.
|
||||
func (cb *CellBuffer) Fill(r rune, style Style) {
|
||||
for i := range cb.cells {
|
||||
c := &cb.cells[i]
|
||||
c.currMain = r
|
||||
c.currComb = nil
|
||||
c.currStyle = style
|
||||
c.width = 1
|
||||
}
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
// +build plan9 nacl
|
||||
|
||||
// Copyright 2015 The TCell Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use file except in compliance with the License.
|
||||
// You may obtain a copy of the license at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package tcell
|
||||
|
||||
func getCharset() string {
|
||||
return ""
|
||||
}
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
// +build !windows,!nacl,!plan9
|
||||
|
||||
// Copyright 2016 The TCell Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use file except in compliance with the License.
|
||||
// You may obtain a copy of the license at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package tcell
|
||||
|
||||
import (
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func getCharset() string {
|
||||
// Determine the character set. This can help us later.
|
||||
// Per POSIX, we search for LC_ALL first, then LC_CTYPE, and
|
||||
// finally LANG. First one set wins.
|
||||
locale := ""
|
||||
if locale = os.Getenv("LC_ALL"); locale == "" {
|
||||
if locale = os.Getenv("LC_CTYPE"); locale == "" {
|
||||
locale = os.Getenv("LANG")
|
||||
}
|
||||
}
|
||||
if locale == "POSIX" || locale == "C" {
|
||||
return "US-ASCII"
|
||||
}
|
||||
if i := strings.IndexRune(locale, '@'); i >= 0 {
|
||||
locale = locale[:i]
|
||||
}
|
||||
if i := strings.IndexRune(locale, '.'); i >= 0 {
|
||||
locale = locale[i+1:]
|
||||
} else {
|
||||
// Default assumption, and on Linux we can see LC_ALL
|
||||
// without a character set, which we assume implies UTF-8.
|
||||
return "UTF-8"
|
||||
}
|
||||
// XXX: add support for aliases
|
||||
return locale
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
// +build windows
|
||||
|
||||
// Copyright 2015 The TCell Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use file except in compliance with the License.
|
||||
// You may obtain a copy of the license at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package tcell
|
||||
|
||||
func getCharset() string {
|
||||
return "UTF-16"
|
||||
}
|
||||
+1019
File diff suppressed because it is too large
Load Diff
+52
@@ -0,0 +1,52 @@
|
||||
// Copyright 2016 The TCell Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use file except in compliance with the License.
|
||||
// You may obtain a copy of the license at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package tcell
|
||||
|
||||
import (
|
||||
"github.com/lucasb-eyer/go-colorful"
|
||||
"math"
|
||||
)
|
||||
|
||||
// FindColor attempts to find a given color, or the best match possible for it,
|
||||
// from the palette given. This is an expensive operation, so results should
|
||||
// be cached by the caller.
|
||||
func FindColor(c Color, palette []Color) Color {
|
||||
match := ColorDefault
|
||||
dist := float64(0)
|
||||
r, g, b := c.RGB()
|
||||
c1 := colorful.Color{
|
||||
R: float64(r) / 255.0,
|
||||
G: float64(g) / 255.0,
|
||||
B: float64(b) / 255.0,
|
||||
}
|
||||
for _, d := range palette {
|
||||
r, g, b = d.RGB()
|
||||
c2 := colorful.Color{
|
||||
R: float64(r) / 255.0,
|
||||
G: float64(g) / 255.0,
|
||||
B: float64(b) / 255.0,
|
||||
}
|
||||
// CIE94 is more accurate, but really really expensive.
|
||||
nd := c1.DistanceCIE76(c2)
|
||||
if math.IsNaN(nd) {
|
||||
nd = math.Inf(1)
|
||||
}
|
||||
if match == ColorDefault || nd < dist {
|
||||
match = d
|
||||
dist = nd
|
||||
}
|
||||
}
|
||||
return match
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
// +build !windows
|
||||
|
||||
// Copyright 2015 The TCell Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use file except in compliance with the License.
|
||||
// You may obtain a copy of the license at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package tcell
|
||||
|
||||
// NewConsoleScreen returns a console based screen. This platform
|
||||
// doesn't have support for any, so it returns nil and a suitable error.
|
||||
func NewConsoleScreen() (Screen, error) {
|
||||
return nil, ErrNoScreen
|
||||
}
|
||||
+1033
File diff suppressed because it is too large
Load Diff
+48
@@ -0,0 +1,48 @@
|
||||
// Copyright 2018 The TCell Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use file except in compliance with the License.
|
||||
// You may obtain a copy of the license at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Package tcell provides a lower-level, portable API for building
|
||||
// programs that interact with terminals or consoles. It works with
|
||||
// both common (and many uncommon!) terminals or terminal emulators,
|
||||
// and Windows console implementations.
|
||||
//
|
||||
// It provides support for up to 256 colors, text attributes, and box drawing
|
||||
// elements. A database of terminals built from a real terminfo database
|
||||
// is provided, along with code to generate new database entries.
|
||||
//
|
||||
// Tcell offers very rich support for mice, dependent upon the terminal
|
||||
// of course. (Windows, XTerm, and iTerm 2 are known to work very well.)
|
||||
//
|
||||
// If the environment is not Unicode by default, such as an ISO8859 based
|
||||
// locale or GB18030, Tcell can convert input and output, so that your
|
||||
// terminal can operate in whatever locale is most convenient, while the
|
||||
// application program can just assume "everything is UTF-8". Reasonable
|
||||
// defaults are used for updating characters to something suitable for
|
||||
// display. Unicode box drawing characters will be converted to use the
|
||||
// alternate character set of your terminal, if native conversions are
|
||||
// not available. If no ACS is available, then some ASCII fallbacks will
|
||||
// be used.
|
||||
//
|
||||
// Note that support for non-UTF-8 locales (other than C) must be enabled
|
||||
// by the application using RegisterEncoding() -- we don't have them all
|
||||
// enabled by default to avoid bloating the application unneccessarily.
|
||||
// (These days UTF-8 is good enough for almost everyone, and nobody should
|
||||
// be using legacy locales anymore.) Also, actual glyphs for various code
|
||||
// point will only be displayed if your terminal or emulator (or the font
|
||||
// the emulator is using) supports them.
|
||||
//
|
||||
// A rich set of keycodes is supported, with support for up to 65 function
|
||||
// keys, and various other special keys.
|
||||
//
|
||||
package tcell
|
||||
+139
@@ -0,0 +1,139 @@
|
||||
// Copyright 2015 The TCell Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use file except in compliance with the License.
|
||||
// You may obtain a copy of the license at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package tcell
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"golang.org/x/text/encoding"
|
||||
|
||||
gencoding "github.com/gdamore/encoding"
|
||||
)
|
||||
|
||||
var encodings map[string]encoding.Encoding
|
||||
var encodingLk sync.Mutex
|
||||
var encodingFallback EncodingFallback = EncodingFallbackFail
|
||||
|
||||
// RegisterEncoding may be called by the application to register an encoding.
|
||||
// The presence of additional encodings will facilitate application usage with
|
||||
// terminal environments where the I/O subsystem does not support Unicode.
|
||||
//
|
||||
// Windows systems use Unicode natively, and do not need any of the encoding
|
||||
// subsystem when using Windows Console screens.
|
||||
//
|
||||
// Please see the Go documentation for golang.org/x/text/encoding -- most of
|
||||
// the common ones exist already as stock variables. For example, ISO8859-15
|
||||
// can be registered using the following code:
|
||||
//
|
||||
// import "golang.org/x/text/encoding/charmap"
|
||||
//
|
||||
// ...
|
||||
// RegisterEncoding("ISO8859-15", charmap.ISO8859_15)
|
||||
//
|
||||
// Aliases can be registered as well, for example "8859-15" could be an alias
|
||||
// for "ISO8859-15".
|
||||
//
|
||||
// For POSIX systems, the tcell package will check the environment variables
|
||||
// LC_ALL, LC_CTYPE, and LANG (in that order) to determine the character set.
|
||||
// These are expected to have the following pattern:
|
||||
//
|
||||
// $language[.$codeset[@$variant]
|
||||
//
|
||||
// We extract only the $codeset part, which will usually be something like
|
||||
// UTF-8 or ISO8859-15 or KOI8-R. Note that if the locale is either "POSIX"
|
||||
// or "C", then we assume US-ASCII (the POSIX 'portable character set'
|
||||
// and assume all other characters are somehow invalid.)
|
||||
//
|
||||
// Modern POSIX systems and terminal emulators may use UTF-8, and for those
|
||||
// systems, this API is also unnecessary. For example, Darwin (MacOS X) and
|
||||
// modern Linux running modern xterm generally will out of the box without
|
||||
// any of this. Use of UTF-8 is recommended when possible, as it saves
|
||||
// quite a lot processing overhead.
|
||||
//
|
||||
// Note that some encodings are quite large (for example GB18030 which is a
|
||||
// superset of Unicode) and so the application size can be expected ot
|
||||
// increase quite a bit as each encoding is added. The East Asian encodings
|
||||
// have been seen to add 100-200K per encoding to the application size.
|
||||
//
|
||||
func RegisterEncoding(charset string, enc encoding.Encoding) {
|
||||
encodingLk.Lock()
|
||||
charset = strings.ToLower(charset)
|
||||
encodings[charset] = enc
|
||||
encodingLk.Unlock()
|
||||
}
|
||||
|
||||
// EncodingFallback describes how the system behavees when the locale
|
||||
// requires a character set that we do not support. The system always
|
||||
// supports UTF-8 and US-ASCII. On Windows consoles, UTF-16LE is also
|
||||
// supported automatically. Other character sets must be added using the
|
||||
// RegisterEncoding API. (A large group of nearly all of them can be
|
||||
// added using the RegisterAll function in the encoding sub package.)
|
||||
type EncodingFallback int
|
||||
|
||||
const (
|
||||
// EncodingFallbackFail behavior causes GetEncoding to fail
|
||||
// when it cannot find an encoding.
|
||||
EncodingFallbackFail = iota
|
||||
|
||||
// EncodingFallbackASCII behaviore causes GetEncoding to fall back
|
||||
// to a 7-bit ASCII encoding, if no other encoding can be found.
|
||||
EncodingFallbackASCII
|
||||
|
||||
// EncodingFallbackUTF8 behavior causes GetEncoding to assume
|
||||
// UTF8 can pass unmodified upon failure. Note that this behavior
|
||||
// is not recommended, unless you are sure your terminal can cope
|
||||
// with real UTF8 sequences.
|
||||
EncodingFallbackUTF8
|
||||
)
|
||||
|
||||
// SetEncodingFallback changes the behavior of GetEncoding when a suitable
|
||||
// encoding is not found. The default is EncodingFallbackFail, which
|
||||
// causes GetEncoding to simply return nil.
|
||||
func SetEncodingFallback(fb EncodingFallback) {
|
||||
encodingLk.Lock()
|
||||
encodingFallback = fb
|
||||
encodingLk.Unlock()
|
||||
}
|
||||
|
||||
// GetEncoding is used by Screen implementors who want to locate an encoding
|
||||
// for the given character set name. Note that this will return nil for
|
||||
// either the Unicode (UTF-8) or ASCII encodings, since we don't use
|
||||
// encodings for them but instead have our own native methods.
|
||||
func GetEncoding(charset string) encoding.Encoding {
|
||||
charset = strings.ToLower(charset)
|
||||
encodingLk.Lock()
|
||||
defer encodingLk.Unlock()
|
||||
if enc, ok := encodings[charset]; ok {
|
||||
return enc
|
||||
}
|
||||
switch encodingFallback {
|
||||
case EncodingFallbackASCII:
|
||||
return gencoding.ASCII
|
||||
case EncodingFallbackUTF8:
|
||||
return encoding.Nop
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
// We always support UTF-8 and ASCII.
|
||||
encodings = make(map[string]encoding.Encoding)
|
||||
encodings["utf-8"] = gencoding.UTF8
|
||||
encodings["utf8"] = gencoding.UTF8
|
||||
encodings["us-ascii"] = gencoding.ASCII
|
||||
encodings["ascii"] = gencoding.ASCII
|
||||
encodings["iso646"] = gencoding.ASCII
|
||||
}
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
// Copyright 2015 The TCell Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use file except in compliance with the License.
|
||||
// You may obtain a copy of the license at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package tcell
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
"github.com/gdamore/tcell/terminfo"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrTermNotFound indicates that a suitable terminal entry could
|
||||
// not be found. This can result from either not having TERM set,
|
||||
// or from the TERM failing to support certain minimal functionality,
|
||||
// in particular absolute cursor addressability (the cup capability)
|
||||
// is required. For example, legacy "adm3" lacks this capability,
|
||||
// whereas the slightly newer "adm3a" supports it. This failure
|
||||
// occurs most often with "dumb".
|
||||
ErrTermNotFound = terminfo.ErrTermNotFound
|
||||
|
||||
// ErrNoScreen indicates that no suitable screen could be found.
|
||||
// This may result from attempting to run on a platform where there
|
||||
// is no support for either termios or console I/O (such as nacl),
|
||||
// or from running in an environment where there is no access to
|
||||
// a suitable console/terminal device. (For example, running on
|
||||
// without a controlling TTY or with no /dev/tty on POSIX platforms.)
|
||||
ErrNoScreen = errors.New("no suitable screen available")
|
||||
|
||||
// ErrNoCharset indicates that the locale environment the
|
||||
// program is not supported by the program, because no suitable
|
||||
// encoding was found for it. This problem never occurs if
|
||||
// the environment is UTF-8 or UTF-16.
|
||||
ErrNoCharset = errors.New("character set not supported")
|
||||
|
||||
// ErrEventQFull indicates that the event queue is full, and
|
||||
// cannot accept more events.
|
||||
ErrEventQFull = errors.New("event queue full")
|
||||
)
|
||||
|
||||
// An EventError is an event representing some sort of error, and carries
|
||||
// an error payload.
|
||||
type EventError struct {
|
||||
t time.Time
|
||||
err error
|
||||
}
|
||||
|
||||
// When returns the time when the event was created.
|
||||
func (ev *EventError) When() time.Time {
|
||||
return ev.t
|
||||
}
|
||||
|
||||
// Error implements the error.
|
||||
func (ev *EventError) Error() string {
|
||||
return ev.err.Error()
|
||||
}
|
||||
|
||||
// NewEventError creates an ErrorEvent with the given error payload.
|
||||
func NewEventError(err error) *EventError {
|
||||
return &EventError{t: time.Now(), err: err}
|
||||
}
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
// Copyright 2015 The TCell Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use file except in compliance with the License.
|
||||
// You may obtain a copy of the license at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package tcell
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// Event is a generic interface used for passing around Events.
|
||||
// Concrete types follow.
|
||||
type Event interface {
|
||||
// When reports the time when the event was generated.
|
||||
When() time.Time
|
||||
}
|
||||
|
||||
// EventTime is a simple base event class, suitable for easy reuse.
|
||||
// It can be used to deliver actual timer events as well.
|
||||
type EventTime struct {
|
||||
when time.Time
|
||||
}
|
||||
|
||||
// When returns the time stamp when the event occurred.
|
||||
func (e *EventTime) When() time.Time {
|
||||
return e.when
|
||||
}
|
||||
|
||||
// SetEventTime sets the time of occurrence for the event.
|
||||
func (e *EventTime) SetEventTime(t time.Time) {
|
||||
e.when = t
|
||||
}
|
||||
|
||||
// SetEventNow sets the time of occurrence for the event to the current time.
|
||||
func (e *EventTime) SetEventNow() {
|
||||
e.SetEventTime(time.Now())
|
||||
}
|
||||
|
||||
// EventHandler is anything that handles events. If the handler has
|
||||
// consumed the event, it should return true. False otherwise.
|
||||
type EventHandler interface {
|
||||
HandleEvent(Event) bool
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
module github.com/gdamore/tcell
|
||||
|
||||
go 1.12
|
||||
|
||||
require (
|
||||
github.com/gdamore/encoding v1.0.0
|
||||
github.com/lucasb-eyer/go-colorful v1.0.2
|
||||
github.com/mattn/go-runewidth v0.0.4
|
||||
golang.org/x/sys v0.0.0-20190626150813-e07cf5db2756
|
||||
golang.org/x/text v0.3.0
|
||||
)
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
github.com/DATA-DOG/go-sqlmock v1.3.3 h1:CWUqKXe0s8A2z6qCgkP4Kru7wC11YoAnoupUKFDnH08=
|
||||
github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
|
||||
github.com/gdamore/encoding v1.0.0 h1:+7OoQ1Bc6eTm5niUzBa0Ctsh6JbMW6Ra+YNuAtDBdko=
|
||||
github.com/gdamore/encoding v1.0.0/go.mod h1:alR0ol34c49FCSBLjhosxzcPHQbf2trDkoo5dl+VrEg=
|
||||
github.com/lucasb-eyer/go-colorful v1.0.2 h1:mCMFu6PgSozg9tDNMMK3g18oJBX7oYGrC09mS6CXfO4=
|
||||
github.com/lucasb-eyer/go-colorful v1.0.2/go.mod h1:0MS4r+7BZKSJ5mw4/S5MPN+qHFF1fYclkSPilDOKW0s=
|
||||
github.com/mattn/go-runewidth v0.0.4 h1:2BvfKmzob6Bmd4YsL0zygOqfdFnK7GR4QL06Do4/p7Y=
|
||||
github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||
golang.org/x/sys v0.0.0-20190626150813-e07cf5db2756 h1:9nuHUbU8dRnRRfj9KjWUVrJeoexdbeMjttk6Oh1rD10=
|
||||
golang.org/x/sys v0.0.0-20190626150813-e07cf5db2756/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
// Copyright 2015 The TCell Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use file except in compliance with the License.
|
||||
// You may obtain a copy of the license at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package tcell
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// EventInterrupt is a generic wakeup event. Its can be used to
|
||||
// to request a redraw. It can carry an arbitrary payload, as well.
|
||||
type EventInterrupt struct {
|
||||
t time.Time
|
||||
v interface{}
|
||||
}
|
||||
|
||||
// When returns the time when this event was created.
|
||||
func (ev *EventInterrupt) When() time.Time {
|
||||
return ev.t
|
||||
}
|
||||
|
||||
// Data is used to obtain the opaque event payload.
|
||||
func (ev *EventInterrupt) Data() interface{} {
|
||||
return ev.v
|
||||
}
|
||||
|
||||
// NewEventInterrupt creates an EventInterrupt with the given payload.
|
||||
func NewEventInterrupt(data interface{}) *EventInterrupt {
|
||||
return &EventInterrupt{t: time.Now(), v: data}
|
||||
}
|
||||
+464
@@ -0,0 +1,464 @@
|
||||
// Copyright 2016 The TCell Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use file except in compliance with the License.
|
||||
// You may obtain a copy of the license at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package tcell
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// EventKey represents a key press. Usually this is a key press followed
|
||||
// by a key release, but since terminal programs don't have a way to report
|
||||
// key release events, we usually get just one event. If a key is held down
|
||||
// then the terminal may synthesize repeated key presses at some predefined
|
||||
// rate. We have no control over that, nor visibility into it.
|
||||
//
|
||||
// In some cases, we can have a modifier key, such as ModAlt, that can be
|
||||
// generated with a key press. (This usually is represented by having the
|
||||
// high bit set, or in some cases, by sending an ESC prior to the rune.)
|
||||
//
|
||||
// If the value of Key() is KeyRune, then the actual key value will be
|
||||
// available with the Rune() method. This will be the case for most keys.
|
||||
// In most situations, the modifiers will not be set. For example, if the
|
||||
// rune is 'A', this will be reported without the ModShift bit set, since
|
||||
// really can't tell if the Shift key was pressed (it might have been CAPSLOCK,
|
||||
// or a terminal that only can send capitals, or keyboard with separate
|
||||
// capital letters from lower case letters).
|
||||
//
|
||||
// Generally, terminal applications have far less visibility into keyboard
|
||||
// activity than graphical applications. Hence, they should avoid depending
|
||||
// overly much on availability of modifiers, or the availability of any
|
||||
// specific keys.
|
||||
type EventKey struct {
|
||||
t time.Time
|
||||
mod ModMask
|
||||
key Key
|
||||
ch rune
|
||||
}
|
||||
|
||||
// When returns the time when this Event was created, which should closely
|
||||
// match the time when the key was pressed.
|
||||
func (ev *EventKey) When() time.Time {
|
||||
return ev.t
|
||||
}
|
||||
|
||||
// Rune returns the rune corresponding to the key press, if it makes sense.
|
||||
// The result is only defined if the value of Key() is KeyRune.
|
||||
func (ev *EventKey) Rune() rune {
|
||||
return ev.ch
|
||||
}
|
||||
|
||||
// Key returns a virtual key code. We use this to identify specific key
|
||||
// codes, such as KeyEnter, etc. Most control and function keys are reported
|
||||
// with unique Key values. Normal alphanumeric and punctuation keys will
|
||||
// generally return KeyRune here; the specific key can be further decoded
|
||||
// using the Rune() function.
|
||||
func (ev *EventKey) Key() Key {
|
||||
return ev.key
|
||||
}
|
||||
|
||||
// Modifiers returns the modifiers that were present with the key press. Note
|
||||
// that not all platforms and terminals support this equally well, and some
|
||||
// cases we will not not know for sure. Hence, applications should avoid
|
||||
// using this in most circumstances.
|
||||
func (ev *EventKey) Modifiers() ModMask {
|
||||
return ev.mod
|
||||
}
|
||||
|
||||
// KeyNames holds the written names of special keys. Useful to echo back a key
|
||||
// name, or to look up a key from a string value.
|
||||
var KeyNames = map[Key]string{
|
||||
KeyEnter: "Enter",
|
||||
KeyBackspace: "Backspace",
|
||||
KeyTab: "Tab",
|
||||
KeyBacktab: "Backtab",
|
||||
KeyEsc: "Esc",
|
||||
KeyBackspace2: "Backspace2",
|
||||
KeyDelete: "Delete",
|
||||
KeyInsert: "Insert",
|
||||
KeyUp: "Up",
|
||||
KeyDown: "Down",
|
||||
KeyLeft: "Left",
|
||||
KeyRight: "Right",
|
||||
KeyHome: "Home",
|
||||
KeyEnd: "End",
|
||||
KeyUpLeft: "UpLeft",
|
||||
KeyUpRight: "UpRight",
|
||||
KeyDownLeft: "DownLeft",
|
||||
KeyDownRight: "DownRight",
|
||||
KeyCenter: "Center",
|
||||
KeyPgDn: "PgDn",
|
||||
KeyPgUp: "PgUp",
|
||||
KeyClear: "Clear",
|
||||
KeyExit: "Exit",
|
||||
KeyCancel: "Cancel",
|
||||
KeyPause: "Pause",
|
||||
KeyPrint: "Print",
|
||||
KeyF1: "F1",
|
||||
KeyF2: "F2",
|
||||
KeyF3: "F3",
|
||||
KeyF4: "F4",
|
||||
KeyF5: "F5",
|
||||
KeyF6: "F6",
|
||||
KeyF7: "F7",
|
||||
KeyF8: "F8",
|
||||
KeyF9: "F9",
|
||||
KeyF10: "F10",
|
||||
KeyF11: "F11",
|
||||
KeyF12: "F12",
|
||||
KeyF13: "F13",
|
||||
KeyF14: "F14",
|
||||
KeyF15: "F15",
|
||||
KeyF16: "F16",
|
||||
KeyF17: "F17",
|
||||
KeyF18: "F18",
|
||||
KeyF19: "F19",
|
||||
KeyF20: "F20",
|
||||
KeyF21: "F21",
|
||||
KeyF22: "F22",
|
||||
KeyF23: "F23",
|
||||
KeyF24: "F24",
|
||||
KeyF25: "F25",
|
||||
KeyF26: "F26",
|
||||
KeyF27: "F27",
|
||||
KeyF28: "F28",
|
||||
KeyF29: "F29",
|
||||
KeyF30: "F30",
|
||||
KeyF31: "F31",
|
||||
KeyF32: "F32",
|
||||
KeyF33: "F33",
|
||||
KeyF34: "F34",
|
||||
KeyF35: "F35",
|
||||
KeyF36: "F36",
|
||||
KeyF37: "F37",
|
||||
KeyF38: "F38",
|
||||
KeyF39: "F39",
|
||||
KeyF40: "F40",
|
||||
KeyF41: "F41",
|
||||
KeyF42: "F42",
|
||||
KeyF43: "F43",
|
||||
KeyF44: "F44",
|
||||
KeyF45: "F45",
|
||||
KeyF46: "F46",
|
||||
KeyF47: "F47",
|
||||
KeyF48: "F48",
|
||||
KeyF49: "F49",
|
||||
KeyF50: "F50",
|
||||
KeyF51: "F51",
|
||||
KeyF52: "F52",
|
||||
KeyF53: "F53",
|
||||
KeyF54: "F54",
|
||||
KeyF55: "F55",
|
||||
KeyF56: "F56",
|
||||
KeyF57: "F57",
|
||||
KeyF58: "F58",
|
||||
KeyF59: "F59",
|
||||
KeyF60: "F60",
|
||||
KeyF61: "F61",
|
||||
KeyF62: "F62",
|
||||
KeyF63: "F63",
|
||||
KeyF64: "F64",
|
||||
KeyCtrlA: "Ctrl-A",
|
||||
KeyCtrlB: "Ctrl-B",
|
||||
KeyCtrlC: "Ctrl-C",
|
||||
KeyCtrlD: "Ctrl-D",
|
||||
KeyCtrlE: "Ctrl-E",
|
||||
KeyCtrlF: "Ctrl-F",
|
||||
KeyCtrlG: "Ctrl-G",
|
||||
KeyCtrlJ: "Ctrl-J",
|
||||
KeyCtrlK: "Ctrl-K",
|
||||
KeyCtrlL: "Ctrl-L",
|
||||
KeyCtrlN: "Ctrl-N",
|
||||
KeyCtrlO: "Ctrl-O",
|
||||
KeyCtrlP: "Ctrl-P",
|
||||
KeyCtrlQ: "Ctrl-Q",
|
||||
KeyCtrlR: "Ctrl-R",
|
||||
KeyCtrlS: "Ctrl-S",
|
||||
KeyCtrlT: "Ctrl-T",
|
||||
KeyCtrlU: "Ctrl-U",
|
||||
KeyCtrlV: "Ctrl-V",
|
||||
KeyCtrlW: "Ctrl-W",
|
||||
KeyCtrlX: "Ctrl-X",
|
||||
KeyCtrlY: "Ctrl-Y",
|
||||
KeyCtrlZ: "Ctrl-Z",
|
||||
KeyCtrlSpace: "Ctrl-Space",
|
||||
KeyCtrlUnderscore: "Ctrl-_",
|
||||
KeyCtrlRightSq: "Ctrl-]",
|
||||
KeyCtrlBackslash: "Ctrl-\\",
|
||||
KeyCtrlCarat: "Ctrl-^",
|
||||
}
|
||||
|
||||
// Name returns a printable value or the key stroke. This can be used
|
||||
// when printing the event, for example.
|
||||
func (ev *EventKey) Name() string {
|
||||
s := ""
|
||||
m := []string{}
|
||||
if ev.mod&ModShift != 0 {
|
||||
m = append(m, "Shift")
|
||||
}
|
||||
if ev.mod&ModAlt != 0 {
|
||||
m = append(m, "Alt")
|
||||
}
|
||||
if ev.mod&ModMeta != 0 {
|
||||
m = append(m, "Meta")
|
||||
}
|
||||
if ev.mod&ModCtrl != 0 {
|
||||
m = append(m, "Ctrl")
|
||||
}
|
||||
|
||||
ok := false
|
||||
if s, ok = KeyNames[ev.key]; !ok {
|
||||
if ev.key == KeyRune {
|
||||
s = "Rune[" + string(ev.ch) + "]"
|
||||
} else {
|
||||
s = fmt.Sprintf("Key[%d,%d]", ev.key, int(ev.ch))
|
||||
}
|
||||
}
|
||||
if len(m) != 0 {
|
||||
if ev.mod&ModCtrl != 0 && strings.HasPrefix(s, "Ctrl-") {
|
||||
s = s[5:]
|
||||
}
|
||||
return fmt.Sprintf("%s+%s", strings.Join(m, "+"), s)
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// NewEventKey attempts to create a suitable event. It parses the various
|
||||
// ASCII control sequences if KeyRune is passed for Key, but if the caller
|
||||
// has more precise information it should set that specifically. Callers
|
||||
// that aren't sure about modifier state (most) should just pass ModNone.
|
||||
func NewEventKey(k Key, ch rune, mod ModMask) *EventKey {
|
||||
if k == KeyRune && (ch < ' ' || ch == 0x7f) {
|
||||
// Turn specials into proper key codes. This is for
|
||||
// control characters and the DEL.
|
||||
k = Key(ch)
|
||||
if mod == ModNone && ch < ' ' {
|
||||
switch Key(ch) {
|
||||
case KeyBackspace, KeyTab, KeyEsc, KeyEnter:
|
||||
// these keys are directly typeable without CTRL
|
||||
default:
|
||||
// most likely entered with a CTRL keypress
|
||||
mod = ModCtrl
|
||||
}
|
||||
}
|
||||
}
|
||||
return &EventKey{t: time.Now(), key: k, ch: ch, mod: mod}
|
||||
}
|
||||
|
||||
// ModMask is a mask of modifier keys. Note that it will not always be
|
||||
// possible to report modifier keys.
|
||||
type ModMask int16
|
||||
|
||||
// These are the modifiers keys that can be sent either with a key press,
|
||||
// or a mouse event. Note that as of now, due to the confusion associated
|
||||
// with Meta, and the lack of support for it on many/most platforms, the
|
||||
// current implementations never use it. Instead, they use ModAlt, even for
|
||||
// events that could possibly have been distinguished from ModAlt.
|
||||
const (
|
||||
ModShift ModMask = 1 << iota
|
||||
ModCtrl
|
||||
ModAlt
|
||||
ModMeta
|
||||
ModNone ModMask = 0
|
||||
)
|
||||
|
||||
// Key is a generic value for representing keys, and especially special
|
||||
// keys (function keys, cursor movement keys, etc.) For normal keys, like
|
||||
// ASCII letters, we use KeyRune, and then expect the application to
|
||||
// inspect the Rune() member of the EventKey.
|
||||
type Key int16
|
||||
|
||||
// This is the list of named keys. KeyRune is special however, in that it is
|
||||
// a place holder key indicating that a printable character was sent. The
|
||||
// actual value of the rune will be transported in the Rune of the associated
|
||||
// EventKey.
|
||||
const (
|
||||
KeyRune Key = iota + 256
|
||||
KeyUp
|
||||
KeyDown
|
||||
KeyRight
|
||||
KeyLeft
|
||||
KeyUpLeft
|
||||
KeyUpRight
|
||||
KeyDownLeft
|
||||
KeyDownRight
|
||||
KeyCenter
|
||||
KeyPgUp
|
||||
KeyPgDn
|
||||
KeyHome
|
||||
KeyEnd
|
||||
KeyInsert
|
||||
KeyDelete
|
||||
KeyHelp
|
||||
KeyExit
|
||||
KeyClear
|
||||
KeyCancel
|
||||
KeyPrint
|
||||
KeyPause
|
||||
KeyBacktab
|
||||
KeyF1
|
||||
KeyF2
|
||||
KeyF3
|
||||
KeyF4
|
||||
KeyF5
|
||||
KeyF6
|
||||
KeyF7
|
||||
KeyF8
|
||||
KeyF9
|
||||
KeyF10
|
||||
KeyF11
|
||||
KeyF12
|
||||
KeyF13
|
||||
KeyF14
|
||||
KeyF15
|
||||
KeyF16
|
||||
KeyF17
|
||||
KeyF18
|
||||
KeyF19
|
||||
KeyF20
|
||||
KeyF21
|
||||
KeyF22
|
||||
KeyF23
|
||||
KeyF24
|
||||
KeyF25
|
||||
KeyF26
|
||||
KeyF27
|
||||
KeyF28
|
||||
KeyF29
|
||||
KeyF30
|
||||
KeyF31
|
||||
KeyF32
|
||||
KeyF33
|
||||
KeyF34
|
||||
KeyF35
|
||||
KeyF36
|
||||
KeyF37
|
||||
KeyF38
|
||||
KeyF39
|
||||
KeyF40
|
||||
KeyF41
|
||||
KeyF42
|
||||
KeyF43
|
||||
KeyF44
|
||||
KeyF45
|
||||
KeyF46
|
||||
KeyF47
|
||||
KeyF48
|
||||
KeyF49
|
||||
KeyF50
|
||||
KeyF51
|
||||
KeyF52
|
||||
KeyF53
|
||||
KeyF54
|
||||
KeyF55
|
||||
KeyF56
|
||||
KeyF57
|
||||
KeyF58
|
||||
KeyF59
|
||||
KeyF60
|
||||
KeyF61
|
||||
KeyF62
|
||||
KeyF63
|
||||
KeyF64
|
||||
)
|
||||
|
||||
// These are the control keys. Note that they overlap with other keys,
|
||||
// perhaps. For example, KeyCtrlH is the same as KeyBackspace.
|
||||
const (
|
||||
KeyCtrlSpace Key = iota
|
||||
KeyCtrlA
|
||||
KeyCtrlB
|
||||
KeyCtrlC
|
||||
KeyCtrlD
|
||||
KeyCtrlE
|
||||
KeyCtrlF
|
||||
KeyCtrlG
|
||||
KeyCtrlH
|
||||
KeyCtrlI
|
||||
KeyCtrlJ
|
||||
KeyCtrlK
|
||||
KeyCtrlL
|
||||
KeyCtrlM
|
||||
KeyCtrlN
|
||||
KeyCtrlO
|
||||
KeyCtrlP
|
||||
KeyCtrlQ
|
||||
KeyCtrlR
|
||||
KeyCtrlS
|
||||
KeyCtrlT
|
||||
KeyCtrlU
|
||||
KeyCtrlV
|
||||
KeyCtrlW
|
||||
KeyCtrlX
|
||||
KeyCtrlY
|
||||
KeyCtrlZ
|
||||
KeyCtrlLeftSq // Escape
|
||||
KeyCtrlBackslash
|
||||
KeyCtrlRightSq
|
||||
KeyCtrlCarat
|
||||
KeyCtrlUnderscore
|
||||
)
|
||||
|
||||
// Special values - these are fixed in an attempt to make it more likely
|
||||
// that aliases will encode the same way.
|
||||
|
||||
// These are the defined ASCII values for key codes. They generally match
|
||||
// with KeyCtrl values.
|
||||
const (
|
||||
KeyNUL Key = iota
|
||||
KeySOH
|
||||
KeySTX
|
||||
KeyETX
|
||||
KeyEOT
|
||||
KeyENQ
|
||||
KeyACK
|
||||
KeyBEL
|
||||
KeyBS
|
||||
KeyTAB
|
||||
KeyLF
|
||||
KeyVT
|
||||
KeyFF
|
||||
KeyCR
|
||||
KeySO
|
||||
KeySI
|
||||
KeyDLE
|
||||
KeyDC1
|
||||
KeyDC2
|
||||
KeyDC3
|
||||
KeyDC4
|
||||
KeyNAK
|
||||
KeySYN
|
||||
KeyETB
|
||||
KeyCAN
|
||||
KeyEM
|
||||
KeySUB
|
||||
KeyESC
|
||||
KeyFS
|
||||
KeyGS
|
||||
KeyRS
|
||||
KeyUS
|
||||
KeyDEL Key = 0x7F
|
||||
)
|
||||
|
||||
// These keys are aliases for other names.
|
||||
const (
|
||||
KeyBackspace = KeyBS
|
||||
KeyTab = KeyTAB
|
||||
KeyEsc = KeyESC
|
||||
KeyEscape = KeyESC
|
||||
KeyEnter = KeyCR
|
||||
KeyBackspace2 = KeyDEL
|
||||
)
|
||||
+97
@@ -0,0 +1,97 @@
|
||||
// Copyright 2015 The TCell Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use file except in compliance with the License.
|
||||
// You may obtain a copy of the license at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package tcell
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// EventMouse is a mouse event. It is sent on either mouse up or mouse down
|
||||
// events. It is also sent on mouse motion events - if the terminal supports
|
||||
// it. We make every effort to ensure that mouse release events are delivered.
|
||||
// Hence, click drag can be identified by a motion event with the mouse down,
|
||||
// without any intervening button release. On some terminals only the initiating
|
||||
// press and terminating release event will be delivered.
|
||||
//
|
||||
// Mouse wheel events, when reported, may appear on their own as individual
|
||||
// impulses; that is, there will normally not be a release event delivered
|
||||
// for mouse wheel movements.
|
||||
//
|
||||
// Most terminals cannot report the state of more than one button at a time --
|
||||
// and some cannot report motion events unless a button is pressed.
|
||||
//
|
||||
// Applications can inspect the time between events to resolve double or
|
||||
// triple clicks.
|
||||
type EventMouse struct {
|
||||
t time.Time
|
||||
btn ButtonMask
|
||||
mod ModMask
|
||||
x int
|
||||
y int
|
||||
}
|
||||
|
||||
// When returns the time when this EventMouse was created.
|
||||
func (ev *EventMouse) When() time.Time {
|
||||
return ev.t
|
||||
}
|
||||
|
||||
// Buttons returns the list of buttons that were pressed or wheel motions.
|
||||
func (ev *EventMouse) Buttons() ButtonMask {
|
||||
return ev.btn
|
||||
}
|
||||
|
||||
// Modifiers returns a list of keyboard modifiers that were pressed
|
||||
// with the mouse button(s).
|
||||
func (ev *EventMouse) Modifiers() ModMask {
|
||||
return ev.mod
|
||||
}
|
||||
|
||||
// Position returns the mouse position in character cells. The origin
|
||||
// 0, 0 is at the upper left corner.
|
||||
func (ev *EventMouse) Position() (int, int) {
|
||||
return ev.x, ev.y
|
||||
}
|
||||
|
||||
// NewEventMouse is used to create a new mouse event. Applications
|
||||
// shouldn't need to use this; its mostly for screen implementors.
|
||||
func NewEventMouse(x, y int, btn ButtonMask, mod ModMask) *EventMouse {
|
||||
return &EventMouse{t: time.Now(), x: x, y: y, btn: btn, mod: mod}
|
||||
}
|
||||
|
||||
// ButtonMask is a mask of mouse buttons and wheel events. Mouse button presses
|
||||
// are normally delivered as both press and release events. Mouse wheel events
|
||||
// are normally just single impulse events. Windows supports up to eight
|
||||
// separate buttons plus all four wheel directions, but XTerm can only support
|
||||
// mouse buttons 1-3 and wheel up/down. Its not unheard of for terminals
|
||||
// to support only one or two buttons (think Macs). Old terminals, and true
|
||||
// emulations (such as vt100) won't support mice at all, of course.
|
||||
type ButtonMask int16
|
||||
|
||||
// These are the actual button values.
|
||||
const (
|
||||
Button1 ButtonMask = 1 << iota // Usually left mouse button.
|
||||
Button2 // Usually the middle mouse button.
|
||||
Button3 // Usually the right mouse button.
|
||||
Button4 // Often a side button (thumb/next).
|
||||
Button5 // Often a side button (thumb/prev).
|
||||
Button6
|
||||
Button7
|
||||
Button8
|
||||
WheelUp // Wheel motion up/away from user.
|
||||
WheelDown // Wheel motion down/towards user.
|
||||
WheelLeft // Wheel motion to left.
|
||||
WheelRight // Wheel motion to right.
|
||||
ButtonNone ButtonMask = 0 // No button or wheel events.
|
||||
)
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
// Copyright 2015 The TCell Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use file except in compliance with the License.
|
||||
// You may obtain a copy of the license at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package tcell
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// EventResize is sent when the window size changes.
|
||||
type EventResize struct {
|
||||
t time.Time
|
||||
w int
|
||||
h int
|
||||
}
|
||||
|
||||
// NewEventResize creates an EventResize with the new updated window size,
|
||||
// which is given in character cells.
|
||||
func NewEventResize(width, height int) *EventResize {
|
||||
return &EventResize{t: time.Now(), w: width, h: height}
|
||||
}
|
||||
|
||||
// When returns the time when the Event was created.
|
||||
func (ev *EventResize) When() time.Time {
|
||||
return ev.t
|
||||
}
|
||||
|
||||
// Size returns the new window size as width, height in character cells.
|
||||
func (ev *EventResize) Size() (int, int) {
|
||||
return ev.w, ev.h
|
||||
}
|
||||
+111
@@ -0,0 +1,111 @@
|
||||
// Copyright 2015 The TCell Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use file except in compliance with the License.
|
||||
// You may obtain a copy of the license at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package tcell
|
||||
|
||||
// The names of these constants are chosen to match Terminfo names,
|
||||
// modulo case, and changing the prefix from ACS_ to Rune. These are
|
||||
// the runes we provide extra special handling for, with ASCII fallbacks
|
||||
// for terminals that lack them.
|
||||
const (
|
||||
RuneSterling = '£'
|
||||
RuneDArrow = '↓'
|
||||
RuneLArrow = '←'
|
||||
RuneRArrow = '→'
|
||||
RuneUArrow = '↑'
|
||||
RuneBullet = '·'
|
||||
RuneBoard = '░'
|
||||
RuneCkBoard = '▒'
|
||||
RuneDegree = '°'
|
||||
RuneDiamond = '◆'
|
||||
RuneGEqual = '≥'
|
||||
RunePi = 'π'
|
||||
RuneHLine = '─'
|
||||
RuneLantern = '§'
|
||||
RunePlus = '┼'
|
||||
RuneLEqual = '≤'
|
||||
RuneLLCorner = '└'
|
||||
RuneLRCorner = '┘'
|
||||
RuneNEqual = '≠'
|
||||
RunePlMinus = '±'
|
||||
RuneS1 = '⎺'
|
||||
RuneS3 = '⎻'
|
||||
RuneS7 = '⎼'
|
||||
RuneS9 = '⎽'
|
||||
RuneBlock = '█'
|
||||
RuneTTee = '┬'
|
||||
RuneRTee = '┤'
|
||||
RuneLTee = '├'
|
||||
RuneBTee = '┴'
|
||||
RuneULCorner = '┌'
|
||||
RuneURCorner = '┐'
|
||||
RuneVLine = '│'
|
||||
)
|
||||
|
||||
// RuneFallbacks is the default map of fallback strings that will be
|
||||
// used to replace a rune when no other more appropriate transformation
|
||||
// is available, and the rune cannot be displayed directly.
|
||||
//
|
||||
// New entries may be added to this map over time, as it becomes clear
|
||||
// that such is desirable. Characters that represent either letters or
|
||||
// numbers should not be added to this list unless it is certain that
|
||||
// the meaning will still convey unambiguously.
|
||||
//
|
||||
// As an example, it would be appropriate to add an ASCII mapping for
|
||||
// the full width form of the letter 'A', but it would not be appropriate
|
||||
// to do so a glyph representing the country China.
|
||||
//
|
||||
// Programs that desire richer fallbacks may register additional ones,
|
||||
// or change or even remove these mappings with Screen.RegisterRuneFallback
|
||||
// Screen.UnregisterRuneFallback methods.
|
||||
//
|
||||
// Note that Unicode is presumed to be able to display all glyphs.
|
||||
// This is a pretty poor assumption, but there is no easy way to
|
||||
// figure out which glyphs are supported in a given font. Hence,
|
||||
// some care in selecting the characters you support in your application
|
||||
// is still appropriate.
|
||||
var RuneFallbacks = map[rune]string{
|
||||
RuneSterling: "f",
|
||||
RuneDArrow: "v",
|
||||
RuneLArrow: "<",
|
||||
RuneRArrow: ">",
|
||||
RuneUArrow: "^",
|
||||
RuneBullet: "o",
|
||||
RuneBoard: "#",
|
||||
RuneCkBoard: ":",
|
||||
RuneDegree: "\\",
|
||||
RuneDiamond: "+",
|
||||
RuneGEqual: ">",
|
||||
RunePi: "*",
|
||||
RuneHLine: "-",
|
||||
RuneLantern: "#",
|
||||
RunePlus: "+",
|
||||
RuneLEqual: "<",
|
||||
RuneLLCorner: "+",
|
||||
RuneLRCorner: "+",
|
||||
RuneNEqual: "!",
|
||||
RunePlMinus: "#",
|
||||
RuneS1: "~",
|
||||
RuneS3: "-",
|
||||
RuneS7: "-",
|
||||
RuneS9: "_",
|
||||
RuneBlock: "#",
|
||||
RuneTTee: "+",
|
||||
RuneRTee: "+",
|
||||
RuneLTee: "+",
|
||||
RuneBTee: "+",
|
||||
RuneULCorner: "+",
|
||||
RuneURCorner: "+",
|
||||
RuneVLine: "|",
|
||||
}
|
||||
+209
@@ -0,0 +1,209 @@
|
||||
// Copyright 2019 The TCell Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use file except in compliance with the License.
|
||||
// You may obtain a copy of the license at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package tcell
|
||||
|
||||
// Screen represents the physical (or emulated) screen.
|
||||
// This can be a terminal window or a physical console. Platforms implement
|
||||
// this differerently.
|
||||
type Screen interface {
|
||||
// Init initializes the screen for use.
|
||||
Init() error
|
||||
|
||||
// Fini finalizes the screen also releasing resources.
|
||||
Fini()
|
||||
|
||||
// Clear erases the screen. The contents of any screen buffers
|
||||
// will also be cleared. This has the logical effect of
|
||||
// filling the screen with spaces, using the global default style.
|
||||
Clear()
|
||||
|
||||
// Fill fills the screen with the given character and style.
|
||||
Fill(rune, Style)
|
||||
|
||||
// SetCell is an older API, and will be removed. Please use
|
||||
// SetContent instead; SetCell is implemented in terms of SetContent.
|
||||
SetCell(x int, y int, style Style, ch ...rune)
|
||||
|
||||
// GetContent returns the contents at the given location. If the
|
||||
// coordinates are out of range, then the values will be 0, nil,
|
||||
// StyleDefault. Note that the contents returned are logical contents
|
||||
// and may not actually be what is displayed, but rather are what will
|
||||
// be displayed if Show() or Sync() is called. The width is the width
|
||||
// in screen cells; most often this will be 1, but some East Asian
|
||||
// characters require two cells.
|
||||
GetContent(x, y int) (mainc rune, combc []rune, style Style, width int)
|
||||
|
||||
// SetContent sets the contents of the given cell location. If
|
||||
// the coordinates are out of range, then the operation is ignored.
|
||||
//
|
||||
// The first rune is the primary non-zero width rune. The array
|
||||
// that follows is a possible list of combining characters to append,
|
||||
// and will usually be nil (no combining characters.)
|
||||
//
|
||||
// The results are not displayd until Show() or Sync() is called.
|
||||
//
|
||||
// Note that wide (East Asian full width) runes occupy two cells,
|
||||
// and attempts to place character at next cell to the right will have
|
||||
// undefined effects. Wide runes that are printed in the
|
||||
// last column will be replaced with a single width space on output.
|
||||
SetContent(x int, y int, mainc rune, combc []rune, style Style)
|
||||
|
||||
// SetStyle sets the default style to use when clearing the screen
|
||||
// or when StyleDefault is specified. If it is also StyleDefault,
|
||||
// then whatever system/terminal default is relevant will be used.
|
||||
SetStyle(style Style)
|
||||
|
||||
// ShowCursor is used to display the cursor at a given location.
|
||||
// If the coordinates -1, -1 are given or are otherwise outside the
|
||||
// dimensions of the screen, the cursor will be hidden.
|
||||
ShowCursor(x int, y int)
|
||||
|
||||
// HideCursor is used to hide the cursor. Its an alias for
|
||||
// ShowCursor(-1, -1).
|
||||
HideCursor()
|
||||
|
||||
// Size returns the screen size as width, height. This changes in
|
||||
// response to a call to Clear or Flush.
|
||||
Size() (int, int)
|
||||
|
||||
// PollEvent waits for events to arrive. Main application loops
|
||||
// must spin on this to prevent the application from stalling.
|
||||
// Furthermore, this will return nil if the Screen is finalized.
|
||||
PollEvent() Event
|
||||
|
||||
// PostEvent tries to post an event into the event stream. This
|
||||
// can fail if the event queue is full. In that case, the event
|
||||
// is dropped, and ErrEventQFull is returned.
|
||||
PostEvent(ev Event) error
|
||||
|
||||
// PostEventWait is like PostEvent, but if the queue is full, it
|
||||
// blocks until there is space in the queue, making delivery
|
||||
// reliable. However, it is VERY important that this function
|
||||
// never be called from within whatever event loop is polling
|
||||
// with PollEvent(), otherwise a deadlock may arise.
|
||||
//
|
||||
// For this reason, when using this function, the use of a
|
||||
// Goroutine is recommended to ensure no deadlock can occur.
|
||||
PostEventWait(ev Event)
|
||||
|
||||
// EnableMouse enables the mouse. (If your terminal supports it.)
|
||||
EnableMouse()
|
||||
|
||||
// DisableMouse disables the mouse.
|
||||
DisableMouse()
|
||||
|
||||
// HasMouse returns true if the terminal (apparently) supports a
|
||||
// mouse. Note that the a return value of true doesn't guarantee that
|
||||
// a mouse/pointing device is present; a false return definitely
|
||||
// indicates no mouse support is available.
|
||||
HasMouse() bool
|
||||
|
||||
// Colors returns the number of colors. All colors are assumed to
|
||||
// use the ANSI color map. If a terminal is monochrome, it will
|
||||
// return 0.
|
||||
Colors() int
|
||||
|
||||
// Show makes all the content changes made using SetContent() visible
|
||||
// on the display.
|
||||
//
|
||||
// It does so in the most efficient and least visually disruptive
|
||||
// manner possible.
|
||||
Show()
|
||||
|
||||
// Sync works like Show(), but it updates every visible cell on the
|
||||
// physical display, assuming that it is not synchronized with any
|
||||
// internal model. This may be both expensive and visually jarring,
|
||||
// so it should only be used when believed to actually be necessary.
|
||||
//
|
||||
// Typically this is called as a result of a user-requested redraw
|
||||
// (e.g. to clear up on screen corruption caused by some other program),
|
||||
// or during a resize event.
|
||||
Sync()
|
||||
|
||||
// CharacterSet returns information about the character set.
|
||||
// This isn't the full locale, but it does give us the input/output
|
||||
// character set. Note that this is just for diagnostic purposes,
|
||||
// we normally translate input/output to/from UTF-8, regardless of
|
||||
// what the user's environment is.
|
||||
CharacterSet() string
|
||||
|
||||
// RegisterRuneFallback adds a fallback for runes that are not
|
||||
// part of the character set -- for example one coudld register
|
||||
// o as a fallback for ø. This should be done cautiously for
|
||||
// characters that might be displayed ordinarily in language
|
||||
// specific text -- characters that could change the meaning of
|
||||
// of written text would be dangerous. The intention here is to
|
||||
// facilitate fallback characters in pseudo-graphical applications.
|
||||
//
|
||||
// If the terminal has fallbacks already in place via an alternate
|
||||
// character set, those are used in preference. Also, standard
|
||||
// fallbacks for graphical characters in the ACSC terminfo string
|
||||
// are registered implicitly.
|
||||
|
||||
// The display string should be the same width as original rune.
|
||||
// This makes it possible to register two character replacements
|
||||
// for full width East Asian characters, for example.
|
||||
//
|
||||
// It is recommended that replacement strings consist only of
|
||||
// 7-bit ASCII, since other characters may not display everywhere.
|
||||
RegisterRuneFallback(r rune, subst string)
|
||||
|
||||
// UnregisterRuneFallback unmaps a replacement. It will unmap
|
||||
// the implicit ASCII replacements for alternate characters as well.
|
||||
// When an unmapped char needs to be displayed, but no suitable
|
||||
// glyph is available, '?' is emitted instead. It is not possible
|
||||
// to "disable" the use of alternate characters that are supported
|
||||
// by your terminal except by changing the terminal database.
|
||||
UnregisterRuneFallback(r rune)
|
||||
|
||||
// CanDisplay returns true if the given rune can be displayed on
|
||||
// this screen. Note that this is a best guess effort -- whether
|
||||
// your fonts support the character or not may be questionable.
|
||||
// Mostly this is for folks who work outside of Unicode.
|
||||
//
|
||||
// If checkFallbacks is true, then if any (possibly imperfect)
|
||||
// fallbacks are registered, this will return true. This will
|
||||
// also return true if the terminal can replace the glyph with
|
||||
// one that is visually indistinguishable from the one requested.
|
||||
CanDisplay(r rune, checkFallbacks bool) bool
|
||||
|
||||
// Resize does nothing, since its generally not possible to
|
||||
// ask a screen to resize, but it allows the Screen to implement
|
||||
// the View interface.
|
||||
Resize(int, int, int, int)
|
||||
|
||||
// HasKey returns true if the keyboard is believed to have the
|
||||
// key. In some cases a keyboard may have keys with this name
|
||||
// but no support for them, while in others a key may be reported
|
||||
// as supported but not actually be usable (such as some emulators
|
||||
// that hijack certain keys). Its best not to depend to strictly
|
||||
// on this function, but it can be used for hinting when building
|
||||
// menus, displayed hot-keys, etc. Note that KeyRune (literal
|
||||
// runes) is always true.
|
||||
HasKey(Key) bool
|
||||
}
|
||||
|
||||
// NewScreen returns a default Screen suitable for the user's terminal
|
||||
// environment.
|
||||
func NewScreen() (Screen, error) {
|
||||
// Windows is happier if we try for a console screen first.
|
||||
if s, _ := NewConsoleScreen(); s != nil {
|
||||
return s, nil
|
||||
} else if s, e := NewTerminfoScreen(); s != nil {
|
||||
return s, nil
|
||||
} else {
|
||||
return nil, e
|
||||
}
|
||||
}
|
||||
+508
@@ -0,0 +1,508 @@
|
||||
// Copyright 2016 The TCell Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use file except in compliance with the License.
|
||||
// You may obtain a copy of the license at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package tcell
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"unicode/utf8"
|
||||
|
||||
"golang.org/x/text/transform"
|
||||
)
|
||||
|
||||
// NewSimulationScreen returns a SimulationScreen. Note that
|
||||
// SimulationScreen is also a Screen.
|
||||
func NewSimulationScreen(charset string) SimulationScreen {
|
||||
if charset == "" {
|
||||
charset = "UTF-8"
|
||||
}
|
||||
s := &simscreen{charset: charset}
|
||||
return s
|
||||
}
|
||||
|
||||
// SimulationScreen represents a screen simulation. This is intended to
|
||||
// be a superset of normal Screens, but also adds some important interfaces
|
||||
// for testing.
|
||||
type SimulationScreen interface {
|
||||
// InjectKeyBytes injects a stream of bytes corresponding to
|
||||
// the native encoding (see charset). It turns true if the entire
|
||||
// set of bytes were processed and delivered as KeyEvents, false
|
||||
// if any bytes were not fully understood. Any bytes that are not
|
||||
// fully converted are discarded.
|
||||
InjectKeyBytes(buf []byte) bool
|
||||
|
||||
// InjectKey injects a key event. The rune is a UTF-8 rune, post
|
||||
// any translation.
|
||||
InjectKey(key Key, r rune, mod ModMask)
|
||||
|
||||
// InjectMouse injects a mouse event.
|
||||
InjectMouse(x, y int, buttons ButtonMask, mod ModMask)
|
||||
|
||||
// SetSize resizes the underlying physical screen. It also causes
|
||||
// a resize event to be injected during the next Show() or Sync().
|
||||
// A new physical contents array will be allocated (with data from
|
||||
// the old copied), so any prior value obtained with GetContents
|
||||
// won't be used anymore
|
||||
SetSize(width, height int)
|
||||
|
||||
// GetContents returns screen contents as an array of
|
||||
// cells, along with the physical width & height. Note that the
|
||||
// physical contents will be used until the next time SetSize()
|
||||
// is called.
|
||||
GetContents() (cells []SimCell, width int, height int)
|
||||
|
||||
// GetCursor returns the cursor details.
|
||||
GetCursor() (x int, y int, visible bool)
|
||||
|
||||
Screen
|
||||
}
|
||||
|
||||
// SimCell represents a simulated screen cell. The purpose of this
|
||||
// is to track on screen content.
|
||||
type SimCell struct {
|
||||
// Bytes is the actual character bytes. Normally this is
|
||||
// rune data, but it could be be data in another encoding system.
|
||||
Bytes []byte
|
||||
|
||||
// Style is the style used to display the data.
|
||||
Style Style
|
||||
|
||||
// Runes is the list of runes, unadulterated, in UTF-8.
|
||||
Runes []rune
|
||||
}
|
||||
|
||||
type simscreen struct {
|
||||
physw int
|
||||
physh int
|
||||
fini bool
|
||||
style Style
|
||||
evch chan Event
|
||||
quit chan struct{}
|
||||
|
||||
front []SimCell
|
||||
back CellBuffer
|
||||
clear bool
|
||||
cursorx int
|
||||
cursory int
|
||||
cursorvis bool
|
||||
mouse bool
|
||||
charset string
|
||||
encoder transform.Transformer
|
||||
decoder transform.Transformer
|
||||
fillchar rune
|
||||
fillstyle Style
|
||||
fallback map[rune]string
|
||||
|
||||
sync.Mutex
|
||||
}
|
||||
|
||||
func (s *simscreen) Init() error {
|
||||
s.evch = make(chan Event, 10)
|
||||
s.quit = make(chan struct{})
|
||||
s.fillchar = 'X'
|
||||
s.fillstyle = StyleDefault
|
||||
s.mouse = false
|
||||
s.physw = 80
|
||||
s.physh = 25
|
||||
s.cursorx = -1
|
||||
s.cursory = -1
|
||||
s.style = StyleDefault
|
||||
|
||||
if enc := GetEncoding(s.charset); enc != nil {
|
||||
s.encoder = enc.NewEncoder()
|
||||
s.decoder = enc.NewDecoder()
|
||||
} else {
|
||||
return ErrNoCharset
|
||||
}
|
||||
|
||||
s.front = make([]SimCell, s.physw*s.physh)
|
||||
s.back.Resize(80, 25)
|
||||
|
||||
// default fallbacks
|
||||
s.fallback = make(map[rune]string)
|
||||
for k, v := range RuneFallbacks {
|
||||
s.fallback[k] = v
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *simscreen) Fini() {
|
||||
s.Lock()
|
||||
s.fini = true
|
||||
s.back.Resize(0, 0)
|
||||
s.Unlock()
|
||||
if s.quit != nil {
|
||||
close(s.quit)
|
||||
}
|
||||
s.physw = 0
|
||||
s.physh = 0
|
||||
s.front = nil
|
||||
}
|
||||
|
||||
func (s *simscreen) SetStyle(style Style) {
|
||||
s.Lock()
|
||||
s.style = style
|
||||
s.Unlock()
|
||||
}
|
||||
|
||||
func (s *simscreen) Clear() {
|
||||
s.Fill(' ', s.style)
|
||||
}
|
||||
|
||||
func (s *simscreen) Fill(r rune, style Style) {
|
||||
s.Lock()
|
||||
s.back.Fill(r, style)
|
||||
s.Unlock()
|
||||
}
|
||||
|
||||
func (s *simscreen) SetCell(x, y int, style Style, ch ...rune) {
|
||||
|
||||
if len(ch) > 0 {
|
||||
s.SetContent(x, y, ch[0], ch[1:], style)
|
||||
} else {
|
||||
s.SetContent(x, y, ' ', nil, style)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *simscreen) SetContent(x, y int, mainc rune, combc []rune, st Style) {
|
||||
|
||||
s.Lock()
|
||||
s.back.SetContent(x, y, mainc, combc, st)
|
||||
s.Unlock()
|
||||
}
|
||||
|
||||
func (s *simscreen) GetContent(x, y int) (rune, []rune, Style, int) {
|
||||
var mainc rune
|
||||
var combc []rune
|
||||
var style Style
|
||||
var width int
|
||||
s.Lock()
|
||||
mainc, combc, style, width = s.back.GetContent(x, y)
|
||||
s.Unlock()
|
||||
return mainc, combc, style, width
|
||||
}
|
||||
|
||||
func (s *simscreen) drawCell(x, y int) int {
|
||||
|
||||
mainc, combc, style, width := s.back.GetContent(x, y)
|
||||
if !s.back.Dirty(x, y) {
|
||||
return width
|
||||
}
|
||||
if x >= s.physw || y >= s.physh || x < 0 || y < 0 {
|
||||
return width
|
||||
}
|
||||
simc := &s.front[(y*s.physw)+x]
|
||||
|
||||
if style == StyleDefault {
|
||||
style = s.style
|
||||
}
|
||||
simc.Style = style
|
||||
simc.Runes = append([]rune{mainc}, combc...)
|
||||
|
||||
// now emit runes - taking care to not overrun width with a
|
||||
// wide character, and to ensure that we emit exactly one regular
|
||||
// character followed up by any residual combing characters
|
||||
|
||||
simc.Bytes = nil
|
||||
|
||||
if x > s.physw-width {
|
||||
simc.Runes = []rune{' '}
|
||||
simc.Bytes = []byte{' '}
|
||||
return width
|
||||
}
|
||||
|
||||
lbuf := make([]byte, 12)
|
||||
ubuf := make([]byte, 12)
|
||||
nout := 0
|
||||
|
||||
for _, r := range simc.Runes {
|
||||
|
||||
l := utf8.EncodeRune(ubuf, r)
|
||||
|
||||
nout, _, _ = s.encoder.Transform(lbuf, ubuf[:l], true)
|
||||
|
||||
if nout == 0 || lbuf[0] == '\x1a' {
|
||||
|
||||
// skip combining
|
||||
|
||||
if subst, ok := s.fallback[r]; ok {
|
||||
simc.Bytes = append(simc.Bytes,
|
||||
[]byte(subst)...)
|
||||
|
||||
} else if r >= ' ' && r <= '~' {
|
||||
simc.Bytes = append(simc.Bytes, byte(r))
|
||||
|
||||
} else if simc.Bytes == nil {
|
||||
simc.Bytes = append(simc.Bytes, '?')
|
||||
}
|
||||
} else {
|
||||
simc.Bytes = append(simc.Bytes, lbuf[:nout]...)
|
||||
}
|
||||
}
|
||||
s.back.SetDirty(x, y, false)
|
||||
return width
|
||||
}
|
||||
|
||||
func (s *simscreen) ShowCursor(x, y int) {
|
||||
s.Lock()
|
||||
s.cursorx, s.cursory = x, y
|
||||
s.showCursor()
|
||||
s.Unlock()
|
||||
}
|
||||
|
||||
func (s *simscreen) HideCursor() {
|
||||
s.ShowCursor(-1, -1)
|
||||
}
|
||||
|
||||
func (s *simscreen) showCursor() {
|
||||
|
||||
x, y := s.cursorx, s.cursory
|
||||
if x < 0 || y < 0 || x >= s.physw || y >= s.physh {
|
||||
s.cursorvis = false
|
||||
} else {
|
||||
s.cursorvis = true
|
||||
}
|
||||
}
|
||||
|
||||
func (s *simscreen) hideCursor() {
|
||||
// does not update cursor position
|
||||
s.cursorvis = false
|
||||
}
|
||||
|
||||
func (s *simscreen) Show() {
|
||||
s.Lock()
|
||||
s.resize()
|
||||
s.draw()
|
||||
s.Unlock()
|
||||
}
|
||||
|
||||
func (s *simscreen) clearScreen() {
|
||||
// We emulate a hardware clear by filling with a specific pattern
|
||||
for i := range s.front {
|
||||
s.front[i].Style = s.fillstyle
|
||||
s.front[i].Runes = []rune{s.fillchar}
|
||||
s.front[i].Bytes = []byte{byte(s.fillchar)}
|
||||
}
|
||||
s.clear = false
|
||||
}
|
||||
|
||||
func (s *simscreen) draw() {
|
||||
s.hideCursor()
|
||||
if s.clear {
|
||||
s.clearScreen()
|
||||
}
|
||||
|
||||
w, h := s.back.Size()
|
||||
for y := 0; y < h; y++ {
|
||||
for x := 0; x < w; x++ {
|
||||
width := s.drawCell(x, y)
|
||||
x += width - 1
|
||||
}
|
||||
}
|
||||
s.showCursor()
|
||||
}
|
||||
|
||||
func (s *simscreen) EnableMouse() {
|
||||
s.mouse = true
|
||||
}
|
||||
|
||||
func (s *simscreen) DisableMouse() {
|
||||
s.mouse = false
|
||||
}
|
||||
|
||||
func (s *simscreen) Size() (int, int) {
|
||||
s.Lock()
|
||||
w, h := s.back.Size()
|
||||
s.Unlock()
|
||||
return w, h
|
||||
}
|
||||
|
||||
func (s *simscreen) resize() {
|
||||
w, h := s.physw, s.physh
|
||||
ow, oh := s.back.Size()
|
||||
if w != ow || h != oh {
|
||||
s.back.Resize(w, h)
|
||||
ev := NewEventResize(w, h)
|
||||
s.PostEvent(ev)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *simscreen) Colors() int {
|
||||
return 256
|
||||
}
|
||||
|
||||
func (s *simscreen) PollEvent() Event {
|
||||
select {
|
||||
case <-s.quit:
|
||||
return nil
|
||||
case ev := <-s.evch:
|
||||
return ev
|
||||
}
|
||||
}
|
||||
|
||||
func (s *simscreen) PostEventWait(ev Event) {
|
||||
s.evch <- ev
|
||||
}
|
||||
|
||||
func (s *simscreen) PostEvent(ev Event) error {
|
||||
select {
|
||||
case s.evch <- ev:
|
||||
return nil
|
||||
default:
|
||||
return ErrEventQFull
|
||||
}
|
||||
}
|
||||
|
||||
func (s *simscreen) InjectMouse(x, y int, buttons ButtonMask, mod ModMask) {
|
||||
ev := NewEventMouse(x, y, buttons, mod)
|
||||
s.PostEvent(ev)
|
||||
}
|
||||
|
||||
func (s *simscreen) InjectKey(key Key, r rune, mod ModMask) {
|
||||
ev := NewEventKey(key, r, mod)
|
||||
s.PostEvent(ev)
|
||||
}
|
||||
|
||||
func (s *simscreen) InjectKeyBytes(b []byte) bool {
|
||||
failed := false
|
||||
|
||||
outer:
|
||||
for len(b) > 0 {
|
||||
if b[0] >= ' ' && b[0] <= 0x7F {
|
||||
// printable ASCII easy to deal with -- no encodings
|
||||
ev := NewEventKey(KeyRune, rune(b[0]), ModNone)
|
||||
s.PostEvent(ev)
|
||||
b = b[1:]
|
||||
continue
|
||||
}
|
||||
|
||||
if b[0] < 0x80 {
|
||||
mod := ModNone
|
||||
// No encodings start with low numbered values
|
||||
if Key(b[0]) >= KeyCtrlA && Key(b[0]) <= KeyCtrlZ {
|
||||
mod = ModCtrl
|
||||
}
|
||||
ev := NewEventKey(Key(b[0]), 0, mod)
|
||||
s.PostEvent(ev)
|
||||
continue
|
||||
}
|
||||
|
||||
utfb := make([]byte, len(b)*4) // worst case
|
||||
for l := 1; l < len(b); l++ {
|
||||
s.decoder.Reset()
|
||||
nout, nin, _ := s.decoder.Transform(utfb, b[:l], true)
|
||||
|
||||
if nout != 0 {
|
||||
r, _ := utf8.DecodeRune(utfb[:nout])
|
||||
if r != utf8.RuneError {
|
||||
ev := NewEventKey(KeyRune, r, ModNone)
|
||||
s.PostEvent(ev)
|
||||
}
|
||||
b = b[nin:]
|
||||
continue outer
|
||||
}
|
||||
}
|
||||
failed = true
|
||||
b = b[1:]
|
||||
continue
|
||||
}
|
||||
|
||||
return !failed
|
||||
}
|
||||
|
||||
func (s *simscreen) Sync() {
|
||||
s.Lock()
|
||||
s.clear = true
|
||||
s.resize()
|
||||
s.back.Invalidate()
|
||||
s.draw()
|
||||
s.Unlock()
|
||||
}
|
||||
|
||||
func (s *simscreen) CharacterSet() string {
|
||||
return s.charset
|
||||
}
|
||||
|
||||
func (s *simscreen) SetSize(w, h int) {
|
||||
s.Lock()
|
||||
newc := make([]SimCell, w*h)
|
||||
for row := 0; row < h && row < s.physh; row++ {
|
||||
for col := 0; col < w && col < s.physw; col++ {
|
||||
newc[(row*w)+col] = s.front[(row*s.physw)+col]
|
||||
}
|
||||
}
|
||||
s.cursorx, s.cursory = -1, -1
|
||||
s.physw, s.physh = w, h
|
||||
s.front = newc
|
||||
s.back.Resize(w, h)
|
||||
s.Unlock()
|
||||
}
|
||||
|
||||
func (s *simscreen) GetContents() ([]SimCell, int, int) {
|
||||
s.Lock()
|
||||
cells, w, h := s.front, s.physw, s.physh
|
||||
s.Unlock()
|
||||
return cells, w, h
|
||||
}
|
||||
|
||||
func (s *simscreen) GetCursor() (int, int, bool) {
|
||||
s.Lock()
|
||||
x, y, vis := s.cursorx, s.cursory, s.cursorvis
|
||||
s.Unlock()
|
||||
return x, y, vis
|
||||
}
|
||||
|
||||
func (s *simscreen) RegisterRuneFallback(r rune, subst string) {
|
||||
s.Lock()
|
||||
s.fallback[r] = subst
|
||||
s.Unlock()
|
||||
}
|
||||
|
||||
func (s *simscreen) UnregisterRuneFallback(r rune) {
|
||||
s.Lock()
|
||||
delete(s.fallback, r)
|
||||
s.Unlock()
|
||||
}
|
||||
|
||||
func (s *simscreen) CanDisplay(r rune, checkFallbacks bool) bool {
|
||||
|
||||
if enc := s.encoder; enc != nil {
|
||||
nb := make([]byte, 6)
|
||||
ob := make([]byte, 6)
|
||||
num := utf8.EncodeRune(ob, r)
|
||||
|
||||
enc.Reset()
|
||||
dst, _, err := enc.Transform(nb, ob[:num], true)
|
||||
if dst != 0 && err == nil && nb[0] != '\x1A' {
|
||||
return true
|
||||
}
|
||||
}
|
||||
if !checkFallbacks {
|
||||
return false
|
||||
}
|
||||
if _, ok := s.fallback[r]; ok {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (s *simscreen) HasMouse() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (s *simscreen) Resize(int, int, int, int) {}
|
||||
|
||||
func (s *simscreen) HasKey(Key) bool {
|
||||
return true
|
||||
}
|
||||
+126
@@ -0,0 +1,126 @@
|
||||
// Copyright 2015 The TCell Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use file except in compliance with the License.
|
||||
// You may obtain a copy of the license at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package tcell
|
||||
|
||||
// Style represents a complete text style, including both foreground
|
||||
// and background color. We encode it in a 64-bit int for efficiency.
|
||||
// The coding is (MSB): <7b flags><1b><24b fgcolor><7b attr><1b><24b bgcolor>.
|
||||
// The <1b> is set true to indicate that the color is an RGB color, rather
|
||||
// than a named index.
|
||||
//
|
||||
// This gives 24bit color options, if it ever becomes truly necessary.
|
||||
// However, applications must not rely on this encoding.
|
||||
//
|
||||
// Note that not all terminals can display all colors or attributes, and
|
||||
// many might have specific incompatibilities between specific attributes
|
||||
// and color combinations.
|
||||
//
|
||||
// The intention is to extend styles to support paletting, in which case
|
||||
// some flag bit(s) would be set, and the foreground and background colors
|
||||
// would be replaced with a palette number and palette index.
|
||||
//
|
||||
// To use Style, just declare a variable of its type.
|
||||
type Style int64
|
||||
|
||||
// StyleDefault represents a default style, based upon the context.
|
||||
// It is the zero value.
|
||||
const StyleDefault Style = 0
|
||||
|
||||
// styleFlags -- used internally for now.
|
||||
const (
|
||||
styleBgSet = 1 << (iota + 57)
|
||||
styleFgSet
|
||||
stylePalette
|
||||
)
|
||||
|
||||
// Foreground returns a new style based on s, with the foreground color set
|
||||
// as requested. ColorDefault can be used to select the global default.
|
||||
func (s Style) Foreground(c Color) Style {
|
||||
if c == ColorDefault {
|
||||
return (s &^ (0x1ffffff00000000 | styleFgSet))
|
||||
}
|
||||
return (s &^ Style(0x1ffffff00000000)) |
|
||||
((Style(c) & 0x1ffffff) << 32) | styleFgSet
|
||||
}
|
||||
|
||||
// Background returns a new style based on s, with the background color set
|
||||
// as requested. ColorDefault can be used to select the global default.
|
||||
func (s Style) Background(c Color) Style {
|
||||
if c == ColorDefault {
|
||||
return (s &^ (0x1ffffff | styleBgSet))
|
||||
}
|
||||
return (s &^ (0x1ffffff)) | (Style(c) & 0x1ffffff) | styleBgSet
|
||||
}
|
||||
|
||||
// Decompose breaks a style up, returning the foreground, background,
|
||||
// and other attributes.
|
||||
func (s Style) Decompose() (fg Color, bg Color, attr AttrMask) {
|
||||
if s&styleFgSet != 0 {
|
||||
fg = Color(s>>32) & 0x1ffffff
|
||||
} else {
|
||||
fg = ColorDefault
|
||||
}
|
||||
if s&styleBgSet != 0 {
|
||||
bg = Color(s & 0x1ffffff)
|
||||
} else {
|
||||
bg = ColorDefault
|
||||
}
|
||||
attr = AttrMask(s) & attrAll
|
||||
|
||||
return fg, bg, attr
|
||||
}
|
||||
|
||||
func (s Style) setAttrs(attrs Style, on bool) Style {
|
||||
if on {
|
||||
return s | attrs
|
||||
}
|
||||
return s &^ attrs
|
||||
}
|
||||
|
||||
// Normal returns the style with all attributes disabled.
|
||||
func (s Style) Normal() Style {
|
||||
return s &^ Style(attrAll)
|
||||
}
|
||||
|
||||
// Bold returns a new style based on s, with the bold attribute set
|
||||
// as requested.
|
||||
func (s Style) Bold(on bool) Style {
|
||||
return s.setAttrs(Style(AttrBold), on)
|
||||
}
|
||||
|
||||
// Blink returns a new style based on s, with the blink attribute set
|
||||
// as requested.
|
||||
func (s Style) Blink(on bool) Style {
|
||||
return s.setAttrs(Style(AttrBlink), on)
|
||||
}
|
||||
|
||||
// Dim returns a new style based on s, with the dim attribute set
|
||||
// as requested.
|
||||
func (s Style) Dim(on bool) Style {
|
||||
return s.setAttrs(Style(AttrDim), on)
|
||||
}
|
||||
|
||||
// Reverse returns a new style based on s, with the reverse attribute set
|
||||
// as requested. (Reverse usually changes the foreground and background
|
||||
// colors.)
|
||||
func (s Style) Reverse(on bool) Style {
|
||||
return s.setAttrs(Style(AttrReverse), on)
|
||||
}
|
||||
|
||||
// Underline returns a new style based on s, with the underline attribute set
|
||||
// as requested.
|
||||
func (s Style) Underline(on bool) Style {
|
||||
return s.setAttrs(Style(AttrUnderline), on)
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
mkinfo
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
This package represents the parent for all terminals.
|
||||
|
||||
In older versions of tcell we had (a couple of) different
|
||||
external file formats for the terminal database. Those are
|
||||
now removed. All terminal definitions are supplied by
|
||||
one of two methods:
|
||||
|
||||
1. Compiled Go code
|
||||
|
||||
2. For systems with terminfo and infocmp, dynamically
|
||||
generated at runtime.
|
||||
|
||||
The Go code can be generated using the mkinfo utility in
|
||||
this directory. The database entry should be generated
|
||||
into a package in a directory named as the first character
|
||||
of the package name. (This permits us to group them all
|
||||
without having a huge directory of little packages.)
|
||||
|
||||
It may be desirable to add new packages to the extended
|
||||
package, or -- rarely -- the base package.
|
||||
|
||||
Applications which want to have the large set of terminal
|
||||
descriptions built into the binary can simply import the
|
||||
extended package. Otherwise a smaller reasonable default
|
||||
set (the base package) will be included instead.
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
TERMINALS
|
||||
=========
|
||||
|
||||
The best way to populate terminals on Debian is to install ncurses,
|
||||
ncurses-term, screen, tmux, rxvt-unicode, and dvtm. This populates the
|
||||
the terminfo database so that we can have a reasonable set of starting
|
||||
terminals.
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
// Generated automatically. DO NOT HAND-EDIT.
|
||||
|
||||
package adm3a
|
||||
|
||||
import "github.com/gdamore/tcell/terminfo"
|
||||
|
||||
func init() {
|
||||
|
||||
// lsi adm3a
|
||||
terminfo.AddTerminfo(&terminfo.Terminfo{
|
||||
Name: "adm3a",
|
||||
Columns: 80,
|
||||
Lines: 24,
|
||||
Bell: "\a",
|
||||
Clear: "\x1a$<1/>",
|
||||
PadChar: "\x00",
|
||||
SetCursor: "\x1b=%p1%' '%+%c%p2%' '%+%c",
|
||||
CursorBack1: "\b",
|
||||
CursorUp1: "\v",
|
||||
KeyUp: "\v",
|
||||
KeyDown: "\n",
|
||||
KeyRight: "\f",
|
||||
KeyLeft: "\b",
|
||||
})
|
||||
}
|
||||
+81
@@ -0,0 +1,81 @@
|
||||
// Generated automatically. DO NOT HAND-EDIT.
|
||||
|
||||
package aixterm
|
||||
|
||||
import "github.com/gdamore/tcell/terminfo"
|
||||
|
||||
func init() {
|
||||
|
||||
// IBM Aixterm Terminal Emulator
|
||||
terminfo.AddTerminfo(&terminfo.Terminfo{
|
||||
Name: "aixterm",
|
||||
Columns: 80,
|
||||
Lines: 25,
|
||||
Colors: 8,
|
||||
Bell: "\a",
|
||||
Clear: "\x1b[H\x1b[J",
|
||||
AttrOff: "\x1b[0;10m\x1b(B",
|
||||
Underline: "\x1b[4m",
|
||||
Bold: "\x1b[1m",
|
||||
Reverse: "\x1b[7m",
|
||||
SetFg: "\x1b[3%p1%dm",
|
||||
SetBg: "\x1b[4%p1%dm",
|
||||
SetFgBg: "\x1b[3%p1%d;4%p2%dm",
|
||||
PadChar: "\x00",
|
||||
AltChars: "jjkkllmmnnqqttuuvvwwxx",
|
||||
EnterAcs: "\x1b(0",
|
||||
ExitAcs: "\x1b(B",
|
||||
SetCursor: "\x1b[%i%p1%d;%p2%dH",
|
||||
CursorBack1: "\b",
|
||||
CursorUp1: "\x1b[A",
|
||||
KeyUp: "\x1b[A",
|
||||
KeyDown: "\x1b[B",
|
||||
KeyRight: "\x1b[C",
|
||||
KeyLeft: "\x1b[D",
|
||||
KeyInsert: "\x1b[139q",
|
||||
KeyDelete: "\x1b[P",
|
||||
KeyBackspace: "\b",
|
||||
KeyHome: "\x1b[H",
|
||||
KeyEnd: "\x1b[146q",
|
||||
KeyPgUp: "\x1b[150q",
|
||||
KeyPgDn: "\x1b[154q",
|
||||
KeyF1: "\x1b[001q",
|
||||
KeyF2: "\x1b[002q",
|
||||
KeyF3: "\x1b[003q",
|
||||
KeyF4: "\x1b[004q",
|
||||
KeyF5: "\x1b[005q",
|
||||
KeyF6: "\x1b[006q",
|
||||
KeyF7: "\x1b[007q",
|
||||
KeyF8: "\x1b[008q",
|
||||
KeyF9: "\x1b[009q",
|
||||
KeyF10: "\x1b[010q",
|
||||
KeyF11: "\x1b[011q",
|
||||
KeyF12: "\x1b[012q",
|
||||
KeyF13: "\x1b[013q",
|
||||
KeyF14: "\x1b[014q",
|
||||
KeyF15: "\x1b[015q",
|
||||
KeyF16: "\x1b[016q",
|
||||
KeyF17: "\x1b[017q",
|
||||
KeyF18: "\x1b[018q",
|
||||
KeyF19: "\x1b[019q",
|
||||
KeyF20: "\x1b[020q",
|
||||
KeyF21: "\x1b[021q",
|
||||
KeyF22: "\x1b[022q",
|
||||
KeyF23: "\x1b[023q",
|
||||
KeyF24: "\x1b[024q",
|
||||
KeyF25: "\x1b[025q",
|
||||
KeyF26: "\x1b[026q",
|
||||
KeyF27: "\x1b[027q",
|
||||
KeyF28: "\x1b[028q",
|
||||
KeyF29: "\x1b[029q",
|
||||
KeyF30: "\x1b[030q",
|
||||
KeyF31: "\x1b[031q",
|
||||
KeyF32: "\x1b[032q",
|
||||
KeyF33: "\x1b[033q",
|
||||
KeyF34: "\x1b[034q",
|
||||
KeyF35: "\x1b[035q",
|
||||
KeyF36: "\x1b[036q",
|
||||
KeyClear: "\x1b[144q",
|
||||
KeyBacktab: "\x1b[Z",
|
||||
})
|
||||
}
|
||||
+156
@@ -0,0 +1,156 @@
|
||||
// Generated automatically. DO NOT HAND-EDIT.
|
||||
|
||||
package alacritty
|
||||
|
||||
import "github.com/gdamore/tcell/terminfo"
|
||||
|
||||
func init() {
|
||||
|
||||
// alacritty terminal emulator
|
||||
terminfo.AddTerminfo(&terminfo.Terminfo{
|
||||
Name: "alacritty",
|
||||
Columns: 80,
|
||||
Lines: 24,
|
||||
Colors: 256,
|
||||
Bell: "\a",
|
||||
Clear: "\x1b[H\x1b[2J",
|
||||
EnterCA: "\x1b[?1049h\x1b[22;0;0t",
|
||||
ExitCA: "\x1b[?1049l\x1b[23;0;0t",
|
||||
ShowCursor: "\x1b[?12l\x1b[?25h",
|
||||
HideCursor: "\x1b[?25l",
|
||||
AttrOff: "\x1b(B\x1b[m",
|
||||
Underline: "\x1b[4m",
|
||||
Bold: "\x1b[1m",
|
||||
Dim: "\x1b[2m",
|
||||
Blink: "\x1b[5m",
|
||||
Reverse: "\x1b[7m",
|
||||
EnterKeypad: "\x1b[?1h\x1b=",
|
||||
ExitKeypad: "\x1b[?1l\x1b>",
|
||||
SetFg: "\x1b[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m",
|
||||
SetBg: "\x1b[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m",
|
||||
SetFgBg: "\x1b[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;;%?%p2%{8}%<%t4%p2%d%e%p2%{16}%<%t10%p2%{8}%-%d%e48;5;%p2%d%;m",
|
||||
AltChars: "``aaffggiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~",
|
||||
EnterAcs: "\x1b(0",
|
||||
ExitAcs: "\x1b(B",
|
||||
Mouse: "\x1b[M",
|
||||
MouseMode: "%?%p1%{1}%=%t%'h'%Pa%e%'l'%Pa%;\x1b[?1000%ga%c\x1b[?1002%ga%c\x1b[?1003%ga%c\x1b[?1006%ga%c",
|
||||
SetCursor: "\x1b[%i%p1%d;%p2%dH",
|
||||
CursorBack1: "\b",
|
||||
CursorUp1: "\x1b[A",
|
||||
KeyUp: "\x1bOA",
|
||||
KeyDown: "\x1bOB",
|
||||
KeyRight: "\x1bOC",
|
||||
KeyLeft: "\x1bOD",
|
||||
KeyInsert: "\x1b[2~",
|
||||
KeyDelete: "\x1b[3~",
|
||||
KeyBackspace: "\b",
|
||||
KeyHome: "\x1bOH",
|
||||
KeyEnd: "\x1bOF",
|
||||
KeyPgUp: "\x1b[5~",
|
||||
KeyPgDn: "\x1b[6~",
|
||||
KeyF1: "\x1bOP",
|
||||
KeyF2: "\x1bOQ",
|
||||
KeyF3: "\x1bOR",
|
||||
KeyF4: "\x1bOS",
|
||||
KeyF5: "\x1b[15~",
|
||||
KeyF6: "\x1b[17~",
|
||||
KeyF7: "\x1b[18~",
|
||||
KeyF8: "\x1b[19~",
|
||||
KeyF9: "\x1b[20~",
|
||||
KeyF10: "\x1b[21~",
|
||||
KeyF11: "\x1b[23~",
|
||||
KeyF12: "\x1b[24~",
|
||||
KeyF13: "\x1b[1;2P",
|
||||
KeyF14: "\x1b[1;2Q",
|
||||
KeyF15: "\x1b[1;2R",
|
||||
KeyF16: "\x1b[1;2S",
|
||||
KeyF17: "\x1b[15;2~",
|
||||
KeyF18: "\x1b[17;2~",
|
||||
KeyF19: "\x1b[18;2~",
|
||||
KeyF20: "\x1b[19;2~",
|
||||
KeyF21: "\x1b[20;2~",
|
||||
KeyF22: "\x1b[21;2~",
|
||||
KeyF23: "\x1b[23;2~",
|
||||
KeyF24: "\x1b[24;2~",
|
||||
KeyF25: "\x1b[1;5P",
|
||||
KeyF26: "\x1b[1;5Q",
|
||||
KeyF27: "\x1b[1;5R",
|
||||
KeyF28: "\x1b[1;5S",
|
||||
KeyF29: "\x1b[15;5~",
|
||||
KeyF30: "\x1b[17;5~",
|
||||
KeyF31: "\x1b[18;5~",
|
||||
KeyF32: "\x1b[19;5~",
|
||||
KeyF33: "\x1b[20;5~",
|
||||
KeyF34: "\x1b[21;5~",
|
||||
KeyF35: "\x1b[23;5~",
|
||||
KeyF36: "\x1b[24;5~",
|
||||
KeyF37: "\x1b[1;6P",
|
||||
KeyF38: "\x1b[1;6Q",
|
||||
KeyF39: "\x1b[1;6R",
|
||||
KeyF40: "\x1b[1;6S",
|
||||
KeyF41: "\x1b[15;6~",
|
||||
KeyF42: "\x1b[17;6~",
|
||||
KeyF43: "\x1b[18;6~",
|
||||
KeyF44: "\x1b[19;6~",
|
||||
KeyF45: "\x1b[20;6~",
|
||||
KeyF46: "\x1b[21;6~",
|
||||
KeyF47: "\x1b[23;6~",
|
||||
KeyF48: "\x1b[24;6~",
|
||||
KeyF49: "\x1b[1;3P",
|
||||
KeyF50: "\x1b[1;3Q",
|
||||
KeyF51: "\x1b[1;3R",
|
||||
KeyF52: "\x1b[1;3S",
|
||||
KeyF53: "\x1b[15;3~",
|
||||
KeyF54: "\x1b[17;3~",
|
||||
KeyF55: "\x1b[18;3~",
|
||||
KeyF56: "\x1b[19;3~",
|
||||
KeyF57: "\x1b[20;3~",
|
||||
KeyF58: "\x1b[21;3~",
|
||||
KeyF59: "\x1b[23;3~",
|
||||
KeyF60: "\x1b[24;3~",
|
||||
KeyF61: "\x1b[1;4P",
|
||||
KeyF62: "\x1b[1;4Q",
|
||||
KeyF63: "\x1b[1;4R",
|
||||
KeyBacktab: "\x1b[Z",
|
||||
KeyShfLeft: "\x1b[1;2D",
|
||||
KeyShfRight: "\x1b[1;2C",
|
||||
KeyShfUp: "\x1b[1;2A",
|
||||
KeyShfDown: "\x1b[1;2B",
|
||||
KeyCtrlLeft: "\x1b[1;5D",
|
||||
KeyCtrlRight: "\x1b[1;5C",
|
||||
KeyCtrlUp: "\x1b[1;5A",
|
||||
KeyCtrlDown: "\x1b[1;5B",
|
||||
KeyMetaLeft: "\x1b[1;9D",
|
||||
KeyMetaRight: "\x1b[1;9C",
|
||||
KeyMetaUp: "\x1b[1;9A",
|
||||
KeyMetaDown: "\x1b[1;9B",
|
||||
KeyAltLeft: "\x1b[1;3D",
|
||||
KeyAltRight: "\x1b[1;3C",
|
||||
KeyAltUp: "\x1b[1;3A",
|
||||
KeyAltDown: "\x1b[1;3B",
|
||||
KeyAltShfLeft: "\x1b[1;4D",
|
||||
KeyAltShfRight: "\x1b[1;4C",
|
||||
KeyAltShfUp: "\x1b[1;4A",
|
||||
KeyAltShfDown: "\x1b[1;4B",
|
||||
KeyMetaShfLeft: "\x1b[1;10D",
|
||||
KeyMetaShfRight: "\x1b[1;10C",
|
||||
KeyMetaShfUp: "\x1b[1;10A",
|
||||
KeyMetaShfDown: "\x1b[1;10B",
|
||||
KeyCtrlShfLeft: "\x1b[1;6D",
|
||||
KeyCtrlShfRight: "\x1b[1;6C",
|
||||
KeyCtrlShfUp: "\x1b[1;6A",
|
||||
KeyCtrlShfDown: "\x1b[1;6B",
|
||||
KeyShfHome: "\x1b[1;2H",
|
||||
KeyShfEnd: "\x1b[1;2F",
|
||||
KeyCtrlHome: "\x1b[1;5H",
|
||||
KeyCtrlEnd: "\x1b[1;5F",
|
||||
KeyAltHome: "\x1b[1;9H",
|
||||
KeyAltEnd: "\x1b[1;9F",
|
||||
KeyCtrlShfHome: "\x1b[1;6H",
|
||||
KeyCtrlShfEnd: "\x1b[1;6F",
|
||||
KeyMetaShfHome: "\x1b[1;10H",
|
||||
KeyMetaShfEnd: "\x1b[1;10F",
|
||||
KeyAltShfHome: "\x1b[1;4H",
|
||||
KeyAltShfEnd: "\x1b[1;4F",
|
||||
})
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
// Generated automatically. DO NOT HAND-EDIT.
|
||||
|
||||
package ansi
|
||||
|
||||
import "github.com/gdamore/tcell/terminfo"
|
||||
|
||||
func init() {
|
||||
|
||||
// ansi/pc-term compatible with color
|
||||
terminfo.AddTerminfo(&terminfo.Terminfo{
|
||||
Name: "ansi",
|
||||
Columns: 80,
|
||||
Lines: 24,
|
||||
Colors: 8,
|
||||
Bell: "\a",
|
||||
Clear: "\x1b[H\x1b[J",
|
||||
AttrOff: "\x1b[0;10m",
|
||||
Underline: "\x1b[4m",
|
||||
Bold: "\x1b[1m",
|
||||
Blink: "\x1b[5m",
|
||||
Reverse: "\x1b[7m",
|
||||
SetFg: "\x1b[3%p1%dm",
|
||||
SetBg: "\x1b[4%p1%dm",
|
||||
SetFgBg: "\x1b[3%p1%d;4%p2%dm",
|
||||
PadChar: "\x00",
|
||||
AltChars: "+\x10,\x11-\x18.\x190\xdb`\x04a\xb1f\xf8g\xf1h\xb0j\xd9k\xbfl\xdam\xc0n\xc5o~p\xc4q\xc4r\xc4s_t\xc3u\xb4v\xc1w\xc2x\xb3y\xf3z\xf2{\xe3|\xd8}\x9c~\xfe",
|
||||
EnterAcs: "\x1b[11m",
|
||||
ExitAcs: "\x1b[10m",
|
||||
SetCursor: "\x1b[%i%p1%d;%p2%dH",
|
||||
CursorBack1: "\x1b[D",
|
||||
CursorUp1: "\x1b[A",
|
||||
KeyUp: "\x1b[A",
|
||||
KeyDown: "\x1b[B",
|
||||
KeyRight: "\x1b[C",
|
||||
KeyLeft: "\x1b[D",
|
||||
KeyInsert: "\x1b[L",
|
||||
KeyBackspace: "\b",
|
||||
KeyHome: "\x1b[H",
|
||||
KeyBacktab: "\x1b[Z",
|
||||
})
|
||||
}
|
||||
+110
@@ -0,0 +1,110 @@
|
||||
// Generated automatically. DO NOT HAND-EDIT.
|
||||
|
||||
package aterm
|
||||
|
||||
import "github.com/gdamore/tcell/terminfo"
|
||||
|
||||
func init() {
|
||||
|
||||
// AfterStep terminal
|
||||
terminfo.AddTerminfo(&terminfo.Terminfo{
|
||||
Name: "aterm",
|
||||
Columns: 80,
|
||||
Lines: 24,
|
||||
Colors: 8,
|
||||
Bell: "\a",
|
||||
Clear: "\x1b[H\x1b[2J",
|
||||
EnterCA: "\x1b7\x1b[?47h",
|
||||
ExitCA: "\x1b[2J\x1b[?47l\x1b8",
|
||||
ShowCursor: "\x1b[?25h",
|
||||
HideCursor: "\x1b[?25l",
|
||||
AttrOff: "\x1b[m\x0f",
|
||||
Underline: "\x1b[4m",
|
||||
Bold: "\x1b[1m",
|
||||
Blink: "\x1b[5m",
|
||||
Reverse: "\x1b[7m",
|
||||
EnterKeypad: "\x1b=",
|
||||
ExitKeypad: "\x1b>",
|
||||
SetFg: "\x1b[3%p1%dm",
|
||||
SetBg: "\x1b[4%p1%dm",
|
||||
SetFgBg: "\x1b[3%p1%d;4%p2%dm",
|
||||
PadChar: "\x00",
|
||||
AltChars: "``aaffggjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~",
|
||||
EnterAcs: "\x0e",
|
||||
ExitAcs: "\x0f",
|
||||
EnableAcs: "\x1b(B\x1b)0",
|
||||
Mouse: "\x1b[M",
|
||||
MouseMode: "%?%p1%{1}%=%t%'h'%Pa%e%'l'%Pa%;\x1b[?1000%ga%c\x1b[?1002%ga%c\x1b[?1003%ga%c\x1b[?1006%ga%c",
|
||||
SetCursor: "\x1b[%i%p1%d;%p2%dH",
|
||||
CursorBack1: "\b",
|
||||
CursorUp1: "\x1b[A",
|
||||
KeyUp: "\x1b[A",
|
||||
KeyDown: "\x1b[B",
|
||||
KeyRight: "\x1b[C",
|
||||
KeyLeft: "\x1b[D",
|
||||
KeyInsert: "\x1b[2~",
|
||||
KeyDelete: "\x1b[3~",
|
||||
KeyBackspace: "\xff",
|
||||
KeyHome: "\x1b[7~",
|
||||
KeyEnd: "\x1b[8~",
|
||||
KeyPgUp: "\x1b[5~",
|
||||
KeyPgDn: "\x1b[6~",
|
||||
KeyF1: "\x1bOP",
|
||||
KeyF2: "\x1bOQ",
|
||||
KeyF3: "\x1bOR",
|
||||
KeyF4: "\x1bOS",
|
||||
KeyF5: "\x1b[15~",
|
||||
KeyF6: "\x1b[17~",
|
||||
KeyF7: "\x1b[18~",
|
||||
KeyF8: "\x1b[19~",
|
||||
KeyF9: "\x1b[20~",
|
||||
KeyF10: "\x1b[21~",
|
||||
KeyF11: "\x1b[23~",
|
||||
KeyF12: "\x1b[24~",
|
||||
KeyF13: "\x1b[25~",
|
||||
KeyF14: "\x1b[26~",
|
||||
KeyF15: "\x1b[28~",
|
||||
KeyF16: "\x1b[29~",
|
||||
KeyF17: "\x1b[31~",
|
||||
KeyF18: "\x1b[32~",
|
||||
KeyF19: "\x1b[33~",
|
||||
KeyF20: "\x1b[34~",
|
||||
KeyF21: "\x1b[23$",
|
||||
KeyF22: "\x1b[24$",
|
||||
KeyF23: "\x1b[11^",
|
||||
KeyF24: "\x1b[12^",
|
||||
KeyF25: "\x1b[13^",
|
||||
KeyF26: "\x1b[14^",
|
||||
KeyF27: "\x1b[15^",
|
||||
KeyF28: "\x1b[17^",
|
||||
KeyF29: "\x1b[18^",
|
||||
KeyF30: "\x1b[19^",
|
||||
KeyF31: "\x1b[20^",
|
||||
KeyF32: "\x1b[21^",
|
||||
KeyF33: "\x1b[23^",
|
||||
KeyF34: "\x1b[24^",
|
||||
KeyF35: "\x1b[25^",
|
||||
KeyF36: "\x1b[26^",
|
||||
KeyF37: "\x1b[28^",
|
||||
KeyF38: "\x1b[29^",
|
||||
KeyF39: "\x1b[31^",
|
||||
KeyF40: "\x1b[32^",
|
||||
KeyF41: "\x1b[33^",
|
||||
KeyF42: "\x1b[34^",
|
||||
KeyF43: "\x1b[23@",
|
||||
KeyF44: "\x1b[24@",
|
||||
KeyBacktab: "\x1b[Z",
|
||||
KeyShfLeft: "\x1b[d",
|
||||
KeyShfRight: "\x1b[c",
|
||||
KeyShfUp: "\x1b[a",
|
||||
KeyShfDown: "\x1b[b",
|
||||
KeyCtrlLeft: "\x1b[Od",
|
||||
KeyCtrlRight: "\x1b[Oc",
|
||||
KeyCtrlUp: "\x1b[Oa",
|
||||
KeyCtrlDown: "\x1b[Ob",
|
||||
KeyShfHome: "\x1b[7$",
|
||||
KeyShfEnd: "\x1b[8$",
|
||||
KeyCtrlHome: "\x1b[7^",
|
||||
KeyCtrlEnd: "\x1b[8^",
|
||||
})
|
||||
}
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
// Generated automatically. DO NOT HAND-EDIT.
|
||||
|
||||
package beterm
|
||||
|
||||
import "github.com/gdamore/tcell/terminfo"
|
||||
|
||||
func init() {
|
||||
|
||||
// BeOS Terminal
|
||||
terminfo.AddTerminfo(&terminfo.Terminfo{
|
||||
Name: "beterm",
|
||||
Columns: 80,
|
||||
Lines: 25,
|
||||
Colors: 8,
|
||||
Bell: "\a",
|
||||
Clear: "\x1b[H\x1b[J",
|
||||
AttrOff: "\x1b[0;10m",
|
||||
Underline: "\x1b[4m",
|
||||
Bold: "\x1b[1m",
|
||||
Reverse: "\x1b[7m",
|
||||
EnterKeypad: "\x1b[?4h",
|
||||
ExitKeypad: "\x1b[?4l",
|
||||
SetFg: "\x1b[3%p1%dm",
|
||||
SetBg: "\x1b[4%p1%dm",
|
||||
SetFgBg: "\x1b[3%p1%d;4%p2%dm",
|
||||
PadChar: "\x00",
|
||||
SetCursor: "\x1b[%i%p1%d;%p2%dH",
|
||||
CursorBack1: "\b",
|
||||
CursorUp1: "\x1b[A",
|
||||
KeyUp: "\x1b[A",
|
||||
KeyDown: "\x1b[B",
|
||||
KeyRight: "\x1b[C",
|
||||
KeyLeft: "\x1b[D",
|
||||
KeyInsert: "\x1b[2~",
|
||||
KeyDelete: "\x1b[3~",
|
||||
KeyBackspace: "\b",
|
||||
KeyHome: "\x1b[1~",
|
||||
KeyEnd: "\x1b[4~",
|
||||
KeyPgUp: "\x1b[5~",
|
||||
KeyPgDn: "\x1b[6~",
|
||||
KeyF1: "\x1b[11~",
|
||||
KeyF2: "\x1b[12~",
|
||||
KeyF3: "\x1b[13~",
|
||||
KeyF4: "\x1b[14~",
|
||||
KeyF5: "\x1b[15~",
|
||||
KeyF6: "\x1b[16~",
|
||||
KeyF7: "\x1b[17~",
|
||||
KeyF8: "\x1b[18~",
|
||||
KeyF9: "\x1b[19~",
|
||||
KeyF10: "\x1b[20~",
|
||||
KeyF11: "\x1b[21~",
|
||||
KeyF12: "\x1b[22~",
|
||||
})
|
||||
}
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
// Generated automatically. DO NOT HAND-EDIT.
|
||||
|
||||
package bsdos_pc
|
||||
|
||||
import "github.com/gdamore/tcell/terminfo"
|
||||
|
||||
func init() {
|
||||
|
||||
// IBM PC BSD/OS Console
|
||||
terminfo.AddTerminfo(&terminfo.Terminfo{
|
||||
Name: "bsdos-pc",
|
||||
Columns: 80,
|
||||
Lines: 25,
|
||||
Colors: 8,
|
||||
Bell: "\a",
|
||||
Clear: "\x1bc",
|
||||
AttrOff: "\x1b[0;10m",
|
||||
Underline: "\x1b[4m",
|
||||
Bold: "\x1b[1m",
|
||||
Blink: "\x1b[5m",
|
||||
Reverse: "\x1b[7m",
|
||||
SetFg: "\x1b[3%p1%dm",
|
||||
SetBg: "\x1b[4%p1%dm",
|
||||
SetFgBg: "\x1b[3%p1%d;4%p2%dm",
|
||||
PadChar: "\x00",
|
||||
AltChars: "+\x10,\x11-\x18.\x190\xdb`\x04a\xb1f\xf8g\xf1h\xb0j\xd9k\xbfl\xdam\xc0n\xc5o~p\xc4q\xc4r\xc4s_t\xc3u\xb4v\xc1w\xc2x\xb3y\xf3z\xf2{\xe3|\xd8}\x9c~\xfe",
|
||||
EnterAcs: "\x1b[11m",
|
||||
ExitAcs: "\x1b[10m",
|
||||
SetCursor: "\x1b[%i%p1%d;%p2%dH",
|
||||
CursorBack1: "\b",
|
||||
CursorUp1: "\x1b[A",
|
||||
KeyUp: "\x1b[A",
|
||||
KeyDown: "\x1b[B",
|
||||
KeyRight: "\x1b[C",
|
||||
KeyLeft: "\x1b[D",
|
||||
KeyInsert: "\x1b[L",
|
||||
KeyBackspace: "\b",
|
||||
KeyHome: "\x1b[H",
|
||||
KeyPgUp: "\x1b[I",
|
||||
KeyPgDn: "\x1b[G",
|
||||
})
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
// Copyright 2019 The TCell Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use file except in compliance with the License.
|
||||
// You may obtain a copy of the license at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// This is just a "minimalist" set of the base terminal descriptions.
|
||||
// It should be sufficient for most applications.
|
||||
|
||||
// Package base contains the base terminal descriptions that are likely
|
||||
// to be needed by any stock application. It is imported by default in the
|
||||
// terminfo package, so terminal types listed here will be available to any
|
||||
// tcell application.
|
||||
package base
|
||||
|
||||
import (
|
||||
// The following imports just register themselves --
|
||||
// thse are the terminal types we aggregate in this package.
|
||||
_ "github.com/gdamore/tcell/terminfo/a/ansi"
|
||||
_ "github.com/gdamore/tcell/terminfo/v/vt100"
|
||||
_ "github.com/gdamore/tcell/terminfo/v/vt102"
|
||||
_ "github.com/gdamore/tcell/terminfo/v/vt220"
|
||||
_ "github.com/gdamore/tcell/terminfo/x/xterm"
|
||||
)
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
// Generated automatically. DO NOT HAND-EDIT.
|
||||
|
||||
package cygwin
|
||||
|
||||
import "github.com/gdamore/tcell/terminfo"
|
||||
|
||||
func init() {
|
||||
|
||||
// ansi emulation for Cygwin
|
||||
terminfo.AddTerminfo(&terminfo.Terminfo{
|
||||
Name: "cygwin",
|
||||
Colors: 8,
|
||||
Bell: "\a",
|
||||
Clear: "\x1b[H\x1b[J",
|
||||
EnterCA: "\x1b7\x1b[?47h",
|
||||
ExitCA: "\x1b[2J\x1b[?47l\x1b8",
|
||||
AttrOff: "\x1b[0;10m",
|
||||
Underline: "\x1b[4m",
|
||||
Bold: "\x1b[1m",
|
||||
Reverse: "\x1b[7m",
|
||||
SetFg: "\x1b[3%p1%dm",
|
||||
SetBg: "\x1b[4%p1%dm",
|
||||
SetFgBg: "\x1b[3%p1%d;4%p2%dm",
|
||||
PadChar: "\x00",
|
||||
AltChars: "+\x10,\x11-\x18.\x190\xdb`\x04a\xb1f\xf8g\xf1h\xb0j\xd9k\xbfl\xdam\xc0n\xc5o~p\xc4q\xc4r\xc4s_t\xc3u\xb4v\xc1w\xc2x\xb3y\xf3z\xf2{\xe3|\xd8}\x9c~\xfe",
|
||||
EnterAcs: "\x1b[11m",
|
||||
ExitAcs: "\x1b[10m",
|
||||
SetCursor: "\x1b[%i%p1%d;%p2%dH",
|
||||
CursorBack1: "\b",
|
||||
CursorUp1: "\x1b[A",
|
||||
KeyUp: "\x1b[A",
|
||||
KeyDown: "\x1b[B",
|
||||
KeyRight: "\x1b[C",
|
||||
KeyLeft: "\x1b[D",
|
||||
KeyInsert: "\x1b[2~",
|
||||
KeyDelete: "\x1b[3~",
|
||||
KeyBackspace: "\b",
|
||||
KeyHome: "\x1b[1~",
|
||||
KeyEnd: "\x1b[4~",
|
||||
KeyPgUp: "\x1b[5~",
|
||||
KeyPgDn: "\x1b[6~",
|
||||
KeyF1: "\x1b[[A",
|
||||
KeyF2: "\x1b[[B",
|
||||
KeyF3: "\x1b[[C",
|
||||
KeyF4: "\x1b[[D",
|
||||
KeyF5: "\x1b[[E",
|
||||
KeyF6: "\x1b[17~",
|
||||
KeyF7: "\x1b[18~",
|
||||
KeyF8: "\x1b[19~",
|
||||
KeyF9: "\x1b[20~",
|
||||
KeyF10: "\x1b[21~",
|
||||
KeyF11: "\x1b[23~",
|
||||
KeyF12: "\x1b[24~",
|
||||
KeyF13: "\x1b[25~",
|
||||
KeyF14: "\x1b[26~",
|
||||
KeyF15: "\x1b[28~",
|
||||
KeyF16: "\x1b[29~",
|
||||
KeyF17: "\x1b[31~",
|
||||
KeyF18: "\x1b[32~",
|
||||
KeyF19: "\x1b[33~",
|
||||
KeyF20: "\x1b[34~",
|
||||
})
|
||||
}
|
||||
+97
@@ -0,0 +1,97 @@
|
||||
// Generated automatically. DO NOT HAND-EDIT.
|
||||
|
||||
package d200
|
||||
|
||||
import "github.com/gdamore/tcell/terminfo"
|
||||
|
||||
func init() {
|
||||
|
||||
// Data General DASHER D200
|
||||
terminfo.AddTerminfo(&terminfo.Terminfo{
|
||||
Name: "d200",
|
||||
Aliases: []string{"d200-dg"},
|
||||
Columns: 80,
|
||||
Lines: 24,
|
||||
Bell: "\a",
|
||||
Clear: "\f",
|
||||
AttrOff: "\x0f\x15\x1d\x1eE",
|
||||
Underline: "\x14",
|
||||
Bold: "\x1eD\x14",
|
||||
Dim: "\x1c",
|
||||
Blink: "\x0e",
|
||||
Reverse: "\x1eD",
|
||||
PadChar: "\x00",
|
||||
SetCursor: "\x10%p2%c%p1%c",
|
||||
CursorBack1: "\x19",
|
||||
CursorUp1: "\x17",
|
||||
KeyUp: "\x17",
|
||||
KeyDown: "\x1a",
|
||||
KeyRight: "\x18",
|
||||
KeyLeft: "\x19",
|
||||
KeyHome: "\b",
|
||||
KeyF1: "\x1eq",
|
||||
KeyF2: "\x1er",
|
||||
KeyF3: "\x1es",
|
||||
KeyF4: "\x1et",
|
||||
KeyF5: "\x1eu",
|
||||
KeyF6: "\x1ev",
|
||||
KeyF7: "\x1ew",
|
||||
KeyF8: "\x1ex",
|
||||
KeyF9: "\x1ey",
|
||||
KeyF10: "\x1ez",
|
||||
KeyF11: "\x1e{",
|
||||
KeyF12: "\x1e|",
|
||||
KeyF13: "\x1e}",
|
||||
KeyF14: "\x1e~",
|
||||
KeyF15: "\x1ep",
|
||||
KeyF16: "\x1ea",
|
||||
KeyF17: "\x1eb",
|
||||
KeyF18: "\x1ec",
|
||||
KeyF19: "\x1ed",
|
||||
KeyF20: "\x1ee",
|
||||
KeyF21: "\x1ef",
|
||||
KeyF22: "\x1eg",
|
||||
KeyF23: "\x1eh",
|
||||
KeyF24: "\x1ei",
|
||||
KeyF25: "\x1ej",
|
||||
KeyF26: "\x1ek",
|
||||
KeyF27: "\x1el",
|
||||
KeyF28: "\x1em",
|
||||
KeyF29: "\x1en",
|
||||
KeyF30: "\x1e`",
|
||||
KeyF31: "\x1e1",
|
||||
KeyF32: "\x1e2",
|
||||
KeyF33: "\x1e3",
|
||||
KeyF34: "\x1e4",
|
||||
KeyF35: "\x1e5",
|
||||
KeyF36: "\x1e6",
|
||||
KeyF37: "\x1e7",
|
||||
KeyF38: "\x1e8",
|
||||
KeyF39: "\x1e9",
|
||||
KeyF40: "\x1e:",
|
||||
KeyF41: "\x1e;",
|
||||
KeyF42: "\x1e<",
|
||||
KeyF43: "\x1e=",
|
||||
KeyF44: "\x1e>",
|
||||
KeyF45: "\x1e0",
|
||||
KeyF46: "\x1e!",
|
||||
KeyF47: "\x1e\"",
|
||||
KeyF48: "\x1e#",
|
||||
KeyF49: "\x1e$",
|
||||
KeyF50: "\x1e%%",
|
||||
KeyF51: "\x1e&",
|
||||
KeyF52: "\x1e'",
|
||||
KeyF53: "\x1e(",
|
||||
KeyF54: "\x1e)",
|
||||
KeyF55: "\x1e*",
|
||||
KeyF56: "\x1e+",
|
||||
KeyF57: "\x1e,",
|
||||
KeyF58: "\x1e-",
|
||||
KeyF59: "\x1e.",
|
||||
KeyF60: "\x1e ",
|
||||
KeyClear: "\f",
|
||||
KeyShfLeft: "\x1e\x19",
|
||||
KeyShfRight: "\x1e\x18",
|
||||
KeyShfHome: "\x1e\b",
|
||||
})
|
||||
}
|
||||
+95
@@ -0,0 +1,95 @@
|
||||
// Generated automatically. DO NOT HAND-EDIT.
|
||||
|
||||
package d210
|
||||
|
||||
import "github.com/gdamore/tcell/terminfo"
|
||||
|
||||
func init() {
|
||||
|
||||
// Data General DASHER D210 series
|
||||
terminfo.AddTerminfo(&terminfo.Terminfo{
|
||||
Name: "d210",
|
||||
Aliases: []string{"d214"},
|
||||
Columns: 80,
|
||||
Lines: 24,
|
||||
Bell: "\a",
|
||||
Clear: "\x1b[2J",
|
||||
AttrOff: "\x1b[m",
|
||||
Underline: "\x1b[4m",
|
||||
Bold: "\x1b[4;7m",
|
||||
Dim: "\x1b[2m",
|
||||
Blink: "\x1b[5m",
|
||||
Reverse: "\x1b[7m",
|
||||
PadChar: "\x00",
|
||||
SetCursor: "\x1b[%i%p1%d;%p2%dH",
|
||||
CursorBack1: "\b",
|
||||
CursorUp1: "\x1b[A",
|
||||
KeyUp: "\x1b[A",
|
||||
KeyDown: "\x1b[B",
|
||||
KeyRight: "\x1b[C",
|
||||
KeyLeft: "\x1b[D",
|
||||
KeyHome: "\x1b[H",
|
||||
KeyF1: "\x1b[001z",
|
||||
KeyF2: "\x1b[002z",
|
||||
KeyF3: "\x1b[003z",
|
||||
KeyF4: "\x1b[004z",
|
||||
KeyF5: "\x1b[005z",
|
||||
KeyF6: "\x1b[006z",
|
||||
KeyF7: "\x1b[007z",
|
||||
KeyF8: "\x1b[008z",
|
||||
KeyF9: "\x1b[009z",
|
||||
KeyF10: "\x1b[010z",
|
||||
KeyF11: "\x1b[011z",
|
||||
KeyF12: "\x1b[012z",
|
||||
KeyF13: "\x1b[013z",
|
||||
KeyF14: "\x1b[014z",
|
||||
KeyF15: "\x1b[000z",
|
||||
KeyF16: "\x1b[101z",
|
||||
KeyF17: "\x1b[102z",
|
||||
KeyF18: "\x1b[103z",
|
||||
KeyF19: "\x1b[104z",
|
||||
KeyF20: "\x1b[105z",
|
||||
KeyF21: "\x1b[106z",
|
||||
KeyF22: "\x1b[107z",
|
||||
KeyF23: "\x1b[108z",
|
||||
KeyF24: "\x1b[109z",
|
||||
KeyF25: "\x1b[110z",
|
||||
KeyF26: "\x1b[111z",
|
||||
KeyF27: "\x1b[112z",
|
||||
KeyF28: "\x1b[113z",
|
||||
KeyF29: "\x1b[114z",
|
||||
KeyF30: "\x1b[100z",
|
||||
KeyF31: "\x1b[201z",
|
||||
KeyF32: "\x1b[202z",
|
||||
KeyF33: "\x1b[203z",
|
||||
KeyF34: "\x1b[204z",
|
||||
KeyF35: "\x1b[205z",
|
||||
KeyF36: "\x1b[206z",
|
||||
KeyF37: "\x1b[207z",
|
||||
KeyF38: "\x1b[208z",
|
||||
KeyF39: "\x1b[209z",
|
||||
KeyF40: "\x1b[210z",
|
||||
KeyF41: "\x1b[211z",
|
||||
KeyF42: "\x1b[212z",
|
||||
KeyF43: "\x1b[213z",
|
||||
KeyF44: "\x1b[214z",
|
||||
KeyF45: "\x1b[200z",
|
||||
KeyF46: "\x1b[301z",
|
||||
KeyF47: "\x1b[302z",
|
||||
KeyF48: "\x1b[303z",
|
||||
KeyF49: "\x1b[304z",
|
||||
KeyF50: "\x1b[305z",
|
||||
KeyF51: "\x1b[306z",
|
||||
KeyF52: "\x1b[307z",
|
||||
KeyF53: "\x1b[308z",
|
||||
KeyF54: "\x1b[309z",
|
||||
KeyF55: "\x1b[310z",
|
||||
KeyF56: "\x1b[311z",
|
||||
KeyF57: "\x1b[312z",
|
||||
KeyF58: "\x1b[313z",
|
||||
KeyF59: "\x1b[314z",
|
||||
KeyF60: "\x1b[300z",
|
||||
KeyPrint: "\x1b[i",
|
||||
KeyClear: "\x1b[2J",
|
||||
})
|
||||
}
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
// Generated automatically. DO NOT HAND-EDIT.
|
||||
|
||||
package dtterm
|
||||
|
||||
import "github.com/gdamore/tcell/terminfo"
|
||||
|
||||
func init() {
|
||||
|
||||
// CDE desktop terminal
|
||||
terminfo.AddTerminfo(&terminfo.Terminfo{
|
||||
Name: "dtterm",
|
||||
Columns: 80,
|
||||
Lines: 24,
|
||||
Colors: 8,
|
||||
Bell: "\a",
|
||||
Clear: "\x1b[H\x1b[J",
|
||||
ShowCursor: "\x1b[?25h",
|
||||
HideCursor: "\x1b[?25l",
|
||||
AttrOff: "\x1b[m\x0f",
|
||||
Underline: "\x1b[4m",
|
||||
Bold: "\x1b[1m",
|
||||
Dim: "\x1b[2m",
|
||||
Blink: "\x1b[5m",
|
||||
Reverse: "\x1b[7m",
|
||||
SetFg: "\x1b[3%p1%dm",
|
||||
SetBg: "\x1b[4%p1%dm",
|
||||
SetFgBg: "\x1b[3%p1%d;4%p2%dm",
|
||||
PadChar: "\x00",
|
||||
AltChars: "``aaffggjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~",
|
||||
EnterAcs: "\x0e",
|
||||
ExitAcs: "\x0f",
|
||||
EnableAcs: "\x1b(B\x1b)0",
|
||||
SetCursor: "\x1b[%i%p1%d;%p2%dH",
|
||||
CursorBack1: "\b",
|
||||
CursorUp1: "\x1b[A",
|
||||
KeyUp: "\x1b[A",
|
||||
KeyDown: "\x1b[B",
|
||||
KeyRight: "\x1b[C",
|
||||
KeyLeft: "\x1b[D",
|
||||
KeyInsert: "\x1b[2~",
|
||||
KeyDelete: "\x1b[3~",
|
||||
KeyBackspace: "\b",
|
||||
KeyPgUp: "\x1b[5~",
|
||||
KeyPgDn: "\x1b[6~",
|
||||
KeyF1: "\x1b[11~",
|
||||
KeyF2: "\x1b[12~",
|
||||
KeyF3: "\x1b[13~",
|
||||
KeyF4: "\x1b[14~",
|
||||
KeyF5: "\x1b[15~",
|
||||
KeyF6: "\x1b[17~",
|
||||
KeyF7: "\x1b[18~",
|
||||
KeyF8: "\x1b[19~",
|
||||
KeyF9: "\x1b[20~",
|
||||
KeyF10: "\x1b[21~",
|
||||
KeyF11: "\x1b[23~",
|
||||
KeyF12: "\x1b[24~",
|
||||
KeyF13: "\x1b[25~",
|
||||
KeyF14: "\x1b[26~",
|
||||
KeyF15: "\x1b[28~",
|
||||
KeyF16: "\x1b[29~",
|
||||
KeyF17: "\x1b[31~",
|
||||
KeyF18: "\x1b[32~",
|
||||
KeyF19: "\x1b[33~",
|
||||
KeyF20: "\x1b[34~",
|
||||
KeyHelp: "\x1b[28~",
|
||||
})
|
||||
}
|
||||
+425
@@ -0,0 +1,425 @@
|
||||
// Copyright 2019 The TCell Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use file except in compliance with the License.
|
||||
// You may obtain a copy of the license at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// The dynamic package is used to generate a terminal description dynamically,
|
||||
// using infocmp. This is really a method of last resort, as the performance
|
||||
// will be slow, and it requires a working infocmp. But, the hope is that it
|
||||
// will assist folks who have to deal with a terminal description that isn't
|
||||
// already built in. This requires infocmp to be in the user's path, and to
|
||||
// support reasonably the -1 option.
|
||||
|
||||
package dynamic
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"os/exec"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/gdamore/tcell/terminfo"
|
||||
)
|
||||
|
||||
type termcap struct {
|
||||
name string
|
||||
desc string
|
||||
aliases []string
|
||||
bools map[string]bool
|
||||
nums map[string]int
|
||||
strs map[string]string
|
||||
}
|
||||
|
||||
func (tc *termcap) getnum(s string) int {
|
||||
return (tc.nums[s])
|
||||
}
|
||||
|
||||
func (tc *termcap) getflag(s string) bool {
|
||||
return (tc.bools[s])
|
||||
}
|
||||
|
||||
func (tc *termcap) getstr(s string) string {
|
||||
return (tc.strs[s])
|
||||
}
|
||||
|
||||
const (
|
||||
none = iota
|
||||
control
|
||||
escaped
|
||||
)
|
||||
|
||||
var errNotAddressable = errors.New("terminal not cursor addressable")
|
||||
|
||||
func unescape(s string) string {
|
||||
// Various escapes are in \x format. Control codes are
|
||||
// encoded as ^M (carat followed by ASCII equivalent).
|
||||
// escapes are: \e, \E - escape
|
||||
// \0 NULL, \n \l \r \t \b \f \s for equivalent C escape.
|
||||
buf := &bytes.Buffer{}
|
||||
esc := none
|
||||
|
||||
for i := 0; i < len(s); i++ {
|
||||
c := s[i]
|
||||
switch esc {
|
||||
case none:
|
||||
switch c {
|
||||
case '\\':
|
||||
esc = escaped
|
||||
case '^':
|
||||
esc = control
|
||||
default:
|
||||
buf.WriteByte(c)
|
||||
}
|
||||
case control:
|
||||
buf.WriteByte(c - 0x40)
|
||||
esc = none
|
||||
case escaped:
|
||||
switch c {
|
||||
case 'E', 'e':
|
||||
buf.WriteByte(0x1b)
|
||||
case '0', '1', '2', '3', '4', '5', '6', '7':
|
||||
if i+2 < len(s) && s[i+1] >= '0' && s[i+1] <= '7' && s[i+2] >= '0' && s[i+2] <= '7' {
|
||||
buf.WriteByte(((c - '0') * 64) + ((s[i+1] - '0') * 8) + (s[i+2] - '0'))
|
||||
i = i + 2
|
||||
} else if c == '0' {
|
||||
buf.WriteByte(0)
|
||||
}
|
||||
case 'n':
|
||||
buf.WriteByte('\n')
|
||||
case 'r':
|
||||
buf.WriteByte('\r')
|
||||
case 't':
|
||||
buf.WriteByte('\t')
|
||||
case 'b':
|
||||
buf.WriteByte('\b')
|
||||
case 'f':
|
||||
buf.WriteByte('\f')
|
||||
case 's':
|
||||
buf.WriteByte(' ')
|
||||
default:
|
||||
buf.WriteByte(c)
|
||||
}
|
||||
esc = none
|
||||
}
|
||||
}
|
||||
return (buf.String())
|
||||
}
|
||||
|
||||
func (tc *termcap) setupterm(name string) error {
|
||||
cmd := exec.Command("infocmp", "-1", name)
|
||||
output := &bytes.Buffer{}
|
||||
cmd.Stdout = output
|
||||
|
||||
tc.strs = make(map[string]string)
|
||||
tc.bools = make(map[string]bool)
|
||||
tc.nums = make(map[string]int)
|
||||
|
||||
if err := cmd.Run(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Now parse the output.
|
||||
// We get comment lines (starting with "#"), followed by
|
||||
// a header line that looks like "<name>|<alias>|...|<desc>"
|
||||
// then capabilities, one per line, starting with a tab and ending
|
||||
// with a comma and newline.
|
||||
lines := strings.Split(output.String(), "\n")
|
||||
for len(lines) > 0 && strings.HasPrefix(lines[0], "#") {
|
||||
lines = lines[1:]
|
||||
}
|
||||
|
||||
// Ditch trailing empty last line
|
||||
if lines[len(lines)-1] == "" {
|
||||
lines = lines[:len(lines)-1]
|
||||
}
|
||||
header := lines[0]
|
||||
if strings.HasSuffix(header, ",") {
|
||||
header = header[:len(header)-1]
|
||||
}
|
||||
names := strings.Split(header, "|")
|
||||
tc.name = names[0]
|
||||
names = names[1:]
|
||||
if len(names) > 0 {
|
||||
tc.desc = names[len(names)-1]
|
||||
names = names[:len(names)-1]
|
||||
}
|
||||
tc.aliases = names
|
||||
for _, val := range lines[1:] {
|
||||
if (!strings.HasPrefix(val, "\t")) ||
|
||||
(!strings.HasSuffix(val, ",")) {
|
||||
return (errors.New("malformed infocmp: " + val))
|
||||
}
|
||||
|
||||
val = val[1:]
|
||||
val = val[:len(val)-1]
|
||||
|
||||
if k := strings.SplitN(val, "=", 2); len(k) == 2 {
|
||||
tc.strs[k[0]] = unescape(k[1])
|
||||
} else if k := strings.SplitN(val, "#", 2); len(k) == 2 {
|
||||
u, err := strconv.ParseUint(k[1], 0, 0)
|
||||
if err != nil {
|
||||
return (err)
|
||||
}
|
||||
tc.nums[k[0]] = int(u)
|
||||
} else {
|
||||
tc.bools[val] = true
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// LoadTerminfo creates a Terminfo by for named terminal by attempting to parse
|
||||
// the output from infocmp. This returns the terminfo entry, a description of
|
||||
// the terminal, and either nil or an error.
|
||||
func LoadTerminfo(name string) (*terminfo.Terminfo, string, error) {
|
||||
var tc termcap
|
||||
if err := tc.setupterm(name); err != nil {
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
}
|
||||
t := &terminfo.Terminfo{}
|
||||
// If this is an alias record, then just emit the alias
|
||||
t.Name = tc.name
|
||||
if t.Name != name {
|
||||
return t, "", nil
|
||||
}
|
||||
t.Aliases = tc.aliases
|
||||
t.Colors = tc.getnum("colors")
|
||||
t.Columns = tc.getnum("cols")
|
||||
t.Lines = tc.getnum("lines")
|
||||
t.Bell = tc.getstr("bel")
|
||||
t.Clear = tc.getstr("clear")
|
||||
t.EnterCA = tc.getstr("smcup")
|
||||
t.ExitCA = tc.getstr("rmcup")
|
||||
t.ShowCursor = tc.getstr("cnorm")
|
||||
t.HideCursor = tc.getstr("civis")
|
||||
t.AttrOff = tc.getstr("sgr0")
|
||||
t.Underline = tc.getstr("smul")
|
||||
t.Bold = tc.getstr("bold")
|
||||
t.Blink = tc.getstr("blink")
|
||||
t.Dim = tc.getstr("dim")
|
||||
t.Reverse = tc.getstr("rev")
|
||||
t.EnterKeypad = tc.getstr("smkx")
|
||||
t.ExitKeypad = tc.getstr("rmkx")
|
||||
t.SetFg = tc.getstr("setaf")
|
||||
t.SetBg = tc.getstr("setab")
|
||||
t.SetCursor = tc.getstr("cup")
|
||||
t.CursorBack1 = tc.getstr("cub1")
|
||||
t.CursorUp1 = tc.getstr("cuu1")
|
||||
t.KeyF1 = tc.getstr("kf1")
|
||||
t.KeyF2 = tc.getstr("kf2")
|
||||
t.KeyF3 = tc.getstr("kf3")
|
||||
t.KeyF4 = tc.getstr("kf4")
|
||||
t.KeyF5 = tc.getstr("kf5")
|
||||
t.KeyF6 = tc.getstr("kf6")
|
||||
t.KeyF7 = tc.getstr("kf7")
|
||||
t.KeyF8 = tc.getstr("kf8")
|
||||
t.KeyF9 = tc.getstr("kf9")
|
||||
t.KeyF10 = tc.getstr("kf10")
|
||||
t.KeyF11 = tc.getstr("kf11")
|
||||
t.KeyF12 = tc.getstr("kf12")
|
||||
t.KeyF13 = tc.getstr("kf13")
|
||||
t.KeyF14 = tc.getstr("kf14")
|
||||
t.KeyF15 = tc.getstr("kf15")
|
||||
t.KeyF16 = tc.getstr("kf16")
|
||||
t.KeyF17 = tc.getstr("kf17")
|
||||
t.KeyF18 = tc.getstr("kf18")
|
||||
t.KeyF19 = tc.getstr("kf19")
|
||||
t.KeyF20 = tc.getstr("kf20")
|
||||
t.KeyF21 = tc.getstr("kf21")
|
||||
t.KeyF22 = tc.getstr("kf22")
|
||||
t.KeyF23 = tc.getstr("kf23")
|
||||
t.KeyF24 = tc.getstr("kf24")
|
||||
t.KeyF25 = tc.getstr("kf25")
|
||||
t.KeyF26 = tc.getstr("kf26")
|
||||
t.KeyF27 = tc.getstr("kf27")
|
||||
t.KeyF28 = tc.getstr("kf28")
|
||||
t.KeyF29 = tc.getstr("kf29")
|
||||
t.KeyF30 = tc.getstr("kf30")
|
||||
t.KeyF31 = tc.getstr("kf31")
|
||||
t.KeyF32 = tc.getstr("kf32")
|
||||
t.KeyF33 = tc.getstr("kf33")
|
||||
t.KeyF34 = tc.getstr("kf34")
|
||||
t.KeyF35 = tc.getstr("kf35")
|
||||
t.KeyF36 = tc.getstr("kf36")
|
||||
t.KeyF37 = tc.getstr("kf37")
|
||||
t.KeyF38 = tc.getstr("kf38")
|
||||
t.KeyF39 = tc.getstr("kf39")
|
||||
t.KeyF40 = tc.getstr("kf40")
|
||||
t.KeyF41 = tc.getstr("kf41")
|
||||
t.KeyF42 = tc.getstr("kf42")
|
||||
t.KeyF43 = tc.getstr("kf43")
|
||||
t.KeyF44 = tc.getstr("kf44")
|
||||
t.KeyF45 = tc.getstr("kf45")
|
||||
t.KeyF46 = tc.getstr("kf46")
|
||||
t.KeyF47 = tc.getstr("kf47")
|
||||
t.KeyF48 = tc.getstr("kf48")
|
||||
t.KeyF49 = tc.getstr("kf49")
|
||||
t.KeyF50 = tc.getstr("kf50")
|
||||
t.KeyF51 = tc.getstr("kf51")
|
||||
t.KeyF52 = tc.getstr("kf52")
|
||||
t.KeyF53 = tc.getstr("kf53")
|
||||
t.KeyF54 = tc.getstr("kf54")
|
||||
t.KeyF55 = tc.getstr("kf55")
|
||||
t.KeyF56 = tc.getstr("kf56")
|
||||
t.KeyF57 = tc.getstr("kf57")
|
||||
t.KeyF58 = tc.getstr("kf58")
|
||||
t.KeyF59 = tc.getstr("kf59")
|
||||
t.KeyF60 = tc.getstr("kf60")
|
||||
t.KeyF61 = tc.getstr("kf61")
|
||||
t.KeyF62 = tc.getstr("kf62")
|
||||
t.KeyF63 = tc.getstr("kf63")
|
||||
t.KeyF64 = tc.getstr("kf64")
|
||||
t.KeyInsert = tc.getstr("kich1")
|
||||
t.KeyDelete = tc.getstr("kdch1")
|
||||
t.KeyBackspace = tc.getstr("kbs")
|
||||
t.KeyHome = tc.getstr("khome")
|
||||
t.KeyEnd = tc.getstr("kend")
|
||||
t.KeyUp = tc.getstr("kcuu1")
|
||||
t.KeyDown = tc.getstr("kcud1")
|
||||
t.KeyRight = tc.getstr("kcuf1")
|
||||
t.KeyLeft = tc.getstr("kcub1")
|
||||
t.KeyPgDn = tc.getstr("knp")
|
||||
t.KeyPgUp = tc.getstr("kpp")
|
||||
t.KeyBacktab = tc.getstr("kcbt")
|
||||
t.KeyExit = tc.getstr("kext")
|
||||
t.KeyCancel = tc.getstr("kcan")
|
||||
t.KeyPrint = tc.getstr("kprt")
|
||||
t.KeyHelp = tc.getstr("khlp")
|
||||
t.KeyClear = tc.getstr("kclr")
|
||||
t.AltChars = tc.getstr("acsc")
|
||||
t.EnterAcs = tc.getstr("smacs")
|
||||
t.ExitAcs = tc.getstr("rmacs")
|
||||
t.EnableAcs = tc.getstr("enacs")
|
||||
t.Mouse = tc.getstr("kmous")
|
||||
t.KeyShfRight = tc.getstr("kRIT")
|
||||
t.KeyShfLeft = tc.getstr("kLFT")
|
||||
t.KeyShfHome = tc.getstr("kHOM")
|
||||
t.KeyShfEnd = tc.getstr("kEND")
|
||||
|
||||
// Terminfo lacks descriptions for a bunch of modified keys,
|
||||
// but modern XTerm and emulators often have them. Let's add them,
|
||||
// if the shifted right and left arrows are defined.
|
||||
if t.KeyShfRight == "\x1b[1;2C" && t.KeyShfLeft == "\x1b[1;2D" {
|
||||
t.KeyShfUp = "\x1b[1;2A"
|
||||
t.KeyShfDown = "\x1b[1;2B"
|
||||
t.KeyMetaUp = "\x1b[1;9A"
|
||||
t.KeyMetaDown = "\x1b[1;9B"
|
||||
t.KeyMetaRight = "\x1b[1;9C"
|
||||
t.KeyMetaLeft = "\x1b[1;9D"
|
||||
t.KeyAltUp = "\x1b[1;3A"
|
||||
t.KeyAltDown = "\x1b[1;3B"
|
||||
t.KeyAltRight = "\x1b[1;3C"
|
||||
t.KeyAltLeft = "\x1b[1;3D"
|
||||
t.KeyCtrlUp = "\x1b[1;5A"
|
||||
t.KeyCtrlDown = "\x1b[1;5B"
|
||||
t.KeyCtrlRight = "\x1b[1;5C"
|
||||
t.KeyCtrlLeft = "\x1b[1;5D"
|
||||
t.KeyAltShfUp = "\x1b[1;4A"
|
||||
t.KeyAltShfDown = "\x1b[1;4B"
|
||||
t.KeyAltShfRight = "\x1b[1;4C"
|
||||
t.KeyAltShfLeft = "\x1b[1;4D"
|
||||
|
||||
t.KeyMetaShfUp = "\x1b[1;10A"
|
||||
t.KeyMetaShfDown = "\x1b[1;10B"
|
||||
t.KeyMetaShfRight = "\x1b[1;10C"
|
||||
t.KeyMetaShfLeft = "\x1b[1;10D"
|
||||
|
||||
t.KeyCtrlShfUp = "\x1b[1;6A"
|
||||
t.KeyCtrlShfDown = "\x1b[1;6B"
|
||||
t.KeyCtrlShfRight = "\x1b[1;6C"
|
||||
t.KeyCtrlShfLeft = "\x1b[1;6D"
|
||||
}
|
||||
// And also for Home and End
|
||||
if t.KeyShfHome == "\x1b[1;2H" && t.KeyShfEnd == "\x1b[1;2F" {
|
||||
t.KeyCtrlHome = "\x1b[1;5H"
|
||||
t.KeyCtrlEnd = "\x1b[1;5F"
|
||||
t.KeyAltHome = "\x1b[1;9H"
|
||||
t.KeyAltEnd = "\x1b[1;9F"
|
||||
t.KeyCtrlShfHome = "\x1b[1;6H"
|
||||
t.KeyCtrlShfEnd = "\x1b[1;6F"
|
||||
t.KeyAltShfHome = "\x1b[1;4H"
|
||||
t.KeyAltShfEnd = "\x1b[1;4F"
|
||||
t.KeyMetaShfHome = "\x1b[1;10H"
|
||||
t.KeyMetaShfEnd = "\x1b[1;10F"
|
||||
}
|
||||
|
||||
// And the same thing for rxvt and workalikes (Eterm, aterm, etc.)
|
||||
// It seems that urxvt at least send escaped as ALT prefix for these,
|
||||
// although some places seem to indicate a separate ALT key sesquence.
|
||||
if t.KeyShfRight == "\x1b[c" && t.KeyShfLeft == "\x1b[d" {
|
||||
t.KeyShfUp = "\x1b[a"
|
||||
t.KeyShfDown = "\x1b[b"
|
||||
t.KeyCtrlUp = "\x1b[Oa"
|
||||
t.KeyCtrlDown = "\x1b[Ob"
|
||||
t.KeyCtrlRight = "\x1b[Oc"
|
||||
t.KeyCtrlLeft = "\x1b[Od"
|
||||
}
|
||||
if t.KeyShfHome == "\x1b[7$" && t.KeyShfEnd == "\x1b[8$" {
|
||||
t.KeyCtrlHome = "\x1b[7^"
|
||||
t.KeyCtrlEnd = "\x1b[8^"
|
||||
}
|
||||
|
||||
// If the kmous entry is present, then we need to record the
|
||||
// the codes to enter and exit mouse mode. Sadly, this is not
|
||||
// part of the terminfo databases anywhere that I've found, but
|
||||
// is an extension. The escapedape codes are documented in the XTerm
|
||||
// manual, and all terminals that have kmous are expected to
|
||||
// use these same codes, unless explicitly configured otherwise
|
||||
// vi XM. Note that in any event, we only known how to parse either
|
||||
// x11 or SGR mouse events -- if your terminal doesn't support one
|
||||
// of these two forms, you maybe out of luck.
|
||||
t.MouseMode = tc.getstr("XM")
|
||||
if t.Mouse != "" && t.MouseMode == "" {
|
||||
// we anticipate that all xterm mouse tracking compatible
|
||||
// terminals understand mouse tracking (1000), but we hope
|
||||
// that those that don't understand any-event tracking (1003)
|
||||
// will at least ignore it. Likewise we hope that terminals
|
||||
// that don't understand SGR reporting (1006) just ignore it.
|
||||
t.MouseMode = "%?%p1%{1}%=%t%'h'%Pa%e%'l'%Pa%;" +
|
||||
"\x1b[?1000%ga%c\x1b[?1002%ga%c\x1b[?1003%ga%c\x1b[?1006%ga%c"
|
||||
}
|
||||
|
||||
// We only support colors in ANSI 8 or 256 color mode.
|
||||
if t.Colors < 8 || t.SetFg == "" {
|
||||
t.Colors = 0
|
||||
}
|
||||
if t.SetCursor == "" {
|
||||
return nil, "", errNotAddressable
|
||||
}
|
||||
|
||||
// For padding, we lookup the pad char. If that isn't present,
|
||||
// and npc is *not* set, then we assume a null byte.
|
||||
t.PadChar = tc.getstr("pad")
|
||||
if t.PadChar == "" {
|
||||
if !tc.getflag("npc") {
|
||||
t.PadChar = "\u0000"
|
||||
}
|
||||
}
|
||||
|
||||
// For terminals that use "standard" SGR sequences, lets combine the
|
||||
// foreground and background together.
|
||||
if strings.HasPrefix(t.SetFg, "\x1b[") &&
|
||||
strings.HasPrefix(t.SetBg, "\x1b[") &&
|
||||
strings.HasSuffix(t.SetFg, "m") &&
|
||||
strings.HasSuffix(t.SetBg, "m") {
|
||||
fg := t.SetFg[:len(t.SetFg)-1]
|
||||
r := regexp.MustCompile("%p1")
|
||||
bg := r.ReplaceAllString(t.SetBg[2:], "%p2")
|
||||
t.SetFgBg = fg + ";" + bg
|
||||
}
|
||||
|
||||
return t, tc.desc, nil
|
||||
}
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
// Generated automatically. DO NOT HAND-EDIT.
|
||||
|
||||
package emacs
|
||||
|
||||
import "github.com/gdamore/tcell/terminfo"
|
||||
|
||||
func init() {
|
||||
|
||||
// gnu emacs term.el terminal emulation
|
||||
terminfo.AddTerminfo(&terminfo.Terminfo{
|
||||
Name: "eterm",
|
||||
Columns: 80,
|
||||
Lines: 24,
|
||||
Bell: "\a",
|
||||
Clear: "\x1b[H\x1b[J",
|
||||
EnterCA: "\x1b7\x1b[?47h",
|
||||
ExitCA: "\x1b[2J\x1b[?47l\x1b8",
|
||||
AttrOff: "\x1b[m",
|
||||
Underline: "\x1b[4m",
|
||||
Bold: "\x1b[1m",
|
||||
Reverse: "\x1b[7m",
|
||||
PadChar: "\x00",
|
||||
SetCursor: "\x1b[%i%p1%d;%p2%dH",
|
||||
CursorBack1: "\b",
|
||||
CursorUp1: "\x1b[A",
|
||||
})
|
||||
|
||||
// Emacs term.el terminal emulator term-protocol-version 0.96
|
||||
terminfo.AddTerminfo(&terminfo.Terminfo{
|
||||
Name: "eterm-color",
|
||||
Columns: 80,
|
||||
Lines: 24,
|
||||
Colors: 8,
|
||||
Bell: "\a",
|
||||
Clear: "\x1b[H\x1b[J",
|
||||
AttrOff: "\x1b[m",
|
||||
Underline: "\x1b[4m",
|
||||
Bold: "\x1b[1m",
|
||||
Blink: "\x1b[5m",
|
||||
Reverse: "\x1b[7m",
|
||||
SetFg: "\x1b[%p1%{30}%+%dm",
|
||||
SetBg: "\x1b[%p1%'('%+%dm",
|
||||
SetFgBg: "\x1b[%p1%{30}%+%d;%p2%'('%+%dm",
|
||||
PadChar: "\x00",
|
||||
SetCursor: "\x1b[%i%p1%d;%p2%dH",
|
||||
CursorBack1: "\b",
|
||||
CursorUp1: "\x1b[A",
|
||||
KeyUp: "\x1bOA",
|
||||
KeyDown: "\x1bOB",
|
||||
KeyRight: "\x1bOC",
|
||||
KeyLeft: "\x1bOD",
|
||||
KeyInsert: "\x1b[2~",
|
||||
KeyDelete: "\x1b[3~",
|
||||
KeyBackspace: "\xff",
|
||||
KeyHome: "\x1b[1~",
|
||||
KeyEnd: "\x1b[4~",
|
||||
KeyPgUp: "\x1b[5~",
|
||||
KeyPgDn: "\x1b[6~",
|
||||
})
|
||||
}
|
||||
+309
@@ -0,0 +1,309 @@
|
||||
// Generated automatically. DO NOT HAND-EDIT.
|
||||
|
||||
package eterm
|
||||
|
||||
import "github.com/gdamore/tcell/terminfo"
|
||||
|
||||
func init() {
|
||||
|
||||
// Eterm with xterm-style color support (X Window System)
|
||||
terminfo.AddTerminfo(&terminfo.Terminfo{
|
||||
Name: "Eterm",
|
||||
Aliases: []string{"Eterm-color"},
|
||||
Columns: 80,
|
||||
Lines: 24,
|
||||
Colors: 8,
|
||||
Bell: "\a",
|
||||
Clear: "\x1b[H\x1b[2J",
|
||||
EnterCA: "\x1b7\x1b[?47h",
|
||||
ExitCA: "\x1b[2J\x1b[?47l\x1b8",
|
||||
ShowCursor: "\x1b[?25h",
|
||||
HideCursor: "\x1b[?25l",
|
||||
AttrOff: "\x1b[m\x0f",
|
||||
Underline: "\x1b[4m",
|
||||
Bold: "\x1b[1m",
|
||||
Blink: "\x1b[5m",
|
||||
Reverse: "\x1b[7m",
|
||||
SetFg: "\x1b[3%p1%dm",
|
||||
SetBg: "\x1b[4%p1%dm",
|
||||
SetFgBg: "\x1b[3%p1%d;4%p2%dm",
|
||||
PadChar: "\x00",
|
||||
AltChars: "``aaffggjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~",
|
||||
EnterAcs: "\x0e",
|
||||
ExitAcs: "\x0f",
|
||||
EnableAcs: "\x1b)0",
|
||||
Mouse: "\x1b[M",
|
||||
MouseMode: "%?%p1%{1}%=%t%'h'%Pa%e%'l'%Pa%;\x1b[?1000%ga%c\x1b[?1002%ga%c\x1b[?1003%ga%c\x1b[?1006%ga%c",
|
||||
SetCursor: "\x1b[%i%p1%d;%p2%dH",
|
||||
CursorBack1: "\b",
|
||||
CursorUp1: "\x1b[A",
|
||||
KeyUp: "\x1b[A",
|
||||
KeyDown: "\x1b[B",
|
||||
KeyRight: "\x1b[C",
|
||||
KeyLeft: "\x1b[D",
|
||||
KeyInsert: "\x1b[2~",
|
||||
KeyDelete: "\x1b[3~",
|
||||
KeyBackspace: "\xff",
|
||||
KeyHome: "\x1b[7~",
|
||||
KeyEnd: "\x1b[8~",
|
||||
KeyPgUp: "\x1b[5~",
|
||||
KeyPgDn: "\x1b[6~",
|
||||
KeyF1: "\x1b[11~",
|
||||
KeyF2: "\x1b[12~",
|
||||
KeyF3: "\x1b[13~",
|
||||
KeyF4: "\x1b[14~",
|
||||
KeyF5: "\x1b[15~",
|
||||
KeyF6: "\x1b[17~",
|
||||
KeyF7: "\x1b[18~",
|
||||
KeyF8: "\x1b[19~",
|
||||
KeyF9: "\x1b[20~",
|
||||
KeyF10: "\x1b[21~",
|
||||
KeyF11: "\x1b[23~",
|
||||
KeyF12: "\x1b[24~",
|
||||
KeyF13: "\x1b[25~",
|
||||
KeyF14: "\x1b[26~",
|
||||
KeyF15: "\x1b[28~",
|
||||
KeyF16: "\x1b[29~",
|
||||
KeyF17: "\x1b[31~",
|
||||
KeyF18: "\x1b[32~",
|
||||
KeyF19: "\x1b[33~",
|
||||
KeyF20: "\x1b[34~",
|
||||
KeyF21: "\x1b[23$",
|
||||
KeyF22: "\x1b[24$",
|
||||
KeyF23: "\x1b[11^",
|
||||
KeyF24: "\x1b[12^",
|
||||
KeyF25: "\x1b[13^",
|
||||
KeyF26: "\x1b[14^",
|
||||
KeyF27: "\x1b[15^",
|
||||
KeyF28: "\x1b[17^",
|
||||
KeyF29: "\x1b[18^",
|
||||
KeyF30: "\x1b[19^",
|
||||
KeyF31: "\x1b[20^",
|
||||
KeyF32: "\x1b[21^",
|
||||
KeyF33: "\x1b[23^",
|
||||
KeyF34: "\x1b[24^",
|
||||
KeyF35: "\x1b[25^",
|
||||
KeyF36: "\x1b[26^",
|
||||
KeyF37: "\x1b[28^",
|
||||
KeyF38: "\x1b[29^",
|
||||
KeyF39: "\x1b[31^",
|
||||
KeyF40: "\x1b[32^",
|
||||
KeyF41: "\x1b[33^",
|
||||
KeyF42: "\x1b[34^",
|
||||
KeyF43: "\x1b[23@",
|
||||
KeyF44: "\x1b[24@",
|
||||
KeyHelp: "\x1b[28~",
|
||||
KeyShfLeft: "\x1b[d",
|
||||
KeyShfRight: "\x1b[c",
|
||||
KeyShfUp: "\x1b[a",
|
||||
KeyShfDown: "\x1b[b",
|
||||
KeyCtrlLeft: "\x1b[Od",
|
||||
KeyCtrlRight: "\x1b[Oc",
|
||||
KeyCtrlUp: "\x1b[Oa",
|
||||
KeyCtrlDown: "\x1b[Ob",
|
||||
KeyShfHome: "\x1b[7$",
|
||||
KeyShfEnd: "\x1b[8$",
|
||||
KeyCtrlHome: "\x1b[7^",
|
||||
KeyCtrlEnd: "\x1b[8^",
|
||||
})
|
||||
|
||||
// Eterm with 88 colors
|
||||
terminfo.AddTerminfo(&terminfo.Terminfo{
|
||||
Name: "Eterm-88color",
|
||||
Columns: 80,
|
||||
Lines: 24,
|
||||
Colors: 88,
|
||||
Bell: "\a",
|
||||
Clear: "\x1b[H\x1b[2J",
|
||||
EnterCA: "\x1b7\x1b[?47h",
|
||||
ExitCA: "\x1b[2J\x1b[?47l\x1b8",
|
||||
ShowCursor: "\x1b[?25h",
|
||||
HideCursor: "\x1b[?25l",
|
||||
AttrOff: "\x1b[m\x0f",
|
||||
Underline: "\x1b[4m",
|
||||
Bold: "\x1b[1m",
|
||||
Blink: "\x1b[5m",
|
||||
Reverse: "\x1b[7m",
|
||||
SetFg: "\x1b[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m",
|
||||
SetBg: "\x1b[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m",
|
||||
SetFgBg: "\x1b[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;;%?%p2%{8}%<%t4%p2%d%e%p2%{16}%<%t10%p2%{8}%-%d%e48;5;%p2%d%;m",
|
||||
PadChar: "\x00",
|
||||
AltChars: "``aaffggjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~",
|
||||
EnterAcs: "\x0e",
|
||||
ExitAcs: "\x0f",
|
||||
EnableAcs: "\x1b)0",
|
||||
Mouse: "\x1b[M",
|
||||
MouseMode: "%?%p1%{1}%=%t%'h'%Pa%e%'l'%Pa%;\x1b[?1000%ga%c\x1b[?1002%ga%c\x1b[?1003%ga%c\x1b[?1006%ga%c",
|
||||
SetCursor: "\x1b[%i%p1%d;%p2%dH",
|
||||
CursorBack1: "\b",
|
||||
CursorUp1: "\x1b[A",
|
||||
KeyUp: "\x1b[A",
|
||||
KeyDown: "\x1b[B",
|
||||
KeyRight: "\x1b[C",
|
||||
KeyLeft: "\x1b[D",
|
||||
KeyInsert: "\x1b[2~",
|
||||
KeyDelete: "\x1b[3~",
|
||||
KeyBackspace: "\xff",
|
||||
KeyHome: "\x1b[7~",
|
||||
KeyEnd: "\x1b[8~",
|
||||
KeyPgUp: "\x1b[5~",
|
||||
KeyPgDn: "\x1b[6~",
|
||||
KeyF1: "\x1b[11~",
|
||||
KeyF2: "\x1b[12~",
|
||||
KeyF3: "\x1b[13~",
|
||||
KeyF4: "\x1b[14~",
|
||||
KeyF5: "\x1b[15~",
|
||||
KeyF6: "\x1b[17~",
|
||||
KeyF7: "\x1b[18~",
|
||||
KeyF8: "\x1b[19~",
|
||||
KeyF9: "\x1b[20~",
|
||||
KeyF10: "\x1b[21~",
|
||||
KeyF11: "\x1b[23~",
|
||||
KeyF12: "\x1b[24~",
|
||||
KeyF13: "\x1b[25~",
|
||||
KeyF14: "\x1b[26~",
|
||||
KeyF15: "\x1b[28~",
|
||||
KeyF16: "\x1b[29~",
|
||||
KeyF17: "\x1b[31~",
|
||||
KeyF18: "\x1b[32~",
|
||||
KeyF19: "\x1b[33~",
|
||||
KeyF20: "\x1b[34~",
|
||||
KeyF21: "\x1b[23$",
|
||||
KeyF22: "\x1b[24$",
|
||||
KeyF23: "\x1b[11^",
|
||||
KeyF24: "\x1b[12^",
|
||||
KeyF25: "\x1b[13^",
|
||||
KeyF26: "\x1b[14^",
|
||||
KeyF27: "\x1b[15^",
|
||||
KeyF28: "\x1b[17^",
|
||||
KeyF29: "\x1b[18^",
|
||||
KeyF30: "\x1b[19^",
|
||||
KeyF31: "\x1b[20^",
|
||||
KeyF32: "\x1b[21^",
|
||||
KeyF33: "\x1b[23^",
|
||||
KeyF34: "\x1b[24^",
|
||||
KeyF35: "\x1b[25^",
|
||||
KeyF36: "\x1b[26^",
|
||||
KeyF37: "\x1b[28^",
|
||||
KeyF38: "\x1b[29^",
|
||||
KeyF39: "\x1b[31^",
|
||||
KeyF40: "\x1b[32^",
|
||||
KeyF41: "\x1b[33^",
|
||||
KeyF42: "\x1b[34^",
|
||||
KeyF43: "\x1b[23@",
|
||||
KeyF44: "\x1b[24@",
|
||||
KeyHelp: "\x1b[28~",
|
||||
KeyShfLeft: "\x1b[d",
|
||||
KeyShfRight: "\x1b[c",
|
||||
KeyShfUp: "\x1b[a",
|
||||
KeyShfDown: "\x1b[b",
|
||||
KeyCtrlLeft: "\x1b[Od",
|
||||
KeyCtrlRight: "\x1b[Oc",
|
||||
KeyCtrlUp: "\x1b[Oa",
|
||||
KeyCtrlDown: "\x1b[Ob",
|
||||
KeyShfHome: "\x1b[7$",
|
||||
KeyShfEnd: "\x1b[8$",
|
||||
KeyCtrlHome: "\x1b[7^",
|
||||
KeyCtrlEnd: "\x1b[8^",
|
||||
})
|
||||
|
||||
// Eterm with xterm 256-colors
|
||||
terminfo.AddTerminfo(&terminfo.Terminfo{
|
||||
Name: "Eterm-256color",
|
||||
Columns: 80,
|
||||
Lines: 24,
|
||||
Colors: 256,
|
||||
Bell: "\a",
|
||||
Clear: "\x1b[H\x1b[2J",
|
||||
EnterCA: "\x1b7\x1b[?47h",
|
||||
ExitCA: "\x1b[2J\x1b[?47l\x1b8",
|
||||
ShowCursor: "\x1b[?25h",
|
||||
HideCursor: "\x1b[?25l",
|
||||
AttrOff: "\x1b[m\x0f",
|
||||
Underline: "\x1b[4m",
|
||||
Bold: "\x1b[1m",
|
||||
Blink: "\x1b[5m",
|
||||
Reverse: "\x1b[7m",
|
||||
SetFg: "\x1b[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m",
|
||||
SetBg: "\x1b[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m",
|
||||
SetFgBg: "\x1b[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;;%?%p2%{8}%<%t4%p2%d%e%p2%{16}%<%t10%p2%{8}%-%d%e48;5;%p2%d%;m",
|
||||
PadChar: "\x00",
|
||||
AltChars: "``aaffggjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~",
|
||||
EnterAcs: "\x0e",
|
||||
ExitAcs: "\x0f",
|
||||
EnableAcs: "\x1b)0",
|
||||
Mouse: "\x1b[M",
|
||||
MouseMode: "%?%p1%{1}%=%t%'h'%Pa%e%'l'%Pa%;\x1b[?1000%ga%c\x1b[?1002%ga%c\x1b[?1003%ga%c\x1b[?1006%ga%c",
|
||||
SetCursor: "\x1b[%i%p1%d;%p2%dH",
|
||||
CursorBack1: "\b",
|
||||
CursorUp1: "\x1b[A",
|
||||
KeyUp: "\x1b[A",
|
||||
KeyDown: "\x1b[B",
|
||||
KeyRight: "\x1b[C",
|
||||
KeyLeft: "\x1b[D",
|
||||
KeyInsert: "\x1b[2~",
|
||||
KeyDelete: "\x1b[3~",
|
||||
KeyBackspace: "\xff",
|
||||
KeyHome: "\x1b[7~",
|
||||
KeyEnd: "\x1b[8~",
|
||||
KeyPgUp: "\x1b[5~",
|
||||
KeyPgDn: "\x1b[6~",
|
||||
KeyF1: "\x1b[11~",
|
||||
KeyF2: "\x1b[12~",
|
||||
KeyF3: "\x1b[13~",
|
||||
KeyF4: "\x1b[14~",
|
||||
KeyF5: "\x1b[15~",
|
||||
KeyF6: "\x1b[17~",
|
||||
KeyF7: "\x1b[18~",
|
||||
KeyF8: "\x1b[19~",
|
||||
KeyF9: "\x1b[20~",
|
||||
KeyF10: "\x1b[21~",
|
||||
KeyF11: "\x1b[23~",
|
||||
KeyF12: "\x1b[24~",
|
||||
KeyF13: "\x1b[25~",
|
||||
KeyF14: "\x1b[26~",
|
||||
KeyF15: "\x1b[28~",
|
||||
KeyF16: "\x1b[29~",
|
||||
KeyF17: "\x1b[31~",
|
||||
KeyF18: "\x1b[32~",
|
||||
KeyF19: "\x1b[33~",
|
||||
KeyF20: "\x1b[34~",
|
||||
KeyF21: "\x1b[23$",
|
||||
KeyF22: "\x1b[24$",
|
||||
KeyF23: "\x1b[11^",
|
||||
KeyF24: "\x1b[12^",
|
||||
KeyF25: "\x1b[13^",
|
||||
KeyF26: "\x1b[14^",
|
||||
KeyF27: "\x1b[15^",
|
||||
KeyF28: "\x1b[17^",
|
||||
KeyF29: "\x1b[18^",
|
||||
KeyF30: "\x1b[19^",
|
||||
KeyF31: "\x1b[20^",
|
||||
KeyF32: "\x1b[21^",
|
||||
KeyF33: "\x1b[23^",
|
||||
KeyF34: "\x1b[24^",
|
||||
KeyF35: "\x1b[25^",
|
||||
KeyF36: "\x1b[26^",
|
||||
KeyF37: "\x1b[28^",
|
||||
KeyF38: "\x1b[29^",
|
||||
KeyF39: "\x1b[31^",
|
||||
KeyF40: "\x1b[32^",
|
||||
KeyF41: "\x1b[33^",
|
||||
KeyF42: "\x1b[34^",
|
||||
KeyF43: "\x1b[23@",
|
||||
KeyF44: "\x1b[24@",
|
||||
KeyHelp: "\x1b[28~",
|
||||
KeyShfLeft: "\x1b[d",
|
||||
KeyShfRight: "\x1b[c",
|
||||
KeyShfUp: "\x1b[a",
|
||||
KeyShfDown: "\x1b[b",
|
||||
KeyCtrlLeft: "\x1b[Od",
|
||||
KeyCtrlRight: "\x1b[Oc",
|
||||
KeyCtrlUp: "\x1b[Oa",
|
||||
KeyCtrlDown: "\x1b[Ob",
|
||||
KeyShfHome: "\x1b[7$",
|
||||
KeyShfEnd: "\x1b[8$",
|
||||
KeyCtrlHome: "\x1b[7^",
|
||||
KeyCtrlEnd: "\x1b[8^",
|
||||
})
|
||||
}
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
// Copyright 2019 The TCell Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use file except in compliance with the License.
|
||||
// You may obtain a copy of the license at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Package extended contains an extended set of terminal descriptions.
|
||||
// Applications desiring to have a better chance of Just Working by
|
||||
// default should include this package. This will significantly increase
|
||||
// the size of the program.
|
||||
package extended
|
||||
|
||||
import (
|
||||
// The following imports just register themselves --
|
||||
// these are the terminal types we aggregate in this package.
|
||||
_ "github.com/gdamore/tcell/terminfo/a/adm3a"
|
||||
_ "github.com/gdamore/tcell/terminfo/a/aixterm"
|
||||
_ "github.com/gdamore/tcell/terminfo/a/alacritty"
|
||||
_ "github.com/gdamore/tcell/terminfo/a/ansi"
|
||||
_ "github.com/gdamore/tcell/terminfo/a/aterm"
|
||||
_ "github.com/gdamore/tcell/terminfo/b/beterm"
|
||||
_ "github.com/gdamore/tcell/terminfo/b/bsdos_pc"
|
||||
_ "github.com/gdamore/tcell/terminfo/c/cygwin"
|
||||
_ "github.com/gdamore/tcell/terminfo/d/d200"
|
||||
_ "github.com/gdamore/tcell/terminfo/d/d210"
|
||||
_ "github.com/gdamore/tcell/terminfo/d/dtterm"
|
||||
_ "github.com/gdamore/tcell/terminfo/e/emacs"
|
||||
_ "github.com/gdamore/tcell/terminfo/e/eterm"
|
||||
_ "github.com/gdamore/tcell/terminfo/g/gnome"
|
||||
_ "github.com/gdamore/tcell/terminfo/h/hpterm"
|
||||
_ "github.com/gdamore/tcell/terminfo/h/hz1500"
|
||||
_ "github.com/gdamore/tcell/terminfo/k/konsole"
|
||||
_ "github.com/gdamore/tcell/terminfo/k/kterm"
|
||||
_ "github.com/gdamore/tcell/terminfo/l/linux"
|
||||
_ "github.com/gdamore/tcell/terminfo/p/pcansi"
|
||||
_ "github.com/gdamore/tcell/terminfo/r/rxvt"
|
||||
_ "github.com/gdamore/tcell/terminfo/s/screen"
|
||||
_ "github.com/gdamore/tcell/terminfo/s/simpleterm"
|
||||
_ "github.com/gdamore/tcell/terminfo/s/sun"
|
||||
_ "github.com/gdamore/tcell/terminfo/t/termite"
|
||||
_ "github.com/gdamore/tcell/terminfo/t/tvi910"
|
||||
_ "github.com/gdamore/tcell/terminfo/t/tvi912"
|
||||
_ "github.com/gdamore/tcell/terminfo/t/tvi921"
|
||||
_ "github.com/gdamore/tcell/terminfo/t/tvi925"
|
||||
_ "github.com/gdamore/tcell/terminfo/t/tvi950"
|
||||
_ "github.com/gdamore/tcell/terminfo/t/tvi970"
|
||||
_ "github.com/gdamore/tcell/terminfo/v/vt100"
|
||||
_ "github.com/gdamore/tcell/terminfo/v/vt102"
|
||||
_ "github.com/gdamore/tcell/terminfo/v/vt220"
|
||||
_ "github.com/gdamore/tcell/terminfo/v/vt320"
|
||||
_ "github.com/gdamore/tcell/terminfo/v/vt400"
|
||||
_ "github.com/gdamore/tcell/terminfo/v/vt420"
|
||||
_ "github.com/gdamore/tcell/terminfo/v/vt52"
|
||||
_ "github.com/gdamore/tcell/terminfo/w/wy50"
|
||||
_ "github.com/gdamore/tcell/terminfo/w/wy60"
|
||||
_ "github.com/gdamore/tcell/terminfo/w/wy99_ansi"
|
||||
_ "github.com/gdamore/tcell/terminfo/x/xfce"
|
||||
_ "github.com/gdamore/tcell/terminfo/x/xnuppc"
|
||||
_ "github.com/gdamore/tcell/terminfo/x/xterm"
|
||||
_ "github.com/gdamore/tcell/terminfo/x/xterm_kitty"
|
||||
)
|
||||
+306
@@ -0,0 +1,306 @@
|
||||
// Generated automatically. DO NOT HAND-EDIT.
|
||||
|
||||
package gnome
|
||||
|
||||
import "github.com/gdamore/tcell/terminfo"
|
||||
|
||||
func init() {
|
||||
|
||||
// GNOME Terminal
|
||||
terminfo.AddTerminfo(&terminfo.Terminfo{
|
||||
Name: "gnome",
|
||||
Columns: 80,
|
||||
Lines: 24,
|
||||
Colors: 8,
|
||||
Bell: "\a",
|
||||
Clear: "\x1b[H\x1b[2J",
|
||||
EnterCA: "\x1b7\x1b[?47h",
|
||||
ExitCA: "\x1b[2J\x1b[?47l\x1b8",
|
||||
ShowCursor: "\x1b[?25h",
|
||||
HideCursor: "\x1b[?25l",
|
||||
AttrOff: "\x1b[0m\x0f",
|
||||
Underline: "\x1b[4m",
|
||||
Bold: "\x1b[1m",
|
||||
Dim: "\x1b[2m",
|
||||
Reverse: "\x1b[7m",
|
||||
EnterKeypad: "\x1b[?1h\x1b=",
|
||||
ExitKeypad: "\x1b[?1l\x1b>",
|
||||
SetFg: "\x1b[3%p1%dm",
|
||||
SetBg: "\x1b[4%p1%dm",
|
||||
SetFgBg: "\x1b[3%p1%d;4%p2%dm",
|
||||
PadChar: "\x00",
|
||||
AltChars: "``aaffggiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~",
|
||||
EnterAcs: "\x0e",
|
||||
ExitAcs: "\x0f",
|
||||
EnableAcs: "\x1b)0",
|
||||
Mouse: "\x1b[M",
|
||||
MouseMode: "%?%p1%{1}%=%t%'h'%Pa%e%'l'%Pa%;\x1b[?1000%ga%c\x1b[?1002%ga%c\x1b[?1003%ga%c\x1b[?1006%ga%c",
|
||||
SetCursor: "\x1b[%i%p1%d;%p2%dH",
|
||||
CursorBack1: "\b",
|
||||
CursorUp1: "\x1b[A",
|
||||
KeyUp: "\x1bOA",
|
||||
KeyDown: "\x1bOB",
|
||||
KeyRight: "\x1bOC",
|
||||
KeyLeft: "\x1bOD",
|
||||
KeyInsert: "\x1b[2~",
|
||||
KeyDelete: "\x1b[3~",
|
||||
KeyBackspace: "\xff",
|
||||
KeyHome: "\x1bOH",
|
||||
KeyEnd: "\x1bOF",
|
||||
KeyPgUp: "\x1b[5~",
|
||||
KeyPgDn: "\x1b[6~",
|
||||
KeyF1: "\x1bOP",
|
||||
KeyF2: "\x1bOQ",
|
||||
KeyF3: "\x1bOR",
|
||||
KeyF4: "\x1bOS",
|
||||
KeyF5: "\x1b[15~",
|
||||
KeyF6: "\x1b[17~",
|
||||
KeyF7: "\x1b[18~",
|
||||
KeyF8: "\x1b[19~",
|
||||
KeyF9: "\x1b[20~",
|
||||
KeyF10: "\x1b[21~",
|
||||
KeyF11: "\x1b[23~",
|
||||
KeyF12: "\x1b[24~",
|
||||
KeyF13: "\x1bO1;2P",
|
||||
KeyF14: "\x1bO1;2Q",
|
||||
KeyF15: "\x1bO1;2R",
|
||||
KeyF16: "\x1bO1;2S",
|
||||
KeyF17: "\x1b[15;2~",
|
||||
KeyF18: "\x1b[17;2~",
|
||||
KeyF19: "\x1b[18;2~",
|
||||
KeyF20: "\x1b[19;2~",
|
||||
KeyF21: "\x1b[20;2~",
|
||||
KeyF22: "\x1b[21;2~",
|
||||
KeyF23: "\x1b[23;2~",
|
||||
KeyF24: "\x1b[24;2~",
|
||||
KeyF25: "\x1bO1;5P",
|
||||
KeyF26: "\x1bO1;5Q",
|
||||
KeyF27: "\x1bO1;5R",
|
||||
KeyF28: "\x1bO1;5S",
|
||||
KeyF29: "\x1b[15;5~",
|
||||
KeyF30: "\x1b[17;5~",
|
||||
KeyF31: "\x1b[18;5~",
|
||||
KeyF32: "\x1b[19;5~",
|
||||
KeyF33: "\x1b[20;5~",
|
||||
KeyF34: "\x1b[21;5~",
|
||||
KeyF35: "\x1b[23;5~",
|
||||
KeyF36: "\x1b[24;5~",
|
||||
KeyF37: "\x1bO1;6P",
|
||||
KeyF38: "\x1bO1;6Q",
|
||||
KeyF39: "\x1bO1;6R",
|
||||
KeyF40: "\x1bO1;6S",
|
||||
KeyF41: "\x1b[15;6~",
|
||||
KeyF42: "\x1b[17;6~",
|
||||
KeyF43: "\x1b[18;6~",
|
||||
KeyF44: "\x1b[19;6~",
|
||||
KeyF45: "\x1b[20;6~",
|
||||
KeyF46: "\x1b[21;6~",
|
||||
KeyF47: "\x1b[23;6~",
|
||||
KeyF48: "\x1b[24;6~",
|
||||
KeyF49: "\x1bO1;3P",
|
||||
KeyF50: "\x1bO1;3Q",
|
||||
KeyF51: "\x1bO1;3R",
|
||||
KeyF52: "\x1bO1;3S",
|
||||
KeyF53: "\x1b[15;3~",
|
||||
KeyF54: "\x1b[17;3~",
|
||||
KeyF55: "\x1b[18;3~",
|
||||
KeyF56: "\x1b[19;3~",
|
||||
KeyF57: "\x1b[20;3~",
|
||||
KeyF58: "\x1b[21;3~",
|
||||
KeyF59: "\x1b[23;3~",
|
||||
KeyF60: "\x1b[24;3~",
|
||||
KeyF61: "\x1bO1;4P",
|
||||
KeyF62: "\x1bO1;4Q",
|
||||
KeyF63: "\x1bO1;4R",
|
||||
KeyBacktab: "\x1b[Z",
|
||||
KeyShfLeft: "\x1b[1;2D",
|
||||
KeyShfRight: "\x1b[1;2C",
|
||||
KeyShfUp: "\x1b[1;2A",
|
||||
KeyShfDown: "\x1b[1;2B",
|
||||
KeyCtrlLeft: "\x1b[1;5D",
|
||||
KeyCtrlRight: "\x1b[1;5C",
|
||||
KeyCtrlUp: "\x1b[1;5A",
|
||||
KeyCtrlDown: "\x1b[1;5B",
|
||||
KeyMetaLeft: "\x1b[1;9D",
|
||||
KeyMetaRight: "\x1b[1;9C",
|
||||
KeyMetaUp: "\x1b[1;9A",
|
||||
KeyMetaDown: "\x1b[1;9B",
|
||||
KeyAltLeft: "\x1b[1;3D",
|
||||
KeyAltRight: "\x1b[1;3C",
|
||||
KeyAltUp: "\x1b[1;3A",
|
||||
KeyAltDown: "\x1b[1;3B",
|
||||
KeyAltShfLeft: "\x1b[1;4D",
|
||||
KeyAltShfRight: "\x1b[1;4C",
|
||||
KeyAltShfUp: "\x1b[1;4A",
|
||||
KeyAltShfDown: "\x1b[1;4B",
|
||||
KeyMetaShfLeft: "\x1b[1;10D",
|
||||
KeyMetaShfRight: "\x1b[1;10C",
|
||||
KeyMetaShfUp: "\x1b[1;10A",
|
||||
KeyMetaShfDown: "\x1b[1;10B",
|
||||
KeyCtrlShfLeft: "\x1b[1;6D",
|
||||
KeyCtrlShfRight: "\x1b[1;6C",
|
||||
KeyCtrlShfUp: "\x1b[1;6A",
|
||||
KeyCtrlShfDown: "\x1b[1;6B",
|
||||
KeyShfHome: "\x1b[1;2H",
|
||||
KeyShfEnd: "\x1b[1;2F",
|
||||
KeyCtrlHome: "\x1b[1;5H",
|
||||
KeyCtrlEnd: "\x1b[1;5F",
|
||||
KeyAltHome: "\x1b[1;9H",
|
||||
KeyAltEnd: "\x1b[1;9F",
|
||||
KeyCtrlShfHome: "\x1b[1;6H",
|
||||
KeyCtrlShfEnd: "\x1b[1;6F",
|
||||
KeyMetaShfHome: "\x1b[1;10H",
|
||||
KeyMetaShfEnd: "\x1b[1;10F",
|
||||
KeyAltShfHome: "\x1b[1;4H",
|
||||
KeyAltShfEnd: "\x1b[1;4F",
|
||||
})
|
||||
|
||||
// GNOME Terminal with xterm 256-colors
|
||||
terminfo.AddTerminfo(&terminfo.Terminfo{
|
||||
Name: "gnome-256color",
|
||||
Columns: 80,
|
||||
Lines: 24,
|
||||
Colors: 256,
|
||||
Bell: "\a",
|
||||
Clear: "\x1b[H\x1b[2J",
|
||||
EnterCA: "\x1b7\x1b[?47h",
|
||||
ExitCA: "\x1b[2J\x1b[?47l\x1b8",
|
||||
ShowCursor: "\x1b[?25h",
|
||||
HideCursor: "\x1b[?25l",
|
||||
AttrOff: "\x1b[0m\x0f",
|
||||
Underline: "\x1b[4m",
|
||||
Bold: "\x1b[1m",
|
||||
Dim: "\x1b[2m",
|
||||
Reverse: "\x1b[7m",
|
||||
EnterKeypad: "\x1b[?1h\x1b=",
|
||||
ExitKeypad: "\x1b[?1l\x1b>",
|
||||
SetFg: "\x1b[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m",
|
||||
SetBg: "\x1b[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m",
|
||||
SetFgBg: "\x1b[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;;%?%p2%{8}%<%t4%p2%d%e%p2%{16}%<%t10%p2%{8}%-%d%e48;5;%p2%d%;m",
|
||||
PadChar: "\x00",
|
||||
AltChars: "``aaffggiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~",
|
||||
EnterAcs: "\x0e",
|
||||
ExitAcs: "\x0f",
|
||||
EnableAcs: "\x1b)0",
|
||||
Mouse: "\x1b[<",
|
||||
MouseMode: "%?%p1%{1}%=%t%'h'%Pa%e%'l'%Pa%;\x1b[?1000%ga%c\x1b[?1002%ga%c\x1b[?1003%ga%c\x1b[?1006%ga%c",
|
||||
SetCursor: "\x1b[%i%p1%d;%p2%dH",
|
||||
CursorBack1: "\b",
|
||||
CursorUp1: "\x1b[A",
|
||||
KeyUp: "\x1bOA",
|
||||
KeyDown: "\x1bOB",
|
||||
KeyRight: "\x1bOC",
|
||||
KeyLeft: "\x1bOD",
|
||||
KeyInsert: "\x1b[2~",
|
||||
KeyDelete: "\x1b[3~",
|
||||
KeyBackspace: "\xff",
|
||||
KeyHome: "\x1bOH",
|
||||
KeyEnd: "\x1bOF",
|
||||
KeyPgUp: "\x1b[5~",
|
||||
KeyPgDn: "\x1b[6~",
|
||||
KeyF1: "\x1bOP",
|
||||
KeyF2: "\x1bOQ",
|
||||
KeyF3: "\x1bOR",
|
||||
KeyF4: "\x1bOS",
|
||||
KeyF5: "\x1b[15~",
|
||||
KeyF6: "\x1b[17~",
|
||||
KeyF7: "\x1b[18~",
|
||||
KeyF8: "\x1b[19~",
|
||||
KeyF9: "\x1b[20~",
|
||||
KeyF10: "\x1b[21~",
|
||||
KeyF11: "\x1b[23~",
|
||||
KeyF12: "\x1b[24~",
|
||||
KeyF13: "\x1b[1;2P",
|
||||
KeyF14: "\x1b[1;2Q",
|
||||
KeyF15: "\x1b[1;2R",
|
||||
KeyF16: "\x1b[1;2S",
|
||||
KeyF17: "\x1b[15;2~",
|
||||
KeyF18: "\x1b[17;2~",
|
||||
KeyF19: "\x1b[18;2~",
|
||||
KeyF20: "\x1b[19;2~",
|
||||
KeyF21: "\x1b[20;2~",
|
||||
KeyF22: "\x1b[21;2~",
|
||||
KeyF23: "\x1b[23;2~",
|
||||
KeyF24: "\x1b[24;2~",
|
||||
KeyF25: "\x1b[1;5P",
|
||||
KeyF26: "\x1b[1;5Q",
|
||||
KeyF27: "\x1b[1;5R",
|
||||
KeyF28: "\x1b[1;5S",
|
||||
KeyF29: "\x1b[15;5~",
|
||||
KeyF30: "\x1b[17;5~",
|
||||
KeyF31: "\x1b[18;5~",
|
||||
KeyF32: "\x1b[19;5~",
|
||||
KeyF33: "\x1b[20;5~",
|
||||
KeyF34: "\x1b[21;5~",
|
||||
KeyF35: "\x1b[23;5~",
|
||||
KeyF36: "\x1b[24;5~",
|
||||
KeyF37: "\x1b[1;6P",
|
||||
KeyF38: "\x1b[1;6Q",
|
||||
KeyF39: "\x1b[1;6R",
|
||||
KeyF40: "\x1b[1;6S",
|
||||
KeyF41: "\x1b[15;6~",
|
||||
KeyF42: "\x1b[17;6~",
|
||||
KeyF43: "\x1b[18;6~",
|
||||
KeyF44: "\x1b[19;6~",
|
||||
KeyF45: "\x1b[20;6~",
|
||||
KeyF46: "\x1b[21;6~",
|
||||
KeyF47: "\x1b[23;6~",
|
||||
KeyF48: "\x1b[24;6~",
|
||||
KeyF49: "\x1b[1;3P",
|
||||
KeyF50: "\x1b[1;3Q",
|
||||
KeyF51: "\x1b[1;3R",
|
||||
KeyF52: "\x1b[1;3S",
|
||||
KeyF53: "\x1b[15;3~",
|
||||
KeyF54: "\x1b[17;3~",
|
||||
KeyF55: "\x1b[18;3~",
|
||||
KeyF56: "\x1b[19;3~",
|
||||
KeyF57: "\x1b[20;3~",
|
||||
KeyF58: "\x1b[21;3~",
|
||||
KeyF59: "\x1b[23;3~",
|
||||
KeyF60: "\x1b[24;3~",
|
||||
KeyF61: "\x1b[1;4P",
|
||||
KeyF62: "\x1b[1;4Q",
|
||||
KeyF63: "\x1b[1;4R",
|
||||
KeyBacktab: "\x1b[Z",
|
||||
KeyShfLeft: "\x1b[1;2D",
|
||||
KeyShfRight: "\x1b[1;2C",
|
||||
KeyShfUp: "\x1b[1;2A",
|
||||
KeyShfDown: "\x1b[1;2B",
|
||||
KeyCtrlLeft: "\x1b[1;5D",
|
||||
KeyCtrlRight: "\x1b[1;5C",
|
||||
KeyCtrlUp: "\x1b[1;5A",
|
||||
KeyCtrlDown: "\x1b[1;5B",
|
||||
KeyMetaLeft: "\x1b[1;9D",
|
||||
KeyMetaRight: "\x1b[1;9C",
|
||||
KeyMetaUp: "\x1b[1;9A",
|
||||
KeyMetaDown: "\x1b[1;9B",
|
||||
KeyAltLeft: "\x1b[1;3D",
|
||||
KeyAltRight: "\x1b[1;3C",
|
||||
KeyAltUp: "\x1b[1;3A",
|
||||
KeyAltDown: "\x1b[1;3B",
|
||||
KeyAltShfLeft: "\x1b[1;4D",
|
||||
KeyAltShfRight: "\x1b[1;4C",
|
||||
KeyAltShfUp: "\x1b[1;4A",
|
||||
KeyAltShfDown: "\x1b[1;4B",
|
||||
KeyMetaShfLeft: "\x1b[1;10D",
|
||||
KeyMetaShfRight: "\x1b[1;10C",
|
||||
KeyMetaShfUp: "\x1b[1;10A",
|
||||
KeyMetaShfDown: "\x1b[1;10B",
|
||||
KeyCtrlShfLeft: "\x1b[1;6D",
|
||||
KeyCtrlShfRight: "\x1b[1;6C",
|
||||
KeyCtrlShfUp: "\x1b[1;6A",
|
||||
KeyCtrlShfDown: "\x1b[1;6B",
|
||||
KeyShfHome: "\x1b[1;2H",
|
||||
KeyShfEnd: "\x1b[1;2F",
|
||||
KeyCtrlHome: "\x1b[1;5H",
|
||||
KeyCtrlEnd: "\x1b[1;5F",
|
||||
KeyAltHome: "\x1b[1;9H",
|
||||
KeyAltEnd: "\x1b[1;9F",
|
||||
KeyCtrlShfHome: "\x1b[1;6H",
|
||||
KeyCtrlShfEnd: "\x1b[1;6F",
|
||||
KeyMetaShfHome: "\x1b[1;10H",
|
||||
KeyMetaShfEnd: "\x1b[1;10F",
|
||||
KeyAltShfHome: "\x1b[1;4H",
|
||||
KeyAltShfEnd: "\x1b[1;4F",
|
||||
})
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
while read line
|
||||
do
|
||||
case "$line" in
|
||||
*'|'*)
|
||||
alias=${line#*|}
|
||||
line=${line%|*}
|
||||
;;
|
||||
*)
|
||||
alias=${line%%,*}
|
||||
;;
|
||||
esac
|
||||
|
||||
alias=${alias//-/_}
|
||||
direc=${alias:0:1}
|
||||
|
||||
mkdir -p ${direc}/${alias}
|
||||
go run mkinfo.go -P ${alias} -go ${direc}/${alias}/term.go ${line//,/ }
|
||||
done < models.txt
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
// Generated automatically. DO NOT HAND-EDIT.
|
||||
|
||||
package hpterm
|
||||
|
||||
import "github.com/gdamore/tcell/terminfo"
|
||||
|
||||
func init() {
|
||||
|
||||
// hp X11 terminal emulator
|
||||
terminfo.AddTerminfo(&terminfo.Terminfo{
|
||||
Name: "hpterm",
|
||||
Aliases: []string{"X-hpterm"},
|
||||
Columns: 80,
|
||||
Lines: 24,
|
||||
Bell: "\a",
|
||||
Clear: "\x1b&a0y0C\x1bJ",
|
||||
AttrOff: "\x1b&d@\x0f",
|
||||
Underline: "\x1b&dD",
|
||||
Bold: "\x1b&dB",
|
||||
Dim: "\x1b&dH",
|
||||
Reverse: "\x1b&dB",
|
||||
EnterKeypad: "\x1b&s1A",
|
||||
ExitKeypad: "\x1b&s0A",
|
||||
PadChar: "\x00",
|
||||
EnterAcs: "\x0e",
|
||||
ExitAcs: "\x0f",
|
||||
SetCursor: "\x1b&a%p1%dy%p2%dC",
|
||||
CursorBack1: "\b",
|
||||
CursorUp1: "\x1bA",
|
||||
KeyUp: "\x1bA",
|
||||
KeyDown: "\x1bB",
|
||||
KeyRight: "\x1bC",
|
||||
KeyLeft: "\x1bD",
|
||||
KeyInsert: "\x1bQ",
|
||||
KeyDelete: "\x1bP",
|
||||
KeyBackspace: "\b",
|
||||
KeyHome: "\x1bh",
|
||||
KeyPgUp: "\x1bV",
|
||||
KeyPgDn: "\x1bU",
|
||||
KeyF1: "\x1bp",
|
||||
KeyF2: "\x1bq",
|
||||
KeyF3: "\x1br",
|
||||
KeyF4: "\x1bs",
|
||||
KeyF5: "\x1bt",
|
||||
KeyF6: "\x1bu",
|
||||
KeyF7: "\x1bv",
|
||||
KeyF8: "\x1bw",
|
||||
KeyClear: "\x1bJ",
|
||||
})
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
// Generated automatically. DO NOT HAND-EDIT.
|
||||
|
||||
package hz1500
|
||||
|
||||
import "github.com/gdamore/tcell/terminfo"
|
||||
|
||||
func init() {
|
||||
|
||||
// hazeltine 1500
|
||||
terminfo.AddTerminfo(&terminfo.Terminfo{
|
||||
Name: "hz1500",
|
||||
Columns: 80,
|
||||
Lines: 24,
|
||||
Bell: "\a",
|
||||
Clear: "~\x1c",
|
||||
PadChar: "\x00",
|
||||
SetCursor: "~\x11%p2%p2%?%{30}%>%t%' '%+%;%'`'%+%c%p1%'`'%+%c",
|
||||
CursorBack1: "\b",
|
||||
CursorUp1: "~\f",
|
||||
KeyUp: "~\f",
|
||||
KeyDown: "\n",
|
||||
KeyRight: "\x10",
|
||||
KeyLeft: "\b",
|
||||
KeyHome: "~\x12",
|
||||
})
|
||||
}
|
||||
+304
@@ -0,0 +1,304 @@
|
||||
// Generated automatically. DO NOT HAND-EDIT.
|
||||
|
||||
package konsole
|
||||
|
||||
import "github.com/gdamore/tcell/terminfo"
|
||||
|
||||
func init() {
|
||||
|
||||
// KDE console window
|
||||
terminfo.AddTerminfo(&terminfo.Terminfo{
|
||||
Name: "konsole",
|
||||
Columns: 80,
|
||||
Lines: 24,
|
||||
Colors: 8,
|
||||
Clear: "\x1b[H\x1b[2J",
|
||||
EnterCA: "\x1b7\x1b[?47h",
|
||||
ExitCA: "\x1b[2J\x1b[?47l\x1b8",
|
||||
ShowCursor: "\x1b[?25h",
|
||||
HideCursor: "\x1b[?25l",
|
||||
AttrOff: "\x1b[0m\x0f",
|
||||
Underline: "\x1b[4m",
|
||||
Bold: "\x1b[1m",
|
||||
Dim: "\x1b[2m",
|
||||
Blink: "\x1b[5m",
|
||||
Reverse: "\x1b[7m",
|
||||
EnterKeypad: "\x1b[?1h\x1b=",
|
||||
ExitKeypad: "\x1b[?1l\x1b>",
|
||||
SetFg: "\x1b[3%p1%dm",
|
||||
SetBg: "\x1b[4%p1%dm",
|
||||
SetFgBg: "\x1b[3%p1%d;4%p2%dm",
|
||||
AltChars: "``aaffggiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~",
|
||||
EnterAcs: "\x0e",
|
||||
ExitAcs: "\x0f",
|
||||
EnableAcs: "\x1b)0",
|
||||
Mouse: "\x1b[M",
|
||||
MouseMode: "%?%p1%{1}%=%t%'h'%Pa%e%'l'%Pa%;\x1b[?1000%ga%c\x1b[?1002%ga%c\x1b[?1003%ga%c\x1b[?1006%ga%c",
|
||||
SetCursor: "\x1b[%i%p1%d;%p2%dH",
|
||||
CursorBack1: "\b",
|
||||
CursorUp1: "\x1b[A",
|
||||
KeyUp: "\x1bOA",
|
||||
KeyDown: "\x1bOB",
|
||||
KeyRight: "\x1bOC",
|
||||
KeyLeft: "\x1bOD",
|
||||
KeyInsert: "\x1b[2~",
|
||||
KeyDelete: "\x1b[3~",
|
||||
KeyBackspace: "\xff",
|
||||
KeyHome: "\x1bOH",
|
||||
KeyEnd: "\x1bOF",
|
||||
KeyPgUp: "\x1b[5~",
|
||||
KeyPgDn: "\x1b[6~",
|
||||
KeyF1: "\x1bOP",
|
||||
KeyF2: "\x1bOQ",
|
||||
KeyF3: "\x1bOR",
|
||||
KeyF4: "\x1bOS",
|
||||
KeyF5: "\x1b[15~",
|
||||
KeyF6: "\x1b[17~",
|
||||
KeyF7: "\x1b[18~",
|
||||
KeyF8: "\x1b[19~",
|
||||
KeyF9: "\x1b[20~",
|
||||
KeyF10: "\x1b[21~",
|
||||
KeyF11: "\x1b[23~",
|
||||
KeyF12: "\x1b[24~",
|
||||
KeyF13: "\x1bO2P",
|
||||
KeyF14: "\x1bO2Q",
|
||||
KeyF15: "\x1bO2R",
|
||||
KeyF16: "\x1bO2S",
|
||||
KeyF17: "\x1b[15;2~",
|
||||
KeyF18: "\x1b[17;2~",
|
||||
KeyF19: "\x1b[18;2~",
|
||||
KeyF20: "\x1b[19;2~",
|
||||
KeyF21: "\x1b[20;2~",
|
||||
KeyF22: "\x1b[21;2~",
|
||||
KeyF23: "\x1b[23;2~",
|
||||
KeyF24: "\x1b[24;2~",
|
||||
KeyF25: "\x1bO5P",
|
||||
KeyF26: "\x1bO5Q",
|
||||
KeyF27: "\x1bO5R",
|
||||
KeyF28: "\x1bO5S",
|
||||
KeyF29: "\x1b[15;5~",
|
||||
KeyF30: "\x1b[17;5~",
|
||||
KeyF31: "\x1b[18;5~",
|
||||
KeyF32: "\x1b[19;5~",
|
||||
KeyF33: "\x1b[20;5~",
|
||||
KeyF34: "\x1b[21;5~",
|
||||
KeyF35: "\x1b[23;5~",
|
||||
KeyF36: "\x1b[24;5~",
|
||||
KeyF37: "\x1bO6P",
|
||||
KeyF38: "\x1bO6Q",
|
||||
KeyF39: "\x1bO6R",
|
||||
KeyF40: "\x1bO6S",
|
||||
KeyF41: "\x1b[15;6~",
|
||||
KeyF42: "\x1b[17;6~",
|
||||
KeyF43: "\x1b[18;6~",
|
||||
KeyF44: "\x1b[19;6~",
|
||||
KeyF45: "\x1b[20;6~",
|
||||
KeyF46: "\x1b[21;6~",
|
||||
KeyF47: "\x1b[23;6~",
|
||||
KeyF48: "\x1b[24;6~",
|
||||
KeyF49: "\x1bO3P",
|
||||
KeyF50: "\x1bO3Q",
|
||||
KeyF51: "\x1bO3R",
|
||||
KeyF52: "\x1bO3S",
|
||||
KeyF53: "\x1b[15;3~",
|
||||
KeyF54: "\x1b[17;3~",
|
||||
KeyF55: "\x1b[18;3~",
|
||||
KeyF56: "\x1b[19;3~",
|
||||
KeyF57: "\x1b[20;3~",
|
||||
KeyF58: "\x1b[21;3~",
|
||||
KeyF59: "\x1b[23;3~",
|
||||
KeyF60: "\x1b[24;3~",
|
||||
KeyF61: "\x1bO4P",
|
||||
KeyF62: "\x1bO4Q",
|
||||
KeyF63: "\x1bO4R",
|
||||
KeyBacktab: "\x1b[Z",
|
||||
KeyShfLeft: "\x1b[1;2D",
|
||||
KeyShfRight: "\x1b[1;2C",
|
||||
KeyShfUp: "\x1b[1;2A",
|
||||
KeyShfDown: "\x1b[1;2B",
|
||||
KeyCtrlLeft: "\x1b[1;5D",
|
||||
KeyCtrlRight: "\x1b[1;5C",
|
||||
KeyCtrlUp: "\x1b[1;5A",
|
||||
KeyCtrlDown: "\x1b[1;5B",
|
||||
KeyMetaLeft: "\x1b[1;9D",
|
||||
KeyMetaRight: "\x1b[1;9C",
|
||||
KeyMetaUp: "\x1b[1;9A",
|
||||
KeyMetaDown: "\x1b[1;9B",
|
||||
KeyAltLeft: "\x1b[1;3D",
|
||||
KeyAltRight: "\x1b[1;3C",
|
||||
KeyAltUp: "\x1b[1;3A",
|
||||
KeyAltDown: "\x1b[1;3B",
|
||||
KeyAltShfLeft: "\x1b[1;4D",
|
||||
KeyAltShfRight: "\x1b[1;4C",
|
||||
KeyAltShfUp: "\x1b[1;4A",
|
||||
KeyAltShfDown: "\x1b[1;4B",
|
||||
KeyMetaShfLeft: "\x1b[1;10D",
|
||||
KeyMetaShfRight: "\x1b[1;10C",
|
||||
KeyMetaShfUp: "\x1b[1;10A",
|
||||
KeyMetaShfDown: "\x1b[1;10B",
|
||||
KeyCtrlShfLeft: "\x1b[1;6D",
|
||||
KeyCtrlShfRight: "\x1b[1;6C",
|
||||
KeyCtrlShfUp: "\x1b[1;6A",
|
||||
KeyCtrlShfDown: "\x1b[1;6B",
|
||||
KeyShfHome: "\x1b[1;2H",
|
||||
KeyShfEnd: "\x1b[1;2F",
|
||||
KeyCtrlHome: "\x1b[1;5H",
|
||||
KeyCtrlEnd: "\x1b[1;5F",
|
||||
KeyAltHome: "\x1b[1;9H",
|
||||
KeyAltEnd: "\x1b[1;9F",
|
||||
KeyCtrlShfHome: "\x1b[1;6H",
|
||||
KeyCtrlShfEnd: "\x1b[1;6F",
|
||||
KeyMetaShfHome: "\x1b[1;10H",
|
||||
KeyMetaShfEnd: "\x1b[1;10F",
|
||||
KeyAltShfHome: "\x1b[1;4H",
|
||||
KeyAltShfEnd: "\x1b[1;4F",
|
||||
})
|
||||
|
||||
// KDE console window with xterm 256-colors
|
||||
terminfo.AddTerminfo(&terminfo.Terminfo{
|
||||
Name: "konsole-256color",
|
||||
Columns: 80,
|
||||
Lines: 24,
|
||||
Colors: 256,
|
||||
Clear: "\x1b[H\x1b[2J",
|
||||
EnterCA: "\x1b7\x1b[?47h",
|
||||
ExitCA: "\x1b[2J\x1b[?47l\x1b8",
|
||||
ShowCursor: "\x1b[?25h",
|
||||
HideCursor: "\x1b[?25l",
|
||||
AttrOff: "\x1b[0m\x0f",
|
||||
Underline: "\x1b[4m",
|
||||
Bold: "\x1b[1m",
|
||||
Dim: "\x1b[2m",
|
||||
Blink: "\x1b[5m",
|
||||
Reverse: "\x1b[7m",
|
||||
EnterKeypad: "\x1b[?1h\x1b=",
|
||||
ExitKeypad: "\x1b[?1l\x1b>",
|
||||
SetFg: "\x1b[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m",
|
||||
SetBg: "\x1b[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m",
|
||||
SetFgBg: "\x1b[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;;%?%p2%{8}%<%t4%p2%d%e%p2%{16}%<%t10%p2%{8}%-%d%e48;5;%p2%d%;m",
|
||||
AltChars: "``aaffggiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~",
|
||||
EnterAcs: "\x0e",
|
||||
ExitAcs: "\x0f",
|
||||
EnableAcs: "\x1b)0",
|
||||
Mouse: "\x1b[M",
|
||||
MouseMode: "%?%p1%{1}%=%t%'h'%Pa%e%'l'%Pa%;\x1b[?1000%ga%c\x1b[?1002%ga%c\x1b[?1003%ga%c\x1b[?1006%ga%c",
|
||||
SetCursor: "\x1b[%i%p1%d;%p2%dH",
|
||||
CursorBack1: "\b",
|
||||
CursorUp1: "\x1b[A",
|
||||
KeyUp: "\x1bOA",
|
||||
KeyDown: "\x1bOB",
|
||||
KeyRight: "\x1bOC",
|
||||
KeyLeft: "\x1bOD",
|
||||
KeyInsert: "\x1b[2~",
|
||||
KeyDelete: "\x1b[3~",
|
||||
KeyBackspace: "\xff",
|
||||
KeyHome: "\x1bOH",
|
||||
KeyEnd: "\x1bOF",
|
||||
KeyPgUp: "\x1b[5~",
|
||||
KeyPgDn: "\x1b[6~",
|
||||
KeyF1: "\x1bOP",
|
||||
KeyF2: "\x1bOQ",
|
||||
KeyF3: "\x1bOR",
|
||||
KeyF4: "\x1bOS",
|
||||
KeyF5: "\x1b[15~",
|
||||
KeyF6: "\x1b[17~",
|
||||
KeyF7: "\x1b[18~",
|
||||
KeyF8: "\x1b[19~",
|
||||
KeyF9: "\x1b[20~",
|
||||
KeyF10: "\x1b[21~",
|
||||
KeyF11: "\x1b[23~",
|
||||
KeyF12: "\x1b[24~",
|
||||
KeyF13: "\x1bO2P",
|
||||
KeyF14: "\x1bO2Q",
|
||||
KeyF15: "\x1bO2R",
|
||||
KeyF16: "\x1bO2S",
|
||||
KeyF17: "\x1b[15;2~",
|
||||
KeyF18: "\x1b[17;2~",
|
||||
KeyF19: "\x1b[18;2~",
|
||||
KeyF20: "\x1b[19;2~",
|
||||
KeyF21: "\x1b[20;2~",
|
||||
KeyF22: "\x1b[21;2~",
|
||||
KeyF23: "\x1b[23;2~",
|
||||
KeyF24: "\x1b[24;2~",
|
||||
KeyF25: "\x1bO5P",
|
||||
KeyF26: "\x1bO5Q",
|
||||
KeyF27: "\x1bO5R",
|
||||
KeyF28: "\x1bO5S",
|
||||
KeyF29: "\x1b[15;5~",
|
||||
KeyF30: "\x1b[17;5~",
|
||||
KeyF31: "\x1b[18;5~",
|
||||
KeyF32: "\x1b[19;5~",
|
||||
KeyF33: "\x1b[20;5~",
|
||||
KeyF34: "\x1b[21;5~",
|
||||
KeyF35: "\x1b[23;5~",
|
||||
KeyF36: "\x1b[24;5~",
|
||||
KeyF37: "\x1bO6P",
|
||||
KeyF38: "\x1bO6Q",
|
||||
KeyF39: "\x1bO6R",
|
||||
KeyF40: "\x1bO6S",
|
||||
KeyF41: "\x1b[15;6~",
|
||||
KeyF42: "\x1b[17;6~",
|
||||
KeyF43: "\x1b[18;6~",
|
||||
KeyF44: "\x1b[19;6~",
|
||||
KeyF45: "\x1b[20;6~",
|
||||
KeyF46: "\x1b[21;6~",
|
||||
KeyF47: "\x1b[23;6~",
|
||||
KeyF48: "\x1b[24;6~",
|
||||
KeyF49: "\x1bO3P",
|
||||
KeyF50: "\x1bO3Q",
|
||||
KeyF51: "\x1bO3R",
|
||||
KeyF52: "\x1bO3S",
|
||||
KeyF53: "\x1b[15;3~",
|
||||
KeyF54: "\x1b[17;3~",
|
||||
KeyF55: "\x1b[18;3~",
|
||||
KeyF56: "\x1b[19;3~",
|
||||
KeyF57: "\x1b[20;3~",
|
||||
KeyF58: "\x1b[21;3~",
|
||||
KeyF59: "\x1b[23;3~",
|
||||
KeyF60: "\x1b[24;3~",
|
||||
KeyF61: "\x1bO4P",
|
||||
KeyF62: "\x1bO4Q",
|
||||
KeyF63: "\x1bO4R",
|
||||
KeyBacktab: "\x1b[Z",
|
||||
KeyShfLeft: "\x1b[1;2D",
|
||||
KeyShfRight: "\x1b[1;2C",
|
||||
KeyShfUp: "\x1b[1;2A",
|
||||
KeyShfDown: "\x1b[1;2B",
|
||||
KeyCtrlLeft: "\x1b[1;5D",
|
||||
KeyCtrlRight: "\x1b[1;5C",
|
||||
KeyCtrlUp: "\x1b[1;5A",
|
||||
KeyCtrlDown: "\x1b[1;5B",
|
||||
KeyMetaLeft: "\x1b[1;9D",
|
||||
KeyMetaRight: "\x1b[1;9C",
|
||||
KeyMetaUp: "\x1b[1;9A",
|
||||
KeyMetaDown: "\x1b[1;9B",
|
||||
KeyAltLeft: "\x1b[1;3D",
|
||||
KeyAltRight: "\x1b[1;3C",
|
||||
KeyAltUp: "\x1b[1;3A",
|
||||
KeyAltDown: "\x1b[1;3B",
|
||||
KeyAltShfLeft: "\x1b[1;4D",
|
||||
KeyAltShfRight: "\x1b[1;4C",
|
||||
KeyAltShfUp: "\x1b[1;4A",
|
||||
KeyAltShfDown: "\x1b[1;4B",
|
||||
KeyMetaShfLeft: "\x1b[1;10D",
|
||||
KeyMetaShfRight: "\x1b[1;10C",
|
||||
KeyMetaShfUp: "\x1b[1;10A",
|
||||
KeyMetaShfDown: "\x1b[1;10B",
|
||||
KeyCtrlShfLeft: "\x1b[1;6D",
|
||||
KeyCtrlShfRight: "\x1b[1;6C",
|
||||
KeyCtrlShfUp: "\x1b[1;6A",
|
||||
KeyCtrlShfDown: "\x1b[1;6B",
|
||||
KeyShfHome: "\x1b[1;2H",
|
||||
KeyShfEnd: "\x1b[1;2F",
|
||||
KeyCtrlHome: "\x1b[1;5H",
|
||||
KeyCtrlEnd: "\x1b[1;5F",
|
||||
KeyAltHome: "\x1b[1;9H",
|
||||
KeyAltEnd: "\x1b[1;9F",
|
||||
KeyCtrlShfHome: "\x1b[1;6H",
|
||||
KeyCtrlShfEnd: "\x1b[1;6F",
|
||||
KeyMetaShfHome: "\x1b[1;10H",
|
||||
KeyMetaShfEnd: "\x1b[1;10F",
|
||||
KeyAltShfHome: "\x1b[1;4H",
|
||||
KeyAltShfEnd: "\x1b[1;4F",
|
||||
})
|
||||
}
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
// Generated automatically. DO NOT HAND-EDIT.
|
||||
|
||||
package kterm
|
||||
|
||||
import "github.com/gdamore/tcell/terminfo"
|
||||
|
||||
func init() {
|
||||
|
||||
// kterm kanji terminal emulator (X window system)
|
||||
terminfo.AddTerminfo(&terminfo.Terminfo{
|
||||
Name: "kterm",
|
||||
Columns: 80,
|
||||
Lines: 24,
|
||||
Colors: 8,
|
||||
Bell: "\a",
|
||||
Clear: "\x1b[H\x1b[2J",
|
||||
EnterCA: "\x1b7\x1b[?47h",
|
||||
ExitCA: "\x1b[2J\x1b[?47l\x1b8",
|
||||
AttrOff: "\x1b[m\x1b(B",
|
||||
Underline: "\x1b[4m",
|
||||
Bold: "\x1b[1m",
|
||||
Reverse: "\x1b[7m",
|
||||
EnterKeypad: "\x1b[?1h\x1b=",
|
||||
ExitKeypad: "\x1b[?1l\x1b>",
|
||||
SetFg: "\x1b[3%p1%dm",
|
||||
SetBg: "\x1b[4%p1%dm",
|
||||
SetFgBg: "\x1b[3%p1%d;4%p2%dm",
|
||||
PadChar: "\x00",
|
||||
AltChars: "``aajjkkllmmnnooppqqrrssttuuvvwwxx~~",
|
||||
EnterAcs: "\x1b(0",
|
||||
ExitAcs: "\x1b(B",
|
||||
Mouse: "\x1b[M",
|
||||
MouseMode: "%?%p1%{1}%=%t%'h'%Pa%e%'l'%Pa%;\x1b[?1000%ga%c\x1b[?1002%ga%c\x1b[?1003%ga%c\x1b[?1006%ga%c",
|
||||
SetCursor: "\x1b[%i%p1%d;%p2%dH",
|
||||
CursorBack1: "\b",
|
||||
CursorUp1: "\x1b[A",
|
||||
KeyUp: "\x1bOA",
|
||||
KeyDown: "\x1bOB",
|
||||
KeyRight: "\x1bOC",
|
||||
KeyLeft: "\x1bOD",
|
||||
KeyInsert: "\x1b[2~",
|
||||
KeyDelete: "\x1b[3~",
|
||||
KeyBackspace: "\xff",
|
||||
KeyPgUp: "\x1b[5~",
|
||||
KeyPgDn: "\x1b[6~",
|
||||
KeyF1: "\x1b[11~",
|
||||
KeyF2: "\x1b[12~",
|
||||
KeyF3: "\x1b[13~",
|
||||
KeyF4: "\x1b[14~",
|
||||
KeyF5: "\x1b[15~",
|
||||
KeyF6: "\x1b[17~",
|
||||
KeyF7: "\x1b[18~",
|
||||
KeyF8: "\x1b[19~",
|
||||
KeyF9: "\x1b[20~",
|
||||
KeyF10: "\x1b[21~",
|
||||
KeyF11: "\x1b[23~",
|
||||
KeyF12: "\x1b[24~",
|
||||
KeyF13: "\x1b[25~",
|
||||
KeyF14: "\x1b[26~",
|
||||
KeyF15: "\x1b[28~",
|
||||
KeyF16: "\x1b[29~",
|
||||
KeyF17: "\x1b[31~",
|
||||
KeyF18: "\x1b[32~",
|
||||
KeyF19: "\x1b[33~",
|
||||
KeyF20: "\x1b[34~",
|
||||
})
|
||||
}
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
// Generated automatically. DO NOT HAND-EDIT.
|
||||
|
||||
package linux
|
||||
|
||||
import "github.com/gdamore/tcell/terminfo"
|
||||
|
||||
func init() {
|
||||
|
||||
// linux console
|
||||
terminfo.AddTerminfo(&terminfo.Terminfo{
|
||||
Name: "linux",
|
||||
Colors: 8,
|
||||
Bell: "\a",
|
||||
Clear: "\x1b[H\x1b[J",
|
||||
ShowCursor: "\x1b[?25h\x1b[?0c",
|
||||
HideCursor: "\x1b[?25l\x1b[?1c",
|
||||
AttrOff: "\x1b[m\x0f",
|
||||
Underline: "\x1b[4m",
|
||||
Bold: "\x1b[1m",
|
||||
Dim: "\x1b[2m",
|
||||
Blink: "\x1b[5m",
|
||||
Reverse: "\x1b[7m",
|
||||
SetFg: "\x1b[3%p1%dm",
|
||||
SetBg: "\x1b[4%p1%dm",
|
||||
SetFgBg: "\x1b[3%p1%d;4%p2%dm",
|
||||
PadChar: "\x00",
|
||||
AltChars: "++,,--..00__``aaffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}c~~",
|
||||
EnterAcs: "\x0e",
|
||||
ExitAcs: "\x0f",
|
||||
EnableAcs: "\x1b)0",
|
||||
Mouse: "\x1b[M",
|
||||
MouseMode: "%?%p1%{1}%=%t%'h'%Pa%e%'l'%Pa%;\x1b[?1000%ga%c\x1b[?1002%ga%c\x1b[?1003%ga%c\x1b[?1006%ga%c",
|
||||
SetCursor: "\x1b[%i%p1%d;%p2%dH",
|
||||
CursorBack1: "\b",
|
||||
CursorUp1: "\x1b[A",
|
||||
KeyUp: "\x1b[A",
|
||||
KeyDown: "\x1b[B",
|
||||
KeyRight: "\x1b[C",
|
||||
KeyLeft: "\x1b[D",
|
||||
KeyInsert: "\x1b[2~",
|
||||
KeyDelete: "\x1b[3~",
|
||||
KeyBackspace: "\xff",
|
||||
KeyHome: "\x1b[1~",
|
||||
KeyEnd: "\x1b[4~",
|
||||
KeyPgUp: "\x1b[5~",
|
||||
KeyPgDn: "\x1b[6~",
|
||||
KeyF1: "\x1b[[A",
|
||||
KeyF2: "\x1b[[B",
|
||||
KeyF3: "\x1b[[C",
|
||||
KeyF4: "\x1b[[D",
|
||||
KeyF5: "\x1b[[E",
|
||||
KeyF6: "\x1b[17~",
|
||||
KeyF7: "\x1b[18~",
|
||||
KeyF8: "\x1b[19~",
|
||||
KeyF9: "\x1b[20~",
|
||||
KeyF10: "\x1b[21~",
|
||||
KeyF11: "\x1b[23~",
|
||||
KeyF12: "\x1b[24~",
|
||||
KeyF13: "\x1b[25~",
|
||||
KeyF14: "\x1b[26~",
|
||||
KeyF15: "\x1b[28~",
|
||||
KeyF16: "\x1b[29~",
|
||||
KeyF17: "\x1b[31~",
|
||||
KeyF18: "\x1b[32~",
|
||||
KeyF19: "\x1b[33~",
|
||||
KeyF20: "\x1b[34~",
|
||||
KeyBacktab: "\x1b[Z",
|
||||
})
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
adm3a
|
||||
aixterm
|
||||
ansi
|
||||
aterm
|
||||
beterm
|
||||
bsdos-pc
|
||||
cygwin
|
||||
d200
|
||||
d210
|
||||
dtterm
|
||||
eterm,eterm-color|emacs
|
||||
Eterm,Eterm-88color,Eterm-256color|eterm
|
||||
gnome,gnome-256color
|
||||
hpterm
|
||||
hz1500
|
||||
konsole,konsole-256color
|
||||
kterm
|
||||
linux
|
||||
pcansi
|
||||
rxvt,rxvt-256color,rxvt-88color,rxvt-unicode,rxvt-unicode-256color
|
||||
screen,screen-256color
|
||||
st,st-256color|simpleterm
|
||||
sun,sun-color
|
||||
termite
|
||||
tvi910
|
||||
tvi912
|
||||
tvi921
|
||||
tvi925
|
||||
tvi950
|
||||
tvi970
|
||||
vt52
|
||||
vt100
|
||||
vt102
|
||||
vt220
|
||||
vt320
|
||||
vt400
|
||||
vt420
|
||||
wy50
|
||||
wy60
|
||||
wy99-ansi,wy99a-ansi
|
||||
xfce
|
||||
xnuppc
|
||||
xterm,xterm-88color,xterm-256color
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
// Generated automatically. DO NOT HAND-EDIT.
|
||||
|
||||
package pcansi
|
||||
|
||||
import "github.com/gdamore/tcell/terminfo"
|
||||
|
||||
func init() {
|
||||
|
||||
// ibm-pc terminal programs claiming to be ansi
|
||||
terminfo.AddTerminfo(&terminfo.Terminfo{
|
||||
Name: "pcansi",
|
||||
Columns: 80,
|
||||
Lines: 24,
|
||||
Colors: 8,
|
||||
Bell: "\a",
|
||||
Clear: "\x1b[H\x1b[J",
|
||||
AttrOff: "\x1b[0;10m",
|
||||
Underline: "\x1b[4m",
|
||||
Bold: "\x1b[1m",
|
||||
Blink: "\x1b[5m",
|
||||
Reverse: "\x1b[7m",
|
||||
SetFg: "\x1b[3%p1%dm",
|
||||
SetBg: "\x1b[4%p1%dm",
|
||||
SetFgBg: "\x1b[3%p1%d;4%p2%dm",
|
||||
PadChar: "\x00",
|
||||
AltChars: "+\x10,\x11-\x18.\x190\xdb`\x04a\xb1f\xf8g\xf1h\xb0j\xd9k\xbfl\xdam\xc0n\xc5o~p\xc4q\xc4r\xc4s_t\xc3u\xb4v\xc1w\xc2x\xb3y\xf3z\xf2{\xe3|\xd8}\x9c~\xfe",
|
||||
EnterAcs: "\x1b[12m",
|
||||
ExitAcs: "\x1b[10m",
|
||||
SetCursor: "\x1b[%i%p1%d;%p2%dH",
|
||||
CursorBack1: "\x1b[D",
|
||||
CursorUp1: "\x1b[A",
|
||||
KeyUp: "\x1b[A",
|
||||
KeyDown: "\x1b[B",
|
||||
KeyRight: "\x1b[C",
|
||||
KeyLeft: "\x1b[D",
|
||||
KeyBackspace: "\b",
|
||||
KeyHome: "\x1b[H",
|
||||
})
|
||||
}
|
||||
+466
@@ -0,0 +1,466 @@
|
||||
// Generated automatically. DO NOT HAND-EDIT.
|
||||
|
||||
package rxvt
|
||||
|
||||
import "github.com/gdamore/tcell/terminfo"
|
||||
|
||||
func init() {
|
||||
|
||||
// rxvt terminal emulator (X Window System)
|
||||
terminfo.AddTerminfo(&terminfo.Terminfo{
|
||||
Name: "rxvt",
|
||||
Columns: 80,
|
||||
Lines: 24,
|
||||
Colors: 8,
|
||||
Bell: "\a",
|
||||
Clear: "\x1b[H\x1b[2J",
|
||||
EnterCA: "\x1b7\x1b[?47h",
|
||||
ExitCA: "\x1b[2J\x1b[?47l\x1b8",
|
||||
ShowCursor: "\x1b[?25h",
|
||||
HideCursor: "\x1b[?25l",
|
||||
AttrOff: "\x1b[m\x0f",
|
||||
Underline: "\x1b[4m",
|
||||
Bold: "\x1b[1m",
|
||||
Blink: "\x1b[5m",
|
||||
Reverse: "\x1b[7m",
|
||||
EnterKeypad: "\x1b=",
|
||||
ExitKeypad: "\x1b>",
|
||||
SetFg: "\x1b[3%p1%dm",
|
||||
SetBg: "\x1b[4%p1%dm",
|
||||
SetFgBg: "\x1b[3%p1%d;4%p2%dm",
|
||||
PadChar: "\x00",
|
||||
AltChars: "``aaffggjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~",
|
||||
EnterAcs: "\x0e",
|
||||
ExitAcs: "\x0f",
|
||||
EnableAcs: "\x1b(B\x1b)0",
|
||||
Mouse: "\x1b[M",
|
||||
MouseMode: "%?%p1%{1}%=%t%'h'%Pa%e%'l'%Pa%;\x1b[?1000%ga%c\x1b[?1002%ga%c\x1b[?1003%ga%c\x1b[?1006%ga%c",
|
||||
SetCursor: "\x1b[%i%p1%d;%p2%dH",
|
||||
CursorBack1: "\b",
|
||||
CursorUp1: "\x1b[A",
|
||||
KeyUp: "\x1b[A",
|
||||
KeyDown: "\x1b[B",
|
||||
KeyRight: "\x1b[C",
|
||||
KeyLeft: "\x1b[D",
|
||||
KeyInsert: "\x1b[2~",
|
||||
KeyDelete: "\x1b[3~",
|
||||
KeyBackspace: "\xff",
|
||||
KeyHome: "\x1b[7~",
|
||||
KeyEnd: "\x1b[8~",
|
||||
KeyPgUp: "\x1b[5~",
|
||||
KeyPgDn: "\x1b[6~",
|
||||
KeyF1: "\x1b[11~",
|
||||
KeyF2: "\x1b[12~",
|
||||
KeyF3: "\x1b[13~",
|
||||
KeyF4: "\x1b[14~",
|
||||
KeyF5: "\x1b[15~",
|
||||
KeyF6: "\x1b[17~",
|
||||
KeyF7: "\x1b[18~",
|
||||
KeyF8: "\x1b[19~",
|
||||
KeyF9: "\x1b[20~",
|
||||
KeyF10: "\x1b[21~",
|
||||
KeyF11: "\x1b[23~",
|
||||
KeyF12: "\x1b[24~",
|
||||
KeyF13: "\x1b[25~",
|
||||
KeyF14: "\x1b[26~",
|
||||
KeyF15: "\x1b[28~",
|
||||
KeyF16: "\x1b[29~",
|
||||
KeyF17: "\x1b[31~",
|
||||
KeyF18: "\x1b[32~",
|
||||
KeyF19: "\x1b[33~",
|
||||
KeyF20: "\x1b[34~",
|
||||
KeyF21: "\x1b[23$",
|
||||
KeyF22: "\x1b[24$",
|
||||
KeyF23: "\x1b[11^",
|
||||
KeyF24: "\x1b[12^",
|
||||
KeyF25: "\x1b[13^",
|
||||
KeyF26: "\x1b[14^",
|
||||
KeyF27: "\x1b[15^",
|
||||
KeyF28: "\x1b[17^",
|
||||
KeyF29: "\x1b[18^",
|
||||
KeyF30: "\x1b[19^",
|
||||
KeyF31: "\x1b[20^",
|
||||
KeyF32: "\x1b[21^",
|
||||
KeyF33: "\x1b[23^",
|
||||
KeyF34: "\x1b[24^",
|
||||
KeyF35: "\x1b[25^",
|
||||
KeyF36: "\x1b[26^",
|
||||
KeyF37: "\x1b[28^",
|
||||
KeyF38: "\x1b[29^",
|
||||
KeyF39: "\x1b[31^",
|
||||
KeyF40: "\x1b[32^",
|
||||
KeyF41: "\x1b[33^",
|
||||
KeyF42: "\x1b[34^",
|
||||
KeyF43: "\x1b[23@",
|
||||
KeyF44: "\x1b[24@",
|
||||
KeyBacktab: "\x1b[Z",
|
||||
KeyShfLeft: "\x1b[d",
|
||||
KeyShfRight: "\x1b[c",
|
||||
KeyShfUp: "\x1b[a",
|
||||
KeyShfDown: "\x1b[b",
|
||||
KeyCtrlLeft: "\x1b[Od",
|
||||
KeyCtrlRight: "\x1b[Oc",
|
||||
KeyCtrlUp: "\x1b[Oa",
|
||||
KeyCtrlDown: "\x1b[Ob",
|
||||
KeyShfHome: "\x1b[7$",
|
||||
KeyShfEnd: "\x1b[8$",
|
||||
KeyCtrlHome: "\x1b[7^",
|
||||
KeyCtrlEnd: "\x1b[8^",
|
||||
})
|
||||
|
||||
// rxvt 2.7.9 with xterm 256-colors
|
||||
terminfo.AddTerminfo(&terminfo.Terminfo{
|
||||
Name: "rxvt-256color",
|
||||
Columns: 80,
|
||||
Lines: 24,
|
||||
Colors: 256,
|
||||
Bell: "\a",
|
||||
Clear: "\x1b[H\x1b[2J",
|
||||
EnterCA: "\x1b7\x1b[?47h",
|
||||
ExitCA: "\x1b[2J\x1b[?47l\x1b8",
|
||||
ShowCursor: "\x1b[?25h",
|
||||
HideCursor: "\x1b[?25l",
|
||||
AttrOff: "\x1b[m\x0f",
|
||||
Underline: "\x1b[4m",
|
||||
Bold: "\x1b[1m",
|
||||
Blink: "\x1b[5m",
|
||||
Reverse: "\x1b[7m",
|
||||
EnterKeypad: "\x1b=",
|
||||
ExitKeypad: "\x1b>",
|
||||
SetFg: "\x1b[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m",
|
||||
SetBg: "\x1b[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m",
|
||||
SetFgBg: "\x1b[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;;%?%p2%{8}%<%t4%p2%d%e%p2%{16}%<%t10%p2%{8}%-%d%e48;5;%p2%d%;m",
|
||||
PadChar: "\x00",
|
||||
AltChars: "``aaffggjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~",
|
||||
EnterAcs: "\x0e",
|
||||
ExitAcs: "\x0f",
|
||||
EnableAcs: "\x1b(B\x1b)0",
|
||||
Mouse: "\x1b[M",
|
||||
MouseMode: "%?%p1%{1}%=%t%'h'%Pa%e%'l'%Pa%;\x1b[?1000%ga%c\x1b[?1002%ga%c\x1b[?1003%ga%c\x1b[?1006%ga%c",
|
||||
SetCursor: "\x1b[%i%p1%d;%p2%dH",
|
||||
CursorBack1: "\b",
|
||||
CursorUp1: "\x1b[A",
|
||||
KeyUp: "\x1b[A",
|
||||
KeyDown: "\x1b[B",
|
||||
KeyRight: "\x1b[C",
|
||||
KeyLeft: "\x1b[D",
|
||||
KeyInsert: "\x1b[2~",
|
||||
KeyDelete: "\x1b[3~",
|
||||
KeyBackspace: "\xff",
|
||||
KeyHome: "\x1b[7~",
|
||||
KeyEnd: "\x1b[8~",
|
||||
KeyPgUp: "\x1b[5~",
|
||||
KeyPgDn: "\x1b[6~",
|
||||
KeyF1: "\x1b[11~",
|
||||
KeyF2: "\x1b[12~",
|
||||
KeyF3: "\x1b[13~",
|
||||
KeyF4: "\x1b[14~",
|
||||
KeyF5: "\x1b[15~",
|
||||
KeyF6: "\x1b[17~",
|
||||
KeyF7: "\x1b[18~",
|
||||
KeyF8: "\x1b[19~",
|
||||
KeyF9: "\x1b[20~",
|
||||
KeyF10: "\x1b[21~",
|
||||
KeyF11: "\x1b[23~",
|
||||
KeyF12: "\x1b[24~",
|
||||
KeyF13: "\x1b[25~",
|
||||
KeyF14: "\x1b[26~",
|
||||
KeyF15: "\x1b[28~",
|
||||
KeyF16: "\x1b[29~",
|
||||
KeyF17: "\x1b[31~",
|
||||
KeyF18: "\x1b[32~",
|
||||
KeyF19: "\x1b[33~",
|
||||
KeyF20: "\x1b[34~",
|
||||
KeyF21: "\x1b[23$",
|
||||
KeyF22: "\x1b[24$",
|
||||
KeyF23: "\x1b[11^",
|
||||
KeyF24: "\x1b[12^",
|
||||
KeyF25: "\x1b[13^",
|
||||
KeyF26: "\x1b[14^",
|
||||
KeyF27: "\x1b[15^",
|
||||
KeyF28: "\x1b[17^",
|
||||
KeyF29: "\x1b[18^",
|
||||
KeyF30: "\x1b[19^",
|
||||
KeyF31: "\x1b[20^",
|
||||
KeyF32: "\x1b[21^",
|
||||
KeyF33: "\x1b[23^",
|
||||
KeyF34: "\x1b[24^",
|
||||
KeyF35: "\x1b[25^",
|
||||
KeyF36: "\x1b[26^",
|
||||
KeyF37: "\x1b[28^",
|
||||
KeyF38: "\x1b[29^",
|
||||
KeyF39: "\x1b[31^",
|
||||
KeyF40: "\x1b[32^",
|
||||
KeyF41: "\x1b[33^",
|
||||
KeyF42: "\x1b[34^",
|
||||
KeyF43: "\x1b[23@",
|
||||
KeyF44: "\x1b[24@",
|
||||
KeyBacktab: "\x1b[Z",
|
||||
KeyShfLeft: "\x1b[d",
|
||||
KeyShfRight: "\x1b[c",
|
||||
KeyShfUp: "\x1b[a",
|
||||
KeyShfDown: "\x1b[b",
|
||||
KeyCtrlLeft: "\x1b[Od",
|
||||
KeyCtrlRight: "\x1b[Oc",
|
||||
KeyCtrlUp: "\x1b[Oa",
|
||||
KeyCtrlDown: "\x1b[Ob",
|
||||
KeyShfHome: "\x1b[7$",
|
||||
KeyShfEnd: "\x1b[8$",
|
||||
KeyCtrlHome: "\x1b[7^",
|
||||
KeyCtrlEnd: "\x1b[8^",
|
||||
})
|
||||
|
||||
// rxvt 2.7.9 with xterm 88-colors
|
||||
terminfo.AddTerminfo(&terminfo.Terminfo{
|
||||
Name: "rxvt-88color",
|
||||
Columns: 80,
|
||||
Lines: 24,
|
||||
Colors: 88,
|
||||
Bell: "\a",
|
||||
Clear: "\x1b[H\x1b[2J",
|
||||
EnterCA: "\x1b7\x1b[?47h",
|
||||
ExitCA: "\x1b[2J\x1b[?47l\x1b8",
|
||||
ShowCursor: "\x1b[?25h",
|
||||
HideCursor: "\x1b[?25l",
|
||||
AttrOff: "\x1b[m\x0f",
|
||||
Underline: "\x1b[4m",
|
||||
Bold: "\x1b[1m",
|
||||
Blink: "\x1b[5m",
|
||||
Reverse: "\x1b[7m",
|
||||
EnterKeypad: "\x1b=",
|
||||
ExitKeypad: "\x1b>",
|
||||
SetFg: "\x1b[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m",
|
||||
SetBg: "\x1b[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m",
|
||||
SetFgBg: "\x1b[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;;%?%p2%{8}%<%t4%p2%d%e%p2%{16}%<%t10%p2%{8}%-%d%e48;5;%p2%d%;m",
|
||||
PadChar: "\x00",
|
||||
AltChars: "``aaffggjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~",
|
||||
EnterAcs: "\x0e",
|
||||
ExitAcs: "\x0f",
|
||||
EnableAcs: "\x1b(B\x1b)0",
|
||||
Mouse: "\x1b[M",
|
||||
MouseMode: "%?%p1%{1}%=%t%'h'%Pa%e%'l'%Pa%;\x1b[?1000%ga%c\x1b[?1002%ga%c\x1b[?1003%ga%c\x1b[?1006%ga%c",
|
||||
SetCursor: "\x1b[%i%p1%d;%p2%dH",
|
||||
CursorBack1: "\b",
|
||||
CursorUp1: "\x1b[A",
|
||||
KeyUp: "\x1b[A",
|
||||
KeyDown: "\x1b[B",
|
||||
KeyRight: "\x1b[C",
|
||||
KeyLeft: "\x1b[D",
|
||||
KeyInsert: "\x1b[2~",
|
||||
KeyDelete: "\x1b[3~",
|
||||
KeyBackspace: "\xff",
|
||||
KeyHome: "\x1b[7~",
|
||||
KeyEnd: "\x1b[8~",
|
||||
KeyPgUp: "\x1b[5~",
|
||||
KeyPgDn: "\x1b[6~",
|
||||
KeyF1: "\x1b[11~",
|
||||
KeyF2: "\x1b[12~",
|
||||
KeyF3: "\x1b[13~",
|
||||
KeyF4: "\x1b[14~",
|
||||
KeyF5: "\x1b[15~",
|
||||
KeyF6: "\x1b[17~",
|
||||
KeyF7: "\x1b[18~",
|
||||
KeyF8: "\x1b[19~",
|
||||
KeyF9: "\x1b[20~",
|
||||
KeyF10: "\x1b[21~",
|
||||
KeyF11: "\x1b[23~",
|
||||
KeyF12: "\x1b[24~",
|
||||
KeyF13: "\x1b[25~",
|
||||
KeyF14: "\x1b[26~",
|
||||
KeyF15: "\x1b[28~",
|
||||
KeyF16: "\x1b[29~",
|
||||
KeyF17: "\x1b[31~",
|
||||
KeyF18: "\x1b[32~",
|
||||
KeyF19: "\x1b[33~",
|
||||
KeyF20: "\x1b[34~",
|
||||
KeyF21: "\x1b[23$",
|
||||
KeyF22: "\x1b[24$",
|
||||
KeyF23: "\x1b[11^",
|
||||
KeyF24: "\x1b[12^",
|
||||
KeyF25: "\x1b[13^",
|
||||
KeyF26: "\x1b[14^",
|
||||
KeyF27: "\x1b[15^",
|
||||
KeyF28: "\x1b[17^",
|
||||
KeyF29: "\x1b[18^",
|
||||
KeyF30: "\x1b[19^",
|
||||
KeyF31: "\x1b[20^",
|
||||
KeyF32: "\x1b[21^",
|
||||
KeyF33: "\x1b[23^",
|
||||
KeyF34: "\x1b[24^",
|
||||
KeyF35: "\x1b[25^",
|
||||
KeyF36: "\x1b[26^",
|
||||
KeyF37: "\x1b[28^",
|
||||
KeyF38: "\x1b[29^",
|
||||
KeyF39: "\x1b[31^",
|
||||
KeyF40: "\x1b[32^",
|
||||
KeyF41: "\x1b[33^",
|
||||
KeyF42: "\x1b[34^",
|
||||
KeyF43: "\x1b[23@",
|
||||
KeyF44: "\x1b[24@",
|
||||
KeyBacktab: "\x1b[Z",
|
||||
KeyShfLeft: "\x1b[d",
|
||||
KeyShfRight: "\x1b[c",
|
||||
KeyShfUp: "\x1b[a",
|
||||
KeyShfDown: "\x1b[b",
|
||||
KeyCtrlLeft: "\x1b[Od",
|
||||
KeyCtrlRight: "\x1b[Oc",
|
||||
KeyCtrlUp: "\x1b[Oa",
|
||||
KeyCtrlDown: "\x1b[Ob",
|
||||
KeyShfHome: "\x1b[7$",
|
||||
KeyShfEnd: "\x1b[8$",
|
||||
KeyCtrlHome: "\x1b[7^",
|
||||
KeyCtrlEnd: "\x1b[8^",
|
||||
})
|
||||
|
||||
// rxvt-unicode terminal (X Window System)
|
||||
terminfo.AddTerminfo(&terminfo.Terminfo{
|
||||
Name: "rxvt-unicode",
|
||||
Columns: 80,
|
||||
Lines: 24,
|
||||
Colors: 88,
|
||||
Bell: "\a",
|
||||
Clear: "\x1b[H\x1b[2J",
|
||||
EnterCA: "\x1b[?1049h",
|
||||
ExitCA: "\x1b[r\x1b[?1049l",
|
||||
ShowCursor: "\x1b[?12l\x1b[?25h",
|
||||
HideCursor: "\x1b[?25l",
|
||||
AttrOff: "\x1b[m\x1b(B",
|
||||
Underline: "\x1b[4m",
|
||||
Bold: "\x1b[1m",
|
||||
Blink: "\x1b[5m",
|
||||
Reverse: "\x1b[7m",
|
||||
EnterKeypad: "\x1b=",
|
||||
ExitKeypad: "\x1b>",
|
||||
SetFg: "\x1b[38;5;%p1%dm",
|
||||
SetBg: "\x1b[48;5;%p1%dm",
|
||||
SetFgBg: "\x1b[38;5;%p1%d;48;5;%p2%dm",
|
||||
AltChars: "+C,D-A.B0E``aaffgghFiGjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~",
|
||||
EnterAcs: "\x1b(0",
|
||||
ExitAcs: "\x1b(B",
|
||||
Mouse: "\x1b[M",
|
||||
MouseMode: "%?%p1%{1}%=%t%'h'%Pa%e%'l'%Pa%;\x1b[?1000%ga%c\x1b[?1002%ga%c\x1b[?1003%ga%c\x1b[?1006%ga%c",
|
||||
SetCursor: "\x1b[%i%p1%d;%p2%dH",
|
||||
CursorBack1: "\b",
|
||||
CursorUp1: "\x1b[A",
|
||||
KeyUp: "\x1b[A",
|
||||
KeyDown: "\x1b[B",
|
||||
KeyRight: "\x1b[C",
|
||||
KeyLeft: "\x1b[D",
|
||||
KeyInsert: "\x1b[2~",
|
||||
KeyDelete: "\x1b[3~",
|
||||
KeyBackspace: "\xff",
|
||||
KeyHome: "\x1b[7~",
|
||||
KeyEnd: "\x1b[8~",
|
||||
KeyPgUp: "\x1b[5~",
|
||||
KeyPgDn: "\x1b[6~",
|
||||
KeyF1: "\x1b[11~",
|
||||
KeyF2: "\x1b[12~",
|
||||
KeyF3: "\x1b[13~",
|
||||
KeyF4: "\x1b[14~",
|
||||
KeyF5: "\x1b[15~",
|
||||
KeyF6: "\x1b[17~",
|
||||
KeyF7: "\x1b[18~",
|
||||
KeyF8: "\x1b[19~",
|
||||
KeyF9: "\x1b[20~",
|
||||
KeyF10: "\x1b[21~",
|
||||
KeyF11: "\x1b[23~",
|
||||
KeyF12: "\x1b[24~",
|
||||
KeyF13: "\x1b[25~",
|
||||
KeyF14: "\x1b[26~",
|
||||
KeyF15: "\x1b[28~",
|
||||
KeyF16: "\x1b[29~",
|
||||
KeyF17: "\x1b[31~",
|
||||
KeyF18: "\x1b[32~",
|
||||
KeyF19: "\x1b[33~",
|
||||
KeyF20: "\x1b[34~",
|
||||
KeyBacktab: "\x1b[Z",
|
||||
KeyShfLeft: "\x1b[d",
|
||||
KeyShfRight: "\x1b[c",
|
||||
KeyShfUp: "\x1b[a",
|
||||
KeyShfDown: "\x1b[b",
|
||||
KeyCtrlLeft: "\x1b[Od",
|
||||
KeyCtrlRight: "\x1b[Oc",
|
||||
KeyCtrlUp: "\x1b[Oa",
|
||||
KeyCtrlDown: "\x1b[Ob",
|
||||
KeyShfHome: "\x1b[7$",
|
||||
KeyShfEnd: "\x1b[8$",
|
||||
KeyCtrlHome: "\x1b[7^",
|
||||
KeyCtrlEnd: "\x1b[8^",
|
||||
})
|
||||
|
||||
// rxvt-unicode terminal with 256 colors (X Window System)
|
||||
terminfo.AddTerminfo(&terminfo.Terminfo{
|
||||
Name: "rxvt-unicode-256color",
|
||||
Columns: 80,
|
||||
Lines: 24,
|
||||
Colors: 256,
|
||||
Bell: "\a",
|
||||
Clear: "\x1b[H\x1b[2J",
|
||||
EnterCA: "\x1b[?1049h",
|
||||
ExitCA: "\x1b[r\x1b[?1049l",
|
||||
ShowCursor: "\x1b[?12l\x1b[?25h",
|
||||
HideCursor: "\x1b[?25l",
|
||||
AttrOff: "\x1b[m\x1b(B",
|
||||
Underline: "\x1b[4m",
|
||||
Bold: "\x1b[1m",
|
||||
Blink: "\x1b[5m",
|
||||
Reverse: "\x1b[7m",
|
||||
EnterKeypad: "\x1b=",
|
||||
ExitKeypad: "\x1b>",
|
||||
SetFg: "\x1b[38;5;%p1%dm",
|
||||
SetBg: "\x1b[48;5;%p1%dm",
|
||||
SetFgBg: "\x1b[38;5;%p1%d;48;5;%p2%dm",
|
||||
AltChars: "+C,D-A.B0E``aaffgghFiGjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~",
|
||||
EnterAcs: "\x1b(0",
|
||||
ExitAcs: "\x1b(B",
|
||||
Mouse: "\x1b[M",
|
||||
MouseMode: "%?%p1%{1}%=%t%'h'%Pa%e%'l'%Pa%;\x1b[?1000%ga%c\x1b[?1002%ga%c\x1b[?1003%ga%c\x1b[?1006%ga%c",
|
||||
SetCursor: "\x1b[%i%p1%d;%p2%dH",
|
||||
CursorBack1: "\b",
|
||||
CursorUp1: "\x1b[A",
|
||||
KeyUp: "\x1b[A",
|
||||
KeyDown: "\x1b[B",
|
||||
KeyRight: "\x1b[C",
|
||||
KeyLeft: "\x1b[D",
|
||||
KeyInsert: "\x1b[2~",
|
||||
KeyDelete: "\x1b[3~",
|
||||
KeyBackspace: "\xff",
|
||||
KeyHome: "\x1b[7~",
|
||||
KeyEnd: "\x1b[8~",
|
||||
KeyPgUp: "\x1b[5~",
|
||||
KeyPgDn: "\x1b[6~",
|
||||
KeyF1: "\x1b[11~",
|
||||
KeyF2: "\x1b[12~",
|
||||
KeyF3: "\x1b[13~",
|
||||
KeyF4: "\x1b[14~",
|
||||
KeyF5: "\x1b[15~",
|
||||
KeyF6: "\x1b[17~",
|
||||
KeyF7: "\x1b[18~",
|
||||
KeyF8: "\x1b[19~",
|
||||
KeyF9: "\x1b[20~",
|
||||
KeyF10: "\x1b[21~",
|
||||
KeyF11: "\x1b[23~",
|
||||
KeyF12: "\x1b[24~",
|
||||
KeyF13: "\x1b[25~",
|
||||
KeyF14: "\x1b[26~",
|
||||
KeyF15: "\x1b[28~",
|
||||
KeyF16: "\x1b[29~",
|
||||
KeyF17: "\x1b[31~",
|
||||
KeyF18: "\x1b[32~",
|
||||
KeyF19: "\x1b[33~",
|
||||
KeyF20: "\x1b[34~",
|
||||
KeyBacktab: "\x1b[Z",
|
||||
KeyShfLeft: "\x1b[d",
|
||||
KeyShfRight: "\x1b[c",
|
||||
KeyShfUp: "\x1b[a",
|
||||
KeyShfDown: "\x1b[b",
|
||||
KeyCtrlLeft: "\x1b[Od",
|
||||
KeyCtrlRight: "\x1b[Oc",
|
||||
KeyCtrlUp: "\x1b[Oa",
|
||||
KeyCtrlDown: "\x1b[Ob",
|
||||
KeyShfHome: "\x1b[7$",
|
||||
KeyShfEnd: "\x1b[8$",
|
||||
KeyCtrlHome: "\x1b[7^",
|
||||
KeyCtrlEnd: "\x1b[8^",
|
||||
})
|
||||
}
|
||||
+126
@@ -0,0 +1,126 @@
|
||||
// Generated automatically. DO NOT HAND-EDIT.
|
||||
|
||||
package screen
|
||||
|
||||
import "github.com/gdamore/tcell/terminfo"
|
||||
|
||||
func init() {
|
||||
|
||||
// VT 100/ANSI X3.64 virtual terminal
|
||||
terminfo.AddTerminfo(&terminfo.Terminfo{
|
||||
Name: "screen",
|
||||
Columns: 80,
|
||||
Lines: 24,
|
||||
Colors: 8,
|
||||
Bell: "\a",
|
||||
Clear: "\x1b[H\x1b[J",
|
||||
EnterCA: "\x1b[?1049h",
|
||||
ExitCA: "\x1b[?1049l",
|
||||
ShowCursor: "\x1b[34h\x1b[?25h",
|
||||
HideCursor: "\x1b[?25l",
|
||||
AttrOff: "\x1b[m\x0f",
|
||||
Underline: "\x1b[4m",
|
||||
Bold: "\x1b[1m",
|
||||
Dim: "\x1b[2m",
|
||||
Blink: "\x1b[5m",
|
||||
Reverse: "\x1b[7m",
|
||||
EnterKeypad: "\x1b[?1h\x1b=",
|
||||
ExitKeypad: "\x1b[?1l\x1b>",
|
||||
SetFg: "\x1b[3%p1%dm",
|
||||
SetBg: "\x1b[4%p1%dm",
|
||||
SetFgBg: "\x1b[3%p1%d;4%p2%dm",
|
||||
PadChar: "\x00",
|
||||
AltChars: "++,,--..00``aaffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~",
|
||||
EnterAcs: "\x0e",
|
||||
ExitAcs: "\x0f",
|
||||
EnableAcs: "\x1b(B\x1b)0",
|
||||
Mouse: "\x1b[M",
|
||||
MouseMode: "%?%p1%{1}%=%t%'h'%Pa%e%'l'%Pa%;\x1b[?1000%ga%c\x1b[?1002%ga%c\x1b[?1003%ga%c\x1b[?1006%ga%c",
|
||||
SetCursor: "\x1b[%i%p1%d;%p2%dH",
|
||||
CursorBack1: "\b",
|
||||
CursorUp1: "\x1bM",
|
||||
KeyUp: "\x1bOA",
|
||||
KeyDown: "\x1bOB",
|
||||
KeyRight: "\x1bOC",
|
||||
KeyLeft: "\x1bOD",
|
||||
KeyInsert: "\x1b[2~",
|
||||
KeyDelete: "\x1b[3~",
|
||||
KeyBackspace: "\xff",
|
||||
KeyHome: "\x1b[1~",
|
||||
KeyEnd: "\x1b[4~",
|
||||
KeyPgUp: "\x1b[5~",
|
||||
KeyPgDn: "\x1b[6~",
|
||||
KeyF1: "\x1bOP",
|
||||
KeyF2: "\x1bOQ",
|
||||
KeyF3: "\x1bOR",
|
||||
KeyF4: "\x1bOS",
|
||||
KeyF5: "\x1b[15~",
|
||||
KeyF6: "\x1b[17~",
|
||||
KeyF7: "\x1b[18~",
|
||||
KeyF8: "\x1b[19~",
|
||||
KeyF9: "\x1b[20~",
|
||||
KeyF10: "\x1b[21~",
|
||||
KeyF11: "\x1b[23~",
|
||||
KeyF12: "\x1b[24~",
|
||||
KeyBacktab: "\x1b[Z",
|
||||
})
|
||||
|
||||
// GNU Screen with 256 colors
|
||||
terminfo.AddTerminfo(&terminfo.Terminfo{
|
||||
Name: "screen-256color",
|
||||
Columns: 80,
|
||||
Lines: 24,
|
||||
Colors: 256,
|
||||
Bell: "\a",
|
||||
Clear: "\x1b[H\x1b[J",
|
||||
EnterCA: "\x1b[?1049h",
|
||||
ExitCA: "\x1b[?1049l",
|
||||
ShowCursor: "\x1b[34h\x1b[?25h",
|
||||
HideCursor: "\x1b[?25l",
|
||||
AttrOff: "\x1b[m\x0f",
|
||||
Underline: "\x1b[4m",
|
||||
Bold: "\x1b[1m",
|
||||
Dim: "\x1b[2m",
|
||||
Blink: "\x1b[5m",
|
||||
Reverse: "\x1b[7m",
|
||||
EnterKeypad: "\x1b[?1h\x1b=",
|
||||
ExitKeypad: "\x1b[?1l\x1b>",
|
||||
SetFg: "\x1b[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m",
|
||||
SetBg: "\x1b[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m",
|
||||
SetFgBg: "\x1b[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;;%?%p2%{8}%<%t4%p2%d%e%p2%{16}%<%t10%p2%{8}%-%d%e48;5;%p2%d%;m",
|
||||
PadChar: "\x00",
|
||||
AltChars: "++,,--..00``aaffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~",
|
||||
EnterAcs: "\x0e",
|
||||
ExitAcs: "\x0f",
|
||||
EnableAcs: "\x1b(B\x1b)0",
|
||||
Mouse: "\x1b[M",
|
||||
MouseMode: "%?%p1%{1}%=%t%'h'%Pa%e%'l'%Pa%;\x1b[?1000%ga%c\x1b[?1002%ga%c\x1b[?1003%ga%c\x1b[?1006%ga%c",
|
||||
SetCursor: "\x1b[%i%p1%d;%p2%dH",
|
||||
CursorBack1: "\b",
|
||||
CursorUp1: "\x1bM",
|
||||
KeyUp: "\x1bOA",
|
||||
KeyDown: "\x1bOB",
|
||||
KeyRight: "\x1bOC",
|
||||
KeyLeft: "\x1bOD",
|
||||
KeyInsert: "\x1b[2~",
|
||||
KeyDelete: "\x1b[3~",
|
||||
KeyBackspace: "\xff",
|
||||
KeyHome: "\x1b[1~",
|
||||
KeyEnd: "\x1b[4~",
|
||||
KeyPgUp: "\x1b[5~",
|
||||
KeyPgDn: "\x1b[6~",
|
||||
KeyF1: "\x1bOP",
|
||||
KeyF2: "\x1bOQ",
|
||||
KeyF3: "\x1bOR",
|
||||
KeyF4: "\x1bOS",
|
||||
KeyF5: "\x1b[15~",
|
||||
KeyF6: "\x1b[17~",
|
||||
KeyF7: "\x1b[18~",
|
||||
KeyF8: "\x1b[19~",
|
||||
KeyF9: "\x1b[20~",
|
||||
KeyF10: "\x1b[21~",
|
||||
KeyF11: "\x1b[23~",
|
||||
KeyF12: "\x1b[24~",
|
||||
KeyBacktab: "\x1b[Z",
|
||||
})
|
||||
}
|
||||
+308
@@ -0,0 +1,308 @@
|
||||
// Generated automatically. DO NOT HAND-EDIT.
|
||||
|
||||
package simpleterm
|
||||
|
||||
import "github.com/gdamore/tcell/terminfo"
|
||||
|
||||
func init() {
|
||||
|
||||
// simpleterm
|
||||
terminfo.AddTerminfo(&terminfo.Terminfo{
|
||||
Name: "st",
|
||||
Aliases: []string{"stterm"},
|
||||
Columns: 80,
|
||||
Lines: 24,
|
||||
Colors: 8,
|
||||
Bell: "\a",
|
||||
Clear: "\x1b[H\x1b[2J",
|
||||
EnterCA: "\x1b[?1049h",
|
||||
ExitCA: "\x1b[?1049l",
|
||||
ShowCursor: "\x1b[?12l\x1b[?25h",
|
||||
HideCursor: "\x1b[?25l",
|
||||
AttrOff: "\x1b[0m",
|
||||
Underline: "\x1b[4m",
|
||||
Bold: "\x1b[1m",
|
||||
Dim: "\x1b[2m",
|
||||
Blink: "\x1b[5m",
|
||||
Reverse: "\x1b[7m",
|
||||
EnterKeypad: "\x1b[?1h\x1b=",
|
||||
ExitKeypad: "\x1b[?1l\x1b>",
|
||||
SetFg: "\x1b[3%p1%dm",
|
||||
SetBg: "\x1b[4%p1%dm",
|
||||
SetFgBg: "\x1b[3%p1%d;4%p2%dm",
|
||||
AltChars: "+C,D-A.B0E``aaffgghFiGjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~",
|
||||
EnterAcs: "\x1b(0",
|
||||
ExitAcs: "\x1b(B",
|
||||
EnableAcs: "\x1b)0",
|
||||
Mouse: "\x1b[M",
|
||||
MouseMode: "%?%p1%{1}%=%t%'h'%Pa%e%'l'%Pa%;\x1b[?1000%ga%c\x1b[?1002%ga%c\x1b[?1003%ga%c\x1b[?1006%ga%c",
|
||||
SetCursor: "\x1b[%i%p1%d;%p2%dH",
|
||||
CursorBack1: "\b",
|
||||
CursorUp1: "\x1b[A",
|
||||
KeyUp: "\x1bOA",
|
||||
KeyDown: "\x1bOB",
|
||||
KeyRight: "\x1bOC",
|
||||
KeyLeft: "\x1bOD",
|
||||
KeyInsert: "\x1b[2~",
|
||||
KeyDelete: "\x1b[3~",
|
||||
KeyBackspace: "\xff",
|
||||
KeyHome: "\x1b[1~",
|
||||
KeyEnd: "\x1b[4~",
|
||||
KeyPgUp: "\x1b[5~",
|
||||
KeyPgDn: "\x1b[6~",
|
||||
KeyF1: "\x1bOP",
|
||||
KeyF2: "\x1bOQ",
|
||||
KeyF3: "\x1bOR",
|
||||
KeyF4: "\x1bOS",
|
||||
KeyF5: "\x1b[15~",
|
||||
KeyF6: "\x1b[17~",
|
||||
KeyF7: "\x1b[18~",
|
||||
KeyF8: "\x1b[19~",
|
||||
KeyF9: "\x1b[20~",
|
||||
KeyF10: "\x1b[21~",
|
||||
KeyF11: "\x1b[23~",
|
||||
KeyF12: "\x1b[24~",
|
||||
KeyF13: "\x1b[1;2P",
|
||||
KeyF14: "\x1b[1;2Q",
|
||||
KeyF15: "\x1b[1;2R",
|
||||
KeyF16: "\x1b[1;2S",
|
||||
KeyF17: "\x1b[15;2~",
|
||||
KeyF18: "\x1b[17;2~",
|
||||
KeyF19: "\x1b[18;2~",
|
||||
KeyF20: "\x1b[19;2~",
|
||||
KeyF21: "\x1b[20;2~",
|
||||
KeyF22: "\x1b[21;2~",
|
||||
KeyF23: "\x1b[23;2~",
|
||||
KeyF24: "\x1b[24;2~",
|
||||
KeyF25: "\x1b[1;5P",
|
||||
KeyF26: "\x1b[1;5Q",
|
||||
KeyF27: "\x1b[1;5R",
|
||||
KeyF28: "\x1b[1;5S",
|
||||
KeyF29: "\x1b[15;5~",
|
||||
KeyF30: "\x1b[17;5~",
|
||||
KeyF31: "\x1b[18;5~",
|
||||
KeyF32: "\x1b[19;5~",
|
||||
KeyF33: "\x1b[20;5~",
|
||||
KeyF34: "\x1b[21;5~",
|
||||
KeyF35: "\x1b[23;5~",
|
||||
KeyF36: "\x1b[24;5~",
|
||||
KeyF37: "\x1b[1;6P",
|
||||
KeyF38: "\x1b[1;6Q",
|
||||
KeyF39: "\x1b[1;6R",
|
||||
KeyF40: "\x1b[1;6S",
|
||||
KeyF41: "\x1b[15;6~",
|
||||
KeyF42: "\x1b[17;6~",
|
||||
KeyF43: "\x1b[18;6~",
|
||||
KeyF44: "\x1b[19;6~",
|
||||
KeyF45: "\x1b[20;6~",
|
||||
KeyF46: "\x1b[21;6~",
|
||||
KeyF47: "\x1b[23;6~",
|
||||
KeyF48: "\x1b[24;6~",
|
||||
KeyF49: "\x1b[1;3P",
|
||||
KeyF50: "\x1b[1;3Q",
|
||||
KeyF51: "\x1b[1;3R",
|
||||
KeyF52: "\x1b[1;3S",
|
||||
KeyF53: "\x1b[15;3~",
|
||||
KeyF54: "\x1b[17;3~",
|
||||
KeyF55: "\x1b[18;3~",
|
||||
KeyF56: "\x1b[19;3~",
|
||||
KeyF57: "\x1b[20;3~",
|
||||
KeyF58: "\x1b[21;3~",
|
||||
KeyF59: "\x1b[23;3~",
|
||||
KeyF60: "\x1b[24;3~",
|
||||
KeyF61: "\x1b[1;4P",
|
||||
KeyF62: "\x1b[1;4Q",
|
||||
KeyF63: "\x1b[1;4R",
|
||||
KeyClear: "\x1b[3;5~",
|
||||
KeyShfLeft: "\x1b[1;2D",
|
||||
KeyShfRight: "\x1b[1;2C",
|
||||
KeyShfUp: "\x1b[1;2A",
|
||||
KeyShfDown: "\x1b[1;2B",
|
||||
KeyCtrlLeft: "\x1b[1;5D",
|
||||
KeyCtrlRight: "\x1b[1;5C",
|
||||
KeyCtrlUp: "\x1b[1;5A",
|
||||
KeyCtrlDown: "\x1b[1;5B",
|
||||
KeyMetaLeft: "\x1b[1;9D",
|
||||
KeyMetaRight: "\x1b[1;9C",
|
||||
KeyMetaUp: "\x1b[1;9A",
|
||||
KeyMetaDown: "\x1b[1;9B",
|
||||
KeyAltLeft: "\x1b[1;3D",
|
||||
KeyAltRight: "\x1b[1;3C",
|
||||
KeyAltUp: "\x1b[1;3A",
|
||||
KeyAltDown: "\x1b[1;3B",
|
||||
KeyAltShfLeft: "\x1b[1;4D",
|
||||
KeyAltShfRight: "\x1b[1;4C",
|
||||
KeyAltShfUp: "\x1b[1;4A",
|
||||
KeyAltShfDown: "\x1b[1;4B",
|
||||
KeyMetaShfLeft: "\x1b[1;10D",
|
||||
KeyMetaShfRight: "\x1b[1;10C",
|
||||
KeyMetaShfUp: "\x1b[1;10A",
|
||||
KeyMetaShfDown: "\x1b[1;10B",
|
||||
KeyCtrlShfLeft: "\x1b[1;6D",
|
||||
KeyCtrlShfRight: "\x1b[1;6C",
|
||||
KeyCtrlShfUp: "\x1b[1;6A",
|
||||
KeyCtrlShfDown: "\x1b[1;6B",
|
||||
KeyShfHome: "\x1b[1;2H",
|
||||
KeyShfEnd: "\x1b[1;2F",
|
||||
KeyCtrlHome: "\x1b[1;5H",
|
||||
KeyCtrlEnd: "\x1b[1;5F",
|
||||
KeyAltHome: "\x1b[1;9H",
|
||||
KeyAltEnd: "\x1b[1;9F",
|
||||
KeyCtrlShfHome: "\x1b[1;6H",
|
||||
KeyCtrlShfEnd: "\x1b[1;6F",
|
||||
KeyMetaShfHome: "\x1b[1;10H",
|
||||
KeyMetaShfEnd: "\x1b[1;10F",
|
||||
KeyAltShfHome: "\x1b[1;4H",
|
||||
KeyAltShfEnd: "\x1b[1;4F",
|
||||
})
|
||||
|
||||
// simpleterm with 256 colors
|
||||
terminfo.AddTerminfo(&terminfo.Terminfo{
|
||||
Name: "st-256color",
|
||||
Aliases: []string{"stterm-256color"},
|
||||
Columns: 80,
|
||||
Lines: 24,
|
||||
Colors: 256,
|
||||
Bell: "\a",
|
||||
Clear: "\x1b[H\x1b[2J",
|
||||
EnterCA: "\x1b[?1049h",
|
||||
ExitCA: "\x1b[?1049l",
|
||||
ShowCursor: "\x1b[?12l\x1b[?25h",
|
||||
HideCursor: "\x1b[?25l",
|
||||
AttrOff: "\x1b[0m",
|
||||
Underline: "\x1b[4m",
|
||||
Bold: "\x1b[1m",
|
||||
Dim: "\x1b[2m",
|
||||
Blink: "\x1b[5m",
|
||||
Reverse: "\x1b[7m",
|
||||
EnterKeypad: "\x1b[?1h\x1b=",
|
||||
ExitKeypad: "\x1b[?1l\x1b>",
|
||||
SetFg: "\x1b[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m",
|
||||
SetBg: "\x1b[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m",
|
||||
SetFgBg: "\x1b[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;;%?%p2%{8}%<%t4%p2%d%e%p2%{16}%<%t10%p2%{8}%-%d%e48;5;%p2%d%;m",
|
||||
AltChars: "+C,D-A.B0E``aaffgghFiGjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~",
|
||||
EnterAcs: "\x1b(0",
|
||||
ExitAcs: "\x1b(B",
|
||||
EnableAcs: "\x1b)0",
|
||||
Mouse: "\x1b[M",
|
||||
MouseMode: "%?%p1%{1}%=%t%'h'%Pa%e%'l'%Pa%;\x1b[?1000%ga%c\x1b[?1002%ga%c\x1b[?1003%ga%c\x1b[?1006%ga%c",
|
||||
SetCursor: "\x1b[%i%p1%d;%p2%dH",
|
||||
CursorBack1: "\b",
|
||||
CursorUp1: "\x1b[A",
|
||||
KeyUp: "\x1bOA",
|
||||
KeyDown: "\x1bOB",
|
||||
KeyRight: "\x1bOC",
|
||||
KeyLeft: "\x1bOD",
|
||||
KeyInsert: "\x1b[2~",
|
||||
KeyDelete: "\x1b[3~",
|
||||
KeyBackspace: "\xff",
|
||||
KeyHome: "\x1b[1~",
|
||||
KeyEnd: "\x1b[4~",
|
||||
KeyPgUp: "\x1b[5~",
|
||||
KeyPgDn: "\x1b[6~",
|
||||
KeyF1: "\x1bOP",
|
||||
KeyF2: "\x1bOQ",
|
||||
KeyF3: "\x1bOR",
|
||||
KeyF4: "\x1bOS",
|
||||
KeyF5: "\x1b[15~",
|
||||
KeyF6: "\x1b[17~",
|
||||
KeyF7: "\x1b[18~",
|
||||
KeyF8: "\x1b[19~",
|
||||
KeyF9: "\x1b[20~",
|
||||
KeyF10: "\x1b[21~",
|
||||
KeyF11: "\x1b[23~",
|
||||
KeyF12: "\x1b[24~",
|
||||
KeyF13: "\x1b[1;2P",
|
||||
KeyF14: "\x1b[1;2Q",
|
||||
KeyF15: "\x1b[1;2R",
|
||||
KeyF16: "\x1b[1;2S",
|
||||
KeyF17: "\x1b[15;2~",
|
||||
KeyF18: "\x1b[17;2~",
|
||||
KeyF19: "\x1b[18;2~",
|
||||
KeyF20: "\x1b[19;2~",
|
||||
KeyF21: "\x1b[20;2~",
|
||||
KeyF22: "\x1b[21;2~",
|
||||
KeyF23: "\x1b[23;2~",
|
||||
KeyF24: "\x1b[24;2~",
|
||||
KeyF25: "\x1b[1;5P",
|
||||
KeyF26: "\x1b[1;5Q",
|
||||
KeyF27: "\x1b[1;5R",
|
||||
KeyF28: "\x1b[1;5S",
|
||||
KeyF29: "\x1b[15;5~",
|
||||
KeyF30: "\x1b[17;5~",
|
||||
KeyF31: "\x1b[18;5~",
|
||||
KeyF32: "\x1b[19;5~",
|
||||
KeyF33: "\x1b[20;5~",
|
||||
KeyF34: "\x1b[21;5~",
|
||||
KeyF35: "\x1b[23;5~",
|
||||
KeyF36: "\x1b[24;5~",
|
||||
KeyF37: "\x1b[1;6P",
|
||||
KeyF38: "\x1b[1;6Q",
|
||||
KeyF39: "\x1b[1;6R",
|
||||
KeyF40: "\x1b[1;6S",
|
||||
KeyF41: "\x1b[15;6~",
|
||||
KeyF42: "\x1b[17;6~",
|
||||
KeyF43: "\x1b[18;6~",
|
||||
KeyF44: "\x1b[19;6~",
|
||||
KeyF45: "\x1b[20;6~",
|
||||
KeyF46: "\x1b[21;6~",
|
||||
KeyF47: "\x1b[23;6~",
|
||||
KeyF48: "\x1b[24;6~",
|
||||
KeyF49: "\x1b[1;3P",
|
||||
KeyF50: "\x1b[1;3Q",
|
||||
KeyF51: "\x1b[1;3R",
|
||||
KeyF52: "\x1b[1;3S",
|
||||
KeyF53: "\x1b[15;3~",
|
||||
KeyF54: "\x1b[17;3~",
|
||||
KeyF55: "\x1b[18;3~",
|
||||
KeyF56: "\x1b[19;3~",
|
||||
KeyF57: "\x1b[20;3~",
|
||||
KeyF58: "\x1b[21;3~",
|
||||
KeyF59: "\x1b[23;3~",
|
||||
KeyF60: "\x1b[24;3~",
|
||||
KeyF61: "\x1b[1;4P",
|
||||
KeyF62: "\x1b[1;4Q",
|
||||
KeyF63: "\x1b[1;4R",
|
||||
KeyClear: "\x1b[3;5~",
|
||||
KeyShfLeft: "\x1b[1;2D",
|
||||
KeyShfRight: "\x1b[1;2C",
|
||||
KeyShfUp: "\x1b[1;2A",
|
||||
KeyShfDown: "\x1b[1;2B",
|
||||
KeyCtrlLeft: "\x1b[1;5D",
|
||||
KeyCtrlRight: "\x1b[1;5C",
|
||||
KeyCtrlUp: "\x1b[1;5A",
|
||||
KeyCtrlDown: "\x1b[1;5B",
|
||||
KeyMetaLeft: "\x1b[1;9D",
|
||||
KeyMetaRight: "\x1b[1;9C",
|
||||
KeyMetaUp: "\x1b[1;9A",
|
||||
KeyMetaDown: "\x1b[1;9B",
|
||||
KeyAltLeft: "\x1b[1;3D",
|
||||
KeyAltRight: "\x1b[1;3C",
|
||||
KeyAltUp: "\x1b[1;3A",
|
||||
KeyAltDown: "\x1b[1;3B",
|
||||
KeyAltShfLeft: "\x1b[1;4D",
|
||||
KeyAltShfRight: "\x1b[1;4C",
|
||||
KeyAltShfUp: "\x1b[1;4A",
|
||||
KeyAltShfDown: "\x1b[1;4B",
|
||||
KeyMetaShfLeft: "\x1b[1;10D",
|
||||
KeyMetaShfRight: "\x1b[1;10C",
|
||||
KeyMetaShfUp: "\x1b[1;10A",
|
||||
KeyMetaShfDown: "\x1b[1;10B",
|
||||
KeyCtrlShfLeft: "\x1b[1;6D",
|
||||
KeyCtrlShfRight: "\x1b[1;6C",
|
||||
KeyCtrlShfUp: "\x1b[1;6A",
|
||||
KeyCtrlShfDown: "\x1b[1;6B",
|
||||
KeyShfHome: "\x1b[1;2H",
|
||||
KeyShfEnd: "\x1b[1;2F",
|
||||
KeyCtrlHome: "\x1b[1;5H",
|
||||
KeyCtrlEnd: "\x1b[1;5F",
|
||||
KeyAltHome: "\x1b[1;9H",
|
||||
KeyAltEnd: "\x1b[1;9F",
|
||||
KeyCtrlShfHome: "\x1b[1;6H",
|
||||
KeyCtrlShfEnd: "\x1b[1;6F",
|
||||
KeyMetaShfHome: "\x1b[1;10H",
|
||||
KeyMetaShfEnd: "\x1b[1;10F",
|
||||
KeyAltShfHome: "\x1b[1;4H",
|
||||
KeyAltShfEnd: "\x1b[1;4F",
|
||||
})
|
||||
}
|
||||
+90
@@ -0,0 +1,90 @@
|
||||
// Generated automatically. DO NOT HAND-EDIT.
|
||||
|
||||
package sun
|
||||
|
||||
import "github.com/gdamore/tcell/terminfo"
|
||||
|
||||
func init() {
|
||||
|
||||
// Sun Microsystems Inc. workstation console
|
||||
terminfo.AddTerminfo(&terminfo.Terminfo{
|
||||
Name: "sun",
|
||||
Aliases: []string{"sun1", "sun2"},
|
||||
Columns: 80,
|
||||
Lines: 34,
|
||||
Bell: "\a",
|
||||
Clear: "\f",
|
||||
AttrOff: "\x1b[m",
|
||||
Reverse: "\x1b[7m",
|
||||
PadChar: "\x00",
|
||||
SetCursor: "\x1b[%i%p1%d;%p2%dH",
|
||||
CursorBack1: "\b",
|
||||
CursorUp1: "\x1b[A",
|
||||
KeyUp: "\x1b[A",
|
||||
KeyDown: "\x1b[B",
|
||||
KeyRight: "\x1b[C",
|
||||
KeyLeft: "\x1b[D",
|
||||
KeyInsert: "\x1b[247z",
|
||||
KeyDelete: "\xff",
|
||||
KeyBackspace: "\b",
|
||||
KeyHome: "\x1b[214z",
|
||||
KeyEnd: "\x1b[220z",
|
||||
KeyPgUp: "\x1b[216z",
|
||||
KeyPgDn: "\x1b[222z",
|
||||
KeyF1: "\x1b[224z",
|
||||
KeyF2: "\x1b[225z",
|
||||
KeyF3: "\x1b[226z",
|
||||
KeyF4: "\x1b[227z",
|
||||
KeyF5: "\x1b[228z",
|
||||
KeyF6: "\x1b[229z",
|
||||
KeyF7: "\x1b[230z",
|
||||
KeyF8: "\x1b[231z",
|
||||
KeyF9: "\x1b[232z",
|
||||
KeyF10: "\x1b[233z",
|
||||
KeyF11: "\x1b[234z",
|
||||
KeyF12: "\x1b[235z",
|
||||
})
|
||||
|
||||
// Sun Microsystems Workstation console with color support (IA systems)
|
||||
terminfo.AddTerminfo(&terminfo.Terminfo{
|
||||
Name: "sun-color",
|
||||
Columns: 80,
|
||||
Lines: 34,
|
||||
Colors: 8,
|
||||
Bell: "\a",
|
||||
Clear: "\f",
|
||||
AttrOff: "\x1b[m",
|
||||
Bold: "\x1b[1m",
|
||||
Reverse: "\x1b[7m",
|
||||
SetFg: "\x1b[3%p1%dm",
|
||||
SetBg: "\x1b[4%p1%dm",
|
||||
SetFgBg: "\x1b[3%p1%d;4%p2%dm",
|
||||
PadChar: "\x00",
|
||||
SetCursor: "\x1b[%i%p1%d;%p2%dH",
|
||||
CursorBack1: "\b",
|
||||
CursorUp1: "\x1b[A",
|
||||
KeyUp: "\x1b[A",
|
||||
KeyDown: "\x1b[B",
|
||||
KeyRight: "\x1b[C",
|
||||
KeyLeft: "\x1b[D",
|
||||
KeyInsert: "\x1b[247z",
|
||||
KeyDelete: "\xff",
|
||||
KeyBackspace: "\b",
|
||||
KeyHome: "\x1b[214z",
|
||||
KeyEnd: "\x1b[220z",
|
||||
KeyPgUp: "\x1b[216z",
|
||||
KeyPgDn: "\x1b[222z",
|
||||
KeyF1: "\x1b[224z",
|
||||
KeyF2: "\x1b[225z",
|
||||
KeyF3: "\x1b[226z",
|
||||
KeyF4: "\x1b[227z",
|
||||
KeyF5: "\x1b[228z",
|
||||
KeyF6: "\x1b[229z",
|
||||
KeyF7: "\x1b[230z",
|
||||
KeyF8: "\x1b[231z",
|
||||
KeyF9: "\x1b[232z",
|
||||
KeyF10: "\x1b[233z",
|
||||
KeyF11: "\x1b[234z",
|
||||
KeyF12: "\x1b[235z",
|
||||
})
|
||||
}
|
||||
+154
@@ -0,0 +1,154 @@
|
||||
// Generated automatically. DO NOT HAND-EDIT.
|
||||
|
||||
package termite
|
||||
|
||||
import "github.com/gdamore/tcell/terminfo"
|
||||
|
||||
func init() {
|
||||
|
||||
// VTE-based terminal
|
||||
terminfo.AddTerminfo(&terminfo.Terminfo{
|
||||
Name: "termite",
|
||||
Columns: 80,
|
||||
Lines: 24,
|
||||
Colors: 256,
|
||||
Bell: "\a",
|
||||
Clear: "\x1b[H\x1b[2J",
|
||||
EnterCA: "\x1b[?1049h",
|
||||
ExitCA: "\x1b[?1049l",
|
||||
ShowCursor: "\x1b[?12l\x1b[?25h",
|
||||
HideCursor: "\x1b[?25l",
|
||||
AttrOff: "\x1b(B\x1b[m",
|
||||
Underline: "\x1b[4m",
|
||||
Bold: "\x1b[1m",
|
||||
Reverse: "\x1b[7m",
|
||||
EnterKeypad: "\x1b[?1h\x1b=",
|
||||
ExitKeypad: "\x1b[?1l\x1b>",
|
||||
SetFg: "\x1b[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m",
|
||||
SetBg: "\x1b[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m",
|
||||
SetFgBg: "\x1b[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;;%?%p2%{8}%<%t4%p2%d%e%p2%{16}%<%t10%p2%{8}%-%d%e48;5;%p2%d%;m",
|
||||
AltChars: "++,,--..00``aaffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~",
|
||||
EnterAcs: "\x1b(0",
|
||||
ExitAcs: "\x1b(B",
|
||||
Mouse: "\x1b[M",
|
||||
MouseMode: "%?%p1%{1}%=%t%'h'%Pa%e%'l'%Pa%;\x1b[?1000%ga%c\x1b[?1002%ga%c\x1b[?1003%ga%c\x1b[?1006%ga%c",
|
||||
SetCursor: "\x1b[%i%p1%d;%p2%dH",
|
||||
CursorBack1: "\b",
|
||||
CursorUp1: "\x1b[A",
|
||||
KeyUp: "\x1bOA",
|
||||
KeyDown: "\x1bOB",
|
||||
KeyRight: "\x1bOC",
|
||||
KeyLeft: "\x1bOD",
|
||||
KeyInsert: "\x1b[2~",
|
||||
KeyDelete: "\x1b[3~",
|
||||
KeyBackspace: "\xff",
|
||||
KeyHome: "\x1bOH",
|
||||
KeyEnd: "\x1bOF",
|
||||
KeyPgUp: "\x1b[5~",
|
||||
KeyPgDn: "\x1b[6~",
|
||||
KeyF1: "\x1bOP",
|
||||
KeyF2: "\x1bOQ",
|
||||
KeyF3: "\x1bOR",
|
||||
KeyF4: "\x1bOS",
|
||||
KeyF5: "\x1b[15~",
|
||||
KeyF6: "\x1b[17~",
|
||||
KeyF7: "\x1b[18~",
|
||||
KeyF8: "\x1b[19~",
|
||||
KeyF9: "\x1b[20~",
|
||||
KeyF10: "\x1b[21~",
|
||||
KeyF11: "\x1b[23~",
|
||||
KeyF12: "\x1b[24~",
|
||||
KeyF13: "\x1b[1;2P",
|
||||
KeyF14: "\x1b[1;2Q",
|
||||
KeyF15: "\x1b[1;2R",
|
||||
KeyF16: "\x1b[1;2S",
|
||||
KeyF17: "\x1b[15;2~",
|
||||
KeyF18: "\x1b[17;2~",
|
||||
KeyF19: "\x1b[18;2~",
|
||||
KeyF20: "\x1b[19;2~",
|
||||
KeyF21: "\x1b[20;2~",
|
||||
KeyF22: "\x1b[21;2~",
|
||||
KeyF23: "\x1b[23;2~",
|
||||
KeyF24: "\x1b[24;2~",
|
||||
KeyF25: "\x1b[1;5P",
|
||||
KeyF26: "\x1b[1;5Q",
|
||||
KeyF27: "\x1b[1;5R",
|
||||
KeyF28: "\x1b[1;5S",
|
||||
KeyF29: "\x1b[15;5~",
|
||||
KeyF30: "\x1b[17;5~",
|
||||
KeyF31: "\x1b[18;5~",
|
||||
KeyF32: "\x1b[19;5~",
|
||||
KeyF33: "\x1b[20;5~",
|
||||
KeyF34: "\x1b[21;5~",
|
||||
KeyF35: "\x1b[23;5~",
|
||||
KeyF36: "\x1b[24;5~",
|
||||
KeyF37: "\x1b[1;6P",
|
||||
KeyF38: "\x1b[1;6Q",
|
||||
KeyF39: "\x1b[1;6R",
|
||||
KeyF40: "\x1b[1;6S",
|
||||
KeyF41: "\x1b[15;6~",
|
||||
KeyF42: "\x1b[17;6~",
|
||||
KeyF43: "\x1b[18;6~",
|
||||
KeyF44: "\x1b[19;6~",
|
||||
KeyF45: "\x1b[20;6~",
|
||||
KeyF46: "\x1b[21;6~",
|
||||
KeyF47: "\x1b[23;6~",
|
||||
KeyF48: "\x1b[24;6~",
|
||||
KeyF49: "\x1b[1;3P",
|
||||
KeyF50: "\x1b[1;3Q",
|
||||
KeyF51: "\x1b[1;3R",
|
||||
KeyF52: "\x1b[1;3S",
|
||||
KeyF53: "\x1b[15;3~",
|
||||
KeyF54: "\x1b[17;3~",
|
||||
KeyF55: "\x1b[18;3~",
|
||||
KeyF56: "\x1b[19;3~",
|
||||
KeyF57: "\x1b[20;3~",
|
||||
KeyF58: "\x1b[21;3~",
|
||||
KeyF59: "\x1b[23;3~",
|
||||
KeyF60: "\x1b[24;3~",
|
||||
KeyF61: "\x1b[1;4P",
|
||||
KeyF62: "\x1b[1;4Q",
|
||||
KeyF63: "\x1b[1;4R",
|
||||
KeyBacktab: "\x1b[Z",
|
||||
KeyShfLeft: "\x1b[1;2D",
|
||||
KeyShfRight: "\x1b[1;2C",
|
||||
KeyShfUp: "\x1b[1;2A",
|
||||
KeyShfDown: "\x1b[1;2B",
|
||||
KeyCtrlLeft: "\x1b[1;5D",
|
||||
KeyCtrlRight: "\x1b[1;5C",
|
||||
KeyCtrlUp: "\x1b[1;5A",
|
||||
KeyCtrlDown: "\x1b[1;5B",
|
||||
KeyMetaLeft: "\x1b[1;9D",
|
||||
KeyMetaRight: "\x1b[1;9C",
|
||||
KeyMetaUp: "\x1b[1;9A",
|
||||
KeyMetaDown: "\x1b[1;9B",
|
||||
KeyAltLeft: "\x1b[1;3D",
|
||||
KeyAltRight: "\x1b[1;3C",
|
||||
KeyAltUp: "\x1b[1;3A",
|
||||
KeyAltDown: "\x1b[1;3B",
|
||||
KeyAltShfLeft: "\x1b[1;4D",
|
||||
KeyAltShfRight: "\x1b[1;4C",
|
||||
KeyAltShfUp: "\x1b[1;4A",
|
||||
KeyAltShfDown: "\x1b[1;4B",
|
||||
KeyMetaShfLeft: "\x1b[1;10D",
|
||||
KeyMetaShfRight: "\x1b[1;10C",
|
||||
KeyMetaShfUp: "\x1b[1;10A",
|
||||
KeyMetaShfDown: "\x1b[1;10B",
|
||||
KeyCtrlShfLeft: "\x1b[1;6D",
|
||||
KeyCtrlShfRight: "\x1b[1;6C",
|
||||
KeyCtrlShfUp: "\x1b[1;6A",
|
||||
KeyCtrlShfDown: "\x1b[1;6B",
|
||||
KeyShfHome: "\x1b[1;2H",
|
||||
KeyShfEnd: "\x1b[1;2F",
|
||||
KeyCtrlHome: "\x1b[1;5H",
|
||||
KeyCtrlEnd: "\x1b[1;5F",
|
||||
KeyAltHome: "\x1b[1;9H",
|
||||
KeyAltEnd: "\x1b[1;9F",
|
||||
KeyCtrlShfHome: "\x1b[1;6H",
|
||||
KeyCtrlShfEnd: "\x1b[1;6F",
|
||||
KeyMetaShfHome: "\x1b[1;10H",
|
||||
KeyMetaShfEnd: "\x1b[1;10F",
|
||||
KeyAltShfHome: "\x1b[1;4H",
|
||||
KeyAltShfEnd: "\x1b[1;4F",
|
||||
})
|
||||
}
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
// Generated automatically. DO NOT HAND-EDIT.
|
||||
|
||||
package tvi910
|
||||
|
||||
import "github.com/gdamore/tcell/terminfo"
|
||||
|
||||
func init() {
|
||||
|
||||
// televideo model 910
|
||||
terminfo.AddTerminfo(&terminfo.Terminfo{
|
||||
Name: "tvi910",
|
||||
Columns: 80,
|
||||
Lines: 24,
|
||||
Bell: "\a",
|
||||
Clear: "\x1a",
|
||||
AttrOff: "\x1bG0",
|
||||
Underline: "\x1bG8",
|
||||
Reverse: "\x1bG4",
|
||||
PadChar: "\x00",
|
||||
SetCursor: "\x1b=%p1%' '%+%c%p2%' '%+%c",
|
||||
CursorBack1: "\b",
|
||||
CursorUp1: "\v",
|
||||
KeyUp: "\v",
|
||||
KeyDown: "\n",
|
||||
KeyRight: "\f",
|
||||
KeyLeft: "\b",
|
||||
KeyBackspace: "\b",
|
||||
KeyHome: "\x1e",
|
||||
KeyF1: "\x01@\r",
|
||||
KeyF2: "\x01A\r",
|
||||
KeyF3: "\x01B\r",
|
||||
KeyF4: "\x01C\r",
|
||||
KeyF5: "\x01D\r",
|
||||
KeyF6: "\x01E\r",
|
||||
KeyF7: "\x01F\r",
|
||||
KeyF8: "\x01G\r",
|
||||
KeyF9: "\x01H\r",
|
||||
})
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user