Use glamour and termev to render/colorize content (#181)

Merge branch 'master' into use-glamour

select Glamour Theme based on BackgroundColor

Merge branch 'master' into use-glamour

Merge branch 'master' into use-glamour

update termev

update go.mod

label color colorate

use glamour for issue content

Vendor: Add glamour

Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: 6543 <6543@obermui.de>
Reviewed-on: https://gitea.com/gitea/tea/pulls/181
Reviewed-by: techknowlogick <techknowlogick@gitea.io>
Reviewed-by: Lunny Xiao <xiaolunwen@gmail.com>
This commit is contained in:
6543
2020-09-19 16:00:50 +00:00
committed by Lunny Xiao
parent f8d983b523
commit 89e93d90b3
434 changed files with 68002 additions and 3 deletions

21
vendor/github.com/muesli/reflow/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2019 Christian Muehlhaeuser
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

33
vendor/github.com/muesli/reflow/ansi/buffer.go generated vendored Normal file
View File

@@ -0,0 +1,33 @@
package ansi
import (
"bytes"
"github.com/mattn/go-runewidth"
)
// Buffer is a buffer aware of ANSI escape sequences.
type Buffer struct {
bytes.Buffer
}
// PrintableRuneCount returns the amount of printable runes in the buffer.
func (w Buffer) PrintableRuneCount() int {
var n int
var ansi bool
for _, c := range w.String() {
if c == '\x1B' {
// ANSI escape sequence
ansi = true
} else if ansi {
if (c >= 0x40 && c <= 0x5a) || (c >= 0x61 && c <= 0x7a) {
// ANSI sequence terminated
ansi = false
}
} else {
n += runewidth.StringWidth(string(c))
}
}
return n
}

65
vendor/github.com/muesli/reflow/ansi/writer.go generated vendored Normal file
View File

@@ -0,0 +1,65 @@
package ansi
import (
"io"
"strings"
)
type Writer struct {
Forward io.Writer
ansi bool
ansiseq string
lastseq string
seqchanged bool
}
// Write is used to write content to the ANSI buffer.
func (w *Writer) Write(b []byte) (int, error) {
for _, c := range string(b) {
if c == '\x1B' {
// ANSI escape sequence
w.ansi = true
w.seqchanged = true
w.ansiseq += string(c)
} else if w.ansi {
w.ansiseq += string(c)
if (c >= 0x41 && c <= 0x5a) || (c >= 0x61 && c <= 0x7a) {
// ANSI sequence terminated
w.ansi = false
_, _ = w.Forward.Write([]byte(w.ansiseq))
if strings.HasSuffix(w.ansiseq, "[0m") {
// reset sequence
w.lastseq = ""
} else if strings.HasSuffix(w.ansiseq, "m") {
// color code
w.lastseq = w.ansiseq
}
w.ansiseq = ""
}
} else {
_, err := w.Forward.Write([]byte(string(c)))
if err != nil {
return 0, err
}
}
}
return len(b), nil
}
func (w *Writer) LastSequence() string {
return w.lastseq
}
func (w *Writer) ResetAnsi() {
if !w.seqchanged {
return
}
_, _ = w.Forward.Write([]byte("\x1b[0m"))
}
func (w *Writer) RestoreAnsi() {
_, _ = w.Forward.Write([]byte(w.lastseq))
}

111
vendor/github.com/muesli/reflow/indent/indent.go generated vendored Normal file
View File

@@ -0,0 +1,111 @@
package indent
import (
"bytes"
"io"
"strings"
"github.com/muesli/reflow/ansi"
)
type IndentFunc func(w io.Writer)
type Writer struct {
Indent uint
IndentFunc IndentFunc
ansiWriter *ansi.Writer
buf bytes.Buffer
skipIndent bool
ansi bool
}
func NewWriter(indent uint, indentFunc IndentFunc) *Writer {
w := &Writer{
Indent: indent,
IndentFunc: indentFunc,
}
w.ansiWriter = &ansi.Writer{
Forward: &w.buf,
}
return w
}
func NewWriterPipe(forward io.Writer, indent uint, indentFunc IndentFunc) *Writer {
return &Writer{
Indent: indent,
IndentFunc: indentFunc,
ansiWriter: &ansi.Writer{
Forward: forward,
},
}
}
// Bytes is shorthand for declaring a new default indent-writer instance,
// used to immediately indent a byte slice.
func Bytes(b []byte, indent uint) []byte {
f := NewWriter(indent, nil)
_, _ = f.Write(b)
return f.Bytes()
}
// String is shorthand for declaring a new default indent-writer instance,
// used to immediately indent a string.
func String(s string, indent uint) string {
return string(Bytes([]byte(s), indent))
}
// Write is used to write content to the indent buffer.
func (w *Writer) Write(b []byte) (int, error) {
for _, c := range string(b) {
if c == '\x1B' {
// ANSI escape sequence
w.ansi = true
} else if w.ansi {
if (c >= 0x41 && c <= 0x5a) || (c >= 0x61 && c <= 0x7a) {
// ANSI sequence terminated
w.ansi = false
}
} else {
if !w.skipIndent {
w.ansiWriter.ResetAnsi()
if w.IndentFunc != nil {
for i := 0; i < int(w.Indent); i++ {
w.IndentFunc(w.ansiWriter)
}
} else {
_, err := w.ansiWriter.Write([]byte(strings.Repeat(" ", int(w.Indent))))
if err != nil {
return 0, err
}
}
w.skipIndent = true
w.ansiWriter.RestoreAnsi()
}
if c == '\n' {
// end of current line
w.skipIndent = false
}
}
_, err := w.ansiWriter.Write([]byte(string(c)))
if err != nil {
return 0, err
}
}
return len(b), nil
}
// Bytes returns the indented result as a byte slice.
func (w *Writer) Bytes() []byte {
return w.buf.Bytes()
}
// String returns the indented result as a string.
func (w *Writer) String() string {
return w.buf.String()
}

132
vendor/github.com/muesli/reflow/padding/padding.go generated vendored Normal file
View File

@@ -0,0 +1,132 @@
package padding
import (
"bytes"
"io"
"strings"
"github.com/mattn/go-runewidth"
"github.com/muesli/reflow/ansi"
)
type PaddingFunc func(w io.Writer)
type Writer struct {
Padding uint
PadFunc PaddingFunc
ansiWriter *ansi.Writer
buf bytes.Buffer
lineLen int
ansi bool
}
func NewWriter(width uint, paddingFunc PaddingFunc) *Writer {
w := &Writer{
Padding: width,
PadFunc: paddingFunc,
}
w.ansiWriter = &ansi.Writer{
Forward: &w.buf,
}
return w
}
func NewWriterPipe(forward io.Writer, width uint, paddingFunc PaddingFunc) *Writer {
return &Writer{
Padding: width,
PadFunc: paddingFunc,
ansiWriter: &ansi.Writer{
Forward: forward,
},
}
}
// Bytes is shorthand for declaring a new default padding-writer instance,
// used to immediately pad a byte slice.
func Bytes(b []byte, width uint) []byte {
f := NewWriter(width, nil)
_, _ = f.Write(b)
f.Close()
return f.Bytes()
}
// String is shorthand for declaring a new default padding-writer instance,
// used to immediately pad a string.
func String(s string, width uint) string {
return string(Bytes([]byte(s), width))
}
// Write is used to write content to the padding buffer.
func (w *Writer) Write(b []byte) (int, error) {
for _, c := range string(b) {
if c == '\x1B' {
// ANSI escape sequence
w.ansi = true
} else if w.ansi {
if (c >= 0x41 && c <= 0x5a) || (c >= 0x61 && c <= 0x7a) {
// ANSI sequence terminated
w.ansi = false
}
} else {
w.lineLen += runewidth.StringWidth(string(c))
if c == '\n' {
// end of current line
err := w.pad()
if err != nil {
return 0, err
}
w.ansiWriter.ResetAnsi()
w.lineLen = 0
}
}
_, err := w.ansiWriter.Write([]byte(string(c)))
if err != nil {
return 0, err
}
}
return len(b), nil
}
func (w *Writer) pad() error {
if w.Padding > 0 && uint(w.lineLen) < w.Padding {
if w.PadFunc != nil {
for i := 0; i < int(w.Padding)-w.lineLen; i++ {
w.PadFunc(w.ansiWriter)
}
} else {
_, err := w.ansiWriter.Write([]byte(strings.Repeat(" ", int(w.Padding)-w.lineLen)))
if err != nil {
return err
}
}
}
return nil
}
// Close will finish the padding operation. Always call it before trying to
// retrieve the final result.
func (w *Writer) Close() error {
// don't pad empty trailing lines
if w.lineLen == 0 {
return nil
}
return w.pad()
}
// Bytes returns the padded result as a byte slice.
func (w *Writer) Bytes() []byte {
return w.buf.Bytes()
}
// String returns the padded result as a string.
func (w *Writer) String() string {
return w.buf.String()
}

167
vendor/github.com/muesli/reflow/wordwrap/wordwrap.go generated vendored Normal file
View File

@@ -0,0 +1,167 @@
package wordwrap
import (
"bytes"
"strings"
"unicode"
"github.com/muesli/reflow/ansi"
)
var (
defaultBreakpoints = []rune{'-'}
defaultNewline = []rune{'\n'}
)
// WordWrap contains settings and state for customisable text reflowing with
// support for ANSI escape sequences. This means you can style your terminal
// output without affecting the word wrapping algorithm.
type WordWrap struct {
Limit int
Breakpoints []rune
Newline []rune
KeepNewlines bool
buf bytes.Buffer
space bytes.Buffer
word ansi.Buffer
lineLen int
ansi bool
}
// NewWriter returns a new instance of a word-wrapping writer, initialized with
// default settings.
func NewWriter(limit int) *WordWrap {
return &WordWrap{
Limit: limit,
Breakpoints: defaultBreakpoints,
Newline: defaultNewline,
KeepNewlines: true,
}
}
// Bytes is shorthand for declaring a new default WordWrap instance,
// used to immediately word-wrap a byte slice.
func Bytes(b []byte, limit int) []byte {
f := NewWriter(limit)
_, _ = f.Write(b)
f.Close()
return f.Bytes()
}
// String is shorthand for declaring a new default WordWrap instance,
// used to immediately word-wrap a string.
func String(s string, limit int) string {
return string(Bytes([]byte(s), limit))
}
func (w *WordWrap) addSpace() {
w.lineLen += w.space.Len()
w.buf.Write(w.space.Bytes())
w.space.Reset()
}
func (w *WordWrap) addWord() {
if w.word.Len() > 0 {
w.addSpace()
w.lineLen += w.word.PrintableRuneCount()
w.buf.Write(w.word.Bytes())
w.word.Reset()
}
}
func (w *WordWrap) addNewLine() {
w.buf.WriteRune('\n')
w.lineLen = 0
w.space.Reset()
}
func inGroup(a []rune, c rune) bool {
for _, v := range a {
if v == c {
return true
}
}
return false
}
// Write is used to write more content to the word-wrap buffer.
func (w *WordWrap) Write(b []byte) (int, error) {
if w.Limit == 0 {
return w.buf.Write(b)
}
s := string(b)
if !w.KeepNewlines {
s = strings.Replace(strings.TrimSpace(s), "\n", " ", -1)
}
for _, c := range s {
if c == '\x1B' {
// ANSI escape sequence
w.word.WriteRune(c)
w.ansi = true
} else if w.ansi {
w.word.WriteRune(c)
if (c >= 0x40 && c <= 0x5a) || (c >= 0x61 && c <= 0x7a) {
// ANSI sequence terminated
w.ansi = false
}
} else if inGroup(w.Newline, c) {
// end of current line
// see if we can add the content of the space buffer to the current line
if w.word.Len() == 0 {
if w.lineLen+w.space.Len() > w.Limit {
w.lineLen = 0
} else {
// preserve whitespace
w.buf.Write(w.space.Bytes())
}
w.space.Reset()
}
w.addWord()
w.addNewLine()
} else if unicode.IsSpace(c) {
// end of current word
w.addWord()
w.space.WriteRune(c)
} else if inGroup(w.Breakpoints, c) {
// valid breakpoint
w.addSpace()
w.addWord()
w.buf.WriteRune(c)
} else {
// any other character
w.word.WriteRune(c)
// add a line break if the current word would exceed the line's
// character limit
if w.lineLen+w.space.Len()+w.word.PrintableRuneCount() > w.Limit &&
w.word.PrintableRuneCount() < w.Limit {
w.addNewLine()
}
}
}
return len(b), nil
}
// Close will finish the word-wrap operation. Always call it before trying to
// retrieve the final result.
func (w *WordWrap) Close() error {
w.addWord()
return nil
}
// Bytes returns the word-wrapped result as a byte slice.
func (w *WordWrap) Bytes() []byte {
return w.buf.Bytes()
}
// String returns the word-wrapped result as a string.
func (w *WordWrap) String() string {
return w.buf.String()
}

15
vendor/github.com/muesli/termenv/.gitignore generated vendored Normal file
View File

@@ -0,0 +1,15 @@
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib
# Test binary, built with `go test -c`
*.test
# Output of the go coverage tool, specifically when used with LiteIDE
*.out
# Dependency directories (remove the comment below to include it)
# vendor/

21
vendor/github.com/muesli/termenv/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2019 Christian Muehlhaeuser
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

174
vendor/github.com/muesli/termenv/README.md generated vendored Normal file
View File

@@ -0,0 +1,174 @@
<p align="center">
<img src="https://stuff.charm.sh/termenv.png" width="480" alt="termenv Logo">
<br />
<a href="https://github.com/muesli/termenv/releases"><img src="https://img.shields.io/github/release/muesli/termenv.svg" alt="Latest Release"></a>
<a href="https://godoc.org/github.com/muesli/termenv"><img src="https://godoc.org/github.com/golang/gddo?status.svg" alt="GoDoc"></a>
<a href="https://github.com/muesli/termenv/actions"><img src="https://github.com/muesli/termenv/workflows/build/badge.svg" alt="Build Status"></a>
<a href="https://coveralls.io/github/muesli/termenv?branch=master"><img src="https://coveralls.io/repos/github/muesli/termenv/badge.svg?branch=master" alt="Coverage Status"></a>
<a href="http://goreportcard.com/report/muesli/termenv"><img src="http://goreportcard.com/badge/muesli/termenv" alt="Go ReportCard"></a>
</p>
`termenv` lets you safely use advanced styling options on the terminal. It
gathers information about the terminal environment in terms of its ANSI & color
support and offers you convenient methods to colorize and style your output,
without you having to deal with all kinds of weird ANSI escape sequences and
color conversions.
![Example output](https://github.com/muesli/termenv/raw/master/examples/hello-world/hello-world.png)
## Installation
```bash
go get github.com/muesli/termenv
```
## Query Terminal Status
```go
// returns supported color profile: Ascii, ANSI, ANSI256, or TrueColor
termenv.ColorProfile()
// returns default foreground color
termenv.ForegroundColor()
// returns default background color
termenv.BackgroundColor()
// returns whether terminal uses a dark-ish background
termenv.HasDarkBackground()
```
## Colors
`termenv` supports multiple color profiles: ANSI (16 colors), ANSI Extended
(256 colors), and TrueColor (24-bit RGB). Colors will automatically be degraded
to the best matching available color in the desired profile:
`TrueColor` => `ANSI 256 Colors` => `ANSI 16 Colors` => `Ascii`
```go
out := termenv.String("Hello World")
// retrieve color profile supported by terminal
p := termenv.ColorProfile()
// supports hex values
// will automatically degrade colors on terminals not supporting RGB
out = out.Foreground(p.Color("#abcdef"))
// but also supports ANSI colors (0-255)
out = out.Background(p.Color("69"))
fmt.Println(out)
```
## Styles
```go
out := termenv.String("foobar")
// text styles
out.Bold()
out.Faint()
out.Italic()
out.CrossOut()
out.Underline()
out.Overline()
// reverse swaps current fore- & background colors
out.Reverse()
// blinking text
out.Blink()
// combine multiple options
out.Bold().Underline()
```
## Template Helpers
```go
// load template helpers
f := termenv.TemplateFuncs(termenv.ColorProfile())
tpl := template.New("tpl").Funcs(f)
// apply bold style in a template
bold := `{{ Bold "Hello World" }}`
// examples for colorized templates
col := `{{ Color "#ff0000" "#0000ff" "Red on Blue" }}`
fg := `{{ Foreground "#ff0000" "Red Foreground" }}`
bg := `{{ Background "#0000ff" "Blue Background" }}`
// wrap styles
wrap := `{{ Bold (Underline "Hello World") }}`
// parse and render
tpl = tpl.Parse(bold)
var buf bytes.Buffer
tpl.Execute(&buf, nil)
fmt.Println(buf)
```
Other available helper functions are: `Faint`, `Italic`, `CrossOut`,
`Underline`, `Overline`, `Reverse`, and `Blink`.
## Screen
```go
// Reset the terminal to its default style, removing any active styles
termenv.Reset()
// Switch to the altscreen. The former view can be restored with ExitAltScreen()
termenv.AltScreen()
// Exit the altscreen and return to the former terminal view
termenv.ExitAltScreen()
// Clear the visible portion of the terminal
termenv.ClearScreen()
// Move the cursor to a given position
termenv.MoveCursor(row, column)
// Hide the cursor
termenv.HideCursor()
// Show the cursor
termenv.ShowCursor()
// Move the cursor up a given number of lines
termenv.CursorUp(n)
// Move the cursor down a given number of lines
termenv.CursorDown(n)
// Move the cursor down a given number of lines and place it at the beginning
// of the line
termenv.CursorNextLine(n)
// Move the cursor up a given number of lines and place it at the beginning of
// the line
termenv.CursorPrevLine(n)
// Clear the current line
termenv.ClearLine()
// Clear a given number of lines
termenv.ClearLines(n)
```
## Color Chart
![ANSI color chart](https://github.com/muesli/termenv/raw/master/examples/color-chart/color-chart.png)
You can find the source code used to create this chart in `termenv`'s examples.
## Related Projects
Check out [Glow](https://github.com/charmbracelet/glow), a markdown renderer for
the command-line, which uses `termenv`.
## License
[MIT](https://github.com/muesli/termenv/raw/master/LICENSE)

280
vendor/github.com/muesli/termenv/ansicolors.go generated vendored Normal file
View File

@@ -0,0 +1,280 @@
package termenv
const (
ANSIBlack ANSIColor = iota
ANSIRed
ANSIGreen
ANSIYellow
ANSIBlue
ANSIMagenta
ANSICyan
ANSIWhite
ANSIBrightBlack
ANSIBrightRed
ANSIBrightGreen
ANSIBrightYellow
ANSIBrightBlue
ANSIBrightMagenta
ANSIBrightCyan
ANSIBrightWhite
)
// RGB values of ANSI colors (0-255).
var ansiHex = []string{
"#000000",
"#800000",
"#008000",
"#808000",
"#000080",
"#800080",
"#008080",
"#c0c0c0",
"#808080",
"#ff0000",
"#00ff00",
"#ffff00",
"#0000ff",
"#ff00ff",
"#00ffff",
"#ffffff",
"#000000",
"#00005f",
"#000087",
"#0000af",
"#0000d7",
"#0000ff",
"#005f00",
"#005f5f",
"#005f87",
"#005faf",
"#005fd7",
"#005fff",
"#008700",
"#00875f",
"#008787",
"#0087af",
"#0087d7",
"#0087ff",
"#00af00",
"#00af5f",
"#00af87",
"#00afaf",
"#00afd7",
"#00afff",
"#00d700",
"#00d75f",
"#00d787",
"#00d7af",
"#00d7d7",
"#00d7ff",
"#00ff00",
"#00ff5f",
"#00ff87",
"#00ffaf",
"#00ffd7",
"#00ffff",
"#5f0000",
"#5f005f",
"#5f0087",
"#5f00af",
"#5f00d7",
"#5f00ff",
"#5f5f00",
"#5f5f5f",
"#5f5f87",
"#5f5faf",
"#5f5fd7",
"#5f5fff",
"#5f8700",
"#5f875f",
"#5f8787",
"#5f87af",
"#5f87d7",
"#5f87ff",
"#5faf00",
"#5faf5f",
"#5faf87",
"#5fafaf",
"#5fafd7",
"#5fafff",
"#5fd700",
"#5fd75f",
"#5fd787",
"#5fd7af",
"#5fd7d7",
"#5fd7ff",
"#5fff00",
"#5fff5f",
"#5fff87",
"#5fffaf",
"#5fffd7",
"#5fffff",
"#870000",
"#87005f",
"#870087",
"#8700af",
"#8700d7",
"#8700ff",
"#875f00",
"#875f5f",
"#875f87",
"#875faf",
"#875fd7",
"#875fff",
"#878700",
"#87875f",
"#878787",
"#8787af",
"#8787d7",
"#8787ff",
"#87af00",
"#87af5f",
"#87af87",
"#87afaf",
"#87afd7",
"#87afff",
"#87d700",
"#87d75f",
"#87d787",
"#87d7af",
"#87d7d7",
"#87d7ff",
"#87ff00",
"#87ff5f",
"#87ff87",
"#87ffaf",
"#87ffd7",
"#87ffff",
"#af0000",
"#af005f",
"#af0087",
"#af00af",
"#af00d7",
"#af00ff",
"#af5f00",
"#af5f5f",
"#af5f87",
"#af5faf",
"#af5fd7",
"#af5fff",
"#af8700",
"#af875f",
"#af8787",
"#af87af",
"#af87d7",
"#af87ff",
"#afaf00",
"#afaf5f",
"#afaf87",
"#afafaf",
"#afafd7",
"#afafff",
"#afd700",
"#afd75f",
"#afd787",
"#afd7af",
"#afd7d7",
"#afd7ff",
"#afff00",
"#afff5f",
"#afff87",
"#afffaf",
"#afffd7",
"#afffff",
"#d70000",
"#d7005f",
"#d70087",
"#d700af",
"#d700d7",
"#d700ff",
"#d75f00",
"#d75f5f",
"#d75f87",
"#d75faf",
"#d75fd7",
"#d75fff",
"#d78700",
"#d7875f",
"#d78787",
"#d787af",
"#d787d7",
"#d787ff",
"#d7af00",
"#d7af5f",
"#d7af87",
"#d7afaf",
"#d7afd7",
"#d7afff",
"#d7d700",
"#d7d75f",
"#d7d787",
"#d7d7af",
"#d7d7d7",
"#d7d7ff",
"#d7ff00",
"#d7ff5f",
"#d7ff87",
"#d7ffaf",
"#d7ffd7",
"#d7ffff",
"#ff0000",
"#ff005f",
"#ff0087",
"#ff00af",
"#ff00d7",
"#ff00ff",
"#ff5f00",
"#ff5f5f",
"#ff5f87",
"#ff5faf",
"#ff5fd7",
"#ff5fff",
"#ff8700",
"#ff875f",
"#ff8787",
"#ff87af",
"#ff87d7",
"#ff87ff",
"#ffaf00",
"#ffaf5f",
"#ffaf87",
"#ffafaf",
"#ffafd7",
"#ffafff",
"#ffd700",
"#ffd75f",
"#ffd787",
"#ffd7af",
"#ffd7d7",
"#ffd7ff",
"#ffff00",
"#ffff5f",
"#ffff87",
"#ffffaf",
"#ffffd7",
"#ffffff",
"#080808",
"#121212",
"#1c1c1c",
"#262626",
"#303030",
"#3a3a3a",
"#444444",
"#4e4e4e",
"#585858",
"#626262",
"#6c6c6c",
"#767676",
"#808080",
"#8a8a8a",
"#949494",
"#9e9e9e",
"#a8a8a8",
"#b2b2b2",
"#bcbcbc",
"#c6c6c6",
"#d0d0d0",
"#dadada",
"#e4e4e4",
"#eeeeee",
}

228
vendor/github.com/muesli/termenv/color.go generated vendored Normal file
View File

@@ -0,0 +1,228 @@
package termenv
import (
"errors"
"fmt"
"math"
"strconv"
"strings"
"github.com/lucasb-eyer/go-colorful"
)
var (
ErrInvalidColor = errors.New("invalid color")
)
const (
Foreground = "38"
Background = "48"
)
type Color interface {
Sequence(bg bool) string
}
type NoColor struct{}
// ANSIColor is a color (0-15) as defined by the ANSI Standard.
type ANSIColor int
// ANSI256Color is a color (16-255) as defined by the ANSI Standard.
type ANSI256Color int
// RGBColor is a hex-encoded color, e.g. "#abcdef".
type RGBColor string
func ConvertToRGB(c Color) colorful.Color {
var hex string
switch v := c.(type) {
case RGBColor:
hex = string(v)
case ANSIColor:
hex = ansiHex[v]
case ANSI256Color:
hex = ansiHex[v]
}
ch, _ := colorful.Hex(hex)
return ch
}
func (p Profile) Convert(c Color) Color {
if p == Ascii {
return NoColor{}
}
switch v := c.(type) {
case ANSIColor:
return v
case ANSI256Color:
if p == ANSI {
return ansi256ToANSIColor(v)
}
return v
case RGBColor:
h, err := colorful.Hex(string(v))
if err != nil {
return nil
}
if p < TrueColor {
ac := hexToANSI256Color(h)
if p == ANSI {
return ansi256ToANSIColor(ac)
}
return ac
}
return v
}
return c
}
func (p Profile) Color(s string) Color {
if len(s) == 0 {
return nil
}
var c Color
if strings.HasPrefix(s, "#") {
c = RGBColor(s)
} else {
i, err := strconv.Atoi(s)
if err != nil {
return nil
}
if i < 16 {
c = ANSIColor(i)
} else {
c = ANSI256Color(i)
}
}
return p.Convert(c)
}
func (c NoColor) Sequence(bg bool) string {
return ""
}
func (c ANSIColor) Sequence(bg bool) string {
col := int(c)
bgMod := func(c int) int {
if bg {
return c + 10
}
return c
}
if col < 8 {
return fmt.Sprintf("%d", bgMod(col)+30)
}
return fmt.Sprintf("%d", bgMod(col-8)+90)
}
func (c ANSI256Color) Sequence(bg bool) string {
prefix := Foreground
if bg {
prefix = Background
}
return fmt.Sprintf("%s;5;%d", prefix, c)
}
func (c RGBColor) Sequence(bg bool) string {
f, err := colorful.Hex(string(c))
if err != nil {
return ""
}
prefix := Foreground
if bg {
prefix = Background
}
return fmt.Sprintf("%s;2;%d;%d;%d", prefix, uint8(f.R*255), uint8(f.G*255), uint8(f.B*255))
}
func xTermColor(s string) (RGBColor, error) {
if len(s) != 24 {
return RGBColor(""), ErrInvalidColor
}
s = s[4:]
prefix := ";rgb:"
if !strings.HasPrefix(s, prefix) {
return RGBColor(""), ErrInvalidColor
}
s = strings.TrimPrefix(s, prefix)
s = strings.TrimSuffix(s, "\a")
h := strings.Split(s, "/")
hex := fmt.Sprintf("#%s%s%s", h[0][:2], h[1][:2], h[2][:2])
return RGBColor(hex), nil
}
func ansi256ToANSIColor(c ANSI256Color) ANSIColor {
var r int
md := math.MaxFloat64
h, _ := colorful.Hex(ansiHex[c])
for i := 0; i <= 15; i++ {
hb, _ := colorful.Hex(ansiHex[i])
d := h.DistanceLab(hb)
if d < md {
md = d
r = i
}
}
return ANSIColor(r)
}
func hexToANSI256Color(c colorful.Color) ANSI256Color {
v2ci := func(v float64) int {
if v < 48 {
return 0
}
if v < 115 {
return 1
}
return int((v - 35) / 40)
}
// Calculate the nearest 0-based color index at 16..231
r := v2ci(c.R * 255.0) // 0..5 each
g := v2ci(c.G * 255.0)
b := v2ci(c.B * 255.0)
ci := 36*r + 6*g + b /* 0..215 */
// Calculate the represented colors back from the index
i2cv := [6]int{0, 0x5f, 0x87, 0xaf, 0xd7, 0xff}
cr := i2cv[r] // r/g/b, 0..255 each
cg := i2cv[g]
cb := i2cv[b]
// Calculate the nearest 0-based gray index at 232..255
var grayIdx int
average := (r + g + b) / 3
if average > 238 {
grayIdx = 23
} else {
grayIdx = (average - 3) / 10 // 0..23
}
gv := 8 + 10*grayIdx // same value for r/g/b, 0..255
// Return the one which is nearer to the original input rgb value
c2 := colorful.Color{R: float64(cr) / 255.0, G: float64(cg) / 255.0, B: float64(cb) / 255.0}
g2 := colorful.Color{R: float64(gv) / 255.0, G: float64(gv) / 255.0, B: float64(gv) / 255.0}
colorDist := c.DistanceLab(c2)
grayDist := c.DistanceLab(g2)
if colorDist <= grayDist {
return ANSI256Color(16 + ci)
}
return ANSI256Color(232 + grayIdx)
}

8
vendor/github.com/muesli/termenv/constants_linux.go generated vendored Normal file
View File

@@ -0,0 +1,8 @@
package termenv
import "golang.org/x/sys/unix"
const (
tcgetattr = unix.TCGETS
tcsetattr = unix.TCSETS
)

10
vendor/github.com/muesli/termenv/constants_unix.go generated vendored Normal file
View File

@@ -0,0 +1,10 @@
// +build darwin dragonfly freebsd netbsd openbsd solaris
package termenv
import "golang.org/x/sys/unix"
const (
tcgetattr = unix.TIOCGETA
tcsetattr = unix.TIOCSETA
)

11
vendor/github.com/muesli/termenv/go.mod generated vendored Normal file
View File

@@ -0,0 +1,11 @@
module github.com/muesli/termenv
go 1.13
require (
github.com/google/goterm v0.0.0-20190703233501-fc88cf888a3f
github.com/lucasb-eyer/go-colorful v1.0.3
github.com/mattn/go-isatty v0.0.12
github.com/mattn/go-runewidth v0.0.9
golang.org/x/sys v0.0.0-20200116001909-b77594299b42
)

10
vendor/github.com/muesli/termenv/go.sum generated vendored Normal file
View File

@@ -0,0 +1,10 @@
github.com/google/goterm v0.0.0-20190703233501-fc88cf888a3f h1:5CjVwnuUcp5adK4gmY6i72gpVFVnZDP2h5TmPScB6u4=
github.com/google/goterm v0.0.0-20190703233501-fc88cf888a3f/go.mod h1:nOFQdrUlIlx6M6ODdSpBj1NVA+VgLC6kmw60mkw34H4=
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/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0=
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42 h1:vEOn+mP2zCOVzKckCZy6YsCtDblrpj/w7B9nxGNELpg=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=

200
vendor/github.com/muesli/termenv/screen.go generated vendored Normal file
View File

@@ -0,0 +1,200 @@
package termenv
import (
"fmt"
"strings"
)
const (
CursorUpSeq = "%dA"
CursorDownSeq = "%dB"
CursorForwardSeq = "%dC"
CursorBackSeq = "%dD"
CursorNextLineSeq = "%dE"
CursorPreviousLineSeq = "%dF"
CursorHorizontalSeq = "%dG"
CursorPositionSeq = "%d;%dH"
EraseDisplaySeq = "%dJ"
EraseLineSeq = "%dK"
ScrollUpSeq = "%dS"
ScrollDownSeq = "%dT"
SaveCursorPositionSeq = "s"
RestoreCursorPositionSeq = "u"
ChangeScrollingRegionSeq = "%d;%dr"
InsertLineSeq = "%dL"
DeleteLineSeq = "%dM"
ShowCursorSeq = "?25h"
HideCursorSeq = "?25l"
EnableMousePressSeq = "?9h" // press only (X10)
DisableMousePressSeq = "?9l"
EnableMouseSeq = "?1000h" // press, release, wheel
DisableMouseSeq = "?1000l"
EnableMouseHiliteSeq = "?1001h" // highlight
DisableMouseHiliteSeq = "?1001l"
EnableMouseCellMotionSeq = "?1002h" // press, release, move on pressed, wheel
DisableMouseCellMotionSeq = "?1002l"
EnableMouseAllMotionSeq = "?1003h" // press, release, move, wheel
DisableMouseAllMotionSeq = "?1003l"
AltScreenSeq = "?1049h"
ExitAltScreenSeq = "?1049l"
)
// Reset the terminal to its default style, removing any active styles.
func Reset() {
fmt.Print(CSI + ResetSeq + "m")
}
// AltScreen switches to the alternate screen buffer. The former view can be
// restored with ExitAltScreen().
func AltScreen() {
fmt.Print(CSI + AltScreenSeq)
}
// ExitAltScreen exits the alternate screen buffer and returns to the former
// terminal view.
func ExitAltScreen() {
fmt.Print(CSI + ExitAltScreenSeq)
}
// ClearScreen clears the visible portion of the terminal.
func ClearScreen() {
fmt.Printf(CSI+EraseDisplaySeq, 2)
MoveCursor(1, 1)
}
// MoveCursor moves the cursor to a given position.
func MoveCursor(row int, column int) {
fmt.Printf(CSI+CursorPositionSeq, row, column)
}
// HideCursor hides the cursor.
func HideCursor() {
fmt.Printf(CSI + HideCursorSeq)
}
// ShowCursor shows the cursor.
func ShowCursor() {
fmt.Printf(CSI + ShowCursorSeq)
}
// SaveCursorPosition saves the cursor position.
func SaveCursorPosition() {
fmt.Print(CSI + SaveCursorPositionSeq)
}
// RestoreCursorPosition restores a saved cursor position.
func RestoreCursorPosition() {
fmt.Print(CSI + RestoreCursorPositionSeq)
}
// CursorUp moves the cursor up a given number of lines.
func CursorUp(n int) {
fmt.Printf(CSI+CursorUpSeq, n)
}
// CursorDown moves the cursor down a given number of lines.
func CursorDown(n int) {
fmt.Printf(CSI+CursorDownSeq, n)
}
// CursorForward moves the cursor up a given number of lines.
func CursorForward(n int) {
fmt.Printf(CSI+CursorForwardSeq, n)
}
// CursorBack moves the cursor backwards a given number of cells.
func CursorBack(n int) {
fmt.Printf(CSI+CursorBackSeq, n)
}
// CursorNextLine moves the cursor down a given number of lines and places it at
// the beginning of the line.
func CursorNextLine(n int) {
fmt.Printf(CSI+CursorNextLineSeq, n)
}
// CursorPrevLine moves the cursor up a given number of lines and places it at
// the beginning of the line.
func CursorPrevLine(n int) {
fmt.Printf(CSI+CursorPreviousLineSeq, n)
}
// ClearLine clears the current line.
func ClearLine() {
fmt.Printf(CSI+EraseLineSeq, 2)
}
// ClearLines clears a given number of lines.
func ClearLines(n int) {
clearLine := fmt.Sprintf(CSI+EraseLineSeq, 2)
cursorUp := fmt.Sprintf(CSI+CursorUpSeq, 1)
fmt.Print(clearLine + strings.Repeat(cursorUp+clearLine, n))
}
// ChangeScrollingRegion sets the scrolling region of the terminal.
func ChangeScrollingRegion(top, bottom int) {
fmt.Printf(CSI+ChangeScrollingRegionSeq, top, bottom)
}
// InsertLines inserts the given number lines at the top of the scrollable
// region, pushing lines below down.
func InsertLines(n int) {
fmt.Printf(CSI+InsertLineSeq, n)
}
// DeleteLines deletes the given number of lines, pulling any lines in
// the scrollable region below up.
func DeleteLines(n int) {
fmt.Printf(CSI+DeleteLineSeq, n)
}
// EnableMousePress enables X10 mouse mode. Button press events are sent only.
func EnableMousePress() {
fmt.Print(CSI + EnableMousePressSeq)
}
// DisableMousePress disables X10 mouse mode.
func DisableMousePress() {
fmt.Print(CSI + EnableMousePressSeq)
}
// EnableMouse enables Mouse Tracking mode.
func EnableMouse() {
fmt.Print(CSI + EnableMouseSeq)
}
// DisableMouse disables Mouse Tracking mode.
func DisableMouse() {
fmt.Print(CSI + DisableMouseSeq)
}
// EnableMouseHilite enables Hilite Mouse Tracking mode.
func EnableMouseHilite() {
fmt.Print(CSI + EnableMouseHiliteSeq)
}
// DisableMouseHilite disables Hilite Mouse Tracking mode.
func DisableMouseHilite() {
fmt.Print(CSI + DisableMouseHiliteSeq)
}
// EnableMouseCellMotion enables Cell Motion Mouse Tracking mode.
func EnableMouseCellMotion() {
fmt.Print(CSI + EnableMouseCellMotionSeq)
}
// DisableMouseCellMotion disables Cell Motion Mouse Tracking mode.
func DisableMouseCellMotion() {
fmt.Print(CSI + DisableMouseCellMotionSeq)
}
// EnableMouseAllMotion enables All Motion Mouse mode.
func EnableMouseAllMotion() {
fmt.Print(CSI + EnableMouseAllMotionSeq)
}
// DisableMouseAllMotion disables All Motion Mouse mode.
func DisableMouseAllMotion() {
fmt.Print(CSI + DisableMouseAllMotionSeq)
}

120
vendor/github.com/muesli/termenv/style.go generated vendored Normal file
View File

@@ -0,0 +1,120 @@
package termenv
import (
"fmt"
"strings"
"github.com/mattn/go-runewidth"
)
const (
ResetSeq = "0"
BoldSeq = "1"
FaintSeq = "2"
ItalicSeq = "3"
UnderlineSeq = "4"
BlinkSeq = "5"
ReverseSeq = "7"
CrossOutSeq = "9"
OverlineSeq = "53"
)
// Style is a string that various rendering styles can be applied to.
type Style struct {
string
styles []string
}
// String returns a new Style.
func String(s ...string) Style {
return Style{
string: strings.Join(s, " "),
}
}
func (t Style) String() string {
return t.Styled(t.string)
}
// Styled renders s with all applied styles.
func (t Style) Styled(s string) string {
if len(t.styles) == 0 {
return s
}
seq := strings.Join(t.styles, ";")
if seq == "" {
return s
}
return fmt.Sprintf("%s%sm%s%sm", CSI, seq, s, CSI+ResetSeq)
}
// Foreground sets a foreground color.
func (t Style) Foreground(c Color) Style {
if c != nil {
t.styles = append(t.styles, c.Sequence(false))
}
return t
}
// Background sets a background color.
func (t Style) Background(c Color) Style {
if c != nil {
t.styles = append(t.styles, c.Sequence(true))
}
return t
}
// Bold enables bold rendering.
func (t Style) Bold() Style {
t.styles = append(t.styles, BoldSeq)
return t
}
// Faint enables faint rendering.
func (t Style) Faint() Style {
t.styles = append(t.styles, FaintSeq)
return t
}
// Italic enables italic rendering.
func (t Style) Italic() Style {
t.styles = append(t.styles, ItalicSeq)
return t
}
// Underline enables underline rendering.
func (t Style) Underline() Style {
t.styles = append(t.styles, UnderlineSeq)
return t
}
// Overline enables overline rendering.
func (t Style) Overline() Style {
t.styles = append(t.styles, OverlineSeq)
return t
}
// Blink enables blink mode.
func (t Style) Blink() Style {
t.styles = append(t.styles, BlinkSeq)
return t
}
// Reverse enables reverse color mode.
func (t Style) Reverse() Style {
t.styles = append(t.styles, ReverseSeq)
return t
}
// CrossOut enables crossed-out rendering.
func (t Style) CrossOut() Style {
t.styles = append(t.styles, CrossOutSeq)
return t
}
// Width returns the width required to print all runes in Style.
func (t Style) Width() int {
return runewidth.StringWidth(t.string)
}

55
vendor/github.com/muesli/termenv/templatehelper.go generated vendored Normal file
View File

@@ -0,0 +1,55 @@
package termenv
import (
"text/template"
)
// TemplateFuncs contains a few useful template helpers.
func TemplateFuncs(p Profile) template.FuncMap {
return template.FuncMap{
"Color": func(values ...interface{}) string {
s := String(values[len(values)-1].(string))
switch len(values) {
case 2:
s = s.Foreground(p.Color(values[0].(string)))
case 3:
s = s.
Foreground(p.Color(values[0].(string))).
Background(p.Color(values[1].(string)))
}
return s.String()
},
"Foreground": func(values ...interface{}) string {
s := String(values[len(values)-1].(string))
if len(values) == 2 {
s = s.Foreground(p.Color(values[0].(string)))
}
return s.String()
},
"Background": func(values ...interface{}) string {
s := String(values[len(values)-1].(string))
if len(values) == 2 {
s = s.Background(p.Color(values[0].(string)))
}
return s.String()
},
"Bold": styleFunc(Style.Bold),
"Faint": styleFunc(Style.Faint),
"Italic": styleFunc(Style.Italic),
"Underline": styleFunc(Style.Underline),
"Overline": styleFunc(Style.Overline),
"Blink": styleFunc(Style.Blink),
"Reverse": styleFunc(Style.Reverse),
"CrossOut": styleFunc(Style.CrossOut),
}
}
func styleFunc(f func(Style) Style) func(...interface{}) string {
return func(values ...interface{}) string {
s := String(values[0].(string))
return f(s).String()
}
}

92
vendor/github.com/muesli/termenv/termenv.go generated vendored Normal file
View File

@@ -0,0 +1,92 @@
package termenv
import (
"errors"
"os"
"github.com/mattn/go-isatty"
)
var (
ErrStatusReport = errors.New("unable to retrieve status report")
)
type Profile int
const (
CSI = "\x1b["
Ascii = Profile(iota)
ANSI
ANSI256
TrueColor
)
// ColorProfile returns the supported color profile:
// Ascii, ANSI, ANSI256, or TrueColor.
func ColorProfile() Profile {
if !isatty.IsTerminal(os.Stdout.Fd()) {
return Ascii
}
return colorProfile()
}
// ForegroundColor returns the terminal's default foreground color.
func ForegroundColor() Color {
if !isatty.IsTerminal(os.Stdout.Fd()) {
return NoColor{}
}
return foregroundColor()
}
// BackgroundColor returns the terminal's default background color.
func BackgroundColor() Color {
if !isatty.IsTerminal(os.Stdout.Fd()) {
return NoColor{}
}
return backgroundColor()
}
// HasDarkBackground returns whether terminal uses a dark-ish background.
func HasDarkBackground() bool {
c := ConvertToRGB(BackgroundColor())
_, _, l := c.Hsl()
return l < 0.5
}
// EnvNoColor returns true if the environment variables explicitly disable color output
// by setting NO_COLOR (https://no-color.org/)
// or CLICOLOR/CLICOLOR_FORCE (https://bixense.com/clicolors/)
// If NO_COLOR is set, this will return true, ignoring CLICOLOR/CLICOLOR_FORCE
// If CLICOLOR=="0", it will be true only if CLICOLOR_FORCE is also "0" or is unset.
func EnvNoColor() bool {
return os.Getenv("NO_COLOR") != "" || (os.Getenv("CLICOLOR") == "0" && !cliColorForced())
}
// EnvColorProfile returns the color profile based on environment variables set
// Supports NO_COLOR (https://no-color.org/)
// and CLICOLOR/CLICOLOR_FORCE (https://bixense.com/clicolors/)
// If none of these environment variables are set, this behaves the same as ColorProfile()
// It will return the Ascii color profile if EnvNoColor() returns true
// If the terminal does not support any colors, but CLICOLOR_FORCE is set and not "0"
// then the ANSI color profile will be returned.
func EnvColorProfile() Profile {
if EnvNoColor() {
return Ascii
}
p := ColorProfile()
if cliColorForced() && p == Ascii {
return ANSI
}
return p
}
func cliColorForced() bool {
if forced := os.Getenv("CLICOLOR_FORCE"); forced != "" {
return forced != "0"
}
return false
}

143
vendor/github.com/muesli/termenv/termenv_unix.go generated vendored Normal file
View File

@@ -0,0 +1,143 @@
// +build darwin dragonfly freebsd linux netbsd openbsd solaris
package termenv
import (
"fmt"
"os"
"runtime"
"strconv"
"strings"
"golang.org/x/sys/unix"
)
func colorProfile() Profile {
colorTerm := os.Getenv("COLORTERM")
if colorTerm == "truecolor" {
return TrueColor
}
term := os.Getenv("TERM")
if strings.Contains(term, "256color") {
return ANSI256
}
if strings.Contains(term, "color") {
return ANSI
}
return Ascii
}
func foregroundColor() Color {
s, err := termStatusReport(10)
if err == nil {
c, err := xTermColor(s)
if err == nil {
return c
}
}
colorFGBG := os.Getenv("COLORFGBG")
if strings.Contains(colorFGBG, ";") {
c := strings.Split(colorFGBG, ";")
i, err := strconv.Atoi(c[0])
if err == nil {
return ANSIColor(i)
}
}
// default gray
return ANSIColor(7)
}
func backgroundColor() Color {
s, err := termStatusReport(11)
if err == nil {
c, err := xTermColor(s)
if err == nil {
return c
}
}
colorFGBG := os.Getenv("COLORFGBG")
if strings.Contains(colorFGBG, ";") {
c := strings.Split(colorFGBG, ";")
i, err := strconv.Atoi(c[1])
if err == nil {
return ANSIColor(i)
}
}
// default black
return ANSIColor(0)
}
func readWithTimeout(f *os.File) (string, bool) {
var readfds unix.FdSet
fd := int(f.Fd())
readfds.Set(fd)
for {
// Use select to attempt to read from os.Stdout for 100 ms
_, err := unix.Select(fd+1, &readfds, nil, nil, &unix.Timeval{Usec: 100000})
if err == nil {
break
}
// On MacOS we can see EINTR here if the user
// pressed ^Z. Similar to issue https://github.com/golang/go/issues/22838
if runtime.GOOS == "darwin" && err == unix.EINTR {
continue
}
// log.Printf("select(read error): %v", err)
return "", false
}
if !readfds.IsSet(fd) {
// log.Print("select(read timeout)")
return "", false
}
// n > 0 => is readable
var data []byte
b := make([]byte, 1)
for {
_, err := f.Read(b)
if err != nil {
// log.Printf("read(%d): %v %d", fd, err, n)
return "", false
}
// log.Printf("read %d bytes from stdout: %s %d\n", n, data, data[len(data)-1])
data = append(data, b[0])
if b[0] == '\a' || (b[0] == '\\' && len(data) > 2) {
break
}
}
// fmt.Printf("read %d bytes from stdout: %s\n", n, data)
return string(data), true
}
func termStatusReport(sequence int) (string, error) {
t, err := unix.IoctlGetTermios(unix.Stdout, tcgetattr)
if err != nil {
return "", ErrStatusReport
}
defer unix.IoctlSetTermios(unix.Stdout, tcsetattr, t)
noecho := *t
noecho.Lflag = noecho.Lflag &^ unix.ECHO
noecho.Lflag = noecho.Lflag &^ unix.ICANON
if err := unix.IoctlSetTermios(unix.Stdout, tcsetattr, &noecho); err != nil {
return "", ErrStatusReport
}
fmt.Printf("\033]%d;?\007", sequence)
s, ok := readWithTimeout(os.Stdout)
if !ok {
return "", ErrStatusReport
}
// fmt.Println("Rcvd", s[1:])
return s, nil
}

17
vendor/github.com/muesli/termenv/termenv_windows.go generated vendored Normal file
View File

@@ -0,0 +1,17 @@
// +build windows
package termenv
func colorProfile() Profile {
return TrueColor
}
func foregroundColor() Color {
// default gray
return ANSIColor(7)
}
func backgroundColor() Color {
// default black
return ANSIColor(0)
}