vendor in deps so CI goes fast
This commit is contained in:
		
							parent
							
								
									7a47873be3
								
							
						
					
					
						commit
						081028f3b2
					
				
							
								
								
									
										31
									
								
								vendor/github.com/atomicgo/cursor/.gitignore
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								vendor/github.com/atomicgo/cursor/.gitignore
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,31 @@ | |||||||
|  | ### Go template | ||||||
|  | # 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/ | ||||||
|  | 
 | ||||||
|  | ### IntelliJ | ||||||
|  | .idea | ||||||
|  | *.iml | ||||||
|  | out | ||||||
|  | gen | ||||||
|  | 
 | ||||||
|  | ### VisualStudioCode | ||||||
|  | .vscode | ||||||
|  | *.code-workspace | ||||||
|  | 
 | ||||||
|  | ### macOS | ||||||
|  | # General | ||||||
|  | .DS_Store | ||||||
|  | experimenting | ||||||
							
								
								
									
										71
									
								
								vendor/github.com/atomicgo/cursor/.golangci.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								vendor/github.com/atomicgo/cursor/.golangci.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,71 @@ | |||||||
|  | linters-settings: | ||||||
|  |   gocritic: | ||||||
|  |     enabled-tags: | ||||||
|  |       - diagnostic | ||||||
|  |       - experimental | ||||||
|  |       - opinionated | ||||||
|  |       - performance | ||||||
|  |       - style | ||||||
|  |     disabled-checks: | ||||||
|  |       - dupImport | ||||||
|  |       - ifElseChain | ||||||
|  |       - octalLiteral | ||||||
|  |       - whyNoLint | ||||||
|  |       - wrapperFunc | ||||||
|  |       - exitAfterDefer | ||||||
|  |       - hugeParam | ||||||
|  |       - ptrToRefParam | ||||||
|  |       - paramTypeCombine | ||||||
|  |       - unnamedResult | ||||||
|  |   misspell: | ||||||
|  |     locale: US | ||||||
|  | linters: | ||||||
|  |   disable-all: true | ||||||
|  |   enable: | ||||||
|  |     - errcheck | ||||||
|  |     - gosimple | ||||||
|  |     - govet | ||||||
|  |     - ineffassign | ||||||
|  |     - staticcheck | ||||||
|  |     - asciicheck | ||||||
|  |     - bodyclose | ||||||
|  |     - dupl | ||||||
|  |     - durationcheck | ||||||
|  |     - errorlint | ||||||
|  |     - exhaustive | ||||||
|  |     - gci | ||||||
|  |     - gocognit | ||||||
|  |     - gocritic | ||||||
|  |     - godot | ||||||
|  |     - godox | ||||||
|  |     - goerr113 | ||||||
|  |     - gofmt | ||||||
|  |     - goimports | ||||||
|  |     - goprintffuncname | ||||||
|  |     - misspell | ||||||
|  |     - nilerr | ||||||
|  |     - nlreturn | ||||||
|  |     - noctx | ||||||
|  |     - prealloc | ||||||
|  |     - predeclared | ||||||
|  |     - thelper | ||||||
|  |     - unconvert | ||||||
|  |     - unparam | ||||||
|  |     - wastedassign | ||||||
|  |     - wrapcheck | ||||||
|  | issues: | ||||||
|  |   # Excluding configuration per-path, per-linter, per-text and per-source | ||||||
|  |   exclude-rules: | ||||||
|  |     - path: _test\.go | ||||||
|  |       linters: | ||||||
|  |         - errcheck | ||||||
|  |         - dupl | ||||||
|  |         - gocritic | ||||||
|  |         - wrapcheck | ||||||
|  |         - goerr113 | ||||||
|  |     # https://github.com/go-critic/go-critic/issues/926 | ||||||
|  |     - linters: | ||||||
|  |         - gocritic | ||||||
|  |       text: "unnecessaryDefer:" | ||||||
|  | service: | ||||||
|  |   golangci-lint-version: 1.39.x # use the fixed version to not introduce new linters unexpectedly | ||||||
							
								
								
									
										0
									
								
								vendor/github.com/atomicgo/cursor/CHANGELOG.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								vendor/github.com/atomicgo/cursor/CHANGELOG.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
								
								
									
										21
									
								
								vendor/github.com/atomicgo/cursor/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								vendor/github.com/atomicgo/cursor/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,21 @@ | |||||||
|  | MIT License | ||||||
|  | 
 | ||||||
|  | Copyright (c) 2020 Marvin Wendt (MarvinJWendt) | ||||||
|  | 
 | ||||||
|  | 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. | ||||||
							
								
								
									
										237
									
								
								vendor/github.com/atomicgo/cursor/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										237
									
								
								vendor/github.com/atomicgo/cursor/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,237 @@ | |||||||
|  | <h1 align="center">AtomicGo | cursor</h1> | ||||||
|  | 
 | ||||||
|  | <p align="center"> | ||||||
|  | 
 | ||||||
|  | <a href="https://github.com/atomicgo/cursor/releases"> | ||||||
|  | <img src="https://img.shields.io/github/v/release/atomicgo/cursor?style=flat-square" alt="Latest Release"> | ||||||
|  | </a> | ||||||
|  | 
 | ||||||
|  | <a href="https://codecov.io/gh/atomicgo/cursor" target="_blank"> | ||||||
|  | <img src="https://img.shields.io/github/workflow/status/atomicgo/cursor/Go?label=tests&style=flat-square" alt="Tests"> | ||||||
|  | </a> | ||||||
|  | 
 | ||||||
|  | <a href="https://codecov.io/gh/atomicgo/cursor" target="_blank"> | ||||||
|  | <img src="https://img.shields.io/codecov/c/gh/atomicgo/cursor?color=magenta&logo=codecov&style=flat-square" alt="Coverage"> | ||||||
|  | </a> | ||||||
|  | 
 | ||||||
|  | <a href="https://codecov.io/gh/atomicgo/cursor"> | ||||||
|  | <!-- unittestcount:start --><img src="https://img.shields.io/badge/Unit_Tests-2-magenta?style=flat-square" alt="Unit test count"><!-- unittestcount:end --> | ||||||
|  | </a> | ||||||
|  | 
 | ||||||
|  | <a href="https://github.com/atomicgo/cursor/issues"> | ||||||
|  | <img src="https://img.shields.io/github/issues/atomicgo/cursor.svg?style=flat-square" alt="Issues"> | ||||||
|  | </a> | ||||||
|  | 
 | ||||||
|  | <a href="https://opensource.org/licenses/MIT" target="_blank"> | ||||||
|  | <img src="https://img.shields.io/badge/License-MIT-yellow.svg?style=flat-square" alt="License: MIT"> | ||||||
|  | </a> | ||||||
|  | 
 | ||||||
|  | </p> | ||||||
|  | 
 | ||||||
|  | --- | ||||||
|  | 
 | ||||||
|  | <p align="center"> | ||||||
|  | <strong><a href="#install">Get The Module</a></strong> | ||||||
|  | | | ||||||
|  | <strong><a href="https://pkg.go.dev/github.com/atomicgo/cursor#section-documentation" target="_blank">Documentation</a></strong> | ||||||
|  | | | ||||||
|  | <strong><a href="https://github.com/atomicgo/atomicgo/blob/main/CONTRIBUTING.md" target="_blank">Contributing</a></strong> | ||||||
|  | | | ||||||
|  | <strong><a href="https://github.com/atomicgo/atomicgo/blob/main/CODE_OF_CONDUCT.md" target="_blank">Code of Conduct</a></strong> | ||||||
|  | </p> | ||||||
|  | 
 | ||||||
|  | --- | ||||||
|  | 
 | ||||||
|  | <p align="center"> | ||||||
|  |   <img src="https://raw.githubusercontent.com/atomicgo/atomicgo/main/assets/header.png" alt="AtomicGo"> | ||||||
|  | </p> | ||||||
|  | 
 | ||||||
|  | ## Description | ||||||
|  | 
 | ||||||
|  | Package cursor contains cross-platform methods to move the terminal cursor in | ||||||
|  | different directions. This package can be used to create interactive CLI tools | ||||||
|  | and games, live charts, algorithm visualizations and other updatable output of | ||||||
|  | any kind. | ||||||
|  | 
 | ||||||
|  | Special thanks to github.com/k0kubun/go-ansi which this project is based on. | ||||||
|  | 
 | ||||||
|  | ## Install | ||||||
|  | 
 | ||||||
|  | ```console | ||||||
|  | # Execute this command inside your project | ||||||
|  | go get -u github.com/atomicgo/cursor | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ```go | ||||||
|  | // Add this to your imports | ||||||
|  | import "github.com/atomicgo/cursor" | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ## Usage | ||||||
|  | 
 | ||||||
|  | #### func  Bottom | ||||||
|  | 
 | ||||||
|  | ```go | ||||||
|  | func Bottom() | ||||||
|  | ``` | ||||||
|  | Bottom moves the cursor to the bottom of the terminal. This is done by | ||||||
|  | calculating how many lines were moved by Up and Down. | ||||||
|  | 
 | ||||||
|  | #### func  ClearLine | ||||||
|  | 
 | ||||||
|  | ```go | ||||||
|  | func ClearLine() | ||||||
|  | ``` | ||||||
|  | ClearLine clears the current line and moves the cursor to it's start position. | ||||||
|  | 
 | ||||||
|  | #### func  ClearLinesDown | ||||||
|  | 
 | ||||||
|  | ```go | ||||||
|  | func ClearLinesDown(n int) | ||||||
|  | ``` | ||||||
|  | ClearLinesDown clears n lines downwards from the current position and moves the | ||||||
|  | cursor. | ||||||
|  | 
 | ||||||
|  | #### func  ClearLinesUp | ||||||
|  | 
 | ||||||
|  | ```go | ||||||
|  | func ClearLinesUp(n int) | ||||||
|  | ``` | ||||||
|  | ClearLinesUp clears n lines upwards from the current position and moves the | ||||||
|  | cursor. | ||||||
|  | 
 | ||||||
|  | #### func  Down | ||||||
|  | 
 | ||||||
|  | ```go | ||||||
|  | func Down(n int) | ||||||
|  | ``` | ||||||
|  | Down moves the cursor n lines down relative to the current position. | ||||||
|  | 
 | ||||||
|  | #### func  DownAndClear | ||||||
|  | 
 | ||||||
|  | ```go | ||||||
|  | func DownAndClear(n int) | ||||||
|  | ``` | ||||||
|  | DownAndClear moves the cursor down by n lines, then clears the line. | ||||||
|  | 
 | ||||||
|  | #### func  Hide | ||||||
|  | 
 | ||||||
|  | ```go | ||||||
|  | func Hide() | ||||||
|  | ``` | ||||||
|  | Hide the cursor. Don't forget to show the cursor at least at the end of your | ||||||
|  | application with Show. Otherwise the user might have a terminal with a | ||||||
|  | permanently hidden cursor, until he reopens the terminal. | ||||||
|  | 
 | ||||||
|  | #### func  HorizontalAbsolute | ||||||
|  | 
 | ||||||
|  | ```go | ||||||
|  | func HorizontalAbsolute(n int) | ||||||
|  | ``` | ||||||
|  | HorizontalAbsolute moves the cursor to n horizontally. The position n is | ||||||
|  | absolute to the start of the line. | ||||||
|  | 
 | ||||||
|  | #### func  Left | ||||||
|  | 
 | ||||||
|  | ```go | ||||||
|  | func Left(n int) | ||||||
|  | ``` | ||||||
|  | Left moves the cursor n characters to the left relative to the current position. | ||||||
|  | 
 | ||||||
|  | #### func  Move | ||||||
|  | 
 | ||||||
|  | ```go | ||||||
|  | func Move(x, y int) | ||||||
|  | ``` | ||||||
|  | Move moves the cursor relative by x and y. | ||||||
|  | 
 | ||||||
|  | #### func  Right | ||||||
|  | 
 | ||||||
|  | ```go | ||||||
|  | func Right(n int) | ||||||
|  | ``` | ||||||
|  | Right moves the cursor n characters to the right relative to the current | ||||||
|  | position. | ||||||
|  | 
 | ||||||
|  | #### func  Show | ||||||
|  | 
 | ||||||
|  | ```go | ||||||
|  | func Show() | ||||||
|  | ``` | ||||||
|  | Show the cursor if it was hidden previously. Don't forget to show the cursor at | ||||||
|  | least at the end of your application. Otherwise the user might have a terminal | ||||||
|  | with a permanently hidden cursor, until he reopens the terminal. | ||||||
|  | 
 | ||||||
|  | #### func  StartOfLine | ||||||
|  | 
 | ||||||
|  | ```go | ||||||
|  | func StartOfLine() | ||||||
|  | ``` | ||||||
|  | StartOfLine moves the cursor to the start of the current line. | ||||||
|  | 
 | ||||||
|  | #### func  StartOfLineDown | ||||||
|  | 
 | ||||||
|  | ```go | ||||||
|  | func StartOfLineDown(n int) | ||||||
|  | ``` | ||||||
|  | StartOfLineDown moves the cursor down by n lines, then moves to cursor to the | ||||||
|  | start of the line. | ||||||
|  | 
 | ||||||
|  | #### func  StartOfLineUp | ||||||
|  | 
 | ||||||
|  | ```go | ||||||
|  | func StartOfLineUp(n int) | ||||||
|  | ``` | ||||||
|  | StartOfLineUp moves the cursor up by n lines, then moves to cursor to the start | ||||||
|  | of the line. | ||||||
|  | 
 | ||||||
|  | #### func  Up | ||||||
|  | 
 | ||||||
|  | ```go | ||||||
|  | func Up(n int) | ||||||
|  | ``` | ||||||
|  | Up moves the cursor n lines up relative to the current position. | ||||||
|  | 
 | ||||||
|  | #### func  UpAndClear | ||||||
|  | 
 | ||||||
|  | ```go | ||||||
|  | func UpAndClear(n int) | ||||||
|  | ``` | ||||||
|  | UpAndClear moves the cursor up by n lines, then clears the line. | ||||||
|  | 
 | ||||||
|  | #### type Area | ||||||
|  | 
 | ||||||
|  | ```go | ||||||
|  | type Area struct { | ||||||
|  | } | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | Area displays content which can be updated on the fly. You can use this to | ||||||
|  | create live output, charts, dropdowns, etc. | ||||||
|  | 
 | ||||||
|  | #### func  NewArea | ||||||
|  | 
 | ||||||
|  | ```go | ||||||
|  | func NewArea() Area | ||||||
|  | ``` | ||||||
|  | NewArea returns a new Area. | ||||||
|  | 
 | ||||||
|  | #### func (*Area) Clear | ||||||
|  | 
 | ||||||
|  | ```go | ||||||
|  | func (area *Area) Clear() | ||||||
|  | ``` | ||||||
|  | Clear clears the content of the Area. | ||||||
|  | 
 | ||||||
|  | #### func (*Area) Update | ||||||
|  | 
 | ||||||
|  | ```go | ||||||
|  | func (area *Area) Update(content string) | ||||||
|  | ``` | ||||||
|  | Update overwrites the content of the Area. | ||||||
|  | 
 | ||||||
|  | --- | ||||||
|  | 
 | ||||||
|  | > [AtomicGo.dev](https://atomicgo.dev)  ·  | ||||||
|  | > with ❤️ by [@MarvinJWendt](https://github.com/MarvinJWendt) | | ||||||
|  | > [MarvinJWendt.com](https://marvinjwendt.com) | ||||||
							
								
								
									
										45
									
								
								vendor/github.com/atomicgo/cursor/area.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								vendor/github.com/atomicgo/cursor/area.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,45 @@ | |||||||
|  | package cursor | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  | 	"runtime" | ||||||
|  | 	"strings" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // Area displays content which can be updated on the fly.
 | ||||||
|  | // You can use this to create live output, charts, dropdowns, etc.
 | ||||||
|  | type Area struct { | ||||||
|  | 	height int | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // NewArea returns a new Area.
 | ||||||
|  | func NewArea() Area { | ||||||
|  | 	return Area{} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Clear clears the content of the Area.
 | ||||||
|  | func (area *Area) Clear() { | ||||||
|  | 	Bottom() | ||||||
|  | 	if area.height > 0 { | ||||||
|  | 		ClearLinesUp(area.height) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Update overwrites the content of the Area.
 | ||||||
|  | func (area *Area) Update(content string) { | ||||||
|  | 	area.Clear() | ||||||
|  | 	lines := strings.Split(content, "\n") | ||||||
|  | 	if runtime.GOOS == "windows" { | ||||||
|  | 		for _, line := range lines { | ||||||
|  | 			fmt.Print(line) | ||||||
|  | 			StartOfLineDown(1) | ||||||
|  | 		} | ||||||
|  | 	} else { | ||||||
|  | 		for _, line := range lines { | ||||||
|  | 			fmt.Println(line) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	height = 0 | ||||||
|  | 
 | ||||||
|  | 	area.height = len(lines) | ||||||
|  | } | ||||||
							
								
								
									
										59
									
								
								vendor/github.com/atomicgo/cursor/cursor.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								vendor/github.com/atomicgo/cursor/cursor.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,59 @@ | |||||||
|  | // +build !windows
 | ||||||
|  | 
 | ||||||
|  | package cursor | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // Up moves the cursor n lines up relative to the current position.
 | ||||||
|  | func Up(n int) { | ||||||
|  | 	fmt.Printf("\x1b[%dA", n) | ||||||
|  | 	height += n | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Down moves the cursor n lines down relative to the current position.
 | ||||||
|  | func Down(n int) { | ||||||
|  | 	fmt.Printf("\x1b[%dB", n) | ||||||
|  | 	if height-n <= 0 { | ||||||
|  | 		height = 0 | ||||||
|  | 	} else { | ||||||
|  | 		height -= n | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Right moves the cursor n characters to the right relative to the current position.
 | ||||||
|  | func Right(n int) { | ||||||
|  | 	fmt.Printf("\x1b[%dC", n) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Left moves the cursor n characters to the left relative to the current position.
 | ||||||
|  | func Left(n int) { | ||||||
|  | 	fmt.Printf("\x1b[%dD", n) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // HorizontalAbsolute moves the cursor to n horizontally.
 | ||||||
|  | // The position n is absolute to the start of the line.
 | ||||||
|  | func HorizontalAbsolute(n int) { | ||||||
|  | 	n += 1 // Moves the line to the character after n
 | ||||||
|  | 	fmt.Printf("\x1b[%dG", n) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Show the cursor if it was hidden previously.
 | ||||||
|  | // Don't forget to show the cursor at least at the end of your application.
 | ||||||
|  | // Otherwise the user might have a terminal with a permanently hidden cursor, until he reopens the terminal.
 | ||||||
|  | func Show() { | ||||||
|  | 	fmt.Print("\x1b[?25h") | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Hide the cursor.
 | ||||||
|  | // Don't forget to show the cursor at least at the end of your application with Show.
 | ||||||
|  | // Otherwise the user might have a terminal with a permanently hidden cursor, until he reopens the terminal.
 | ||||||
|  | func Hide() { | ||||||
|  | 	fmt.Print("\x1b[?25l") | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ClearLine clears the current line and moves the cursor to it's start position.
 | ||||||
|  | func ClearLine() { | ||||||
|  | 	fmt.Print("\x1b[2K") | ||||||
|  | } | ||||||
							
								
								
									
										105
									
								
								vendor/github.com/atomicgo/cursor/cursor_windows.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										105
									
								
								vendor/github.com/atomicgo/cursor/cursor_windows.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,105 @@ | |||||||
|  | package cursor | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"os" | ||||||
|  | 	"syscall" | ||||||
|  | 	"unsafe" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // Up moves the cursor n lines up relative to the current position.
 | ||||||
|  | func Up(n int) { | ||||||
|  | 	move(0, -n) | ||||||
|  | 	height += n | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Down moves the cursor n lines down relative to the current position.
 | ||||||
|  | func Down(n int) { | ||||||
|  | 	move(0, n) | ||||||
|  | 	if height-n <= 0 { | ||||||
|  | 		height = 0 | ||||||
|  | 	} else { | ||||||
|  | 		height -= n | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Right moves the cursor n characters to the right relative to the current position.
 | ||||||
|  | func Right(n int) { | ||||||
|  | 	move(n, 0) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Left moves the cursor n characters to the left relative to the current position.
 | ||||||
|  | func Left(n int) { | ||||||
|  | 	move(-n, 0) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func move(x int, y int) { | ||||||
|  | 	handle := syscall.Handle(os.Stdout.Fd()) | ||||||
|  | 
 | ||||||
|  | 	var csbi consoleScreenBufferInfo | ||||||
|  | 	_, _, _ = procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) | ||||||
|  | 
 | ||||||
|  | 	var cursor coord | ||||||
|  | 	cursor.x = csbi.cursorPosition.x + short(x) | ||||||
|  | 	cursor.y = csbi.cursorPosition.y + short(y) | ||||||
|  | 
 | ||||||
|  | 	_, _, _ = procSetConsoleCursorPosition.Call(uintptr(handle), uintptr(*(*int32)(unsafe.Pointer(&cursor)))) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // HorizontalAbsolute moves the cursor to n horizontally.
 | ||||||
|  | // The position n is absolute to the start of the line.
 | ||||||
|  | func HorizontalAbsolute(n int) { | ||||||
|  | 	handle := syscall.Handle(os.Stdout.Fd()) | ||||||
|  | 
 | ||||||
|  | 	var csbi consoleScreenBufferInfo | ||||||
|  | 	_, _, _ = procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) | ||||||
|  | 
 | ||||||
|  | 	var cursor coord | ||||||
|  | 	cursor.x = short(n) | ||||||
|  | 	cursor.y = csbi.cursorPosition.y | ||||||
|  | 
 | ||||||
|  | 	if csbi.size.x < cursor.x { | ||||||
|  | 		cursor.x = csbi.size.x | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	_, _, _ = procSetConsoleCursorPosition.Call(uintptr(handle), uintptr(*(*int32)(unsafe.Pointer(&cursor)))) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Show the cursor if it was hidden previously.
 | ||||||
|  | // Don't forget to show the cursor at least at the end of your application.
 | ||||||
|  | // Otherwise the user might have a terminal with a permanently hidden cursor, until he reopens the terminal.
 | ||||||
|  | func Show() { | ||||||
|  | 	handle := syscall.Handle(os.Stdout.Fd()) | ||||||
|  | 
 | ||||||
|  | 	var cci consoleCursorInfo | ||||||
|  | 	_, _, _ = procGetConsoleCursorInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&cci))) | ||||||
|  | 	cci.visible = 1 | ||||||
|  | 
 | ||||||
|  | 	_, _, _ = procSetConsoleCursorInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&cci))) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Hide the cursor.
 | ||||||
|  | // Don't forget to show the cursor at least at the end of your application with Show.
 | ||||||
|  | // Otherwise the user might have a terminal with a permanently hidden cursor, until he reopens the terminal.
 | ||||||
|  | func Hide() { | ||||||
|  | 	handle := syscall.Handle(os.Stdout.Fd()) | ||||||
|  | 
 | ||||||
|  | 	var cci consoleCursorInfo | ||||||
|  | 	_, _, _ = procGetConsoleCursorInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&cci))) | ||||||
|  | 	cci.visible = 0 | ||||||
|  | 
 | ||||||
|  | 	_, _, _ = procSetConsoleCursorInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&cci))) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ClearLine clears the current line and moves the cursor to it's start position.
 | ||||||
|  | func ClearLine() { | ||||||
|  | 	handle := syscall.Handle(os.Stdout.Fd()) | ||||||
|  | 
 | ||||||
|  | 	var csbi consoleScreenBufferInfo | ||||||
|  | 	_, _, _ = procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) | ||||||
|  | 
 | ||||||
|  | 	var w uint32 | ||||||
|  | 	var x short | ||||||
|  | 	cursor := csbi.cursorPosition | ||||||
|  | 	x = csbi.size.x | ||||||
|  | 	_, _, _ = procFillConsoleOutputCharacter.Call(uintptr(handle), uintptr(' '), uintptr(x), uintptr(*(*int32)(unsafe.Pointer(&cursor))), uintptr(unsafe.Pointer(&w))) | ||||||
|  | } | ||||||
							
								
								
									
										7
									
								
								vendor/github.com/atomicgo/cursor/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								vendor/github.com/atomicgo/cursor/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,7 @@ | |||||||
|  | /* | ||||||
|  | Package cursor contains cross-platform methods to move the terminal cursor in different directions. | ||||||
|  | This package can be used to create interactive CLI tools and games, live charts, algorithm visualizations and other updatable output of any kind. | ||||||
|  | 
 | ||||||
|  | Special thanks to github.com/k0kubun/go-ansi which this project is based on. | ||||||
|  | */ | ||||||
|  | package cursor | ||||||
							
								
								
									
										3
									
								
								vendor/github.com/atomicgo/cursor/go.mod
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								vendor/github.com/atomicgo/cursor/go.mod
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,3 @@ | |||||||
|  | module github.com/atomicgo/cursor | ||||||
|  | 
 | ||||||
|  | go 1.15 | ||||||
							
								
								
									
										0
									
								
								vendor/github.com/atomicgo/cursor/go.sum
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								vendor/github.com/atomicgo/cursor/go.sum
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
								
								
									
										43
									
								
								vendor/github.com/atomicgo/cursor/syscall_windows.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								vendor/github.com/atomicgo/cursor/syscall_windows.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,43 @@ | |||||||
|  | package cursor | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"syscall" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | var ( | ||||||
|  | 	kernel32                       = syscall.NewLazyDLL("kernel32.dll") | ||||||
|  | 	procFillConsoleOutputCharacter = kernel32.NewProc("FillConsoleOutputCharacterW") | ||||||
|  | 	procGetConsoleCursorInfo       = kernel32.NewProc("GetConsoleCursorInfo") | ||||||
|  | 	procGetConsoleScreenBufferInfo = kernel32.NewProc("GetConsoleScreenBufferInfo") | ||||||
|  | 	procSetConsoleCursorInfo       = kernel32.NewProc("SetConsoleCursorInfo") | ||||||
|  | 	procSetConsoleCursorPosition   = kernel32.NewProc("SetConsoleCursorPosition") | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | type short int16 | ||||||
|  | type dword uint32 | ||||||
|  | type word uint16 | ||||||
|  | 
 | ||||||
|  | type coord struct { | ||||||
|  | 	x short | ||||||
|  | 	y short | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | type smallRect struct { | ||||||
|  | 	bottom short | ||||||
|  | 	left   short | ||||||
|  | 	right  short | ||||||
|  | 	top    short | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | type consoleScreenBufferInfo struct { | ||||||
|  | 	size              coord | ||||||
|  | 	cursorPosition    coord | ||||||
|  | 	attributes        word | ||||||
|  | 	window            smallRect | ||||||
|  | 	maximumWindowSize coord | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | type consoleCursorInfo struct { | ||||||
|  | 	size    dword | ||||||
|  | 	visible int32 | ||||||
|  | } | ||||||
							
								
								
									
										73
									
								
								vendor/github.com/atomicgo/cursor/utils.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								vendor/github.com/atomicgo/cursor/utils.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,73 @@ | |||||||
|  | package cursor | ||||||
|  | 
 | ||||||
|  | var height int | ||||||
|  | 
 | ||||||
|  | // Bottom moves the cursor to the bottom of the terminal.
 | ||||||
|  | // This is done by calculating how many lines were moved by Up and Down.
 | ||||||
|  | func Bottom() { | ||||||
|  | 	if height > 0 { | ||||||
|  | 		Down(height) | ||||||
|  | 		StartOfLine() | ||||||
|  | 		height = 0 | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // StartOfLine moves the cursor to the start of the current line.
 | ||||||
|  | func StartOfLine() { | ||||||
|  | 	HorizontalAbsolute(0) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // StartOfLineDown moves the cursor down by n lines, then moves to cursor to the start of the line.
 | ||||||
|  | func StartOfLineDown(n int) { | ||||||
|  | 	Down(n) | ||||||
|  | 	StartOfLine() | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // StartOfLineUp moves the cursor up by n lines, then moves to cursor to the start of the line.
 | ||||||
|  | func StartOfLineUp(n int) { | ||||||
|  | 	Up(n) | ||||||
|  | 	StartOfLine() | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // UpAndClear moves the cursor up by n lines, then clears the line.
 | ||||||
|  | func UpAndClear(n int) { | ||||||
|  | 	Up(n) | ||||||
|  | 	ClearLine() | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // DownAndClear moves the cursor down by n lines, then clears the line.
 | ||||||
|  | func DownAndClear(n int) { | ||||||
|  | 	Down(n) | ||||||
|  | 	ClearLine() | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Move moves the cursor relative by x and y.
 | ||||||
|  | func Move(x, y int) { | ||||||
|  | 	if x > 0 { | ||||||
|  | 		Right(x) | ||||||
|  | 	} else if x < 0 { | ||||||
|  | 		x *= -1 | ||||||
|  | 		Left(x) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if y > 0 { | ||||||
|  | 		Up(y) | ||||||
|  | 	} else if y < 0 { | ||||||
|  | 		y *= -1 | ||||||
|  | 		Down(y) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ClearLinesUp clears n lines upwards from the current position and moves the cursor.
 | ||||||
|  | func ClearLinesUp(n int) { | ||||||
|  | 	for i := 0; i < n; i++ { | ||||||
|  | 		UpAndClear(1) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ClearLinesDown clears n lines downwards from the current position and moves the cursor.
 | ||||||
|  | func ClearLinesDown(n int) { | ||||||
|  | 	for i := 0; i < n; i++ { | ||||||
|  | 		DownAndClear(1) | ||||||
|  | 	} | ||||||
|  | } | ||||||
							
								
								
									
										21
									
								
								vendor/github.com/cpuguy83/go-md2man/v2/LICENSE.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								vendor/github.com/cpuguy83/go-md2man/v2/LICENSE.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,21 @@ | |||||||
|  | The MIT License (MIT) | ||||||
|  | 
 | ||||||
|  | Copyright (c) 2014 Brian Goff | ||||||
|  | 
 | ||||||
|  | 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. | ||||||
							
								
								
									
										14
									
								
								vendor/github.com/cpuguy83/go-md2man/v2/md2man/md2man.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								vendor/github.com/cpuguy83/go-md2man/v2/md2man/md2man.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,14 @@ | |||||||
|  | package md2man | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"github.com/russross/blackfriday/v2" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // Render converts a markdown document into a roff formatted document.
 | ||||||
|  | func Render(doc []byte) []byte { | ||||||
|  | 	renderer := NewRoffRenderer() | ||||||
|  | 
 | ||||||
|  | 	return blackfriday.Run(doc, | ||||||
|  | 		[]blackfriday.Option{blackfriday.WithRenderer(renderer), | ||||||
|  | 			blackfriday.WithExtensions(renderer.GetExtensions())}...) | ||||||
|  | } | ||||||
							
								
								
									
										345
									
								
								vendor/github.com/cpuguy83/go-md2man/v2/md2man/roff.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										345
									
								
								vendor/github.com/cpuguy83/go-md2man/v2/md2man/roff.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,345 @@ | |||||||
|  | package md2man | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  | 	"io" | ||||||
|  | 	"os" | ||||||
|  | 	"strings" | ||||||
|  | 
 | ||||||
|  | 	"github.com/russross/blackfriday/v2" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // roffRenderer implements the blackfriday.Renderer interface for creating
 | ||||||
|  | // roff format (manpages) from markdown text
 | ||||||
|  | type roffRenderer struct { | ||||||
|  | 	extensions   blackfriday.Extensions | ||||||
|  | 	listCounters []int | ||||||
|  | 	firstHeader  bool | ||||||
|  | 	defineTerm   bool | ||||||
|  | 	listDepth    int | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | const ( | ||||||
|  | 	titleHeader      = ".TH " | ||||||
|  | 	topLevelHeader   = "\n\n.SH " | ||||||
|  | 	secondLevelHdr   = "\n.SH " | ||||||
|  | 	otherHeader      = "\n.SS " | ||||||
|  | 	crTag            = "\n" | ||||||
|  | 	emphTag          = "\\fI" | ||||||
|  | 	emphCloseTag     = "\\fP" | ||||||
|  | 	strongTag        = "\\fB" | ||||||
|  | 	strongCloseTag   = "\\fP" | ||||||
|  | 	breakTag         = "\n.br\n" | ||||||
|  | 	paraTag          = "\n.PP\n" | ||||||
|  | 	hruleTag         = "\n.ti 0\n\\l'\\n(.lu'\n" | ||||||
|  | 	linkTag          = "\n\\[la]" | ||||||
|  | 	linkCloseTag     = "\\[ra]" | ||||||
|  | 	codespanTag      = "\\fB\\fC" | ||||||
|  | 	codespanCloseTag = "\\fR" | ||||||
|  | 	codeTag          = "\n.PP\n.RS\n\n.nf\n" | ||||||
|  | 	codeCloseTag     = "\n.fi\n.RE\n" | ||||||
|  | 	quoteTag         = "\n.PP\n.RS\n" | ||||||
|  | 	quoteCloseTag    = "\n.RE\n" | ||||||
|  | 	listTag          = "\n.RS\n" | ||||||
|  | 	listCloseTag     = "\n.RE\n" | ||||||
|  | 	arglistTag       = "\n.TP\n" | ||||||
|  | 	tableStart       = "\n.TS\nallbox;\n" | ||||||
|  | 	tableEnd         = ".TE\n" | ||||||
|  | 	tableCellStart   = "T{\n" | ||||||
|  | 	tableCellEnd     = "\nT}\n" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // NewRoffRenderer creates a new blackfriday Renderer for generating roff documents
 | ||||||
|  | // from markdown
 | ||||||
|  | func NewRoffRenderer() *roffRenderer { // nolint: golint
 | ||||||
|  | 	var extensions blackfriday.Extensions | ||||||
|  | 
 | ||||||
|  | 	extensions |= blackfriday.NoIntraEmphasis | ||||||
|  | 	extensions |= blackfriday.Tables | ||||||
|  | 	extensions |= blackfriday.FencedCode | ||||||
|  | 	extensions |= blackfriday.SpaceHeadings | ||||||
|  | 	extensions |= blackfriday.Footnotes | ||||||
|  | 	extensions |= blackfriday.Titleblock | ||||||
|  | 	extensions |= blackfriday.DefinitionLists | ||||||
|  | 	return &roffRenderer{ | ||||||
|  | 		extensions: extensions, | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // GetExtensions returns the list of extensions used by this renderer implementation
 | ||||||
|  | func (r *roffRenderer) GetExtensions() blackfriday.Extensions { | ||||||
|  | 	return r.extensions | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // RenderHeader handles outputting the header at document start
 | ||||||
|  | func (r *roffRenderer) RenderHeader(w io.Writer, ast *blackfriday.Node) { | ||||||
|  | 	// disable hyphenation
 | ||||||
|  | 	out(w, ".nh\n") | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // RenderFooter handles outputting the footer at the document end; the roff
 | ||||||
|  | // renderer has no footer information
 | ||||||
|  | func (r *roffRenderer) RenderFooter(w io.Writer, ast *blackfriday.Node) { | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // RenderNode is called for each node in a markdown document; based on the node
 | ||||||
|  | // type the equivalent roff output is sent to the writer
 | ||||||
|  | func (r *roffRenderer) RenderNode(w io.Writer, node *blackfriday.Node, entering bool) blackfriday.WalkStatus { | ||||||
|  | 
 | ||||||
|  | 	var walkAction = blackfriday.GoToNext | ||||||
|  | 
 | ||||||
|  | 	switch node.Type { | ||||||
|  | 	case blackfriday.Text: | ||||||
|  | 		r.handleText(w, node, entering) | ||||||
|  | 	case blackfriday.Softbreak: | ||||||
|  | 		out(w, crTag) | ||||||
|  | 	case blackfriday.Hardbreak: | ||||||
|  | 		out(w, breakTag) | ||||||
|  | 	case blackfriday.Emph: | ||||||
|  | 		if entering { | ||||||
|  | 			out(w, emphTag) | ||||||
|  | 		} else { | ||||||
|  | 			out(w, emphCloseTag) | ||||||
|  | 		} | ||||||
|  | 	case blackfriday.Strong: | ||||||
|  | 		if entering { | ||||||
|  | 			out(w, strongTag) | ||||||
|  | 		} else { | ||||||
|  | 			out(w, strongCloseTag) | ||||||
|  | 		} | ||||||
|  | 	case blackfriday.Link: | ||||||
|  | 		if !entering { | ||||||
|  | 			out(w, linkTag+string(node.LinkData.Destination)+linkCloseTag) | ||||||
|  | 		} | ||||||
|  | 	case blackfriday.Image: | ||||||
|  | 		// ignore images
 | ||||||
|  | 		walkAction = blackfriday.SkipChildren | ||||||
|  | 	case blackfriday.Code: | ||||||
|  | 		out(w, codespanTag) | ||||||
|  | 		escapeSpecialChars(w, node.Literal) | ||||||
|  | 		out(w, codespanCloseTag) | ||||||
|  | 	case blackfriday.Document: | ||||||
|  | 		break | ||||||
|  | 	case blackfriday.Paragraph: | ||||||
|  | 		// roff .PP markers break lists
 | ||||||
|  | 		if r.listDepth > 0 { | ||||||
|  | 			return blackfriday.GoToNext | ||||||
|  | 		} | ||||||
|  | 		if entering { | ||||||
|  | 			out(w, paraTag) | ||||||
|  | 		} else { | ||||||
|  | 			out(w, crTag) | ||||||
|  | 		} | ||||||
|  | 	case blackfriday.BlockQuote: | ||||||
|  | 		if entering { | ||||||
|  | 			out(w, quoteTag) | ||||||
|  | 		} else { | ||||||
|  | 			out(w, quoteCloseTag) | ||||||
|  | 		} | ||||||
|  | 	case blackfriday.Heading: | ||||||
|  | 		r.handleHeading(w, node, entering) | ||||||
|  | 	case blackfriday.HorizontalRule: | ||||||
|  | 		out(w, hruleTag) | ||||||
|  | 	case blackfriday.List: | ||||||
|  | 		r.handleList(w, node, entering) | ||||||
|  | 	case blackfriday.Item: | ||||||
|  | 		r.handleItem(w, node, entering) | ||||||
|  | 	case blackfriday.CodeBlock: | ||||||
|  | 		out(w, codeTag) | ||||||
|  | 		escapeSpecialChars(w, node.Literal) | ||||||
|  | 		out(w, codeCloseTag) | ||||||
|  | 	case blackfriday.Table: | ||||||
|  | 		r.handleTable(w, node, entering) | ||||||
|  | 	case blackfriday.TableCell: | ||||||
|  | 		r.handleTableCell(w, node, entering) | ||||||
|  | 	case blackfriday.TableHead: | ||||||
|  | 	case blackfriday.TableBody: | ||||||
|  | 	case blackfriday.TableRow: | ||||||
|  | 		// no action as cell entries do all the nroff formatting
 | ||||||
|  | 		return blackfriday.GoToNext | ||||||
|  | 	default: | ||||||
|  | 		fmt.Fprintln(os.Stderr, "WARNING: go-md2man does not handle node type "+node.Type.String()) | ||||||
|  | 	} | ||||||
|  | 	return walkAction | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (r *roffRenderer) handleText(w io.Writer, node *blackfriday.Node, entering bool) { | ||||||
|  | 	var ( | ||||||
|  | 		start, end string | ||||||
|  | 	) | ||||||
|  | 	// handle special roff table cell text encapsulation
 | ||||||
|  | 	if node.Parent.Type == blackfriday.TableCell { | ||||||
|  | 		if len(node.Literal) > 30 { | ||||||
|  | 			start = tableCellStart | ||||||
|  | 			end = tableCellEnd | ||||||
|  | 		} else { | ||||||
|  | 			// end rows that aren't terminated by "tableCellEnd" with a cr if end of row
 | ||||||
|  | 			if node.Parent.Next == nil && !node.Parent.IsHeader { | ||||||
|  | 				end = crTag | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	out(w, start) | ||||||
|  | 	escapeSpecialChars(w, node.Literal) | ||||||
|  | 	out(w, end) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (r *roffRenderer) handleHeading(w io.Writer, node *blackfriday.Node, entering bool) { | ||||||
|  | 	if entering { | ||||||
|  | 		switch node.Level { | ||||||
|  | 		case 1: | ||||||
|  | 			if !r.firstHeader { | ||||||
|  | 				out(w, titleHeader) | ||||||
|  | 				r.firstHeader = true | ||||||
|  | 				break | ||||||
|  | 			} | ||||||
|  | 			out(w, topLevelHeader) | ||||||
|  | 		case 2: | ||||||
|  | 			out(w, secondLevelHdr) | ||||||
|  | 		default: | ||||||
|  | 			out(w, otherHeader) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (r *roffRenderer) handleList(w io.Writer, node *blackfriday.Node, entering bool) { | ||||||
|  | 	openTag := listTag | ||||||
|  | 	closeTag := listCloseTag | ||||||
|  | 	if node.ListFlags&blackfriday.ListTypeDefinition != 0 { | ||||||
|  | 		// tags for definition lists handled within Item node
 | ||||||
|  | 		openTag = "" | ||||||
|  | 		closeTag = "" | ||||||
|  | 	} | ||||||
|  | 	if entering { | ||||||
|  | 		r.listDepth++ | ||||||
|  | 		if node.ListFlags&blackfriday.ListTypeOrdered != 0 { | ||||||
|  | 			r.listCounters = append(r.listCounters, 1) | ||||||
|  | 		} | ||||||
|  | 		out(w, openTag) | ||||||
|  | 	} else { | ||||||
|  | 		if node.ListFlags&blackfriday.ListTypeOrdered != 0 { | ||||||
|  | 			r.listCounters = r.listCounters[:len(r.listCounters)-1] | ||||||
|  | 		} | ||||||
|  | 		out(w, closeTag) | ||||||
|  | 		r.listDepth-- | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (r *roffRenderer) handleItem(w io.Writer, node *blackfriday.Node, entering bool) { | ||||||
|  | 	if entering { | ||||||
|  | 		if node.ListFlags&blackfriday.ListTypeOrdered != 0 { | ||||||
|  | 			out(w, fmt.Sprintf(".IP \"%3d.\" 5\n", r.listCounters[len(r.listCounters)-1])) | ||||||
|  | 			r.listCounters[len(r.listCounters)-1]++ | ||||||
|  | 		} else if node.ListFlags&blackfriday.ListTypeDefinition != 0 { | ||||||
|  | 			// state machine for handling terms and following definitions
 | ||||||
|  | 			// since blackfriday does not distinguish them properly, nor
 | ||||||
|  | 			// does it seperate them into separate lists as it should
 | ||||||
|  | 			if !r.defineTerm { | ||||||
|  | 				out(w, arglistTag) | ||||||
|  | 				r.defineTerm = true | ||||||
|  | 			} else { | ||||||
|  | 				r.defineTerm = false | ||||||
|  | 			} | ||||||
|  | 		} else { | ||||||
|  | 			out(w, ".IP \\(bu 2\n") | ||||||
|  | 		} | ||||||
|  | 	} else { | ||||||
|  | 		out(w, "\n") | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (r *roffRenderer) handleTable(w io.Writer, node *blackfriday.Node, entering bool) { | ||||||
|  | 	if entering { | ||||||
|  | 		out(w, tableStart) | ||||||
|  | 		//call walker to count cells (and rows?) so format section can be produced
 | ||||||
|  | 		columns := countColumns(node) | ||||||
|  | 		out(w, strings.Repeat("l ", columns)+"\n") | ||||||
|  | 		out(w, strings.Repeat("l ", columns)+".\n") | ||||||
|  | 	} else { | ||||||
|  | 		out(w, tableEnd) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (r *roffRenderer) handleTableCell(w io.Writer, node *blackfriday.Node, entering bool) { | ||||||
|  | 	var ( | ||||||
|  | 		start, end string | ||||||
|  | 	) | ||||||
|  | 	if node.IsHeader { | ||||||
|  | 		start = codespanTag | ||||||
|  | 		end = codespanCloseTag | ||||||
|  | 	} | ||||||
|  | 	if entering { | ||||||
|  | 		if node.Prev != nil && node.Prev.Type == blackfriday.TableCell { | ||||||
|  | 			out(w, "\t"+start) | ||||||
|  | 		} else { | ||||||
|  | 			out(w, start) | ||||||
|  | 		} | ||||||
|  | 	} else { | ||||||
|  | 		// need to carriage return if we are at the end of the header row
 | ||||||
|  | 		if node.IsHeader && node.Next == nil { | ||||||
|  | 			end = end + crTag | ||||||
|  | 		} | ||||||
|  | 		out(w, end) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // because roff format requires knowing the column count before outputting any table
 | ||||||
|  | // data we need to walk a table tree and count the columns
 | ||||||
|  | func countColumns(node *blackfriday.Node) int { | ||||||
|  | 	var columns int | ||||||
|  | 
 | ||||||
|  | 	node.Walk(func(node *blackfriday.Node, entering bool) blackfriday.WalkStatus { | ||||||
|  | 		switch node.Type { | ||||||
|  | 		case blackfriday.TableRow: | ||||||
|  | 			if !entering { | ||||||
|  | 				return blackfriday.Terminate | ||||||
|  | 			} | ||||||
|  | 		case blackfriday.TableCell: | ||||||
|  | 			if entering { | ||||||
|  | 				columns++ | ||||||
|  | 			} | ||||||
|  | 		default: | ||||||
|  | 		} | ||||||
|  | 		return blackfriday.GoToNext | ||||||
|  | 	}) | ||||||
|  | 	return columns | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func out(w io.Writer, output string) { | ||||||
|  | 	io.WriteString(w, output) // nolint: errcheck
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func needsBackslash(c byte) bool { | ||||||
|  | 	for _, r := range []byte("-_&\\~") { | ||||||
|  | 		if c == r { | ||||||
|  | 			return true | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return false | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func escapeSpecialChars(w io.Writer, text []byte) { | ||||||
|  | 	for i := 0; i < len(text); i++ { | ||||||
|  | 		// escape initial apostrophe or period
 | ||||||
|  | 		if len(text) >= 1 && (text[0] == '\'' || text[0] == '.') { | ||||||
|  | 			out(w, "\\&") | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		// directly copy normal characters
 | ||||||
|  | 		org := i | ||||||
|  | 
 | ||||||
|  | 		for i < len(text) && !needsBackslash(text[i]) { | ||||||
|  | 			i++ | ||||||
|  | 		} | ||||||
|  | 		if i > org { | ||||||
|  | 			w.Write(text[org:i]) // nolint: errcheck
 | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		// escape a character
 | ||||||
|  | 		if i >= len(text) { | ||||||
|  | 			break | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		w.Write([]byte{'\\', text[i]}) // nolint: errcheck
 | ||||||
|  | 	} | ||||||
|  | } | ||||||
							
								
								
									
										20
									
								
								vendor/github.com/gookit/color/.gitignore
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								vendor/github.com/gookit/color/.gitignore
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,20 @@ | |||||||
|  | *.log | ||||||
|  | *.swp | ||||||
|  | .idea | ||||||
|  | *.patch | ||||||
|  | ### Go template | ||||||
|  | # Binaries for programs and plugins | ||||||
|  | *.exe | ||||||
|  | *.exe~ | ||||||
|  | *.dll | ||||||
|  | *.so | ||||||
|  | *.dylib | ||||||
|  | 
 | ||||||
|  | # Test binary, build with `go test -c` | ||||||
|  | *.test | ||||||
|  | 
 | ||||||
|  | # Output of the go coverage tool, specifically when used with LiteIDE | ||||||
|  | *.out | ||||||
|  | .DS_Store | ||||||
|  | app | ||||||
|  | demo | ||||||
							
								
								
									
										20
									
								
								vendor/github.com/gookit/color/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								vendor/github.com/gookit/color/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,20 @@ | |||||||
|  | The MIT License (MIT) | ||||||
|  | 
 | ||||||
|  | Copyright (c) 2016 inhere | ||||||
|  | 
 | ||||||
|  | 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. | ||||||
							
								
								
									
										468
									
								
								vendor/github.com/gookit/color/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										468
									
								
								vendor/github.com/gookit/color/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,468 @@ | |||||||
|  | # CLI Color | ||||||
|  | 
 | ||||||
|  |  | ||||||
|  | [](https://github.com/gookit/color/actions) | ||||||
|  | [](https://app.codacy.com/app/inhere/color) | ||||||
|  | [](https://pkg.go.dev/github.com/gookit/color?tab=overview) | ||||||
|  | [](https://github.com/gookit/color) | ||||||
|  | [](https://travis-ci.org/gookit/color) | ||||||
|  | [](https://coveralls.io/github/gookit/color?branch=master) | ||||||
|  | [](https://goreportcard.com/report/github.com/gookit/color) | ||||||
|  | 
 | ||||||
|  | A command-line color library with true color support, universal API methods and Windows support. | ||||||
|  | 
 | ||||||
|  | > **[中文说明](README.zh-CN.md)** | ||||||
|  | 
 | ||||||
|  | Basic color preview: | ||||||
|  | 
 | ||||||
|  |  | ||||||
|  | 
 | ||||||
|  | Now, 256 colors and RGB colors have also been supported to work in Windows CMD and PowerShell: | ||||||
|  | 
 | ||||||
|  |  | ||||||
|  | 
 | ||||||
|  | ## Features | ||||||
|  | 
 | ||||||
|  |   - Simple to use, zero dependencies | ||||||
|  |   - Supports rich color output: 16-color (4-bit), 256-color (8-bit), true color (24-bit, RGB) | ||||||
|  |     - 16-color output is the most commonly used and most widely supported, working on any Windows version | ||||||
|  |     - Since `v1.2.4` **the 256-color (8-bit), true color (24-bit) support windows CMD and PowerShell** | ||||||
|  |     - See [this gist](https://gist.github.com/XVilka/8346728) for information on true color support | ||||||
|  |   - Generic API methods: `Print`, `Printf`, `Println`, `Sprint`, `Sprintf` | ||||||
|  |   - Supports HTML tag-style color rendering, such as `<green>message</>`. | ||||||
|  |     - In addition to using built-in tags, it also supports custom color attributes | ||||||
|  |     - Custom color attributes support the use of 16 color names, 256 color values, rgb color values and hex color values | ||||||
|  |     - Support working on Windows `cmd` and `powerShell` terminal | ||||||
|  |   - Basic colors: `Bold`, `Black`, `White`, `Gray`, `Red`, `Green`, `Yellow`, `Blue`, `Magenta`, `Cyan` | ||||||
|  |   - Additional styles: `Info`, `Note`, `Light`, `Error`, `Danger`, `Notice`, `Success`, `Comment`, `Primary`, `Warning`, `Question`, `Secondary` | ||||||
|  |   - Support by set `NO_COLOR` for disable color or use `FORCE_COLOR` for force open color render. | ||||||
|  |   - Support Rgb, 256, 16 color conversion | ||||||
|  | 
 | ||||||
|  | ## GoDoc | ||||||
|  | 
 | ||||||
|  |   - [godoc for gopkg](https://pkg.go.dev/gopkg.in/gookit/color.v1) | ||||||
|  |   - [godoc for github](https://pkg.go.dev/github.com/gookit/color) | ||||||
|  | 
 | ||||||
|  | ## Install | ||||||
|  | 
 | ||||||
|  | ```bash | ||||||
|  | go get github.com/gookit/color | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ## Quick start | ||||||
|  | 
 | ||||||
|  | ```go | ||||||
|  | package main | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  | 
 | ||||||
|  | 	"github.com/gookit/color" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | func main() { | ||||||
|  | 	// quick use package func | ||||||
|  | 	color.Redp("Simple to use color") | ||||||
|  | 	color.Redln("Simple to use color") | ||||||
|  | 	color.Greenp("Simple to use color\n") | ||||||
|  | 	color.Cyanln("Simple to use color") | ||||||
|  | 	color.Yellowln("Simple to use color") | ||||||
|  | 
 | ||||||
|  | 	// quick use like fmt.Print* | ||||||
|  | 	color.Red.Println("Simple to use color") | ||||||
|  | 	color.Green.Print("Simple to use color\n") | ||||||
|  | 	color.Cyan.Printf("Simple to use %s\n", "color") | ||||||
|  | 	color.Yellow.Printf("Simple to use %s\n", "color") | ||||||
|  | 
 | ||||||
|  | 	// use like func | ||||||
|  | 	red := color.FgRed.Render | ||||||
|  | 	green := color.FgGreen.Render | ||||||
|  | 	fmt.Printf("%s line %s library\n", red("Command"), green("color")) | ||||||
|  | 
 | ||||||
|  | 	// custom color | ||||||
|  | 	color.New(color.FgWhite, color.BgBlack).Println("custom color style") | ||||||
|  | 
 | ||||||
|  | 	// can also: | ||||||
|  | 	color.Style{color.FgCyan, color.OpBold}.Println("custom color style") | ||||||
|  | 
 | ||||||
|  | 	// internal theme/style: | ||||||
|  | 	color.Info.Tips("message") | ||||||
|  | 	color.Info.Prompt("message") | ||||||
|  | 	color.Info.Println("message") | ||||||
|  | 	color.Warn.Println("message") | ||||||
|  | 	color.Error.Println("message") | ||||||
|  | 
 | ||||||
|  | 	// use style tag | ||||||
|  | 	color.Print("<suc>he</><comment>llo</>, <cyan>wel</><red>come</>\n") | ||||||
|  | 	// Custom label attr: Supports the use of 16 color names, 256 color values, rgb color values and hex color values | ||||||
|  | 	color.Println("<fg=11aa23>he</><bg=120,35,156>llo</>, <fg=167;bg=232>wel</><fg=red>come</>") | ||||||
|  | 
 | ||||||
|  | 	// apply a style tag | ||||||
|  | 	color.Tag("info").Println("info style text") | ||||||
|  | 
 | ||||||
|  | 	// prompt message | ||||||
|  | 	color.Info.Prompt("prompt style message") | ||||||
|  | 	color.Warn.Prompt("prompt style message") | ||||||
|  | 
 | ||||||
|  | 	// tips message | ||||||
|  | 	color.Info.Tips("tips style message") | ||||||
|  | 	color.Warn.Tips("tips style message") | ||||||
|  | } | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | Run demo: `go run ./_examples/demo.go` | ||||||
|  | 
 | ||||||
|  |  | ||||||
|  | 
 | ||||||
|  | ## Basic/16 color | ||||||
|  | 
 | ||||||
|  | Supported on any Windows version. Provide generic API methods: `Print`, `Printf`, `Println`, `Sprint`, `Sprintf` | ||||||
|  | 
 | ||||||
|  | ```go | ||||||
|  | color.Bold.Println("bold message") | ||||||
|  | color.Black.Println("bold message") | ||||||
|  | color.White.Println("bold message") | ||||||
|  | color.Gray.Println("bold message") | ||||||
|  | color.Red.Println("yellow message") | ||||||
|  | color.Blue.Println("yellow message") | ||||||
|  | color.Cyan.Println("yellow message") | ||||||
|  | color.Yellow.Println("yellow message") | ||||||
|  | color.Magenta.Println("yellow message") | ||||||
|  | 
 | ||||||
|  | // Only use foreground color | ||||||
|  | color.FgCyan.Printf("Simple to use %s\n", "color") | ||||||
|  | // Only use background color | ||||||
|  | color.BgRed.Printf("Simple to use %s\n", "color") | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | Run demo: `go run ./_examples/color_16.go` | ||||||
|  | 
 | ||||||
|  |  | ||||||
|  | 
 | ||||||
|  | ### Custom build color | ||||||
|  | 
 | ||||||
|  | ```go | ||||||
|  | // Full custom: foreground, background, option | ||||||
|  | myStyle := color.New(color.FgWhite, color.BgBlack, color.OpBold) | ||||||
|  | myStyle.Println("custom color style") | ||||||
|  | 
 | ||||||
|  | // can also: | ||||||
|  | color.Style{color.FgCyan, color.OpBold}.Println("custom color style") | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | custom set console settings: | ||||||
|  | 
 | ||||||
|  | ```go | ||||||
|  | // set console color | ||||||
|  | color.Set(color.FgCyan) | ||||||
|  | 
 | ||||||
|  | // print message | ||||||
|  | fmt.Print("message") | ||||||
|  | 
 | ||||||
|  | // reset console settings | ||||||
|  | color.Reset() | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ### Additional styles | ||||||
|  | 
 | ||||||
|  | provide generic API methods: `Print`, `Printf`, `Println`, `Sprint`, `Sprintf` | ||||||
|  | 
 | ||||||
|  | print message use defined style: | ||||||
|  | 
 | ||||||
|  | ```go | ||||||
|  | color.Info.Println("Info message") | ||||||
|  | color.Note.Println("Note message") | ||||||
|  | color.Notice.Println("Notice message") | ||||||
|  | color.Error.Println("Error message") | ||||||
|  | color.Danger.Println("Danger message") | ||||||
|  | color.Warn.Println("Warn message") | ||||||
|  | color.Debug.Println("Debug message") | ||||||
|  | color.Primary.Println("Primary message") | ||||||
|  | color.Question.Println("Question message") | ||||||
|  | color.Secondary.Println("Secondary message") | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | Run demo: `go run ./_examples/theme_basic.go` | ||||||
|  | 
 | ||||||
|  |  | ||||||
|  | 
 | ||||||
|  | **Tips style** | ||||||
|  | 
 | ||||||
|  | ```go | ||||||
|  | color.Info.Tips("Info tips message") | ||||||
|  | color.Note.Tips("Note tips message") | ||||||
|  | color.Notice.Tips("Notice tips message") | ||||||
|  | color.Error.Tips("Error tips message") | ||||||
|  | color.Danger.Tips("Danger tips message") | ||||||
|  | color.Warn.Tips("Warn tips message") | ||||||
|  | color.Debug.Tips("Debug tips message") | ||||||
|  | color.Primary.Tips("Primary tips message") | ||||||
|  | color.Question.Tips("Question tips message") | ||||||
|  | color.Secondary.Tips("Secondary tips message") | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | Run demo: `go run ./_examples/theme_tips.go` | ||||||
|  | 
 | ||||||
|  |  | ||||||
|  | 
 | ||||||
|  | **Prompt Style** | ||||||
|  | 
 | ||||||
|  | ```go | ||||||
|  | color.Info.Prompt("Info prompt message") | ||||||
|  | color.Note.Prompt("Note prompt message") | ||||||
|  | color.Notice.Prompt("Notice prompt message") | ||||||
|  | color.Error.Prompt("Error prompt message") | ||||||
|  | color.Danger.Prompt("Danger prompt message") | ||||||
|  | color.Warn.Prompt("Warn prompt message") | ||||||
|  | color.Debug.Prompt("Debug prompt message") | ||||||
|  | color.Primary.Prompt("Primary prompt message") | ||||||
|  | color.Question.Prompt("Question prompt message") | ||||||
|  | color.Secondary.Prompt("Secondary prompt message") | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | Run demo: `go run ./_examples/theme_prompt.go` | ||||||
|  | 
 | ||||||
|  |  | ||||||
|  | 
 | ||||||
|  | **Block Style** | ||||||
|  | 
 | ||||||
|  | ```go | ||||||
|  | color.Info.Block("Info block message") | ||||||
|  | color.Note.Block("Note block message") | ||||||
|  | color.Notice.Block("Notice block message") | ||||||
|  | color.Error.Block("Error block message") | ||||||
|  | color.Danger.Block("Danger block message") | ||||||
|  | color.Warn.Block("Warn block message") | ||||||
|  | color.Debug.Block("Debug block message") | ||||||
|  | color.Primary.Block("Primary block message") | ||||||
|  | color.Question.Block("Question block message") | ||||||
|  | color.Secondary.Block("Secondary block message") | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | Run demo: `go run ./_examples/theme_block.go` | ||||||
|  | 
 | ||||||
|  |  | ||||||
|  | 
 | ||||||
|  | ## 256-color usage | ||||||
|  | 
 | ||||||
|  | > 256 colors support Windows CMD, PowerShell environment after `v1.2.4` | ||||||
|  | 
 | ||||||
|  | ### Set the foreground or background color | ||||||
|  | 
 | ||||||
|  | - `color.C256(val uint8, isBg ...bool) Color256` | ||||||
|  | 
 | ||||||
|  | ```go | ||||||
|  | c := color.C256(132) // fg color | ||||||
|  | c.Println("message") | ||||||
|  | c.Printf("format %s", "message") | ||||||
|  | 
 | ||||||
|  | c := color.C256(132, true) // bg color | ||||||
|  | c.Println("message") | ||||||
|  | c.Printf("format %s", "message") | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ### 256-color style | ||||||
|  | 
 | ||||||
|  | Can be used to set foreground and background colors at the same time. | ||||||
|  | 
 | ||||||
|  | - `S256(fgAndBg ...uint8) *Style256` | ||||||
|  | 
 | ||||||
|  | ```go | ||||||
|  | s := color.S256(32, 203) | ||||||
|  | s.Println("message") | ||||||
|  | s.Printf("format %s", "message") | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | with options: | ||||||
|  | 
 | ||||||
|  | ```go | ||||||
|  | s := color.S256(32, 203) | ||||||
|  | s.SetOpts(color.Opts{color.OpBold}) | ||||||
|  | 
 | ||||||
|  | s.Println("style with options") | ||||||
|  | s.Printf("style with %s\n", "options") | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | Run demo: `go run ./_examples/color_256.go` | ||||||
|  | 
 | ||||||
|  |  | ||||||
|  | 
 | ||||||
|  | ## RGB/True color | ||||||
|  | 
 | ||||||
|  | > RGB colors support Windows `CMD`, `PowerShell` environment after `v1.2.4` | ||||||
|  | 
 | ||||||
|  | **Preview:** | ||||||
|  | 
 | ||||||
|  | > Run demo: `Run demo: go run ./_examples/color_rgb.go` | ||||||
|  | 
 | ||||||
|  |  | ||||||
|  | 
 | ||||||
|  | example: | ||||||
|  | 
 | ||||||
|  | ```go | ||||||
|  | color.RGB(30, 144, 255).Println("message. use RGB number") | ||||||
|  | 
 | ||||||
|  | color.HEX("#1976D2").Println("blue-darken") | ||||||
|  | color.HEX("#D50000", true).Println("red-accent. use HEX style") | ||||||
|  | 
 | ||||||
|  | color.RGBStyleFromString("213,0,0").Println("red-accent. use RGB number") | ||||||
|  | color.HEXStyle("eee", "D50000").Println("deep-purple color") | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ### Set the foreground or background color | ||||||
|  | 
 | ||||||
|  | - `color.RGB(r, g, b uint8, isBg ...bool) RGBColor` | ||||||
|  | 
 | ||||||
|  | ```go | ||||||
|  | c := color.RGB(30,144,255) // fg color | ||||||
|  | c.Println("message") | ||||||
|  | c.Printf("format %s", "message") | ||||||
|  | 
 | ||||||
|  | c := color.RGB(30,144,255, true) // bg color | ||||||
|  | c.Println("message") | ||||||
|  | c.Printf("format %s", "message") | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | Create a style from an hexadecimal color string: | ||||||
|  | 
 | ||||||
|  | - `color.HEX(hex string, isBg ...bool) RGBColor` | ||||||
|  | 
 | ||||||
|  | ```go | ||||||
|  | c := color.HEX("ccc") // can also: "cccccc" "#cccccc" | ||||||
|  | c.Println("message") | ||||||
|  | c.Printf("format %s", "message") | ||||||
|  | 
 | ||||||
|  | c = color.HEX("aabbcc", true) // as bg color | ||||||
|  | c.Println("message") | ||||||
|  | c.Printf("format %s", "message") | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ### RGB color style | ||||||
|  | 
 | ||||||
|  | Can be used to set the foreground and background colors at the same time. | ||||||
|  | 
 | ||||||
|  | - `color.NewRGBStyle(fg RGBColor, bg ...RGBColor) *RGBStyle` | ||||||
|  | 
 | ||||||
|  | ```go | ||||||
|  | s := color.NewRGBStyle(RGB(20, 144, 234), RGB(234, 78, 23)) | ||||||
|  | s.Println("message") | ||||||
|  | s.Printf("format %s", "message") | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | Create a style from an hexadecimal color string: | ||||||
|  | 
 | ||||||
|  | - `color.HEXStyle(fg string, bg ...string) *RGBStyle` | ||||||
|  | 
 | ||||||
|  | ```go | ||||||
|  | s := color.HEXStyle("11aa23", "eee") | ||||||
|  | s.Println("message") | ||||||
|  | s.Printf("format %s", "message") | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | with options: | ||||||
|  | 
 | ||||||
|  | ```go | ||||||
|  | s := color.HEXStyle("11aa23", "eee") | ||||||
|  | s.SetOpts(color.Opts{color.OpBold}) | ||||||
|  | 
 | ||||||
|  | s.Println("style with options") | ||||||
|  | s.Printf("style with %s\n", "options") | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ## HTML-like tag usage | ||||||
|  | 
 | ||||||
|  | **Supported** on Windows `cmd.exe` `PowerShell` . | ||||||
|  | 
 | ||||||
|  | ```go | ||||||
|  | // use style tag | ||||||
|  | color.Print("<suc>he</><comment>llo</>, <cyan>wel</><red>come</>") | ||||||
|  | color.Println("<suc>hello</>") | ||||||
|  | color.Println("<error>hello</>") | ||||||
|  | color.Println("<warning>hello</>") | ||||||
|  | 
 | ||||||
|  | // custom color attributes | ||||||
|  | color.Print("<fg=yellow;bg=black;op=underscore;>hello, welcome</>\n") | ||||||
|  | 
 | ||||||
|  | // Custom label attr: Supports the use of 16 color names, 256 color values, rgb color values and hex color values | ||||||
|  | color.Println("<fg=11aa23>he</><bg=120,35,156>llo</>, <fg=167;bg=232>wel</><fg=red>come</>") | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | - `color.Tag` | ||||||
|  | 
 | ||||||
|  | ```go | ||||||
|  | // set a style tag | ||||||
|  | color.Tag("info").Print("info style text") | ||||||
|  | color.Tag("info").Printf("%s style text", "info") | ||||||
|  | color.Tag("info").Println("info style text") | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | Run demo: `go run ./_examples/color_tag.go` | ||||||
|  | 
 | ||||||
|  |  | ||||||
|  | 
 | ||||||
|  | ## Color convert | ||||||
|  | 
 | ||||||
|  | Supports conversion between Rgb, 256, 16 colors, `Rgb <=> 256 <=> 16` | ||||||
|  | 
 | ||||||
|  | ```go | ||||||
|  | basic := color.Red | ||||||
|  | basic.Println("basic color") | ||||||
|  | 
 | ||||||
|  | c256 := color.Red.C256() | ||||||
|  | c256.Println("256 color") | ||||||
|  | c256.C16().Println("basic color") | ||||||
|  | 
 | ||||||
|  | rgb := color.Red.RGB() | ||||||
|  | rgb.Println("rgb color") | ||||||
|  | rgb.C256().Println("256 color") | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ## Func refer | ||||||
|  | 
 | ||||||
|  | There are some useful functions reference | ||||||
|  | 
 | ||||||
|  | - `Disable()` disable color render | ||||||
|  | - `SetOutput(io.Writer)` custom set the colored text output writer | ||||||
|  | - `ForceOpenColor()` force open color render | ||||||
|  | - `Colors2code(colors ...Color) string` Convert colors to code. return like "32;45;3" | ||||||
|  | - `ClearCode(str string) string` Use for clear color codes | ||||||
|  | - `ClearTag(s string) string` clear all color html-tag for a string | ||||||
|  | - `IsConsole(w io.Writer)` Determine whether w is one of stderr, stdout, stdin | ||||||
|  | - `HexToRgb(hex string) (rgb []int)` Convert hex color string to RGB numbers | ||||||
|  | - `RgbToHex(rgb []int) string` Convert RGB to hex code | ||||||
|  | - More useful func please see https://pkg.go.dev/github.com/gookit/color | ||||||
|  | 
 | ||||||
|  | ## Project use | ||||||
|  | 
 | ||||||
|  | Check out these projects, which use https://github.com/gookit/color : | ||||||
|  | 
 | ||||||
|  | - https://github.com/Delta456/box-cli-maker Make Highly Customized Boxes for your CLI | ||||||
|  | 
 | ||||||
|  | ## Gookit packages | ||||||
|  | 
 | ||||||
|  |   - [gookit/ini](https://github.com/gookit/ini) Go config management, use INI files | ||||||
|  |   - [gookit/rux](https://github.com/gookit/rux) Simple and fast request router for golang HTTP  | ||||||
|  |   - [gookit/gcli](https://github.com/gookit/gcli) build CLI application, tool library, running CLI commands | ||||||
|  |   - [gookit/slog](https://github.com/gookit/slog) Concise and extensible go log library | ||||||
|  |   - [gookit/event](https://github.com/gookit/event) Lightweight event manager and dispatcher implements by Go | ||||||
|  |   - [gookit/cache](https://github.com/gookit/cache) Generic cache use and cache manager for golang. support File, Memory, Redis, Memcached. | ||||||
|  |   - [gookit/config](https://github.com/gookit/config) Go config management. support JSON, YAML, TOML, INI, HCL, ENV and Flags | ||||||
|  |   - [gookit/color](https://github.com/gookit/color) A command-line color library with true color support, universal API methods and Windows support | ||||||
|  |   - [gookit/filter](https://github.com/gookit/filter) Provide filtering, sanitizing, and conversion of golang data | ||||||
|  |   - [gookit/validate](https://github.com/gookit/validate) Use for data validation and filtering. support Map, Struct, Form data | ||||||
|  |   - [gookit/goutil](https://github.com/gookit/goutil) Some utils for the Go: string, array/slice, map, format, cli, env, filesystem, test and more | ||||||
|  |   - More, please see https://github.com/gookit | ||||||
|  | 
 | ||||||
|  | ## See also | ||||||
|  | 
 | ||||||
|  |   - [inhere/console](https://github.com/inhere/php-console) | ||||||
|  |   - [xo/terminfo](https://github.com/xo/terminfo) | ||||||
|  |   - [beego/bee](https://github.com/beego/bee) | ||||||
|  |   - [issue9/term](https://github.com/issue9/term) | ||||||
|  |   - [ANSI escape code](https://en.wikipedia.org/wiki/ANSI_escape_code) | ||||||
|  |   - [Standard ANSI color map](https://conemu.github.io/en/AnsiEscapeCodes.html#Standard_ANSI_color_map) | ||||||
|  |   - [Terminal Colors](https://gist.github.com/XVilka/8346728) | ||||||
|  | 
 | ||||||
|  | ## License | ||||||
|  | 
 | ||||||
|  | [MIT](/LICENSE) | ||||||
							
								
								
									
										472
									
								
								vendor/github.com/gookit/color/README.zh-CN.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										472
									
								
								vendor/github.com/gookit/color/README.zh-CN.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,472 @@ | |||||||
|  | # CLI Color | ||||||
|  | 
 | ||||||
|  |  | ||||||
|  | [](https://github.com/gookit/color/actions) | ||||||
|  | [](https://app.codacy.com/app/inhere/color) | ||||||
|  | [](https://pkg.go.dev/github.com/gookit/color?tab=overview) | ||||||
|  | [](https://github.com/gookit/color) | ||||||
|  | [](https://travis-ci.org/gookit/color) | ||||||
|  | [](https://coveralls.io/github/gookit/color?branch=master) | ||||||
|  | [](https://goreportcard.com/report/github.com/gookit/color) | ||||||
|  | 
 | ||||||
|  | Golang下的命令行色彩使用库, 拥有丰富的色彩渲染输出,通用的API方法,兼容Windows系统 | ||||||
|  | 
 | ||||||
|  | > **[EN README](README.md)** | ||||||
|  | 
 | ||||||
|  | 基本颜色预览: | ||||||
|  | 
 | ||||||
|  |  | ||||||
|  | 
 | ||||||
|  | 现在,256色和RGB色彩也已经支持windows CMD和PowerShell中工作: | ||||||
|  | 
 | ||||||
|  |  | ||||||
|  | 
 | ||||||
|  | ## 功能特色 | ||||||
|  | 
 | ||||||
|  |   - 使用简单方便 | ||||||
|  |   - 支持丰富的颜色输出, 16色(4bit),256色(8bit),RGB色彩(24bit, RGB) | ||||||
|  |     - 16色(4bit)是最常用和支持最广的,支持Windows `cmd.exe` | ||||||
|  |     - 自 `v1.2.4` 起 **256色(8bit),RGB色彩(24bit)均支持Windows CMD和PowerShell终端** | ||||||
|  |     - 请查看 [this gist](https://gist.github.com/XVilka/8346728) 了解支持RGB色彩的终端 | ||||||
|  |   - 提供通用的API方法:`Print` `Printf` `Println` `Sprint` `Sprintf` | ||||||
|  |   - 同时支持html标签式的颜色渲染,除了使用内置标签,同时支持自定义颜色属性 | ||||||
|  |     - 例如: `this an <green>message</>` 标签内部的文本将会渲染为绿色字体 | ||||||
|  |     - 自定义颜色属性: 支持使用16色彩名称,256色彩值,rgb色彩值以及hex色彩值 | ||||||
|  |   - 基础色彩: `Bold` `Black` `White` `Gray` `Red` `Green` `Yellow` `Blue` `Magenta` `Cyan` | ||||||
|  |   - 扩展风格: `Info` `Note` `Light` `Error` `Danger` `Notice` `Success` `Comment` `Primary` `Warning` `Question` `Secondary` | ||||||
|  |   - 支持通过设置环境变量 `NO_COLOR` 来禁用色彩,或者使用 `FORCE_COLOR` 来强制使用色彩渲染. | ||||||
|  |   - 支持 Rgb, 256, 16 色彩之间的互相转换 | ||||||
|  |   - 支持Linux、Mac,同时兼容Windows系统环境 | ||||||
|  | 
 | ||||||
|  | ## GoDoc | ||||||
|  | 
 | ||||||
|  |   - [godoc for gopkg](https://pkg.go.dev/gopkg.in/gookit/color.v1) | ||||||
|  |   - [godoc for github](https://pkg.go.dev/github.com/gookit/color) | ||||||
|  | 
 | ||||||
|  | ## 安装 | ||||||
|  | 
 | ||||||
|  | ```bash | ||||||
|  | go get github.com/gookit/color | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ## 快速开始 | ||||||
|  | 
 | ||||||
|  | 如下,引入当前包就可以快速的使用 | ||||||
|  | 
 | ||||||
|  | ```go | ||||||
|  | package main | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  | 	 | ||||||
|  | 	"github.com/gookit/color" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | func main() { | ||||||
|  | 	// 简单快速的使用,跟 fmt.Print* 类似 | ||||||
|  | 	color.Redp("Simple to use color") | ||||||
|  | 	color.Redln("Simple to use color") | ||||||
|  | 	color.Greenp("Simple to use color\n") | ||||||
|  | 	color.Cyanln("Simple to use color") | ||||||
|  | 	color.Yellowln("Simple to use color") | ||||||
|  | 
 | ||||||
|  | 	// 简单快速的使用,跟 fmt.Print* 类似 | ||||||
|  | 	color.Red.Println("Simple to use color") | ||||||
|  | 	color.Green.Print("Simple to use color\n") | ||||||
|  | 	color.Cyan.Printf("Simple to use %s\n", "color") | ||||||
|  | 	color.Yellow.Printf("Simple to use %s\n", "color") | ||||||
|  | 
 | ||||||
|  | 	// use like func | ||||||
|  | 	red := color.FgRed.Render | ||||||
|  | 	green := color.FgGreen.Render | ||||||
|  | 	fmt.Printf("%s line %s library\n", red("Command"), green("color")) | ||||||
|  | 
 | ||||||
|  | 	// 自定义颜色 | ||||||
|  | 	color.New(color.FgWhite, color.BgBlack).Println("custom color style") | ||||||
|  | 
 | ||||||
|  | 	// 也可以: | ||||||
|  | 	color.Style{color.FgCyan, color.OpBold}.Println("custom color style") | ||||||
|  | 	 | ||||||
|  | 	// internal style: | ||||||
|  | 	color.Info.Println("message") | ||||||
|  | 	color.Warn.Println("message") | ||||||
|  | 	color.Error.Println("message") | ||||||
|  | 	 | ||||||
|  | 	// 使用内置颜色标签 | ||||||
|  | 	color.Print("<suc>he</><comment>llo</>, <cyan>wel</><red>come</>\n") | ||||||
|  | 	// 自定义标签: 支持使用16色彩名称,256色彩值,rgb色彩值以及hex色彩值 | ||||||
|  | 	color.Println("<fg=11aa23>he</><bg=120,35,156>llo</>, <fg=167;bg=232>wel</><fg=red>come</>") | ||||||
|  | 
 | ||||||
|  | 	// apply a style tag | ||||||
|  | 	color.Tag("info").Println("info style text") | ||||||
|  | 
 | ||||||
|  | 	// prompt message | ||||||
|  | 	color.Info.Prompt("prompt style message") | ||||||
|  | 	color.Warn.Prompt("prompt style message") | ||||||
|  | 
 | ||||||
|  | 	// tips message | ||||||
|  | 	color.Info.Tips("tips style message") | ||||||
|  | 	color.Warn.Tips("tips style message") | ||||||
|  | } | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | > 运行 demo: `go run ./_examples/demo.go` | ||||||
|  | 
 | ||||||
|  |  | ||||||
|  | 
 | ||||||
|  | ## 基础颜色(16-color) | ||||||
|  | 
 | ||||||
|  | 提供通用的API方法:`Print` `Printf` `Println` `Sprint` `Sprintf` | ||||||
|  | 
 | ||||||
|  | > 支持在windows `cmd.exe`  `powerShell` 等终端使用 | ||||||
|  | 
 | ||||||
|  | ```go | ||||||
|  | color.Bold.Println("bold message") | ||||||
|  | color.Black.Println("bold message") | ||||||
|  | color.White.Println("bold message") | ||||||
|  | color.Gray.Println("bold message") | ||||||
|  | color.Red.Println("yellow message") | ||||||
|  | color.Blue.Println("yellow message") | ||||||
|  | color.Cyan.Println("yellow message") | ||||||
|  | color.Yellow.Println("yellow message") | ||||||
|  | color.Magenta.Println("yellow message") | ||||||
|  | 
 | ||||||
|  | // Only use foreground color | ||||||
|  | color.FgCyan.Printf("Simple to use %s\n", "color") | ||||||
|  | // Only use background color | ||||||
|  | color.BgRed.Printf("Simple to use %s\n", "color") | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | > 运行demo: `go run ./_examples/color_16.go` | ||||||
|  | 
 | ||||||
|  |  | ||||||
|  | 
 | ||||||
|  | ### 构建风格 | ||||||
|  | 
 | ||||||
|  | ```go | ||||||
|  | // 仅设置前景色 | ||||||
|  | color.FgCyan.Printf("Simple to use %s\n", "color") | ||||||
|  | // 仅设置背景色 | ||||||
|  | color.BgRed.Printf("Simple to use %s\n", "color") | ||||||
|  | 
 | ||||||
|  | // 完全自定义: 前景色 背景色 选项 | ||||||
|  | style := color.New(color.FgWhite, color.BgBlack, color.OpBold) | ||||||
|  | style.Println("custom color style") | ||||||
|  | 
 | ||||||
|  | // 也可以: | ||||||
|  | color.Style{color.FgCyan, color.OpBold}.Println("custom color style") | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | 直接设置控制台属性: | ||||||
|  | 
 | ||||||
|  | ```go | ||||||
|  | // 设置console颜色 | ||||||
|  | color.Set(color.FgCyan) | ||||||
|  | 
 | ||||||
|  | // 输出信息 | ||||||
|  | fmt.Print("message") | ||||||
|  | 
 | ||||||
|  | // 重置console颜色 | ||||||
|  | color.Reset() | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | > 当然,color已经内置丰富的色彩风格支持 | ||||||
|  | 
 | ||||||
|  | ### 扩展风格方法  | ||||||
|  | 
 | ||||||
|  | 提供通用的API方法:`Print` `Printf` `Println` `Sprint` `Sprintf` | ||||||
|  | 
 | ||||||
|  | > 支持在windows `cmd.exe`  `powerShell` 等终端使用 | ||||||
|  | 
 | ||||||
|  | 基础使用: | ||||||
|  | 
 | ||||||
|  | ```go | ||||||
|  | // print message | ||||||
|  | color.Info.Println("Info message") | ||||||
|  | color.Note.Println("Note message") | ||||||
|  | color.Notice.Println("Notice message") | ||||||
|  | color.Error.Println("Error message") | ||||||
|  | color.Danger.Println("Danger message") | ||||||
|  | color.Warn.Println("Warn message") | ||||||
|  | color.Debug.Println("Debug message") | ||||||
|  | color.Primary.Println("Primary message") | ||||||
|  | color.Question.Println("Question message") | ||||||
|  | color.Secondary.Println("Secondary message") | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | Run demo: `go run ./_examples/theme_basic.go` | ||||||
|  | 
 | ||||||
|  |  | ||||||
|  | 
 | ||||||
|  | **简约提示风格** | ||||||
|  | 
 | ||||||
|  | ```go | ||||||
|  | color.Info.Tips("Info tips message") | ||||||
|  | color.Note.Tips("Note tips message") | ||||||
|  | color.Notice.Tips("Notice tips message") | ||||||
|  | color.Error.Tips("Error tips message") | ||||||
|  | color.Danger.Tips("Danger tips message") | ||||||
|  | color.Warn.Tips("Warn tips message") | ||||||
|  | color.Debug.Tips("Debug tips message") | ||||||
|  | color.Primary.Tips("Primary tips message") | ||||||
|  | color.Question.Tips("Question tips message") | ||||||
|  | color.Secondary.Tips("Secondary tips message") | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | Run demo: `go run ./_examples/theme_tips.go` | ||||||
|  | 
 | ||||||
|  |  | ||||||
|  | 
 | ||||||
|  | **着重提示风格** | ||||||
|  | 
 | ||||||
|  | ```go | ||||||
|  | color.Info.Prompt("Info prompt message") | ||||||
|  | color.Note.Prompt("Note prompt message") | ||||||
|  | color.Notice.Prompt("Notice prompt message") | ||||||
|  | color.Error.Prompt("Error prompt message") | ||||||
|  | color.Danger.Prompt("Danger prompt message") | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | Run demo: `go run ./_examples/theme_prompt.go` | ||||||
|  | 
 | ||||||
|  |  | ||||||
|  | 
 | ||||||
|  | **强调提示风格** | ||||||
|  | 
 | ||||||
|  | ```go | ||||||
|  | color.Warn.Block("Warn block message") | ||||||
|  | color.Debug.Block("Debug block message") | ||||||
|  | color.Primary.Block("Primary block message") | ||||||
|  | color.Question.Block("Question block message") | ||||||
|  | color.Secondary.Block("Secondary block message") | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | Run demo: `go run ./_examples/theme_block.go` | ||||||
|  | 
 | ||||||
|  |  | ||||||
|  | 
 | ||||||
|  | ## 256 色彩使用 | ||||||
|  | 
 | ||||||
|  | > 256色彩在 `v1.2.4` 后支持Windows CMD,PowerShell 环境 | ||||||
|  | 
 | ||||||
|  | ### 使用前景或后景色 | ||||||
|  |   | ||||||
|  |   - `color.C256(val uint8, isBg ...bool) Color256` | ||||||
|  | 
 | ||||||
|  | ```go | ||||||
|  | c := color.C256(132) // fg color | ||||||
|  | c.Println("message") | ||||||
|  | c.Printf("format %s", "message") | ||||||
|  | 
 | ||||||
|  | c := color.C256(132, true) // bg color | ||||||
|  | c.Println("message") | ||||||
|  | c.Printf("format %s", "message") | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ### 使用256 色彩风格 | ||||||
|  | 
 | ||||||
|  | > 可同时设置前景和背景色 | ||||||
|  |   | ||||||
|  | - `color.S256(fgAndBg ...uint8) *Style256` | ||||||
|  | 
 | ||||||
|  | ```go | ||||||
|  | s := color.S256(32, 203) | ||||||
|  | s.Println("message") | ||||||
|  | s.Printf("format %s", "message") | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | 可以同时添加选项设置: | ||||||
|  | 
 | ||||||
|  | ```go | ||||||
|  | s := color.S256(32, 203) | ||||||
|  | s.SetOpts(color.Opts{color.OpBold}) | ||||||
|  | 
 | ||||||
|  | s.Println("style with options") | ||||||
|  | s.Printf("style with %s\n", "options") | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | > 运行 demo: `go run ./_examples/color_256.go` | ||||||
|  | 
 | ||||||
|  |  | ||||||
|  | 
 | ||||||
|  | ## RGB/True色彩使用 | ||||||
|  | 
 | ||||||
|  | > RGB色彩在 `v1.2.4` 后支持 Windows `CMD`, `PowerShell` 环境 | ||||||
|  | 
 | ||||||
|  | **效果预览:** | ||||||
|  | 
 | ||||||
|  | > 运行 demo: `Run demo: go run ./_examples/color_rgb.go` | ||||||
|  | 
 | ||||||
|  |  | ||||||
|  | 
 | ||||||
|  | 代码示例: | ||||||
|  | 
 | ||||||
|  | ```go | ||||||
|  | color.RGB(30, 144, 255).Println("message. use RGB number") | ||||||
|  | 
 | ||||||
|  | color.HEX("#1976D2").Println("blue-darken") | ||||||
|  | color.HEX("#D50000", true).Println("red-accent. use HEX style") | ||||||
|  | 
 | ||||||
|  | color.RGBStyleFromString("213,0,0").Println("red-accent. use RGB number") | ||||||
|  | color.HEXStyle("eee", "D50000").Println("deep-purple color") | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ### 使用前景或后景色  | ||||||
|  | 
 | ||||||
|  | - `color.RGB(r, g, b uint8, isBg ...bool) RGBColor` | ||||||
|  | 
 | ||||||
|  | ```go | ||||||
|  | c := color.RGB(30,144,255) // fg color | ||||||
|  | c.Println("message") | ||||||
|  | c.Printf("format %s", "message") | ||||||
|  | 
 | ||||||
|  | c := color.RGB(30,144,255, true) // bg color | ||||||
|  | c.Println("message") | ||||||
|  | c.Printf("format %s", "message") | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | - `color.HEX(hex string, isBg ...bool) RGBColor` 从16进制颜色创建 | ||||||
|  | 
 | ||||||
|  | ```go | ||||||
|  | c := color.HEX("ccc") // 也可以写为: "cccccc" "#cccccc" | ||||||
|  | c.Println("message") | ||||||
|  | c.Printf("format %s", "message") | ||||||
|  | 
 | ||||||
|  | c = color.HEX("aabbcc", true) // as bg color | ||||||
|  | c.Println("message") | ||||||
|  | c.Printf("format %s", "message") | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ### 使用RGB风格 | ||||||
|  | 
 | ||||||
|  | > 可同时设置前景和背景色 | ||||||
|  | 
 | ||||||
|  | - `color.NewRGBStyle(fg RGBColor, bg ...RGBColor) *RGBStyle` | ||||||
|  | 
 | ||||||
|  | ```go | ||||||
|  | s := color.NewRGBStyle(RGB(20, 144, 234), RGB(234, 78, 23)) | ||||||
|  | s.Println("message") | ||||||
|  | s.Printf("format %s", "message") | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | - `color.HEXStyle(fg string, bg ...string) *RGBStyle` 从16进制颜色创建 | ||||||
|  | 
 | ||||||
|  | ```go | ||||||
|  | s := color.HEXStyle("11aa23", "eee") | ||||||
|  | s.Println("message") | ||||||
|  | s.Printf("format %s", "message") | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | - 可以同时添加选项设置: | ||||||
|  | 
 | ||||||
|  | ```go | ||||||
|  | s := color.HEXStyle("11aa23", "eee") | ||||||
|  | s.SetOpts(color.Opts{color.OpBold}) | ||||||
|  | 
 | ||||||
|  | s.Println("style with options") | ||||||
|  | s.Printf("style with %s\n", "options") | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ## 使用颜色标签 | ||||||
|  | 
 | ||||||
|  | > **支持** 在windows `cmd.exe` `PowerShell` 使用 | ||||||
|  | 
 | ||||||
|  | 使用内置的颜色标签,可以非常方便简单的构建自己需要的任何格式 | ||||||
|  | 
 | ||||||
|  | > 同时支持自定义颜色属性: 支持使用16色彩名称,256色彩值,rgb色彩值以及hex色彩值 | ||||||
|  | 
 | ||||||
|  | ```go | ||||||
|  | // 使用内置的 color tag | ||||||
|  | color.Print("<suc>he</><comment>llo</>, <cyan>wel</><red>come</>") | ||||||
|  | color.Println("<suc>hello</>") | ||||||
|  | color.Println("<error>hello</>") | ||||||
|  | color.Println("<warning>hello</>") | ||||||
|  | 
 | ||||||
|  | // 自定义颜色属性 | ||||||
|  | color.Print("<fg=yellow;bg=black;op=underscore;>hello, welcome</>\n") | ||||||
|  | 
 | ||||||
|  | // 自定义颜色属性: 支持使用16色彩名称,256色彩值,rgb色彩值以及hex色彩值 | ||||||
|  | color.Println("<fg=11aa23>he</><bg=120,35,156>llo</>, <fg=167;bg=232>wel</><fg=red>come</>") | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | - 使用 `color.Tag` | ||||||
|  | 
 | ||||||
|  | 给后面输出的文本信息加上给定的颜色风格标签 | ||||||
|  | 
 | ||||||
|  | ```go | ||||||
|  | // set a style tag | ||||||
|  | color.Tag("info").Print("info style text") | ||||||
|  | color.Tag("info").Printf("%s style text", "info") | ||||||
|  | color.Tag("info").Println("info style text") | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | > 运行 demo: `go run ./_examples/color_tag.go` | ||||||
|  | 
 | ||||||
|  |  | ||||||
|  | 
 | ||||||
|  | ## 颜色转换 | ||||||
|  | 
 | ||||||
|  | 支持 Rgb, 256, 16 色彩之间的互相转换 `Rgb <=> 256 <=> 16` | ||||||
|  | 
 | ||||||
|  | ```go | ||||||
|  | basic := color.Red | ||||||
|  | basic.Println("basic color") | ||||||
|  | 
 | ||||||
|  | c256 := color.Red.C256() | ||||||
|  | c256.Println("256 color") | ||||||
|  | c256.C16().Println("basic color") | ||||||
|  | 
 | ||||||
|  | rgb := color.Red.RGB() | ||||||
|  | rgb.Println("rgb color") | ||||||
|  | rgb.C256().Println("256 color") | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ## 方法参考 | ||||||
|  | 
 | ||||||
|  | 一些有用的工具方法参考 | ||||||
|  | 
 | ||||||
|  | - `Disable()` disable color render | ||||||
|  | - `SetOutput(io.Writer)` custom set the colored text output writer | ||||||
|  | - `ForceOpenColor()` force open color render | ||||||
|  | - `ClearCode(str string) string` Use for clear color codes | ||||||
|  | - `Colors2code(colors ...Color) string` Convert colors to code. return like "32;45;3" | ||||||
|  | - `ClearTag(s string) string` clear all color html-tag for a string | ||||||
|  | - `IsConsole(w io.Writer)` Determine whether w is one of stderr, stdout, stdin | ||||||
|  | - `HexToRgb(hex string) (rgb []int)` Convert hex color string to RGB numbers | ||||||
|  | - `RgbToHex(rgb []int) string` Convert RGB to hex code | ||||||
|  | - 更多请查看文档 https://pkg.go.dev/github.com/gookit/color | ||||||
|  | 
 | ||||||
|  | ## 使用color的项目 | ||||||
|  | 
 | ||||||
|  | 看看这些使用了 https://github.com/gookit/color 的项目: | ||||||
|  | 
 | ||||||
|  | - https://github.com/Delta456/box-cli-maker Make Highly Customized Boxes for your CLI | ||||||
|  | 
 | ||||||
|  | ## Gookit 工具包 | ||||||
|  | 
 | ||||||
|  |   - [gookit/ini](https://github.com/gookit/ini) INI配置读取管理,支持多文件加载,数据覆盖合并, 解析ENV变量, 解析变量引用 | ||||||
|  |   - [gookit/rux](https://github.com/gookit/rux) Simple and fast request router for golang HTTP  | ||||||
|  |   - [gookit/gcli](https://github.com/gookit/gcli) Go的命令行应用,工具库,运行CLI命令,支持命令行色彩,用户交互,进度显示,数据格式化显示 | ||||||
|  |   - [gookit/slog](https://github.com/gookit/slog) 简洁易扩展的go日志库 | ||||||
|  |   - [gookit/event](https://github.com/gookit/event) Go实现的轻量级的事件管理、调度程序库, 支持设置监听器的优先级, 支持对一组事件进行监听 | ||||||
|  |   - [gookit/cache](https://github.com/gookit/cache) 通用的缓存使用包装库,通过包装各种常用的驱动,来提供统一的使用API | ||||||
|  |   - [gookit/config](https://github.com/gookit/config) Go应用配置管理,支持多种格式(JSON, YAML, TOML, INI, HCL, ENV, Flags),多文件加载,远程文件加载,数据合并 | ||||||
|  |   - [gookit/color](https://github.com/gookit/color) CLI 控制台颜色渲染工具库, 拥有简洁的使用API,支持16色,256色,RGB色彩渲染输出 | ||||||
|  |   - [gookit/filter](https://github.com/gookit/filter) 提供对Golang数据的过滤,净化,转换 | ||||||
|  |   - [gookit/validate](https://github.com/gookit/validate) Go通用的数据验证与过滤库,使用简单,内置大部分常用验证、过滤器 | ||||||
|  |   - [gookit/goutil](https://github.com/gookit/goutil) Go 的一些工具函数,格式化,特殊处理,常用信息获取等 | ||||||
|  |   - 更多请查看 https://github.com/gookit | ||||||
|  | 
 | ||||||
|  | ## 参考项目 | ||||||
|  | 
 | ||||||
|  |   - [inhere/console](https://github.com/inhere/php-console) | ||||||
|  |   - [xo/terminfo](https://github.com/xo/terminfo) | ||||||
|  |   - [beego/bee](https://github.com/beego/bee) | ||||||
|  |   - [issue9/term](https://github.com/issue9/term) | ||||||
|  |   - [ANSI转义序列](https://zh.wikipedia.org/wiki/ANSI转义序列) | ||||||
|  |   - [Standard ANSI color map](https://conemu.github.io/en/AnsiEscapeCodes.html#Standard_ANSI_color_map) | ||||||
|  |   - [Terminal Colors](https://gist.github.com/XVilka/8346728) | ||||||
|  | 
 | ||||||
|  | ## License | ||||||
|  | 
 | ||||||
|  | MIT | ||||||
							
								
								
									
										238
									
								
								vendor/github.com/gookit/color/color.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										238
									
								
								vendor/github.com/gookit/color/color.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,238 @@ | |||||||
|  | /* | ||||||
|  | Package color is Command line color library. | ||||||
|  | Support rich color rendering output, universal API method, compatible with Windows system | ||||||
|  | 
 | ||||||
|  | Source code and other details for the project are available at GitHub: | ||||||
|  | 
 | ||||||
|  | 	https://github.com/gookit/color
 | ||||||
|  | 
 | ||||||
|  | More usage please see README and tests. | ||||||
|  | */ | ||||||
|  | package color | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  | 	"io" | ||||||
|  | 	"os" | ||||||
|  | 	"regexp" | ||||||
|  | 
 | ||||||
|  | 	"github.com/xo/terminfo" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // terminal color available level alias of the terminfo.ColorLevel*
 | ||||||
|  | const ( | ||||||
|  | 	LevelNo  = terminfo.ColorLevelNone     // not support color.
 | ||||||
|  | 	Level16  = terminfo.ColorLevelBasic    // 3/4 bit color supported
 | ||||||
|  | 	Level256 = terminfo.ColorLevelHundreds // 8 bit color supported
 | ||||||
|  | 	LevelRgb = terminfo.ColorLevelMillions // (24 bit)true color supported
 | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // color render templates
 | ||||||
|  | // ESC 操作的表示:
 | ||||||
|  | // 	"\033"(Octal 8进制) = "\x1b"(Hexadecimal 16进制) = 27 (10进制)
 | ||||||
|  | const ( | ||||||
|  | 	SettingTpl   = "\x1b[%sm" | ||||||
|  | 	FullColorTpl = "\x1b[%sm%s\x1b[0m" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // ResetSet Close all properties.
 | ||||||
|  | const ResetSet = "\x1b[0m" | ||||||
|  | 
 | ||||||
|  | // CodeExpr regex to clear color codes eg "\033[1;36mText\x1b[0m"
 | ||||||
|  | const CodeExpr = `\033\[[\d;?]+m` | ||||||
|  | 
 | ||||||
|  | var ( | ||||||
|  | 	// Enable switch color render and display
 | ||||||
|  | 	//
 | ||||||
|  | 	// NOTICE:
 | ||||||
|  | 	// if ENV: NO_COLOR is not empty, will disable color render.
 | ||||||
|  | 	Enable = os.Getenv("NO_COLOR") == "" | ||||||
|  | 	// RenderTag render HTML tag on call color.Xprint, color.PrintX
 | ||||||
|  | 	RenderTag = true | ||||||
|  | 	// debug mode for development.
 | ||||||
|  | 	//
 | ||||||
|  | 	// set env:
 | ||||||
|  | 	// 	COLOR_DEBUG_MODE=on
 | ||||||
|  | 	// or:
 | ||||||
|  | 	// 	COLOR_DEBUG_MODE=on go run ./_examples/envcheck.go
 | ||||||
|  | 	debugMode = os.Getenv("COLOR_DEBUG_MODE") == "on" | ||||||
|  | 	// inner errors record on detect color level
 | ||||||
|  | 	innerErrs []error | ||||||
|  | 	// output the default io.Writer message print
 | ||||||
|  | 	output io.Writer = os.Stdout | ||||||
|  | 	// mark current env, It's like in `cmd.exe`
 | ||||||
|  | 	// if not in windows, it's always is False.
 | ||||||
|  | 	isLikeInCmd bool | ||||||
|  | 	// the color support level for current terminal
 | ||||||
|  | 	// needVTP - need enable VTP, only for windows OS
 | ||||||
|  | 	colorLevel, needVTP = detectTermColorLevel() | ||||||
|  | 	// match color codes
 | ||||||
|  | 	codeRegex = regexp.MustCompile(CodeExpr) | ||||||
|  | 	// mark current env is support color.
 | ||||||
|  | 	// Always: isLikeInCmd != supportColor
 | ||||||
|  | 	// supportColor = IsSupportColor()
 | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // TermColorLevel value on current ENV
 | ||||||
|  | func TermColorLevel() terminfo.ColorLevel { | ||||||
|  | 	return colorLevel | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // SupportColor on the current ENV
 | ||||||
|  | func SupportColor() bool { | ||||||
|  | 	return colorLevel > terminfo.ColorLevelNone | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Support16Color on the current ENV
 | ||||||
|  | // func Support16Color() bool {
 | ||||||
|  | // 	return colorLevel > terminfo.ColorLevelNone
 | ||||||
|  | // }
 | ||||||
|  | 
 | ||||||
|  | // Support256Color on the current ENV
 | ||||||
|  | func Support256Color() bool { | ||||||
|  | 	return colorLevel > terminfo.ColorLevelBasic | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // SupportTrueColor on the current ENV
 | ||||||
|  | func SupportTrueColor() bool { | ||||||
|  | 	return colorLevel > terminfo.ColorLevelHundreds | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /************************************************************* | ||||||
|  |  * global settings | ||||||
|  |  *************************************************************/ | ||||||
|  | 
 | ||||||
|  | // Set set console color attributes
 | ||||||
|  | func Set(colors ...Color) (int, error) { | ||||||
|  | 	code := Colors2code(colors...) | ||||||
|  | 	err := SetTerminal(code) | ||||||
|  | 	return 0, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Reset reset console color attributes
 | ||||||
|  | func Reset() (int, error) { | ||||||
|  | 	err := ResetTerminal() | ||||||
|  | 	return 0, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Disable disable color output
 | ||||||
|  | func Disable() bool { | ||||||
|  | 	oldVal := Enable | ||||||
|  | 	Enable = false | ||||||
|  | 	return oldVal | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // NotRenderTag on call color.Xprint, color.PrintX
 | ||||||
|  | func NotRenderTag() { | ||||||
|  | 	RenderTag = false | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // SetOutput set default colored text output
 | ||||||
|  | func SetOutput(w io.Writer) { | ||||||
|  | 	output = w | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ResetOutput reset output
 | ||||||
|  | func ResetOutput() { | ||||||
|  | 	output = os.Stdout | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ResetOptions reset all package option setting
 | ||||||
|  | func ResetOptions() { | ||||||
|  | 	RenderTag = true | ||||||
|  | 	Enable = true | ||||||
|  | 	output = os.Stdout | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ForceColor force open color render
 | ||||||
|  | func ForceSetColorLevel(level terminfo.ColorLevel) terminfo.ColorLevel { | ||||||
|  | 	oldLevelVal := colorLevel | ||||||
|  | 	colorLevel = level | ||||||
|  | 	return oldLevelVal | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ForceColor force open color render
 | ||||||
|  | func ForceColor() terminfo.ColorLevel { | ||||||
|  | 	return ForceOpenColor() | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ForceOpenColor force open color render
 | ||||||
|  | func ForceOpenColor() terminfo.ColorLevel { | ||||||
|  | 	// TODO should set level to ?
 | ||||||
|  | 	return ForceSetColorLevel(terminfo.ColorLevelMillions) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // IsLikeInCmd check result
 | ||||||
|  | // Deprecated
 | ||||||
|  | func IsLikeInCmd() bool { | ||||||
|  | 	return isLikeInCmd | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // InnerErrs info
 | ||||||
|  | func InnerErrs() []error { | ||||||
|  | 	return innerErrs | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /************************************************************* | ||||||
|  |  * render color code | ||||||
|  |  *************************************************************/ | ||||||
|  | 
 | ||||||
|  | // RenderCode render message by color code.
 | ||||||
|  | // Usage:
 | ||||||
|  | // 	msg := RenderCode("3;32;45", "some", "message")
 | ||||||
|  | func RenderCode(code string, args ...interface{}) string { | ||||||
|  | 	var message string | ||||||
|  | 	if ln := len(args); ln == 0 { | ||||||
|  | 		return "" | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	message = fmt.Sprint(args...) | ||||||
|  | 	if len(code) == 0 { | ||||||
|  | 		return message | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// disabled OR not support color
 | ||||||
|  | 	if !Enable || !SupportColor() { | ||||||
|  | 		return ClearCode(message) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return fmt.Sprintf(FullColorTpl, code, message) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // RenderWithSpaces Render code with spaces.
 | ||||||
|  | // If the number of args is > 1, a space will be added between the args
 | ||||||
|  | func RenderWithSpaces(code string, args ...interface{}) string { | ||||||
|  | 	message := formatArgsForPrintln(args) | ||||||
|  | 	if len(code) == 0 { | ||||||
|  | 		return message | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// disabled OR not support color
 | ||||||
|  | 	if !Enable || !SupportColor() { | ||||||
|  | 		return ClearCode(message) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return fmt.Sprintf(FullColorTpl, code, message) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // RenderString render a string with color code.
 | ||||||
|  | // Usage:
 | ||||||
|  | // 	msg := RenderString("3;32;45", "a message")
 | ||||||
|  | func RenderString(code string, str string) string { | ||||||
|  | 	if len(code) == 0 || str == "" { | ||||||
|  | 		return str | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// disabled OR not support color
 | ||||||
|  | 	if !Enable || !SupportColor() { | ||||||
|  | 		return ClearCode(str) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return fmt.Sprintf(FullColorTpl, code, str) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ClearCode clear color codes.
 | ||||||
|  | // eg: "\033[36;1mText\x1b[0m" -> "Text"
 | ||||||
|  | func ClearCode(str string) string { | ||||||
|  | 	return codeRegex.ReplaceAllString(str, "") | ||||||
|  | } | ||||||
							
								
								
									
										440
									
								
								vendor/github.com/gookit/color/color_16.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										440
									
								
								vendor/github.com/gookit/color/color_16.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,440 @@ | |||||||
|  | package color | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  | 	"strconv" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // Color Color16, 16 color value type
 | ||||||
|  | // 3(2^3=8) OR 4(2^4=16) bite color.
 | ||||||
|  | type Color uint8 | ||||||
|  | type Basic = Color // alias of Color
 | ||||||
|  | 
 | ||||||
|  | // Opts basic color options. code: 0 - 9
 | ||||||
|  | type Opts []Color | ||||||
|  | 
 | ||||||
|  | // Add option value
 | ||||||
|  | func (o *Opts) Add(ops ...Color) { | ||||||
|  | 	for _, op := range ops { | ||||||
|  | 		if uint8(op) < 10 { | ||||||
|  | 			*o = append(*o, op) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // IsValid options
 | ||||||
|  | func (o Opts) IsValid() bool { | ||||||
|  | 	return len(o) > 0 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // IsEmpty options
 | ||||||
|  | func (o Opts) IsEmpty() bool { | ||||||
|  | 	return len(o) == 0 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // String options to string. eg: "1;3"
 | ||||||
|  | func (o Opts) String() string { | ||||||
|  | 	return Colors2code(o...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /************************************************************* | ||||||
|  |  * Basic 16 color definition | ||||||
|  |  *************************************************************/ | ||||||
|  | 
 | ||||||
|  | // Base value for foreground/background color
 | ||||||
|  | const ( | ||||||
|  | 	FgBase uint8 = 30 | ||||||
|  | 	BgBase uint8 = 40 | ||||||
|  | 	// hi color base code
 | ||||||
|  | 	HiFgBase uint8 = 90 | ||||||
|  | 	HiBgBase uint8 = 100 | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // Foreground colors. basic foreground colors 30 - 37
 | ||||||
|  | const ( | ||||||
|  | 	FgBlack Color = iota + 30 | ||||||
|  | 	FgRed | ||||||
|  | 	FgGreen | ||||||
|  | 	FgYellow | ||||||
|  | 	FgBlue | ||||||
|  | 	FgMagenta // 品红
 | ||||||
|  | 	FgCyan    // 青色
 | ||||||
|  | 	FgWhite | ||||||
|  | 	// FgDefault revert default FG
 | ||||||
|  | 	FgDefault Color = 39 | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // Extra foreground color 90 - 97(非标准)
 | ||||||
|  | const ( | ||||||
|  | 	FgDarkGray Color = iota + 90 // 亮黑(灰)
 | ||||||
|  | 	FgLightRed | ||||||
|  | 	FgLightGreen | ||||||
|  | 	FgLightYellow | ||||||
|  | 	FgLightBlue | ||||||
|  | 	FgLightMagenta | ||||||
|  | 	FgLightCyan | ||||||
|  | 	FgLightWhite | ||||||
|  | 	// FgGray is alias of FgDarkGray
 | ||||||
|  | 	FgGray Color = 90 // 亮黑(灰)
 | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // Background colors. basic background colors 40 - 47
 | ||||||
|  | const ( | ||||||
|  | 	BgBlack Color = iota + 40 | ||||||
|  | 	BgRed | ||||||
|  | 	BgGreen | ||||||
|  | 	BgYellow // BgBrown like yellow
 | ||||||
|  | 	BgBlue | ||||||
|  | 	BgMagenta | ||||||
|  | 	BgCyan | ||||||
|  | 	BgWhite | ||||||
|  | 	// BgDefault revert default BG
 | ||||||
|  | 	BgDefault Color = 49 | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // Extra background color 100 - 107(非标准)
 | ||||||
|  | const ( | ||||||
|  | 	BgDarkGray Color = iota + 100 | ||||||
|  | 	BgLightRed | ||||||
|  | 	BgLightGreen | ||||||
|  | 	BgLightYellow | ||||||
|  | 	BgLightBlue | ||||||
|  | 	BgLightMagenta | ||||||
|  | 	BgLightCyan | ||||||
|  | 	BgLightWhite | ||||||
|  | 	// BgGray is alias of BgDarkGray
 | ||||||
|  | 	BgGray Color = 100 | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // Option settings
 | ||||||
|  | const ( | ||||||
|  | 	OpReset         Color = iota // 0 重置所有设置
 | ||||||
|  | 	OpBold                       // 1 加粗
 | ||||||
|  | 	OpFuzzy                      // 2 模糊(不是所有的终端仿真器都支持)
 | ||||||
|  | 	OpItalic                     // 3 斜体(不是所有的终端仿真器都支持)
 | ||||||
|  | 	OpUnderscore                 // 4 下划线
 | ||||||
|  | 	OpBlink                      // 5 闪烁
 | ||||||
|  | 	OpFastBlink                  // 5 快速闪烁(未广泛支持)
 | ||||||
|  | 	OpReverse                    // 7 颠倒的 交换背景色与前景色
 | ||||||
|  | 	OpConcealed                  // 8 隐匿的
 | ||||||
|  | 	OpStrikethrough              // 9 删除的,删除线(未广泛支持)
 | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // There are basic and light foreground color aliases
 | ||||||
|  | const ( | ||||||
|  | 	Red     = FgRed | ||||||
|  | 	Cyan    = FgCyan | ||||||
|  | 	Gray    = FgDarkGray // is light Black
 | ||||||
|  | 	Blue    = FgBlue | ||||||
|  | 	Black   = FgBlack | ||||||
|  | 	Green   = FgGreen | ||||||
|  | 	White   = FgWhite | ||||||
|  | 	Yellow  = FgYellow | ||||||
|  | 	Magenta = FgMagenta | ||||||
|  | 
 | ||||||
|  | 	// special
 | ||||||
|  | 
 | ||||||
|  | 	Bold   = OpBold | ||||||
|  | 	Normal = FgDefault | ||||||
|  | 
 | ||||||
|  | 	// extra light
 | ||||||
|  | 
 | ||||||
|  | 	LightRed     = FgLightRed | ||||||
|  | 	LightCyan    = FgLightCyan | ||||||
|  | 	LightBlue    = FgLightBlue | ||||||
|  | 	LightGreen   = FgLightGreen | ||||||
|  | 	LightWhite   = FgLightWhite | ||||||
|  | 	LightYellow  = FgLightYellow | ||||||
|  | 	LightMagenta = FgLightMagenta | ||||||
|  | 
 | ||||||
|  | 	HiRed     = FgLightRed | ||||||
|  | 	HiCyan    = FgLightCyan | ||||||
|  | 	HiBlue    = FgLightBlue | ||||||
|  | 	HiGreen   = FgLightGreen | ||||||
|  | 	HiWhite   = FgLightWhite | ||||||
|  | 	HiYellow  = FgLightYellow | ||||||
|  | 	HiMagenta = FgLightMagenta | ||||||
|  | 
 | ||||||
|  | 	BgHiRed     = BgLightRed | ||||||
|  | 	BgHiCyan    = BgLightCyan | ||||||
|  | 	BgHiBlue    = BgLightBlue | ||||||
|  | 	BgHiGreen   = BgLightGreen | ||||||
|  | 	BgHiWhite   = BgLightWhite | ||||||
|  | 	BgHiYellow  = BgLightYellow | ||||||
|  | 	BgHiMagenta = BgLightMagenta | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // Bit4 an method for create Color
 | ||||||
|  | func Bit4(code uint8) Color { | ||||||
|  | 	return Color(code) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /************************************************************* | ||||||
|  |  * Color render methods | ||||||
|  |  *************************************************************/ | ||||||
|  | 
 | ||||||
|  | // Name get color code name.
 | ||||||
|  | func (c Color) Name() string { | ||||||
|  | 	name, ok := basic2nameMap[uint8(c)] | ||||||
|  | 	if ok { | ||||||
|  | 		return name | ||||||
|  | 	} | ||||||
|  | 	return "unknown" | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Text render a text message
 | ||||||
|  | func (c Color) Text(message string) string { | ||||||
|  | 	return RenderString(c.String(), message) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Render messages by color setting
 | ||||||
|  | // Usage:
 | ||||||
|  | // 		green := color.FgGreen.Render
 | ||||||
|  | // 		fmt.Println(green("message"))
 | ||||||
|  | func (c Color) Render(a ...interface{}) string { | ||||||
|  | 	return RenderCode(c.String(), a...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Renderln messages by color setting.
 | ||||||
|  | // like Println, will add spaces for each argument
 | ||||||
|  | // Usage:
 | ||||||
|  | // 		green := color.FgGreen.Renderln
 | ||||||
|  | // 		fmt.Println(green("message"))
 | ||||||
|  | func (c Color) Renderln(a ...interface{}) string { | ||||||
|  | 	return RenderWithSpaces(c.String(), a...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Sprint render messages by color setting. is alias of the Render()
 | ||||||
|  | func (c Color) Sprint(a ...interface{}) string { | ||||||
|  | 	return RenderCode(c.String(), a...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Sprintf format and render message.
 | ||||||
|  | // Usage:
 | ||||||
|  | // 	green := color.Green.Sprintf
 | ||||||
|  | //  colored := green("message")
 | ||||||
|  | func (c Color) Sprintf(format string, args ...interface{}) string { | ||||||
|  | 	return RenderString(c.String(), fmt.Sprintf(format, args...)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Print messages.
 | ||||||
|  | // Usage:
 | ||||||
|  | // 		color.Green.Print("message")
 | ||||||
|  | // OR:
 | ||||||
|  | // 		green := color.FgGreen.Print
 | ||||||
|  | // 		green("message")
 | ||||||
|  | func (c Color) Print(args ...interface{}) { | ||||||
|  | 	doPrintV2(c.Code(), fmt.Sprint(args...)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Printf format and print messages.
 | ||||||
|  | // Usage:
 | ||||||
|  | // 		color.Cyan.Printf("string %s", "arg0")
 | ||||||
|  | func (c Color) Printf(format string, a ...interface{}) { | ||||||
|  | 	doPrintV2(c.Code(), fmt.Sprintf(format, a...)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Println messages with new line
 | ||||||
|  | func (c Color) Println(a ...interface{}) { | ||||||
|  | 	doPrintlnV2(c.String(), a) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Light current color. eg: 36(FgCyan) -> 96(FgLightCyan).
 | ||||||
|  | // Usage:
 | ||||||
|  | // 	lightCyan := Cyan.Light()
 | ||||||
|  | // 	lightCyan.Print("message")
 | ||||||
|  | func (c Color) Light() Color { | ||||||
|  | 	val := int(c) | ||||||
|  | 	if val >= 30 && val <= 47 { | ||||||
|  | 		return Color(uint8(c) + 60) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// don't change
 | ||||||
|  | 	return c | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Darken current color. eg. 96(FgLightCyan) -> 36(FgCyan)
 | ||||||
|  | // Usage:
 | ||||||
|  | // 	cyan := LightCyan.Darken()
 | ||||||
|  | // 	cyan.Print("message")
 | ||||||
|  | func (c Color) Darken() Color { | ||||||
|  | 	val := int(c) | ||||||
|  | 	if val >= 90 && val <= 107 { | ||||||
|  | 		return Color(uint8(c) - 60) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// don't change
 | ||||||
|  | 	return c | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // C256 convert 16 color to 256-color code.
 | ||||||
|  | func (c Color) C256() Color256 { | ||||||
|  | 	val := uint8(c) | ||||||
|  | 	if val < 10 { // is option code
 | ||||||
|  | 		return emptyC256 // empty
 | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	var isBg uint8 | ||||||
|  | 	if val >= BgBase && val <= 47 { // is bg
 | ||||||
|  | 		isBg = AsBg | ||||||
|  | 		val = val - 10 // to fg code
 | ||||||
|  | 	} else if val >= HiBgBase && val <= 107 { // is hi bg
 | ||||||
|  | 		isBg = AsBg | ||||||
|  | 		val = val - 10 // to fg code
 | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if c256, ok := basicTo256Map[val]; ok { | ||||||
|  | 		return Color256{c256, isBg} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// use raw value direct convert
 | ||||||
|  | 	return Color256{val} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // RGB convert 16 color to 256-color code.
 | ||||||
|  | func (c Color) RGB() RGBColor { | ||||||
|  | 	val := uint8(c) | ||||||
|  | 	if val < 10 { // is option code
 | ||||||
|  | 		return emptyRGBColor | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return HEX(Basic2hex(val)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Code convert to code string. eg "35"
 | ||||||
|  | func (c Color) Code() string { | ||||||
|  | 	// return fmt.Sprintf("%d", c)
 | ||||||
|  | 	return strconv.Itoa(int(c)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // String convert to code string. eg "35"
 | ||||||
|  | func (c Color) String() string { | ||||||
|  | 	// return fmt.Sprintf("%d", c)
 | ||||||
|  | 	return strconv.Itoa(int(c)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // IsValid color value
 | ||||||
|  | func (c Color) IsValid() bool { | ||||||
|  | 	return c < 107 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /************************************************************* | ||||||
|  |  * basic color maps | ||||||
|  |  *************************************************************/ | ||||||
|  | 
 | ||||||
|  | // FgColors foreground colors map
 | ||||||
|  | var FgColors = map[string]Color{ | ||||||
|  | 	"black":   FgBlack, | ||||||
|  | 	"red":     FgRed, | ||||||
|  | 	"green":   FgGreen, | ||||||
|  | 	"yellow":  FgYellow, | ||||||
|  | 	"blue":    FgBlue, | ||||||
|  | 	"magenta": FgMagenta, | ||||||
|  | 	"cyan":    FgCyan, | ||||||
|  | 	"white":   FgWhite, | ||||||
|  | 	"default": FgDefault, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // BgColors background colors map
 | ||||||
|  | var BgColors = map[string]Color{ | ||||||
|  | 	"black":   BgBlack, | ||||||
|  | 	"red":     BgRed, | ||||||
|  | 	"green":   BgGreen, | ||||||
|  | 	"yellow":  BgYellow, | ||||||
|  | 	"blue":    BgBlue, | ||||||
|  | 	"magenta": BgMagenta, | ||||||
|  | 	"cyan":    BgCyan, | ||||||
|  | 	"white":   BgWhite, | ||||||
|  | 	"default": BgDefault, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ExFgColors extra foreground colors map
 | ||||||
|  | var ExFgColors = map[string]Color{ | ||||||
|  | 	"darkGray":     FgDarkGray, | ||||||
|  | 	"lightRed":     FgLightRed, | ||||||
|  | 	"lightGreen":   FgLightGreen, | ||||||
|  | 	"lightYellow":  FgLightYellow, | ||||||
|  | 	"lightBlue":    FgLightBlue, | ||||||
|  | 	"lightMagenta": FgLightMagenta, | ||||||
|  | 	"lightCyan":    FgLightCyan, | ||||||
|  | 	"lightWhite":   FgLightWhite, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ExBgColors extra background colors map
 | ||||||
|  | var ExBgColors = map[string]Color{ | ||||||
|  | 	"darkGray":     BgDarkGray, | ||||||
|  | 	"lightRed":     BgLightRed, | ||||||
|  | 	"lightGreen":   BgLightGreen, | ||||||
|  | 	"lightYellow":  BgLightYellow, | ||||||
|  | 	"lightBlue":    BgLightBlue, | ||||||
|  | 	"lightMagenta": BgLightMagenta, | ||||||
|  | 	"lightCyan":    BgLightCyan, | ||||||
|  | 	"lightWhite":   BgLightWhite, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Options color options map
 | ||||||
|  | // Deprecated
 | ||||||
|  | // NOTICE: please use AllOptions instead.
 | ||||||
|  | var Options = AllOptions | ||||||
|  | 
 | ||||||
|  | // AllOptions color options map
 | ||||||
|  | var AllOptions = map[string]Color{ | ||||||
|  | 	"reset":      OpReset, | ||||||
|  | 	"bold":       OpBold, | ||||||
|  | 	"fuzzy":      OpFuzzy, | ||||||
|  | 	"italic":     OpItalic, | ||||||
|  | 	"underscore": OpUnderscore, | ||||||
|  | 	"blink":      OpBlink, | ||||||
|  | 	"reverse":    OpReverse, | ||||||
|  | 	"concealed":  OpConcealed, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | var ( | ||||||
|  | 	// TODO basic name alias
 | ||||||
|  | 	// basicNameAlias = map[string]string{}
 | ||||||
|  | 
 | ||||||
|  | 	// basic color name to code
 | ||||||
|  | 	name2basicMap = initName2basicMap() | ||||||
|  | 	// basic2nameMap basic color code to name
 | ||||||
|  | 	basic2nameMap = map[uint8]string{ | ||||||
|  | 		30: "black", | ||||||
|  | 		31: "red", | ||||||
|  | 		32: "green", | ||||||
|  | 		33: "yellow", | ||||||
|  | 		34: "blue", | ||||||
|  | 		35: "magenta", | ||||||
|  | 		36: "cyan", | ||||||
|  | 		37: "white", | ||||||
|  | 		// hi color code
 | ||||||
|  | 		90: "lightBlack", | ||||||
|  | 		91: "lightRed", | ||||||
|  | 		92: "lightGreen", | ||||||
|  | 		93: "lightYellow", | ||||||
|  | 		94: "lightBlue", | ||||||
|  | 		95: "lightMagenta", | ||||||
|  | 		96: "lightCyan", | ||||||
|  | 		97: "lightWhite", | ||||||
|  | 		// options
 | ||||||
|  | 		0: "reset", | ||||||
|  | 		1: "bold", | ||||||
|  | 		2: "fuzzy", | ||||||
|  | 		3: "italic", | ||||||
|  | 		4: "underscore", | ||||||
|  | 		5: "blink", | ||||||
|  | 		7: "reverse", | ||||||
|  | 		8: "concealed", | ||||||
|  | 	} | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // Basic2nameMap data
 | ||||||
|  | func Basic2nameMap() map[uint8]string { | ||||||
|  | 	return basic2nameMap | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func initName2basicMap() map[string]uint8 { | ||||||
|  | 	n2b := make(map[string]uint8, len(basic2nameMap)) | ||||||
|  | 	for u, s := range basic2nameMap { | ||||||
|  | 		n2b[s] = u | ||||||
|  | 	} | ||||||
|  | 	return n2b | ||||||
|  | } | ||||||
							
								
								
									
										308
									
								
								vendor/github.com/gookit/color/color_256.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										308
									
								
								vendor/github.com/gookit/color/color_256.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,308 @@ | |||||||
|  | package color | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  | 	"strconv" | ||||||
|  | 	"strings" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | /* | ||||||
|  | from wikipedia, 256 color: | ||||||
|  |    ESC[ … 38;5;<n> … m选择前景色 | ||||||
|  |    ESC[ … 48;5;<n> … m选择背景色 | ||||||
|  |      0-  7:标准颜色(同 ESC[30–37m) | ||||||
|  |      8- 15:高强度颜色(同 ESC[90–97m) | ||||||
|  |     16-231:6 × 6 × 6 立方(216色): 16 + 36 × r + 6 × g + b (0 ≤ r, g, b ≤ 5) | ||||||
|  |    232-255:从黑到白的24阶灰度色 | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | // tpl for 8 bit 256 color(`2^8`)
 | ||||||
|  | //
 | ||||||
|  | // format:
 | ||||||
|  | // 	ESC[ … 38;5;<n> … m // 选择前景色
 | ||||||
|  | //  ESC[ … 48;5;<n> … m // 选择背景色
 | ||||||
|  | //
 | ||||||
|  | // example:
 | ||||||
|  | //  fg "\x1b[38;5;242m"
 | ||||||
|  | //  bg "\x1b[48;5;208m"
 | ||||||
|  | //  both "\x1b[38;5;242;48;5;208m"
 | ||||||
|  | //
 | ||||||
|  | // links:
 | ||||||
|  | // 	https://zh.wikipedia.org/wiki/ANSI%E8%BD%AC%E4%B9%89%E5%BA%8F%E5%88%97#8位
 | ||||||
|  | const ( | ||||||
|  | 	TplFg256 = "38;5;%d" | ||||||
|  | 	TplBg256 = "48;5;%d" | ||||||
|  | 	Fg256Pfx = "38;5;" | ||||||
|  | 	Bg256Pfx = "48;5;" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | /************************************************************* | ||||||
|  |  * 8bit(256) Color: Bit8Color Color256 | ||||||
|  |  *************************************************************/ | ||||||
|  | 
 | ||||||
|  | // Color256 256 color (8 bit), uint8 range at 0 - 255
 | ||||||
|  | //
 | ||||||
|  | // 颜色值使用10进制和16进制都可 0x98 = 152
 | ||||||
|  | //
 | ||||||
|  | // The color consists of two uint8:
 | ||||||
|  | // 	0: color value
 | ||||||
|  | // 	1: color type; Fg=0, Bg=1, >1: unset value
 | ||||||
|  | //
 | ||||||
|  | // example:
 | ||||||
|  | // 	fg color: [152, 0]
 | ||||||
|  | //  bg color: [152, 1]
 | ||||||
|  | //
 | ||||||
|  | // NOTICE: now support 256 color on windows CMD, PowerShell
 | ||||||
|  | // lint warn - Name starts with package name
 | ||||||
|  | type Color256 [2]uint8 | ||||||
|  | type Bit8Color = Color256 // alias
 | ||||||
|  | 
 | ||||||
|  | var emptyC256 = Color256{1: 99} | ||||||
|  | 
 | ||||||
|  | // Bit8 create a color256
 | ||||||
|  | func Bit8(val uint8, isBg ...bool) Color256 { | ||||||
|  | 	return C256(val, isBg...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // C256 create a color256
 | ||||||
|  | func C256(val uint8, isBg ...bool) Color256 { | ||||||
|  | 	bc := Color256{val} | ||||||
|  | 
 | ||||||
|  | 	// mark is bg color
 | ||||||
|  | 	if len(isBg) > 0 && isBg[0] { | ||||||
|  | 		bc[1] = AsBg | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return bc | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Set terminal by 256 color code
 | ||||||
|  | func (c Color256) Set() error { | ||||||
|  | 	return SetTerminal(c.String()) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Reset terminal. alias of the ResetTerminal()
 | ||||||
|  | func (c Color256) Reset() error { | ||||||
|  | 	return ResetTerminal() | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Print print message
 | ||||||
|  | func (c Color256) Print(a ...interface{}) { | ||||||
|  | 	doPrintV2(c.String(), fmt.Sprint(a...)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Printf format and print message
 | ||||||
|  | func (c Color256) Printf(format string, a ...interface{}) { | ||||||
|  | 	doPrintV2(c.String(), fmt.Sprintf(format, a...)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Println print message with newline
 | ||||||
|  | func (c Color256) Println(a ...interface{}) { | ||||||
|  | 	doPrintlnV2(c.String(), a) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Sprint returns rendered message
 | ||||||
|  | func (c Color256) Sprint(a ...interface{}) string { | ||||||
|  | 	return RenderCode(c.String(), a...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Sprintf returns format and rendered message
 | ||||||
|  | func (c Color256) Sprintf(format string, a ...interface{}) string { | ||||||
|  | 	return RenderString(c.String(), fmt.Sprintf(format, a...)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // C16 convert color-256 to 16 color.
 | ||||||
|  | func (c Color256) C16() Color { | ||||||
|  | 	return c.Basic() | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Basic convert color-256 to basic 16 color.
 | ||||||
|  | func (c Color256) Basic() Color { | ||||||
|  | 	return Color(c[0]) // TODO
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // RGB convert color-256 to RGB color.
 | ||||||
|  | func (c Color256) RGB() RGBColor { | ||||||
|  | 	return RGBFromSlice(C256ToRgb(c[0]), c[1] == AsBg) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // RGBColor convert color-256 to RGB color.
 | ||||||
|  | func (c Color256) RGBColor() RGBColor { | ||||||
|  | 	return c.RGB() | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Value return color value
 | ||||||
|  | func (c Color256) Value() uint8 { | ||||||
|  | 	return c[0] | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Code convert to color code string. eg: "12"
 | ||||||
|  | func (c Color256) Code() string { | ||||||
|  | 	return strconv.Itoa(int(c[0])) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // FullCode convert to color code string with prefix. eg: "38;5;12"
 | ||||||
|  | func (c Color256) FullCode() string { | ||||||
|  | 	return c.String() | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // String convert to color code string with prefix. eg: "38;5;12"
 | ||||||
|  | func (c Color256) String() string { | ||||||
|  | 	if c[1] == AsFg { // 0 is Fg
 | ||||||
|  | 		// return fmt.Sprintf(TplFg256, c[0])
 | ||||||
|  | 		return Fg256Pfx + strconv.Itoa(int(c[0])) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if c[1] == AsBg { // 1 is Bg
 | ||||||
|  | 		// return fmt.Sprintf(TplBg256, c[0])
 | ||||||
|  | 		return Bg256Pfx + strconv.Itoa(int(c[0])) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return "" // empty
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // IsFg color
 | ||||||
|  | func (c Color256) IsFg() bool { | ||||||
|  | 	return c[1] == AsFg | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ToFg 256 color
 | ||||||
|  | func (c Color256) ToFg() Color256 { | ||||||
|  | 	c[1] = AsFg | ||||||
|  | 	return c | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // IsBg color
 | ||||||
|  | func (c Color256) IsBg() bool { | ||||||
|  | 	return c[1] == AsBg | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ToBg 256 color
 | ||||||
|  | func (c Color256) ToBg() Color256 { | ||||||
|  | 	c[1] = AsBg | ||||||
|  | 	return c | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // IsEmpty value
 | ||||||
|  | func (c Color256) IsEmpty() bool { | ||||||
|  | 	return c[1] > 1 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /************************************************************* | ||||||
|  |  * 8bit(256) Style | ||||||
|  |  *************************************************************/ | ||||||
|  | 
 | ||||||
|  | // Style256 definition
 | ||||||
|  | //
 | ||||||
|  | // 前/背景色
 | ||||||
|  | // 都是由两位uint8组成, 第一位是色彩值;
 | ||||||
|  | // 第二位与 Bit8Color 不一样的是,在这里表示是否设置了值 0 未设置 !=0 已设置
 | ||||||
|  | type Style256 struct { | ||||||
|  | 	// p Printer
 | ||||||
|  | 
 | ||||||
|  | 	// Name of the style
 | ||||||
|  | 	Name string | ||||||
|  | 	// color options of the style
 | ||||||
|  | 	opts Opts | ||||||
|  | 	// fg and bg color
 | ||||||
|  | 	fg, bg Color256 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // S256 create a color256 style
 | ||||||
|  | // Usage:
 | ||||||
|  | // 	s := color.S256()
 | ||||||
|  | // 	s := color.S256(132) // fg
 | ||||||
|  | // 	s := color.S256(132, 203) // fg and bg
 | ||||||
|  | func S256(fgAndBg ...uint8) *Style256 { | ||||||
|  | 	s := &Style256{} | ||||||
|  | 	vl := len(fgAndBg) | ||||||
|  | 	if vl > 0 { // with fg
 | ||||||
|  | 		s.fg = Color256{fgAndBg[0], 1} | ||||||
|  | 
 | ||||||
|  | 		if vl > 1 { // and with bg
 | ||||||
|  | 			s.bg = Color256{fgAndBg[1], 1} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return s | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Set fg and bg color value, can also with color options
 | ||||||
|  | func (s *Style256) Set(fgVal, bgVal uint8, opts ...Color) *Style256 { | ||||||
|  | 	s.fg = Color256{fgVal, 1} | ||||||
|  | 	s.bg = Color256{bgVal, 1} | ||||||
|  | 	s.opts.Add(opts...) | ||||||
|  | 	return s | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // SetBg set bg color value
 | ||||||
|  | func (s *Style256) SetBg(bgVal uint8) *Style256 { | ||||||
|  | 	s.bg = Color256{bgVal, 1} | ||||||
|  | 	return s | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // SetFg set fg color value
 | ||||||
|  | func (s *Style256) SetFg(fgVal uint8) *Style256 { | ||||||
|  | 	s.fg = Color256{fgVal, 1} | ||||||
|  | 	return s | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // SetOpts set options
 | ||||||
|  | func (s *Style256) SetOpts(opts Opts) *Style256 { | ||||||
|  | 	s.opts = opts | ||||||
|  | 	return s | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // AddOpts add options
 | ||||||
|  | func (s *Style256) AddOpts(opts ...Color) *Style256 { | ||||||
|  | 	s.opts.Add(opts...) | ||||||
|  | 	return s | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Print message
 | ||||||
|  | func (s *Style256) Print(a ...interface{}) { | ||||||
|  | 	doPrintV2(s.String(), fmt.Sprint(a...)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Printf format and print message
 | ||||||
|  | func (s *Style256) Printf(format string, a ...interface{}) { | ||||||
|  | 	doPrintV2(s.String(), fmt.Sprintf(format, a...)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Println print message with newline
 | ||||||
|  | func (s *Style256) Println(a ...interface{}) { | ||||||
|  | 	doPrintlnV2(s.String(), a) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Sprint returns rendered message
 | ||||||
|  | func (s *Style256) Sprint(a ...interface{}) string { | ||||||
|  | 	return RenderCode(s.Code(), a...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Sprintf returns format and rendered message
 | ||||||
|  | func (s *Style256) Sprintf(format string, a ...interface{}) string { | ||||||
|  | 	return RenderString(s.Code(), fmt.Sprintf(format, a...)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Code convert to color code string
 | ||||||
|  | func (s *Style256) Code() string { | ||||||
|  | 	return s.String() | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // String convert to color code string
 | ||||||
|  | func (s *Style256) String() string { | ||||||
|  | 	var ss []string | ||||||
|  | 	if s.fg[1] > 0 { | ||||||
|  | 		ss = append(ss, fmt.Sprintf(TplFg256, s.fg[0])) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if s.bg[1] > 0 { | ||||||
|  | 		ss = append(ss, fmt.Sprintf(TplBg256, s.bg[0])) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if s.opts.IsValid() { | ||||||
|  | 		ss = append(ss, s.opts.String()) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return strings.Join(ss, ";") | ||||||
|  | } | ||||||
							
								
								
									
										391
									
								
								vendor/github.com/gookit/color/color_rgb.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										391
									
								
								vendor/github.com/gookit/color/color_rgb.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,391 @@ | |||||||
|  | package color | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  | 	"strconv" | ||||||
|  | 	"strings" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // 24 bit RGB color
 | ||||||
|  | // RGB:
 | ||||||
|  | // 	R 0-255 G 0-255 B 0-255
 | ||||||
|  | // 	R 00-FF G 00-FF B 00-FF (16进制)
 | ||||||
|  | //
 | ||||||
|  | // Format:
 | ||||||
|  | // 	ESC[ … 38;2;<r>;<g>;<b> … m // Select RGB foreground color
 | ||||||
|  | // 	ESC[ … 48;2;<r>;<g>;<b> … m // Choose RGB background color
 | ||||||
|  | //
 | ||||||
|  | // links:
 | ||||||
|  | // 	https://zh.wikipedia.org/wiki/ANSI%E8%BD%AC%E4%B9%89%E5%BA%8F%E5%88%97#24位
 | ||||||
|  | //
 | ||||||
|  | // example:
 | ||||||
|  | // 	fg: \x1b[38;2;30;144;255mMESSAGE\x1b[0m
 | ||||||
|  | // 	bg: \x1b[48;2;30;144;255mMESSAGE\x1b[0m
 | ||||||
|  | // 	both: \x1b[38;2;233;90;203;48;2;30;144;255mMESSAGE\x1b[0m
 | ||||||
|  | const ( | ||||||
|  | 	TplFgRGB = "38;2;%d;%d;%d" | ||||||
|  | 	TplBgRGB = "48;2;%d;%d;%d" | ||||||
|  | 	FgRGBPfx = "38;2;" | ||||||
|  | 	BgRGBPfx = "48;2;" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // mark color is fg or bg.
 | ||||||
|  | const ( | ||||||
|  | 	AsFg uint8 = iota | ||||||
|  | 	AsBg | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // values from https://github.com/go-terminfo/terminfo
 | ||||||
|  | // var (
 | ||||||
|  | // RgbaBlack    = image_color.RGBA{0, 0, 0, 255}
 | ||||||
|  | // Red       = color.RGBA{205, 0, 0, 255}
 | ||||||
|  | // Green     = color.RGBA{0, 205, 0, 255}
 | ||||||
|  | // Orange    = color.RGBA{205, 205, 0, 255}
 | ||||||
|  | // Blue      = color.RGBA{0, 0, 238, 255}
 | ||||||
|  | // Magenta   = color.RGBA{205, 0, 205, 255}
 | ||||||
|  | // Cyan      = color.RGBA{0, 205, 205, 255}
 | ||||||
|  | // LightGrey = color.RGBA{229, 229, 229, 255}
 | ||||||
|  | //
 | ||||||
|  | // DarkGrey     = color.RGBA{127, 127, 127, 255}
 | ||||||
|  | // LightRed     = color.RGBA{255, 0, 0, 255}
 | ||||||
|  | // LightGreen   = color.RGBA{0, 255, 0, 255}
 | ||||||
|  | // Yellow       = color.RGBA{255, 255, 0, 255}
 | ||||||
|  | // LightBlue    = color.RGBA{92, 92, 255, 255}
 | ||||||
|  | // LightMagenta = color.RGBA{255, 0, 255, 255}
 | ||||||
|  | // LightCyan    = color.RGBA{0, 255, 255, 255}
 | ||||||
|  | // White        = color.RGBA{255, 255, 255, 255}
 | ||||||
|  | // )
 | ||||||
|  | 
 | ||||||
|  | /************************************************************* | ||||||
|  |  * RGB Color(Bit24Color, TrueColor) | ||||||
|  |  *************************************************************/ | ||||||
|  | 
 | ||||||
|  | // RGBColor definition.
 | ||||||
|  | //
 | ||||||
|  | // The first to third digits represent the color value.
 | ||||||
|  | // The last digit represents the foreground(0), background(1), >1 is unset value
 | ||||||
|  | //
 | ||||||
|  | // Usage:
 | ||||||
|  | // 	// 0, 1, 2 is R,G,B.
 | ||||||
|  | // 	// 3rd: Fg=0, Bg=1, >1: unset value
 | ||||||
|  | // 	RGBColor{30,144,255, 0}
 | ||||||
|  | // 	RGBColor{30,144,255, 1}
 | ||||||
|  | //
 | ||||||
|  | // NOTICE: now support RGB color on windows CMD, PowerShell
 | ||||||
|  | type RGBColor [4]uint8 | ||||||
|  | 
 | ||||||
|  | // create a empty RGBColor
 | ||||||
|  | var emptyRGBColor = RGBColor{3: 99} | ||||||
|  | 
 | ||||||
|  | // RGB color create.
 | ||||||
|  | // Usage:
 | ||||||
|  | // 	c := RGB(30,144,255)
 | ||||||
|  | // 	c := RGB(30,144,255, true)
 | ||||||
|  | // 	c.Print("message")
 | ||||||
|  | func RGB(r, g, b uint8, isBg ...bool) RGBColor { | ||||||
|  | 	rgb := RGBColor{r, g, b} | ||||||
|  | 	if len(isBg) > 0 && isBg[0] { | ||||||
|  | 		rgb[3] = AsBg | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return rgb | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Rgb alias of the RGB()
 | ||||||
|  | func Rgb(r, g, b uint8, isBg ...bool) RGBColor { return RGB(r, g, b, isBg...) } | ||||||
|  | 
 | ||||||
|  | // Bit24 alias of the RGB()
 | ||||||
|  | func Bit24(r, g, b uint8, isBg ...bool) RGBColor { return RGB(r, g, b, isBg...) } | ||||||
|  | 
 | ||||||
|  | // RGBFromSlice quick RGBColor from slice
 | ||||||
|  | func RGBFromSlice(rgb []uint8, isBg ...bool) RGBColor { | ||||||
|  | 	return RGB(rgb[0], rgb[1], rgb[2], isBg...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // HEX create RGB color from a HEX color string.
 | ||||||
|  | // Usage:
 | ||||||
|  | // 	c := HEX("ccc") // rgb: [204 204 204]
 | ||||||
|  | // 	c := HEX("aabbcc") // rgb: [170 187 204]
 | ||||||
|  | // 	c := HEX("#aabbcc")
 | ||||||
|  | // 	c := HEX("0xaabbcc")
 | ||||||
|  | // 	c.Print("message")
 | ||||||
|  | func HEX(hex string, isBg ...bool) RGBColor { | ||||||
|  | 	if rgb := HexToRgb(hex); len(rgb) > 0 { | ||||||
|  | 		return RGB(uint8(rgb[0]), uint8(rgb[1]), uint8(rgb[2]), isBg...) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// mark is empty
 | ||||||
|  | 	return emptyRGBColor | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Hex alias of the HEX()
 | ||||||
|  | func Hex(hex string, isBg ...bool) RGBColor { return HEX(hex, isBg...) } | ||||||
|  | 
 | ||||||
|  | // RGBFromString create RGB color from a string.
 | ||||||
|  | // Usage:
 | ||||||
|  | // 	c := RGBFromString("170,187,204")
 | ||||||
|  | // 	c.Print("message")
 | ||||||
|  | func RGBFromString(rgb string, isBg ...bool) RGBColor { | ||||||
|  | 	ss := stringToArr(rgb, ",") | ||||||
|  | 	if len(ss) != 3 { | ||||||
|  | 		return emptyRGBColor | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	var ar [3]int | ||||||
|  | 	for i, val := range ss { | ||||||
|  | 		iv, err := strconv.Atoi(val) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return emptyRGBColor | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		ar[i] = iv | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return RGB(uint8(ar[0]), uint8(ar[1]), uint8(ar[2]), isBg...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Set terminal by rgb/true color code
 | ||||||
|  | func (c RGBColor) Set() error { | ||||||
|  | 	return SetTerminal(c.String()) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Reset terminal. alias of the ResetTerminal()
 | ||||||
|  | func (c RGBColor) Reset() error { | ||||||
|  | 	return ResetTerminal() | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Print print message
 | ||||||
|  | func (c RGBColor) Print(a ...interface{}) { | ||||||
|  | 	doPrintV2(c.String(), fmt.Sprint(a...)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Printf format and print message
 | ||||||
|  | func (c RGBColor) Printf(format string, a ...interface{}) { | ||||||
|  | 	doPrintV2(c.String(), fmt.Sprintf(format, a...)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Println print message with newline
 | ||||||
|  | func (c RGBColor) Println(a ...interface{}) { | ||||||
|  | 	doPrintlnV2(c.String(), a) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Sprint returns rendered message
 | ||||||
|  | func (c RGBColor) Sprint(a ...interface{}) string { | ||||||
|  | 	return RenderCode(c.String(), a...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Sprintf returns format and rendered message
 | ||||||
|  | func (c RGBColor) Sprintf(format string, a ...interface{}) string { | ||||||
|  | 	return RenderString(c.String(), fmt.Sprintf(format, a...)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Values to RGB values
 | ||||||
|  | func (c RGBColor) Values() []int { | ||||||
|  | 	return []int{int(c[0]), int(c[1]), int(c[2])} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Code to color code string without prefix. eg: "204;123;56"
 | ||||||
|  | func (c RGBColor) Code() string { | ||||||
|  | 	return fmt.Sprintf("%d;%d;%d", c[0], c[1], c[2]) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Hex color rgb to hex string. as in "ff0080".
 | ||||||
|  | func (c RGBColor) Hex() string { | ||||||
|  | 	return fmt.Sprintf("%02x%02x%02x", c[0], c[1], c[2]) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // FullCode to color code string with prefix
 | ||||||
|  | func (c RGBColor) FullCode() string { | ||||||
|  | 	return c.String() | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // String to color code string with prefix. eg: "38;2;204;123;56"
 | ||||||
|  | func (c RGBColor) String() string { | ||||||
|  | 	if c[3] == AsFg { | ||||||
|  | 		return fmt.Sprintf(TplFgRGB, c[0], c[1], c[2]) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if c[3] == AsBg { | ||||||
|  | 		return fmt.Sprintf(TplBgRGB, c[0], c[1], c[2]) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// c[3] > 1 is empty
 | ||||||
|  | 	return "" | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // IsEmpty value
 | ||||||
|  | func (c RGBColor) IsEmpty() bool { | ||||||
|  | 	return c[3] > AsBg | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // IsValid value
 | ||||||
|  | // func (c RGBColor) IsValid() bool {
 | ||||||
|  | // 	return c[3] <= AsBg
 | ||||||
|  | // }
 | ||||||
|  | 
 | ||||||
|  | // C256 returns the closest approximate 256 (8 bit) color
 | ||||||
|  | func (c RGBColor) C256() Color256 { | ||||||
|  | 	return C256(RgbTo256(c[0], c[1], c[2]), c[3] == AsBg) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Basic returns the closest approximate 16 (4 bit) color
 | ||||||
|  | func (c RGBColor) Basic() Color { | ||||||
|  | 	// return Color(RgbToAnsi(c[0], c[1], c[2], c[3] == AsBg))
 | ||||||
|  | 	return Color(Rgb2basic(c[0], c[1], c[2], c[3] == AsBg)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Color returns the closest approximate 16 (4 bit) color
 | ||||||
|  | func (c RGBColor) Color() Color { return c.Basic() } | ||||||
|  | 
 | ||||||
|  | // C16 returns the closest approximate 16 (4 bit) color
 | ||||||
|  | func (c RGBColor) C16() Color { return c.Basic() } | ||||||
|  | 
 | ||||||
|  | /************************************************************* | ||||||
|  |  * RGB Style | ||||||
|  |  *************************************************************/ | ||||||
|  | 
 | ||||||
|  | // RGBStyle definition.
 | ||||||
|  | //
 | ||||||
|  | // Foreground/Background color
 | ||||||
|  | // All are composed of 4 digits uint8, the first three digits are the color value;
 | ||||||
|  | // The last bit is different from RGBColor, here it indicates whether the value is set.
 | ||||||
|  | // - 1  Has been set
 | ||||||
|  | // - ^1 Not set
 | ||||||
|  | type RGBStyle struct { | ||||||
|  | 	// Name of the style
 | ||||||
|  | 	Name string | ||||||
|  | 	// color options of the style
 | ||||||
|  | 	opts Opts | ||||||
|  | 	// fg and bg color
 | ||||||
|  | 	fg, bg RGBColor | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // NewRGBStyle create a RGBStyle.
 | ||||||
|  | func NewRGBStyle(fg RGBColor, bg ...RGBColor) *RGBStyle { | ||||||
|  | 	s := &RGBStyle{} | ||||||
|  | 	if len(bg) > 0 { | ||||||
|  | 		s.SetBg(bg[0]) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return s.SetFg(fg) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // HEXStyle create a RGBStyle from HEX color string.
 | ||||||
|  | // Usage:
 | ||||||
|  | // 	s := HEXStyle("aabbcc", "eee")
 | ||||||
|  | // 	s.Print("message")
 | ||||||
|  | func HEXStyle(fg string, bg ...string) *RGBStyle { | ||||||
|  | 	s := &RGBStyle{} | ||||||
|  | 	if len(bg) > 0 { | ||||||
|  | 		s.SetBg(HEX(bg[0])) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if len(fg) > 0 { | ||||||
|  | 		s.SetFg(HEX(fg)) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return s | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // RGBStyleFromString create a RGBStyle from color value string.
 | ||||||
|  | // Usage:
 | ||||||
|  | // 	s := RGBStyleFromString("170,187,204", "70,87,4")
 | ||||||
|  | // 	s.Print("message")
 | ||||||
|  | func RGBStyleFromString(fg string, bg ...string) *RGBStyle { | ||||||
|  | 	s := &RGBStyle{} | ||||||
|  | 	if len(bg) > 0 { | ||||||
|  | 		s.SetBg(RGBFromString(bg[0])) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return s.SetFg(RGBFromString(fg)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Set fg and bg color, can also with color options
 | ||||||
|  | func (s *RGBStyle) Set(fg, bg RGBColor, opts ...Color) *RGBStyle { | ||||||
|  | 	return s.SetFg(fg).SetBg(bg).SetOpts(opts) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // SetFg set fg color
 | ||||||
|  | func (s *RGBStyle) SetFg(fg RGBColor) *RGBStyle { | ||||||
|  | 	fg[3] = 1 // add fixed value, mark is valid
 | ||||||
|  | 	s.fg = fg | ||||||
|  | 	return s | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // SetBg set bg color
 | ||||||
|  | func (s *RGBStyle) SetBg(bg RGBColor) *RGBStyle { | ||||||
|  | 	bg[3] = 1 // add fixed value, mark is valid
 | ||||||
|  | 	s.bg = bg | ||||||
|  | 	return s | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // SetOpts set color options
 | ||||||
|  | func (s *RGBStyle) SetOpts(opts Opts) *RGBStyle { | ||||||
|  | 	s.opts = opts | ||||||
|  | 	return s | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // AddOpts add options
 | ||||||
|  | func (s *RGBStyle) AddOpts(opts ...Color) *RGBStyle { | ||||||
|  | 	s.opts.Add(opts...) | ||||||
|  | 	return s | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Print print message
 | ||||||
|  | func (s *RGBStyle) Print(a ...interface{}) { | ||||||
|  | 	doPrintV2(s.String(), fmt.Sprint(a...)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Printf format and print message
 | ||||||
|  | func (s *RGBStyle) Printf(format string, a ...interface{}) { | ||||||
|  | 	doPrintV2(s.String(), fmt.Sprintf(format, a...)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Println print message with newline
 | ||||||
|  | func (s *RGBStyle) Println(a ...interface{}) { | ||||||
|  | 	doPrintlnV2(s.String(), a) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Sprint returns rendered message
 | ||||||
|  | func (s *RGBStyle) Sprint(a ...interface{}) string { | ||||||
|  | 	return RenderCode(s.String(), a...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Sprintf returns format and rendered message
 | ||||||
|  | func (s *RGBStyle) Sprintf(format string, a ...interface{}) string { | ||||||
|  | 	return RenderString(s.String(), fmt.Sprintf(format, a...)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Code convert to color code string
 | ||||||
|  | func (s *RGBStyle) Code() string { | ||||||
|  | 	return s.String() | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // FullCode convert to color code string
 | ||||||
|  | func (s *RGBStyle) FullCode() string { | ||||||
|  | 	return s.String() | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // String convert to color code string
 | ||||||
|  | func (s *RGBStyle) String() string { | ||||||
|  | 	var ss []string | ||||||
|  | 	// last value ensure is enable.
 | ||||||
|  | 	if s.fg[3] == 1 { | ||||||
|  | 		ss = append(ss, fmt.Sprintf(TplFgRGB, s.fg[0], s.fg[1], s.fg[2])) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if s.bg[3] == 1 { | ||||||
|  | 		ss = append(ss, fmt.Sprintf(TplBgRGB, s.bg[0], s.bg[1], s.bg[2])) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if s.opts.IsValid() { | ||||||
|  | 		ss = append(ss, s.opts.String()) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return strings.Join(ss, ";") | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // IsEmpty style
 | ||||||
|  | func (s *RGBStyle) IsEmpty() bool { | ||||||
|  | 	return s.fg[3] != 1 && s.bg[3] != 1 | ||||||
|  | } | ||||||
							
								
								
									
										427
									
								
								vendor/github.com/gookit/color/color_tag.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										427
									
								
								vendor/github.com/gookit/color/color_tag.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,427 @@ | |||||||
|  | package color | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  | 	"regexp" | ||||||
|  | 	"strings" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // output colored text like use html tag. (not support windows cmd)
 | ||||||
|  | const ( | ||||||
|  | 	// MatchExpr regex to match color tags
 | ||||||
|  | 	//
 | ||||||
|  | 	// Notice: golang 不支持反向引用. 即不支持使用 \1 引用第一个匹配 ([a-z=;]+)
 | ||||||
|  | 	// MatchExpr = `<([a-z=;]+)>(.*?)<\/\1>`
 | ||||||
|  | 	// 所以调整一下 统一使用 `</>` 来结束标签,例如 "<info>some text</>"
 | ||||||
|  | 	//
 | ||||||
|  | 	// allow custom attrs, eg: "<fg=white;bg=blue;op=bold>content</>"
 | ||||||
|  | 	// (?s:...) s - 让 "." 匹配换行
 | ||||||
|  | 	MatchExpr = `<([0-9a-zA-Z_=,;]+)>(?s:(.*?))<\/>` | ||||||
|  | 
 | ||||||
|  | 	// AttrExpr regex to match custom color attributes
 | ||||||
|  | 	// eg: "<fg=white;bg=blue;op=bold>content</>"
 | ||||||
|  | 	AttrExpr = `(fg|bg|op)[\s]*=[\s]*([0-9a-zA-Z,]+);?` | ||||||
|  | 
 | ||||||
|  | 	// StripExpr regex used for removing color tags
 | ||||||
|  | 	// StripExpr = `<[\/]?[a-zA-Z=;]+>`
 | ||||||
|  | 	// 随着上面的做一些调整
 | ||||||
|  | 	StripExpr = `<[\/]?[0-9a-zA-Z_=,;]*>` | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | var ( | ||||||
|  | 	attrRegex  = regexp.MustCompile(AttrExpr) | ||||||
|  | 	matchRegex = regexp.MustCompile(MatchExpr) | ||||||
|  | 	stripRegex = regexp.MustCompile(StripExpr) | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | /************************************************************* | ||||||
|  |  * internal defined color tags | ||||||
|  |  *************************************************************/ | ||||||
|  | 
 | ||||||
|  | // There are internal defined color tags
 | ||||||
|  | // Usage: <tag>content text</>
 | ||||||
|  | // @notice 加 0 在前面是为了防止之前的影响到现在的设置
 | ||||||
|  | var colorTags = map[string]string{ | ||||||
|  | 	// basic tags
 | ||||||
|  | 	"red":      "0;31", | ||||||
|  | 	"red1":     "1;31", // with bold
 | ||||||
|  | 	"redB":     "1;31", | ||||||
|  | 	"red_b":    "1;31", | ||||||
|  | 	"blue":     "0;34", | ||||||
|  | 	"blue1":    "1;34", // with bold
 | ||||||
|  | 	"blueB":    "1;34", | ||||||
|  | 	"blue_b":   "1;34", | ||||||
|  | 	"cyan":     "0;36", | ||||||
|  | 	"cyan1":    "1;36", // with bold
 | ||||||
|  | 	"cyanB":    "1;36", | ||||||
|  | 	"cyan_b":   "1;36", | ||||||
|  | 	"green":    "0;32", | ||||||
|  | 	"green1":   "1;32", // with bold
 | ||||||
|  | 	"greenB":   "1;32", | ||||||
|  | 	"green_b":  "1;32", | ||||||
|  | 	"black":    "0;30", | ||||||
|  | 	"white":    "1;37", | ||||||
|  | 	"default":  "0;39", // no color
 | ||||||
|  | 	"normal":   "0;39", // no color
 | ||||||
|  | 	"brown":    "0;33", // #A52A2A
 | ||||||
|  | 	"yellow":   "0;33", | ||||||
|  | 	"ylw0":     "0;33", | ||||||
|  | 	"yellowB":  "1;33", // with bold
 | ||||||
|  | 	"ylw1":     "1;33", | ||||||
|  | 	"ylwB":     "1;33", | ||||||
|  | 	"magenta":  "0;35", | ||||||
|  | 	"mga":      "0;35", // short name
 | ||||||
|  | 	"magentaB": "1;35", // with bold
 | ||||||
|  | 	"mgb":      "1;35", | ||||||
|  | 	"mgaB":     "1;35", | ||||||
|  | 
 | ||||||
|  | 	// light/hi tags
 | ||||||
|  | 
 | ||||||
|  | 	"gray":          "0;90", | ||||||
|  | 	"darkGray":      "0;90", | ||||||
|  | 	"dark_gray":     "0;90", | ||||||
|  | 	"lightYellow":   "0;93", | ||||||
|  | 	"light_yellow":  "0;93", | ||||||
|  | 	"hiYellow":      "0;93", | ||||||
|  | 	"hi_yellow":     "0;93", | ||||||
|  | 	"hiYellowB":     "1;93", // with bold
 | ||||||
|  | 	"hi_yellow_b":   "1;93", | ||||||
|  | 	"lightMagenta":  "0;95", | ||||||
|  | 	"light_magenta": "0;95", | ||||||
|  | 	"hiMagenta":     "0;95", | ||||||
|  | 	"hi_magenta":    "0;95", | ||||||
|  | 	"lightMagentaB": "1;95", // with bold
 | ||||||
|  | 	"hiMagentaB":    "1;95", // with bold
 | ||||||
|  | 	"hi_magenta_b":  "1;95", | ||||||
|  | 	"lightRed":      "0;91", | ||||||
|  | 	"light_red":     "0;91", | ||||||
|  | 	"hiRed":         "0;91", | ||||||
|  | 	"hi_red":        "0;91", | ||||||
|  | 	"lightRedB":     "1;91", // with bold
 | ||||||
|  | 	"light_red_b":   "1;91", | ||||||
|  | 	"hi_red_b":      "1;91", | ||||||
|  | 	"lightGreen":    "0;92", | ||||||
|  | 	"light_green":   "0;92", | ||||||
|  | 	"hiGreen":       "0;92", | ||||||
|  | 	"hi_green":      "0;92", | ||||||
|  | 	"lightGreenB":   "1;92", | ||||||
|  | 	"light_green_b": "1;92", | ||||||
|  | 	"hi_green_b":    "1;92", | ||||||
|  | 	"lightBlue":     "0;94", | ||||||
|  | 	"light_blue":    "0;94", | ||||||
|  | 	"hiBlue":        "0;94", | ||||||
|  | 	"hi_blue":       "0;94", | ||||||
|  | 	"lightBlueB":    "1;94", | ||||||
|  | 	"light_blue_b":  "1;94", | ||||||
|  | 	"hi_blue_b":     "1;94", | ||||||
|  | 	"lightCyan":     "0;96", | ||||||
|  | 	"light_cyan":    "0;96", | ||||||
|  | 	"hiCyan":        "0;96", | ||||||
|  | 	"hi_cyan":       "0;96", | ||||||
|  | 	"lightCyanB":    "1;96", | ||||||
|  | 	"light_cyan_b":  "1;96", | ||||||
|  | 	"hi_cyan_b":     "1;96", | ||||||
|  | 	"lightWhite":    "0;97;40", | ||||||
|  | 	"light_white":   "0;97;40", | ||||||
|  | 
 | ||||||
|  | 	// option
 | ||||||
|  | 	"bold":       "1", | ||||||
|  | 	"b":          "1", | ||||||
|  | 	"underscore": "4", | ||||||
|  | 	"us":         "4", // short name for 'underscore'
 | ||||||
|  | 	"reverse":    "7", | ||||||
|  | 
 | ||||||
|  | 	// alert tags, like bootstrap's alert
 | ||||||
|  | 	"suc":     "1;32", // same "green" and "bold"
 | ||||||
|  | 	"success": "1;32", | ||||||
|  | 	"info":    "0;32", // same "green",
 | ||||||
|  | 	"comment": "0;33", // same "brown"
 | ||||||
|  | 	"note":    "36;1", | ||||||
|  | 	"notice":  "36;4", | ||||||
|  | 	"warn":    "0;1;33", | ||||||
|  | 	"warning": "0;30;43", | ||||||
|  | 	"primary": "0;34", | ||||||
|  | 	"danger":  "1;31", // same "red" but add bold
 | ||||||
|  | 	"err":     "97;41", | ||||||
|  | 	"error":   "97;41", // fg light white; bg red
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /************************************************************* | ||||||
|  |  * parse color tags | ||||||
|  |  *************************************************************/ | ||||||
|  | 
 | ||||||
|  | var ( | ||||||
|  | 	tagParser = TagParser{} | ||||||
|  | 	rxNumStr  = regexp.MustCompile("^[0-9]{1,3}$") | ||||||
|  | 	rxHexCode = regexp.MustCompile("^#?([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$") | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // TagParser struct
 | ||||||
|  | type TagParser struct { | ||||||
|  | 	disable bool | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // NewTagParser create
 | ||||||
|  | func NewTagParser() *TagParser { | ||||||
|  | 	return &TagParser{} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // func (tp *TagParser) Disable() *TagParser {
 | ||||||
|  | // 	tp.disable = true
 | ||||||
|  | // 	return tp
 | ||||||
|  | // }
 | ||||||
|  | 
 | ||||||
|  | // ParseByEnv parse given string. will check package setting.
 | ||||||
|  | func (tp *TagParser) ParseByEnv(str string) string { | ||||||
|  | 	// disable handler TAG
 | ||||||
|  | 	if !RenderTag { | ||||||
|  | 		return str | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// disable OR not support color
 | ||||||
|  | 	if !Enable || !SupportColor() { | ||||||
|  | 		return ClearTag(str) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return tp.Parse(str) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Parse parse given string, replace color tag and return rendered string
 | ||||||
|  | func (tp *TagParser) Parse(str string) string { | ||||||
|  | 	// not contains color tag
 | ||||||
|  | 	if !strings.Contains(str, "</>") { | ||||||
|  | 		return str | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// find color tags by regex. str eg: "<fg=white;bg=blue;op=bold>content</>"
 | ||||||
|  | 	matched := matchRegex.FindAllStringSubmatch(str, -1) | ||||||
|  | 
 | ||||||
|  | 	// item: 0 full text 1 tag name 2 tag content
 | ||||||
|  | 	for _, item := range matched { | ||||||
|  | 		full, tag, content := item[0], item[1], item[2] | ||||||
|  | 
 | ||||||
|  | 		// use defined tag name: "<info>content</>" -> tag: "info"
 | ||||||
|  | 		if !strings.ContainsRune(tag, '=') { | ||||||
|  | 			code := colorTags[tag] | ||||||
|  | 			if len(code) > 0 { | ||||||
|  | 				now := RenderString(code, content) | ||||||
|  | 				// old := WrapTag(content, tag) is equals to var 'full'
 | ||||||
|  | 				str = strings.Replace(str, full, now, 1) | ||||||
|  | 			} | ||||||
|  | 			continue | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		// custom color in tag
 | ||||||
|  | 		// - basic: "fg=white;bg=blue;op=bold"
 | ||||||
|  | 		if code := ParseCodeFromAttr(tag); len(code) > 0 { | ||||||
|  | 			now := RenderString(code, content) | ||||||
|  | 			str = strings.Replace(str, full, now, 1) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return str | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // func (tp *TagParser) ParseAttr(attr string) (code string) {
 | ||||||
|  | // 	return
 | ||||||
|  | // }
 | ||||||
|  | 
 | ||||||
|  | // ReplaceTag parse string, replace color tag and return rendered string
 | ||||||
|  | func ReplaceTag(str string) string { | ||||||
|  | 	return tagParser.ParseByEnv(str) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ParseCodeFromAttr parse color attributes.
 | ||||||
|  | //
 | ||||||
|  | // attr format:
 | ||||||
|  | // 	// VALUE please see var: FgColors, BgColors, AllOptions
 | ||||||
|  | // 	"fg=VALUE;bg=VALUE;op=VALUE"
 | ||||||
|  | // 16 color:
 | ||||||
|  | // 	"fg=yellow"
 | ||||||
|  | // 	"bg=red"
 | ||||||
|  | // 	"op=bold,underscore" option is allow multi value
 | ||||||
|  | // 	"fg=white;bg=blue;op=bold"
 | ||||||
|  | // 	"fg=white;op=bold,underscore"
 | ||||||
|  | // 256 color:
 | ||||||
|  | //	"fg=167"
 | ||||||
|  | //	"fg=167;bg=23"
 | ||||||
|  | //	"fg=167;bg=23;op=bold"
 | ||||||
|  | // true color:
 | ||||||
|  | // 	// hex
 | ||||||
|  | //	"fg=fc1cac"
 | ||||||
|  | //	"fg=fc1cac;bg=c2c3c4"
 | ||||||
|  | // 	// r,g,b
 | ||||||
|  | //	"fg=23,45,214"
 | ||||||
|  | //	"fg=23,45,214;bg=109,99,88"
 | ||||||
|  | func ParseCodeFromAttr(attr string) (code string) { | ||||||
|  | 	if !strings.ContainsRune(attr, '=') { | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	attr = strings.Trim(attr, ";=,") | ||||||
|  | 	if len(attr) == 0 { | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	var codes []string | ||||||
|  | 	matched := attrRegex.FindAllStringSubmatch(attr, -1) | ||||||
|  | 
 | ||||||
|  | 	for _, item := range matched { | ||||||
|  | 		pos, val := item[1], item[2] | ||||||
|  | 		switch pos { | ||||||
|  | 		case "fg": | ||||||
|  | 			if c, ok := FgColors[val]; ok { // basic
 | ||||||
|  | 				codes = append(codes, c.String()) | ||||||
|  | 			} else if c, ok := ExFgColors[val]; ok { // extra
 | ||||||
|  | 				codes = append(codes, c.String()) | ||||||
|  | 			} else if code := rgbHex256toCode(val, false); code != "" { | ||||||
|  | 				codes = append(codes, code) | ||||||
|  | 			} | ||||||
|  | 		case "bg": | ||||||
|  | 			if c, ok := BgColors[val]; ok { // basic bg
 | ||||||
|  | 				codes = append(codes, c.String()) | ||||||
|  | 			} else if c, ok := ExBgColors[val]; ok { // extra bg
 | ||||||
|  | 				codes = append(codes, c.String()) | ||||||
|  | 			} else if code := rgbHex256toCode(val, true); code != "" { | ||||||
|  | 				codes = append(codes, code) | ||||||
|  | 			} | ||||||
|  | 		case "op": // options allow multi value
 | ||||||
|  | 			if strings.Contains(val, ",") { | ||||||
|  | 				ns := strings.Split(val, ",") | ||||||
|  | 				for _, n := range ns { | ||||||
|  | 					if c, ok := AllOptions[n]; ok { | ||||||
|  | 						codes = append(codes, c.String()) | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  | 			} else if c, ok := AllOptions[val]; ok { | ||||||
|  | 				codes = append(codes, c.String()) | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return strings.Join(codes, ";") | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func rgbHex256toCode(val string, isBg bool) (code string) { | ||||||
|  | 	if len(val) == 6 && rxHexCode.MatchString(val) { // hex: "fc1cac"
 | ||||||
|  | 		code = HEX(val, isBg).String() | ||||||
|  | 	} else if strings.ContainsRune(val, ',') { // rgb: "231,178,161"
 | ||||||
|  | 		code = strings.Replace(val, ",", ";", -1) | ||||||
|  | 		if isBg { | ||||||
|  | 			code = BgRGBPfx + code | ||||||
|  | 		} else { | ||||||
|  | 			code = FgRGBPfx + code | ||||||
|  | 		} | ||||||
|  | 	} else if len(val) < 4 && rxNumStr.MatchString(val) { // 256 code
 | ||||||
|  | 		if isBg { | ||||||
|  | 			code = Bg256Pfx + val | ||||||
|  | 		} else { | ||||||
|  | 			code = Fg256Pfx + val | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ClearTag clear all tag for a string
 | ||||||
|  | func ClearTag(s string) string { | ||||||
|  | 	if !strings.Contains(s, "</>") { | ||||||
|  | 		return s | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return stripRegex.ReplaceAllString(s, "") | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /************************************************************* | ||||||
|  |  * helper methods | ||||||
|  |  *************************************************************/ | ||||||
|  | 
 | ||||||
|  | // GetTagCode get color code by tag name
 | ||||||
|  | func GetTagCode(name string) string { | ||||||
|  | 	return colorTags[name] | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ApplyTag for messages
 | ||||||
|  | func ApplyTag(tag string, a ...interface{}) string { | ||||||
|  | 	return RenderCode(GetTagCode(tag), a...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WrapTag wrap a tag for a string "<tag>content</>"
 | ||||||
|  | func WrapTag(s string, tag string) string { | ||||||
|  | 	if s == "" || tag == "" { | ||||||
|  | 		return s | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return fmt.Sprintf("<%s>%s</>", tag, s) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // GetColorTags get all internal color tags
 | ||||||
|  | func GetColorTags() map[string]string { | ||||||
|  | 	return colorTags | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // IsDefinedTag is defined tag name
 | ||||||
|  | func IsDefinedTag(name string) bool { | ||||||
|  | 	_, ok := colorTags[name] | ||||||
|  | 	return ok | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /************************************************************* | ||||||
|  |  * Tag extra | ||||||
|  |  *************************************************************/ | ||||||
|  | 
 | ||||||
|  | // Tag value is a defined style name
 | ||||||
|  | // Usage:
 | ||||||
|  | // 	Tag("info").Println("message")
 | ||||||
|  | type Tag string | ||||||
|  | 
 | ||||||
|  | // Print messages
 | ||||||
|  | func (tg Tag) Print(a ...interface{}) { | ||||||
|  | 	name := string(tg) | ||||||
|  | 	str := fmt.Sprint(a...) | ||||||
|  | 
 | ||||||
|  | 	if stl := GetStyle(name); !stl.IsEmpty() { | ||||||
|  | 		stl.Print(str) | ||||||
|  | 	} else { | ||||||
|  | 		doPrintV2(GetTagCode(name), str) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Printf format and print messages
 | ||||||
|  | func (tg Tag) Printf(format string, a ...interface{}) { | ||||||
|  | 	name := string(tg) | ||||||
|  | 	str := fmt.Sprintf(format, a...) | ||||||
|  | 
 | ||||||
|  | 	if stl := GetStyle(name); !stl.IsEmpty() { | ||||||
|  | 		stl.Print(str) | ||||||
|  | 	} else { | ||||||
|  | 		doPrintV2(GetTagCode(name), str) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Println messages line
 | ||||||
|  | func (tg Tag) Println(a ...interface{}) { | ||||||
|  | 	name := string(tg) | ||||||
|  | 	if stl := GetStyle(name); !stl.IsEmpty() { | ||||||
|  | 		stl.Println(a...) | ||||||
|  | 	} else { | ||||||
|  | 		doPrintlnV2(GetTagCode(name), a) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Sprint render messages
 | ||||||
|  | func (tg Tag) Sprint(a ...interface{}) string { | ||||||
|  | 	name := string(tg) | ||||||
|  | 	// if stl := GetStyle(name); !stl.IsEmpty() {
 | ||||||
|  | 	// 	return stl.Render(args...)
 | ||||||
|  | 	// }
 | ||||||
|  | 
 | ||||||
|  | 	return RenderCode(GetTagCode(name), a...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Sprintf format and render messages
 | ||||||
|  | func (tg Tag) Sprintf(format string, a ...interface{}) string { | ||||||
|  | 	tag := string(tg) | ||||||
|  | 	str := fmt.Sprintf(format, a...) | ||||||
|  | 
 | ||||||
|  | 	return RenderString(GetTagCode(tag), str) | ||||||
|  | } | ||||||
							
								
								
									
										593
									
								
								vendor/github.com/gookit/color/convert.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										593
									
								
								vendor/github.com/gookit/color/convert.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,593 @@ | |||||||
|  | package color | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  | 	"math" | ||||||
|  | 	"strconv" | ||||||
|  | 	"strings" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | var ( | ||||||
|  | 	// ---------- basic(16) <=> 256 color convert ----------
 | ||||||
|  | 	basicTo256Map = map[uint8]uint8{ | ||||||
|  | 		30: 0,   // black 	000000
 | ||||||
|  | 		31: 160, // red 	c51e14
 | ||||||
|  | 		32: 34,  // green 	1dc121
 | ||||||
|  | 		33: 184, // yellow 	c7c329
 | ||||||
|  | 		34: 20,  // blue 	0a2fc4
 | ||||||
|  | 		35: 170, // magenta c839c5
 | ||||||
|  | 		36: 44,  // cyan 	20c5c6
 | ||||||
|  | 		37: 188, // white 	c7c7c7
 | ||||||
|  | 		90: 59,  // lightBlack 		686868
 | ||||||
|  | 		91: 203, // lightRed 		fd6f6b
 | ||||||
|  | 		92: 83,  // lightGreen 		67f86f
 | ||||||
|  | 		93: 227, // lightYellow 	fffa72
 | ||||||
|  | 		94: 69,  // lightBlue 		6a76fb
 | ||||||
|  | 		95: 213, // lightMagenta 	fd7cfc
 | ||||||
|  | 		96: 87,  // lightCyan 		68fdfe
 | ||||||
|  | 		97: 15,  // lightWhite 		ffffff
 | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// ---------- basic(16) <=> RGB color convert ----------
 | ||||||
|  | 	// refer from Hyper app
 | ||||||
|  | 	basic2hexMap = map[uint8]string{ | ||||||
|  | 		30: "000000", // black
 | ||||||
|  | 		31: "c51e14", // red
 | ||||||
|  | 		32: "1dc121", // green
 | ||||||
|  | 		33: "c7c329", // yellow
 | ||||||
|  | 		34: "0a2fc4", // blue
 | ||||||
|  | 		35: "c839c5", // magenta
 | ||||||
|  | 		36: "20c5c6", // cyan
 | ||||||
|  | 		37: "c7c7c7", // white
 | ||||||
|  | 		90: "686868", // lightBlack/darkGray
 | ||||||
|  | 		91: "fd6f6b", // lightRed
 | ||||||
|  | 		92: "67f86f", // lightGreen
 | ||||||
|  | 		93: "fffa72", // lightYellow
 | ||||||
|  | 		94: "6a76fb", // lightBlue
 | ||||||
|  | 		95: "fd7cfc", // lightMagenta
 | ||||||
|  | 		96: "68fdfe", // lightCyan
 | ||||||
|  | 		97: "ffffff", // lightWhite
 | ||||||
|  | 	} | ||||||
|  | 	// will convert data from basic2hexMap
 | ||||||
|  | 	hex2basicMap = initHex2basicMap() | ||||||
|  | 
 | ||||||
|  | 	// ---------- 256 <=> RGB color convert ----------
 | ||||||
|  | 	// adapted from https://gist.github.com/MicahElliott/719710
 | ||||||
|  | 
 | ||||||
|  | 	c256ToHexMap = init256ToHexMap() | ||||||
|  | 
 | ||||||
|  | 	// rgb to 256 color look-up table
 | ||||||
|  | 	// RGB hex => 256 code
 | ||||||
|  | 	hexTo256Table = map[string]uint8{ | ||||||
|  | 		// Primary 3-bit (8 colors). Unique representation!
 | ||||||
|  | 		"000000": 0, | ||||||
|  | 		"800000": 1, | ||||||
|  | 		"008000": 2, | ||||||
|  | 		"808000": 3, | ||||||
|  | 		"000080": 4, | ||||||
|  | 		"800080": 5, | ||||||
|  | 		"008080": 6, | ||||||
|  | 		"c0c0c0": 7, | ||||||
|  | 
 | ||||||
|  | 		// Equivalent "bright" versions of original 8 colors.
 | ||||||
|  | 		"808080": 8, | ||||||
|  | 		"ff0000": 9, | ||||||
|  | 		"00ff00": 10, | ||||||
|  | 		"ffff00": 11, | ||||||
|  | 		"0000ff": 12, | ||||||
|  | 		"ff00ff": 13, | ||||||
|  | 		"00ffff": 14, | ||||||
|  | 		"ffffff": 15, | ||||||
|  | 
 | ||||||
|  | 		// values commented out below are duplicates from the prior sections
 | ||||||
|  | 
 | ||||||
|  | 		// Strictly ascending.
 | ||||||
|  | 		// "000000": 16,
 | ||||||
|  | 		"000001": 16, // up: avoid key conflicts, value + 1
 | ||||||
|  | 		"00005f": 17, | ||||||
|  | 		"000087": 18, | ||||||
|  | 		"0000af": 19, | ||||||
|  | 		"0000d7": 20, | ||||||
|  | 		// "0000ff": 21,
 | ||||||
|  | 		"0000fe": 21, // up: avoid key conflicts, value - 1
 | ||||||
|  | 		"005f00": 22, | ||||||
|  | 		"005f5f": 23, | ||||||
|  | 		"005f87": 24, | ||||||
|  | 		"005faf": 25, | ||||||
|  | 		"005fd7": 26, | ||||||
|  | 		"005fff": 27, | ||||||
|  | 		"008700": 28, | ||||||
|  | 		"00875f": 29, | ||||||
|  | 		"008787": 30, | ||||||
|  | 		"0087af": 31, | ||||||
|  | 		"0087d7": 32, | ||||||
|  | 		"0087ff": 33, | ||||||
|  | 		"00af00": 34, | ||||||
|  | 		"00af5f": 35, | ||||||
|  | 		"00af87": 36, | ||||||
|  | 		"00afaf": 37, | ||||||
|  | 		"00afd7": 38, | ||||||
|  | 		"00afff": 39, | ||||||
|  | 		"00d700": 40, | ||||||
|  | 		"00d75f": 41, | ||||||
|  | 		"00d787": 42, | ||||||
|  | 		"00d7af": 43, | ||||||
|  | 		"00d7d7": 44, | ||||||
|  | 		"00d7ff": 45, | ||||||
|  | 		// "00ff00": 46,
 | ||||||
|  | 		"00ff01": 46, // up: avoid key conflicts, value + 1
 | ||||||
|  | 		"00ff5f": 47, | ||||||
|  | 		"00ff87": 48, | ||||||
|  | 		"00ffaf": 49, | ||||||
|  | 		"00ffd7": 50, | ||||||
|  | 		// "00ffff": 51,
 | ||||||
|  | 		"00fffe": 51, // up: avoid key conflicts, value - 1
 | ||||||
|  | 		"5f0000": 52, | ||||||
|  | 		"5f005f": 53, | ||||||
|  | 		"5f0087": 54, | ||||||
|  | 		"5f00af": 55, | ||||||
|  | 		"5f00d7": 56, | ||||||
|  | 		"5f00ff": 57, | ||||||
|  | 		"5f5f00": 58, | ||||||
|  | 		"5f5f5f": 59, | ||||||
|  | 		"5f5f87": 60, | ||||||
|  | 		"5f5faf": 61, | ||||||
|  | 		"5f5fd7": 62, | ||||||
|  | 		"5f5fff": 63, | ||||||
|  | 		"5f8700": 64, | ||||||
|  | 		"5f875f": 65, | ||||||
|  | 		"5f8787": 66, | ||||||
|  | 		"5f87af": 67, | ||||||
|  | 		"5f87d7": 68, | ||||||
|  | 		"5f87ff": 69, | ||||||
|  | 		"5faf00": 70, | ||||||
|  | 		"5faf5f": 71, | ||||||
|  | 		"5faf87": 72, | ||||||
|  | 		"5fafaf": 73, | ||||||
|  | 		"5fafd7": 74, | ||||||
|  | 		"5fafff": 75, | ||||||
|  | 		"5fd700": 76, | ||||||
|  | 		"5fd75f": 77, | ||||||
|  | 		"5fd787": 78, | ||||||
|  | 		"5fd7af": 79, | ||||||
|  | 		"5fd7d7": 80, | ||||||
|  | 		"5fd7ff": 81, | ||||||
|  | 		"5fff00": 82, | ||||||
|  | 		"5fff5f": 83, | ||||||
|  | 		"5fff87": 84, | ||||||
|  | 		"5fffaf": 85, | ||||||
|  | 		"5fffd7": 86, | ||||||
|  | 		"5fffff": 87, | ||||||
|  | 		"870000": 88, | ||||||
|  | 		"87005f": 89, | ||||||
|  | 		"870087": 90, | ||||||
|  | 		"8700af": 91, | ||||||
|  | 		"8700d7": 92, | ||||||
|  | 		"8700ff": 93, | ||||||
|  | 		"875f00": 94, | ||||||
|  | 		"875f5f": 95, | ||||||
|  | 		"875f87": 96, | ||||||
|  | 		"875faf": 97, | ||||||
|  | 		"875fd7": 98, | ||||||
|  | 		"875fff": 99, | ||||||
|  | 		"878700": 100, | ||||||
|  | 		"87875f": 101, | ||||||
|  | 		"878787": 102, | ||||||
|  | 		"8787af": 103, | ||||||
|  | 		"8787d7": 104, | ||||||
|  | 		"8787ff": 105, | ||||||
|  | 		"87af00": 106, | ||||||
|  | 		"87af5f": 107, | ||||||
|  | 		"87af87": 108, | ||||||
|  | 		"87afaf": 109, | ||||||
|  | 		"87afd7": 110, | ||||||
|  | 		"87afff": 111, | ||||||
|  | 		"87d700": 112, | ||||||
|  | 		"87d75f": 113, | ||||||
|  | 		"87d787": 114, | ||||||
|  | 		"87d7af": 115, | ||||||
|  | 		"87d7d7": 116, | ||||||
|  | 		"87d7ff": 117, | ||||||
|  | 		"87ff00": 118, | ||||||
|  | 		"87ff5f": 119, | ||||||
|  | 		"87ff87": 120, | ||||||
|  | 		"87ffaf": 121, | ||||||
|  | 		"87ffd7": 122, | ||||||
|  | 		"87ffff": 123, | ||||||
|  | 		"af0000": 124, | ||||||
|  | 		"af005f": 125, | ||||||
|  | 		"af0087": 126, | ||||||
|  | 		"af00af": 127, | ||||||
|  | 		"af00d7": 128, | ||||||
|  | 		"af00ff": 129, | ||||||
|  | 		"af5f00": 130, | ||||||
|  | 		"af5f5f": 131, | ||||||
|  | 		"af5f87": 132, | ||||||
|  | 		"af5faf": 133, | ||||||
|  | 		"af5fd7": 134, | ||||||
|  | 		"af5fff": 135, | ||||||
|  | 		"af8700": 136, | ||||||
|  | 		"af875f": 137, | ||||||
|  | 		"af8787": 138, | ||||||
|  | 		"af87af": 139, | ||||||
|  | 		"af87d7": 140, | ||||||
|  | 		"af87ff": 141, | ||||||
|  | 		"afaf00": 142, | ||||||
|  | 		"afaf5f": 143, | ||||||
|  | 		"afaf87": 144, | ||||||
|  | 		"afafaf": 145, | ||||||
|  | 		"afafd7": 146, | ||||||
|  | 		"afafff": 147, | ||||||
|  | 		"afd700": 148, | ||||||
|  | 		"afd75f": 149, | ||||||
|  | 		"afd787": 150, | ||||||
|  | 		"afd7af": 151, | ||||||
|  | 		"afd7d7": 152, | ||||||
|  | 		"afd7ff": 153, | ||||||
|  | 		"afff00": 154, | ||||||
|  | 		"afff5f": 155, | ||||||
|  | 		"afff87": 156, | ||||||
|  | 		"afffaf": 157, | ||||||
|  | 		"afffd7": 158, | ||||||
|  | 		"afffff": 159, | ||||||
|  | 		"d70000": 160, | ||||||
|  | 		"d7005f": 161, | ||||||
|  | 		"d70087": 162, | ||||||
|  | 		"d700af": 163, | ||||||
|  | 		"d700d7": 164, | ||||||
|  | 		"d700ff": 165, | ||||||
|  | 		"d75f00": 166, | ||||||
|  | 		"d75f5f": 167, | ||||||
|  | 		"d75f87": 168, | ||||||
|  | 		"d75faf": 169, | ||||||
|  | 		"d75fd7": 170, | ||||||
|  | 		"d75fff": 171, | ||||||
|  | 		"d78700": 172, | ||||||
|  | 		"d7875f": 173, | ||||||
|  | 		"d78787": 174, | ||||||
|  | 		"d787af": 175, | ||||||
|  | 		"d787d7": 176, | ||||||
|  | 		"d787ff": 177, | ||||||
|  | 		"d7af00": 178, | ||||||
|  | 		"d7af5f": 179, | ||||||
|  | 		"d7af87": 180, | ||||||
|  | 		"d7afaf": 181, | ||||||
|  | 		"d7afd7": 182, | ||||||
|  | 		"d7afff": 183, | ||||||
|  | 		"d7d700": 184, | ||||||
|  | 		"d7d75f": 185, | ||||||
|  | 		"d7d787": 186, | ||||||
|  | 		"d7d7af": 187, | ||||||
|  | 		"d7d7d7": 188, | ||||||
|  | 		"d7d7ff": 189, | ||||||
|  | 		"d7ff00": 190, | ||||||
|  | 		"d7ff5f": 191, | ||||||
|  | 		"d7ff87": 192, | ||||||
|  | 		"d7ffaf": 193, | ||||||
|  | 		"d7ffd7": 194, | ||||||
|  | 		"d7ffff": 195, | ||||||
|  | 		// "ff0000": 196,
 | ||||||
|  | 		"ff0001": 196, // up: avoid key conflicts, value + 1
 | ||||||
|  | 		"ff005f": 197, | ||||||
|  | 		"ff0087": 198, | ||||||
|  | 		"ff00af": 199, | ||||||
|  | 		"ff00d7": 200, | ||||||
|  | 		// "ff00ff": 201,
 | ||||||
|  | 		"ff00fe": 201, // up: avoid key conflicts, value - 1
 | ||||||
|  | 		"ff5f00": 202, | ||||||
|  | 		"ff5f5f": 203, | ||||||
|  | 		"ff5f87": 204, | ||||||
|  | 		"ff5faf": 205, | ||||||
|  | 		"ff5fd7": 206, | ||||||
|  | 		"ff5fff": 207, | ||||||
|  | 		"ff8700": 208, | ||||||
|  | 		"ff875f": 209, | ||||||
|  | 		"ff8787": 210, | ||||||
|  | 		"ff87af": 211, | ||||||
|  | 		"ff87d7": 212, | ||||||
|  | 		"ff87ff": 213, | ||||||
|  | 		"ffaf00": 214, | ||||||
|  | 		"ffaf5f": 215, | ||||||
|  | 		"ffaf87": 216, | ||||||
|  | 		"ffafaf": 217, | ||||||
|  | 		"ffafd7": 218, | ||||||
|  | 		"ffafff": 219, | ||||||
|  | 		"ffd700": 220, | ||||||
|  | 		"ffd75f": 221, | ||||||
|  | 		"ffd787": 222, | ||||||
|  | 		"ffd7af": 223, | ||||||
|  | 		"ffd7d7": 224, | ||||||
|  | 		"ffd7ff": 225, | ||||||
|  | 		// "ffff00": 226,
 | ||||||
|  | 		"ffff01": 226, // up: avoid key conflicts, value + 1
 | ||||||
|  | 		"ffff5f": 227, | ||||||
|  | 		"ffff87": 228, | ||||||
|  | 		"ffffaf": 229, | ||||||
|  | 		"ffffd7": 230, | ||||||
|  | 		// "ffffff": 231,
 | ||||||
|  | 		"fffffe": 231, // up: avoid key conflicts, value - 1
 | ||||||
|  | 
 | ||||||
|  | 		// Gray-scale range.
 | ||||||
|  | 		"080808": 232, | ||||||
|  | 		"121212": 233, | ||||||
|  | 		"1c1c1c": 234, | ||||||
|  | 		"262626": 235, | ||||||
|  | 		"303030": 236, | ||||||
|  | 		"3a3a3a": 237, | ||||||
|  | 		"444444": 238, | ||||||
|  | 		"4e4e4e": 239, | ||||||
|  | 		"585858": 240, | ||||||
|  | 		"626262": 241, | ||||||
|  | 		"6c6c6c": 242, | ||||||
|  | 		"767676": 243, | ||||||
|  | 		// "808080": 244,
 | ||||||
|  | 		"808081": 244, // up: avoid key conflicts, value + 1
 | ||||||
|  | 		"8a8a8a": 245, | ||||||
|  | 		"949494": 246, | ||||||
|  | 		"9e9e9e": 247, | ||||||
|  | 		"a8a8a8": 248, | ||||||
|  | 		"b2b2b2": 249, | ||||||
|  | 		"bcbcbc": 250, | ||||||
|  | 		"c6c6c6": 251, | ||||||
|  | 		"d0d0d0": 252, | ||||||
|  | 		"dadada": 253, | ||||||
|  | 		"e4e4e4": 254, | ||||||
|  | 		"eeeeee": 255, | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	incs = []uint8{0x00, 0x5f, 0x87, 0xaf, 0xd7, 0xff} | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | func initHex2basicMap() map[string]uint8 { | ||||||
|  | 	h2b := make(map[string]uint8, len(basic2hexMap)) | ||||||
|  | 	// ini data map
 | ||||||
|  | 	for u, s := range basic2hexMap { | ||||||
|  | 		h2b[s] = u | ||||||
|  | 	} | ||||||
|  | 	return h2b | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func init256ToHexMap() map[uint8]string { | ||||||
|  | 	c256toh := make(map[uint8]string, len(hexTo256Table)) | ||||||
|  | 	// ini data map
 | ||||||
|  | 	for hex, c256 := range hexTo256Table { | ||||||
|  | 		c256toh[c256] = hex | ||||||
|  | 	} | ||||||
|  | 	return c256toh | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // RgbTo256Table mapping data
 | ||||||
|  | func RgbTo256Table() map[string]uint8 { | ||||||
|  | 	return hexTo256Table | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Colors2code convert colors to code. return like "32;45;3"
 | ||||||
|  | func Colors2code(colors ...Color) string { | ||||||
|  | 	if len(colors) == 0 { | ||||||
|  | 		return "" | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	var codes []string | ||||||
|  | 	for _, color := range colors { | ||||||
|  | 		codes = append(codes, color.String()) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return strings.Join(codes, ";") | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /************************************************************* | ||||||
|  |  * HEX code <=> RGB/True color code | ||||||
|  |  *************************************************************/ | ||||||
|  | 
 | ||||||
|  | // Hex2rgb alias of the HexToRgb()
 | ||||||
|  | func Hex2rgb(hex string) []int { return HexToRgb(hex) } | ||||||
|  | 
 | ||||||
|  | // HexToRGB alias of the HexToRgb()
 | ||||||
|  | func HexToRGB(hex string) []int { return HexToRgb(hex) } | ||||||
|  | 
 | ||||||
|  | // HexToRgb convert hex color string to RGB numbers
 | ||||||
|  | //
 | ||||||
|  | // Usage:
 | ||||||
|  | // 	rgb := HexToRgb("ccc") // rgb: [204 204 204]
 | ||||||
|  | // 	rgb := HexToRgb("aabbcc") // rgb: [170 187 204]
 | ||||||
|  | // 	rgb := HexToRgb("#aabbcc") // rgb: [170 187 204]
 | ||||||
|  | // 	rgb := HexToRgb("0xad99c0") // rgb: [170 187 204]
 | ||||||
|  | func HexToRgb(hex string) (rgb []int) { | ||||||
|  | 	hex = strings.TrimSpace(hex) | ||||||
|  | 	if hex == "" { | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// like from css. eg "#ccc" "#ad99c0"
 | ||||||
|  | 	if hex[0] == '#' { | ||||||
|  | 		hex = hex[1:] | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	hex = strings.ToLower(hex) | ||||||
|  | 	switch len(hex) { | ||||||
|  | 	case 3: // "ccc"
 | ||||||
|  | 		hex = string([]byte{hex[0], hex[0], hex[1], hex[1], hex[2], hex[2]}) | ||||||
|  | 	case 8: // "0xad99c0"
 | ||||||
|  | 		hex = strings.TrimPrefix(hex, "0x") | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// recheck
 | ||||||
|  | 	if len(hex) != 6 { | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// convert string to int64
 | ||||||
|  | 	if i64, err := strconv.ParseInt(hex, 16, 32); err == nil { | ||||||
|  | 		color := int(i64) | ||||||
|  | 		// parse int
 | ||||||
|  | 		rgb = make([]int, 3) | ||||||
|  | 		rgb[0] = color >> 16 | ||||||
|  | 		rgb[1] = (color & 0x00FF00) >> 8 | ||||||
|  | 		rgb[2] = color & 0x0000FF | ||||||
|  | 	} | ||||||
|  | 	return | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Rgb2hex alias of the RgbToHex()
 | ||||||
|  | func Rgb2hex(rgb []int) string { return RgbToHex(rgb) } | ||||||
|  | 
 | ||||||
|  | // RgbToHex convert RGB-code to hex-code
 | ||||||
|  | //
 | ||||||
|  | // Usage:
 | ||||||
|  | //	hex := RgbToHex([]int{170, 187, 204}) // hex: "aabbcc"
 | ||||||
|  | func RgbToHex(rgb []int) string { | ||||||
|  | 	hexNodes := make([]string, len(rgb)) | ||||||
|  | 
 | ||||||
|  | 	for _, v := range rgb { | ||||||
|  | 		hexNodes = append(hexNodes, strconv.FormatInt(int64(v), 16)) | ||||||
|  | 	} | ||||||
|  | 	return strings.Join(hexNodes, "") | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /************************************************************* | ||||||
|  |  * 4bit(16) color <=> RGB/True color | ||||||
|  |  *************************************************************/ | ||||||
|  | 
 | ||||||
|  | // Basic2hex convert basic color to hex string.
 | ||||||
|  | func Basic2hex(val uint8) string { | ||||||
|  | 	return basic2hexMap[val] | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Hex2basic convert hex string to basic color code.
 | ||||||
|  | func Hex2basic(hex string) uint8 { | ||||||
|  | 	return hex2basicMap[hex] | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Rgb2basic alias of the RgbToAnsi()
 | ||||||
|  | func Rgb2basic(r, g, b uint8, isBg bool) uint8 { | ||||||
|  | 	// is basic color, direct use static map data.
 | ||||||
|  | 	hex := RgbToHex([]int{int(r), int(g), int(b)}) | ||||||
|  | 	if val, ok := hex2basicMap[hex]; ok { | ||||||
|  | 		if isBg { | ||||||
|  | 			return val + 10 | ||||||
|  | 		} | ||||||
|  | 		return val | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return RgbToAnsi(r, g, b, isBg) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Rgb2ansi alias of the RgbToAnsi()
 | ||||||
|  | func Rgb2ansi(r, g, b uint8, isBg bool) uint8 { | ||||||
|  | 	return RgbToAnsi(r, g, b, isBg) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // RgbToAnsi convert RGB-code to 16-code
 | ||||||
|  | // refer https://github.com/radareorg/radare2/blob/master/libr/cons/rgb.c#L249-L271
 | ||||||
|  | func RgbToAnsi(r, g, b uint8, isBg bool) uint8 { | ||||||
|  | 	var bright, c, k uint8 | ||||||
|  | 	base := compareVal(isBg, BgBase, FgBase) | ||||||
|  | 
 | ||||||
|  | 	// eco bright-specific
 | ||||||
|  | 	if r == 0x80 && g == 0x80 && b == 0x80 { // 0x80=128
 | ||||||
|  | 		bright = 53 | ||||||
|  | 	} else if r == 0xff || g == 0xff || b == 0xff { // 0xff=255
 | ||||||
|  | 		bright = 60 | ||||||
|  | 	} // else bright = 0
 | ||||||
|  | 
 | ||||||
|  | 	if r == g && g == b { | ||||||
|  | 		// 0x7f=127
 | ||||||
|  | 		// r = (r > 0x7f) ? 1 : 0;
 | ||||||
|  | 		r = compareVal(r > 0x7f, 1, 0) | ||||||
|  | 		g = compareVal(g > 0x7f, 1, 0) | ||||||
|  | 		b = compareVal(b > 0x7f, 1, 0) | ||||||
|  | 	} else { | ||||||
|  | 		k = (r + g + b) / 3 | ||||||
|  | 
 | ||||||
|  | 		// r = (r >= k) ? 1 : 0;
 | ||||||
|  | 		r = compareVal(r >= k, 1, 0) | ||||||
|  | 		g = compareVal(g >= k, 1, 0) | ||||||
|  | 		b = compareVal(b >= k, 1, 0) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// c = (r ? 1 : 0) + (g ? (b ? 6 : 2) : (b ? 4 : 0))
 | ||||||
|  | 	c = compareVal(r > 0, 1, 0) | ||||||
|  | 
 | ||||||
|  | 	if g > 0 { | ||||||
|  | 		c += compareVal(b > 0, 6, 2) | ||||||
|  | 	} else { | ||||||
|  | 		c += compareVal(b > 0, 4, 0) | ||||||
|  | 	} | ||||||
|  | 	return base + bright + c | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /************************************************************* | ||||||
|  |  * 8bit(256) color <=> RGB/True color | ||||||
|  |  *************************************************************/ | ||||||
|  | 
 | ||||||
|  | // Rgb2short convert RGB-code to 256-code
 | ||||||
|  | func Rgb2short(r, g, b uint8) uint8 { | ||||||
|  | 	return RgbTo256(r, g, b) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // RgbTo256 convert RGB-code to 256-code
 | ||||||
|  | func RgbTo256(r, g, b uint8) uint8 { | ||||||
|  | 	res := make([]uint8, 3) | ||||||
|  | 	for partI, part := range [3]uint8{r, g, b} { | ||||||
|  | 		i := 0 | ||||||
|  | 		for i < len(incs)-1 { | ||||||
|  | 			s, b := incs[i], incs[i+1] // smaller, bigger
 | ||||||
|  | 			if s <= part && part <= b { | ||||||
|  | 				s1 := math.Abs(float64(s) - float64(part)) | ||||||
|  | 				b1 := math.Abs(float64(b) - float64(part)) | ||||||
|  | 				var closest uint8 | ||||||
|  | 				if s1 < b1 { | ||||||
|  | 					closest = s | ||||||
|  | 				} else { | ||||||
|  | 					closest = b | ||||||
|  | 				} | ||||||
|  | 				res[partI] = closest | ||||||
|  | 				break | ||||||
|  | 			} | ||||||
|  | 			i++ | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	hex := fmt.Sprintf("%02x%02x%02x", res[0], res[1], res[2]) | ||||||
|  | 	equiv := hexTo256Table[hex] | ||||||
|  | 	return equiv | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // C256ToRgb convert an 256 color code to RGB numbers
 | ||||||
|  | func C256ToRgb(val uint8) (rgb []uint8) { | ||||||
|  | 	hex := c256ToHexMap[val] | ||||||
|  | 	// convert to rgb code
 | ||||||
|  | 	rgbInts := Hex2rgb(hex) | ||||||
|  | 
 | ||||||
|  | 	return []uint8{ | ||||||
|  | 		uint8(rgbInts[0]), | ||||||
|  | 		uint8(rgbInts[1]), | ||||||
|  | 		uint8(rgbInts[2]), | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // C256ToRgbV1 convert an 256 color code to RGB numbers
 | ||||||
|  | // refer https://github.com/torvalds/linux/commit/cec5b2a97a11ade56a701e83044d0a2a984c67b4
 | ||||||
|  | func C256ToRgbV1(val uint8) (rgb []uint8) { | ||||||
|  | 	var r, g, b uint8 | ||||||
|  | 	if val < 8 { // Standard colours.
 | ||||||
|  | 		// r = val&1 ? 0xaa : 0x00;
 | ||||||
|  | 		r = compareVal(val&1 == 1, 0xaa, 0x00) | ||||||
|  | 		g = compareVal(val&2 == 2, 0xaa, 0x00) | ||||||
|  | 		b = compareVal(val&4 == 4, 0xaa, 0x00) | ||||||
|  | 	} else if val < 16 { | ||||||
|  | 		// r = val & 1 ? 0xff : 0x55;
 | ||||||
|  | 		r = compareVal(val&1 == 1, 0xff, 0x55) | ||||||
|  | 		g = compareVal(val&2 == 2, 0xff, 0x55) | ||||||
|  | 		b = compareVal(val&4 == 4, 0xff, 0x55) | ||||||
|  | 	} else if val < 232 { /* 6x6x6 colour cube. */ | ||||||
|  | 		r = (val - 16) / 36 * 85 / 2 | ||||||
|  | 		g = (val - 16) / 6 % 6 * 85 / 2 | ||||||
|  | 		b = (val - 16) % 6 * 85 / 2 | ||||||
|  | 	} else { /* Grayscale ramp. */ | ||||||
|  | 		nv := uint8(int(val)*10 - 2312) | ||||||
|  | 		// set value
 | ||||||
|  | 		r, g, b = nv, nv, nv | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return []uint8{r, g, b} | ||||||
|  | } | ||||||
							
								
								
									
										281
									
								
								vendor/github.com/gookit/color/detect_env.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										281
									
								
								vendor/github.com/gookit/color/detect_env.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,281 @@ | |||||||
|  | package color | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"io" | ||||||
|  | 	"io/ioutil" | ||||||
|  | 	"os" | ||||||
|  | 	"runtime" | ||||||
|  | 	"strconv" | ||||||
|  | 	"strings" | ||||||
|  | 	"syscall" | ||||||
|  | 
 | ||||||
|  | 	"github.com/xo/terminfo" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | /************************************************************* | ||||||
|  |  * helper methods for detect color supports | ||||||
|  |  *************************************************************/ | ||||||
|  | 
 | ||||||
|  | // DetectColorLevel for current env
 | ||||||
|  | //
 | ||||||
|  | // NOTICE: The method will detect terminal info each times,
 | ||||||
|  | // 	if only want get current color level, please direct call SupportColor() or TermColorLevel()
 | ||||||
|  | func DetectColorLevel() terminfo.ColorLevel { | ||||||
|  | 	level, _ := detectTermColorLevel() | ||||||
|  | 	return level | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // detect terminal color support level
 | ||||||
|  | //
 | ||||||
|  | // refer https://github.com/Delta456/box-cli-maker
 | ||||||
|  | func detectTermColorLevel() (level terminfo.ColorLevel, needVTP bool) { | ||||||
|  | 	// on windows WSL:
 | ||||||
|  | 	// - runtime.GOOS == "Linux"
 | ||||||
|  | 	// - support true-color
 | ||||||
|  | 	// env:
 | ||||||
|  | 	// 	WSL_DISTRO_NAME=Debian
 | ||||||
|  | 	if val := os.Getenv("WSL_DISTRO_NAME"); val != "" { | ||||||
|  | 		// detect WSL as it has True Color support
 | ||||||
|  | 		if detectWSL() { | ||||||
|  | 			debugf("True Color support on WSL environment") | ||||||
|  | 			return terminfo.ColorLevelMillions, false | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	isWin := runtime.GOOS == "windows" | ||||||
|  | 	termVal := os.Getenv("TERM") | ||||||
|  | 
 | ||||||
|  | 	// on TERM=screen: not support true-color
 | ||||||
|  | 	if termVal != "screen" { | ||||||
|  | 		// On JetBrains Terminal
 | ||||||
|  | 		// - support true-color
 | ||||||
|  | 		// env:
 | ||||||
|  | 		// 	TERMINAL_EMULATOR=JetBrains-JediTerm
 | ||||||
|  | 		val := os.Getenv("TERMINAL_EMULATOR") | ||||||
|  | 		if val == "JetBrains-JediTerm" { | ||||||
|  | 			debugf("True Color support on JetBrains-JediTerm, is win: %v", isWin) | ||||||
|  | 			return terminfo.ColorLevelMillions, isWin | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// level, err = terminfo.ColorLevelFromEnv()
 | ||||||
|  | 	level = detectColorLevelFromEnv(termVal, isWin) | ||||||
|  | 	debugf("color level by detectColorLevelFromEnv: %s", level.String()) | ||||||
|  | 
 | ||||||
|  | 	// fallback: simple detect by TERM value string.
 | ||||||
|  | 	if level == terminfo.ColorLevelNone { | ||||||
|  | 		debugf("level none - fallback check special term color support") | ||||||
|  | 		// on Windows: enable VTP as it has True Color support
 | ||||||
|  | 		level, needVTP = detectSpecialTermColor(termVal) | ||||||
|  | 	} | ||||||
|  | 	return | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // detectColorFromEnv returns the color level COLORTERM, FORCE_COLOR,
 | ||||||
|  | // TERM_PROGRAM, or determined from the TERM environment variable.
 | ||||||
|  | //
 | ||||||
|  | // refer the terminfo.ColorLevelFromEnv()
 | ||||||
|  | // https://en.wikipedia.org/wiki/Terminfo
 | ||||||
|  | func detectColorLevelFromEnv(termVal string, isWin bool) terminfo.ColorLevel { | ||||||
|  | 	// check for overriding environment variables
 | ||||||
|  | 	colorTerm, termProg, forceColor := os.Getenv("COLORTERM"), os.Getenv("TERM_PROGRAM"), os.Getenv("FORCE_COLOR") | ||||||
|  | 	switch { | ||||||
|  | 	case strings.Contains(colorTerm, "truecolor") || strings.Contains(colorTerm, "24bit"): | ||||||
|  | 		if termVal == "screen" { // on TERM=screen: not support true-color
 | ||||||
|  | 			return terminfo.ColorLevelHundreds | ||||||
|  | 		} | ||||||
|  | 		return terminfo.ColorLevelMillions | ||||||
|  | 	case colorTerm != "" || forceColor != "": | ||||||
|  | 		return terminfo.ColorLevelBasic | ||||||
|  | 	case termProg == "Apple_Terminal": | ||||||
|  | 		return terminfo.ColorLevelHundreds | ||||||
|  | 	case termProg == "Terminus" || termProg == "Hyper": | ||||||
|  | 		if termVal == "screen" { // on TERM=screen: not support true-color
 | ||||||
|  | 			return terminfo.ColorLevelHundreds | ||||||
|  | 		} | ||||||
|  | 		return terminfo.ColorLevelMillions | ||||||
|  | 	case termProg == "iTerm.app": | ||||||
|  | 		if termVal == "screen" { // on TERM=screen: not support true-color
 | ||||||
|  | 			return terminfo.ColorLevelHundreds | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		// check iTerm version
 | ||||||
|  | 		ver := os.Getenv("TERM_PROGRAM_VERSION") | ||||||
|  | 		if ver != "" { | ||||||
|  | 			i, err := strconv.Atoi(strings.Split(ver, ".")[0]) | ||||||
|  | 			if err != nil { | ||||||
|  | 				saveInternalError(terminfo.ErrInvalidTermProgramVersion) | ||||||
|  | 				// return terminfo.ColorLevelNone
 | ||||||
|  | 				return terminfo.ColorLevelHundreds | ||||||
|  | 			} | ||||||
|  | 			if i == 3 { | ||||||
|  | 				return terminfo.ColorLevelMillions | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		return terminfo.ColorLevelHundreds | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// otherwise determine from TERM's max_colors capability
 | ||||||
|  | 	if !isWin && termVal != "" { | ||||||
|  | 		debugf("TERM=%s - check color level by load terminfo file", termVal) | ||||||
|  | 		ti, err := terminfo.Load(termVal) | ||||||
|  | 		if err != nil { | ||||||
|  | 			saveInternalError(err) | ||||||
|  | 			return terminfo.ColorLevelNone | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		debugf("the loaded term info file is: %s", ti.File) | ||||||
|  | 		v, ok := ti.Nums[terminfo.MaxColors] | ||||||
|  | 		switch { | ||||||
|  | 		case !ok || v <= 16: | ||||||
|  | 			return terminfo.ColorLevelNone | ||||||
|  | 		case ok && v >= 256: | ||||||
|  | 			return terminfo.ColorLevelHundreds | ||||||
|  | 		} | ||||||
|  | 		return terminfo.ColorLevelBasic | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// no TERM env value. default return none level
 | ||||||
|  | 	return terminfo.ColorLevelNone | ||||||
|  | 	// return terminfo.ColorLevelBasic
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | var detectedWSL bool | ||||||
|  | var wslContents string | ||||||
|  | 
 | ||||||
|  | // https://github.com/Microsoft/WSL/issues/423#issuecomment-221627364
 | ||||||
|  | func detectWSL() bool { | ||||||
|  | 	if !detectedWSL { | ||||||
|  | 		b := make([]byte, 1024) | ||||||
|  | 		// `cat /proc/version`
 | ||||||
|  | 		// on mac:
 | ||||||
|  | 		// 	!not the file!
 | ||||||
|  | 		// on linux(debian,ubuntu,alpine):
 | ||||||
|  | 		//	Linux version 4.19.121-linuxkit (root@18b3f92ade35) (gcc version 9.2.0 (Alpine 9.2.0)) #1 SMP Thu Jan 21 15:36:34 UTC 2021
 | ||||||
|  | 		// on win git bash, conEmu:
 | ||||||
|  | 		// 	MINGW64_NT-10.0-19042 version 3.1.7-340.x86_64 (@WIN-N0G619FD3UK) (gcc version 9.3.0 (GCC) ) 2020-10-23 13:08 UTC
 | ||||||
|  | 		// on WSL:
 | ||||||
|  | 		//  Linux version 4.4.0-19041-Microsoft (Microsoft@Microsoft.com) (gcc version 5.4.0 (GCC) ) #488-Microsoft Mon Sep 01 13:43:00 PST 2020
 | ||||||
|  | 		f, err := os.Open("/proc/version") | ||||||
|  | 		if err == nil { | ||||||
|  | 			_, _ = f.Read(b) // ignore error
 | ||||||
|  | 			if err = f.Close(); err != nil { | ||||||
|  | 				saveInternalError(err) | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			wslContents = string(b) | ||||||
|  | 		} | ||||||
|  | 		detectedWSL = true | ||||||
|  | 	} | ||||||
|  | 	return strings.Contains(wslContents, "Microsoft") | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // refer
 | ||||||
|  | //  https://github.com/Delta456/box-cli-maker/blob/7b5a1ad8a016ce181e7d8b05e24b54ff60b4b38a/detect_unix.go#L27-L45
 | ||||||
|  | // detect WSL as it has True Color support
 | ||||||
|  | func isWSL() bool { | ||||||
|  | 	// on windows WSL:
 | ||||||
|  | 	// - runtime.GOOS == "Linux"
 | ||||||
|  | 	// - support true-color
 | ||||||
|  | 	// 	WSL_DISTRO_NAME=Debian
 | ||||||
|  | 	if val := os.Getenv("WSL_DISTRO_NAME"); val == "" { | ||||||
|  | 		return false | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// `cat /proc/sys/kernel/osrelease`
 | ||||||
|  | 	// on mac:
 | ||||||
|  | 	//	!not the file!
 | ||||||
|  | 	// on linux:
 | ||||||
|  | 	// 	4.19.121-linuxkit
 | ||||||
|  | 	// on WSL Output:
 | ||||||
|  | 	//  4.4.0-19041-Microsoft
 | ||||||
|  | 	wsl, err := ioutil.ReadFile("/proc/sys/kernel/osrelease") | ||||||
|  | 	if err != nil { | ||||||
|  | 		saveInternalError(err) | ||||||
|  | 		return false | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// it gives "Microsoft" for WSL and "microsoft" for WSL 2
 | ||||||
|  | 	// it support True-color
 | ||||||
|  | 	content := strings.ToLower(string(wsl)) | ||||||
|  | 	return strings.Contains(content, "microsoft") | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /************************************************************* | ||||||
|  |  * helper methods for check env | ||||||
|  |  *************************************************************/ | ||||||
|  | 
 | ||||||
|  | // IsWindows OS env
 | ||||||
|  | func IsWindows() bool { | ||||||
|  | 	return runtime.GOOS == "windows" | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // IsConsole Determine whether w is one of stderr, stdout, stdin
 | ||||||
|  | func IsConsole(w io.Writer) bool { | ||||||
|  | 	o, ok := w.(*os.File) | ||||||
|  | 	if !ok { | ||||||
|  | 		return false | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	fd := o.Fd() | ||||||
|  | 
 | ||||||
|  | 	// fix: cannot use 'o == os.Stdout' to compare
 | ||||||
|  | 	return fd == uintptr(syscall.Stdout) || fd == uintptr(syscall.Stdin) || fd == uintptr(syscall.Stderr) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // IsMSys msys(MINGW64) environment, does not necessarily support color
 | ||||||
|  | func IsMSys() bool { | ||||||
|  | 	// like "MSYSTEM=MINGW64"
 | ||||||
|  | 	if len(os.Getenv("MSYSTEM")) > 0 { | ||||||
|  | 		return true | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return false | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // IsSupportColor check current console is support color.
 | ||||||
|  | //
 | ||||||
|  | // NOTICE: The method will detect terminal info each times,
 | ||||||
|  | // 	if only want get current color level, please direct call SupportColor() or TermColorLevel()
 | ||||||
|  | func IsSupportColor() bool { | ||||||
|  | 	return IsSupport16Color() | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // IsSupportColor check current console is support color.
 | ||||||
|  | //
 | ||||||
|  | // NOTICE: The method will detect terminal info each times,
 | ||||||
|  | // 	if only want get current color level, please direct call SupportColor() or TermColorLevel()
 | ||||||
|  | func IsSupport16Color() bool { | ||||||
|  | 	level, _ := detectTermColorLevel() | ||||||
|  | 	return level > terminfo.ColorLevelNone | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // IsSupport256Color render check
 | ||||||
|  | //
 | ||||||
|  | // NOTICE: The method will detect terminal info each times,
 | ||||||
|  | // 	if only want get current color level, please direct call SupportColor() or TermColorLevel()
 | ||||||
|  | func IsSupport256Color() bool { | ||||||
|  | 	level, _ := detectTermColorLevel() | ||||||
|  | 	return level > terminfo.ColorLevelBasic | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // IsSupportRGBColor check. alias of the IsSupportTrueColor()
 | ||||||
|  | //
 | ||||||
|  | // NOTICE: The method will detect terminal info each times,
 | ||||||
|  | // 	if only want get current color level, please direct call SupportColor() or TermColorLevel()
 | ||||||
|  | func IsSupportRGBColor() bool { | ||||||
|  | 	return IsSupportTrueColor() | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // IsSupportTrueColor render check.
 | ||||||
|  | //
 | ||||||
|  | // NOTICE: The method will detect terminal info each times,
 | ||||||
|  | // 	if only want get current color level, please direct call SupportColor() or TermColorLevel()
 | ||||||
|  | //
 | ||||||
|  | // ENV:
 | ||||||
|  | // "COLORTERM=truecolor"
 | ||||||
|  | // "COLORTERM=24bit"
 | ||||||
|  | func IsSupportTrueColor() bool { | ||||||
|  | 	level, _ := detectTermColorLevel() | ||||||
|  | 	return level > terminfo.ColorLevelHundreds | ||||||
|  | } | ||||||
							
								
								
									
										48
									
								
								vendor/github.com/gookit/color/detect_nonwin.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								vendor/github.com/gookit/color/detect_nonwin.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,48 @@ | |||||||
|  | // +build !windows
 | ||||||
|  | 
 | ||||||
|  | // The method in the file has no effect
 | ||||||
|  | // Only for compatibility with non-Windows systems
 | ||||||
|  | 
 | ||||||
|  | package color | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"strings" | ||||||
|  | 	"syscall" | ||||||
|  | 
 | ||||||
|  | 	"github.com/xo/terminfo" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // detect special term color support
 | ||||||
|  | func detectSpecialTermColor(termVal string) (terminfo.ColorLevel, bool) { | ||||||
|  | 	if termVal == "" { | ||||||
|  | 		return terminfo.ColorLevelNone, false | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	debugf("terminfo check fail - fallback detect color by check TERM value") | ||||||
|  | 
 | ||||||
|  | 	// on TERM=screen:
 | ||||||
|  | 	// - support 256, not support true-color. test on macOS
 | ||||||
|  | 	if termVal == "screen" { | ||||||
|  | 		return terminfo.ColorLevelHundreds, false | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if strings.Contains(termVal, "256color") { | ||||||
|  | 		return terminfo.ColorLevelHundreds, false | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if strings.Contains(termVal, "xterm") { | ||||||
|  | 		return terminfo.ColorLevelHundreds, false | ||||||
|  | 		// return terminfo.ColorLevelBasic, false
 | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// return terminfo.ColorLevelNone, nil
 | ||||||
|  | 	return terminfo.ColorLevelBasic, false | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // IsTerminal returns true if the given file descriptor is a terminal.
 | ||||||
|  | //
 | ||||||
|  | // Usage:
 | ||||||
|  | // 	IsTerminal(os.Stdout.Fd())
 | ||||||
|  | func IsTerminal(fd uintptr) bool { | ||||||
|  | 	return fd == uintptr(syscall.Stdout) || fd == uintptr(syscall.Stdin) || fd == uintptr(syscall.Stderr) | ||||||
|  | } | ||||||
							
								
								
									
										243
									
								
								vendor/github.com/gookit/color/detect_windows.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										243
									
								
								vendor/github.com/gookit/color/detect_windows.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,243 @@ | |||||||
|  | // +build windows
 | ||||||
|  | 
 | ||||||
|  | // Display color on windows
 | ||||||
|  | // refer:
 | ||||||
|  | //  golang.org/x/sys/windows
 | ||||||
|  | // 	golang.org/x/crypto/ssh/terminal
 | ||||||
|  | // 	https://docs.microsoft.com/en-us/windows/console
 | ||||||
|  | package color | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"os" | ||||||
|  | 	"syscall" | ||||||
|  | 	"unsafe" | ||||||
|  | 
 | ||||||
|  | 	"github.com/xo/terminfo" | ||||||
|  | 	"golang.org/x/sys/windows" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // related docs
 | ||||||
|  | // https://docs.microsoft.com/zh-cn/windows/console/console-virtual-terminal-sequences
 | ||||||
|  | // https://docs.microsoft.com/zh-cn/windows/console/console-virtual-terminal-sequences#samples
 | ||||||
|  | var ( | ||||||
|  | 	// isMSys bool
 | ||||||
|  | 	kernel32 *syscall.LazyDLL | ||||||
|  | 
 | ||||||
|  | 	procGetConsoleMode *syscall.LazyProc | ||||||
|  | 	procSetConsoleMode *syscall.LazyProc | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | func init() { | ||||||
|  | 	if !SupportColor() { | ||||||
|  | 		isLikeInCmd = true | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// if disabled.
 | ||||||
|  | 	if !Enable { | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// if at windows's ConEmu, Cmder, putty ... terminals not need VTP
 | ||||||
|  | 
 | ||||||
|  | 	// -------- try force enable colors on windows terminal -------
 | ||||||
|  | 	tryEnableVTP(needVTP) | ||||||
|  | 
 | ||||||
|  | 	// fetch console screen buffer info
 | ||||||
|  | 	// err := getConsoleScreenBufferInfo(uintptr(syscall.Stdout), &defScreenInfo)
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // try force enable colors on windows terminal
 | ||||||
|  | func tryEnableVTP(enable bool) bool { | ||||||
|  | 	if !enable { | ||||||
|  | 		return false | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	debugf("True-Color by enable VirtualTerminalProcessing on windows") | ||||||
|  | 
 | ||||||
|  | 	initKernel32Proc() | ||||||
|  | 
 | ||||||
|  | 	// enable colors on windows terminal
 | ||||||
|  | 	if tryEnableOnCONOUT() { | ||||||
|  | 		return true | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return tryEnableOnStdout() | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func initKernel32Proc() { | ||||||
|  | 	if kernel32 != nil { | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// load related windows dll
 | ||||||
|  | 	// https://docs.microsoft.com/en-us/windows/console/setconsolemode
 | ||||||
|  | 	kernel32 = syscall.NewLazyDLL("kernel32.dll") | ||||||
|  | 
 | ||||||
|  | 	procGetConsoleMode = kernel32.NewProc("GetConsoleMode") | ||||||
|  | 	procSetConsoleMode = kernel32.NewProc("SetConsoleMode") | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func tryEnableOnCONOUT() bool { | ||||||
|  | 	outHandle, err := syscall.Open("CONOUT$", syscall.O_RDWR, 0) | ||||||
|  | 	if err != nil { | ||||||
|  | 		saveInternalError(err) | ||||||
|  | 		return false | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	err = EnableVirtualTerminalProcessing(outHandle, true) | ||||||
|  | 	if err != nil { | ||||||
|  | 		saveInternalError(err) | ||||||
|  | 		return false | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return true | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func tryEnableOnStdout() bool { | ||||||
|  | 	// try direct open syscall.Stdout
 | ||||||
|  | 	err := EnableVirtualTerminalProcessing(syscall.Stdout, true) | ||||||
|  | 	if err != nil { | ||||||
|  | 		saveInternalError(err) | ||||||
|  | 		return false | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return true | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Get the Windows Version and Build Number
 | ||||||
|  | var ( | ||||||
|  | 	winVersion, _, buildNumber = windows.RtlGetNtVersionNumbers() | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // refer
 | ||||||
|  | //  https://github.com/Delta456/box-cli-maker/blob/7b5a1ad8a016ce181e7d8b05e24b54ff60b4b38a/detect_windows.go#L30-L57
 | ||||||
|  | //  https://github.com/gookit/color/issues/25#issuecomment-738727917
 | ||||||
|  | // detects the Color Level Supported on windows: cmd, powerShell
 | ||||||
|  | func detectSpecialTermColor(termVal string) (tl terminfo.ColorLevel, needVTP bool) { | ||||||
|  | 	if os.Getenv("ConEmuANSI") == "ON" { | ||||||
|  | 		debugf("support True Color by ConEmuANSI=ON") | ||||||
|  | 		// ConEmuANSI is "ON" for generic ANSI support
 | ||||||
|  | 		// but True Color option is enabled by default
 | ||||||
|  | 		// I am just assuming that people wouldn't have disabled it
 | ||||||
|  | 		// Even if it is not enabled then ConEmu will auto round off
 | ||||||
|  | 		// accordingly
 | ||||||
|  | 		return terminfo.ColorLevelMillions, false | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// Before Windows 10 Build Number 10586, console never supported ANSI Colors
 | ||||||
|  | 	if buildNumber < 10586 || winVersion < 10 { | ||||||
|  | 		// Detect if using ANSICON on older systems
 | ||||||
|  | 		if os.Getenv("ANSICON") != "" { | ||||||
|  | 			conVersion := os.Getenv("ANSICON_VER") | ||||||
|  | 			// 8 bit Colors were only supported after v1.81 release
 | ||||||
|  | 			if conVersion >= "181" { | ||||||
|  | 				return terminfo.ColorLevelHundreds, false | ||||||
|  | 			} | ||||||
|  | 			return terminfo.ColorLevelBasic, false | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		return terminfo.ColorLevelNone, false | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// True Color is not available before build 14931 so fallback to 8 bit color.
 | ||||||
|  | 	if buildNumber < 14931 { | ||||||
|  | 		return terminfo.ColorLevelHundreds, true | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// Windows 10 build 14931 is the first release that supports 16m/TrueColor
 | ||||||
|  | 	debugf("support True Color on windows version is >= build 14931") | ||||||
|  | 	return terminfo.ColorLevelMillions, true | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /************************************************************* | ||||||
|  |  * render full color code on windows(8,16,24bit color) | ||||||
|  |  *************************************************************/ | ||||||
|  | 
 | ||||||
|  | // docs https://docs.microsoft.com/zh-cn/windows/console/getconsolemode#parameters
 | ||||||
|  | const ( | ||||||
|  | 	// equals to docs page's ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004
 | ||||||
|  | 	EnableVirtualTerminalProcessingMode uint32 = 0x4 | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // EnableVirtualTerminalProcessing Enable virtual terminal processing
 | ||||||
|  | //
 | ||||||
|  | // ref from github.com/konsorten/go-windows-terminal-sequences
 | ||||||
|  | // doc https://docs.microsoft.com/zh-cn/windows/console/console-virtual-terminal-sequences#samples
 | ||||||
|  | //
 | ||||||
|  | // Usage:
 | ||||||
|  | // 	err := EnableVirtualTerminalProcessing(syscall.Stdout, true)
 | ||||||
|  | // 	// support print color text
 | ||||||
|  | // 	err = EnableVirtualTerminalProcessing(syscall.Stdout, false)
 | ||||||
|  | func EnableVirtualTerminalProcessing(stream syscall.Handle, enable bool) error { | ||||||
|  | 	var mode uint32 | ||||||
|  | 	// Check if it is currently in the terminal
 | ||||||
|  | 	// err := syscall.GetConsoleMode(syscall.Stdout, &mode)
 | ||||||
|  | 	err := syscall.GetConsoleMode(stream, &mode) | ||||||
|  | 	if err != nil { | ||||||
|  | 		// fmt.Println("EnableVirtualTerminalProcessing", err)
 | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if enable { | ||||||
|  | 		mode |= EnableVirtualTerminalProcessingMode | ||||||
|  | 	} else { | ||||||
|  | 		mode &^= EnableVirtualTerminalProcessingMode | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	ret, _, err := procSetConsoleMode.Call(uintptr(stream), uintptr(mode)) | ||||||
|  | 	if ret == 0 { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // renderColorCodeOnCmd enable cmd color render.
 | ||||||
|  | // func renderColorCodeOnCmd(fn func()) {
 | ||||||
|  | // 	err := EnableVirtualTerminalProcessing(syscall.Stdout, true)
 | ||||||
|  | // 	// if is not in terminal, will clear color tag.
 | ||||||
|  | // 	if err != nil {
 | ||||||
|  | // 		// panic(err)
 | ||||||
|  | // 		fn()
 | ||||||
|  | // 		return
 | ||||||
|  | // 	}
 | ||||||
|  | //
 | ||||||
|  | // 	// force open color render
 | ||||||
|  | // 	old := ForceOpenColor()
 | ||||||
|  | // 	fn()
 | ||||||
|  | // 	// revert color setting
 | ||||||
|  | // 	supportColor = old
 | ||||||
|  | //
 | ||||||
|  | // 	err = EnableVirtualTerminalProcessing(syscall.Stdout, false)
 | ||||||
|  | // 	if err != nil {
 | ||||||
|  | // 		panic(err)
 | ||||||
|  | // 	}
 | ||||||
|  | // }
 | ||||||
|  | 
 | ||||||
|  | /************************************************************* | ||||||
|  |  * render simple color code on windows | ||||||
|  |  *************************************************************/ | ||||||
|  | 
 | ||||||
|  | // IsTty returns true if the given file descriptor is a terminal.
 | ||||||
|  | func IsTty(fd uintptr) bool { | ||||||
|  | 	initKernel32Proc() | ||||||
|  | 
 | ||||||
|  | 	var st uint32 | ||||||
|  | 	r, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, fd, uintptr(unsafe.Pointer(&st)), 0) | ||||||
|  | 	return r != 0 && e == 0 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // IsTerminal returns true if the given file descriptor is a terminal.
 | ||||||
|  | //
 | ||||||
|  | // Usage:
 | ||||||
|  | // 	fd := os.Stdout.Fd()
 | ||||||
|  | // 	fd := uintptr(syscall.Stdout) // for windows
 | ||||||
|  | // 	IsTerminal(fd)
 | ||||||
|  | func IsTerminal(fd uintptr) bool { | ||||||
|  | 	initKernel32Proc() | ||||||
|  | 
 | ||||||
|  | 	var st uint32 | ||||||
|  | 	r, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, fd, uintptr(unsafe.Pointer(&st)), 0) | ||||||
|  | 	return r != 0 && e == 0 | ||||||
|  | } | ||||||
							
								
								
									
										9
									
								
								vendor/github.com/gookit/color/go.mod
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								vendor/github.com/gookit/color/go.mod
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,9 @@ | |||||||
|  | module github.com/gookit/color | ||||||
|  | 
 | ||||||
|  | go 1.12 | ||||||
|  | 
 | ||||||
|  | require ( | ||||||
|  | 	github.com/stretchr/testify v1.6.1 | ||||||
|  | 	github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 | ||||||
|  | 	golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44 | ||||||
|  | ) | ||||||
							
								
								
									
										15
									
								
								vendor/github.com/gookit/color/go.sum
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								vendor/github.com/gookit/color/go.sum
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,15 @@ | |||||||
|  | github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= | ||||||
|  | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||||||
|  | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= | ||||||
|  | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= | ||||||
|  | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= | ||||||
|  | github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= | ||||||
|  | github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= | ||||||
|  | github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 h1:QldyIu/L63oPpyvQmHgvgickp1Yw510KJOqX7H24mg8= | ||||||
|  | github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778/go.mod h1:2MuV+tbUrU1zIOPMxZ5EncGwgmMJsa+9ucAQZXxsObs= | ||||||
|  | golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44 h1:Bli41pIlzTzf3KEY06n+xnzK/BESIg2ze4Pgfh/aI8c= | ||||||
|  | golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||||
|  | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= | ||||||
|  | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | ||||||
|  | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= | ||||||
|  | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= | ||||||
							
								
								
									
										122
									
								
								vendor/github.com/gookit/color/printer.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										122
									
								
								vendor/github.com/gookit/color/printer.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,122 @@ | |||||||
|  | package color | ||||||
|  | 
 | ||||||
|  | import "fmt" | ||||||
|  | 
 | ||||||
|  | /************************************************************* | ||||||
|  |  * colored message Printer | ||||||
|  |  *************************************************************/ | ||||||
|  | 
 | ||||||
|  | // PrinterFace interface
 | ||||||
|  | type PrinterFace interface { | ||||||
|  | 	fmt.Stringer | ||||||
|  | 	Sprint(a ...interface{}) string | ||||||
|  | 	Sprintf(format string, a ...interface{}) string | ||||||
|  | 	Print(a ...interface{}) | ||||||
|  | 	Printf(format string, a ...interface{}) | ||||||
|  | 	Println(a ...interface{}) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Printer a generic color message printer.
 | ||||||
|  | //
 | ||||||
|  | // Usage:
 | ||||||
|  | // 	p := &Printer{Code: "32;45;3"}
 | ||||||
|  | // 	p.Print("message")
 | ||||||
|  | type Printer struct { | ||||||
|  | 	// NoColor disable color.
 | ||||||
|  | 	NoColor bool | ||||||
|  | 	// Code color code string. eg "32;45;3"
 | ||||||
|  | 	Code string | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // NewPrinter instance
 | ||||||
|  | func NewPrinter(colorCode string) *Printer { | ||||||
|  | 	return &Printer{Code: colorCode} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // String returns color code string. eg: "32;45;3"
 | ||||||
|  | func (p *Printer) String() string { | ||||||
|  | 	// panic("implement me")
 | ||||||
|  | 	return p.Code | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Sprint returns rendering colored messages
 | ||||||
|  | func (p *Printer) Sprint(a ...interface{}) string { | ||||||
|  | 	return RenderCode(p.String(), a...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Sprintf returns format and rendering colored messages
 | ||||||
|  | func (p *Printer) Sprintf(format string, a ...interface{}) string { | ||||||
|  | 	return RenderString(p.String(), fmt.Sprintf(format, a...)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Print rendering colored messages
 | ||||||
|  | func (p *Printer) Print(a ...interface{}) { | ||||||
|  | 	doPrintV2(p.String(), fmt.Sprint(a...)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Printf format and rendering colored messages
 | ||||||
|  | func (p *Printer) Printf(format string, a ...interface{}) { | ||||||
|  | 	doPrintV2(p.String(), fmt.Sprintf(format, a...)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Println rendering colored messages with newline
 | ||||||
|  | func (p *Printer) Println(a ...interface{}) { | ||||||
|  | 	doPrintlnV2(p.Code, a) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // IsEmpty color code
 | ||||||
|  | func (p *Printer) IsEmpty() bool { | ||||||
|  | 	return p.Code == "" | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /************************************************************* | ||||||
|  |  * SimplePrinter struct | ||||||
|  |  *************************************************************/ | ||||||
|  | 
 | ||||||
|  | // SimplePrinter use for quick use color print on inject to struct
 | ||||||
|  | type SimplePrinter struct{} | ||||||
|  | 
 | ||||||
|  | // Print message
 | ||||||
|  | func (s *SimplePrinter) Print(v ...interface{}) { | ||||||
|  | 	Print(v...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Printf message
 | ||||||
|  | func (s *SimplePrinter) Printf(format string, v ...interface{}) { | ||||||
|  | 	Printf(format, v...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Println message
 | ||||||
|  | func (s *SimplePrinter) Println(v ...interface{}) { | ||||||
|  | 	Println(v...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Infof message
 | ||||||
|  | func (s *SimplePrinter) Infof(format string, a ...interface{}) { | ||||||
|  | 	Info.Printf(format, a...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Infoln message
 | ||||||
|  | func (s *SimplePrinter) Infoln(a ...interface{}) { | ||||||
|  | 	Info.Println(a...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Warnf message
 | ||||||
|  | func (s *SimplePrinter) Warnf(format string, a ...interface{}) { | ||||||
|  | 	Warn.Printf(format, a...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Warnln message
 | ||||||
|  | func (s *SimplePrinter) Warnln(a ...interface{}) { | ||||||
|  | 	Warn.Println(a...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Errorf message
 | ||||||
|  | func (s *SimplePrinter) Errorf(format string, a ...interface{}) { | ||||||
|  | 	Error.Printf(format, a...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Errorln message
 | ||||||
|  | func (s *SimplePrinter) Errorln(a ...interface{}) { | ||||||
|  | 	Error.Println(a...) | ||||||
|  | } | ||||||
							
								
								
									
										109
									
								
								vendor/github.com/gookit/color/quickstart.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								vendor/github.com/gookit/color/quickstart.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,109 @@ | |||||||
|  | package color | ||||||
|  | 
 | ||||||
|  | /************************************************************* | ||||||
|  |  * quick use color print message | ||||||
|  |  *************************************************************/ | ||||||
|  | 
 | ||||||
|  | // Redp print message with Red color
 | ||||||
|  | func Redp(a ...interface{}) { | ||||||
|  | 	Red.Print(a...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Redln print message line with Red color
 | ||||||
|  | func Redln(a ...interface{}) { | ||||||
|  | 	Red.Println(a...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Bluep print message with Blue color
 | ||||||
|  | func Bluep(a ...interface{}) { | ||||||
|  | 	Blue.Print(a...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Blueln print message line with Blue color
 | ||||||
|  | func Blueln(a ...interface{}) { | ||||||
|  | 	Blue.Println(a...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Cyanp print message with Cyan color
 | ||||||
|  | func Cyanp(a ...interface{}) { | ||||||
|  | 	Cyan.Print(a...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Cyanln print message line with Cyan color
 | ||||||
|  | func Cyanln(a ...interface{}) { | ||||||
|  | 	Cyan.Println(a...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Grayp print message with Gray color
 | ||||||
|  | func Grayp(a ...interface{}) { | ||||||
|  | 	Gray.Print(a...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Grayln print message line with Gray color
 | ||||||
|  | func Grayln(a ...interface{}) { | ||||||
|  | 	Gray.Println(a...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Greenp print message with Green color
 | ||||||
|  | func Greenp(a ...interface{}) { | ||||||
|  | 	Green.Print(a...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Greenln print message line with Green color
 | ||||||
|  | func Greenln(a ...interface{}) { | ||||||
|  | 	Green.Println(a...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Yellowp print message with Yellow color
 | ||||||
|  | func Yellowp(a ...interface{}) { | ||||||
|  | 	Yellow.Print(a...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Yellowln print message line with Yellow color
 | ||||||
|  | func Yellowln(a ...interface{}) { | ||||||
|  | 	Yellow.Println(a...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Magentap print message with Magenta color
 | ||||||
|  | func Magentap(a ...interface{}) { | ||||||
|  | 	Magenta.Print(a...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Magentaln print message line with Magenta color
 | ||||||
|  | func Magentaln(a ...interface{}) { | ||||||
|  | 	Magenta.Println(a...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /************************************************************* | ||||||
|  |  * quick use style print message | ||||||
|  |  *************************************************************/ | ||||||
|  | 
 | ||||||
|  | // Infof print message with Info style
 | ||||||
|  | func Infof(format string, a ...interface{}) { | ||||||
|  | 	Info.Printf(format, a...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Infoln print message with Info style
 | ||||||
|  | func Infoln(a ...interface{}) { | ||||||
|  | 	Info.Println(a...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Errorf print message with Error style
 | ||||||
|  | func Errorf(format string, a ...interface{}) { | ||||||
|  | 	Error.Printf(format, a...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Errorln print message with Error style
 | ||||||
|  | func Errorln(a ...interface{}) { | ||||||
|  | 	Error.Println(a...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Warnf print message with Warn style
 | ||||||
|  | func Warnf(format string, a ...interface{}) { | ||||||
|  | 	Warn.Printf(format, a...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Warnln print message with Warn style
 | ||||||
|  | func Warnln(a ...interface{}) { | ||||||
|  | 	Warn.Println(a...) | ||||||
|  | } | ||||||
							
								
								
									
										315
									
								
								vendor/github.com/gookit/color/style.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										315
									
								
								vendor/github.com/gookit/color/style.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,315 @@ | |||||||
|  | package color | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  | 	"strings" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | /************************************************************* | ||||||
|  |  * 16 color Style | ||||||
|  |  *************************************************************/ | ||||||
|  | 
 | ||||||
|  | // Style a 16 color style. can add: fg color, bg color, color options
 | ||||||
|  | //
 | ||||||
|  | // Example:
 | ||||||
|  | // 	color.Style{color.FgGreen}.Print("message")
 | ||||||
|  | type Style []Color | ||||||
|  | 
 | ||||||
|  | // New create a custom style
 | ||||||
|  | //
 | ||||||
|  | // Usage:
 | ||||||
|  | //	color.New(color.FgGreen).Print("message")
 | ||||||
|  | //	equals to:
 | ||||||
|  | //	color.Style{color.FgGreen}.Print("message")
 | ||||||
|  | func New(colors ...Color) Style { | ||||||
|  | 	return colors | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Save to global styles map
 | ||||||
|  | func (s Style) Save(name string) { | ||||||
|  | 	AddStyle(name, s) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Add to global styles map
 | ||||||
|  | func (s *Style) Add(cs ...Color) { | ||||||
|  | 	*s = append(*s, cs...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Render render text
 | ||||||
|  | // Usage:
 | ||||||
|  | //  color.New(color.FgGreen).Render("text")
 | ||||||
|  | //  color.New(color.FgGreen, color.BgBlack, color.OpBold).Render("text")
 | ||||||
|  | func (s Style) Render(a ...interface{}) string { | ||||||
|  | 	return RenderCode(s.String(), a...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Renderln render text line.
 | ||||||
|  | // like Println, will add spaces for each argument
 | ||||||
|  | // Usage:
 | ||||||
|  | //  color.New(color.FgGreen).Renderln("text", "more")
 | ||||||
|  | //  color.New(color.FgGreen, color.BgBlack, color.OpBold).Render("text", "more")
 | ||||||
|  | func (s Style) Renderln(a ...interface{}) string { | ||||||
|  | 	return RenderWithSpaces(s.String(), a...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Sprint is alias of the 'Render'
 | ||||||
|  | func (s Style) Sprint(a ...interface{}) string { | ||||||
|  | 	return RenderCode(s.String(), a...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Sprintf format and render message.
 | ||||||
|  | func (s Style) Sprintf(format string, a ...interface{}) string { | ||||||
|  | 	return RenderString(s.String(), fmt.Sprintf(format, a...)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Print render and Print text
 | ||||||
|  | func (s Style) Print(a ...interface{}) { | ||||||
|  | 	doPrintV2(s.String(), fmt.Sprint(a...)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Printf render and print text
 | ||||||
|  | func (s Style) Printf(format string, a ...interface{}) { | ||||||
|  | 	doPrintV2(s.Code(), fmt.Sprintf(format, a...)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Println render and print text line
 | ||||||
|  | func (s Style) Println(a ...interface{}) { | ||||||
|  | 	doPrintlnV2(s.String(), a) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Code convert to code string. returns like "32;45;3"
 | ||||||
|  | func (s Style) Code() string { | ||||||
|  | 	return s.String() | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // String convert to code string. returns like "32;45;3"
 | ||||||
|  | func (s Style) String() string { | ||||||
|  | 	return Colors2code(s...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // IsEmpty style
 | ||||||
|  | func (s Style) IsEmpty() bool { | ||||||
|  | 	return len(s) == 0 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /************************************************************* | ||||||
|  |  * Theme(extended Style) | ||||||
|  |  *************************************************************/ | ||||||
|  | 
 | ||||||
|  | // Theme definition. extends from Style
 | ||||||
|  | type Theme struct { | ||||||
|  | 	// Name theme name
 | ||||||
|  | 	Name string | ||||||
|  | 	// Style for the theme
 | ||||||
|  | 	Style | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // NewTheme instance
 | ||||||
|  | func NewTheme(name string, style Style) *Theme { | ||||||
|  | 	return &Theme{name, style} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Save to themes map
 | ||||||
|  | func (t *Theme) Save() { | ||||||
|  | 	AddTheme(t.Name, t.Style) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Tips use name as title, only apply style for name
 | ||||||
|  | func (t *Theme) Tips(format string, a ...interface{}) { | ||||||
|  | 	// only apply style for name
 | ||||||
|  | 	t.Print(strings.ToUpper(t.Name) + ": ") | ||||||
|  | 	Printf(format+"\n", a...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Prompt use name as title, and apply style for message
 | ||||||
|  | func (t *Theme) Prompt(format string, a ...interface{}) { | ||||||
|  | 	title := strings.ToUpper(t.Name) + ":" | ||||||
|  | 	t.Println(title, fmt.Sprintf(format, a...)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Block like Prompt, but will wrap a empty line
 | ||||||
|  | func (t *Theme) Block(format string, a ...interface{}) { | ||||||
|  | 	title := strings.ToUpper(t.Name) + ":\n" | ||||||
|  | 
 | ||||||
|  | 	t.Println(title, fmt.Sprintf(format, a...)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /************************************************************* | ||||||
|  |  * Theme: internal themes | ||||||
|  |  *************************************************************/ | ||||||
|  | 
 | ||||||
|  | // internal themes(like bootstrap style)
 | ||||||
|  | // Usage:
 | ||||||
|  | // 	color.Info.Print("message")
 | ||||||
|  | // 	color.Info.Printf("a %s message", "test")
 | ||||||
|  | // 	color.Warn.Println("message")
 | ||||||
|  | // 	color.Error.Println("message")
 | ||||||
|  | var ( | ||||||
|  | 	// Info color style
 | ||||||
|  | 	Info = &Theme{"info", Style{OpReset, FgGreen}} | ||||||
|  | 	// Note color style
 | ||||||
|  | 	Note = &Theme{"note", Style{OpBold, FgLightCyan}} | ||||||
|  | 	// Warn color style
 | ||||||
|  | 	Warn = &Theme{"warning", Style{OpBold, FgYellow}} | ||||||
|  | 	// Light color style
 | ||||||
|  | 	Light = &Theme{"light", Style{FgLightWhite, BgBlack}} | ||||||
|  | 	// Error color style
 | ||||||
|  | 	Error = &Theme{"error", Style{FgLightWhite, BgRed}} | ||||||
|  | 	// Danger color style
 | ||||||
|  | 	Danger = &Theme{"danger", Style{OpBold, FgRed}} | ||||||
|  | 	// Debug color style
 | ||||||
|  | 	Debug = &Theme{"debug", Style{OpReset, FgCyan}} | ||||||
|  | 	// Notice color style
 | ||||||
|  | 	Notice = &Theme{"notice", Style{OpBold, FgCyan}} | ||||||
|  | 	// Comment color style
 | ||||||
|  | 	Comment = &Theme{"comment", Style{OpReset, FgYellow}} | ||||||
|  | 	// Success color style
 | ||||||
|  | 	Success = &Theme{"success", Style{OpBold, FgGreen}} | ||||||
|  | 	// Primary color style
 | ||||||
|  | 	Primary = &Theme{"primary", Style{OpReset, FgBlue}} | ||||||
|  | 	// Question color style
 | ||||||
|  | 	Question = &Theme{"question", Style{OpReset, FgMagenta}} | ||||||
|  | 	// Secondary color style
 | ||||||
|  | 	Secondary = &Theme{"secondary", Style{FgDarkGray}} | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // Themes internal defined themes.
 | ||||||
|  | // Usage:
 | ||||||
|  | // 	color.Themes["info"].Println("message")
 | ||||||
|  | var Themes = map[string]*Theme{ | ||||||
|  | 	"info":  Info, | ||||||
|  | 	"note":  Note, | ||||||
|  | 	"light": Light, | ||||||
|  | 	"error": Error, | ||||||
|  | 
 | ||||||
|  | 	"debug":   Debug, | ||||||
|  | 	"danger":  Danger, | ||||||
|  | 	"notice":  Notice, | ||||||
|  | 	"success": Success, | ||||||
|  | 	"comment": Comment, | ||||||
|  | 	"primary": Primary, | ||||||
|  | 	"warning": Warn, | ||||||
|  | 
 | ||||||
|  | 	"question":  Question, | ||||||
|  | 	"secondary": Secondary, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // AddTheme add a theme and style
 | ||||||
|  | func AddTheme(name string, style Style) { | ||||||
|  | 	Themes[name] = NewTheme(name, style) | ||||||
|  | 	Styles[name] = style | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // GetTheme get defined theme by name
 | ||||||
|  | func GetTheme(name string) *Theme { | ||||||
|  | 	return Themes[name] | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /************************************************************* | ||||||
|  |  * internal styles | ||||||
|  |  *************************************************************/ | ||||||
|  | 
 | ||||||
|  | // Styles internal defined styles, like bootstrap styles.
 | ||||||
|  | // Usage:
 | ||||||
|  | // 	color.Styles["info"].Println("message")
 | ||||||
|  | var Styles = map[string]Style{ | ||||||
|  | 	"info":  {OpReset, FgGreen}, | ||||||
|  | 	"note":  {OpBold, FgLightCyan}, | ||||||
|  | 	"light": {FgLightWhite, BgRed}, | ||||||
|  | 	"error": {FgLightWhite, BgRed}, | ||||||
|  | 
 | ||||||
|  | 	"danger":  {OpBold, FgRed}, | ||||||
|  | 	"notice":  {OpBold, FgCyan}, | ||||||
|  | 	"success": {OpBold, FgGreen}, | ||||||
|  | 	"comment": {OpReset, FgMagenta}, | ||||||
|  | 	"primary": {OpReset, FgBlue}, | ||||||
|  | 	"warning": {OpBold, FgYellow}, | ||||||
|  | 
 | ||||||
|  | 	"question":  {OpReset, FgMagenta}, | ||||||
|  | 	"secondary": {FgDarkGray}, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // some style name alias
 | ||||||
|  | var styleAliases = map[string]string{ | ||||||
|  | 	"err":  "error", | ||||||
|  | 	"suc":  "success", | ||||||
|  | 	"warn": "warning", | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // AddStyle add a style
 | ||||||
|  | func AddStyle(name string, s Style) { | ||||||
|  | 	Styles[name] = s | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // GetStyle get defined style by name
 | ||||||
|  | func GetStyle(name string) Style { | ||||||
|  | 	if s, ok := Styles[name]; ok { | ||||||
|  | 		return s | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if realName, ok := styleAliases[name]; ok { | ||||||
|  | 		return Styles[realName] | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// empty style
 | ||||||
|  | 	return New() | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /************************************************************* | ||||||
|  |  * color scheme | ||||||
|  |  *************************************************************/ | ||||||
|  | 
 | ||||||
|  | // Scheme struct
 | ||||||
|  | type Scheme struct { | ||||||
|  | 	Name   string | ||||||
|  | 	Styles map[string]Style | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // NewScheme create new Scheme
 | ||||||
|  | func NewScheme(name string, styles map[string]Style) *Scheme { | ||||||
|  | 	return &Scheme{Name: name, Styles: styles} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // NewDefaultScheme create an defuault color Scheme
 | ||||||
|  | func NewDefaultScheme(name string) *Scheme { | ||||||
|  | 	return NewScheme(name, map[string]Style{ | ||||||
|  | 		"info":  {OpReset, FgGreen}, | ||||||
|  | 		"warn":  {OpBold, FgYellow}, | ||||||
|  | 		"error": {FgLightWhite, BgRed}, | ||||||
|  | 	}) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Style get by name
 | ||||||
|  | func (s *Scheme) Style(name string) Style { | ||||||
|  | 	return s.Styles[name] | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Infof message print
 | ||||||
|  | func (s *Scheme) Infof(format string, a ...interface{}) { | ||||||
|  | 	s.Styles["info"].Printf(format, a...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Infoln message print
 | ||||||
|  | func (s *Scheme) Infoln(v ...interface{}) { | ||||||
|  | 	s.Styles["info"].Println(v...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Warnf message print
 | ||||||
|  | func (s *Scheme) Warnf(format string, a ...interface{}) { | ||||||
|  | 	s.Styles["warn"].Printf(format, a...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Warnln message print
 | ||||||
|  | func (s *Scheme) Warnln(v ...interface{}) { | ||||||
|  | 	s.Styles["warn"].Println(v...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Errorf message print
 | ||||||
|  | func (s *Scheme) Errorf(format string, a ...interface{}) { | ||||||
|  | 	s.Styles["error"].Printf(format, a...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Errorln message print
 | ||||||
|  | func (s *Scheme) Errorln(v ...interface{}) { | ||||||
|  | 	s.Styles["error"].Println(v...) | ||||||
|  | } | ||||||
							
								
								
									
										206
									
								
								vendor/github.com/gookit/color/utils.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										206
									
								
								vendor/github.com/gookit/color/utils.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,206 @@ | |||||||
|  | package color | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  | 	"io" | ||||||
|  | 	"log" | ||||||
|  | 	"strings" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // SetTerminal by given code.
 | ||||||
|  | func SetTerminal(code string) error { | ||||||
|  | 	if !Enable || !SupportColor() { | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	_, err := fmt.Fprintf(output, SettingTpl, code) | ||||||
|  | 	return err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ResetTerminal terminal setting.
 | ||||||
|  | func ResetTerminal() error { | ||||||
|  | 	if !Enable || !SupportColor() { | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	_, err := fmt.Fprint(output, ResetSet) | ||||||
|  | 	return err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /************************************************************* | ||||||
|  |  * print methods(will auto parse color tags) | ||||||
|  |  *************************************************************/ | ||||||
|  | 
 | ||||||
|  | // Print render color tag and print messages
 | ||||||
|  | func Print(a ...interface{}) { | ||||||
|  | 	Fprint(output, a...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Printf format and print messages
 | ||||||
|  | func Printf(format string, a ...interface{}) { | ||||||
|  | 	Fprintf(output, format, a...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Println messages with new line
 | ||||||
|  | func Println(a ...interface{}) { | ||||||
|  | 	Fprintln(output, a...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Fprint print rendered messages to writer
 | ||||||
|  | // Notice: will ignore print error
 | ||||||
|  | func Fprint(w io.Writer, a ...interface{}) { | ||||||
|  | 	_, err := fmt.Fprint(w, Render(a...)) | ||||||
|  | 	saveInternalError(err) | ||||||
|  | 
 | ||||||
|  | 	// if isLikeInCmd {
 | ||||||
|  | 	// 	renderColorCodeOnCmd(func() {
 | ||||||
|  | 	// 		_, _ = fmt.Fprint(w, Render(a...))
 | ||||||
|  | 	// 	})
 | ||||||
|  | 	// } else {
 | ||||||
|  | 	// 	_, _ = fmt.Fprint(w, Render(a...))
 | ||||||
|  | 	// }
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Fprintf print format and rendered messages to writer.
 | ||||||
|  | // Notice: will ignore print error
 | ||||||
|  | func Fprintf(w io.Writer, format string, a ...interface{}) { | ||||||
|  | 	str := fmt.Sprintf(format, a...) | ||||||
|  | 	_, err := fmt.Fprint(w, ReplaceTag(str)) | ||||||
|  | 	saveInternalError(err) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Fprintln print rendered messages line to writer
 | ||||||
|  | // Notice: will ignore print error
 | ||||||
|  | func Fprintln(w io.Writer, a ...interface{}) { | ||||||
|  | 	str := formatArgsForPrintln(a) | ||||||
|  | 	_, err := fmt.Fprintln(w, ReplaceTag(str)) | ||||||
|  | 	saveInternalError(err) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Lprint passes colored messages to a log.Logger for printing.
 | ||||||
|  | // Notice: should be goroutine safe
 | ||||||
|  | func Lprint(l *log.Logger, a ...interface{}) { | ||||||
|  | 	l.Print(Render(a...)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Render parse color tags, return rendered string.
 | ||||||
|  | // Usage:
 | ||||||
|  | //	text := Render("<info>hello</> <cyan>world</>!")
 | ||||||
|  | //	fmt.Println(text)
 | ||||||
|  | func Render(a ...interface{}) string { | ||||||
|  | 	if len(a) == 0 { | ||||||
|  | 		return "" | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return ReplaceTag(fmt.Sprint(a...)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Sprint parse color tags, return rendered string
 | ||||||
|  | func Sprint(a ...interface{}) string { | ||||||
|  | 	if len(a) == 0 { | ||||||
|  | 		return "" | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return ReplaceTag(fmt.Sprint(a...)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Sprintf format and return rendered string
 | ||||||
|  | func Sprintf(format string, a ...interface{}) string { | ||||||
|  | 	return ReplaceTag(fmt.Sprintf(format, a...)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // String alias of the ReplaceTag
 | ||||||
|  | func String(s string) string { | ||||||
|  | 	return ReplaceTag(s) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Text alias of the ReplaceTag
 | ||||||
|  | func Text(s string) string { | ||||||
|  | 	return ReplaceTag(s) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /************************************************************* | ||||||
|  |  * helper methods for print | ||||||
|  |  *************************************************************/ | ||||||
|  | 
 | ||||||
|  | // new implementation, support render full color code on pwsh.exe, cmd.exe
 | ||||||
|  | func doPrintV2(code, str string) { | ||||||
|  | 	_, err := fmt.Fprint(output, RenderString(code, str)) | ||||||
|  | 	saveInternalError(err) | ||||||
|  | 
 | ||||||
|  | 	// if isLikeInCmd {
 | ||||||
|  | 	// 	renderColorCodeOnCmd(func() {
 | ||||||
|  | 	// 		_, _ = fmt.Fprint(output, RenderString(code, str))
 | ||||||
|  | 	// 	})
 | ||||||
|  | 	// } else {
 | ||||||
|  | 	// 	_, _ = fmt.Fprint(output, RenderString(code, str))
 | ||||||
|  | 	// }
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // new implementation, support render full color code on pwsh.exe, cmd.exe
 | ||||||
|  | func doPrintlnV2(code string, args []interface{}) { | ||||||
|  | 	str := formatArgsForPrintln(args) | ||||||
|  | 	_, err := fmt.Fprintln(output, RenderString(code, str)) | ||||||
|  | 	saveInternalError(err) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // if use Println, will add spaces for each arg
 | ||||||
|  | func formatArgsForPrintln(args []interface{}) (message string) { | ||||||
|  | 	if ln := len(args); ln == 0 { | ||||||
|  | 		message = "" | ||||||
|  | 	} else if ln == 1 { | ||||||
|  | 		message = fmt.Sprint(args[0]) | ||||||
|  | 	} else { | ||||||
|  | 		message = fmt.Sprintln(args...) | ||||||
|  | 		// clear last "\n"
 | ||||||
|  | 		message = message[:len(message)-1] | ||||||
|  | 	} | ||||||
|  | 	return | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /************************************************************* | ||||||
|  |  * helper methods | ||||||
|  |  *************************************************************/ | ||||||
|  | 
 | ||||||
|  | // is on debug mode
 | ||||||
|  | // func isDebugMode() bool {
 | ||||||
|  | // 	return debugMode == "on"
 | ||||||
|  | // }
 | ||||||
|  | 
 | ||||||
|  | func debugf(f string, v ...interface{}) { | ||||||
|  | 	if debugMode { | ||||||
|  | 		fmt.Print("COLOR_DEBUG: ") | ||||||
|  | 		fmt.Printf(f, v...) | ||||||
|  | 		fmt.Println() | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // equals: return ok ? val1 : val2
 | ||||||
|  | func compareVal(ok bool, val1, val2 uint8) uint8 { | ||||||
|  | 	if ok { | ||||||
|  | 		return val1 | ||||||
|  | 	} | ||||||
|  | 	return val2 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func saveInternalError(err error) { | ||||||
|  | 	if err != nil { | ||||||
|  | 		debugf("inner error: %s", err.Error()) | ||||||
|  | 		innerErrs = append(innerErrs, err) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func stringToArr(str, sep string) (arr []string) { | ||||||
|  | 	str = strings.TrimSpace(str) | ||||||
|  | 	if str == "" { | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	ss := strings.Split(str, sep) | ||||||
|  | 	for _, val := range ss { | ||||||
|  | 		if val = strings.TrimSpace(val); val != "" { | ||||||
|  | 			arr = append(arr, val) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return | ||||||
|  | } | ||||||
							
								
								
									
										16
									
								
								vendor/github.com/mattn/go-runewidth/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								vendor/github.com/mattn/go-runewidth/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,16 @@ | |||||||
|  | language: go | ||||||
|  | sudo: false | ||||||
|  | go: | ||||||
|  |   - 1.13.x | ||||||
|  |   - tip | ||||||
|  | 
 | ||||||
|  | before_install: | ||||||
|  |   - go get -t -v ./... | ||||||
|  | 
 | ||||||
|  | script: | ||||||
|  |   - go generate | ||||||
|  |   - git diff --cached --exit-code | ||||||
|  |   - ./go.test.sh | ||||||
|  | 
 | ||||||
|  | after_success: | ||||||
|  |   - bash <(curl -s https://codecov.io/bash) | ||||||
							
								
								
									
										21
									
								
								vendor/github.com/mattn/go-runewidth/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								vendor/github.com/mattn/go-runewidth/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,21 @@ | |||||||
|  | The MIT License (MIT) | ||||||
|  | 
 | ||||||
|  | Copyright (c) 2016 Yasuhiro Matsumoto | ||||||
|  | 
 | ||||||
|  | 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. | ||||||
							
								
								
									
										27
									
								
								vendor/github.com/mattn/go-runewidth/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								vendor/github.com/mattn/go-runewidth/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,27 @@ | |||||||
|  | go-runewidth | ||||||
|  | ============ | ||||||
|  | 
 | ||||||
|  | [](https://travis-ci.org/mattn/go-runewidth) | ||||||
|  | [](https://codecov.io/gh/mattn/go-runewidth) | ||||||
|  | [](http://godoc.org/github.com/mattn/go-runewidth) | ||||||
|  | [](https://goreportcard.com/report/github.com/mattn/go-runewidth) | ||||||
|  | 
 | ||||||
|  | Provides functions to get fixed width of the character or string. | ||||||
|  | 
 | ||||||
|  | Usage | ||||||
|  | ----- | ||||||
|  | 
 | ||||||
|  | ```go | ||||||
|  | runewidth.StringWidth("つのだ☆HIRO") == 12 | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | Author | ||||||
|  | ------ | ||||||
|  | 
 | ||||||
|  | Yasuhiro Matsumoto | ||||||
|  | 
 | ||||||
|  | License | ||||||
|  | ------- | ||||||
|  | 
 | ||||||
|  | under the MIT License: http://mattn.mit-license.org/2013 | ||||||
							
								
								
									
										5
									
								
								vendor/github.com/mattn/go-runewidth/go.mod
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								vendor/github.com/mattn/go-runewidth/go.mod
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,5 @@ | |||||||
|  | module github.com/mattn/go-runewidth | ||||||
|  | 
 | ||||||
|  | go 1.9 | ||||||
|  | 
 | ||||||
|  | require github.com/rivo/uniseg v0.2.0 | ||||||
							
								
								
									
										2
									
								
								vendor/github.com/mattn/go-runewidth/go.sum
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/mattn/go-runewidth/go.sum
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,2 @@ | |||||||
|  | github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= | ||||||
|  | github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= | ||||||
							
								
								
									
										12
									
								
								vendor/github.com/mattn/go-runewidth/go.test.sh
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								vendor/github.com/mattn/go-runewidth/go.test.sh
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,12 @@ | |||||||
|  | #!/usr/bin/env bash | ||||||
|  | 
 | ||||||
|  | set -e | ||||||
|  | echo "" > coverage.txt | ||||||
|  | 
 | ||||||
|  | for d in $(go list ./... | grep -v vendor); do | ||||||
|  |     go test -race -coverprofile=profile.out -covermode=atomic "$d" | ||||||
|  |     if [ -f profile.out ]; then | ||||||
|  |         cat profile.out >> coverage.txt | ||||||
|  |         rm profile.out | ||||||
|  |     fi | ||||||
|  | done | ||||||
							
								
								
									
										273
									
								
								vendor/github.com/mattn/go-runewidth/runewidth.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										273
									
								
								vendor/github.com/mattn/go-runewidth/runewidth.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,273 @@ | |||||||
|  | package runewidth | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"os" | ||||||
|  | 
 | ||||||
|  | 	"github.com/rivo/uniseg" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | //go:generate go run script/generate.go
 | ||||||
|  | 
 | ||||||
|  | var ( | ||||||
|  | 	// EastAsianWidth will be set true if the current locale is CJK
 | ||||||
|  | 	EastAsianWidth bool | ||||||
|  | 
 | ||||||
|  | 	// StrictEmojiNeutral should be set false if handle broken fonts
 | ||||||
|  | 	StrictEmojiNeutral bool = true | ||||||
|  | 
 | ||||||
|  | 	// DefaultCondition is a condition in current locale
 | ||||||
|  | 	DefaultCondition = &Condition{ | ||||||
|  | 		EastAsianWidth:     false, | ||||||
|  | 		StrictEmojiNeutral: true, | ||||||
|  | 	} | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | func init() { | ||||||
|  | 	handleEnv() | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func handleEnv() { | ||||||
|  | 	env := os.Getenv("RUNEWIDTH_EASTASIAN") | ||||||
|  | 	if env == "" { | ||||||
|  | 		EastAsianWidth = IsEastAsian() | ||||||
|  | 	} else { | ||||||
|  | 		EastAsianWidth = env == "1" | ||||||
|  | 	} | ||||||
|  | 	// update DefaultCondition
 | ||||||
|  | 	DefaultCondition.EastAsianWidth = EastAsianWidth | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | type interval struct { | ||||||
|  | 	first rune | ||||||
|  | 	last  rune | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | type table []interval | ||||||
|  | 
 | ||||||
|  | func inTables(r rune, ts ...table) bool { | ||||||
|  | 	for _, t := range ts { | ||||||
|  | 		if inTable(r, t) { | ||||||
|  | 			return true | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return false | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func inTable(r rune, t table) bool { | ||||||
|  | 	if r < t[0].first { | ||||||
|  | 		return false | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	bot := 0 | ||||||
|  | 	top := len(t) - 1 | ||||||
|  | 	for top >= bot { | ||||||
|  | 		mid := (bot + top) >> 1 | ||||||
|  | 
 | ||||||
|  | 		switch { | ||||||
|  | 		case t[mid].last < r: | ||||||
|  | 			bot = mid + 1 | ||||||
|  | 		case t[mid].first > r: | ||||||
|  | 			top = mid - 1 | ||||||
|  | 		default: | ||||||
|  | 			return true | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return false | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | var private = table{ | ||||||
|  | 	{0x00E000, 0x00F8FF}, {0x0F0000, 0x0FFFFD}, {0x100000, 0x10FFFD}, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | var nonprint = table{ | ||||||
|  | 	{0x0000, 0x001F}, {0x007F, 0x009F}, {0x00AD, 0x00AD}, | ||||||
|  | 	{0x070F, 0x070F}, {0x180B, 0x180E}, {0x200B, 0x200F}, | ||||||
|  | 	{0x2028, 0x202E}, {0x206A, 0x206F}, {0xD800, 0xDFFF}, | ||||||
|  | 	{0xFEFF, 0xFEFF}, {0xFFF9, 0xFFFB}, {0xFFFE, 0xFFFF}, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Condition have flag EastAsianWidth whether the current locale is CJK or not.
 | ||||||
|  | type Condition struct { | ||||||
|  | 	EastAsianWidth     bool | ||||||
|  | 	StrictEmojiNeutral bool | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // NewCondition return new instance of Condition which is current locale.
 | ||||||
|  | func NewCondition() *Condition { | ||||||
|  | 	return &Condition{ | ||||||
|  | 		EastAsianWidth:     EastAsianWidth, | ||||||
|  | 		StrictEmojiNeutral: StrictEmojiNeutral, | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // RuneWidth returns the number of cells in r.
 | ||||||
|  | // See http://www.unicode.org/reports/tr11/
 | ||||||
|  | func (c *Condition) RuneWidth(r rune) int { | ||||||
|  | 	// optimized version, verified by TestRuneWidthChecksums()
 | ||||||
|  | 	if !c.EastAsianWidth { | ||||||
|  | 		switch { | ||||||
|  | 		case r < 0x20 || r > 0x10FFFF: | ||||||
|  | 			return 0 | ||||||
|  | 		case (r >= 0x7F && r <= 0x9F) || r == 0xAD: // nonprint
 | ||||||
|  | 			return 0 | ||||||
|  | 		case r < 0x300: | ||||||
|  | 			return 1 | ||||||
|  | 		case inTable(r, narrow): | ||||||
|  | 			return 1 | ||||||
|  | 		case inTables(r, nonprint, combining): | ||||||
|  | 			return 0 | ||||||
|  | 		case inTable(r, doublewidth): | ||||||
|  | 			return 2 | ||||||
|  | 		default: | ||||||
|  | 			return 1 | ||||||
|  | 		} | ||||||
|  | 	} else { | ||||||
|  | 		switch { | ||||||
|  | 		case r < 0 || r > 0x10FFFF || inTables(r, nonprint, combining): | ||||||
|  | 			return 0 | ||||||
|  | 		case inTable(r, narrow): | ||||||
|  | 			return 1 | ||||||
|  | 		case inTables(r, ambiguous, doublewidth): | ||||||
|  | 			return 2 | ||||||
|  | 		case !c.StrictEmojiNeutral && inTables(r, ambiguous, emoji, narrow): | ||||||
|  | 			return 2 | ||||||
|  | 		default: | ||||||
|  | 			return 1 | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // StringWidth return width as you can see
 | ||||||
|  | func (c *Condition) StringWidth(s string) (width int) { | ||||||
|  | 	g := uniseg.NewGraphemes(s) | ||||||
|  | 	for g.Next() { | ||||||
|  | 		var chWidth int | ||||||
|  | 		for _, r := range g.Runes() { | ||||||
|  | 			chWidth = c.RuneWidth(r) | ||||||
|  | 			if chWidth > 0 { | ||||||
|  | 				break // Our best guess at this point is to use the width of the first non-zero-width rune.
 | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		width += chWidth | ||||||
|  | 	} | ||||||
|  | 	return | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Truncate return string truncated with w cells
 | ||||||
|  | func (c *Condition) Truncate(s string, w int, tail string) string { | ||||||
|  | 	if c.StringWidth(s) <= w { | ||||||
|  | 		return s | ||||||
|  | 	} | ||||||
|  | 	w -= c.StringWidth(tail) | ||||||
|  | 	var width int | ||||||
|  | 	pos := len(s) | ||||||
|  | 	g := uniseg.NewGraphemes(s) | ||||||
|  | 	for g.Next() { | ||||||
|  | 		var chWidth int | ||||||
|  | 		for _, r := range g.Runes() { | ||||||
|  | 			chWidth = c.RuneWidth(r) | ||||||
|  | 			if chWidth > 0 { | ||||||
|  | 				break // See StringWidth() for details.
 | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		if width+chWidth > w { | ||||||
|  | 			pos, _ = g.Positions() | ||||||
|  | 			break | ||||||
|  | 		} | ||||||
|  | 		width += chWidth | ||||||
|  | 	} | ||||||
|  | 	return s[:pos] + tail | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Wrap return string wrapped with w cells
 | ||||||
|  | func (c *Condition) Wrap(s string, w int) string { | ||||||
|  | 	width := 0 | ||||||
|  | 	out := "" | ||||||
|  | 	for _, r := range []rune(s) { | ||||||
|  | 		cw := c.RuneWidth(r) | ||||||
|  | 		if r == '\n' { | ||||||
|  | 			out += string(r) | ||||||
|  | 			width = 0 | ||||||
|  | 			continue | ||||||
|  | 		} else if width+cw > w { | ||||||
|  | 			out += "\n" | ||||||
|  | 			width = 0 | ||||||
|  | 			out += string(r) | ||||||
|  | 			width += cw | ||||||
|  | 			continue | ||||||
|  | 		} | ||||||
|  | 		out += string(r) | ||||||
|  | 		width += cw | ||||||
|  | 	} | ||||||
|  | 	return out | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // FillLeft return string filled in left by spaces in w cells
 | ||||||
|  | func (c *Condition) FillLeft(s string, w int) string { | ||||||
|  | 	width := c.StringWidth(s) | ||||||
|  | 	count := w - width | ||||||
|  | 	if count > 0 { | ||||||
|  | 		b := make([]byte, count) | ||||||
|  | 		for i := range b { | ||||||
|  | 			b[i] = ' ' | ||||||
|  | 		} | ||||||
|  | 		return string(b) + s | ||||||
|  | 	} | ||||||
|  | 	return s | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // FillRight return string filled in left by spaces in w cells
 | ||||||
|  | func (c *Condition) FillRight(s string, w int) string { | ||||||
|  | 	width := c.StringWidth(s) | ||||||
|  | 	count := w - width | ||||||
|  | 	if count > 0 { | ||||||
|  | 		b := make([]byte, count) | ||||||
|  | 		for i := range b { | ||||||
|  | 			b[i] = ' ' | ||||||
|  | 		} | ||||||
|  | 		return s + string(b) | ||||||
|  | 	} | ||||||
|  | 	return s | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // RuneWidth returns the number of cells in r.
 | ||||||
|  | // See http://www.unicode.org/reports/tr11/
 | ||||||
|  | func RuneWidth(r rune) int { | ||||||
|  | 	return DefaultCondition.RuneWidth(r) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // IsAmbiguousWidth returns whether is ambiguous width or not.
 | ||||||
|  | func IsAmbiguousWidth(r rune) bool { | ||||||
|  | 	return inTables(r, private, ambiguous) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // IsNeutralWidth returns whether is neutral width or not.
 | ||||||
|  | func IsNeutralWidth(r rune) bool { | ||||||
|  | 	return inTable(r, neutral) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // StringWidth return width as you can see
 | ||||||
|  | func StringWidth(s string) (width int) { | ||||||
|  | 	return DefaultCondition.StringWidth(s) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Truncate return string truncated with w cells
 | ||||||
|  | func Truncate(s string, w int, tail string) string { | ||||||
|  | 	return DefaultCondition.Truncate(s, w, tail) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Wrap return string wrapped with w cells
 | ||||||
|  | func Wrap(s string, w int) string { | ||||||
|  | 	return DefaultCondition.Wrap(s, w) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // FillLeft return string filled in left by spaces in w cells
 | ||||||
|  | func FillLeft(s string, w int) string { | ||||||
|  | 	return DefaultCondition.FillLeft(s, w) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // FillRight return string filled in left by spaces in w cells
 | ||||||
|  | func FillRight(s string, w int) string { | ||||||
|  | 	return DefaultCondition.FillRight(s, w) | ||||||
|  | } | ||||||
							
								
								
									
										8
									
								
								vendor/github.com/mattn/go-runewidth/runewidth_appengine.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								vendor/github.com/mattn/go-runewidth/runewidth_appengine.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,8 @@ | |||||||
|  | // +build appengine
 | ||||||
|  | 
 | ||||||
|  | package runewidth | ||||||
|  | 
 | ||||||
|  | // IsEastAsian return true if the current locale is CJK
 | ||||||
|  | func IsEastAsian() bool { | ||||||
|  | 	return false | ||||||
|  | } | ||||||
							
								
								
									
										9
									
								
								vendor/github.com/mattn/go-runewidth/runewidth_js.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								vendor/github.com/mattn/go-runewidth/runewidth_js.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,9 @@ | |||||||
|  | // +build js
 | ||||||
|  | // +build !appengine
 | ||||||
|  | 
 | ||||||
|  | package runewidth | ||||||
|  | 
 | ||||||
|  | func IsEastAsian() bool { | ||||||
|  | 	// TODO: Implement this for the web. Detect east asian in a compatible way, and return true.
 | ||||||
|  | 	return false | ||||||
|  | } | ||||||
							
								
								
									
										82
									
								
								vendor/github.com/mattn/go-runewidth/runewidth_posix.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								vendor/github.com/mattn/go-runewidth/runewidth_posix.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,82 @@ | |||||||
|  | // +build !windows
 | ||||||
|  | // +build !js
 | ||||||
|  | // +build !appengine
 | ||||||
|  | 
 | ||||||
|  | package runewidth | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"os" | ||||||
|  | 	"regexp" | ||||||
|  | 	"strings" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | var reLoc = regexp.MustCompile(`^[a-z][a-z][a-z]?(?:_[A-Z][A-Z])?\.(.+)`) | ||||||
|  | 
 | ||||||
|  | var mblenTable = map[string]int{ | ||||||
|  | 	"utf-8":   6, | ||||||
|  | 	"utf8":    6, | ||||||
|  | 	"jis":     8, | ||||||
|  | 	"eucjp":   3, | ||||||
|  | 	"euckr":   2, | ||||||
|  | 	"euccn":   2, | ||||||
|  | 	"sjis":    2, | ||||||
|  | 	"cp932":   2, | ||||||
|  | 	"cp51932": 2, | ||||||
|  | 	"cp936":   2, | ||||||
|  | 	"cp949":   2, | ||||||
|  | 	"cp950":   2, | ||||||
|  | 	"big5":    2, | ||||||
|  | 	"gbk":     2, | ||||||
|  | 	"gb2312":  2, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func isEastAsian(locale string) bool { | ||||||
|  | 	charset := strings.ToLower(locale) | ||||||
|  | 	r := reLoc.FindStringSubmatch(locale) | ||||||
|  | 	if len(r) == 2 { | ||||||
|  | 		charset = strings.ToLower(r[1]) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if strings.HasSuffix(charset, "@cjk_narrow") { | ||||||
|  | 		return false | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	for pos, b := range []byte(charset) { | ||||||
|  | 		if b == '@' { | ||||||
|  | 			charset = charset[:pos] | ||||||
|  | 			break | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	max := 1 | ||||||
|  | 	if m, ok := mblenTable[charset]; ok { | ||||||
|  | 		max = m | ||||||
|  | 	} | ||||||
|  | 	if max > 1 && (charset[0] != 'u' || | ||||||
|  | 		strings.HasPrefix(locale, "ja") || | ||||||
|  | 		strings.HasPrefix(locale, "ko") || | ||||||
|  | 		strings.HasPrefix(locale, "zh")) { | ||||||
|  | 		return true | ||||||
|  | 	} | ||||||
|  | 	return false | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // IsEastAsian return true if the current locale is CJK
 | ||||||
|  | func IsEastAsian() bool { | ||||||
|  | 	locale := os.Getenv("LC_ALL") | ||||||
|  | 	if locale == "" { | ||||||
|  | 		locale = os.Getenv("LC_CTYPE") | ||||||
|  | 	} | ||||||
|  | 	if locale == "" { | ||||||
|  | 		locale = os.Getenv("LANG") | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// ignore C locale
 | ||||||
|  | 	if locale == "POSIX" || locale == "C" { | ||||||
|  | 		return false | ||||||
|  | 	} | ||||||
|  | 	if len(locale) > 1 && locale[0] == 'C' && (locale[1] == '.' || locale[1] == '-') { | ||||||
|  | 		return false | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return isEastAsian(locale) | ||||||
|  | } | ||||||
							
								
								
									
										439
									
								
								vendor/github.com/mattn/go-runewidth/runewidth_table.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										439
									
								
								vendor/github.com/mattn/go-runewidth/runewidth_table.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,439 @@ | |||||||
|  | // Code generated by script/generate.go. DO NOT EDIT.
 | ||||||
|  | 
 | ||||||
|  | package runewidth | ||||||
|  | 
 | ||||||
|  | var combining = table{ | ||||||
|  | 	{0x0300, 0x036F}, {0x0483, 0x0489}, {0x07EB, 0x07F3}, | ||||||
|  | 	{0x0C00, 0x0C00}, {0x0C04, 0x0C04}, {0x0D00, 0x0D01}, | ||||||
|  | 	{0x135D, 0x135F}, {0x1A7F, 0x1A7F}, {0x1AB0, 0x1AC0}, | ||||||
|  | 	{0x1B6B, 0x1B73}, {0x1DC0, 0x1DF9}, {0x1DFB, 0x1DFF}, | ||||||
|  | 	{0x20D0, 0x20F0}, {0x2CEF, 0x2CF1}, {0x2DE0, 0x2DFF}, | ||||||
|  | 	{0x3099, 0x309A}, {0xA66F, 0xA672}, {0xA674, 0xA67D}, | ||||||
|  | 	{0xA69E, 0xA69F}, {0xA6F0, 0xA6F1}, {0xA8E0, 0xA8F1}, | ||||||
|  | 	{0xFE20, 0xFE2F}, {0x101FD, 0x101FD}, {0x10376, 0x1037A}, | ||||||
|  | 	{0x10EAB, 0x10EAC}, {0x10F46, 0x10F50}, {0x11300, 0x11301}, | ||||||
|  | 	{0x1133B, 0x1133C}, {0x11366, 0x1136C}, {0x11370, 0x11374}, | ||||||
|  | 	{0x16AF0, 0x16AF4}, {0x1D165, 0x1D169}, {0x1D16D, 0x1D172}, | ||||||
|  | 	{0x1D17B, 0x1D182}, {0x1D185, 0x1D18B}, {0x1D1AA, 0x1D1AD}, | ||||||
|  | 	{0x1D242, 0x1D244}, {0x1E000, 0x1E006}, {0x1E008, 0x1E018}, | ||||||
|  | 	{0x1E01B, 0x1E021}, {0x1E023, 0x1E024}, {0x1E026, 0x1E02A}, | ||||||
|  | 	{0x1E8D0, 0x1E8D6}, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | var doublewidth = table{ | ||||||
|  | 	{0x1100, 0x115F}, {0x231A, 0x231B}, {0x2329, 0x232A}, | ||||||
|  | 	{0x23E9, 0x23EC}, {0x23F0, 0x23F0}, {0x23F3, 0x23F3}, | ||||||
|  | 	{0x25FD, 0x25FE}, {0x2614, 0x2615}, {0x2648, 0x2653}, | ||||||
|  | 	{0x267F, 0x267F}, {0x2693, 0x2693}, {0x26A1, 0x26A1}, | ||||||
|  | 	{0x26AA, 0x26AB}, {0x26BD, 0x26BE}, {0x26C4, 0x26C5}, | ||||||
|  | 	{0x26CE, 0x26CE}, {0x26D4, 0x26D4}, {0x26EA, 0x26EA}, | ||||||
|  | 	{0x26F2, 0x26F3}, {0x26F5, 0x26F5}, {0x26FA, 0x26FA}, | ||||||
|  | 	{0x26FD, 0x26FD}, {0x2705, 0x2705}, {0x270A, 0x270B}, | ||||||
|  | 	{0x2728, 0x2728}, {0x274C, 0x274C}, {0x274E, 0x274E}, | ||||||
|  | 	{0x2753, 0x2755}, {0x2757, 0x2757}, {0x2795, 0x2797}, | ||||||
|  | 	{0x27B0, 0x27B0}, {0x27BF, 0x27BF}, {0x2B1B, 0x2B1C}, | ||||||
|  | 	{0x2B50, 0x2B50}, {0x2B55, 0x2B55}, {0x2E80, 0x2E99}, | ||||||
|  | 	{0x2E9B, 0x2EF3}, {0x2F00, 0x2FD5}, {0x2FF0, 0x2FFB}, | ||||||
|  | 	{0x3000, 0x303E}, {0x3041, 0x3096}, {0x3099, 0x30FF}, | ||||||
|  | 	{0x3105, 0x312F}, {0x3131, 0x318E}, {0x3190, 0x31E3}, | ||||||
|  | 	{0x31F0, 0x321E}, {0x3220, 0x3247}, {0x3250, 0x4DBF}, | ||||||
|  | 	{0x4E00, 0xA48C}, {0xA490, 0xA4C6}, {0xA960, 0xA97C}, | ||||||
|  | 	{0xAC00, 0xD7A3}, {0xF900, 0xFAFF}, {0xFE10, 0xFE19}, | ||||||
|  | 	{0xFE30, 0xFE52}, {0xFE54, 0xFE66}, {0xFE68, 0xFE6B}, | ||||||
|  | 	{0xFF01, 0xFF60}, {0xFFE0, 0xFFE6}, {0x16FE0, 0x16FE4}, | ||||||
|  | 	{0x16FF0, 0x16FF1}, {0x17000, 0x187F7}, {0x18800, 0x18CD5}, | ||||||
|  | 	{0x18D00, 0x18D08}, {0x1B000, 0x1B11E}, {0x1B150, 0x1B152}, | ||||||
|  | 	{0x1B164, 0x1B167}, {0x1B170, 0x1B2FB}, {0x1F004, 0x1F004}, | ||||||
|  | 	{0x1F0CF, 0x1F0CF}, {0x1F18E, 0x1F18E}, {0x1F191, 0x1F19A}, | ||||||
|  | 	{0x1F200, 0x1F202}, {0x1F210, 0x1F23B}, {0x1F240, 0x1F248}, | ||||||
|  | 	{0x1F250, 0x1F251}, {0x1F260, 0x1F265}, {0x1F300, 0x1F320}, | ||||||
|  | 	{0x1F32D, 0x1F335}, {0x1F337, 0x1F37C}, {0x1F37E, 0x1F393}, | ||||||
|  | 	{0x1F3A0, 0x1F3CA}, {0x1F3CF, 0x1F3D3}, {0x1F3E0, 0x1F3F0}, | ||||||
|  | 	{0x1F3F4, 0x1F3F4}, {0x1F3F8, 0x1F43E}, {0x1F440, 0x1F440}, | ||||||
|  | 	{0x1F442, 0x1F4FC}, {0x1F4FF, 0x1F53D}, {0x1F54B, 0x1F54E}, | ||||||
|  | 	{0x1F550, 0x1F567}, {0x1F57A, 0x1F57A}, {0x1F595, 0x1F596}, | ||||||
|  | 	{0x1F5A4, 0x1F5A4}, {0x1F5FB, 0x1F64F}, {0x1F680, 0x1F6C5}, | ||||||
|  | 	{0x1F6CC, 0x1F6CC}, {0x1F6D0, 0x1F6D2}, {0x1F6D5, 0x1F6D7}, | ||||||
|  | 	{0x1F6EB, 0x1F6EC}, {0x1F6F4, 0x1F6FC}, {0x1F7E0, 0x1F7EB}, | ||||||
|  | 	{0x1F90C, 0x1F93A}, {0x1F93C, 0x1F945}, {0x1F947, 0x1F978}, | ||||||
|  | 	{0x1F97A, 0x1F9CB}, {0x1F9CD, 0x1F9FF}, {0x1FA70, 0x1FA74}, | ||||||
|  | 	{0x1FA78, 0x1FA7A}, {0x1FA80, 0x1FA86}, {0x1FA90, 0x1FAA8}, | ||||||
|  | 	{0x1FAB0, 0x1FAB6}, {0x1FAC0, 0x1FAC2}, {0x1FAD0, 0x1FAD6}, | ||||||
|  | 	{0x20000, 0x2FFFD}, {0x30000, 0x3FFFD}, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | var ambiguous = table{ | ||||||
|  | 	{0x00A1, 0x00A1}, {0x00A4, 0x00A4}, {0x00A7, 0x00A8}, | ||||||
|  | 	{0x00AA, 0x00AA}, {0x00AD, 0x00AE}, {0x00B0, 0x00B4}, | ||||||
|  | 	{0x00B6, 0x00BA}, {0x00BC, 0x00BF}, {0x00C6, 0x00C6}, | ||||||
|  | 	{0x00D0, 0x00D0}, {0x00D7, 0x00D8}, {0x00DE, 0x00E1}, | ||||||
|  | 	{0x00E6, 0x00E6}, {0x00E8, 0x00EA}, {0x00EC, 0x00ED}, | ||||||
|  | 	{0x00F0, 0x00F0}, {0x00F2, 0x00F3}, {0x00F7, 0x00FA}, | ||||||
|  | 	{0x00FC, 0x00FC}, {0x00FE, 0x00FE}, {0x0101, 0x0101}, | ||||||
|  | 	{0x0111, 0x0111}, {0x0113, 0x0113}, {0x011B, 0x011B}, | ||||||
|  | 	{0x0126, 0x0127}, {0x012B, 0x012B}, {0x0131, 0x0133}, | ||||||
|  | 	{0x0138, 0x0138}, {0x013F, 0x0142}, {0x0144, 0x0144}, | ||||||
|  | 	{0x0148, 0x014B}, {0x014D, 0x014D}, {0x0152, 0x0153}, | ||||||
|  | 	{0x0166, 0x0167}, {0x016B, 0x016B}, {0x01CE, 0x01CE}, | ||||||
|  | 	{0x01D0, 0x01D0}, {0x01D2, 0x01D2}, {0x01D4, 0x01D4}, | ||||||
|  | 	{0x01D6, 0x01D6}, {0x01D8, 0x01D8}, {0x01DA, 0x01DA}, | ||||||
|  | 	{0x01DC, 0x01DC}, {0x0251, 0x0251}, {0x0261, 0x0261}, | ||||||
|  | 	{0x02C4, 0x02C4}, {0x02C7, 0x02C7}, {0x02C9, 0x02CB}, | ||||||
|  | 	{0x02CD, 0x02CD}, {0x02D0, 0x02D0}, {0x02D8, 0x02DB}, | ||||||
|  | 	{0x02DD, 0x02DD}, {0x02DF, 0x02DF}, {0x0300, 0x036F}, | ||||||
|  | 	{0x0391, 0x03A1}, {0x03A3, 0x03A9}, {0x03B1, 0x03C1}, | ||||||
|  | 	{0x03C3, 0x03C9}, {0x0401, 0x0401}, {0x0410, 0x044F}, | ||||||
|  | 	{0x0451, 0x0451}, {0x2010, 0x2010}, {0x2013, 0x2016}, | ||||||
|  | 	{0x2018, 0x2019}, {0x201C, 0x201D}, {0x2020, 0x2022}, | ||||||
|  | 	{0x2024, 0x2027}, {0x2030, 0x2030}, {0x2032, 0x2033}, | ||||||
|  | 	{0x2035, 0x2035}, {0x203B, 0x203B}, {0x203E, 0x203E}, | ||||||
|  | 	{0x2074, 0x2074}, {0x207F, 0x207F}, {0x2081, 0x2084}, | ||||||
|  | 	{0x20AC, 0x20AC}, {0x2103, 0x2103}, {0x2105, 0x2105}, | ||||||
|  | 	{0x2109, 0x2109}, {0x2113, 0x2113}, {0x2116, 0x2116}, | ||||||
|  | 	{0x2121, 0x2122}, {0x2126, 0x2126}, {0x212B, 0x212B}, | ||||||
|  | 	{0x2153, 0x2154}, {0x215B, 0x215E}, {0x2160, 0x216B}, | ||||||
|  | 	{0x2170, 0x2179}, {0x2189, 0x2189}, {0x2190, 0x2199}, | ||||||
|  | 	{0x21B8, 0x21B9}, {0x21D2, 0x21D2}, {0x21D4, 0x21D4}, | ||||||
|  | 	{0x21E7, 0x21E7}, {0x2200, 0x2200}, {0x2202, 0x2203}, | ||||||
|  | 	{0x2207, 0x2208}, {0x220B, 0x220B}, {0x220F, 0x220F}, | ||||||
|  | 	{0x2211, 0x2211}, {0x2215, 0x2215}, {0x221A, 0x221A}, | ||||||
|  | 	{0x221D, 0x2220}, {0x2223, 0x2223}, {0x2225, 0x2225}, | ||||||
|  | 	{0x2227, 0x222C}, {0x222E, 0x222E}, {0x2234, 0x2237}, | ||||||
|  | 	{0x223C, 0x223D}, {0x2248, 0x2248}, {0x224C, 0x224C}, | ||||||
|  | 	{0x2252, 0x2252}, {0x2260, 0x2261}, {0x2264, 0x2267}, | ||||||
|  | 	{0x226A, 0x226B}, {0x226E, 0x226F}, {0x2282, 0x2283}, | ||||||
|  | 	{0x2286, 0x2287}, {0x2295, 0x2295}, {0x2299, 0x2299}, | ||||||
|  | 	{0x22A5, 0x22A5}, {0x22BF, 0x22BF}, {0x2312, 0x2312}, | ||||||
|  | 	{0x2460, 0x24E9}, {0x24EB, 0x254B}, {0x2550, 0x2573}, | ||||||
|  | 	{0x2580, 0x258F}, {0x2592, 0x2595}, {0x25A0, 0x25A1}, | ||||||
|  | 	{0x25A3, 0x25A9}, {0x25B2, 0x25B3}, {0x25B6, 0x25B7}, | ||||||
|  | 	{0x25BC, 0x25BD}, {0x25C0, 0x25C1}, {0x25C6, 0x25C8}, | ||||||
|  | 	{0x25CB, 0x25CB}, {0x25CE, 0x25D1}, {0x25E2, 0x25E5}, | ||||||
|  | 	{0x25EF, 0x25EF}, {0x2605, 0x2606}, {0x2609, 0x2609}, | ||||||
|  | 	{0x260E, 0x260F}, {0x261C, 0x261C}, {0x261E, 0x261E}, | ||||||
|  | 	{0x2640, 0x2640}, {0x2642, 0x2642}, {0x2660, 0x2661}, | ||||||
|  | 	{0x2663, 0x2665}, {0x2667, 0x266A}, {0x266C, 0x266D}, | ||||||
|  | 	{0x266F, 0x266F}, {0x269E, 0x269F}, {0x26BF, 0x26BF}, | ||||||
|  | 	{0x26C6, 0x26CD}, {0x26CF, 0x26D3}, {0x26D5, 0x26E1}, | ||||||
|  | 	{0x26E3, 0x26E3}, {0x26E8, 0x26E9}, {0x26EB, 0x26F1}, | ||||||
|  | 	{0x26F4, 0x26F4}, {0x26F6, 0x26F9}, {0x26FB, 0x26FC}, | ||||||
|  | 	{0x26FE, 0x26FF}, {0x273D, 0x273D}, {0x2776, 0x277F}, | ||||||
|  | 	{0x2B56, 0x2B59}, {0x3248, 0x324F}, {0xE000, 0xF8FF}, | ||||||
|  | 	{0xFE00, 0xFE0F}, {0xFFFD, 0xFFFD}, {0x1F100, 0x1F10A}, | ||||||
|  | 	{0x1F110, 0x1F12D}, {0x1F130, 0x1F169}, {0x1F170, 0x1F18D}, | ||||||
|  | 	{0x1F18F, 0x1F190}, {0x1F19B, 0x1F1AC}, {0xE0100, 0xE01EF}, | ||||||
|  | 	{0xF0000, 0xFFFFD}, {0x100000, 0x10FFFD}, | ||||||
|  | } | ||||||
|  | var narrow = table{ | ||||||
|  | 	{0x0020, 0x007E}, {0x00A2, 0x00A3}, {0x00A5, 0x00A6}, | ||||||
|  | 	{0x00AC, 0x00AC}, {0x00AF, 0x00AF}, {0x27E6, 0x27ED}, | ||||||
|  | 	{0x2985, 0x2986}, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | var neutral = table{ | ||||||
|  | 	{0x0000, 0x001F}, {0x007F, 0x00A0}, {0x00A9, 0x00A9}, | ||||||
|  | 	{0x00AB, 0x00AB}, {0x00B5, 0x00B5}, {0x00BB, 0x00BB}, | ||||||
|  | 	{0x00C0, 0x00C5}, {0x00C7, 0x00CF}, {0x00D1, 0x00D6}, | ||||||
|  | 	{0x00D9, 0x00DD}, {0x00E2, 0x00E5}, {0x00E7, 0x00E7}, | ||||||
|  | 	{0x00EB, 0x00EB}, {0x00EE, 0x00EF}, {0x00F1, 0x00F1}, | ||||||
|  | 	{0x00F4, 0x00F6}, {0x00FB, 0x00FB}, {0x00FD, 0x00FD}, | ||||||
|  | 	{0x00FF, 0x0100}, {0x0102, 0x0110}, {0x0112, 0x0112}, | ||||||
|  | 	{0x0114, 0x011A}, {0x011C, 0x0125}, {0x0128, 0x012A}, | ||||||
|  | 	{0x012C, 0x0130}, {0x0134, 0x0137}, {0x0139, 0x013E}, | ||||||
|  | 	{0x0143, 0x0143}, {0x0145, 0x0147}, {0x014C, 0x014C}, | ||||||
|  | 	{0x014E, 0x0151}, {0x0154, 0x0165}, {0x0168, 0x016A}, | ||||||
|  | 	{0x016C, 0x01CD}, {0x01CF, 0x01CF}, {0x01D1, 0x01D1}, | ||||||
|  | 	{0x01D3, 0x01D3}, {0x01D5, 0x01D5}, {0x01D7, 0x01D7}, | ||||||
|  | 	{0x01D9, 0x01D9}, {0x01DB, 0x01DB}, {0x01DD, 0x0250}, | ||||||
|  | 	{0x0252, 0x0260}, {0x0262, 0x02C3}, {0x02C5, 0x02C6}, | ||||||
|  | 	{0x02C8, 0x02C8}, {0x02CC, 0x02CC}, {0x02CE, 0x02CF}, | ||||||
|  | 	{0x02D1, 0x02D7}, {0x02DC, 0x02DC}, {0x02DE, 0x02DE}, | ||||||
|  | 	{0x02E0, 0x02FF}, {0x0370, 0x0377}, {0x037A, 0x037F}, | ||||||
|  | 	{0x0384, 0x038A}, {0x038C, 0x038C}, {0x038E, 0x0390}, | ||||||
|  | 	{0x03AA, 0x03B0}, {0x03C2, 0x03C2}, {0x03CA, 0x0400}, | ||||||
|  | 	{0x0402, 0x040F}, {0x0450, 0x0450}, {0x0452, 0x052F}, | ||||||
|  | 	{0x0531, 0x0556}, {0x0559, 0x058A}, {0x058D, 0x058F}, | ||||||
|  | 	{0x0591, 0x05C7}, {0x05D0, 0x05EA}, {0x05EF, 0x05F4}, | ||||||
|  | 	{0x0600, 0x061C}, {0x061E, 0x070D}, {0x070F, 0x074A}, | ||||||
|  | 	{0x074D, 0x07B1}, {0x07C0, 0x07FA}, {0x07FD, 0x082D}, | ||||||
|  | 	{0x0830, 0x083E}, {0x0840, 0x085B}, {0x085E, 0x085E}, | ||||||
|  | 	{0x0860, 0x086A}, {0x08A0, 0x08B4}, {0x08B6, 0x08C7}, | ||||||
|  | 	{0x08D3, 0x0983}, {0x0985, 0x098C}, {0x098F, 0x0990}, | ||||||
|  | 	{0x0993, 0x09A8}, {0x09AA, 0x09B0}, {0x09B2, 0x09B2}, | ||||||
|  | 	{0x09B6, 0x09B9}, {0x09BC, 0x09C4}, {0x09C7, 0x09C8}, | ||||||
|  | 	{0x09CB, 0x09CE}, {0x09D7, 0x09D7}, {0x09DC, 0x09DD}, | ||||||
|  | 	{0x09DF, 0x09E3}, {0x09E6, 0x09FE}, {0x0A01, 0x0A03}, | ||||||
|  | 	{0x0A05, 0x0A0A}, {0x0A0F, 0x0A10}, {0x0A13, 0x0A28}, | ||||||
|  | 	{0x0A2A, 0x0A30}, {0x0A32, 0x0A33}, {0x0A35, 0x0A36}, | ||||||
|  | 	{0x0A38, 0x0A39}, {0x0A3C, 0x0A3C}, {0x0A3E, 0x0A42}, | ||||||
|  | 	{0x0A47, 0x0A48}, {0x0A4B, 0x0A4D}, {0x0A51, 0x0A51}, | ||||||
|  | 	{0x0A59, 0x0A5C}, {0x0A5E, 0x0A5E}, {0x0A66, 0x0A76}, | ||||||
|  | 	{0x0A81, 0x0A83}, {0x0A85, 0x0A8D}, {0x0A8F, 0x0A91}, | ||||||
|  | 	{0x0A93, 0x0AA8}, {0x0AAA, 0x0AB0}, {0x0AB2, 0x0AB3}, | ||||||
|  | 	{0x0AB5, 0x0AB9}, {0x0ABC, 0x0AC5}, {0x0AC7, 0x0AC9}, | ||||||
|  | 	{0x0ACB, 0x0ACD}, {0x0AD0, 0x0AD0}, {0x0AE0, 0x0AE3}, | ||||||
|  | 	{0x0AE6, 0x0AF1}, {0x0AF9, 0x0AFF}, {0x0B01, 0x0B03}, | ||||||
|  | 	{0x0B05, 0x0B0C}, {0x0B0F, 0x0B10}, {0x0B13, 0x0B28}, | ||||||
|  | 	{0x0B2A, 0x0B30}, {0x0B32, 0x0B33}, {0x0B35, 0x0B39}, | ||||||
|  | 	{0x0B3C, 0x0B44}, {0x0B47, 0x0B48}, {0x0B4B, 0x0B4D}, | ||||||
|  | 	{0x0B55, 0x0B57}, {0x0B5C, 0x0B5D}, {0x0B5F, 0x0B63}, | ||||||
|  | 	{0x0B66, 0x0B77}, {0x0B82, 0x0B83}, {0x0B85, 0x0B8A}, | ||||||
|  | 	{0x0B8E, 0x0B90}, {0x0B92, 0x0B95}, {0x0B99, 0x0B9A}, | ||||||
|  | 	{0x0B9C, 0x0B9C}, {0x0B9E, 0x0B9F}, {0x0BA3, 0x0BA4}, | ||||||
|  | 	{0x0BA8, 0x0BAA}, {0x0BAE, 0x0BB9}, {0x0BBE, 0x0BC2}, | ||||||
|  | 	{0x0BC6, 0x0BC8}, {0x0BCA, 0x0BCD}, {0x0BD0, 0x0BD0}, | ||||||
|  | 	{0x0BD7, 0x0BD7}, {0x0BE6, 0x0BFA}, {0x0C00, 0x0C0C}, | ||||||
|  | 	{0x0C0E, 0x0C10}, {0x0C12, 0x0C28}, {0x0C2A, 0x0C39}, | ||||||
|  | 	{0x0C3D, 0x0C44}, {0x0C46, 0x0C48}, {0x0C4A, 0x0C4D}, | ||||||
|  | 	{0x0C55, 0x0C56}, {0x0C58, 0x0C5A}, {0x0C60, 0x0C63}, | ||||||
|  | 	{0x0C66, 0x0C6F}, {0x0C77, 0x0C8C}, {0x0C8E, 0x0C90}, | ||||||
|  | 	{0x0C92, 0x0CA8}, {0x0CAA, 0x0CB3}, {0x0CB5, 0x0CB9}, | ||||||
|  | 	{0x0CBC, 0x0CC4}, {0x0CC6, 0x0CC8}, {0x0CCA, 0x0CCD}, | ||||||
|  | 	{0x0CD5, 0x0CD6}, {0x0CDE, 0x0CDE}, {0x0CE0, 0x0CE3}, | ||||||
|  | 	{0x0CE6, 0x0CEF}, {0x0CF1, 0x0CF2}, {0x0D00, 0x0D0C}, | ||||||
|  | 	{0x0D0E, 0x0D10}, {0x0D12, 0x0D44}, {0x0D46, 0x0D48}, | ||||||
|  | 	{0x0D4A, 0x0D4F}, {0x0D54, 0x0D63}, {0x0D66, 0x0D7F}, | ||||||
|  | 	{0x0D81, 0x0D83}, {0x0D85, 0x0D96}, {0x0D9A, 0x0DB1}, | ||||||
|  | 	{0x0DB3, 0x0DBB}, {0x0DBD, 0x0DBD}, {0x0DC0, 0x0DC6}, | ||||||
|  | 	{0x0DCA, 0x0DCA}, {0x0DCF, 0x0DD4}, {0x0DD6, 0x0DD6}, | ||||||
|  | 	{0x0DD8, 0x0DDF}, {0x0DE6, 0x0DEF}, {0x0DF2, 0x0DF4}, | ||||||
|  | 	{0x0E01, 0x0E3A}, {0x0E3F, 0x0E5B}, {0x0E81, 0x0E82}, | ||||||
|  | 	{0x0E84, 0x0E84}, {0x0E86, 0x0E8A}, {0x0E8C, 0x0EA3}, | ||||||
|  | 	{0x0EA5, 0x0EA5}, {0x0EA7, 0x0EBD}, {0x0EC0, 0x0EC4}, | ||||||
|  | 	{0x0EC6, 0x0EC6}, {0x0EC8, 0x0ECD}, {0x0ED0, 0x0ED9}, | ||||||
|  | 	{0x0EDC, 0x0EDF}, {0x0F00, 0x0F47}, {0x0F49, 0x0F6C}, | ||||||
|  | 	{0x0F71, 0x0F97}, {0x0F99, 0x0FBC}, {0x0FBE, 0x0FCC}, | ||||||
|  | 	{0x0FCE, 0x0FDA}, {0x1000, 0x10C5}, {0x10C7, 0x10C7}, | ||||||
|  | 	{0x10CD, 0x10CD}, {0x10D0, 0x10FF}, {0x1160, 0x1248}, | ||||||
|  | 	{0x124A, 0x124D}, {0x1250, 0x1256}, {0x1258, 0x1258}, | ||||||
|  | 	{0x125A, 0x125D}, {0x1260, 0x1288}, {0x128A, 0x128D}, | ||||||
|  | 	{0x1290, 0x12B0}, {0x12B2, 0x12B5}, {0x12B8, 0x12BE}, | ||||||
|  | 	{0x12C0, 0x12C0}, {0x12C2, 0x12C5}, {0x12C8, 0x12D6}, | ||||||
|  | 	{0x12D8, 0x1310}, {0x1312, 0x1315}, {0x1318, 0x135A}, | ||||||
|  | 	{0x135D, 0x137C}, {0x1380, 0x1399}, {0x13A0, 0x13F5}, | ||||||
|  | 	{0x13F8, 0x13FD}, {0x1400, 0x169C}, {0x16A0, 0x16F8}, | ||||||
|  | 	{0x1700, 0x170C}, {0x170E, 0x1714}, {0x1720, 0x1736}, | ||||||
|  | 	{0x1740, 0x1753}, {0x1760, 0x176C}, {0x176E, 0x1770}, | ||||||
|  | 	{0x1772, 0x1773}, {0x1780, 0x17DD}, {0x17E0, 0x17E9}, | ||||||
|  | 	{0x17F0, 0x17F9}, {0x1800, 0x180E}, {0x1810, 0x1819}, | ||||||
|  | 	{0x1820, 0x1878}, {0x1880, 0x18AA}, {0x18B0, 0x18F5}, | ||||||
|  | 	{0x1900, 0x191E}, {0x1920, 0x192B}, {0x1930, 0x193B}, | ||||||
|  | 	{0x1940, 0x1940}, {0x1944, 0x196D}, {0x1970, 0x1974}, | ||||||
|  | 	{0x1980, 0x19AB}, {0x19B0, 0x19C9}, {0x19D0, 0x19DA}, | ||||||
|  | 	{0x19DE, 0x1A1B}, {0x1A1E, 0x1A5E}, {0x1A60, 0x1A7C}, | ||||||
|  | 	{0x1A7F, 0x1A89}, {0x1A90, 0x1A99}, {0x1AA0, 0x1AAD}, | ||||||
|  | 	{0x1AB0, 0x1AC0}, {0x1B00, 0x1B4B}, {0x1B50, 0x1B7C}, | ||||||
|  | 	{0x1B80, 0x1BF3}, {0x1BFC, 0x1C37}, {0x1C3B, 0x1C49}, | ||||||
|  | 	{0x1C4D, 0x1C88}, {0x1C90, 0x1CBA}, {0x1CBD, 0x1CC7}, | ||||||
|  | 	{0x1CD0, 0x1CFA}, {0x1D00, 0x1DF9}, {0x1DFB, 0x1F15}, | ||||||
|  | 	{0x1F18, 0x1F1D}, {0x1F20, 0x1F45}, {0x1F48, 0x1F4D}, | ||||||
|  | 	{0x1F50, 0x1F57}, {0x1F59, 0x1F59}, {0x1F5B, 0x1F5B}, | ||||||
|  | 	{0x1F5D, 0x1F5D}, {0x1F5F, 0x1F7D}, {0x1F80, 0x1FB4}, | ||||||
|  | 	{0x1FB6, 0x1FC4}, {0x1FC6, 0x1FD3}, {0x1FD6, 0x1FDB}, | ||||||
|  | 	{0x1FDD, 0x1FEF}, {0x1FF2, 0x1FF4}, {0x1FF6, 0x1FFE}, | ||||||
|  | 	{0x2000, 0x200F}, {0x2011, 0x2012}, {0x2017, 0x2017}, | ||||||
|  | 	{0x201A, 0x201B}, {0x201E, 0x201F}, {0x2023, 0x2023}, | ||||||
|  | 	{0x2028, 0x202F}, {0x2031, 0x2031}, {0x2034, 0x2034}, | ||||||
|  | 	{0x2036, 0x203A}, {0x203C, 0x203D}, {0x203F, 0x2064}, | ||||||
|  | 	{0x2066, 0x2071}, {0x2075, 0x207E}, {0x2080, 0x2080}, | ||||||
|  | 	{0x2085, 0x208E}, {0x2090, 0x209C}, {0x20A0, 0x20A8}, | ||||||
|  | 	{0x20AA, 0x20AB}, {0x20AD, 0x20BF}, {0x20D0, 0x20F0}, | ||||||
|  | 	{0x2100, 0x2102}, {0x2104, 0x2104}, {0x2106, 0x2108}, | ||||||
|  | 	{0x210A, 0x2112}, {0x2114, 0x2115}, {0x2117, 0x2120}, | ||||||
|  | 	{0x2123, 0x2125}, {0x2127, 0x212A}, {0x212C, 0x2152}, | ||||||
|  | 	{0x2155, 0x215A}, {0x215F, 0x215F}, {0x216C, 0x216F}, | ||||||
|  | 	{0x217A, 0x2188}, {0x218A, 0x218B}, {0x219A, 0x21B7}, | ||||||
|  | 	{0x21BA, 0x21D1}, {0x21D3, 0x21D3}, {0x21D5, 0x21E6}, | ||||||
|  | 	{0x21E8, 0x21FF}, {0x2201, 0x2201}, {0x2204, 0x2206}, | ||||||
|  | 	{0x2209, 0x220A}, {0x220C, 0x220E}, {0x2210, 0x2210}, | ||||||
|  | 	{0x2212, 0x2214}, {0x2216, 0x2219}, {0x221B, 0x221C}, | ||||||
|  | 	{0x2221, 0x2222}, {0x2224, 0x2224}, {0x2226, 0x2226}, | ||||||
|  | 	{0x222D, 0x222D}, {0x222F, 0x2233}, {0x2238, 0x223B}, | ||||||
|  | 	{0x223E, 0x2247}, {0x2249, 0x224B}, {0x224D, 0x2251}, | ||||||
|  | 	{0x2253, 0x225F}, {0x2262, 0x2263}, {0x2268, 0x2269}, | ||||||
|  | 	{0x226C, 0x226D}, {0x2270, 0x2281}, {0x2284, 0x2285}, | ||||||
|  | 	{0x2288, 0x2294}, {0x2296, 0x2298}, {0x229A, 0x22A4}, | ||||||
|  | 	{0x22A6, 0x22BE}, {0x22C0, 0x2311}, {0x2313, 0x2319}, | ||||||
|  | 	{0x231C, 0x2328}, {0x232B, 0x23E8}, {0x23ED, 0x23EF}, | ||||||
|  | 	{0x23F1, 0x23F2}, {0x23F4, 0x2426}, {0x2440, 0x244A}, | ||||||
|  | 	{0x24EA, 0x24EA}, {0x254C, 0x254F}, {0x2574, 0x257F}, | ||||||
|  | 	{0x2590, 0x2591}, {0x2596, 0x259F}, {0x25A2, 0x25A2}, | ||||||
|  | 	{0x25AA, 0x25B1}, {0x25B4, 0x25B5}, {0x25B8, 0x25BB}, | ||||||
|  | 	{0x25BE, 0x25BF}, {0x25C2, 0x25C5}, {0x25C9, 0x25CA}, | ||||||
|  | 	{0x25CC, 0x25CD}, {0x25D2, 0x25E1}, {0x25E6, 0x25EE}, | ||||||
|  | 	{0x25F0, 0x25FC}, {0x25FF, 0x2604}, {0x2607, 0x2608}, | ||||||
|  | 	{0x260A, 0x260D}, {0x2610, 0x2613}, {0x2616, 0x261B}, | ||||||
|  | 	{0x261D, 0x261D}, {0x261F, 0x263F}, {0x2641, 0x2641}, | ||||||
|  | 	{0x2643, 0x2647}, {0x2654, 0x265F}, {0x2662, 0x2662}, | ||||||
|  | 	{0x2666, 0x2666}, {0x266B, 0x266B}, {0x266E, 0x266E}, | ||||||
|  | 	{0x2670, 0x267E}, {0x2680, 0x2692}, {0x2694, 0x269D}, | ||||||
|  | 	{0x26A0, 0x26A0}, {0x26A2, 0x26A9}, {0x26AC, 0x26BC}, | ||||||
|  | 	{0x26C0, 0x26C3}, {0x26E2, 0x26E2}, {0x26E4, 0x26E7}, | ||||||
|  | 	{0x2700, 0x2704}, {0x2706, 0x2709}, {0x270C, 0x2727}, | ||||||
|  | 	{0x2729, 0x273C}, {0x273E, 0x274B}, {0x274D, 0x274D}, | ||||||
|  | 	{0x274F, 0x2752}, {0x2756, 0x2756}, {0x2758, 0x2775}, | ||||||
|  | 	{0x2780, 0x2794}, {0x2798, 0x27AF}, {0x27B1, 0x27BE}, | ||||||
|  | 	{0x27C0, 0x27E5}, {0x27EE, 0x2984}, {0x2987, 0x2B1A}, | ||||||
|  | 	{0x2B1D, 0x2B4F}, {0x2B51, 0x2B54}, {0x2B5A, 0x2B73}, | ||||||
|  | 	{0x2B76, 0x2B95}, {0x2B97, 0x2C2E}, {0x2C30, 0x2C5E}, | ||||||
|  | 	{0x2C60, 0x2CF3}, {0x2CF9, 0x2D25}, {0x2D27, 0x2D27}, | ||||||
|  | 	{0x2D2D, 0x2D2D}, {0x2D30, 0x2D67}, {0x2D6F, 0x2D70}, | ||||||
|  | 	{0x2D7F, 0x2D96}, {0x2DA0, 0x2DA6}, {0x2DA8, 0x2DAE}, | ||||||
|  | 	{0x2DB0, 0x2DB6}, {0x2DB8, 0x2DBE}, {0x2DC0, 0x2DC6}, | ||||||
|  | 	{0x2DC8, 0x2DCE}, {0x2DD0, 0x2DD6}, {0x2DD8, 0x2DDE}, | ||||||
|  | 	{0x2DE0, 0x2E52}, {0x303F, 0x303F}, {0x4DC0, 0x4DFF}, | ||||||
|  | 	{0xA4D0, 0xA62B}, {0xA640, 0xA6F7}, {0xA700, 0xA7BF}, | ||||||
|  | 	{0xA7C2, 0xA7CA}, {0xA7F5, 0xA82C}, {0xA830, 0xA839}, | ||||||
|  | 	{0xA840, 0xA877}, {0xA880, 0xA8C5}, {0xA8CE, 0xA8D9}, | ||||||
|  | 	{0xA8E0, 0xA953}, {0xA95F, 0xA95F}, {0xA980, 0xA9CD}, | ||||||
|  | 	{0xA9CF, 0xA9D9}, {0xA9DE, 0xA9FE}, {0xAA00, 0xAA36}, | ||||||
|  | 	{0xAA40, 0xAA4D}, {0xAA50, 0xAA59}, {0xAA5C, 0xAAC2}, | ||||||
|  | 	{0xAADB, 0xAAF6}, {0xAB01, 0xAB06}, {0xAB09, 0xAB0E}, | ||||||
|  | 	{0xAB11, 0xAB16}, {0xAB20, 0xAB26}, {0xAB28, 0xAB2E}, | ||||||
|  | 	{0xAB30, 0xAB6B}, {0xAB70, 0xABED}, {0xABF0, 0xABF9}, | ||||||
|  | 	{0xD7B0, 0xD7C6}, {0xD7CB, 0xD7FB}, {0xD800, 0xDFFF}, | ||||||
|  | 	{0xFB00, 0xFB06}, {0xFB13, 0xFB17}, {0xFB1D, 0xFB36}, | ||||||
|  | 	{0xFB38, 0xFB3C}, {0xFB3E, 0xFB3E}, {0xFB40, 0xFB41}, | ||||||
|  | 	{0xFB43, 0xFB44}, {0xFB46, 0xFBC1}, {0xFBD3, 0xFD3F}, | ||||||
|  | 	{0xFD50, 0xFD8F}, {0xFD92, 0xFDC7}, {0xFDF0, 0xFDFD}, | ||||||
|  | 	{0xFE20, 0xFE2F}, {0xFE70, 0xFE74}, {0xFE76, 0xFEFC}, | ||||||
|  | 	{0xFEFF, 0xFEFF}, {0xFFF9, 0xFFFC}, {0x10000, 0x1000B}, | ||||||
|  | 	{0x1000D, 0x10026}, {0x10028, 0x1003A}, {0x1003C, 0x1003D}, | ||||||
|  | 	{0x1003F, 0x1004D}, {0x10050, 0x1005D}, {0x10080, 0x100FA}, | ||||||
|  | 	{0x10100, 0x10102}, {0x10107, 0x10133}, {0x10137, 0x1018E}, | ||||||
|  | 	{0x10190, 0x1019C}, {0x101A0, 0x101A0}, {0x101D0, 0x101FD}, | ||||||
|  | 	{0x10280, 0x1029C}, {0x102A0, 0x102D0}, {0x102E0, 0x102FB}, | ||||||
|  | 	{0x10300, 0x10323}, {0x1032D, 0x1034A}, {0x10350, 0x1037A}, | ||||||
|  | 	{0x10380, 0x1039D}, {0x1039F, 0x103C3}, {0x103C8, 0x103D5}, | ||||||
|  | 	{0x10400, 0x1049D}, {0x104A0, 0x104A9}, {0x104B0, 0x104D3}, | ||||||
|  | 	{0x104D8, 0x104FB}, {0x10500, 0x10527}, {0x10530, 0x10563}, | ||||||
|  | 	{0x1056F, 0x1056F}, {0x10600, 0x10736}, {0x10740, 0x10755}, | ||||||
|  | 	{0x10760, 0x10767}, {0x10800, 0x10805}, {0x10808, 0x10808}, | ||||||
|  | 	{0x1080A, 0x10835}, {0x10837, 0x10838}, {0x1083C, 0x1083C}, | ||||||
|  | 	{0x1083F, 0x10855}, {0x10857, 0x1089E}, {0x108A7, 0x108AF}, | ||||||
|  | 	{0x108E0, 0x108F2}, {0x108F4, 0x108F5}, {0x108FB, 0x1091B}, | ||||||
|  | 	{0x1091F, 0x10939}, {0x1093F, 0x1093F}, {0x10980, 0x109B7}, | ||||||
|  | 	{0x109BC, 0x109CF}, {0x109D2, 0x10A03}, {0x10A05, 0x10A06}, | ||||||
|  | 	{0x10A0C, 0x10A13}, {0x10A15, 0x10A17}, {0x10A19, 0x10A35}, | ||||||
|  | 	{0x10A38, 0x10A3A}, {0x10A3F, 0x10A48}, {0x10A50, 0x10A58}, | ||||||
|  | 	{0x10A60, 0x10A9F}, {0x10AC0, 0x10AE6}, {0x10AEB, 0x10AF6}, | ||||||
|  | 	{0x10B00, 0x10B35}, {0x10B39, 0x10B55}, {0x10B58, 0x10B72}, | ||||||
|  | 	{0x10B78, 0x10B91}, {0x10B99, 0x10B9C}, {0x10BA9, 0x10BAF}, | ||||||
|  | 	{0x10C00, 0x10C48}, {0x10C80, 0x10CB2}, {0x10CC0, 0x10CF2}, | ||||||
|  | 	{0x10CFA, 0x10D27}, {0x10D30, 0x10D39}, {0x10E60, 0x10E7E}, | ||||||
|  | 	{0x10E80, 0x10EA9}, {0x10EAB, 0x10EAD}, {0x10EB0, 0x10EB1}, | ||||||
|  | 	{0x10F00, 0x10F27}, {0x10F30, 0x10F59}, {0x10FB0, 0x10FCB}, | ||||||
|  | 	{0x10FE0, 0x10FF6}, {0x11000, 0x1104D}, {0x11052, 0x1106F}, | ||||||
|  | 	{0x1107F, 0x110C1}, {0x110CD, 0x110CD}, {0x110D0, 0x110E8}, | ||||||
|  | 	{0x110F0, 0x110F9}, {0x11100, 0x11134}, {0x11136, 0x11147}, | ||||||
|  | 	{0x11150, 0x11176}, {0x11180, 0x111DF}, {0x111E1, 0x111F4}, | ||||||
|  | 	{0x11200, 0x11211}, {0x11213, 0x1123E}, {0x11280, 0x11286}, | ||||||
|  | 	{0x11288, 0x11288}, {0x1128A, 0x1128D}, {0x1128F, 0x1129D}, | ||||||
|  | 	{0x1129F, 0x112A9}, {0x112B0, 0x112EA}, {0x112F0, 0x112F9}, | ||||||
|  | 	{0x11300, 0x11303}, {0x11305, 0x1130C}, {0x1130F, 0x11310}, | ||||||
|  | 	{0x11313, 0x11328}, {0x1132A, 0x11330}, {0x11332, 0x11333}, | ||||||
|  | 	{0x11335, 0x11339}, {0x1133B, 0x11344}, {0x11347, 0x11348}, | ||||||
|  | 	{0x1134B, 0x1134D}, {0x11350, 0x11350}, {0x11357, 0x11357}, | ||||||
|  | 	{0x1135D, 0x11363}, {0x11366, 0x1136C}, {0x11370, 0x11374}, | ||||||
|  | 	{0x11400, 0x1145B}, {0x1145D, 0x11461}, {0x11480, 0x114C7}, | ||||||
|  | 	{0x114D0, 0x114D9}, {0x11580, 0x115B5}, {0x115B8, 0x115DD}, | ||||||
|  | 	{0x11600, 0x11644}, {0x11650, 0x11659}, {0x11660, 0x1166C}, | ||||||
|  | 	{0x11680, 0x116B8}, {0x116C0, 0x116C9}, {0x11700, 0x1171A}, | ||||||
|  | 	{0x1171D, 0x1172B}, {0x11730, 0x1173F}, {0x11800, 0x1183B}, | ||||||
|  | 	{0x118A0, 0x118F2}, {0x118FF, 0x11906}, {0x11909, 0x11909}, | ||||||
|  | 	{0x1190C, 0x11913}, {0x11915, 0x11916}, {0x11918, 0x11935}, | ||||||
|  | 	{0x11937, 0x11938}, {0x1193B, 0x11946}, {0x11950, 0x11959}, | ||||||
|  | 	{0x119A0, 0x119A7}, {0x119AA, 0x119D7}, {0x119DA, 0x119E4}, | ||||||
|  | 	{0x11A00, 0x11A47}, {0x11A50, 0x11AA2}, {0x11AC0, 0x11AF8}, | ||||||
|  | 	{0x11C00, 0x11C08}, {0x11C0A, 0x11C36}, {0x11C38, 0x11C45}, | ||||||
|  | 	{0x11C50, 0x11C6C}, {0x11C70, 0x11C8F}, {0x11C92, 0x11CA7}, | ||||||
|  | 	{0x11CA9, 0x11CB6}, {0x11D00, 0x11D06}, {0x11D08, 0x11D09}, | ||||||
|  | 	{0x11D0B, 0x11D36}, {0x11D3A, 0x11D3A}, {0x11D3C, 0x11D3D}, | ||||||
|  | 	{0x11D3F, 0x11D47}, {0x11D50, 0x11D59}, {0x11D60, 0x11D65}, | ||||||
|  | 	{0x11D67, 0x11D68}, {0x11D6A, 0x11D8E}, {0x11D90, 0x11D91}, | ||||||
|  | 	{0x11D93, 0x11D98}, {0x11DA0, 0x11DA9}, {0x11EE0, 0x11EF8}, | ||||||
|  | 	{0x11FB0, 0x11FB0}, {0x11FC0, 0x11FF1}, {0x11FFF, 0x12399}, | ||||||
|  | 	{0x12400, 0x1246E}, {0x12470, 0x12474}, {0x12480, 0x12543}, | ||||||
|  | 	{0x13000, 0x1342E}, {0x13430, 0x13438}, {0x14400, 0x14646}, | ||||||
|  | 	{0x16800, 0x16A38}, {0x16A40, 0x16A5E}, {0x16A60, 0x16A69}, | ||||||
|  | 	{0x16A6E, 0x16A6F}, {0x16AD0, 0x16AED}, {0x16AF0, 0x16AF5}, | ||||||
|  | 	{0x16B00, 0x16B45}, {0x16B50, 0x16B59}, {0x16B5B, 0x16B61}, | ||||||
|  | 	{0x16B63, 0x16B77}, {0x16B7D, 0x16B8F}, {0x16E40, 0x16E9A}, | ||||||
|  | 	{0x16F00, 0x16F4A}, {0x16F4F, 0x16F87}, {0x16F8F, 0x16F9F}, | ||||||
|  | 	{0x1BC00, 0x1BC6A}, {0x1BC70, 0x1BC7C}, {0x1BC80, 0x1BC88}, | ||||||
|  | 	{0x1BC90, 0x1BC99}, {0x1BC9C, 0x1BCA3}, {0x1D000, 0x1D0F5}, | ||||||
|  | 	{0x1D100, 0x1D126}, {0x1D129, 0x1D1E8}, {0x1D200, 0x1D245}, | ||||||
|  | 	{0x1D2E0, 0x1D2F3}, {0x1D300, 0x1D356}, {0x1D360, 0x1D378}, | ||||||
|  | 	{0x1D400, 0x1D454}, {0x1D456, 0x1D49C}, {0x1D49E, 0x1D49F}, | ||||||
|  | 	{0x1D4A2, 0x1D4A2}, {0x1D4A5, 0x1D4A6}, {0x1D4A9, 0x1D4AC}, | ||||||
|  | 	{0x1D4AE, 0x1D4B9}, {0x1D4BB, 0x1D4BB}, {0x1D4BD, 0x1D4C3}, | ||||||
|  | 	{0x1D4C5, 0x1D505}, {0x1D507, 0x1D50A}, {0x1D50D, 0x1D514}, | ||||||
|  | 	{0x1D516, 0x1D51C}, {0x1D51E, 0x1D539}, {0x1D53B, 0x1D53E}, | ||||||
|  | 	{0x1D540, 0x1D544}, {0x1D546, 0x1D546}, {0x1D54A, 0x1D550}, | ||||||
|  | 	{0x1D552, 0x1D6A5}, {0x1D6A8, 0x1D7CB}, {0x1D7CE, 0x1DA8B}, | ||||||
|  | 	{0x1DA9B, 0x1DA9F}, {0x1DAA1, 0x1DAAF}, {0x1E000, 0x1E006}, | ||||||
|  | 	{0x1E008, 0x1E018}, {0x1E01B, 0x1E021}, {0x1E023, 0x1E024}, | ||||||
|  | 	{0x1E026, 0x1E02A}, {0x1E100, 0x1E12C}, {0x1E130, 0x1E13D}, | ||||||
|  | 	{0x1E140, 0x1E149}, {0x1E14E, 0x1E14F}, {0x1E2C0, 0x1E2F9}, | ||||||
|  | 	{0x1E2FF, 0x1E2FF}, {0x1E800, 0x1E8C4}, {0x1E8C7, 0x1E8D6}, | ||||||
|  | 	{0x1E900, 0x1E94B}, {0x1E950, 0x1E959}, {0x1E95E, 0x1E95F}, | ||||||
|  | 	{0x1EC71, 0x1ECB4}, {0x1ED01, 0x1ED3D}, {0x1EE00, 0x1EE03}, | ||||||
|  | 	{0x1EE05, 0x1EE1F}, {0x1EE21, 0x1EE22}, {0x1EE24, 0x1EE24}, | ||||||
|  | 	{0x1EE27, 0x1EE27}, {0x1EE29, 0x1EE32}, {0x1EE34, 0x1EE37}, | ||||||
|  | 	{0x1EE39, 0x1EE39}, {0x1EE3B, 0x1EE3B}, {0x1EE42, 0x1EE42}, | ||||||
|  | 	{0x1EE47, 0x1EE47}, {0x1EE49, 0x1EE49}, {0x1EE4B, 0x1EE4B}, | ||||||
|  | 	{0x1EE4D, 0x1EE4F}, {0x1EE51, 0x1EE52}, {0x1EE54, 0x1EE54}, | ||||||
|  | 	{0x1EE57, 0x1EE57}, {0x1EE59, 0x1EE59}, {0x1EE5B, 0x1EE5B}, | ||||||
|  | 	{0x1EE5D, 0x1EE5D}, {0x1EE5F, 0x1EE5F}, {0x1EE61, 0x1EE62}, | ||||||
|  | 	{0x1EE64, 0x1EE64}, {0x1EE67, 0x1EE6A}, {0x1EE6C, 0x1EE72}, | ||||||
|  | 	{0x1EE74, 0x1EE77}, {0x1EE79, 0x1EE7C}, {0x1EE7E, 0x1EE7E}, | ||||||
|  | 	{0x1EE80, 0x1EE89}, {0x1EE8B, 0x1EE9B}, {0x1EEA1, 0x1EEA3}, | ||||||
|  | 	{0x1EEA5, 0x1EEA9}, {0x1EEAB, 0x1EEBB}, {0x1EEF0, 0x1EEF1}, | ||||||
|  | 	{0x1F000, 0x1F003}, {0x1F005, 0x1F02B}, {0x1F030, 0x1F093}, | ||||||
|  | 	{0x1F0A0, 0x1F0AE}, {0x1F0B1, 0x1F0BF}, {0x1F0C1, 0x1F0CE}, | ||||||
|  | 	{0x1F0D1, 0x1F0F5}, {0x1F10B, 0x1F10F}, {0x1F12E, 0x1F12F}, | ||||||
|  | 	{0x1F16A, 0x1F16F}, {0x1F1AD, 0x1F1AD}, {0x1F1E6, 0x1F1FF}, | ||||||
|  | 	{0x1F321, 0x1F32C}, {0x1F336, 0x1F336}, {0x1F37D, 0x1F37D}, | ||||||
|  | 	{0x1F394, 0x1F39F}, {0x1F3CB, 0x1F3CE}, {0x1F3D4, 0x1F3DF}, | ||||||
|  | 	{0x1F3F1, 0x1F3F3}, {0x1F3F5, 0x1F3F7}, {0x1F43F, 0x1F43F}, | ||||||
|  | 	{0x1F441, 0x1F441}, {0x1F4FD, 0x1F4FE}, {0x1F53E, 0x1F54A}, | ||||||
|  | 	{0x1F54F, 0x1F54F}, {0x1F568, 0x1F579}, {0x1F57B, 0x1F594}, | ||||||
|  | 	{0x1F597, 0x1F5A3}, {0x1F5A5, 0x1F5FA}, {0x1F650, 0x1F67F}, | ||||||
|  | 	{0x1F6C6, 0x1F6CB}, {0x1F6CD, 0x1F6CF}, {0x1F6D3, 0x1F6D4}, | ||||||
|  | 	{0x1F6E0, 0x1F6EA}, {0x1F6F0, 0x1F6F3}, {0x1F700, 0x1F773}, | ||||||
|  | 	{0x1F780, 0x1F7D8}, {0x1F800, 0x1F80B}, {0x1F810, 0x1F847}, | ||||||
|  | 	{0x1F850, 0x1F859}, {0x1F860, 0x1F887}, {0x1F890, 0x1F8AD}, | ||||||
|  | 	{0x1F8B0, 0x1F8B1}, {0x1F900, 0x1F90B}, {0x1F93B, 0x1F93B}, | ||||||
|  | 	{0x1F946, 0x1F946}, {0x1FA00, 0x1FA53}, {0x1FA60, 0x1FA6D}, | ||||||
|  | 	{0x1FB00, 0x1FB92}, {0x1FB94, 0x1FBCA}, {0x1FBF0, 0x1FBF9}, | ||||||
|  | 	{0xE0001, 0xE0001}, {0xE0020, 0xE007F}, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | var emoji = table{ | ||||||
|  | 	{0x203C, 0x203C}, {0x2049, 0x2049}, {0x2122, 0x2122}, | ||||||
|  | 	{0x2139, 0x2139}, {0x2194, 0x2199}, {0x21A9, 0x21AA}, | ||||||
|  | 	{0x231A, 0x231B}, {0x2328, 0x2328}, {0x2388, 0x2388}, | ||||||
|  | 	{0x23CF, 0x23CF}, {0x23E9, 0x23F3}, {0x23F8, 0x23FA}, | ||||||
|  | 	{0x24C2, 0x24C2}, {0x25AA, 0x25AB}, {0x25B6, 0x25B6}, | ||||||
|  | 	{0x25C0, 0x25C0}, {0x25FB, 0x25FE}, {0x2600, 0x2605}, | ||||||
|  | 	{0x2607, 0x2612}, {0x2614, 0x2685}, {0x2690, 0x2705}, | ||||||
|  | 	{0x2708, 0x2712}, {0x2714, 0x2714}, {0x2716, 0x2716}, | ||||||
|  | 	{0x271D, 0x271D}, {0x2721, 0x2721}, {0x2728, 0x2728}, | ||||||
|  | 	{0x2733, 0x2734}, {0x2744, 0x2744}, {0x2747, 0x2747}, | ||||||
|  | 	{0x274C, 0x274C}, {0x274E, 0x274E}, {0x2753, 0x2755}, | ||||||
|  | 	{0x2757, 0x2757}, {0x2763, 0x2767}, {0x2795, 0x2797}, | ||||||
|  | 	{0x27A1, 0x27A1}, {0x27B0, 0x27B0}, {0x27BF, 0x27BF}, | ||||||
|  | 	{0x2934, 0x2935}, {0x2B05, 0x2B07}, {0x2B1B, 0x2B1C}, | ||||||
|  | 	{0x2B50, 0x2B50}, {0x2B55, 0x2B55}, {0x3030, 0x3030}, | ||||||
|  | 	{0x303D, 0x303D}, {0x3297, 0x3297}, {0x3299, 0x3299}, | ||||||
|  | 	{0x1F000, 0x1F0FF}, {0x1F10D, 0x1F10F}, {0x1F12F, 0x1F12F}, | ||||||
|  | 	{0x1F16C, 0x1F171}, {0x1F17E, 0x1F17F}, {0x1F18E, 0x1F18E}, | ||||||
|  | 	{0x1F191, 0x1F19A}, {0x1F1AD, 0x1F1E5}, {0x1F201, 0x1F20F}, | ||||||
|  | 	{0x1F21A, 0x1F21A}, {0x1F22F, 0x1F22F}, {0x1F232, 0x1F23A}, | ||||||
|  | 	{0x1F23C, 0x1F23F}, {0x1F249, 0x1F3FA}, {0x1F400, 0x1F53D}, | ||||||
|  | 	{0x1F546, 0x1F64F}, {0x1F680, 0x1F6FF}, {0x1F774, 0x1F77F}, | ||||||
|  | 	{0x1F7D5, 0x1F7FF}, {0x1F80C, 0x1F80F}, {0x1F848, 0x1F84F}, | ||||||
|  | 	{0x1F85A, 0x1F85F}, {0x1F888, 0x1F88F}, {0x1F8AE, 0x1F8FF}, | ||||||
|  | 	{0x1F90C, 0x1F93A}, {0x1F93C, 0x1F945}, {0x1F947, 0x1FAFF}, | ||||||
|  | 	{0x1FC00, 0x1FFFD}, | ||||||
|  | } | ||||||
							
								
								
									
										28
									
								
								vendor/github.com/mattn/go-runewidth/runewidth_windows.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								vendor/github.com/mattn/go-runewidth/runewidth_windows.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,28 @@ | |||||||
|  | // +build windows
 | ||||||
|  | // +build !appengine
 | ||||||
|  | 
 | ||||||
|  | package runewidth | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"syscall" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | var ( | ||||||
|  | 	kernel32               = syscall.NewLazyDLL("kernel32") | ||||||
|  | 	procGetConsoleOutputCP = kernel32.NewProc("GetConsoleOutputCP") | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // IsEastAsian return true if the current locale is CJK
 | ||||||
|  | func IsEastAsian() bool { | ||||||
|  | 	r1, _, _ := procGetConsoleOutputCP.Call() | ||||||
|  | 	if r1 == 0 { | ||||||
|  | 		return false | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	switch int(r1) { | ||||||
|  | 	case 932, 51932, 936, 949, 950: | ||||||
|  | 		return true | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return false | ||||||
|  | } | ||||||
							
								
								
									
										21
									
								
								vendor/github.com/pterm/pterm/.gitignore
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								vendor/github.com/pterm/pterm/.gitignore
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,21 @@ | |||||||
|  | # 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/ | ||||||
|  | 
 | ||||||
|  | # This is where we test stuff | ||||||
|  | /experimenting/ | ||||||
|  | 
 | ||||||
|  | /.history | ||||||
|  | /.vscode | ||||||
							
								
								
									
										92
									
								
								vendor/github.com/pterm/pterm/.golangci.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										92
									
								
								vendor/github.com/pterm/pterm/.golangci.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,92 @@ | |||||||
|  | linters-settings: | ||||||
|  |   gocritic: | ||||||
|  |     enabled-tags: | ||||||
|  |       - diagnostic | ||||||
|  |       - experimental | ||||||
|  |       - opinionated | ||||||
|  |       - performance | ||||||
|  |       - style | ||||||
|  |     disabled-checks: | ||||||
|  |       - dupImport | ||||||
|  |       - ifElseChain | ||||||
|  |       - octalLiteral | ||||||
|  |       - whyNoLint | ||||||
|  |       - wrapperFunc | ||||||
|  |       - exitAfterDefer | ||||||
|  |       - hugeParam | ||||||
|  |       - ptrToRefParam | ||||||
|  |       - paramTypeCombine | ||||||
|  |       - unnamedResult | ||||||
|  |   #  maligned: | ||||||
|  |   #    suggest-new: true | ||||||
|  |   misspell: | ||||||
|  |     locale: US | ||||||
|  | linters: | ||||||
|  |   disable-all: true | ||||||
|  |   enable: | ||||||
|  |     - gocritic | ||||||
|  |     - gosec | ||||||
|  |     - govet | ||||||
|  |     - ineffassign | ||||||
|  |     - interfacer | ||||||
|  |     - unconvert | ||||||
|  |     - gosimple | ||||||
|  |     - godox | ||||||
|  |     - whitespace | ||||||
|  |     - staticcheck | ||||||
|  |   #    - bodyclose | ||||||
|  |   #    - maligned | ||||||
|  |   #    - godot | ||||||
|  |   #    - deadcode | ||||||
|  |   #    - depguard | ||||||
|  |   #    - dogsled | ||||||
|  |   #    - dupl | ||||||
|  |   #    - errcheck | ||||||
|  |   #    - exhaustive | ||||||
|  |   #    - funlen | ||||||
|  |   #    - gochecknoinits | ||||||
|  |   #    - goconst | ||||||
|  |   #    - gocyclo | ||||||
|  |   #    - gofmt | ||||||
|  |   #    - goimports | ||||||
|  |   #    - golint | ||||||
|  |   #    - gomnd | ||||||
|  |   #    - goprintffuncname | ||||||
|  |   #    - lll | ||||||
|  |   #    - misspell | ||||||
|  |   #    - nakedret | ||||||
|  |   #    - noctx | ||||||
|  |   #    - nolintlint | ||||||
|  |   #    - rowserrcheck | ||||||
|  |   #    - scopelint | ||||||
|  |   #    - structcheck | ||||||
|  |   #    - stylecheck | ||||||
|  |   #    - typecheck | ||||||
|  |   #    - unparam | ||||||
|  |   #    - unused | ||||||
|  |   #    - varcheck | ||||||
|  |   #    - whitespace | ||||||
|  |   #   - asciicheck | ||||||
|  |   #   - gochecknoglobals | ||||||
|  |   #   - gocognit | ||||||
|  |   #   - goerr113 | ||||||
|  |   #   - nestif | ||||||
|  |   #   - prealloc | ||||||
|  |   #   - testpackage | ||||||
|  |   #   - wsl | ||||||
|  | issues: | ||||||
|  |   # Excluding configuration per-path, per-linter, per-text and per-source | ||||||
|  |   exclude-rules: | ||||||
|  |     - path: _test\.go | ||||||
|  |       linters: | ||||||
|  |         - gocyclo | ||||||
|  |         - errcheck | ||||||
|  |         - dupl | ||||||
|  |         - gosec | ||||||
|  |         - gocritic | ||||||
|  |     # https://github.com/go-critic/go-critic/issues/926 | ||||||
|  |     - linters: | ||||||
|  |         - gocritic | ||||||
|  |       text: "unnecessaryDefer:" | ||||||
|  | service: | ||||||
|  |   golangci-lint-version: 1.31.x # use the fixed version to not introduce new linters unexpectedly | ||||||
							
								
								
									
										1003
									
								
								vendor/github.com/pterm/pterm/CHANGELOG.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1003
									
								
								vendor/github.com/pterm/pterm/CHANGELOG.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										76
									
								
								vendor/github.com/pterm/pterm/CODE_OF_CONDUCT.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								vendor/github.com/pterm/pterm/CODE_OF_CONDUCT.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,76 @@ | |||||||
|  | # Contributor Covenant Code of Conduct | ||||||
|  | 
 | ||||||
|  | ## Our Pledge | ||||||
|  | 
 | ||||||
|  | In the interest of fostering an open and welcoming environment, we as | ||||||
|  | contributors and maintainers pledge to making participation in our project and | ||||||
|  | our community a harassment-free experience for everyone, regardless of age, body | ||||||
|  | size, disability, ethnicity, sex characteristics, gender identity and expression, | ||||||
|  | level of experience, education, socio-economic status, nationality, personal | ||||||
|  | appearance, race, religion, or sexual identity and orientation. | ||||||
|  | 
 | ||||||
|  | ## Our Standards | ||||||
|  | 
 | ||||||
|  | Examples of behavior that contributes to creating a positive environment | ||||||
|  | include: | ||||||
|  | 
 | ||||||
|  | * Using welcoming and inclusive language | ||||||
|  | * Being respectful of differing viewpoints and experiences | ||||||
|  | * Gracefully accepting constructive criticism | ||||||
|  | * Focusing on what is best for the community | ||||||
|  | * Showing empathy towards other community members | ||||||
|  | 
 | ||||||
|  | Examples of unacceptable behavior by participants include: | ||||||
|  | 
 | ||||||
|  | * The use of sexualized language or imagery and unwelcome sexual attention or | ||||||
|  |  advances | ||||||
|  | * Trolling, insulting/derogatory comments, and personal or political attacks | ||||||
|  | * Public or private harassment | ||||||
|  | * Publishing others' private information, such as a physical or electronic | ||||||
|  |  address, without explicit permission | ||||||
|  | * Other conduct which could reasonably be considered inappropriate in a | ||||||
|  |  professional setting | ||||||
|  | 
 | ||||||
|  | ## Our Responsibilities | ||||||
|  | 
 | ||||||
|  | Project maintainers are responsible for clarifying the standards of acceptable | ||||||
|  | behavior and are expected to take appropriate and fair corrective action in | ||||||
|  | response to any instances of unacceptable behavior. | ||||||
|  | 
 | ||||||
|  | Project maintainers have the right and responsibility to remove, edit, or | ||||||
|  | reject comments, commits, code, wiki edits, issues, and other contributions | ||||||
|  | that are not aligned to this Code of Conduct, or to ban temporarily or | ||||||
|  | permanently any contributor for other behaviors that they deem inappropriate, | ||||||
|  | threatening, offensive, or harmful. | ||||||
|  | 
 | ||||||
|  | ## Scope | ||||||
|  | 
 | ||||||
|  | This Code of Conduct applies both within project spaces and in public spaces | ||||||
|  | when an individual is representing the project or its community. Examples of | ||||||
|  | representing a project or community include using an official project e-mail | ||||||
|  | address, posting via an official social media account, or acting as an appointed | ||||||
|  | representative at an online or offline event. Representation of a project may be | ||||||
|  | further defined and clarified by project maintainers. | ||||||
|  | 
 | ||||||
|  | ## Enforcement | ||||||
|  | 
 | ||||||
|  | Instances of abusive, harassing, or otherwise unacceptable behavior may be | ||||||
|  | reported by contacting the project team at pterm@marvinjwendt.com. All | ||||||
|  | complaints will be reviewed and investigated and will result in a response that | ||||||
|  | is deemed necessary and appropriate to the circumstances. The project team is | ||||||
|  | obligated to maintain confidentiality with regard to the reporter of an incident. | ||||||
|  | Further details of specific enforcement policies may be posted separately. | ||||||
|  | 
 | ||||||
|  | Project maintainers who do not follow or enforce the Code of Conduct in good | ||||||
|  | faith may face temporary or permanent repercussions as determined by other | ||||||
|  | members of the project's leadership. | ||||||
|  | 
 | ||||||
|  | ## Attribution | ||||||
|  | 
 | ||||||
|  | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, | ||||||
|  | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html | ||||||
|  | 
 | ||||||
|  | [homepage]: https://www.contributor-covenant.org | ||||||
|  | 
 | ||||||
|  | For answers to common questions about this code of conduct, see | ||||||
|  | https://www.contributor-covenant.org/faq | ||||||
							
								
								
									
										217
									
								
								vendor/github.com/pterm/pterm/CONTRIBUTING.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										217
									
								
								vendor/github.com/pterm/pterm/CONTRIBUTING.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,217 @@ | |||||||
|  | # Contributing to PTerm | ||||||
|  | 
 | ||||||
|  | > This document explains how to participate in the development of PTerm.\ | ||||||
|  | If your goal is to report a bug instead of programming PTerm, you can do so [here](https://github.com/pterm/pterm/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc). | ||||||
|  | 
 | ||||||
|  | ## Creating a new printer | ||||||
|  | 
 | ||||||
|  | > In this chapter we will show you how to create a new printer. | ||||||
|  | 
 | ||||||
|  | ### `TextPrinter` Template | ||||||
|  | ```go | ||||||
|  | package pterm | ||||||
|  | 
 | ||||||
|  | type TemplatePrinter struct{ | ||||||
|  | 	// TODO: Add printer settings here | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Sprint formats using the default formats for its operands and returns the resulting string. | ||||||
|  | // Spaces are added between operands when neither is a string. | ||||||
|  | func (p TemplatePrinter) Sprint(a ...interface{}) string { | ||||||
|  | 	panic("write printer code here") | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Sprintln formats using the default formats for its operands and returns the resulting string. | ||||||
|  | // Spaces are always added between operands and a newline is appended. | ||||||
|  | func (p TemplatePrinter) Sprintln(a ...interface{}) string { | ||||||
|  | 	return Sprintln(p.Sprint(a...)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Sprintf formats according to a format specifier and returns the resulting string. | ||||||
|  | func (p TemplatePrinter) Sprintf(format string, a ...interface{}) string { | ||||||
|  | 	return p.Sprint(Sprintf(format, a...)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Print formats using the default formats for its operands and writes to standard output. | ||||||
|  | // Spaces are added between operands when neither is a string. | ||||||
|  | // It returns the number of bytes written and any write error encountered. | ||||||
|  | func (p TemplatePrinter) Print(a ...interface{}) *TextPrinter { | ||||||
|  | 	Print(p.Sprint(a...)) | ||||||
|  | 	tp := TextPrinter(p) | ||||||
|  | 	return &tp | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Println formats using the default formats for its operands and writes to standard output. | ||||||
|  | // Spaces are always added between operands and a newline is appended. | ||||||
|  | // It returns the number of bytes written and any write error encountered. | ||||||
|  | func (p TemplatePrinter) Println(a ...interface{}) *TextPrinter { | ||||||
|  | 	Println(p.Sprint(a...)) | ||||||
|  |     tp := TextPrinter(p) | ||||||
|  |     return &tp | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Printf formats according to a format specifier and writes to standard output. | ||||||
|  | // It returns the number of bytes written and any write error encountered. | ||||||
|  | func (p TemplatePrinter) Printf(format string, a ...interface{}) *TextPrinter { | ||||||
|  | 	Print(p.Sprintf(format, a...)) | ||||||
|  | 	tp := TextPrinter(p) | ||||||
|  | 	return &tp | ||||||
|  | } | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ### `RenderablePrinter` Template | ||||||
|  | 
 | ||||||
|  | ```go | ||||||
|  | package pterm | ||||||
|  | 
 | ||||||
|  | type TemplatePrinter struct{ | ||||||
|  | 	// TODO: Add printer settings here | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Srender renders the Template as a string. | ||||||
|  | func (p TemplatePrinter) Srender() (string, error) { | ||||||
|  | 	var ret string | ||||||
|  | 
 | ||||||
|  |     return ret, nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Render prints the Template to the terminal. | ||||||
|  | func (p TemplatePrinter) Render() error { | ||||||
|  | 	s, err := p.Srender() | ||||||
|  |     if err != nil { | ||||||
|  |         return err | ||||||
|  |     } | ||||||
|  |     Println(s) | ||||||
|  | 
 | ||||||
|  |     return nil | ||||||
|  | } | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ### `LivePrinter` Template | ||||||
|  | 
 | ||||||
|  | ```go | ||||||
|  | // Start the TemplatePrinter. | ||||||
|  | package pterm | ||||||
|  | import "github.com/pterm/pterm" | ||||||
|  | 
 | ||||||
|  | type TemplatePrinter struct{ | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | func (s TemplatePrinter) Start(text...interface{}) (*TemplatePrinter, error) { // TODO: Replace Template with actual printer. | ||||||
|  | 	// TODO: start logic | ||||||
|  | 	return &s, nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Stop terminates the TemplatePrinter immediately. | ||||||
|  | // The TemplatePrinter will not resolve into anything. | ||||||
|  | func (s *TemplatePrinter) Stop() error { | ||||||
|  | 	// TODO: stop logic | ||||||
|  |     return nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // GenericStart runs Start, but returns a LivePrinter. | ||||||
|  | // This is used for the interface LivePrinter. | ||||||
|  | // You most likely want to use Start instead of this in your program. | ||||||
|  | func (s *TemplatePrinter) GenericStart() (*LivePrinter, error) { | ||||||
|  | 	_, err := s.Start() | ||||||
|  | 	lp := LivePrinter(s) | ||||||
|  | 	return &lp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // GenericStop runs Stop, but returns a LivePrinter. | ||||||
|  | // This is used for the interface LivePrinter. | ||||||
|  | // You most likely want to use Stop instead of this in your program. | ||||||
|  | func (s *TemplatePrinter) GenericStop() (*LivePrinter, error) { | ||||||
|  | 	err := s.Stop() | ||||||
|  | 	lp := LivePrinter(s) | ||||||
|  | 	return &lp, err | ||||||
|  | } | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ## Writing Tests | ||||||
|  | 
 | ||||||
|  | > Each method of PTerm must be tested. | ||||||
|  | 
 | ||||||
|  | ### Required tests for every printer | ||||||
|  | 
 | ||||||
|  | #### Nil Check | ||||||
|  | 
 | ||||||
|  | > This ensures that a printer without set values will not produce errors. | ||||||
|  | 
 | ||||||
|  | ```go | ||||||
|  | func TestTemplatePrinterNilPrint(t *testing.T) { // TODO: Replace "Template" with actual printer name. | ||||||
|  | 	p := TemplatePrinter{} // TODO: Replace "Template" with actual printer name. | ||||||
|  | 	p.Println("Hello, World!") | ||||||
|  | } | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | #### `WithXxx()` Methods | ||||||
|  | 
 | ||||||
|  | > Each method, which starts with `With` can be tested by checking if it actually creates a new printer and sets the value. | ||||||
|  | 
 | ||||||
|  | Example from `SectionPrinter`: | ||||||
|  | 
 | ||||||
|  | ```go | ||||||
|  | func TestSectionPrinter_WithStyle(t *testing.T) { | ||||||
|  | 	p := SectionPrinter{} | ||||||
|  | 	s := NewStyle(FgRed, BgRed, Bold) | ||||||
|  | 	p2 := p.WithStyle(s) | ||||||
|  | 
 | ||||||
|  | 	assert.Equal(t, s, p2.Style) | ||||||
|  | 	assert.Empty(t, p.Style) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func TestSectionPrinter_WithTopPadding(t *testing.T) { | ||||||
|  | 	p := SectionPrinter{} | ||||||
|  | 	p2 := p.WithTopPadding(1337) | ||||||
|  | 
 | ||||||
|  | 	assert.Equal(t, 1337, p2.TopPadding) | ||||||
|  | 	assert.Empty(t, p.TopPadding) | ||||||
|  | } | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ### `TextPrinter` Tests Template | ||||||
|  | 
 | ||||||
|  | ```go | ||||||
|  | func TestTemplatePrinterPrintMethods(t *testing.T) { // TODO: Replace "Template" with actual printer name. | ||||||
|  | 	p := DefaultTemplate // TODO: Replace "Template" with actual printer name. | ||||||
|  | 
 | ||||||
|  | 	t.Run("Print", func(t *testing.T) { | ||||||
|  | 		testPrintContains(t, func(w io.Writer, a interface{}) { | ||||||
|  | 			p.Print(a) | ||||||
|  | 		}) | ||||||
|  | 	}) | ||||||
|  | 
 | ||||||
|  | 	t.Run("Printf", func(t *testing.T) { | ||||||
|  | 		testPrintfContains(t, func(w io.Writer, format string, a interface{}) { | ||||||
|  | 			p.Printf(format, a) | ||||||
|  | 		}) | ||||||
|  | 	}) | ||||||
|  | 
 | ||||||
|  | 	t.Run("Println", func(t *testing.T) { | ||||||
|  | 		testPrintlnContains(t, func(w io.Writer, a interface{}) { | ||||||
|  | 			p.Println(a) | ||||||
|  | 		}) | ||||||
|  | 	}) | ||||||
|  | 
 | ||||||
|  | 	t.Run("Sprint", func(t *testing.T) { | ||||||
|  | 		testSprintContains(t, func(a interface{}) string { | ||||||
|  | 			return p.Sprint(a) | ||||||
|  | 		}) | ||||||
|  | 	}) | ||||||
|  | 
 | ||||||
|  | 	t.Run("Sprintf", func(t *testing.T) { | ||||||
|  | 		testSprintfContains(t, func(format string, a interface{}) string { | ||||||
|  | 			return p.Sprintf(format, a) | ||||||
|  | 		}) | ||||||
|  | 	}) | ||||||
|  | 
 | ||||||
|  | 	t.Run("Sprintln", func(t *testing.T) { | ||||||
|  | 		testSprintlnContains(t, func(a interface{}) string { | ||||||
|  | 			return p.Sprintln(a) | ||||||
|  | 		}) | ||||||
|  | 	}) | ||||||
|  | } | ||||||
|  | ``` | ||||||
							
								
								
									
										21
									
								
								vendor/github.com/pterm/pterm/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								vendor/github.com/pterm/pterm/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,21 @@ | |||||||
|  | MIT License | ||||||
|  | 
 | ||||||
|  | Copyright (c) 2020 pterm | ||||||
|  | 
 | ||||||
|  | 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. | ||||||
							
								
								
									
										1827
									
								
								vendor/github.com/pterm/pterm/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1827
									
								
								vendor/github.com/pterm/pterm/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										130
									
								
								vendor/github.com/pterm/pterm/area_printer.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										130
									
								
								vendor/github.com/pterm/pterm/area_printer.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,130 @@ | |||||||
|  | package pterm | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"strings" | ||||||
|  | 
 | ||||||
|  | 	"github.com/atomicgo/cursor" | ||||||
|  | 
 | ||||||
|  | 	"github.com/pterm/pterm/internal" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // DefaultArea is the default area printer.
 | ||||||
|  | var DefaultArea = AreaPrinter{} | ||||||
|  | 
 | ||||||
|  | // AreaPrinter prints an area which can be updated easily.
 | ||||||
|  | // use this printer for live output like charts, algorithm visualizations, simulations and even games.
 | ||||||
|  | type AreaPrinter struct { | ||||||
|  | 	RemoveWhenDone bool | ||||||
|  | 	Fullscreen     bool | ||||||
|  | 	Center         bool | ||||||
|  | 
 | ||||||
|  | 	content  string | ||||||
|  | 	isActive bool | ||||||
|  | 
 | ||||||
|  | 	area *cursor.Area | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // GetContent returns the current area content.
 | ||||||
|  | func (p *AreaPrinter) GetContent() string { | ||||||
|  | 	return p.content | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithRemoveWhenDone removes the AreaPrinter content after it is stopped.
 | ||||||
|  | func (p AreaPrinter) WithRemoveWhenDone(b ...bool) *AreaPrinter { | ||||||
|  | 	p.RemoveWhenDone = internal.WithBoolean(b) | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithFullscreen sets the AreaPrinter height the same height as the terminal, making it fullscreen.
 | ||||||
|  | func (p AreaPrinter) WithFullscreen(b ...bool) *AreaPrinter { | ||||||
|  | 	p.Fullscreen = internal.WithBoolean(b) | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithCenter centers the AreaPrinter content to the terminal.
 | ||||||
|  | func (p AreaPrinter) WithCenter(b ...bool) *AreaPrinter { | ||||||
|  | 	p.Center = internal.WithBoolean(b) | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Update overwrites the content of the AreaPrinter.
 | ||||||
|  | // Can be used live.
 | ||||||
|  | func (p *AreaPrinter) Update(text ...interface{}) { | ||||||
|  | 	if p.area == nil { | ||||||
|  | 		newArea := cursor.NewArea() | ||||||
|  | 		p.area = &newArea | ||||||
|  | 	} | ||||||
|  | 	str := Sprint(text...) | ||||||
|  | 	p.content = str | ||||||
|  | 
 | ||||||
|  | 	if p.Center { | ||||||
|  | 		str = DefaultCenter.Sprint(str) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if p.Fullscreen { | ||||||
|  | 		str = strings.TrimRight(str, "\n") | ||||||
|  | 		height := GetTerminalHeight() | ||||||
|  | 		contentHeight := strings.Count(str, "\n") | ||||||
|  | 
 | ||||||
|  | 		topPadding := 0 | ||||||
|  | 		bottomPadding := height - contentHeight - 2 | ||||||
|  | 
 | ||||||
|  | 		if p.Center { | ||||||
|  | 			topPadding = (bottomPadding / 2) + 1 | ||||||
|  | 			bottomPadding /= 2 | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if height > contentHeight { | ||||||
|  | 			str = strings.Repeat("\n", topPadding) + str | ||||||
|  | 			str += strings.Repeat("\n", bottomPadding) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	p.area.Update(str) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Start the AreaPrinter.
 | ||||||
|  | func (p *AreaPrinter) Start(text ...interface{}) (*AreaPrinter, error) { | ||||||
|  | 	p.isActive = true | ||||||
|  | 	str := Sprint(text...) | ||||||
|  | 	newArea := cursor.NewArea() | ||||||
|  | 	p.area = &newArea | ||||||
|  | 
 | ||||||
|  | 	p.Update(str) | ||||||
|  | 
 | ||||||
|  | 	return p, nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Stop terminates the AreaPrinter immediately.
 | ||||||
|  | // The AreaPrinter will not resolve into anything.
 | ||||||
|  | func (p *AreaPrinter) Stop() error { | ||||||
|  | 	p.isActive = false | ||||||
|  | 	if p.RemoveWhenDone { | ||||||
|  | 		p.Clear() | ||||||
|  | 	} | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // GenericStart runs Start, but returns a LivePrinter.
 | ||||||
|  | // This is used for the interface LivePrinter.
 | ||||||
|  | // You most likely want to use Start instead of this in your program.
 | ||||||
|  | func (p *AreaPrinter) GenericStart() (*LivePrinter, error) { | ||||||
|  | 	_, _ = p.Start() | ||||||
|  | 	lp := LivePrinter(p) | ||||||
|  | 	return &lp, nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // GenericStop runs Stop, but returns a LivePrinter.
 | ||||||
|  | // This is used for the interface LivePrinter.
 | ||||||
|  | // You most likely want to use Stop instead of this in your program.
 | ||||||
|  | func (p *AreaPrinter) GenericStop() (*LivePrinter, error) { | ||||||
|  | 	_ = p.Stop() | ||||||
|  | 	lp := LivePrinter(p) | ||||||
|  | 	return &lp, nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Wrapper function that clears the content of the Area.
 | ||||||
|  | // Moves the cursor to the bottom of the terminal, clears n lines upwards from
 | ||||||
|  | // the current position and moves the cursor again.
 | ||||||
|  | func (p *AreaPrinter) Clear() { | ||||||
|  | 	p.area.Clear() | ||||||
|  | } | ||||||
							
								
								
									
										36
									
								
								vendor/github.com/pterm/pterm/atoms.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								vendor/github.com/pterm/pterm/atoms.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,36 @@ | |||||||
|  | package pterm | ||||||
|  | 
 | ||||||
|  | // Bars is used to display multiple Bar.
 | ||||||
|  | type Bars []Bar | ||||||
|  | 
 | ||||||
|  | // Bar is used in bar charts.
 | ||||||
|  | type Bar struct { | ||||||
|  | 	Label      string | ||||||
|  | 	Value      int | ||||||
|  | 	Style      *Style | ||||||
|  | 	LabelStyle *Style | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithLabel returns a new Bar with a specific option.
 | ||||||
|  | func (p Bar) WithLabel(s string) *Bar { | ||||||
|  | 	p.Label = s | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithLabelStyle returns a new Bar with a specific option.
 | ||||||
|  | func (p Bar) WithLabelStyle(style *Style) *Bar { | ||||||
|  | 	p.LabelStyle = style | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithValue returns a new Bar with a specific option.
 | ||||||
|  | func (p Bar) WithValue(value int) *Bar { | ||||||
|  | 	p.Value = value | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithStyle returns a new Bar with a specific option.
 | ||||||
|  | func (p Bar) WithStyle(style *Style) *Bar { | ||||||
|  | 	p.Style = style | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
							
								
								
									
										416
									
								
								vendor/github.com/pterm/pterm/barchart.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										416
									
								
								vendor/github.com/pterm/pterm/barchart.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,416 @@ | |||||||
|  | package pterm | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"strconv" | ||||||
|  | 	"strings" | ||||||
|  | 
 | ||||||
|  | 	"github.com/mattn/go-runewidth" | ||||||
|  | 
 | ||||||
|  | 	"github.com/pterm/pterm/internal" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // BarChartPrinter is used to print bar charts.
 | ||||||
|  | type BarChartPrinter struct { | ||||||
|  | 	Bars       Bars | ||||||
|  | 	Horizontal bool | ||||||
|  | 	ShowValue  bool | ||||||
|  | 	// Height sets the maximum height of a vertical bar chart.
 | ||||||
|  | 	// The default is calculated to fit into the terminal.
 | ||||||
|  | 	// Ignored if Horizontal is set to true.
 | ||||||
|  | 	Height int | ||||||
|  | 	// Width sets the maximum width of a horizontal bar chart.
 | ||||||
|  | 	// The default is calculated to fit into the terminal.
 | ||||||
|  | 	// Ignored if Horizontal is set to false.
 | ||||||
|  | 	Width                  int | ||||||
|  | 	VerticalBarCharacter   string | ||||||
|  | 	HorizontalBarCharacter string | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | var ( | ||||||
|  | 	// DefaultBarChart is the default BarChartPrinter.
 | ||||||
|  | 	DefaultBarChart = BarChartPrinter{ | ||||||
|  | 		Horizontal:             false, | ||||||
|  | 		VerticalBarCharacter:   "██", | ||||||
|  | 		HorizontalBarCharacter: "█", | ||||||
|  | 		// keep in sync with RecalculateTerminalSize()
 | ||||||
|  | 		Height: GetTerminalHeight() * 2 / 3, | ||||||
|  | 		Width:  GetTerminalWidth() * 2 / 3, | ||||||
|  | 	} | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // WithBars returns a new BarChartPrinter with a specific option.
 | ||||||
|  | func (p BarChartPrinter) WithBars(bars Bars) *BarChartPrinter { | ||||||
|  | 	p.Bars = bars | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithVerticalBarCharacter returns a new BarChartPrinter with a specific option.
 | ||||||
|  | func (p BarChartPrinter) WithVerticalBarCharacter(char string) *BarChartPrinter { | ||||||
|  | 	p.VerticalBarCharacter = char | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithHorizontalBarCharacter returns a new BarChartPrinter with a specific option.
 | ||||||
|  | func (p BarChartPrinter) WithHorizontalBarCharacter(char string) *BarChartPrinter { | ||||||
|  | 	p.HorizontalBarCharacter = char | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithHorizontal returns a new BarChartPrinter with a specific option.
 | ||||||
|  | func (p BarChartPrinter) WithHorizontal(b ...bool) *BarChartPrinter { | ||||||
|  | 	b2 := internal.WithBoolean(b) | ||||||
|  | 	p.Horizontal = b2 | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithHeight returns a new BarChartPrinter with a specific option.
 | ||||||
|  | func (p BarChartPrinter) WithHeight(value int) *BarChartPrinter { | ||||||
|  | 	p.Height = value | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithWidth returns a new BarChartPrinter with a specific option.
 | ||||||
|  | func (p BarChartPrinter) WithWidth(value int) *BarChartPrinter { | ||||||
|  | 	p.Width = value | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithShowValue returns a new BarChartPrinter with a specific option.
 | ||||||
|  | func (p BarChartPrinter) WithShowValue(b ...bool) *BarChartPrinter { | ||||||
|  | 	p.ShowValue = internal.WithBoolean(b) | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (p BarChartPrinter) getRawOutput() string { | ||||||
|  | 	var ret string | ||||||
|  | 
 | ||||||
|  | 	for _, bar := range p.Bars { | ||||||
|  | 		ret += Sprintfln("%s: %d", bar.Label, bar.Value) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return ret | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Srender renders the BarChart as a string.
 | ||||||
|  | func (p BarChartPrinter) Srender() (string, error) { | ||||||
|  | 	maxAbsValue := func(value1 int, value2 int) int { | ||||||
|  | 		min := value1 | ||||||
|  | 		max := value2 | ||||||
|  | 
 | ||||||
|  | 		if value1 > value2 { | ||||||
|  | 			min = value2 | ||||||
|  | 			max = value1 | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		maxAbs := max | ||||||
|  | 
 | ||||||
|  | 		if min < 0 && -min > max { // This is to avoid something like "int(math.Abs(float64(minBarValue)))"
 | ||||||
|  | 			maxAbs = -min // (--) == (+)
 | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		return maxAbs | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	abs := func(value int) int { | ||||||
|  | 		if value < 0 { | ||||||
|  | 			return -value | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		return value | ||||||
|  | 	} | ||||||
|  | 	// =================================== VERTICAL BARS RENDERER ======================================================
 | ||||||
|  | 
 | ||||||
|  | 	type renderParams struct { | ||||||
|  | 		repeatCount             int | ||||||
|  | 		bar                     Bar | ||||||
|  | 		positiveChartPartHeight int | ||||||
|  | 		negativeChartPartHeight int | ||||||
|  | 		positiveChartPartWidth  int | ||||||
|  | 		negativeChartPartWidth  int | ||||||
|  | 		indent                  string | ||||||
|  | 		showValue               bool | ||||||
|  | 		moveUp                  bool | ||||||
|  | 		moveRight               bool | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	renderPositiveVerticalBar := func(renderedBarRef *string, rParams renderParams) { | ||||||
|  | 		if rParams.showValue { | ||||||
|  | 			*renderedBarRef += Sprint(rParams.indent + strconv.Itoa(rParams.bar.Value) + rParams.indent + "\n") | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		for i := rParams.positiveChartPartHeight; i > 0; i-- { | ||||||
|  | 			if i > rParams.repeatCount { | ||||||
|  | 				*renderedBarRef += rParams.indent + "  " + rParams.indent + " \n" | ||||||
|  | 			} else { | ||||||
|  | 				*renderedBarRef += rParams.indent + rParams.bar.Style.Sprint(p.VerticalBarCharacter) + rParams.indent + " \n" | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		// Used when we draw diagram with both POSITIVE and NEGATIVE values.
 | ||||||
|  | 		// In such case we separately draw top and bottom half of chart.
 | ||||||
|  | 		// And we need MOVE UP positive part to top part of chart,
 | ||||||
|  | 		// technically by adding empty pillars with height == height of chart's bottom part.
 | ||||||
|  | 		if rParams.moveUp { | ||||||
|  | 			for i := 0; i <= rParams.negativeChartPartHeight; i++ { | ||||||
|  | 				*renderedBarRef += rParams.indent + "  " + rParams.indent + " \n" | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	renderNegativeVerticalBar := func(renderedBarRef *string, rParams renderParams) { | ||||||
|  | 		for i := 0; i > -rParams.negativeChartPartHeight; i-- { | ||||||
|  | 			if i > rParams.repeatCount { | ||||||
|  | 				*renderedBarRef += rParams.indent + rParams.bar.Style.Sprint(p.VerticalBarCharacter) + rParams.indent + " \n" | ||||||
|  | 			} else { | ||||||
|  | 				*renderedBarRef += rParams.indent + "  " + rParams.indent + " \n" | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if rParams.showValue { | ||||||
|  | 			*renderedBarRef += Sprint(rParams.indent + strconv.Itoa(rParams.bar.Value) + rParams.indent + "\n") | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// =================================== HORIZONTAL BARS RENDERER ====================================================
 | ||||||
|  | 	renderPositiveHorizontalBar := func(renderedBarRef *string, rParams renderParams) { | ||||||
|  | 		if rParams.moveRight { | ||||||
|  | 			for i := 0; i < rParams.negativeChartPartWidth; i++ { | ||||||
|  | 				*renderedBarRef += " " | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		for i := 0; i < rParams.positiveChartPartWidth; i++ { | ||||||
|  | 			if i < rParams.repeatCount { | ||||||
|  | 				*renderedBarRef += rParams.bar.Style.Sprint(p.HorizontalBarCharacter) | ||||||
|  | 			} else { | ||||||
|  | 				*renderedBarRef += " " | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if rParams.showValue { | ||||||
|  | 			// For positive horizontal bars we add one more space before adding value,
 | ||||||
|  | 			// so they will be well aligned with negative values, which have "-" sign before them
 | ||||||
|  | 			*renderedBarRef += " " | ||||||
|  | 
 | ||||||
|  | 			*renderedBarRef += " " + strconv.Itoa(rParams.bar.Value) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	renderNegativeHorizontalBar := func(renderedBarRef *string, rParams renderParams) { | ||||||
|  | 		for i := -rParams.negativeChartPartWidth; i < 0; i++ { | ||||||
|  | 			if i < rParams.repeatCount { | ||||||
|  | 				*renderedBarRef += " " | ||||||
|  | 			} else { | ||||||
|  | 				*renderedBarRef += rParams.bar.Style.Sprint(p.HorizontalBarCharacter) | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		// In order to print values well-aligned (in case when we have both - positive and negative part of chart),
 | ||||||
|  | 		// we should insert an indent with width == width of positive chart part
 | ||||||
|  | 		if rParams.positiveChartPartWidth > 0 { | ||||||
|  | 			for i := 0; i < rParams.positiveChartPartWidth; i++ { | ||||||
|  | 				*renderedBarRef += " " | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if rParams.showValue { | ||||||
|  | 			/* | ||||||
|  | 				This is in order to achieve this effect: | ||||||
|  | 				 0 | ||||||
|  | 				-15 | ||||||
|  | 				 0 | ||||||
|  | 				-19 | ||||||
|  | 
 | ||||||
|  | 				INSTEAD OF THIS: | ||||||
|  | 
 | ||||||
|  | 				0 | ||||||
|  | 				-15 | ||||||
|  | 				0 | ||||||
|  | 				-19 | ||||||
|  | 			*/ | ||||||
|  | 			if rParams.repeatCount == 0 { | ||||||
|  | 				*renderedBarRef += " " | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			*renderedBarRef += " " + strconv.Itoa(rParams.bar.Value) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	// =================================================================================================================
 | ||||||
|  | 
 | ||||||
|  | 	if RawOutput { | ||||||
|  | 		return p.getRawOutput(), nil | ||||||
|  | 	} | ||||||
|  | 	for i, bar := range p.Bars { | ||||||
|  | 		if bar.Style == nil { | ||||||
|  | 			p.Bars[i].Style = &ThemeDefault.BarStyle | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if bar.LabelStyle == nil { | ||||||
|  | 			p.Bars[i].LabelStyle = &ThemeDefault.BarLabelStyle | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		p.Bars[i].Label = p.Bars[i].LabelStyle.Sprint(bar.Label) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	var ret string | ||||||
|  | 
 | ||||||
|  | 	var maxLabelHeight int | ||||||
|  | 	var maxBarValue int | ||||||
|  | 	var minBarValue int | ||||||
|  | 	var maxAbsBarValue int | ||||||
|  | 	var rParams renderParams | ||||||
|  | 
 | ||||||
|  | 	for _, bar := range p.Bars { | ||||||
|  | 		if bar.Value > maxBarValue { | ||||||
|  | 			maxBarValue = bar.Value | ||||||
|  | 		} | ||||||
|  | 		if bar.Value < minBarValue { | ||||||
|  | 			minBarValue = bar.Value | ||||||
|  | 		} | ||||||
|  | 		labelHeight := len(strings.Split(bar.Label, "\n")) | ||||||
|  | 		if labelHeight > maxLabelHeight { | ||||||
|  | 			maxLabelHeight = labelHeight | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	maxAbsBarValue = maxAbsValue(maxBarValue, minBarValue) | ||||||
|  | 
 | ||||||
|  | 	if p.Horizontal { | ||||||
|  | 		panels := Panels{[]Panel{{}, {}}} | ||||||
|  | 
 | ||||||
|  | 		rParams.showValue = p.ShowValue | ||||||
|  | 		rParams.positiveChartPartWidth = p.Width | ||||||
|  | 		rParams.negativeChartPartWidth = p.Width | ||||||
|  | 
 | ||||||
|  | 		// If chart will consist of two parts - positive and negative - we should recalculate max bars WIDTH in LEFT and RIGHT parts
 | ||||||
|  | 		if minBarValue < 0 && maxBarValue > 0 { | ||||||
|  | 			rParams.positiveChartPartWidth = abs(internal.MapRangeToRange(-float32(maxAbsBarValue), float32(maxAbsBarValue), -float32(p.Width)/2, float32(p.Width)/2, float32(maxBarValue))) | ||||||
|  | 			rParams.negativeChartPartWidth = abs(internal.MapRangeToRange(-float32(maxAbsBarValue), float32(maxAbsBarValue), -float32(p.Width)/2, float32(p.Width)/2, float32(minBarValue))) | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		for _, bar := range p.Bars { | ||||||
|  | 			rParams.bar = bar | ||||||
|  | 			panels[0][0].Data += "\n" + bar.Label | ||||||
|  | 			panels[0][1].Data += "\n" | ||||||
|  | 
 | ||||||
|  | 			if minBarValue >= 0 { | ||||||
|  | 				// As we don't have negative values, draw only positive (right) part of the chart:
 | ||||||
|  | 				rParams.repeatCount = internal.MapRangeToRange(0, float32(maxAbsBarValue), 0, float32(p.Width), float32(bar.Value)) | ||||||
|  | 				rParams.moveRight = false | ||||||
|  | 
 | ||||||
|  | 				renderPositiveHorizontalBar(&panels[0][1].Data, rParams) | ||||||
|  | 			} else if maxBarValue <= 0 { | ||||||
|  | 				// As we have only negative values, draw only negative (left) part of the chart:
 | ||||||
|  | 				rParams.repeatCount = internal.MapRangeToRange(-float32(maxAbsBarValue), 0, -float32(p.Width), 0, float32(bar.Value)) | ||||||
|  | 				rParams.positiveChartPartWidth = 0 | ||||||
|  | 
 | ||||||
|  | 				renderNegativeHorizontalBar(&panels[0][1].Data, rParams) | ||||||
|  | 			} else { | ||||||
|  | 				// We have positive and negative values, so draw both (left+right) parts of the chart:
 | ||||||
|  | 				rParams.repeatCount = internal.MapRangeToRange(-float32(maxAbsBarValue), float32(maxAbsBarValue), -float32(p.Width)/2, float32(p.Width)/2, float32(bar.Value)) | ||||||
|  | 
 | ||||||
|  | 				if bar.Value >= 0 { | ||||||
|  | 					rParams.moveRight = true | ||||||
|  | 
 | ||||||
|  | 					renderPositiveHorizontalBar(&panels[0][1].Data, rParams) | ||||||
|  | 				} | ||||||
|  | 
 | ||||||
|  | 				if bar.Value < 0 { | ||||||
|  | 					renderNegativeHorizontalBar(&panels[0][1].Data, rParams) | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		ret, _ = DefaultPanel.WithPanels(panels).Srender() | ||||||
|  | 		return ret, nil | ||||||
|  | 	} else { | ||||||
|  | 		renderedBars := make([]string, len(p.Bars)) | ||||||
|  | 
 | ||||||
|  | 		rParams.showValue = p.ShowValue | ||||||
|  | 		rParams.positiveChartPartHeight = p.Height | ||||||
|  | 		rParams.negativeChartPartHeight = p.Height | ||||||
|  | 
 | ||||||
|  | 		// If chart will consist of two parts - positive and negative - we should recalculate max bars height in top and bottom parts
 | ||||||
|  | 		if minBarValue < 0 && maxBarValue > 0 { | ||||||
|  | 			rParams.positiveChartPartHeight = abs(internal.MapRangeToRange(-float32(maxAbsBarValue), float32(maxAbsBarValue), -float32(p.Height)/2, float32(p.Height)/2, float32(maxBarValue))) | ||||||
|  | 			rParams.negativeChartPartHeight = abs(internal.MapRangeToRange(-float32(maxAbsBarValue), float32(maxAbsBarValue), -float32(p.Height)/2, float32(p.Height)/2, float32(minBarValue))) | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		for i, bar := range p.Bars { | ||||||
|  | 			var renderedBar string | ||||||
|  | 			rParams.bar = bar | ||||||
|  | 			rParams.indent = strings.Repeat(" ", internal.GetStringMaxWidth(RemoveColorFromString(bar.Label))/2) | ||||||
|  | 
 | ||||||
|  | 			if minBarValue >= 0 { | ||||||
|  | 				// As we don't have negative values, draw only positive (top) part of the chart:
 | ||||||
|  | 				rParams.repeatCount = internal.MapRangeToRange(0, float32(maxAbsBarValue), 0, float32(p.Height), float32(bar.Value)) | ||||||
|  | 				rParams.moveUp = false // Don't MOVE UP as we have ONLY positive part of chart.
 | ||||||
|  | 
 | ||||||
|  | 				renderPositiveVerticalBar(&renderedBar, rParams) | ||||||
|  | 			} else if maxBarValue <= 0 { | ||||||
|  | 				// As we have only negative values, draw only negative (bottom) part of the chart:
 | ||||||
|  | 				rParams.repeatCount = internal.MapRangeToRange(-float32(maxAbsBarValue), 0, -float32(p.Height), 0, float32(bar.Value)) | ||||||
|  | 
 | ||||||
|  | 				renderNegativeVerticalBar(&renderedBar, rParams) | ||||||
|  | 			} else { | ||||||
|  | 				// We have positive and negative values, so draw both (top+bottom) parts of the chart:
 | ||||||
|  | 				rParams.repeatCount = internal.MapRangeToRange(-float32(maxAbsBarValue), float32(maxAbsBarValue), -float32(p.Height)/2, float32(p.Height)/2, float32(bar.Value)) | ||||||
|  | 
 | ||||||
|  | 				if bar.Value >= 0 { | ||||||
|  | 					rParams.moveUp = true // MOVE UP positive part, because we have both positive and negative parts of chart.
 | ||||||
|  | 
 | ||||||
|  | 					renderPositiveVerticalBar(&renderedBar, rParams) | ||||||
|  | 				} | ||||||
|  | 
 | ||||||
|  | 				if bar.Value < 0 { | ||||||
|  | 					renderNegativeVerticalBar(&renderedBar, rParams) | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			labelHeight := len(strings.Split(bar.Label, "\n")) | ||||||
|  | 			renderedBars[i] = renderedBar + bar.Label + strings.Repeat("\n", maxLabelHeight-labelHeight) + " " | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		var maxBarHeight int | ||||||
|  | 
 | ||||||
|  | 		for _, bar := range renderedBars { | ||||||
|  | 			totalBarHeight := len(strings.Split(bar, "\n")) | ||||||
|  | 			if totalBarHeight > maxBarHeight { | ||||||
|  | 				maxBarHeight = totalBarHeight | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		for i, bar := range renderedBars { | ||||||
|  | 			totalBarHeight := len(strings.Split(bar, "\n")) | ||||||
|  | 			if totalBarHeight < maxBarHeight { | ||||||
|  | 				renderedBars[i] = strings.Repeat("\n", maxBarHeight-totalBarHeight) + renderedBars[i] | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		for i := 0; i <= maxBarHeight; i++ { | ||||||
|  | 			for _, barString := range renderedBars { | ||||||
|  | 				var barLine string | ||||||
|  | 				letterLines := strings.Split(barString, "\n") | ||||||
|  | 				maxBarWidth := internal.GetStringMaxWidth(RemoveColorFromString(barString)) | ||||||
|  | 				if len(letterLines) > i { | ||||||
|  | 					barLine = letterLines[i] | ||||||
|  | 				} | ||||||
|  | 				letterLineLength := runewidth.StringWidth(RemoveColorFromString(barLine)) | ||||||
|  | 				if letterLineLength < maxBarWidth { | ||||||
|  | 					barLine += strings.Repeat(" ", maxBarWidth-letterLineLength) | ||||||
|  | 				} | ||||||
|  | 				ret += barLine | ||||||
|  | 			} | ||||||
|  | 			ret += "\n" | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return ret, nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Render prints the Template to the terminal.
 | ||||||
|  | func (p BarChartPrinter) Render() error { | ||||||
|  | 	s, _ := p.Srender() | ||||||
|  | 	Println(s) | ||||||
|  | 
 | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
							
								
								
									
										114
									
								
								vendor/github.com/pterm/pterm/basic_text_printer.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										114
									
								
								vendor/github.com/pterm/pterm/basic_text_printer.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,114 @@ | |||||||
|  | package pterm | ||||||
|  | 
 | ||||||
|  | import "fmt" | ||||||
|  | 
 | ||||||
|  | var ( | ||||||
|  | 	// DefaultBasicText returns a default BasicTextPrinter, which can be used to print text as is.
 | ||||||
|  | 	// No default style is present for BasicTextPrinter.
 | ||||||
|  | 	DefaultBasicText = BasicTextPrinter{} | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // BasicTextPrinter is the printer used to print the input as-is or as specified by user formatting.
 | ||||||
|  | type BasicTextPrinter struct { | ||||||
|  | 	Style *Style | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithStyle adds a style to the printer.
 | ||||||
|  | func (p BasicTextPrinter) WithStyle(style *Style) *BasicTextPrinter { | ||||||
|  | 	p.Style = style | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Sprint formats using the default formats for its operands and returns the resulting string.
 | ||||||
|  | // Spaces are added between operands when neither is a string.
 | ||||||
|  | func (p BasicTextPrinter) Sprint(a ...interface{}) string { | ||||||
|  | 	if p.Style == nil { | ||||||
|  | 		p.Style = NewStyle() | ||||||
|  | 	} | ||||||
|  | 	return p.Style.Sprint(a...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Sprintln formats using the default formats for its operands and returns the resulting string.
 | ||||||
|  | // Spaces are always added between operands and a newline is appended.
 | ||||||
|  | func (p BasicTextPrinter) Sprintln(a ...interface{}) string { | ||||||
|  | 	str := fmt.Sprintln(a...) | ||||||
|  | 	return Sprintln(p.Sprint(str)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Sprintf formats according to a format specifier and returns the resulting string.
 | ||||||
|  | func (p BasicTextPrinter) Sprintf(format string, a ...interface{}) string { | ||||||
|  | 	return p.Sprint(Sprintf(format, a...)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Sprintfln formats according to a format specifier and returns the resulting string.
 | ||||||
|  | // Spaces are always added between operands and a newline is appended.
 | ||||||
|  | func (p BasicTextPrinter) Sprintfln(format string, a ...interface{}) string { | ||||||
|  | 	return p.Sprintf(format, a...) + "\n" | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Print formats using the default formats for its operands and writes to standard output.
 | ||||||
|  | // Spaces are added between operands when neither is a string.
 | ||||||
|  | // It returns the number of bytes written and any write error encountered.
 | ||||||
|  | func (p *BasicTextPrinter) Print(a ...interface{}) *TextPrinter { | ||||||
|  | 	Print(p.Sprint(a...)) | ||||||
|  | 	tp := TextPrinter(p) | ||||||
|  | 	return &tp | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Println formats using the default formats for its operands and writes to standard output.
 | ||||||
|  | // Spaces are always added between operands and a newline is appended.
 | ||||||
|  | // It returns the number of bytes written and any write error encountered.
 | ||||||
|  | func (p *BasicTextPrinter) Println(a ...interface{}) *TextPrinter { | ||||||
|  | 	Print(p.Sprintln(a...)) | ||||||
|  | 	tp := TextPrinter(p) | ||||||
|  | 	return &tp | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Printf formats according to a format specifier and writes to standard output.
 | ||||||
|  | // It returns the number of bytes written and any write error encountered.
 | ||||||
|  | func (p *BasicTextPrinter) Printf(format string, a ...interface{}) *TextPrinter { | ||||||
|  | 	Print(p.Sprintf(format, a...)) | ||||||
|  | 	tp := TextPrinter(p) | ||||||
|  | 	return &tp | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Printfln formats according to a format specifier and writes to standard output.
 | ||||||
|  | // Spaces are always added between operands and a newline is appended.
 | ||||||
|  | // It returns the number of bytes written and any write error encountered.
 | ||||||
|  | func (p *BasicTextPrinter) Printfln(format string, a ...interface{}) *TextPrinter { | ||||||
|  | 	Print(p.Sprintfln(format, a...)) | ||||||
|  | 	tp := TextPrinter(p) | ||||||
|  | 	return &tp | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // PrintOnError prints every error which is not nil.
 | ||||||
|  | // If every error is nil, nothing will be printed.
 | ||||||
|  | // This can be used for simple error checking.
 | ||||||
|  | func (p *BasicTextPrinter) PrintOnError(a ...interface{}) *TextPrinter { | ||||||
|  | 	for _, arg := range a { | ||||||
|  | 		if err, ok := arg.(error); ok { | ||||||
|  | 			if err != nil { | ||||||
|  | 				p.Println(err) | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	tp := TextPrinter(p) | ||||||
|  | 	return &tp | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // PrintOnErrorf wraps every error which is not nil and prints it.
 | ||||||
|  | // If every error is nil, nothing will be printed.
 | ||||||
|  | // This can be used for simple error checking.
 | ||||||
|  | func (p *BasicTextPrinter) PrintOnErrorf(format string, a ...interface{}) *TextPrinter { | ||||||
|  | 	for _, arg := range a { | ||||||
|  | 		if err, ok := arg.(error); ok { | ||||||
|  | 			if err != nil { | ||||||
|  | 				p.Println(fmt.Errorf(format, err)) | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	tp := TextPrinter(p) | ||||||
|  | 	return &tp | ||||||
|  | } | ||||||
							
								
								
									
										549
									
								
								vendor/github.com/pterm/pterm/bigtext_printer.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										549
									
								
								vendor/github.com/pterm/pterm/bigtext_printer.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,549 @@ | |||||||
|  | package pterm | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"strings" | ||||||
|  | 
 | ||||||
|  | 	"github.com/mattn/go-runewidth" | ||||||
|  | 
 | ||||||
|  | 	"github.com/pterm/pterm/internal" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // Letters is a slice of Letter.
 | ||||||
|  | type Letters []Letter | ||||||
|  | 
 | ||||||
|  | // NewLettersFromString creates a Letters object from a string, which is prefilled with the LetterStyle from ThemeDefault.
 | ||||||
|  | // You can override the ThemeDefault LetterStyle if you want to.
 | ||||||
|  | func NewLettersFromString(text string) Letters { | ||||||
|  | 	return NewLettersFromStringWithStyle(text, &ThemeDefault.LetterStyle) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // NewLettersFromStringWithStyle creates a Letters object from a string and applies a Style to it.
 | ||||||
|  | func NewLettersFromStringWithStyle(text string, style *Style) Letters { | ||||||
|  | 	s := strings.Split(text, "") | ||||||
|  | 	l := Letters{} | ||||||
|  | 
 | ||||||
|  | 	for _, s2 := range s { | ||||||
|  | 		l = append(l, Letter{ | ||||||
|  | 			String: s2, | ||||||
|  | 			Style:  style, | ||||||
|  | 		}) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return l | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Letter is an object, which holds a string and a specific Style for it.
 | ||||||
|  | type Letter struct { | ||||||
|  | 	String string | ||||||
|  | 	Style  *Style | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithStyle returns a new Letter with a specific Style.
 | ||||||
|  | func (l Letter) WithStyle(style *Style) *Letter { | ||||||
|  | 	l.Style = style | ||||||
|  | 	return &l | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithString returns a new Letter with a specific String.
 | ||||||
|  | func (l Letter) WithString(s string) *Letter { | ||||||
|  | 	l.String = s | ||||||
|  | 	return &l | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // BigTextPrinter renders big text.
 | ||||||
|  | // You can use this as title screen for your application.
 | ||||||
|  | type BigTextPrinter struct { | ||||||
|  | 	// BigCharacters holds the map from a normal character to it's big version.
 | ||||||
|  | 	BigCharacters map[string]string | ||||||
|  | 	Letters       Letters | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithBigCharacters returns a new BigTextPrinter with specific BigCharacters.
 | ||||||
|  | func (p BigTextPrinter) WithBigCharacters(chars map[string]string) *BigTextPrinter { | ||||||
|  | 	p.BigCharacters = chars | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithLetters returns a new BigTextPrinter with specific Letters
 | ||||||
|  | func (p BigTextPrinter) WithLetters(letters ...Letters) *BigTextPrinter { | ||||||
|  | 	l := Letters{} | ||||||
|  | 	for _, letter := range letters { | ||||||
|  | 		l = append(l, letter...) | ||||||
|  | 	} | ||||||
|  | 	p.Letters = l | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Srender renders the BigText as a string.
 | ||||||
|  | func (p BigTextPrinter) Srender() (string, error) { | ||||||
|  | 	var ret string | ||||||
|  | 
 | ||||||
|  | 	if RawOutput { | ||||||
|  | 		for _, letter := range p.Letters { | ||||||
|  | 			ret += letter.String | ||||||
|  | 		} | ||||||
|  | 		return ret, nil | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	var bigLetters Letters | ||||||
|  | 	for _, l := range p.Letters { | ||||||
|  | 		if val, ok := p.BigCharacters[l.String]; ok { | ||||||
|  | 			bigLetters = append(bigLetters, Letter{ | ||||||
|  | 				String: val, | ||||||
|  | 				Style:  l.Style, | ||||||
|  | 			}) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	var maxHeight int | ||||||
|  | 
 | ||||||
|  | 	for _, l := range bigLetters { | ||||||
|  | 		h := strings.Count(l.String, "\n") | ||||||
|  | 		if h > maxHeight { | ||||||
|  | 			maxHeight = h | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	for i := 0; i <= maxHeight; i++ { | ||||||
|  | 		for _, letter := range bigLetters { | ||||||
|  | 			var letterLine string | ||||||
|  | 			letterLines := strings.Split(letter.String, "\n") | ||||||
|  | 			maxLetterWidth := internal.GetStringMaxWidth(letter.String) | ||||||
|  | 			if len(letterLines) > i { | ||||||
|  | 				letterLine = letterLines[i] | ||||||
|  | 			} | ||||||
|  | 			letterLineLength := runewidth.StringWidth(letterLine) | ||||||
|  | 			if letterLineLength < maxLetterWidth { | ||||||
|  | 				letterLine += strings.Repeat(" ", maxLetterWidth-letterLineLength) | ||||||
|  | 			} | ||||||
|  | 			ret += letter.Style.Sprint(letterLine) | ||||||
|  | 		} | ||||||
|  | 		ret += "\n" | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return ret, nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Render prints the BigText to the terminal.
 | ||||||
|  | func (p BigTextPrinter) Render() error { | ||||||
|  | 	s, _ := p.Srender() | ||||||
|  | 	Println(s) | ||||||
|  | 
 | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // DefaultBigText contains default values for BigTextPrinter.
 | ||||||
|  | var DefaultBigText = BigTextPrinter{ | ||||||
|  | 	BigCharacters: map[string]string{ | ||||||
|  | 		"a": ` █████   | ||||||
|  | ██   ██  | ||||||
|  | ███████  | ||||||
|  | ██   ██  | ||||||
|  | ██   ██ `, | ||||||
|  | 		"A": ` █████   | ||||||
|  | ██   ██  | ||||||
|  | ███████  | ||||||
|  | ██   ██  | ||||||
|  | ██   ██ `, | ||||||
|  | 		"b": `██████   | ||||||
|  | ██   ██  | ||||||
|  | ██████   | ||||||
|  | ██   ██  | ||||||
|  | ██████`, | ||||||
|  | 		"B": `██████   | ||||||
|  | ██   ██  | ||||||
|  | ██████   | ||||||
|  | ██   ██  | ||||||
|  | ██████`, | ||||||
|  | 		"c": ` ██████  | ||||||
|  | ██       | ||||||
|  | ██       | ||||||
|  | ██       | ||||||
|  |  ██████`, | ||||||
|  | 		"C": ` ██████  | ||||||
|  | ██       | ||||||
|  | ██       | ||||||
|  | ██       | ||||||
|  |  ██████`, | ||||||
|  | 		"d": `██████   | ||||||
|  | ██   ██  | ||||||
|  | ██   ██  | ||||||
|  | ██   ██  | ||||||
|  | ██████ `, | ||||||
|  | 		"D": `██████   | ||||||
|  | ██   ██  | ||||||
|  | ██   ██  | ||||||
|  | ██   ██  | ||||||
|  | ██████ `, | ||||||
|  | 		"e": `███████  | ||||||
|  | ██       | ||||||
|  | █████    | ||||||
|  | ██       | ||||||
|  | ███████`, | ||||||
|  | 		"E": `███████  | ||||||
|  | ██       | ||||||
|  | █████    | ||||||
|  | ██       | ||||||
|  | ███████`, | ||||||
|  | 		"f": `███████  | ||||||
|  | ██       | ||||||
|  | █████    | ||||||
|  | ██       | ||||||
|  | ██     `, | ||||||
|  | 		"F": `███████  | ||||||
|  | ██       | ||||||
|  | █████    | ||||||
|  | ██       | ||||||
|  | ██     `, | ||||||
|  | 		"g": ` ██████   | ||||||
|  | ██        | ||||||
|  | ██   ███  | ||||||
|  | ██    ██  | ||||||
|  |  ██████  `, | ||||||
|  | 		"G": ` ██████   | ||||||
|  | ██        | ||||||
|  | ██   ███  | ||||||
|  | ██    ██  | ||||||
|  |  ██████  `, | ||||||
|  | 		"h": `██   ██  | ||||||
|  | ██   ██  | ||||||
|  | ███████  | ||||||
|  | ██   ██  | ||||||
|  | ██   ██ `, | ||||||
|  | 		"H": `██   ██  | ||||||
|  | ██   ██  | ||||||
|  | ███████  | ||||||
|  | ██   ██  | ||||||
|  | ██   ██ `, | ||||||
|  | 		"i": `██  | ||||||
|  | ██  | ||||||
|  | ██  | ||||||
|  | ██  | ||||||
|  | ██`, | ||||||
|  | 		"I": `██  | ||||||
|  | ██  | ||||||
|  | ██  | ||||||
|  | ██  | ||||||
|  | ██`, | ||||||
|  | 		"j": `     ██  | ||||||
|  |      ██  | ||||||
|  |      ██  | ||||||
|  | ██   ██  | ||||||
|  |  █████ `, | ||||||
|  | 		"J": `     ██  | ||||||
|  |      ██  | ||||||
|  |      ██  | ||||||
|  | ██   ██  | ||||||
|  |  █████ `, | ||||||
|  | 		"k": `██   ██  | ||||||
|  | ██  ██   | ||||||
|  | █████    | ||||||
|  | ██  ██   | ||||||
|  | ██   ██`, | ||||||
|  | 		"K": `██   ██  | ||||||
|  | ██  ██   | ||||||
|  | █████    | ||||||
|  | ██  ██   | ||||||
|  | ██   ██`, | ||||||
|  | 		"l": `██       | ||||||
|  | ██       | ||||||
|  | ██       | ||||||
|  | ██       | ||||||
|  | ███████ `, | ||||||
|  | 		"L": `██       | ||||||
|  | ██       | ||||||
|  | ██       | ||||||
|  | ██       | ||||||
|  | ███████ `, | ||||||
|  | 		"m": `███    ███  | ||||||
|  | ████  ████  | ||||||
|  | ██ ████ ██  | ||||||
|  | ██  ██  ██  | ||||||
|  | ██      ██`, | ||||||
|  | 		"M": `███    ███  | ||||||
|  | ████  ████  | ||||||
|  | ██ ████ ██  | ||||||
|  | ██  ██  ██  | ||||||
|  | ██      ██`, | ||||||
|  | 		"n": `███    ██  | ||||||
|  | ████   ██  | ||||||
|  | ██ ██  ██  | ||||||
|  | ██  ██ ██  | ||||||
|  | ██   ████`, | ||||||
|  | 		"N": `███    ██  | ||||||
|  | ████   ██  | ||||||
|  | ██ ██  ██  | ||||||
|  | ██  ██ ██  | ||||||
|  | ██   ████`, | ||||||
|  | 		"o": ` ██████   | ||||||
|  | ██    ██  | ||||||
|  | ██    ██  | ||||||
|  | ██    ██  | ||||||
|  |  ██████  `, | ||||||
|  | 		"O": ` ██████   | ||||||
|  | ██    ██  | ||||||
|  | ██    ██  | ||||||
|  | ██    ██  | ||||||
|  |  ██████  `, | ||||||
|  | 		"p": `██████   | ||||||
|  | ██   ██  | ||||||
|  | ██████   | ||||||
|  | ██       | ||||||
|  | ██     `, | ||||||
|  | 		"P": `██████   | ||||||
|  | ██   ██  | ||||||
|  | ██████   | ||||||
|  | ██       | ||||||
|  | ██     `, | ||||||
|  | 		"q": ` ██████   | ||||||
|  | ██    ██  | ||||||
|  | ██    ██  | ||||||
|  | ██ ▄▄ ██  | ||||||
|  |  ██████   | ||||||
|  |     ▀▀   `, | ||||||
|  | 		"Q": ` ██████   | ||||||
|  | ██    ██  | ||||||
|  | ██    ██  | ||||||
|  | ██ ▄▄ ██  | ||||||
|  |  ██████   | ||||||
|  |     ▀▀   `, | ||||||
|  | 		"r": `██████   | ||||||
|  | ██   ██  | ||||||
|  | ██████   | ||||||
|  | ██   ██  | ||||||
|  | ██   ██`, | ||||||
|  | 		"R": `██████   | ||||||
|  | ██   ██  | ||||||
|  | ██████   | ||||||
|  | ██   ██  | ||||||
|  | ██   ██`, | ||||||
|  | 		"s": `███████  | ||||||
|  | ██       | ||||||
|  | ███████  | ||||||
|  |      ██  | ||||||
|  | ███████`, | ||||||
|  | 		"S": `███████  | ||||||
|  | ██       | ||||||
|  | ███████  | ||||||
|  |      ██  | ||||||
|  | ███████`, | ||||||
|  | 		"t": `████████  | ||||||
|  |    ██     | ||||||
|  |    ██     | ||||||
|  |    ██     | ||||||
|  |    ██    `, | ||||||
|  | 		"T": `████████  | ||||||
|  |    ██     | ||||||
|  |    ██     | ||||||
|  |    ██     | ||||||
|  |    ██    `, | ||||||
|  | 		"u": `██    ██  | ||||||
|  | ██    ██  | ||||||
|  | ██    ██  | ||||||
|  | ██    ██  | ||||||
|  |  ██████ `, | ||||||
|  | 		"U": `██    ██  | ||||||
|  | ██    ██  | ||||||
|  | ██    ██  | ||||||
|  | ██    ██  | ||||||
|  |  ██████ `, | ||||||
|  | 		"v": `██    ██  | ||||||
|  | ██    ██  | ||||||
|  | ██    ██  | ||||||
|  |  ██  ██   | ||||||
|  |   ████   `, | ||||||
|  | 		"V": `██    ██  | ||||||
|  | ██    ██  | ||||||
|  | ██    ██  | ||||||
|  |  ██  ██   | ||||||
|  |   ████   `, | ||||||
|  | 		"w": `██     ██  | ||||||
|  | ██     ██  | ||||||
|  | ██  █  ██  | ||||||
|  | ██ ███ ██  | ||||||
|  |  ███ ███ `, | ||||||
|  | 		"W": `██     ██  | ||||||
|  | ██     ██  | ||||||
|  | ██  █  ██  | ||||||
|  | ██ ███ ██  | ||||||
|  |  ███ ███ `, | ||||||
|  | 		"x": `██   ██  | ||||||
|  |  ██ ██   | ||||||
|  |   ███    | ||||||
|  |  ██ ██   | ||||||
|  | ██   ██ `, | ||||||
|  | 		"X": `██   ██  | ||||||
|  |  ██ ██   | ||||||
|  |   ███    | ||||||
|  |  ██ ██   | ||||||
|  | ██   ██ `, | ||||||
|  | 		"y": `██    ██  | ||||||
|  |  ██  ██   | ||||||
|  |   ████    | ||||||
|  |    ██     | ||||||
|  |    ██   `, | ||||||
|  | 		"Y": `██    ██  | ||||||
|  |  ██  ██   | ||||||
|  |   ████    | ||||||
|  |    ██     | ||||||
|  |    ██   `, | ||||||
|  | 		"z": `███████  | ||||||
|  |    ███   | ||||||
|  |   ███    | ||||||
|  |  ███     | ||||||
|  | ███████`, | ||||||
|  | 		"Z": `███████  | ||||||
|  |    ███   | ||||||
|  |   ███    | ||||||
|  |  ███     | ||||||
|  | ███████`, | ||||||
|  | 		"0": ` ██████   | ||||||
|  | ██  ████  | ||||||
|  | ██ ██ ██  | ||||||
|  | ████  ██  | ||||||
|  |  ██████ `, | ||||||
|  | 		"1": ` ██  | ||||||
|  | ███  | ||||||
|  |  ██  | ||||||
|  |  ██  | ||||||
|  |  ██ `, | ||||||
|  | 		"2": `██████   | ||||||
|  |      ██  | ||||||
|  |  █████   | ||||||
|  | ██       | ||||||
|  | ███████ `, | ||||||
|  | 		"3": `██████   | ||||||
|  |      ██  | ||||||
|  |  █████   | ||||||
|  |      ██  | ||||||
|  | ██████ `, | ||||||
|  | 		"4": `██   ██  | ||||||
|  | ██   ██  | ||||||
|  | ███████  | ||||||
|  |      ██  | ||||||
|  |      ██ `, | ||||||
|  | 		"5": `███████  | ||||||
|  | ██       | ||||||
|  | ███████  | ||||||
|  |      ██  | ||||||
|  | ███████`, | ||||||
|  | 		"6": ` ██████   | ||||||
|  | ██        | ||||||
|  | ███████   | ||||||
|  | ██    ██  | ||||||
|  |  ██████ `, | ||||||
|  | 		"7": `███████  | ||||||
|  |      ██  | ||||||
|  |     ██   | ||||||
|  |    ██    | ||||||
|  |    ██`, | ||||||
|  | 		"8": ` █████   | ||||||
|  | ██   ██  | ||||||
|  |  █████   | ||||||
|  | ██   ██  | ||||||
|  |  █████ `, | ||||||
|  | 		"9": ` █████   | ||||||
|  | ██   ██  | ||||||
|  |  ██████  | ||||||
|  |      ██  | ||||||
|  |  █████ `, | ||||||
|  | 		" ": "    ", | ||||||
|  | 		"!": `██  | ||||||
|  | ██  | ||||||
|  | ██  | ||||||
|  |     | ||||||
|  | ██ `, | ||||||
|  | 		"$": `▄▄███▄▄· | ||||||
|  | ██       | ||||||
|  | ███████  | ||||||
|  |      ██  | ||||||
|  | ███████  | ||||||
|  |   ▀▀▀  `, | ||||||
|  | 		"%": `██  ██  | ||||||
|  |    ██   | ||||||
|  |   ██    | ||||||
|  |  ██     | ||||||
|  | ██  ██`, | ||||||
|  | 		"/": `    ██  | ||||||
|  |    ██   | ||||||
|  |   ██    | ||||||
|  |  ██     | ||||||
|  | ██   `, | ||||||
|  | 		"(": ` ██  | ||||||
|  | ██   | ||||||
|  | ██   | ||||||
|  | ██   | ||||||
|  |  ██ `, | ||||||
|  | 		")": `██   | ||||||
|  |  ██  | ||||||
|  |  ██  | ||||||
|  |  ██  | ||||||
|  | ██  `, | ||||||
|  | 		"?": `██████   | ||||||
|  |      ██  | ||||||
|  |   ▄███   | ||||||
|  |   ▀▀     | ||||||
|  |   ██   `, | ||||||
|  | 		"[": `███  | ||||||
|  | ██   | ||||||
|  | ██   | ||||||
|  | ██   | ||||||
|  | ███`, | ||||||
|  | 		"]": `███  | ||||||
|  |  ██  | ||||||
|  |  ██  | ||||||
|  |  ██  | ||||||
|  | ███ `, | ||||||
|  | 		".": `    | ||||||
|  |     | ||||||
|  |     | ||||||
|  |     | ||||||
|  | ██`, | ||||||
|  | 		",": `    | ||||||
|  |     | ||||||
|  |     | ||||||
|  |     | ||||||
|  | ▄█`, | ||||||
|  | 		"-": `       | ||||||
|  |        | ||||||
|  | █████  | ||||||
|  |        | ||||||
|  |        | ||||||
|  |      `, | ||||||
|  | 		"<": `  ██  | ||||||
|  |  ██   | ||||||
|  | ██    | ||||||
|  |  ██   | ||||||
|  |   ██ `, | ||||||
|  | 		">": `██    | ||||||
|  |  ██   | ||||||
|  |   ██  | ||||||
|  |  ██   | ||||||
|  | ██ `, | ||||||
|  | 		"*": `       | ||||||
|  | ▄ ██ ▄ | ||||||
|  |  ████  | ||||||
|  | ▀ ██ ▀ | ||||||
|  |      `, | ||||||
|  | 		"#": ` ██  ██   | ||||||
|  | ████████  | ||||||
|  |  ██  ██   | ||||||
|  | ████████  | ||||||
|  |  ██  ██ `, | ||||||
|  | 		"_": `         | ||||||
|  |          | ||||||
|  |          | ||||||
|  |          | ||||||
|  | ███████ `, | ||||||
|  | 		":": `    | ||||||
|  | ██  | ||||||
|  |     | ||||||
|  |     | ||||||
|  | ██ `, | ||||||
|  | 		"°": ` ████   | ||||||
|  | ██  ██  | ||||||
|  |  ████   | ||||||
|  |         | ||||||
|  |       `, | ||||||
|  | 	}, | ||||||
|  | } | ||||||
							
								
								
									
										363
									
								
								vendor/github.com/pterm/pterm/box_printer.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										363
									
								
								vendor/github.com/pterm/pterm/box_printer.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,363 @@ | |||||||
|  | package pterm | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  | 	"strings" | ||||||
|  | 
 | ||||||
|  | 	"github.com/mattn/go-runewidth" | ||||||
|  | 
 | ||||||
|  | 	"github.com/pterm/pterm/internal" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // BoxPrinter is able to render a box around printables.
 | ||||||
|  | type BoxPrinter struct { | ||||||
|  | 	Title                   string | ||||||
|  | 	TitleTopLeft            bool | ||||||
|  | 	TitleTopRight           bool | ||||||
|  | 	TitleTopCenter          bool | ||||||
|  | 	TitleBottomLeft         bool | ||||||
|  | 	TitleBottomRight        bool | ||||||
|  | 	TitleBottomCenter       bool | ||||||
|  | 	TextStyle               *Style | ||||||
|  | 	VerticalString          string | ||||||
|  | 	BoxStyle                *Style | ||||||
|  | 	HorizontalString        string | ||||||
|  | 	TopRightCornerString    string | ||||||
|  | 	TopLeftCornerString     string | ||||||
|  | 	BottomLeftCornerString  string | ||||||
|  | 	BottomRightCornerString string | ||||||
|  | 	TopPadding              int | ||||||
|  | 	BottomPadding           int | ||||||
|  | 	RightPadding            int | ||||||
|  | 	LeftPadding             int | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // DefaultBox is the default BoxPrinter.
 | ||||||
|  | var DefaultBox = BoxPrinter{ | ||||||
|  | 	VerticalString:          "|", | ||||||
|  | 	TopRightCornerString:    "└", | ||||||
|  | 	TopLeftCornerString:     "┘", | ||||||
|  | 	BottomLeftCornerString:  "┐", | ||||||
|  | 	BottomRightCornerString: "┌", | ||||||
|  | 	HorizontalString:        "─", | ||||||
|  | 	BoxStyle:                &ThemeDefault.BoxStyle, | ||||||
|  | 	TextStyle:               &ThemeDefault.BoxTextStyle, | ||||||
|  | 	RightPadding:            1, | ||||||
|  | 	LeftPadding:             1, | ||||||
|  | 	TopPadding:              0, | ||||||
|  | 	BottomPadding:           0, | ||||||
|  | 	TitleTopLeft:            true, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithTitle returns a new box with a specific Title.
 | ||||||
|  | func (p BoxPrinter) WithTitle(str string) *BoxPrinter { | ||||||
|  | 	p.Title = str | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithTitleTopLeft returns a new box with a specific Title alignment.
 | ||||||
|  | func (p BoxPrinter) WithTitleTopLeft(b ...bool) *BoxPrinter { | ||||||
|  | 	b2 := internal.WithBoolean(b) | ||||||
|  | 	p.TitleTopLeft = b2 | ||||||
|  | 	p.TitleTopRight = false | ||||||
|  | 	p.TitleTopCenter = false | ||||||
|  | 	p.TitleBottomLeft = false | ||||||
|  | 	p.TitleBottomRight = false | ||||||
|  | 	p.TitleBottomCenter = false | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithTitleTopRight returns a new box with a specific Title alignment.
 | ||||||
|  | func (p BoxPrinter) WithTitleTopRight(b ...bool) *BoxPrinter { | ||||||
|  | 	b2 := internal.WithBoolean(b) | ||||||
|  | 	p.TitleTopLeft = false | ||||||
|  | 	p.TitleTopRight = b2 | ||||||
|  | 	p.TitleTopCenter = false | ||||||
|  | 	p.TitleBottomLeft = false | ||||||
|  | 	p.TitleBottomRight = false | ||||||
|  | 	p.TitleBottomCenter = false | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithTitleTopCenter returns a new box with a specific Title alignment.
 | ||||||
|  | func (p BoxPrinter) WithTitleTopCenter(b ...bool) *BoxPrinter { | ||||||
|  | 	b2 := internal.WithBoolean(b) | ||||||
|  | 	p.TitleTopLeft = false | ||||||
|  | 	p.TitleTopRight = false | ||||||
|  | 	p.TitleTopCenter = b2 | ||||||
|  | 	p.TitleBottomLeft = false | ||||||
|  | 	p.TitleBottomRight = false | ||||||
|  | 	p.TitleBottomCenter = false | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithTitleBottomLeft returns a new box with a specific Title alignment.
 | ||||||
|  | func (p BoxPrinter) WithTitleBottomLeft(b ...bool) *BoxPrinter { | ||||||
|  | 	b2 := internal.WithBoolean(b) | ||||||
|  | 	p.TitleTopLeft = false | ||||||
|  | 	p.TitleTopRight = false | ||||||
|  | 	p.TitleTopCenter = false | ||||||
|  | 	p.TitleBottomLeft = b2 | ||||||
|  | 	p.TitleBottomRight = false | ||||||
|  | 	p.TitleBottomCenter = false | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithTitleBottomRight returns a new box with a specific Title alignment.
 | ||||||
|  | func (p BoxPrinter) WithTitleBottomRight(b ...bool) *BoxPrinter { | ||||||
|  | 	b2 := internal.WithBoolean(b) | ||||||
|  | 	p.TitleTopLeft = false | ||||||
|  | 	p.TitleTopRight = false | ||||||
|  | 	p.TitleTopCenter = false | ||||||
|  | 	p.TitleBottomLeft = false | ||||||
|  | 	p.TitleBottomRight = b2 | ||||||
|  | 	p.TitleBottomCenter = false | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithTitleBottomCenter returns a new box with a specific Title alignment.
 | ||||||
|  | func (p BoxPrinter) WithTitleBottomCenter(b ...bool) *BoxPrinter { | ||||||
|  | 	b2 := internal.WithBoolean(b) | ||||||
|  | 	p.TitleTopLeft = false | ||||||
|  | 	p.TitleTopRight = false | ||||||
|  | 	p.TitleTopCenter = false | ||||||
|  | 	p.TitleBottomLeft = false | ||||||
|  | 	p.TitleBottomRight = false | ||||||
|  | 	p.TitleBottomCenter = b2 | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithBoxStyle returns a new box with a specific box Style.
 | ||||||
|  | func (p BoxPrinter) WithBoxStyle(style *Style) *BoxPrinter { | ||||||
|  | 	p.BoxStyle = style | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithTextStyle returns a new box with a specific text Style.
 | ||||||
|  | func (p BoxPrinter) WithTextStyle(style *Style) *BoxPrinter { | ||||||
|  | 	p.TextStyle = style | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithTopRightCornerString returns a new box with a specific TopRightCornerString.
 | ||||||
|  | func (p BoxPrinter) WithTopRightCornerString(str string) *BoxPrinter { | ||||||
|  | 	p.TopRightCornerString = str | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithTopLeftCornerString returns a new box with a specific TopLeftCornerString.
 | ||||||
|  | func (p BoxPrinter) WithTopLeftCornerString(str string) *BoxPrinter { | ||||||
|  | 	p.TopLeftCornerString = str | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithBottomRightCornerString returns a new box with a specific BottomRightCornerString.
 | ||||||
|  | func (p BoxPrinter) WithBottomRightCornerString(str string) *BoxPrinter { | ||||||
|  | 	p.BottomRightCornerString = str | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithBottomLeftCornerString returns a new box with a specific BottomLeftCornerString.
 | ||||||
|  | func (p BoxPrinter) WithBottomLeftCornerString(str string) *BoxPrinter { | ||||||
|  | 	p.BottomLeftCornerString = str | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithVerticalString returns a new box with a specific VerticalString.
 | ||||||
|  | func (p BoxPrinter) WithVerticalString(str string) *BoxPrinter { | ||||||
|  | 	p.VerticalString = str | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithHorizontalString returns a new box with a specific HorizontalString.
 | ||||||
|  | func (p BoxPrinter) WithHorizontalString(str string) *BoxPrinter { | ||||||
|  | 	p.HorizontalString = str | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithTopPadding returns a new box with a specific TopPadding.
 | ||||||
|  | func (p BoxPrinter) WithTopPadding(padding int) *BoxPrinter { | ||||||
|  | 	if padding < 0 { | ||||||
|  | 		padding = 0 | ||||||
|  | 	} | ||||||
|  | 	p.TopPadding = padding | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithBottomPadding returns a new box with a specific BottomPadding.
 | ||||||
|  | func (p BoxPrinter) WithBottomPadding(padding int) *BoxPrinter { | ||||||
|  | 	if padding < 0 { | ||||||
|  | 		padding = 0 | ||||||
|  | 	} | ||||||
|  | 	p.BottomPadding = padding | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithRightPadding returns a new box with a specific RightPadding.
 | ||||||
|  | func (p BoxPrinter) WithRightPadding(padding int) *BoxPrinter { | ||||||
|  | 	if padding < 0 { | ||||||
|  | 		padding = 0 | ||||||
|  | 	} | ||||||
|  | 	p.RightPadding = padding | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithLeftPadding returns a new box with a specific LeftPadding.
 | ||||||
|  | func (p BoxPrinter) WithLeftPadding(padding int) *BoxPrinter { | ||||||
|  | 	if padding < 0 { | ||||||
|  | 		padding = 0 | ||||||
|  | 	} | ||||||
|  | 	p.LeftPadding = padding | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Sprint formats using the default formats for its operands and returns the resulting string.
 | ||||||
|  | // Spaces are added between operands when neither is a string.
 | ||||||
|  | func (p BoxPrinter) Sprint(a ...interface{}) string { | ||||||
|  | 	if p.BoxStyle == nil { | ||||||
|  | 		p.BoxStyle = &ThemeDefault.BoxStyle | ||||||
|  | 	} | ||||||
|  | 	if p.TextStyle == nil { | ||||||
|  | 		p.TextStyle = &ThemeDefault.BoxTextStyle | ||||||
|  | 	} | ||||||
|  | 	maxWidth := internal.GetStringMaxWidth(Sprint(a...)) | ||||||
|  | 
 | ||||||
|  | 	var topLine string | ||||||
|  | 	var bottomLine string | ||||||
|  | 
 | ||||||
|  | 	if p.Title == "" { | ||||||
|  | 		topLine = p.BoxStyle.Sprint(p.BottomRightCornerString) + strings.Repeat(p.BoxStyle.Sprint(p.HorizontalString), | ||||||
|  | 			maxWidth+p.LeftPadding+p.RightPadding) + p.BoxStyle.Sprint(p.BottomLeftCornerString) | ||||||
|  | 		bottomLine = p.BoxStyle.Sprint(p.TopRightCornerString) + strings.Repeat(p.BoxStyle.Sprint(p.HorizontalString), | ||||||
|  | 			maxWidth+p.LeftPadding+p.RightPadding) + p.BoxStyle.Sprint(p.TopLeftCornerString) | ||||||
|  | 	} else { | ||||||
|  | 		p.Title = strings.ReplaceAll(p.Title, "\n", " ") | ||||||
|  | 		if (maxWidth + p.RightPadding + p.LeftPadding - 4) < len(RemoveColorFromString(p.Title)) { | ||||||
|  | 			p.RightPadding = len(RemoveColorFromString(p.Title)) - (maxWidth + p.RightPadding + p.LeftPadding - 5) | ||||||
|  | 		} | ||||||
|  | 		if p.TitleTopLeft { | ||||||
|  | 			topLine = p.BoxStyle.Sprint(p.BottomRightCornerString) + internal.AddTitleToLine(p.Title, p.BoxStyle.Sprint(p.HorizontalString), maxWidth+p.LeftPadding+p.RightPadding, true) + p.BoxStyle.Sprint(p.BottomLeftCornerString) | ||||||
|  | 			bottomLine = p.BoxStyle.Sprint(p.TopRightCornerString) + strings.Repeat(p.BoxStyle.Sprint(p.HorizontalString), | ||||||
|  | 				maxWidth+p.LeftPadding+p.RightPadding) + p.BoxStyle.Sprint(p.TopLeftCornerString) | ||||||
|  | 		} else if p.TitleTopRight { | ||||||
|  | 			topLine = p.BoxStyle.Sprint(p.BottomRightCornerString) + internal.AddTitleToLine(p.Title, p.BoxStyle.Sprint(p.HorizontalString), maxWidth+p.LeftPadding+p.RightPadding, false) + p.BoxStyle.Sprint(p.BottomLeftCornerString) | ||||||
|  | 			bottomLine = p.BoxStyle.Sprint(p.TopRightCornerString) + strings.Repeat(p.BoxStyle.Sprint(p.HorizontalString), | ||||||
|  | 				maxWidth+p.LeftPadding+p.RightPadding) + p.BoxStyle.Sprint(p.TopLeftCornerString) | ||||||
|  | 		} else if p.TitleTopCenter { | ||||||
|  | 			topLine = p.BoxStyle.Sprint(p.BottomRightCornerString) + internal.AddTitleToLineCenter(p.Title, p.BoxStyle.Sprint(p.HorizontalString), maxWidth+p.LeftPadding+p.RightPadding) + p.BoxStyle.Sprint(p.BottomLeftCornerString) | ||||||
|  | 			bottomLine = p.BoxStyle.Sprint(p.TopRightCornerString) + strings.Repeat(p.BoxStyle.Sprint(p.HorizontalString), | ||||||
|  | 				maxWidth+p.LeftPadding+p.RightPadding) + p.BoxStyle.Sprint(p.TopLeftCornerString) | ||||||
|  | 		} else if p.TitleBottomLeft { | ||||||
|  | 			topLine = p.BoxStyle.Sprint(p.BottomRightCornerString) + strings.Repeat(p.BoxStyle.Sprint(p.HorizontalString), | ||||||
|  | 				maxWidth+p.LeftPadding+p.RightPadding) + p.BoxStyle.Sprint(p.BottomLeftCornerString) | ||||||
|  | 			bottomLine = p.BoxStyle.Sprint(p.TopRightCornerString) + internal.AddTitleToLine(p.Title, p.BoxStyle.Sprint(p.HorizontalString), maxWidth+p.LeftPadding+p.RightPadding, true) + p.BoxStyle.Sprint(p.TopLeftCornerString) | ||||||
|  | 		} else if p.TitleBottomRight { | ||||||
|  | 			topLine = p.BoxStyle.Sprint(p.BottomRightCornerString) + strings.Repeat(p.BoxStyle.Sprint(p.HorizontalString), | ||||||
|  | 				maxWidth+p.LeftPadding+p.RightPadding) + p.BoxStyle.Sprint(p.BottomLeftCornerString) | ||||||
|  | 			bottomLine = p.BoxStyle.Sprint(p.TopRightCornerString) + internal.AddTitleToLine(p.Title, p.BoxStyle.Sprint(p.HorizontalString), maxWidth+p.LeftPadding+p.RightPadding, false) + p.BoxStyle.Sprint(p.TopLeftCornerString) | ||||||
|  | 		} else if p.TitleBottomCenter { | ||||||
|  | 			topLine = p.BoxStyle.Sprint(p.BottomRightCornerString) + strings.Repeat(p.BoxStyle.Sprint(p.HorizontalString), | ||||||
|  | 				maxWidth+p.LeftPadding+p.RightPadding) + p.BoxStyle.Sprint(p.BottomLeftCornerString) | ||||||
|  | 			bottomLine = p.BoxStyle.Sprint(p.TopRightCornerString) + internal.AddTitleToLineCenter(p.Title, p.BoxStyle.Sprint(p.HorizontalString), maxWidth+p.LeftPadding+p.RightPadding) + p.BoxStyle.Sprint(p.TopLeftCornerString) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	boxString := strings.Repeat("\n", p.TopPadding) + Sprint(a...) + strings.Repeat("\n", p.BottomPadding) | ||||||
|  | 
 | ||||||
|  | 	ss := strings.Split(boxString, "\n") | ||||||
|  | 	for i, s2 := range ss { | ||||||
|  | 		if runewidth.StringWidth(RemoveColorFromString(s2)) < maxWidth { | ||||||
|  | 			ss[i] = p.BoxStyle.Sprint(p.VerticalString) + strings.Repeat(" ", p.LeftPadding) + p.TextStyle.Sprint(s2) + | ||||||
|  | 				strings.Repeat(" ", maxWidth-runewidth.StringWidth(RemoveColorFromString(s2))+p.RightPadding) + | ||||||
|  | 				p.BoxStyle.Sprint(p.VerticalString) | ||||||
|  | 		} else { | ||||||
|  | 			ss[i] = p.BoxStyle.Sprint(p.VerticalString) + strings.Repeat(" ", p.LeftPadding) + p.TextStyle.Sprint(s2) + | ||||||
|  | 				strings.Repeat(" ", p.RightPadding) + p.BoxStyle.Sprint(p.VerticalString) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return topLine + "\n" + strings.Join(ss, "\n") + "\n" + bottomLine | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Sprintln formats using the default formats for its operands and returns the resulting string.
 | ||||||
|  | // Spaces are always added between operands and a newline is appended.
 | ||||||
|  | func (p BoxPrinter) Sprintln(a ...interface{}) string { | ||||||
|  | 	return p.Sprint(strings.TrimSuffix(Sprintln(a...), "\n")) + "\n" | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Sprintf formats according to a format specifier and returns the resulting string.
 | ||||||
|  | func (p BoxPrinter) Sprintf(format string, a ...interface{}) string { | ||||||
|  | 	return p.Sprint(Sprintf(format, a...)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Sprintfln formats according to a format specifier and returns the resulting string.
 | ||||||
|  | // Spaces are always added between operands and a newline is appended.
 | ||||||
|  | func (p BoxPrinter) Sprintfln(format string, a ...interface{}) string { | ||||||
|  | 	return p.Sprintf(format, a...) + "\n" | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Print formats using the default formats for its operands and writes to standard output.
 | ||||||
|  | // Spaces are added between operands when neither is a string.
 | ||||||
|  | // It returns the number of bytes written and any write error encountered.
 | ||||||
|  | func (p BoxPrinter) Print(a ...interface{}) *TextPrinter { | ||||||
|  | 	Print(p.Sprint(a...)) | ||||||
|  | 	tp := TextPrinter(p) | ||||||
|  | 	return &tp | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Println formats using the default formats for its operands and writes to standard output.
 | ||||||
|  | // Spaces are always added between operands and a newline is appended.
 | ||||||
|  | // It returns the number of bytes written and any write error encountered.
 | ||||||
|  | func (p BoxPrinter) Println(a ...interface{}) *TextPrinter { | ||||||
|  | 	Print(p.Sprintln(a...)) | ||||||
|  | 	tp := TextPrinter(p) | ||||||
|  | 	return &tp | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Printf formats according to a format specifier and writes to standard output.
 | ||||||
|  | // It returns the number of bytes written and any write error encountered.
 | ||||||
|  | func (p BoxPrinter) Printf(format string, a ...interface{}) *TextPrinter { | ||||||
|  | 	Print(p.Sprintf(format, a...)) | ||||||
|  | 	tp := TextPrinter(p) | ||||||
|  | 	return &tp | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Printfln formats according to a format specifier and writes to standard output.
 | ||||||
|  | // Spaces are always added between operands and a newline is appended.
 | ||||||
|  | // It returns the number of bytes written and any write error encountered.
 | ||||||
|  | func (p BoxPrinter) Printfln(format string, a ...interface{}) *TextPrinter { | ||||||
|  | 	Print(p.Sprintfln(format, a...)) | ||||||
|  | 	tp := TextPrinter(p) | ||||||
|  | 	return &tp | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // PrintOnError prints every error which is not nil.
 | ||||||
|  | // If every error is nil, nothing will be printed.
 | ||||||
|  | // This can be used for simple error checking.
 | ||||||
|  | func (p BoxPrinter) PrintOnError(a ...interface{}) *TextPrinter { | ||||||
|  | 	for _, arg := range a { | ||||||
|  | 		if err, ok := arg.(error); ok { | ||||||
|  | 			if err != nil { | ||||||
|  | 				p.Println(err) | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	tp := TextPrinter(p) | ||||||
|  | 	return &tp | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // PrintOnErrorf wraps every error which is not nil and prints it.
 | ||||||
|  | // If every error is nil, nothing will be printed.
 | ||||||
|  | // This can be used for simple error checking.
 | ||||||
|  | func (p BoxPrinter) PrintOnErrorf(format string, a ...interface{}) *TextPrinter { | ||||||
|  | 	for _, arg := range a { | ||||||
|  | 		if err, ok := arg.(error); ok { | ||||||
|  | 			if err != nil { | ||||||
|  | 				p.Println(fmt.Errorf(format, err)) | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	tp := TextPrinter(p) | ||||||
|  | 	return &tp | ||||||
|  | } | ||||||
							
								
								
									
										143
									
								
								vendor/github.com/pterm/pterm/bulletlist_printer.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										143
									
								
								vendor/github.com/pterm/pterm/bulletlist_printer.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,143 @@ | |||||||
|  | package pterm | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"strings" | ||||||
|  | 
 | ||||||
|  | 	"github.com/pterm/pterm/internal" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // NewBulletListFromStrings returns a BulletListPrinter with Text using the NewTreeListItemFromString method.
 | ||||||
|  | func NewBulletListFromStrings(s []string, padding string) BulletListPrinter { | ||||||
|  | 	var lis []BulletListItem | ||||||
|  | 	for _, line := range s { | ||||||
|  | 		lis = append(lis, NewBulletListItemFromString(line, padding)) | ||||||
|  | 	} | ||||||
|  | 	return *DefaultBulletList.WithItems(lis) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // NewBulletListItemFromString returns a BulletListItem with a Text. The padding is counted in the Text to define the Level of the ListItem.
 | ||||||
|  | func NewBulletListItemFromString(text string, padding string) BulletListItem { | ||||||
|  | 	s, l := internal.RemoveAndCountPrefix(text, padding) | ||||||
|  | 	return BulletListItem{ | ||||||
|  | 		Level: l, | ||||||
|  | 		Text:  s, | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // BulletListItem is able to render a ListItem.
 | ||||||
|  | type BulletListItem struct { | ||||||
|  | 	Level       int | ||||||
|  | 	Text        string | ||||||
|  | 	TextStyle   *Style | ||||||
|  | 	Bullet      string | ||||||
|  | 	BulletStyle *Style | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithLevel returns a new BulletListItem with a specific Level.
 | ||||||
|  | func (p BulletListItem) WithLevel(level int) *BulletListItem { | ||||||
|  | 	p.Level = level | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithText returns a new BulletListItem with a specific Text.
 | ||||||
|  | func (p BulletListItem) WithText(text string) *BulletListItem { | ||||||
|  | 	p.Text = text | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithTextStyle returns a new BulletListItem with a specific TextStyle.
 | ||||||
|  | func (p BulletListItem) WithTextStyle(style *Style) *BulletListItem { | ||||||
|  | 	p.TextStyle = style | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithBullet returns a new BulletListItem with a specific Prefix.
 | ||||||
|  | func (p BulletListItem) WithBullet(bullet string) *BulletListItem { | ||||||
|  | 	p.Bullet = bullet | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithBulletStyle returns a new BulletListItem with a specific BulletStyle.
 | ||||||
|  | func (p BulletListItem) WithBulletStyle(style *Style) *BulletListItem { | ||||||
|  | 	p.BulletStyle = style | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // NewBulletListFromString returns a BulletListPrinter with Text using the NewTreeListItemFromString method, splitting after return (\n).
 | ||||||
|  | func NewBulletListFromString(s string, padding string) BulletListPrinter { | ||||||
|  | 	return NewBulletListFromStrings(strings.Split(s, "\n"), padding) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // DefaultBulletList contains standards, which can be used to print a BulletListPrinter.
 | ||||||
|  | var DefaultBulletList = BulletListPrinter{ | ||||||
|  | 	Bullet:      "•", | ||||||
|  | 	TextStyle:   &ThemeDefault.BulletListTextStyle, | ||||||
|  | 	BulletStyle: &ThemeDefault.BulletListBulletStyle, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // BulletListPrinter is able to render a list.
 | ||||||
|  | type BulletListPrinter struct { | ||||||
|  | 	Items       []BulletListItem | ||||||
|  | 	TextStyle   *Style | ||||||
|  | 	Bullet      string | ||||||
|  | 	BulletStyle *Style | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithItems returns a new list with specific Items.
 | ||||||
|  | func (l BulletListPrinter) WithItems(items []BulletListItem) *BulletListPrinter { | ||||||
|  | 	l.Items = append(l.Items, items...) | ||||||
|  | 	return &l | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithTextStyle returns a new list with a specific text style.
 | ||||||
|  | func (l BulletListPrinter) WithTextStyle(style *Style) *BulletListPrinter { | ||||||
|  | 	l.TextStyle = style | ||||||
|  | 	return &l | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithBullet returns a new list with a specific bullet.
 | ||||||
|  | func (l BulletListPrinter) WithBullet(bullet string) *BulletListPrinter { | ||||||
|  | 	l.Bullet = bullet | ||||||
|  | 	return &l | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithBulletStyle returns a new list with a specific bullet style.
 | ||||||
|  | func (l BulletListPrinter) WithBulletStyle(style *Style) *BulletListPrinter { | ||||||
|  | 	l.BulletStyle = style | ||||||
|  | 	return &l | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Render prints the list to the terminal.
 | ||||||
|  | func (l BulletListPrinter) Render() error { | ||||||
|  | 	s, _ := l.Srender() | ||||||
|  | 	Println(s) | ||||||
|  | 
 | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Srender renders the list as a string.
 | ||||||
|  | func (l BulletListPrinter) Srender() (string, error) { | ||||||
|  | 	var ret string | ||||||
|  | 	for _, item := range l.Items { | ||||||
|  | 		if item.TextStyle == nil { | ||||||
|  | 			if l.TextStyle == nil { | ||||||
|  | 				item.TextStyle = &ThemeDefault.BulletListTextStyle | ||||||
|  | 			} else { | ||||||
|  | 				item.TextStyle = l.TextStyle | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		if item.BulletStyle == nil { | ||||||
|  | 			if l.BulletStyle == nil { | ||||||
|  | 				item.BulletStyle = &ThemeDefault.BulletListBulletStyle | ||||||
|  | 			} else { | ||||||
|  | 				item.BulletStyle = l.BulletStyle | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		if item.Bullet == "" { | ||||||
|  | 			ret += strings.Repeat(" ", item.Level) + item.BulletStyle.Sprint(l.Bullet) + " " + item.TextStyle.Sprint(item.Text) + "\n" | ||||||
|  | 		} else { | ||||||
|  | 			ret += strings.Repeat(" ", item.Level) + item.BulletStyle.Sprint(item.Bullet) + " " + item.TextStyle.Sprint(item.Text) + "\n" | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return ret, nil | ||||||
|  | } | ||||||
							
								
								
									
										160
									
								
								vendor/github.com/pterm/pterm/center_printer.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										160
									
								
								vendor/github.com/pterm/pterm/center_printer.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,160 @@ | |||||||
|  | package pterm | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  | 	"strings" | ||||||
|  | 
 | ||||||
|  | 	"github.com/mattn/go-runewidth" | ||||||
|  | 
 | ||||||
|  | 	"github.com/pterm/pterm/internal" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // DefaultCenter is the default CenterPrinter.
 | ||||||
|  | var DefaultCenter = CenterPrinter{ | ||||||
|  | 	CenterEachLineSeparately: false, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // CenterPrinter prints centered text.
 | ||||||
|  | type CenterPrinter struct { | ||||||
|  | 	CenterEachLineSeparately bool | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithCenterEachLineSeparately centers each line separately.
 | ||||||
|  | func (p CenterPrinter) WithCenterEachLineSeparately(b ...bool) *CenterPrinter { | ||||||
|  | 	bt := internal.WithBoolean(b) | ||||||
|  | 	p.CenterEachLineSeparately = bt | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Sprint formats using the default formats for its operands and returns the resulting string.
 | ||||||
|  | // Spaces are added between operands when neither is a string.
 | ||||||
|  | func (p CenterPrinter) Sprint(a ...interface{}) string { | ||||||
|  | 	if RawOutput { | ||||||
|  | 		return Sprint(a...) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	lines := strings.Split(Sprint(a...), "\n") | ||||||
|  | 
 | ||||||
|  | 	var ret string | ||||||
|  | 
 | ||||||
|  | 	if p.CenterEachLineSeparately { | ||||||
|  | 		for _, line := range lines { | ||||||
|  | 			margin := (GetTerminalWidth() - runewidth.StringWidth(RemoveColorFromString(line))) / 2 | ||||||
|  | 			if margin < 1 { | ||||||
|  | 				ret += line + "\n" | ||||||
|  | 			} else { | ||||||
|  | 				ret += strings.Repeat(" ", margin) + line + "\n" | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		return ret | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	var maxLineWidth int | ||||||
|  | 
 | ||||||
|  | 	for _, line := range lines { | ||||||
|  | 		lineLength := runewidth.StringWidth(RemoveColorFromString(line)) | ||||||
|  | 		if maxLineWidth < lineLength { | ||||||
|  | 			maxLineWidth = lineLength | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	indent := GetTerminalWidth() - maxLineWidth | ||||||
|  | 
 | ||||||
|  | 	if indent/2 < 1 { | ||||||
|  | 		for _, line := range lines { | ||||||
|  | 			ret += line + "\n" | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		return ret | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	for _, line := range lines { | ||||||
|  | 		ret += strings.Repeat(" ", indent/2) + line + "\n" | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return ret | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Sprintln formats using the default formats for its operands and returns the resulting string.
 | ||||||
|  | // Spaces are always added between operands and a newline is appended.
 | ||||||
|  | func (p CenterPrinter) Sprintln(a ...interface{}) string { | ||||||
|  | 	return p.Sprint(Sprintln(a...)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Sprintf formats according to a format specifier and returns the resulting string.
 | ||||||
|  | func (p CenterPrinter) Sprintf(format string, a ...interface{}) string { | ||||||
|  | 	return p.Sprint(Sprintf(format, a...)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Sprintfln formats according to a format specifier and returns the resulting string.
 | ||||||
|  | // Spaces are always added between operands and a newline is appended.
 | ||||||
|  | func (p CenterPrinter) Sprintfln(format string, a ...interface{}) string { | ||||||
|  | 	return p.Sprintf(format, a...) + "\n" | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Print formats using the default formats for its operands and writes to standard output.
 | ||||||
|  | // Spaces are added between operands when neither is a string.
 | ||||||
|  | // It returns the number of bytes written and any write error encountered.
 | ||||||
|  | func (p CenterPrinter) Print(a ...interface{}) *TextPrinter { | ||||||
|  | 	Print(p.Sprint(a...)) | ||||||
|  | 	tp := TextPrinter(p) | ||||||
|  | 	return &tp | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Println formats using the default formats for its operands and writes to standard output.
 | ||||||
|  | // Spaces are always added between operands and a newline is appended.
 | ||||||
|  | // It returns the number of bytes written and any write error encountered.
 | ||||||
|  | func (p CenterPrinter) Println(a ...interface{}) *TextPrinter { | ||||||
|  | 	Print(p.Sprintln(a...)) | ||||||
|  | 	tp := TextPrinter(p) | ||||||
|  | 	return &tp | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Printf formats according to a format specifier and writes to standard output.
 | ||||||
|  | // It returns the number of bytes written and any write error encountered.
 | ||||||
|  | func (p CenterPrinter) Printf(format string, a ...interface{}) *TextPrinter { | ||||||
|  | 	Print(p.Sprintf(format, a...)) | ||||||
|  | 	tp := TextPrinter(p) | ||||||
|  | 	return &tp | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Printfln formats according to a format specifier and writes to standard output.
 | ||||||
|  | // Spaces are always added between operands and a newline is appended.
 | ||||||
|  | // It returns the number of bytes written and any write error encountered.
 | ||||||
|  | func (p CenterPrinter) Printfln(format string, a ...interface{}) *TextPrinter { | ||||||
|  | 	Print(p.Sprintfln(format, a...)) | ||||||
|  | 	tp := TextPrinter(p) | ||||||
|  | 	return &tp | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // PrintOnError prints every error which is not nil.
 | ||||||
|  | // If every error is nil, nothing will be printed.
 | ||||||
|  | // This can be used for simple error checking.
 | ||||||
|  | func (p CenterPrinter) PrintOnError(a ...interface{}) *TextPrinter { | ||||||
|  | 	for _, arg := range a { | ||||||
|  | 		if err, ok := arg.(error); ok { | ||||||
|  | 			if err != nil { | ||||||
|  | 				p.Println(err) | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	tp := TextPrinter(p) | ||||||
|  | 	return &tp | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // PrintOnErrorf wraps every error which is not nil and prints it.
 | ||||||
|  | // If every error is nil, nothing will be printed.
 | ||||||
|  | // This can be used for simple error checking.
 | ||||||
|  | func (p CenterPrinter) PrintOnErrorf(format string, a ...interface{}) *TextPrinter { | ||||||
|  | 	for _, arg := range a { | ||||||
|  | 		if err, ok := arg.(error); ok { | ||||||
|  | 			if err != nil { | ||||||
|  | 				p.Println(fmt.Errorf(format, err)) | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	tp := TextPrinter(p) | ||||||
|  | 	return &tp | ||||||
|  | } | ||||||
							
								
								
									
										361
									
								
								vendor/github.com/pterm/pterm/color.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										361
									
								
								vendor/github.com/pterm/pterm/color.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,361 @@ | |||||||
|  | package pterm | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  | 	"strings" | ||||||
|  | 
 | ||||||
|  | 	"github.com/gookit/color" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // PrintColor is false if PTerm should not print colored output.
 | ||||||
|  | var PrintColor = true | ||||||
|  | 
 | ||||||
|  | // EnableColor enables colors.
 | ||||||
|  | func EnableColor() { | ||||||
|  | 	color.Enable = true | ||||||
|  | 	PrintColor = true | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // DisableColor disables colors.
 | ||||||
|  | func DisableColor() { | ||||||
|  | 	color.Enable = false | ||||||
|  | 	PrintColor = false | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Foreground colors. basic foreground colors 30 - 37.
 | ||||||
|  | const ( | ||||||
|  | 	FgBlack Color = iota + 30 | ||||||
|  | 	FgRed | ||||||
|  | 	FgGreen | ||||||
|  | 	FgYellow | ||||||
|  | 	FgBlue | ||||||
|  | 	FgMagenta | ||||||
|  | 	FgCyan | ||||||
|  | 	FgWhite | ||||||
|  | 	// FgDefault revert default FG.
 | ||||||
|  | 	FgDefault Color = 39 | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // Extra foreground color 90 - 97.
 | ||||||
|  | const ( | ||||||
|  | 	FgDarkGray Color = iota + 90 | ||||||
|  | 	FgLightRed | ||||||
|  | 	FgLightGreen | ||||||
|  | 	FgLightYellow | ||||||
|  | 	FgLightBlue | ||||||
|  | 	FgLightMagenta | ||||||
|  | 	FgLightCyan | ||||||
|  | 	FgLightWhite | ||||||
|  | 	// FgGray is an alias of FgDarkGray.
 | ||||||
|  | 	FgGray Color = 90 | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // Background colors. basic background colors 40 - 47.
 | ||||||
|  | const ( | ||||||
|  | 	BgBlack Color = iota + 40 | ||||||
|  | 	BgRed | ||||||
|  | 	BgGreen | ||||||
|  | 	BgYellow // BgBrown like yellow
 | ||||||
|  | 	BgBlue | ||||||
|  | 	BgMagenta | ||||||
|  | 	BgCyan | ||||||
|  | 	BgWhite | ||||||
|  | 	// BgDefault reverts to the default background.
 | ||||||
|  | 	BgDefault Color = 49 | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // Extra background color 100 - 107.
 | ||||||
|  | const ( | ||||||
|  | 	BgDarkGray Color = iota + 100 | ||||||
|  | 	BgLightRed | ||||||
|  | 	BgLightGreen | ||||||
|  | 	BgLightYellow | ||||||
|  | 	BgLightBlue | ||||||
|  | 	BgLightMagenta | ||||||
|  | 	BgLightCyan | ||||||
|  | 	BgLightWhite | ||||||
|  | 	// BgGray is an alias of BgDarkGray.
 | ||||||
|  | 	BgGray Color = 100 | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // Option settings.
 | ||||||
|  | const ( | ||||||
|  | 	Reset Color = iota | ||||||
|  | 	Bold | ||||||
|  | 	Fuzzy | ||||||
|  | 	Italic | ||||||
|  | 	Underscore | ||||||
|  | 	Blink | ||||||
|  | 	FastBlink | ||||||
|  | 	Reverse | ||||||
|  | 	Concealed | ||||||
|  | 	Strikethrough | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | var ( | ||||||
|  | 	// Red is an alias for FgRed.Sprint.
 | ||||||
|  | 	Red = FgRed.Sprint | ||||||
|  | 	// Cyan is an alias for FgCyan.Sprint.
 | ||||||
|  | 	Cyan = FgCyan.Sprint | ||||||
|  | 	// Gray is an alias for FgGray.Sprint.
 | ||||||
|  | 	Gray = FgGray.Sprint | ||||||
|  | 	// Blue is an alias for FgBlue.Sprint.
 | ||||||
|  | 	Blue = FgBlue.Sprint | ||||||
|  | 	// Black is an alias for FgBlack.Sprint.
 | ||||||
|  | 	Black = FgBlack.Sprint | ||||||
|  | 	// Green is an alias for FgGreen.Sprint.
 | ||||||
|  | 	Green = FgGreen.Sprint | ||||||
|  | 	// White is an alias for FgWhite.Sprint.
 | ||||||
|  | 	White = FgWhite.Sprint | ||||||
|  | 	// Yellow is an alias for FgYellow.Sprint.
 | ||||||
|  | 	Yellow = FgYellow.Sprint | ||||||
|  | 	// Magenta is an alias for FgMagenta.Sprint.
 | ||||||
|  | 	Magenta = FgMagenta.Sprint | ||||||
|  | 
 | ||||||
|  | 	// Normal is an alias for FgDefault.Sprint.
 | ||||||
|  | 	Normal = FgDefault.Sprint | ||||||
|  | 
 | ||||||
|  | 	// extra light.
 | ||||||
|  | 
 | ||||||
|  | 	// LightRed is a shortcut for FgLightRed.Sprint.
 | ||||||
|  | 	LightRed = FgLightRed.Sprint | ||||||
|  | 	// LightCyan is a shortcut for FgLightCyan.Sprint.
 | ||||||
|  | 	LightCyan = FgLightCyan.Sprint | ||||||
|  | 	// LightBlue is a shortcut for FgLightBlue.Sprint.
 | ||||||
|  | 	LightBlue = FgLightBlue.Sprint | ||||||
|  | 	// LightGreen is a shortcut for FgLightGreen.Sprint.
 | ||||||
|  | 	LightGreen = FgLightGreen.Sprint | ||||||
|  | 	// LightWhite is a shortcut for FgLightWhite.Sprint.
 | ||||||
|  | 	LightWhite = FgLightWhite.Sprint | ||||||
|  | 	// LightYellow is a shortcut for FgLightYellow.Sprint.
 | ||||||
|  | 	LightYellow = FgLightYellow.Sprint | ||||||
|  | 	// LightMagenta is a shortcut for FgLightMagenta.Sprint.
 | ||||||
|  | 	LightMagenta = FgLightMagenta.Sprint | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // Color is a number which will be used to color strings in the terminal.
 | ||||||
|  | type Color uint8 | ||||||
|  | 
 | ||||||
|  | // Sprintln formats using the default formats for its operands and returns the resulting string.
 | ||||||
|  | // Spaces are always added between operands and a newline is appended.
 | ||||||
|  | // Input will be colored with the parent Color.
 | ||||||
|  | func (c Color) Sprintln(a ...interface{}) string { | ||||||
|  | 	str := fmt.Sprintln(a...) | ||||||
|  | 	return c.Sprint(str) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Sprint formats using the default formats for its operands and returns the resulting string.
 | ||||||
|  | // Spaces are added between operands when neither is a string.
 | ||||||
|  | // Input will be colored with the parent Color.
 | ||||||
|  | func (c Color) Sprint(a ...interface{}) string { | ||||||
|  | 	message := Sprint(a...) | ||||||
|  | 	messageLines := strings.Split(message, "\n") | ||||||
|  | 	for i, line := range messageLines { | ||||||
|  | 		messageLines[i] = color.RenderCode(c.String(), strings.ReplaceAll(line, color.ResetSet, Sprintf("\x1b[0m\u001B[%sm", c.String()))) | ||||||
|  | 	} | ||||||
|  | 	message = strings.Join(messageLines, "\n") | ||||||
|  | 	return message | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Sprintf formats according to a format specifier and returns the resulting string.
 | ||||||
|  | // Input will be colored with the parent Color.
 | ||||||
|  | func (c Color) Sprintf(format string, a ...interface{}) string { | ||||||
|  | 	return c.Sprint(Sprintf(format, a...)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Sprintfln formats according to a format specifier and returns the resulting string.
 | ||||||
|  | // Spaces are always added between operands and a newline is appended.
 | ||||||
|  | // Input will be colored with the parent Color.
 | ||||||
|  | func (c Color) Sprintfln(format string, a ...interface{}) string { | ||||||
|  | 	return c.Sprint(Sprintf(format, a...) + "\n") | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Println formats using the default formats for its operands and writes to standard output.
 | ||||||
|  | // Spaces are always added between operands and a newline is appended.
 | ||||||
|  | // It returns the number of bytes written and any write error encountered.
 | ||||||
|  | // Input will be colored with the parent Color.
 | ||||||
|  | func (c Color) Println(a ...interface{}) *TextPrinter { | ||||||
|  | 	Print(c.Sprintln(a...)) | ||||||
|  | 	tc := TextPrinter(c) | ||||||
|  | 	return &tc | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Print formats using the default formats for its operands and writes to standard output.
 | ||||||
|  | // Spaces are added between operands when neither is a string.
 | ||||||
|  | // It returns the number of bytes written and any write error encountered.
 | ||||||
|  | // Input will be colored with the parent Color.
 | ||||||
|  | func (c Color) Print(a ...interface{}) *TextPrinter { | ||||||
|  | 	Print(c.Sprint(a...)) | ||||||
|  | 	tc := TextPrinter(c) | ||||||
|  | 	return &tc | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Printf formats according to a format specifier and writes to standard output.
 | ||||||
|  | // It returns the number of bytes written and any write error encountered.
 | ||||||
|  | // Input will be colored with the parent Color.
 | ||||||
|  | func (c Color) Printf(format string, a ...interface{}) *TextPrinter { | ||||||
|  | 	Print(c.Sprintf(format, a...)) | ||||||
|  | 	tc := TextPrinter(c) | ||||||
|  | 	return &tc | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Printfln formats according to a format specifier and writes to standard output.
 | ||||||
|  | // Spaces are always added between operands and a newline is appended.
 | ||||||
|  | // It returns the number of bytes written and any write error encountered.
 | ||||||
|  | // Input will be colored with the parent Color.
 | ||||||
|  | func (c Color) Printfln(format string, a ...interface{}) *TextPrinter { | ||||||
|  | 	Print(c.Sprintfln(format, a...)) | ||||||
|  | 	tp := TextPrinter(c) | ||||||
|  | 	return &tp | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // PrintOnError prints every error which is not nil.
 | ||||||
|  | // If every error is nil, nothing will be printed.
 | ||||||
|  | // This can be used for simple error checking.
 | ||||||
|  | func (p Color) PrintOnError(a ...interface{}) *TextPrinter { | ||||||
|  | 	for _, arg := range a { | ||||||
|  | 		if err, ok := arg.(error); ok { | ||||||
|  | 			if err != nil { | ||||||
|  | 				p.Println(err) | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	tp := TextPrinter(p) | ||||||
|  | 	return &tp | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // PrintOnErrorf wraps every error which is not nil and prints it.
 | ||||||
|  | // If every error is nil, nothing will be printed.
 | ||||||
|  | // This can be used for simple error checking.
 | ||||||
|  | func (p Color) PrintOnErrorf(format string, a ...interface{}) *TextPrinter { | ||||||
|  | 	for _, arg := range a { | ||||||
|  | 		if err, ok := arg.(error); ok { | ||||||
|  | 			if err != nil { | ||||||
|  | 				p.Println(fmt.Errorf(format, err)) | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	tp := TextPrinter(p) | ||||||
|  | 	return &tp | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // String converts the color to a string. eg "35".
 | ||||||
|  | func (c Color) String() string { | ||||||
|  | 	return fmt.Sprintf("%d", c) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Style is a collection of colors.
 | ||||||
|  | // Can include foreground, background and styling (eg. Bold, Underscore, etc.) colors.
 | ||||||
|  | type Style []Color | ||||||
|  | 
 | ||||||
|  | // NewStyle returns a new Style.
 | ||||||
|  | // Accepts multiple colors.
 | ||||||
|  | func NewStyle(colors ...Color) *Style { | ||||||
|  | 	ret := Style{} | ||||||
|  | 	for _, c := range colors { | ||||||
|  | 		ret = append(ret, c) | ||||||
|  | 	} | ||||||
|  | 	return &ret | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Add styles to the current Style.
 | ||||||
|  | func (s Style) Add(styles ...Style) Style { | ||||||
|  | 	ret := s | ||||||
|  | 
 | ||||||
|  | 	for _, st := range styles { | ||||||
|  | 		ret = append(ret, st...) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return ret | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Sprint formats using the default formats for its operands and returns the resulting string.
 | ||||||
|  | // Spaces are added between operands when neither is a string.
 | ||||||
|  | // Input will be colored with the parent Style.
 | ||||||
|  | func (s Style) Sprint(a ...interface{}) string { | ||||||
|  | 	message := Sprint(a...) | ||||||
|  | 	messageLines := strings.Split(message, "\n") | ||||||
|  | 	for i, line := range messageLines { | ||||||
|  | 		messageLines[i] = color.RenderCode(s.String(), strings.ReplaceAll(line, color.ResetSet, Sprintf("\x1b[0m\u001B[%sm", s.String()))) | ||||||
|  | 	} | ||||||
|  | 	message = strings.Join(messageLines, "\n") | ||||||
|  | 	return color.RenderCode(s.String(), message) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Sprintln formats using the default formats for its operands and returns the resulting string.
 | ||||||
|  | // Spaces are always added between operands and a newline is appended.
 | ||||||
|  | // Input will be colored with the parent Style.
 | ||||||
|  | func (s Style) Sprintln(a ...interface{}) string { | ||||||
|  | 	return s.Sprint(a...) + "\n" | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Sprintf formats according to a format specifier and returns the resulting string.
 | ||||||
|  | // Input will be colored with the parent Style.
 | ||||||
|  | func (s Style) Sprintf(format string, a ...interface{}) string { | ||||||
|  | 	return s.Sprint(Sprintf(format, a...)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Sprintfln formats according to a format specifier and returns the resulting string.
 | ||||||
|  | // Spaces are always added between operands and a newline is appended.
 | ||||||
|  | // Input will be colored with the parent Style.
 | ||||||
|  | func (s Style) Sprintfln(format string, a ...interface{}) string { | ||||||
|  | 	return s.Sprint(Sprintf(format, a...) + "\n") | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Print formats using the default formats for its operands and writes to standard output.
 | ||||||
|  | // Spaces are added between operands when neither is a string.
 | ||||||
|  | // It returns the number of bytes written and any write error encountered.
 | ||||||
|  | // Input will be colored with the parent Style.
 | ||||||
|  | func (s Style) Print(a ...interface{}) { | ||||||
|  | 	Print(s.Sprint(a...)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Println formats using the default formats for its operands and writes to standard output.
 | ||||||
|  | // Spaces are always added between operands and a newline is appended.
 | ||||||
|  | // It returns the number of bytes written and any write error encountered.
 | ||||||
|  | // Input will be colored with the parent Style.
 | ||||||
|  | func (s Style) Println(a ...interface{}) { | ||||||
|  | 	Println(s.Sprint(a...)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Printf formats according to a format specifier and writes to standard output.
 | ||||||
|  | // It returns the number of bytes written and any write error encountered.
 | ||||||
|  | // Input will be colored with the parent Style.
 | ||||||
|  | func (s Style) Printf(format string, a ...interface{}) { | ||||||
|  | 	Print(s.Sprintf(format, a...)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Printfln formats according to a format specifier and writes to standard output.
 | ||||||
|  | // Spaces are always added between operands and a newline is appended.
 | ||||||
|  | // It returns the number of bytes written and any write error encountered.
 | ||||||
|  | // Input will be colored with the parent Style.
 | ||||||
|  | func (s Style) Printfln(format string, a ...interface{}) { | ||||||
|  | 	Print(s.Sprintfln(format, a...)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Code convert to code string. returns like "32;45;3".
 | ||||||
|  | func (s Style) Code() string { | ||||||
|  | 	return s.String() | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // String convert to code string. returns like "32;45;3".
 | ||||||
|  | func (s Style) String() string { | ||||||
|  | 	return colors2code(s...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Converts colors to code.
 | ||||||
|  | // Return format: "32;45;3".
 | ||||||
|  | func colors2code(colors ...Color) string { | ||||||
|  | 	if len(colors) == 0 { | ||||||
|  | 		return "" | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	var codes []string | ||||||
|  | 	for _, c := range colors { | ||||||
|  | 		codes = append(codes, c.String()) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return strings.Join(codes, ";") | ||||||
|  | } | ||||||
							
								
								
									
										61
									
								
								vendor/github.com/pterm/pterm/conventionalcommit.json
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								vendor/github.com/pterm/pterm/conventionalcommit.json
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,61 @@ | |||||||
|  | { | ||||||
|  |   "types": { | ||||||
|  |     "refactor": { | ||||||
|  |       "description": "Changes which neither fix a bug nor add a feature", | ||||||
|  |     }, | ||||||
|  |     "fix": { | ||||||
|  |       "description": "Changes which patch a bug" | ||||||
|  |     }, | ||||||
|  |     "feat": { | ||||||
|  |       "description": "Changes which introduce a new feature" | ||||||
|  |     }, | ||||||
|  |     "build": { | ||||||
|  |       "description": "Changes which affect the build system or external dependencies (example scopes: gulp, broccoli, npm)" | ||||||
|  |     }, | ||||||
|  |     "chore": { | ||||||
|  |       "description": "Changes which aren’t user-facing" | ||||||
|  |     }, | ||||||
|  |     "style": { | ||||||
|  |       "description": "Changes which don't affect code logic.\nWhite-spaces, formatting, missing semi-colons, etc" | ||||||
|  |     }, | ||||||
|  |     "test": { | ||||||
|  |       "description": "Changes which add missing tests or correct existing tests" | ||||||
|  |     }, | ||||||
|  |     "docs": { | ||||||
|  |       "description": "Changes which affect documentation", | ||||||
|  |       "scopes": { | ||||||
|  |         "pterm-sh": {}, | ||||||
|  |         "examples": {}, | ||||||
|  |         "readme": {}, | ||||||
|  |         "contributing": {} | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "perf": { | ||||||
|  |       "description": "Changes which improve performance" | ||||||
|  |     }, | ||||||
|  |     "ci": { | ||||||
|  |       "description": "Changes which affect CI configuration files and scripts (example scopes: travis, circle, browser-stack, sauce-labs)" | ||||||
|  |     }, | ||||||
|  |     "revert": { | ||||||
|  |       "description": "Changes which revert a previous commit" | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   "footerTypes": [ | ||||||
|  |     { | ||||||
|  |       "name": "BREAKING CHANGE", | ||||||
|  |       "description": "The commit introduces breaking API changes" | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "name": "Closes", | ||||||
|  |       "description": "The commit closes issues or pull requests" | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "name": "Implements", | ||||||
|  |       "description": "The commit implements features" | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "name": "Co-authored-by", | ||||||
|  |       "description": "The commit is co-authored by another person (for multiple people use one line each)" | ||||||
|  |     } | ||||||
|  |   ] | ||||||
|  | } | ||||||
							
								
								
									
										11
									
								
								vendor/github.com/pterm/pterm/errors.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								vendor/github.com/pterm/pterm/errors.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,11 @@ | |||||||
|  | package pterm | ||||||
|  | 
 | ||||||
|  | import "errors" | ||||||
|  | 
 | ||||||
|  | var ( | ||||||
|  | 	// ErrTerminalSizeNotDetectable - the terminal size can not be detected and the fallback values are used.
 | ||||||
|  | 	ErrTerminalSizeNotDetectable = errors.New("terminal size could not be detected - using fallback value") | ||||||
|  | 
 | ||||||
|  | 	// ErrHexCodeIsInvalid - the given HEX code is invalid.
 | ||||||
|  | 	ErrHexCodeIsInvalid = errors.New("hex code is not valid") | ||||||
|  | ) | ||||||
							
								
								
									
										11
									
								
								vendor/github.com/pterm/pterm/go.mod
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								vendor/github.com/pterm/pterm/go.mod
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,11 @@ | |||||||
|  | module github.com/pterm/pterm | ||||||
|  | 
 | ||||||
|  | go 1.15 | ||||||
|  | 
 | ||||||
|  | require ( | ||||||
|  | 	github.com/MarvinJWendt/testza v0.2.12 | ||||||
|  | 	github.com/atomicgo/cursor v0.0.1 | ||||||
|  | 	github.com/gookit/color v1.4.2 | ||||||
|  | 	github.com/mattn/go-runewidth v0.0.13 | ||||||
|  | 	golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 | ||||||
|  | ) | ||||||
							
								
								
									
										46
									
								
								vendor/github.com/pterm/pterm/go.sum
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								vendor/github.com/pterm/pterm/go.sum
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,46 @@ | |||||||
|  | github.com/MarvinJWendt/testza v0.1.0/go.mod h1:7AxNvlfeHP7Z/hDQ5JtE3OKYT3XFUeLCDE2DQninSqs= | ||||||
|  | github.com/MarvinJWendt/testza v0.2.1/go.mod h1:God7bhG8n6uQxwdScay+gjm9/LnO4D3kkcZX4hv9Rp8= | ||||||
|  | github.com/MarvinJWendt/testza v0.2.8/go.mod h1:nwIcjmr0Zz+Rcwfh3/4UhBp7ePKVhuBExvZqnKYWlII= | ||||||
|  | github.com/MarvinJWendt/testza v0.2.10/go.mod h1:pd+VWsoGUiFtq+hRKSU1Bktnn+DMCSrDrXDpX2bG66k= | ||||||
|  | github.com/MarvinJWendt/testza v0.2.12 h1:/PRp/BF+27t2ZxynTiqj0nyND5PbOtfJS0SuTuxmgeg= | ||||||
|  | github.com/MarvinJWendt/testza v0.2.12/go.mod h1:JOIegYyV7rX+7VZ9r77L/eH6CfJHHzXjB69adAhzZkI= | ||||||
|  | github.com/atomicgo/cursor v0.0.1 h1:xdogsqa6YYlLfM+GyClC/Lchf7aiMerFiZQn7soTOoU= | ||||||
|  | github.com/atomicgo/cursor v0.0.1/go.mod h1:cBON2QmmrysudxNBFthvMtN32r3jxVRIvzkUiF/RuIk= | ||||||
|  | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||||||
|  | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= | ||||||
|  | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||||||
|  | github.com/gookit/color v1.4.2 h1:tXy44JFSFkKnELV6WaMo/lLfu/meqITX3iAV52do7lk= | ||||||
|  | github.com/gookit/color v1.4.2/go.mod h1:fqRyamkC1W8uxl+lxCQxOT09l/vYfZ+QeiX3rKQHCoQ= | ||||||
|  | github.com/klauspost/cpuid/v2 v2.0.9 h1:lgaqFMSdTdQYdZ04uHyN2d/eKdOMyi2YLSvlQIBFYa4= | ||||||
|  | github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= | ||||||
|  | github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= | ||||||
|  | github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= | ||||||
|  | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= | ||||||
|  | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= | ||||||
|  | github.com/pterm/pterm v0.12.27/go.mod h1:PhQ89w4i95rhgE+xedAoqous6K9X+r6aSOI2eFF7DZI= | ||||||
|  | github.com/pterm/pterm v0.12.29/go.mod h1:WI3qxgvoQFFGKGjGnJR849gU0TsEOvKn5Q8LlY1U7lg= | ||||||
|  | github.com/pterm/pterm v0.12.30/go.mod h1:MOqLIyMOgmTDz9yorcYbcw+HsgoZo3BQfg2wtl3HEFE= | ||||||
|  | github.com/pterm/pterm v0.12.31/go.mod h1:32ZAWZVXD7ZfG0s8qqHXePte42kdz8ECtRyEejaWgXU= | ||||||
|  | github.com/pterm/pterm v0.12.33/go.mod h1:x+h2uL+n7CP/rel9+bImHD5lF3nM9vJj80k9ybiiTTE= | ||||||
|  | github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= | ||||||
|  | github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= | ||||||
|  | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= | ||||||
|  | github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= | ||||||
|  | github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= | ||||||
|  | github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= | ||||||
|  | github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 h1:QldyIu/L63oPpyvQmHgvgickp1Yw510KJOqX7H24mg8= | ||||||
|  | github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778/go.mod h1:2MuV+tbUrU1zIOPMxZ5EncGwgmMJsa+9ucAQZXxsObs= | ||||||
|  | golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||||
|  | golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||||
|  | golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||||||
|  | golang.org/x/sys v0.0.0-20211013075003-97ac67df715c h1:taxlMj0D/1sOAuv/CbSD+MMDof2vbyPTqz5FNYKpXt8= | ||||||
|  | golang.org/x/sys v0.0.0-20211013075003-97ac67df715c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||||||
|  | golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= | ||||||
|  | golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= | ||||||
|  | golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY= | ||||||
|  | golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= | ||||||
|  | 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/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= | ||||||
|  | gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= | ||||||
|  | gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= | ||||||
							
								
								
									
										228
									
								
								vendor/github.com/pterm/pterm/header_printer.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										228
									
								
								vendor/github.com/pterm/pterm/header_printer.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,228 @@ | |||||||
|  | package pterm | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  | 	"strings" | ||||||
|  | 
 | ||||||
|  | 	"github.com/mattn/go-runewidth" | ||||||
|  | 
 | ||||||
|  | 	"github.com/pterm/pterm/internal" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | var ( | ||||||
|  | 	// DefaultHeader returns the printer for a default header text.
 | ||||||
|  | 	// Defaults to LightWhite, Bold Text and a Gray DefaultHeader background.
 | ||||||
|  | 	DefaultHeader = HeaderPrinter{ | ||||||
|  | 		TextStyle:       &ThemeDefault.HeaderTextStyle, | ||||||
|  | 		BackgroundStyle: &ThemeDefault.HeaderBackgroundStyle, | ||||||
|  | 		Margin:          5, | ||||||
|  | 	} | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // HeaderPrinter contains the data used to craft a header.
 | ||||||
|  | // A header is printed as a big box with text in it.
 | ||||||
|  | // Can be used as title screens or section separator.
 | ||||||
|  | type HeaderPrinter struct { | ||||||
|  | 	TextStyle       *Style | ||||||
|  | 	BackgroundStyle *Style | ||||||
|  | 	Margin          int | ||||||
|  | 	FullWidth       bool | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithTextStyle returns a new HeaderPrinter with changed
 | ||||||
|  | func (p HeaderPrinter) WithTextStyle(style *Style) *HeaderPrinter { | ||||||
|  | 	p.TextStyle = style | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithBackgroundStyle changes the background styling of the header.
 | ||||||
|  | func (p HeaderPrinter) WithBackgroundStyle(style *Style) *HeaderPrinter { | ||||||
|  | 	p.BackgroundStyle = style | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithMargin changes the background styling of the header.
 | ||||||
|  | func (p HeaderPrinter) WithMargin(margin int) *HeaderPrinter { | ||||||
|  | 	p.Margin = margin | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithFullWidth enables full width on a HeaderPrinter.
 | ||||||
|  | func (p HeaderPrinter) WithFullWidth(b ...bool) *HeaderPrinter { | ||||||
|  | 	p.FullWidth = internal.WithBoolean(b) | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Sprint formats using the default formats for its operands and returns the resulting string.
 | ||||||
|  | // Spaces are added between operands when neither is a string.
 | ||||||
|  | func (p HeaderPrinter) Sprint(a ...interface{}) string { | ||||||
|  | 	if RawOutput { | ||||||
|  | 		return Sprint(a...) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if p.TextStyle == nil { | ||||||
|  | 		p.TextStyle = NewStyle() | ||||||
|  | 	} | ||||||
|  | 	if p.BackgroundStyle == nil { | ||||||
|  | 		p.BackgroundStyle = NewStyle() | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	text := Sprint(a...) | ||||||
|  | 
 | ||||||
|  | 	var blankLine string | ||||||
|  | 
 | ||||||
|  | 	longestLine := internal.ReturnLongestLine(text, "\n") | ||||||
|  | 	longestLineLen := runewidth.StringWidth(RemoveColorFromString(longestLine)) + p.Margin*2 | ||||||
|  | 
 | ||||||
|  | 	if p.FullWidth { | ||||||
|  | 		text = splitText(text, GetTerminalWidth()-p.Margin*2) | ||||||
|  | 		blankLine = strings.Repeat(" ", GetTerminalWidth()) | ||||||
|  | 	} else { | ||||||
|  | 		if longestLineLen > GetTerminalWidth() { | ||||||
|  | 			text = splitText(text, GetTerminalWidth()-p.Margin*2) | ||||||
|  | 			blankLine = strings.Repeat(" ", GetTerminalWidth()) | ||||||
|  | 		} else { | ||||||
|  | 			text = splitText(text, longestLineLen-p.Margin*2) | ||||||
|  | 			blankLine = strings.Repeat(" ", longestLineLen) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	var marginString string | ||||||
|  | 	var ret string | ||||||
|  | 
 | ||||||
|  | 	if p.FullWidth { | ||||||
|  | 		longestLineLen = runewidth.StringWidth(RemoveColorFromString(internal.ReturnLongestLine(text, "\n"))) | ||||||
|  | 		marginString = strings.Repeat(" ", (GetTerminalWidth()-longestLineLen)/2) | ||||||
|  | 	} else { | ||||||
|  | 		marginString = strings.Repeat(" ", p.Margin) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	ret += p.BackgroundStyle.Sprint(blankLine) + "\n" | ||||||
|  | 	for _, line := range strings.Split(text, "\n") { | ||||||
|  | 		line = strings.ReplaceAll(line, "\n", "") | ||||||
|  | 		line = marginString + line + marginString | ||||||
|  | 		if runewidth.StringWidth(line) < runewidth.StringWidth(blankLine) { | ||||||
|  | 			line += strings.Repeat(" ", runewidth.StringWidth(blankLine)-runewidth.StringWidth(line)) | ||||||
|  | 		} | ||||||
|  | 		ret += p.BackgroundStyle.Sprint(p.TextStyle.Sprint(line)) + "\n" | ||||||
|  | 	} | ||||||
|  | 	ret += p.BackgroundStyle.Sprint(blankLine) + "\n" | ||||||
|  | 
 | ||||||
|  | 	return ret | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func splitText(text string, width int) string { | ||||||
|  | 	var lines []string | ||||||
|  | 	linesTmp := strings.Split(text, "\n") | ||||||
|  | 	for _, line := range linesTmp { | ||||||
|  | 		if runewidth.StringWidth(RemoveColorFromString(line)) > width { | ||||||
|  | 			extraLines := []string{""} | ||||||
|  | 			extraLinesCounter := 0 | ||||||
|  | 			for i, letter := range line { | ||||||
|  | 				if i%width == 0 && i != 0 { | ||||||
|  | 					extraLinesCounter++ | ||||||
|  | 					extraLines = append(extraLines, "") | ||||||
|  | 				} | ||||||
|  | 				extraLines[extraLinesCounter] += string(letter) | ||||||
|  | 			} | ||||||
|  | 			for _, extraLine := range extraLines { | ||||||
|  | 				extraLine += "\n" | ||||||
|  | 				lines = append(lines, extraLine) | ||||||
|  | 			} | ||||||
|  | 		} else { | ||||||
|  | 			line += "\n" | ||||||
|  | 			lines = append(lines, line) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	var line string | ||||||
|  | 	for _, s := range lines { | ||||||
|  | 		line += s | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return strings.TrimSuffix(line, "\n") | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Sprintln formats using the default formats for its operands and returns the resulting string.
 | ||||||
|  | // Spaces are always added between operands and a newline is appended.
 | ||||||
|  | func (p HeaderPrinter) Sprintln(a ...interface{}) string { | ||||||
|  | 	return p.Sprint(strings.TrimSuffix(Sprintln(a...), "\n")) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Sprintf formats according to a format specifier and returns the resulting string.
 | ||||||
|  | func (p HeaderPrinter) Sprintf(format string, a ...interface{}) string { | ||||||
|  | 	return p.Sprint(Sprintf(format, a...)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Sprintfln formats according to a format specifier and returns the resulting string.
 | ||||||
|  | // Spaces are always added between operands and a newline is appended.
 | ||||||
|  | func (p HeaderPrinter) Sprintfln(format string, a ...interface{}) string { | ||||||
|  | 	return p.Sprintf(format, a...) + "\n" | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Print formats using the default formats for its operands and writes to standard output.
 | ||||||
|  | // Spaces are added between operands when neither is a string.
 | ||||||
|  | // It returns the number of bytes written and any write error encountered.
 | ||||||
|  | func (p *HeaderPrinter) Print(a ...interface{}) *TextPrinter { | ||||||
|  | 	Print(p.Sprint(a...)) | ||||||
|  | 	tp := TextPrinter(p) | ||||||
|  | 	return &tp | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Println formats using the default formats for its operands and writes to standard output.
 | ||||||
|  | // Spaces are always added between operands and a newline is appended.
 | ||||||
|  | // It returns the number of bytes written and any write error encountered.
 | ||||||
|  | func (p *HeaderPrinter) Println(a ...interface{}) *TextPrinter { | ||||||
|  | 	Print(p.Sprintln(a...)) | ||||||
|  | 	tp := TextPrinter(p) | ||||||
|  | 	return &tp | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Printf formats according to a format specifier and writes to standard output.
 | ||||||
|  | // It returns the number of bytes written and any write error encountered.
 | ||||||
|  | func (p *HeaderPrinter) Printf(format string, a ...interface{}) *TextPrinter { | ||||||
|  | 	Print(p.Sprintf(format, a...)) | ||||||
|  | 	tp := TextPrinter(p) | ||||||
|  | 	return &tp | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Printfln formats according to a format specifier and writes to standard output.
 | ||||||
|  | // Spaces are always added between operands and a newline is appended.
 | ||||||
|  | // It returns the number of bytes written and any write error encountered.
 | ||||||
|  | func (p *HeaderPrinter) Printfln(format string, a ...interface{}) *TextPrinter { | ||||||
|  | 	Print(p.Sprintfln(format, a...)) | ||||||
|  | 	tp := TextPrinter(p) | ||||||
|  | 	return &tp | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // PrintOnError prints every error which is not nil.
 | ||||||
|  | // If every error is nil, nothing will be printed.
 | ||||||
|  | // This can be used for simple error checking.
 | ||||||
|  | func (p *HeaderPrinter) PrintOnError(a ...interface{}) *TextPrinter { | ||||||
|  | 	for _, arg := range a { | ||||||
|  | 		if err, ok := arg.(error); ok { | ||||||
|  | 			if err != nil { | ||||||
|  | 				p.Println(err) | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	tp := TextPrinter(p) | ||||||
|  | 	return &tp | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // PrintOnErrorf wraps every error which is not nil and prints it.
 | ||||||
|  | // If every error is nil, nothing will be printed.
 | ||||||
|  | // This can be used for simple error checking.
 | ||||||
|  | func (p *HeaderPrinter) PrintOnErrorf(format string, a ...interface{}) *TextPrinter { | ||||||
|  | 	for _, arg := range a { | ||||||
|  | 		if err, ok := arg.(error); ok { | ||||||
|  | 			if err != nil { | ||||||
|  | 				p.Println(fmt.Errorf(format, err)) | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	tp := TextPrinter(p) | ||||||
|  | 	return &tp | ||||||
|  | } | ||||||
							
								
								
									
										14
									
								
								vendor/github.com/pterm/pterm/interface_live_printer.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								vendor/github.com/pterm/pterm/interface_live_printer.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,14 @@ | |||||||
|  | package pterm | ||||||
|  | 
 | ||||||
|  | // LivePrinter is a printer which can update it's output live.
 | ||||||
|  | type LivePrinter interface { | ||||||
|  | 	// GenericStart runs Start, but returns a LivePrinter.
 | ||||||
|  | 	// This is used for the interface LivePrinter.
 | ||||||
|  | 	// You most likely want to use Start instead of this in your program.
 | ||||||
|  | 	GenericStart() (*LivePrinter, error) | ||||||
|  | 
 | ||||||
|  | 	// GenericStop runs Stop, but returns a LivePrinter.
 | ||||||
|  | 	// This is used for the interface LivePrinter.
 | ||||||
|  | 	// You most likely want to use Stop instead of this in your program.
 | ||||||
|  | 	GenericStop() (*LivePrinter, error) | ||||||
|  | } | ||||||
							
								
								
									
										11
									
								
								vendor/github.com/pterm/pterm/interface_renderable_printer.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								vendor/github.com/pterm/pterm/interface_renderable_printer.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,11 @@ | |||||||
|  | package pterm | ||||||
|  | 
 | ||||||
|  | // RenderPrinter is used to display renderable content.
 | ||||||
|  | // Example for renderable content is a Table.
 | ||||||
|  | type RenderPrinter interface { | ||||||
|  | 	// Render the XXX to the terminal.
 | ||||||
|  | 	Render() error | ||||||
|  | 
 | ||||||
|  | 	// Srender returns the rendered string of XXX.
 | ||||||
|  | 	Srender() (string, error) | ||||||
|  | } | ||||||
							
								
								
									
										48
									
								
								vendor/github.com/pterm/pterm/interface_text_printer.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								vendor/github.com/pterm/pterm/interface_text_printer.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,48 @@ | |||||||
|  | package pterm | ||||||
|  | 
 | ||||||
|  | // TextPrinter contains methods to print formatted text to the console or return it as a string.
 | ||||||
|  | type TextPrinter interface { | ||||||
|  | 	// Sprint formats using the default formats for its operands and returns the resulting string.
 | ||||||
|  | 	// Spaces are added between operands when neither is a string.
 | ||||||
|  | 	Sprint(a ...interface{}) string | ||||||
|  | 
 | ||||||
|  | 	// Sprintln formats using the default formats for its operands and returns the resulting string.
 | ||||||
|  | 	// Spaces are always added between operands and a newline is appended.
 | ||||||
|  | 	Sprintln(a ...interface{}) string | ||||||
|  | 
 | ||||||
|  | 	// Sprintf formats according to a format specifier and returns the resulting string.
 | ||||||
|  | 	Sprintf(format string, a ...interface{}) string | ||||||
|  | 
 | ||||||
|  | 	// Sprintfln formats according to a format specifier and returns the resulting string.
 | ||||||
|  | 	// Spaces are always added between operands and a newline is appended.
 | ||||||
|  | 	Sprintfln(format string, a ...interface{}) string | ||||||
|  | 
 | ||||||
|  | 	// Print formats using the default formats for its operands and writes to standard output.
 | ||||||
|  | 	// Spaces are added between operands when neither is a string.
 | ||||||
|  | 	// It returns the number of bytes written and any write error encountered.
 | ||||||
|  | 	Print(a ...interface{}) *TextPrinter | ||||||
|  | 
 | ||||||
|  | 	// Println formats using the default formats for its operands and writes to standard output.
 | ||||||
|  | 	// Spaces are always added between operands and a newline is appended.
 | ||||||
|  | 	// It returns the number of bytes written and any write error encountered.
 | ||||||
|  | 	Println(a ...interface{}) *TextPrinter | ||||||
|  | 
 | ||||||
|  | 	// Printf formats according to a format specifier and writes to standard output.
 | ||||||
|  | 	// It returns the number of bytes written and any write error encountered.
 | ||||||
|  | 	Printf(format string, a ...interface{}) *TextPrinter | ||||||
|  | 
 | ||||||
|  | 	// Printfln formats according to a format specifier and writes to standard output.
 | ||||||
|  | 	// Spaces are always added between operands and a newline is appended.
 | ||||||
|  | 	// It returns the number of bytes written and any write error encountered.
 | ||||||
|  | 	Printfln(format string, a ...interface{}) *TextPrinter | ||||||
|  | 
 | ||||||
|  | 	// PrintOnError prints every error which is not nil.
 | ||||||
|  | 	// If every error is nil, nothing will be printed.
 | ||||||
|  | 	// This can be used for simple error checking.
 | ||||||
|  | 	PrintOnError(a ...interface{}) *TextPrinter | ||||||
|  | 
 | ||||||
|  | 	// PrintOnErrorf wraps every error which is not nil and prints it.
 | ||||||
|  | 	// If every error is nil, nothing will be printed.
 | ||||||
|  | 	// This can be used for simple error checking.
 | ||||||
|  | 	PrintOnErrorf(format string, a ...interface{}) *TextPrinter | ||||||
|  | } | ||||||
							
								
								
									
										42
									
								
								vendor/github.com/pterm/pterm/internal/center_text.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								vendor/github.com/pterm/pterm/internal/center_text.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,42 @@ | |||||||
|  | package internal | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"strings" | ||||||
|  | 
 | ||||||
|  | 	"github.com/gookit/color" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // CenterText returns a centered string with a padding left and right
 | ||||||
|  | func CenterText(text string, width int) string { | ||||||
|  | 	var lines []string | ||||||
|  | 	linesTmp := strings.Split(text, "\n") | ||||||
|  | 	for _, line := range linesTmp { | ||||||
|  | 		if len(color.ClearCode(line)) > width { | ||||||
|  | 			extraLines := []string{""} | ||||||
|  | 			extraLinesCounter := 0 | ||||||
|  | 			for i, letter := range line { | ||||||
|  | 				if i%width == 0 && i != 0 { | ||||||
|  | 					extraLinesCounter++ | ||||||
|  | 					extraLines = append(extraLines, "") | ||||||
|  | 				} | ||||||
|  | 				extraLines[extraLinesCounter] += string(letter) | ||||||
|  | 			} | ||||||
|  | 			for _, extraLine := range extraLines { | ||||||
|  | 				padding := width - len(color.ClearCode(extraLine)) | ||||||
|  | 				extraLine = strings.Repeat(" ", padding/2) + extraLine + strings.Repeat(" ", padding/2) + "\n" | ||||||
|  | 				lines = append(lines, extraLine) | ||||||
|  | 			} | ||||||
|  | 		} else { | ||||||
|  | 			padding := width - len(color.ClearCode(line)) | ||||||
|  | 			line = strings.Repeat(" ", padding/2) + line + strings.Repeat(" ", padding/2) + "\n" | ||||||
|  | 			lines = append(lines, line) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	var line string | ||||||
|  | 	for _, s := range lines { | ||||||
|  | 		line += s | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return strings.TrimSuffix(line, "\n") | ||||||
|  | } | ||||||
							
								
								
									
										7
									
								
								vendor/github.com/pterm/pterm/internal/collection.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								vendor/github.com/pterm/pterm/internal/collection.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,7 @@ | |||||||
|  | package internal | ||||||
|  | 
 | ||||||
|  | // RandomStrings contains a list of random strings to use while testing.
 | ||||||
|  | var RandomStrings = []string{ | ||||||
|  | 	"hello world", "²³14234!`§=)$-.€@_&", "This is a sentence.", "This\nstring\nhas\nmultiple\nlines", | ||||||
|  | 	"windows\r\nline\r\nendings", "\rtext", | ||||||
|  | } | ||||||
							
								
								
									
										21
									
								
								vendor/github.com/pterm/pterm/internal/longest_line.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								vendor/github.com/pterm/pterm/internal/longest_line.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,21 @@ | |||||||
|  | package internal | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"strings" | ||||||
|  | 
 | ||||||
|  | 	"github.com/gookit/color" | ||||||
|  | 	"github.com/mattn/go-runewidth" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // ReturnLongestLine returns the longest line with a given separator
 | ||||||
|  | func ReturnLongestLine(text, sep string) string { | ||||||
|  | 	lines := strings.Split(text, sep) | ||||||
|  | 	var longest string | ||||||
|  | 	for _, line := range lines { | ||||||
|  | 		if runewidth.StringWidth(color.ClearCode(line)) > runewidth.StringWidth(color.ClearCode(longest)) { | ||||||
|  | 			longest = line | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return longest | ||||||
|  | } | ||||||
							
								
								
									
										8
									
								
								vendor/github.com/pterm/pterm/internal/map_range_to_range.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								vendor/github.com/pterm/pterm/internal/map_range_to_range.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,8 @@ | |||||||
|  | package internal | ||||||
|  | 
 | ||||||
|  | func MapRangeToRange(fromMin, fromMax, toMin, toMax, current float32) int { | ||||||
|  | 	if fromMax-fromMin == 0 { | ||||||
|  | 		return 0 | ||||||
|  | 	} | ||||||
|  | 	return int(toMin + ((toMax-toMin)/(fromMax-fromMin))*(current-fromMin)) | ||||||
|  | } | ||||||
							
								
								
									
										20
									
								
								vendor/github.com/pterm/pterm/internal/max_text_width.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								vendor/github.com/pterm/pterm/internal/max_text_width.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,20 @@ | |||||||
|  | package internal | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"strings" | ||||||
|  | 
 | ||||||
|  | 	"github.com/gookit/color" | ||||||
|  | 	"github.com/mattn/go-runewidth" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // GetStringMaxWidth returns the maximum width of a string with multiple lines.
 | ||||||
|  | func GetStringMaxWidth(s string) int { | ||||||
|  | 	var max int | ||||||
|  | 	ss := strings.Split(s, "\n") | ||||||
|  | 	for _, s2 := range ss { | ||||||
|  | 		if runewidth.StringWidth(color.ClearCode(s2)) > max { | ||||||
|  | 			max = runewidth.StringWidth(color.ClearCode(s2)) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return max | ||||||
|  | } | ||||||
							
								
								
									
										13
									
								
								vendor/github.com/pterm/pterm/internal/percentage.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								vendor/github.com/pterm/pterm/internal/percentage.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,13 @@ | |||||||
|  | package internal | ||||||
|  | 
 | ||||||
|  | import "math" | ||||||
|  | 
 | ||||||
|  | // Percentage calculates percentage.
 | ||||||
|  | func Percentage(total, current float64) float64 { | ||||||
|  | 	return (current / total) * 100 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // PercentageRound returns a rounded Percentage.
 | ||||||
|  | func PercentageRound(total, current float64) float64 { | ||||||
|  | 	return math.Round(Percentage(total, current)) | ||||||
|  | } | ||||||
							
								
								
									
										11
									
								
								vendor/github.com/pterm/pterm/internal/remove_and_count_prefix.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								vendor/github.com/pterm/pterm/internal/remove_and_count_prefix.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,11 @@ | |||||||
|  | package internal | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"strings" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | func RemoveAndCountPrefix(input, subString string) (string, int) { | ||||||
|  | 	inputLength := len(input) | ||||||
|  | 	input = strings.TrimLeft(input, subString) | ||||||
|  | 	return input, inputLength - len(input) | ||||||
|  | } | ||||||
							
								
								
									
										30
									
								
								vendor/github.com/pterm/pterm/internal/title_in_line.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								vendor/github.com/pterm/pterm/internal/title_in_line.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,30 @@ | |||||||
|  | package internal | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"strings" | ||||||
|  | 
 | ||||||
|  | 	"github.com/gookit/color" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // AddTitleToLine adds a title to a site of a line ex: "─ This is the title ──────"
 | ||||||
|  | func AddTitleToLine(title, line string, length int, left bool) string { | ||||||
|  | 	var ret string | ||||||
|  | 	if left { | ||||||
|  | 		ret += line + " " + title + " " + line + strings.Repeat(line, length-(4+len(color.ClearCode(title)))) | ||||||
|  | 	} else { | ||||||
|  | 		ret += strings.Repeat(line, length-(4+len(color.ClearCode(title)))) + line + " " + title + " " + line | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return ret | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // AddTitleToLineCenter adds a title to the center of a line ex: "─ This is the title ──────"
 | ||||||
|  | func AddTitleToLineCenter(title, line string, length int) string { | ||||||
|  | 	var ret string | ||||||
|  | 	repeatString := length - (4 + len(color.ClearCode(title))) | ||||||
|  | 	unevenRepeatString := repeatString % 2 | ||||||
|  | 
 | ||||||
|  | 	ret += strings.Repeat(line, repeatString/2) + line + " " + title + " " + line + strings.Repeat(line, repeatString/2+unevenRepeatString) | ||||||
|  | 
 | ||||||
|  | 	return ret | ||||||
|  | } | ||||||
							
								
								
									
										9
									
								
								vendor/github.com/pterm/pterm/internal/with_boolean.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								vendor/github.com/pterm/pterm/internal/with_boolean.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,9 @@ | |||||||
|  | package internal | ||||||
|  | 
 | ||||||
|  | // WithBoolean helps an option setter (WithXXX(b ...bool) to return true, if no boolean is set, but false if it's explicitly set to false.
 | ||||||
|  | func WithBoolean(b []bool) bool { | ||||||
|  | 	if len(b) == 0 { | ||||||
|  | 		b = append(b, true) | ||||||
|  | 	} | ||||||
|  | 	return b[0] | ||||||
|  | } | ||||||
							
								
								
									
										182
									
								
								vendor/github.com/pterm/pterm/panel_printer.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										182
									
								
								vendor/github.com/pterm/pterm/panel_printer.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,182 @@ | |||||||
|  | package pterm | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"strings" | ||||||
|  | 
 | ||||||
|  | 	"github.com/mattn/go-runewidth" | ||||||
|  | 
 | ||||||
|  | 	"github.com/pterm/pterm/internal" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // Panel contains the data, which should be printed inside a PanelPrinter.
 | ||||||
|  | type Panel struct { | ||||||
|  | 	Data string | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Panels is a two dimensional coordinate system for Panel.
 | ||||||
|  | type Panels [][]Panel | ||||||
|  | 
 | ||||||
|  | // DefaultPanel is the default PanelPrinter.
 | ||||||
|  | var DefaultPanel = PanelPrinter{ | ||||||
|  | 	Padding: 1, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // PanelPrinter prints content in boxes.
 | ||||||
|  | type PanelPrinter struct { | ||||||
|  | 	Panels          Panels | ||||||
|  | 	Padding         int | ||||||
|  | 	BottomPadding   int | ||||||
|  | 	SameColumnWidth bool | ||||||
|  | 	BoxPrinter      BoxPrinter | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithPanels returns a new PanelPrinter with specific options.
 | ||||||
|  | func (p PanelPrinter) WithPanels(panels Panels) *PanelPrinter { | ||||||
|  | 	p.Panels = panels | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithPadding returns a new PanelPrinter with specific options.
 | ||||||
|  | func (p PanelPrinter) WithPadding(padding int) *PanelPrinter { | ||||||
|  | 	if padding < 0 { | ||||||
|  | 		padding = 0 | ||||||
|  | 	} | ||||||
|  | 	p.Padding = padding | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithBottomPadding returns a new PanelPrinter with specific options.
 | ||||||
|  | func (p PanelPrinter) WithBottomPadding(bottomPadding int) *PanelPrinter { | ||||||
|  | 	if bottomPadding < 0 { | ||||||
|  | 		bottomPadding = 0 | ||||||
|  | 	} | ||||||
|  | 	p.BottomPadding = bottomPadding | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithSameColumnWidth returns a new PanelPrinter with specific options.
 | ||||||
|  | func (p PanelPrinter) WithSameColumnWidth(b ...bool) *PanelPrinter { | ||||||
|  | 	b2 := internal.WithBoolean(b) | ||||||
|  | 	p.SameColumnWidth = b2 | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithBoxPrinter returns a new PanelPrinter with specific options.
 | ||||||
|  | func (p PanelPrinter) WithBoxPrinter(boxPrinter BoxPrinter) *PanelPrinter { | ||||||
|  | 	p.BoxPrinter = boxPrinter | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (p PanelPrinter) getRawOutput() string { | ||||||
|  | 	var ret string | ||||||
|  | 	for _, panel := range p.Panels { | ||||||
|  | 		for _, panel2 := range panel { | ||||||
|  | 			ret += panel2.Data + "\n\n" | ||||||
|  | 		} | ||||||
|  | 		ret += "\n" | ||||||
|  | 	} | ||||||
|  | 	return ret | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Srender renders the Template as a string.
 | ||||||
|  | func (p PanelPrinter) Srender() (string, error) { | ||||||
|  | 	var ret string | ||||||
|  | 
 | ||||||
|  | 	if RawOutput { | ||||||
|  | 		return p.getRawOutput(), nil | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	for i := range p.Panels { | ||||||
|  | 		for i2 := range p.Panels[i] { | ||||||
|  | 			p.Panels[i][i2].Data = strings.TrimSuffix(p.Panels[i][i2].Data, "\n") | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if p.BoxPrinter != (BoxPrinter{}) { | ||||||
|  | 		for i := range p.Panels { | ||||||
|  | 			for i2 := range p.Panels[i] { | ||||||
|  | 				p.Panels[i][i2].Data = p.BoxPrinter.Sprint(p.Panels[i][i2].Data) | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	for i := range p.Panels { | ||||||
|  | 		if len(p.Panels)-1 != i { | ||||||
|  | 			for i2 := range p.Panels[i] { | ||||||
|  | 				p.Panels[i][i2].Data += strings.Repeat("\n", p.BottomPadding) | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	columnMaxHeightMap := make(map[int]int) | ||||||
|  | 
 | ||||||
|  | 	if p.SameColumnWidth { | ||||||
|  | 		for _, panel := range p.Panels { | ||||||
|  | 			for i, p2 := range panel { | ||||||
|  | 				if columnMaxHeightMap[i] < internal.GetStringMaxWidth(p2.Data) { | ||||||
|  | 					columnMaxHeightMap[i] = internal.GetStringMaxWidth(p2.Data) | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	for _, boxLine := range p.Panels { | ||||||
|  | 		var maxHeight int | ||||||
|  | 
 | ||||||
|  | 		var renderedPanels []string | ||||||
|  | 
 | ||||||
|  | 		for _, box := range boxLine { | ||||||
|  | 			renderedPanels = append(renderedPanels, box.Data) | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		for i, panel := range renderedPanels { | ||||||
|  | 			renderedPanels[i] = strings.ReplaceAll(panel, "\n", Reset.Sprint()+"\n") | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		for _, box := range renderedPanels { | ||||||
|  | 			height := len(strings.Split(box, "\n")) | ||||||
|  | 			if height > maxHeight { | ||||||
|  | 				maxHeight = height | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		for i := 0; i < maxHeight; i++ { | ||||||
|  | 			if maxHeight != i { | ||||||
|  | 				for j, letter := range renderedPanels { | ||||||
|  | 					var letterLine string | ||||||
|  | 					letterLines := strings.Split(letter, "\n") | ||||||
|  | 					var maxLetterWidth int | ||||||
|  | 					if !p.SameColumnWidth { | ||||||
|  | 						maxLetterWidth = internal.GetStringMaxWidth(letter) | ||||||
|  | 					} | ||||||
|  | 					if len(letterLines) > i { | ||||||
|  | 						letterLine = letterLines[i] | ||||||
|  | 					} | ||||||
|  | 					letterLineLength := runewidth.StringWidth(RemoveColorFromString(letterLine)) | ||||||
|  | 					if !p.SameColumnWidth { | ||||||
|  | 						if letterLineLength < maxLetterWidth { | ||||||
|  | 							letterLine += strings.Repeat(" ", maxLetterWidth-letterLineLength) | ||||||
|  | 						} | ||||||
|  | 					} else { | ||||||
|  | 						if letterLineLength < columnMaxHeightMap[j] { | ||||||
|  | 							letterLine += strings.Repeat(" ", columnMaxHeightMap[j]-letterLineLength) | ||||||
|  | 						} | ||||||
|  | 					} | ||||||
|  | 					letterLine += strings.Repeat(" ", p.Padding) | ||||||
|  | 					ret += letterLine | ||||||
|  | 				} | ||||||
|  | 				ret += "\n" | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return ret, nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Render prints the Template to the terminal.
 | ||||||
|  | func (p PanelPrinter) Render() error { | ||||||
|  | 	s, _ := p.Srender() | ||||||
|  | 	Println(s) | ||||||
|  | 
 | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
							
								
								
									
										134
									
								
								vendor/github.com/pterm/pterm/paragraph_printer.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										134
									
								
								vendor/github.com/pterm/pterm/paragraph_printer.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,134 @@ | |||||||
|  | package pterm | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  | 	"strings" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // DefaultParagraph contains the default values for a ParagraphPrinter.
 | ||||||
|  | var DefaultParagraph = ParagraphPrinter{ | ||||||
|  | 	MaxWidth: GetTerminalWidth(), | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ParagraphPrinter can print paragraphs to a fixed line width.
 | ||||||
|  | // The text will split between words, so that words will stick together.
 | ||||||
|  | // It's like in a book.
 | ||||||
|  | type ParagraphPrinter struct { | ||||||
|  | 	MaxWidth int | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithMaxWidth returns a new ParagraphPrinter with a specific MaxWidth
 | ||||||
|  | func (p ParagraphPrinter) WithMaxWidth(width int) *ParagraphPrinter { | ||||||
|  | 	p.MaxWidth = width | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Sprint formats using the default formats for its operands and returns the resulting string.
 | ||||||
|  | // Spaces are added between operands when neither is a string.
 | ||||||
|  | func (p ParagraphPrinter) Sprint(a ...interface{}) string { | ||||||
|  | 	if RawOutput { | ||||||
|  | 		return Sprint(a...) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	words := strings.Fields(strings.TrimSpace(Sprint(a...))) | ||||||
|  | 	if len(words) == 0 { | ||||||
|  | 		return "" | ||||||
|  | 	} | ||||||
|  | 	wrapped := words[0] | ||||||
|  | 	spaceLeft := p.MaxWidth - len(wrapped) | ||||||
|  | 	for _, word := range words[1:] { | ||||||
|  | 		if len(word)+1 > spaceLeft { | ||||||
|  | 			wrapped += "\n" + word | ||||||
|  | 			spaceLeft = p.MaxWidth - len(word) | ||||||
|  | 		} else { | ||||||
|  | 			wrapped += " " + word | ||||||
|  | 			spaceLeft -= 1 + len(word) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return wrapped | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Sprintln formats using the default formats for its operands and returns the resulting string.
 | ||||||
|  | // Spaces are always added between operands and a newline is appended.
 | ||||||
|  | func (p ParagraphPrinter) Sprintln(a ...interface{}) string { | ||||||
|  | 	return p.Sprint(Sprintln(a...)) + "\n" | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Sprintf formats according to a format specifier and returns the resulting string.
 | ||||||
|  | func (p ParagraphPrinter) Sprintf(format string, a ...interface{}) string { | ||||||
|  | 	return p.Sprint(Sprintf(format, a...)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Sprintfln formats according to a format specifier and returns the resulting string.
 | ||||||
|  | // Spaces are always added between operands and a newline is appended.
 | ||||||
|  | func (p ParagraphPrinter) Sprintfln(format string, a ...interface{}) string { | ||||||
|  | 	return p.Sprintf(format, a...) + "\n" | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Print formats using the default formats for its operands and writes to standard output.
 | ||||||
|  | // Spaces are added between operands when neither is a string.
 | ||||||
|  | // It returns the number of bytes written and any write error encountered.
 | ||||||
|  | func (p *ParagraphPrinter) Print(a ...interface{}) *TextPrinter { | ||||||
|  | 	Print(p.Sprint(a...)) | ||||||
|  | 	tp := TextPrinter(p) | ||||||
|  | 	return &tp | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Println formats using the default formats for its operands and writes to standard output.
 | ||||||
|  | // Spaces are always added between operands and a newline is appended.
 | ||||||
|  | // It returns the number of bytes written and any write error encountered.
 | ||||||
|  | func (p *ParagraphPrinter) Println(a ...interface{}) *TextPrinter { | ||||||
|  | 	Print(p.Sprintln(a...)) | ||||||
|  | 	tp := TextPrinter(p) | ||||||
|  | 	return &tp | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Printf formats according to a format specifier and writes to standard output.
 | ||||||
|  | // It returns the number of bytes written and any write error encountered.
 | ||||||
|  | func (p *ParagraphPrinter) Printf(format string, a ...interface{}) *TextPrinter { | ||||||
|  | 	Print(p.Sprintf(format, a...)) | ||||||
|  | 	tp := TextPrinter(p) | ||||||
|  | 	return &tp | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Printfln formats according to a format specifier and writes to standard output.
 | ||||||
|  | // Spaces are always added between operands and a newline is appended.
 | ||||||
|  | // It returns the number of bytes written and any write error encountered.
 | ||||||
|  | func (p *ParagraphPrinter) Printfln(format string, a ...interface{}) *TextPrinter { | ||||||
|  | 	Print(p.Sprintfln(format, a...)) | ||||||
|  | 	tp := TextPrinter(p) | ||||||
|  | 	return &tp | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // PrintOnError prints every error which is not nil.
 | ||||||
|  | // If every error is nil, nothing will be printed.
 | ||||||
|  | // This can be used for simple error checking.
 | ||||||
|  | func (p *ParagraphPrinter) PrintOnError(a ...interface{}) *TextPrinter { | ||||||
|  | 	for _, arg := range a { | ||||||
|  | 		if err, ok := arg.(error); ok { | ||||||
|  | 			if err != nil { | ||||||
|  | 				p.Println(err) | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	tp := TextPrinter(p) | ||||||
|  | 	return &tp | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // PrintOnErrorf wraps every error which is not nil and prints it.
 | ||||||
|  | // If every error is nil, nothing will be printed.
 | ||||||
|  | // This can be used for simple error checking.
 | ||||||
|  | func (p *ParagraphPrinter) PrintOnErrorf(format string, a ...interface{}) *TextPrinter { | ||||||
|  | 	for _, arg := range a { | ||||||
|  | 		if err, ok := arg.(error); ok { | ||||||
|  | 			if err != nil { | ||||||
|  | 				p.Println(fmt.Errorf(format, err)) | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	tp := TextPrinter(p) | ||||||
|  | 	return &tp | ||||||
|  | } | ||||||
							
								
								
									
										342
									
								
								vendor/github.com/pterm/pterm/prefix_printer.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										342
									
								
								vendor/github.com/pterm/pterm/prefix_printer.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,342 @@ | |||||||
|  | package pterm | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  | 	"runtime" | ||||||
|  | 	"strings" | ||||||
|  | 
 | ||||||
|  | 	"github.com/pterm/pterm/internal" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | var ( | ||||||
|  | 	// GrayBoxStyle wraps text in a gray box.
 | ||||||
|  | 	GrayBoxStyle = NewStyle(BgGray, FgLightWhite) | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | var ( | ||||||
|  | 	// Info returns a PrefixPrinter, which can be used to print text with an "info" Prefix.
 | ||||||
|  | 	Info = PrefixPrinter{ | ||||||
|  | 		MessageStyle: &ThemeDefault.InfoMessageStyle, | ||||||
|  | 		Prefix: Prefix{ | ||||||
|  | 			Style: &ThemeDefault.InfoPrefixStyle, | ||||||
|  | 			Text:  "INFO", | ||||||
|  | 		}, | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// Warning returns a PrefixPrinter, which can be used to print text with a "warning" Prefix.
 | ||||||
|  | 	Warning = PrefixPrinter{ | ||||||
|  | 		MessageStyle: &ThemeDefault.WarningMessageStyle, | ||||||
|  | 		Prefix: Prefix{ | ||||||
|  | 			Style: &ThemeDefault.WarningPrefixStyle, | ||||||
|  | 			Text:  "WARNING", | ||||||
|  | 		}, | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// Success returns a PrefixPrinter, which can be used to print text with a "success" Prefix.
 | ||||||
|  | 	Success = PrefixPrinter{ | ||||||
|  | 		MessageStyle: &ThemeDefault.SuccessMessageStyle, | ||||||
|  | 		Prefix: Prefix{ | ||||||
|  | 			Style: &ThemeDefault.SuccessPrefixStyle, | ||||||
|  | 			Text:  "SUCCESS", | ||||||
|  | 		}, | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// Error returns a PrefixPrinter, which can be used to print text with an "error" Prefix.
 | ||||||
|  | 	Error = PrefixPrinter{ | ||||||
|  | 		MessageStyle: &ThemeDefault.ErrorMessageStyle, | ||||||
|  | 		Prefix: Prefix{ | ||||||
|  | 			Style: &ThemeDefault.ErrorPrefixStyle, | ||||||
|  | 			Text:  " ERROR ", | ||||||
|  | 		}, | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// Fatal returns a PrefixPrinter, which can be used to print text with an "fatal" Prefix.
 | ||||||
|  | 	// NOTICE: Fatal terminates the application immediately!
 | ||||||
|  | 	Fatal = PrefixPrinter{ | ||||||
|  | 		MessageStyle: &ThemeDefault.FatalMessageStyle, | ||||||
|  | 		Prefix: Prefix{ | ||||||
|  | 			Style: &ThemeDefault.FatalPrefixStyle, | ||||||
|  | 			Text:  " FATAL ", | ||||||
|  | 		}, | ||||||
|  | 		Fatal: true, | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// Debug Prints debug messages. By default it will only print if PrintDebugMessages is true.
 | ||||||
|  | 	// You can change PrintDebugMessages with EnableDebugMessages and DisableDebugMessages, or by setting the variable itself.
 | ||||||
|  | 	Debug = PrefixPrinter{ | ||||||
|  | 		MessageStyle: &ThemeDefault.DebugMessageStyle, | ||||||
|  | 		Prefix: Prefix{ | ||||||
|  | 			Text:  " DEBUG ", | ||||||
|  | 			Style: &ThemeDefault.DebugPrefixStyle, | ||||||
|  | 		}, | ||||||
|  | 		Debugger: true, | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// Description returns a PrefixPrinter, which can be used to print text with a "description" Prefix.
 | ||||||
|  | 	Description = PrefixPrinter{ | ||||||
|  | 		MessageStyle: &ThemeDefault.DescriptionMessageStyle, | ||||||
|  | 		Prefix: Prefix{ | ||||||
|  | 			Style: &ThemeDefault.DescriptionPrefixStyle, | ||||||
|  | 			Text:  "Description", | ||||||
|  | 		}, | ||||||
|  | 	} | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // PrefixPrinter is the printer used to print a Prefix.
 | ||||||
|  | type PrefixPrinter struct { | ||||||
|  | 	Prefix           Prefix | ||||||
|  | 	Scope            Scope | ||||||
|  | 	MessageStyle     *Style | ||||||
|  | 	Fatal            bool | ||||||
|  | 	ShowLineNumber   bool | ||||||
|  | 	LineNumberOffset int | ||||||
|  | 	// If Debugger is true, the printer will only print if PrintDebugMessages is set to true.
 | ||||||
|  | 	// You can change PrintDebugMessages with EnableDebugMessages and DisableDebugMessages, or by setting the variable itself.
 | ||||||
|  | 	Debugger bool | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithPrefix adds a custom prefix to the printer.
 | ||||||
|  | func (p PrefixPrinter) WithPrefix(prefix Prefix) *PrefixPrinter { | ||||||
|  | 	p.Prefix = prefix | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithScope adds a scope to the Prefix.
 | ||||||
|  | func (p PrefixPrinter) WithScope(scope Scope) *PrefixPrinter { | ||||||
|  | 	p.Scope = scope | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithMessageStyle adds a custom prefix to the printer.
 | ||||||
|  | func (p PrefixPrinter) WithMessageStyle(style *Style) *PrefixPrinter { | ||||||
|  | 	p.MessageStyle = style | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithFatal sets if the printer should panic after printing.
 | ||||||
|  | // NOTE:
 | ||||||
|  | // The printer will only panic if either PrefixPrinter.Println, PrefixPrinter.Print
 | ||||||
|  | // or PrefixPrinter.Printf is called.
 | ||||||
|  | func (p PrefixPrinter) WithFatal(b ...bool) *PrefixPrinter { | ||||||
|  | 	p.Fatal = internal.WithBoolean(b) | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithShowLineNumber sets if the printer should print the line number from where it's called in a go file.
 | ||||||
|  | func (p PrefixPrinter) WithShowLineNumber(b ...bool) *PrefixPrinter { | ||||||
|  | 	p.ShowLineNumber = internal.WithBoolean(b) | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithDebugger returns a new Printer with specific Debugger value.
 | ||||||
|  | // If Debugger is true, the printer will only print if PrintDebugMessages is set to true.
 | ||||||
|  | // You can change PrintDebugMessages with EnableDebugMessages and DisableDebugMessages, or by setting the variable itself.
 | ||||||
|  | func (p PrefixPrinter) WithDebugger(b ...bool) *PrefixPrinter { | ||||||
|  | 	p.Debugger = internal.WithBoolean(b) | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithLineNumberOffset can be used to exclude a specific amount of calls in the call stack.
 | ||||||
|  | // If you make a wrapper function for example, you can set this to one.
 | ||||||
|  | // The printed line number will then be the line number where your wrapper function is called.
 | ||||||
|  | func (p PrefixPrinter) WithLineNumberOffset(offset int) *PrefixPrinter { | ||||||
|  | 	p.LineNumberOffset = offset | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Sprint formats using the default formats for its operands and returns the resulting string.
 | ||||||
|  | // Spaces are added between operands when neither is a string.
 | ||||||
|  | func (p *PrefixPrinter) Sprint(a ...interface{}) string { | ||||||
|  | 	m := Sprint(a...) | ||||||
|  | 	if p.Debugger && !PrintDebugMessages { | ||||||
|  | 		return "" | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if RawOutput { | ||||||
|  | 		if p.Prefix.Text != "" { | ||||||
|  | 			return Sprintf("%s: %s", strings.TrimSpace(p.Prefix.Text), Sprint(a...)) | ||||||
|  | 		} else { | ||||||
|  | 			return Sprint(a...) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if p.Prefix.Style == nil { | ||||||
|  | 		p.Prefix.Style = NewStyle() | ||||||
|  | 	} | ||||||
|  | 	if p.Scope.Style == nil { | ||||||
|  | 		p.Scope.Style = NewStyle() | ||||||
|  | 	} | ||||||
|  | 	if p.MessageStyle == nil { | ||||||
|  | 		p.MessageStyle = NewStyle() | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	var ret string | ||||||
|  | 	var newLine bool | ||||||
|  | 
 | ||||||
|  | 	if strings.HasSuffix(m, "\n") { | ||||||
|  | 		m = strings.TrimRight(m, "\n") | ||||||
|  | 		newLine = true | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	messageLines := strings.Split(m, "\n") | ||||||
|  | 	for i, m := range messageLines { | ||||||
|  | 		if i == 0 { | ||||||
|  | 			ret += p.GetFormattedPrefix() + " " | ||||||
|  | 			if p.Scope.Text != "" { | ||||||
|  | 				ret += NewStyle(*p.Scope.Style...).Sprint(" (" + p.Scope.Text + ") ") | ||||||
|  | 			} | ||||||
|  | 			ret += p.MessageStyle.Sprint(m) | ||||||
|  | 		} else { | ||||||
|  | 			ret += "\n" + p.Prefix.Style.Sprint(strings.Repeat(" ", len(p.Prefix.Text)+2)) + " " + p.MessageStyle.Sprint(m) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	_, fileName, line, _ := runtime.Caller(3 + p.LineNumberOffset) | ||||||
|  | 
 | ||||||
|  | 	if p.ShowLineNumber { | ||||||
|  | 		ret += FgGray.Sprint("\n└ " + fmt.Sprintf("(%s:%d)\n", fileName, line)) | ||||||
|  | 		newLine = false | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if newLine { | ||||||
|  | 		ret += "\n" | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return Sprint(ret) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Sprintln formats using the default formats for its operands and returns the resulting string.
 | ||||||
|  | // Spaces are always added between operands and a newline is appended.
 | ||||||
|  | func (p PrefixPrinter) Sprintln(a ...interface{}) string { | ||||||
|  | 	if p.Debugger && !PrintDebugMessages { | ||||||
|  | 		return "" | ||||||
|  | 	} | ||||||
|  | 	str := fmt.Sprintln(a...) | ||||||
|  | 	return p.Sprint(str) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Sprintf formats according to a format specifier and returns the resulting string.
 | ||||||
|  | func (p PrefixPrinter) Sprintf(format string, a ...interface{}) string { | ||||||
|  | 	if p.Debugger && !PrintDebugMessages { | ||||||
|  | 		return "" | ||||||
|  | 	} | ||||||
|  | 	return p.Sprint(Sprintf(format, a...)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Sprintfln formats according to a format specifier and returns the resulting string.
 | ||||||
|  | // Spaces are always added between operands and a newline is appended.
 | ||||||
|  | func (p PrefixPrinter) Sprintfln(format string, a ...interface{}) string { | ||||||
|  | 	if p.Debugger && !PrintDebugMessages { | ||||||
|  | 		return "" | ||||||
|  | 	} | ||||||
|  | 	return p.Sprintf(format, a...) + "\n" | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Print formats using the default formats for its operands and writes to standard output.
 | ||||||
|  | // Spaces are added between operands when neither is a string.
 | ||||||
|  | // It returns the number of bytes written and any write error encountered.
 | ||||||
|  | func (p *PrefixPrinter) Print(a ...interface{}) *TextPrinter { | ||||||
|  | 	tp := TextPrinter(p) | ||||||
|  | 	if p.Debugger && !PrintDebugMessages { | ||||||
|  | 		return &tp | ||||||
|  | 	} | ||||||
|  | 	Print(p.Sprint(a...)) | ||||||
|  | 	checkFatal(p) | ||||||
|  | 	return &tp | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Println formats using the default formats for its operands and writes to standard output.
 | ||||||
|  | // Spaces are always added between operands and a newline is appended.
 | ||||||
|  | // It returns the number of bytes written and any write error encountered.
 | ||||||
|  | func (p *PrefixPrinter) Println(a ...interface{}) *TextPrinter { | ||||||
|  | 	tp := TextPrinter(p) | ||||||
|  | 	if p.Debugger && !PrintDebugMessages { | ||||||
|  | 		return &tp | ||||||
|  | 	} | ||||||
|  | 	Print(p.Sprintln(a...)) | ||||||
|  | 	checkFatal(p) | ||||||
|  | 	return &tp | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Printf formats according to a format specifier and writes to standard output.
 | ||||||
|  | // It returns the number of bytes written and any write error encountered.
 | ||||||
|  | func (p *PrefixPrinter) Printf(format string, a ...interface{}) *TextPrinter { | ||||||
|  | 	tp := TextPrinter(p) | ||||||
|  | 	if p.Debugger && !PrintDebugMessages { | ||||||
|  | 		return &tp | ||||||
|  | 	} | ||||||
|  | 	Print(p.Sprintf(format, a...)) | ||||||
|  | 	checkFatal(p) | ||||||
|  | 	return &tp | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Printfln formats according to a format specifier and writes to standard output.
 | ||||||
|  | // Spaces are always added between operands and a newline is appended.
 | ||||||
|  | // It returns the number of bytes written and any write error encountered.
 | ||||||
|  | func (p *PrefixPrinter) Printfln(format string, a ...interface{}) *TextPrinter { | ||||||
|  | 	tp := TextPrinter(p) | ||||||
|  | 	if p.Debugger && !PrintDebugMessages { | ||||||
|  | 		return &tp | ||||||
|  | 	} | ||||||
|  | 	Print(p.Sprintfln(format, a...)) | ||||||
|  | 	checkFatal(p) | ||||||
|  | 	return &tp | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // PrintOnError prints every error which is not nil.
 | ||||||
|  | // If every error is nil, nothing will be printed.
 | ||||||
|  | // This can be used for simple error checking.
 | ||||||
|  | //
 | ||||||
|  | // Note: Use WithFatal(true) or Fatal to panic after first non nil error.
 | ||||||
|  | func (p *PrefixPrinter) PrintOnError(a ...interface{}) *TextPrinter { | ||||||
|  | 	for _, arg := range a { | ||||||
|  | 		if err, ok := arg.(error); ok { | ||||||
|  | 			if err != nil { | ||||||
|  | 				p.Println(err) | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	tp := TextPrinter(p) | ||||||
|  | 	return &tp | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // PrintOnErrorf wraps every error which is not nil and prints it.
 | ||||||
|  | // If every error is nil, nothing will be printed.
 | ||||||
|  | // This can be used for simple error checking.
 | ||||||
|  | func (p *PrefixPrinter) PrintOnErrorf(format string, a ...interface{}) *TextPrinter { | ||||||
|  | 	for _, arg := range a { | ||||||
|  | 		if err, ok := arg.(error); ok { | ||||||
|  | 			if err != nil { | ||||||
|  | 				p.Println(fmt.Errorf(format, err)) | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	tp := TextPrinter(p) | ||||||
|  | 	return &tp | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // GetFormattedPrefix returns the Prefix as a styled text string.
 | ||||||
|  | func (p PrefixPrinter) GetFormattedPrefix() string { | ||||||
|  | 	return p.Prefix.Style.Sprint(" " + p.Prefix.Text + " ") | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Prefix contains the data used as the beginning of a printed text via a PrefixPrinter.
 | ||||||
|  | type Prefix struct { | ||||||
|  | 	Text  string | ||||||
|  | 	Style *Style | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Scope contains the data of the optional scope of a prefix.
 | ||||||
|  | // If it has a text, it will be printed after the Prefix in brackets.
 | ||||||
|  | type Scope struct { | ||||||
|  | 	Text  string | ||||||
|  | 	Style *Style | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func checkFatal(p *PrefixPrinter) { | ||||||
|  | 	if p.Fatal { | ||||||
|  | 		panic("") | ||||||
|  | 	} | ||||||
|  | } | ||||||
							
								
								
									
										179
									
								
								vendor/github.com/pterm/pterm/print.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										179
									
								
								vendor/github.com/pterm/pterm/print.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,179 @@ | |||||||
|  | package pterm | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  | 	"io" | ||||||
|  | 	"strings" | ||||||
|  | 
 | ||||||
|  | 	"github.com/gookit/color" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // SetDefaultOutput sets the default output of pterm.
 | ||||||
|  | func SetDefaultOutput(w io.Writer) { | ||||||
|  | 	color.SetOutput(w) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Sprint formats using the default formats for its operands and returns the resulting string.
 | ||||||
|  | // Spaces are added between operands when neither is a string.
 | ||||||
|  | func Sprint(a ...interface{}) string { | ||||||
|  | 	return color.Sprint(a...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Sprintf formats according to a format specifier and returns the resulting string.
 | ||||||
|  | func Sprintf(format string, a ...interface{}) string { | ||||||
|  | 	return color.Sprintf(format, a...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Sprintfln formats according to a format specifier and returns the resulting string.
 | ||||||
|  | // Spaces are always added between operands and a newline is appended.
 | ||||||
|  | func Sprintfln(format string, a ...interface{}) string { | ||||||
|  | 	return color.Sprintf(format, a...) + "\n" | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Sprintln returns what Println would print to the terminal.
 | ||||||
|  | func Sprintln(a ...interface{}) string { | ||||||
|  | 	str := fmt.Sprintln(a...) | ||||||
|  | 	return Sprint(str) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Sprinto returns what Printo would print.
 | ||||||
|  | func Sprinto(a ...interface{}) string { | ||||||
|  | 	return "\r" + Sprint(a...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Print formats using the default formats for its operands and writes to standard output.
 | ||||||
|  | // Spaces are added between operands when neither is a string.
 | ||||||
|  | // It returns the number of bytes written and any write error encountered.
 | ||||||
|  | func Print(a ...interface{}) { | ||||||
|  | 	if !Output { | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	var ret string | ||||||
|  | 	var printed bool | ||||||
|  | 
 | ||||||
|  | 	for _, bar := range ActiveProgressBarPrinters { | ||||||
|  | 		if bar.IsActive { | ||||||
|  | 			ret += sClearLine() | ||||||
|  | 			ret += Sprinto(a...) | ||||||
|  | 			printed = true | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	for _, spinner := range activeSpinnerPrinters { | ||||||
|  | 		if spinner.IsActive { | ||||||
|  | 			ret += sClearLine() | ||||||
|  | 			ret += Sprinto(a...) | ||||||
|  | 			printed = true | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if !printed { | ||||||
|  | 		ret = color.Sprint(Sprint(a...)) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	color.Print(Sprint(ret)) | ||||||
|  | 
 | ||||||
|  | 	// Refresh all progressbars in case they were overwritten previously. Reference: #302
 | ||||||
|  | 	for _, bar := range ActiveProgressBarPrinters { | ||||||
|  | 		if bar.IsActive { | ||||||
|  | 			bar.UpdateTitle(bar.Title) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Println formats using the default formats for its operands and writes to standard output.
 | ||||||
|  | // Spaces are always added between operands and a newline is appended.
 | ||||||
|  | // It returns the number of bytes written and any write error encountered.
 | ||||||
|  | func Println(a ...interface{}) { | ||||||
|  | 	Print(Sprintln(a...)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Printf formats according to a format specifier and writes to standard output.
 | ||||||
|  | // It returns the number of bytes written and any write error encountered.
 | ||||||
|  | func Printf(format string, a ...interface{}) { | ||||||
|  | 	Print(Sprintf(format, a...)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Printfln formats according to a format specifier and writes to standard output.
 | ||||||
|  | // Spaces are always added between operands and a newline is appended.
 | ||||||
|  | // It returns the number of bytes written and any write error encountered.
 | ||||||
|  | func Printfln(format string, a ...interface{}) { | ||||||
|  | 	Print(Sprintfln(format, a...)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // PrintOnError prints every error which is not nil.
 | ||||||
|  | // If every error is nil, nothing will be printed.
 | ||||||
|  | // This can be used for simple error checking.
 | ||||||
|  | func PrintOnError(a ...interface{}) { | ||||||
|  | 	for _, arg := range a { | ||||||
|  | 		if err, ok := arg.(error); ok { | ||||||
|  | 			if err != nil { | ||||||
|  | 				Println(err) | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // PrintOnErrorf wraps every error which is not nil and prints it.
 | ||||||
|  | // If every error is nil, nothing will be printed.
 | ||||||
|  | // This can be used for simple error checking.
 | ||||||
|  | func PrintOnErrorf(format string, a ...interface{}) { | ||||||
|  | 	for _, arg := range a { | ||||||
|  | 		if err, ok := arg.(error); ok { | ||||||
|  | 			if err != nil { | ||||||
|  | 				Println(fmt.Errorf(format, err)) | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Fprint formats using the default formats for its operands and writes to w.
 | ||||||
|  | // Spaces are added between operands when neither is a string.
 | ||||||
|  | // It returns the number of bytes written and any write error encountered.
 | ||||||
|  | func Fprint(writer io.Writer, a ...interface{}) { | ||||||
|  | 	if !Output { | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	color.Fprint(writer, Sprint(a...)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Fprintln formats using the default formats for its operands and writes to w.
 | ||||||
|  | // Spaces are always added between operands and a newline is appended.
 | ||||||
|  | // It returns the number of bytes written and any write error encountered.
 | ||||||
|  | func Fprintln(writer io.Writer, a ...interface{}) { | ||||||
|  | 	Fprint(writer, Sprint(a...)+"\n") | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Printo overrides the current line in a terminal.
 | ||||||
|  | // If the current line is empty, the text will be printed like with pterm.Print.
 | ||||||
|  | // Example:
 | ||||||
|  | //   pterm.Printo("Hello, World")
 | ||||||
|  | //   time.Sleep(time.Second)
 | ||||||
|  | //   pterm.Printo("Hello, Earth!")
 | ||||||
|  | func Printo(a ...interface{}) { | ||||||
|  | 	if !Output { | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	color.Print("\r" + Sprint(a...)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Fprinto prints Printo to a custom writer.
 | ||||||
|  | func Fprinto(w io.Writer, a ...interface{}) { | ||||||
|  | 	Fprint(w, "\r", Sprint(a...)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // RemoveColorFromString removes color codes from a string.
 | ||||||
|  | func RemoveColorFromString(a ...interface{}) string { | ||||||
|  | 	return color.ClearCode(Sprint(a...)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func clearLine() { | ||||||
|  | 	Printo(strings.Repeat(" ", GetTerminalWidth())) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func sClearLine() string { | ||||||
|  | 	return Sprinto(strings.Repeat(" ", GetTerminalWidth())) | ||||||
|  | } | ||||||
							
								
								
									
										271
									
								
								vendor/github.com/pterm/pterm/progressbar_printer.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										271
									
								
								vendor/github.com/pterm/pterm/progressbar_printer.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,271 @@ | |||||||
|  | package pterm | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"strconv" | ||||||
|  | 	"strings" | ||||||
|  | 	"time" | ||||||
|  | 
 | ||||||
|  | 	"github.com/gookit/color" | ||||||
|  | 
 | ||||||
|  | 	"github.com/pterm/pterm/internal" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // ActiveProgressBarPrinters contains all running ProgressbarPrinters.
 | ||||||
|  | // Generally, there should only be one active ProgressbarPrinter at a time.
 | ||||||
|  | var ActiveProgressBarPrinters []*ProgressbarPrinter | ||||||
|  | 
 | ||||||
|  | var ( | ||||||
|  | 	// DefaultProgressbar is the default ProgressbarPrinter.
 | ||||||
|  | 	DefaultProgressbar = ProgressbarPrinter{ | ||||||
|  | 		Total:                     100, | ||||||
|  | 		BarCharacter:              "█", | ||||||
|  | 		LastCharacter:             "█", | ||||||
|  | 		ElapsedTimeRoundingFactor: time.Second, | ||||||
|  | 		BarStyle:                  &ThemeDefault.ProgressbarBarStyle, | ||||||
|  | 		TitleStyle:                &ThemeDefault.ProgressbarTitleStyle, | ||||||
|  | 		ShowTitle:                 true, | ||||||
|  | 		ShowCount:                 true, | ||||||
|  | 		ShowPercentage:            true, | ||||||
|  | 		ShowElapsedTime:           true, | ||||||
|  | 		BarFiller:                 " ", | ||||||
|  | 	} | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // ProgressbarPrinter shows a progress animation in the terminal.
 | ||||||
|  | type ProgressbarPrinter struct { | ||||||
|  | 	Title                     string | ||||||
|  | 	Total                     int | ||||||
|  | 	Current                   int | ||||||
|  | 	BarCharacter              string | ||||||
|  | 	LastCharacter             string | ||||||
|  | 	ElapsedTimeRoundingFactor time.Duration | ||||||
|  | 	BarFiller                 string | ||||||
|  | 
 | ||||||
|  | 	ShowElapsedTime bool | ||||||
|  | 	ShowCount       bool | ||||||
|  | 	ShowTitle       bool | ||||||
|  | 	ShowPercentage  bool | ||||||
|  | 	RemoveWhenDone  bool | ||||||
|  | 
 | ||||||
|  | 	TitleStyle *Style | ||||||
|  | 	BarStyle   *Style | ||||||
|  | 
 | ||||||
|  | 	IsActive bool | ||||||
|  | 
 | ||||||
|  | 	startedAt time.Time | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithTitle sets the name of the ProgressbarPrinter.
 | ||||||
|  | func (p ProgressbarPrinter) WithTitle(name string) *ProgressbarPrinter { | ||||||
|  | 	p.Title = name | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithTotal sets the total value of the ProgressbarPrinter.
 | ||||||
|  | func (p ProgressbarPrinter) WithTotal(total int) *ProgressbarPrinter { | ||||||
|  | 	p.Total = total | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithCurrent sets the current value of the ProgressbarPrinter.
 | ||||||
|  | func (p ProgressbarPrinter) WithCurrent(current int) *ProgressbarPrinter { | ||||||
|  | 	p.Current = current | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithBarCharacter sets the bar character of the ProgressbarPrinter.
 | ||||||
|  | func (p ProgressbarPrinter) WithBarCharacter(char string) *ProgressbarPrinter { | ||||||
|  | 	p.BarCharacter = char | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithLastCharacter sets the last character of the ProgressbarPrinter.
 | ||||||
|  | func (p ProgressbarPrinter) WithLastCharacter(char string) *ProgressbarPrinter { | ||||||
|  | 	p.LastCharacter = char | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithElapsedTimeRoundingFactor sets the rounding factor of the elapsed time.
 | ||||||
|  | func (p ProgressbarPrinter) WithElapsedTimeRoundingFactor(duration time.Duration) *ProgressbarPrinter { | ||||||
|  | 	p.ElapsedTimeRoundingFactor = duration | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithShowElapsedTime sets if the elapsed time should be displayed in the ProgressbarPrinter.
 | ||||||
|  | func (p ProgressbarPrinter) WithShowElapsedTime(b ...bool) *ProgressbarPrinter { | ||||||
|  | 	p.ShowElapsedTime = internal.WithBoolean(b) | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithShowCount sets if the total and current count should be displayed in the ProgressbarPrinter.
 | ||||||
|  | func (p ProgressbarPrinter) WithShowCount(b ...bool) *ProgressbarPrinter { | ||||||
|  | 	p.ShowCount = internal.WithBoolean(b) | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithShowTitle sets if the title should be displayed in the ProgressbarPrinter.
 | ||||||
|  | func (p ProgressbarPrinter) WithShowTitle(b ...bool) *ProgressbarPrinter { | ||||||
|  | 	p.ShowTitle = internal.WithBoolean(b) | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithShowPercentage sets if the completed percentage should be displayed in the ProgressbarPrinter.
 | ||||||
|  | func (p ProgressbarPrinter) WithShowPercentage(b ...bool) *ProgressbarPrinter { | ||||||
|  | 	p.ShowPercentage = internal.WithBoolean(b) | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithTitleStyle sets the style of the title.
 | ||||||
|  | func (p ProgressbarPrinter) WithTitleStyle(style *Style) *ProgressbarPrinter { | ||||||
|  | 	p.TitleStyle = style | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithBarStyle sets the style of the bar.
 | ||||||
|  | func (p ProgressbarPrinter) WithBarStyle(style *Style) *ProgressbarPrinter { | ||||||
|  | 	p.BarStyle = style | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithRemoveWhenDone sets if the ProgressbarPrinter should be removed when it is done.
 | ||||||
|  | func (p ProgressbarPrinter) WithRemoveWhenDone(b ...bool) *ProgressbarPrinter { | ||||||
|  | 	p.RemoveWhenDone = internal.WithBoolean(b) | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Increment current value by one.
 | ||||||
|  | func (p *ProgressbarPrinter) Increment() *ProgressbarPrinter { | ||||||
|  | 	p.Add(1) | ||||||
|  | 	return p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // This method changed the title and re-renders the progressbar
 | ||||||
|  | func (p *ProgressbarPrinter) UpdateTitle(title string) *ProgressbarPrinter { | ||||||
|  | 	p.Title = title | ||||||
|  | 	p.updateProgress() | ||||||
|  | 	return p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // This is the update logic, renders the progressbar
 | ||||||
|  | func (p *ProgressbarPrinter) updateProgress() *ProgressbarPrinter { | ||||||
|  | 	if p.TitleStyle == nil { | ||||||
|  | 		p.TitleStyle = NewStyle() | ||||||
|  | 	} | ||||||
|  | 	if p.BarStyle == nil { | ||||||
|  | 		p.BarStyle = NewStyle() | ||||||
|  | 	} | ||||||
|  | 	if p.Total == 0 { | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	var before string | ||||||
|  | 	var after string | ||||||
|  | 
 | ||||||
|  | 	width := GetTerminalWidth() | ||||||
|  | 	currentPercentage := int(internal.PercentageRound(float64(int64(p.Total)), float64(int64(p.Current)))) | ||||||
|  | 
 | ||||||
|  | 	decoratorCount := Gray("[") + LightWhite(p.Current) + Gray("/") + LightWhite(p.Total) + Gray("]") | ||||||
|  | 
 | ||||||
|  | 	decoratorCurrentPercentage := color.RGB(NewRGB(255, 0, 0).Fade(0, float32(p.Total), float32(p.Current), NewRGB(0, 255, 0)).GetValues()). | ||||||
|  | 		Sprint(strconv.Itoa(currentPercentage) + "%") | ||||||
|  | 
 | ||||||
|  | 	decoratorTitle := p.TitleStyle.Sprint(p.Title) | ||||||
|  | 
 | ||||||
|  | 	if p.ShowTitle { | ||||||
|  | 		before += decoratorTitle + " " | ||||||
|  | 	} | ||||||
|  | 	if p.ShowCount { | ||||||
|  | 		before += decoratorCount + " " | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	after += " " | ||||||
|  | 
 | ||||||
|  | 	if p.ShowPercentage { | ||||||
|  | 		after += decoratorCurrentPercentage + " " | ||||||
|  | 	} | ||||||
|  | 	if p.ShowElapsedTime { | ||||||
|  | 		after += "| " + p.parseElapsedTime() | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	barMaxLength := width - len(RemoveColorFromString(before)) - len(RemoveColorFromString(after)) - 1 | ||||||
|  | 	barCurrentLength := (p.Current * barMaxLength) / p.Total | ||||||
|  | 	barFiller := strings.Repeat(p.BarFiller, barMaxLength-barCurrentLength) | ||||||
|  | 
 | ||||||
|  | 	bar := p.BarStyle.Sprint(strings.Repeat(p.BarCharacter, barCurrentLength)+p.LastCharacter) + barFiller | ||||||
|  | 	if !RawOutput { | ||||||
|  | 		Printo(before + bar + after) | ||||||
|  | 	} | ||||||
|  | 	return p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Add to current value.
 | ||||||
|  | func (p *ProgressbarPrinter) Add(count int) *ProgressbarPrinter { | ||||||
|  | 	if p.Total == 0 { | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	p.Current += count | ||||||
|  | 	p.updateProgress() | ||||||
|  | 
 | ||||||
|  | 	if p.Current == p.Total { | ||||||
|  | 		p.Stop() | ||||||
|  | 	} | ||||||
|  | 	return p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Start the ProgressbarPrinter.
 | ||||||
|  | func (p ProgressbarPrinter) Start() (*ProgressbarPrinter, error) { | ||||||
|  | 	if RawOutput && p.ShowTitle { | ||||||
|  | 		Println(p.Title) | ||||||
|  | 	} | ||||||
|  | 	p.IsActive = true | ||||||
|  | 	ActiveProgressBarPrinters = append(ActiveProgressBarPrinters, &p) | ||||||
|  | 	p.startedAt = time.Now() | ||||||
|  | 
 | ||||||
|  | 	p.updateProgress() | ||||||
|  | 
 | ||||||
|  | 	return &p, nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Stop the ProgressbarPrinter.
 | ||||||
|  | func (p *ProgressbarPrinter) Stop() (*ProgressbarPrinter, error) { | ||||||
|  | 	if !p.IsActive { | ||||||
|  | 		return p, nil | ||||||
|  | 	} | ||||||
|  | 	p.IsActive = false | ||||||
|  | 	if p.RemoveWhenDone { | ||||||
|  | 		clearLine() | ||||||
|  | 		Printo() | ||||||
|  | 	} else { | ||||||
|  | 		Println() | ||||||
|  | 	} | ||||||
|  | 	return p, nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // GenericStart runs Start, but returns a LivePrinter.
 | ||||||
|  | // This is used for the interface LivePrinter.
 | ||||||
|  | // You most likely want to use Start instead of this in your program.
 | ||||||
|  | func (p ProgressbarPrinter) GenericStart() (*LivePrinter, error) { | ||||||
|  | 	p2, _ := p.Start() | ||||||
|  | 	lp := LivePrinter(p2) | ||||||
|  | 	return &lp, nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // GenericStop runs Stop, but returns a LivePrinter.
 | ||||||
|  | // This is used for the interface LivePrinter.
 | ||||||
|  | // You most likely want to use Stop instead of this in your program.
 | ||||||
|  | func (p ProgressbarPrinter) GenericStop() (*LivePrinter, error) { | ||||||
|  | 	p2, _ := p.Stop() | ||||||
|  | 	lp := LivePrinter(p2) | ||||||
|  | 	return &lp, nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // GetElapsedTime returns the elapsed time, since the ProgressbarPrinter was started.
 | ||||||
|  | func (p *ProgressbarPrinter) GetElapsedTime() time.Duration { | ||||||
|  | 	return time.Since(p.startedAt) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (p *ProgressbarPrinter) parseElapsedTime() string { | ||||||
|  | 	s := p.GetElapsedTime().Round(p.ElapsedTimeRoundingFactor).String() | ||||||
|  | 	return s | ||||||
|  | } | ||||||
							
								
								
									
										67
									
								
								vendor/github.com/pterm/pterm/pterm.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								vendor/github.com/pterm/pterm/pterm.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,67 @@ | |||||||
|  | // Package pterm is a modern go module to beautify console output.
 | ||||||
|  | // It can be used without configuration, but if desired, everything can be customized down to the smallest detail.
 | ||||||
|  | // View the animated examples here: https://github.com/pterm/pterm#-examples
 | ||||||
|  | package pterm | ||||||
|  | 
 | ||||||
|  | import "github.com/gookit/color" | ||||||
|  | 
 | ||||||
|  | var ( | ||||||
|  | 	// Output completely disables output from pterm if set to false. Can be used in CLI application quiet mode.
 | ||||||
|  | 	Output = true | ||||||
|  | 
 | ||||||
|  | 	// PrintDebugMessages sets if messages printed by the DebugPrinter should be printed.
 | ||||||
|  | 	PrintDebugMessages = false | ||||||
|  | 
 | ||||||
|  | 	// RawOutput is set to true if pterm.DisableStyling() was called.
 | ||||||
|  | 	// The variable indicates that PTerm will not add additional styling to text.
 | ||||||
|  | 	// Use pterm.DisableStyling() or pterm.EnableStyling() to change this variable.
 | ||||||
|  | 	// Changing this variable directly, will disable or enable the output of colored text.
 | ||||||
|  | 	RawOutput = false | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | func init() { | ||||||
|  | 	color.ForceColor() | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // EnableOutput enables the output of PTerm.
 | ||||||
|  | func EnableOutput() { | ||||||
|  | 	Output = true | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // DisableOutput disables the output of PTerm.
 | ||||||
|  | func DisableOutput() { | ||||||
|  | 	Output = false | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // EnableDebugMessages enables the output of debug printers.
 | ||||||
|  | func EnableDebugMessages() { | ||||||
|  | 	PrintDebugMessages = true | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // DisableDebugMessages disables the output of debug printers.
 | ||||||
|  | func DisableDebugMessages() { | ||||||
|  | 	PrintDebugMessages = false | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // EnableStyling enables the default PTerm styling.
 | ||||||
|  | // This also calls EnableColor.
 | ||||||
|  | func EnableStyling() { | ||||||
|  | 	RawOutput = false | ||||||
|  | 	EnableColor() | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // DisableStyling sets PTerm to RawOutput mode and disables all of PTerms styling.
 | ||||||
|  | // You can use this to print to text files etc.
 | ||||||
|  | // This also calls DisableColor.
 | ||||||
|  | func DisableStyling() { | ||||||
|  | 	RawOutput = true | ||||||
|  | 	DisableColor() | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // RecalculateTerminalSize updates already initialized terminal dimensions. Has to be called after a termina resize to guarantee proper rendering. Applies only to new instances.
 | ||||||
|  | func RecalculateTerminalSize() { | ||||||
|  | 	// keep in sync with DefaultBarChart
 | ||||||
|  | 	DefaultBarChart.Width = GetTerminalWidth() * 2 / 3 | ||||||
|  | 	DefaultBarChart.Height = GetTerminalHeight() * 2 / 3 | ||||||
|  | 	DefaultParagraph.MaxWidth = GetTerminalWidth() | ||||||
|  | } | ||||||
							
								
								
									
										176
									
								
								vendor/github.com/pterm/pterm/rgb.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										176
									
								
								vendor/github.com/pterm/pterm/rgb.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,176 @@ | |||||||
|  | package pterm | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  | 	"strconv" | ||||||
|  | 	"strings" | ||||||
|  | 
 | ||||||
|  | 	"github.com/gookit/color" | ||||||
|  | 
 | ||||||
|  | 	"github.com/pterm/pterm/internal" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // RGB color model is an additive color model in which red, green, and blue light are added together in various ways to reproduce a broad array of colors.
 | ||||||
|  | // The name of the model comes from the initials of the three additive primary colors, red, green, and blue.
 | ||||||
|  | // https://en.wikipedia.org/wiki/RGB_color_model
 | ||||||
|  | type RGB struct { | ||||||
|  | 	R uint8 | ||||||
|  | 	G uint8 | ||||||
|  | 	B uint8 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // GetValues returns the RGB values separately.
 | ||||||
|  | func (p RGB) GetValues() (r, g, b uint8) { | ||||||
|  | 	return p.R, p.G, p.B | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // NewRGB returns a new RGB.
 | ||||||
|  | func NewRGB(r, g, b uint8) RGB { | ||||||
|  | 	return RGB{R: r, G: g, B: b} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // NewRGBFromHEX converts a HEX and returns a new RGB.
 | ||||||
|  | func NewRGBFromHEX(hex string) (RGB, error) { | ||||||
|  | 	hex = strings.ToLower(hex) | ||||||
|  | 	hex = strings.ReplaceAll(hex, "#", "") | ||||||
|  | 	hex = strings.ReplaceAll(hex, "0x", "") | ||||||
|  | 
 | ||||||
|  | 	if len(hex) == 3 { | ||||||
|  | 		hex = string([]byte{hex[0], hex[0], hex[1], hex[1], hex[2], hex[2]}) | ||||||
|  | 	} | ||||||
|  | 	if len(hex) != 6 { | ||||||
|  | 		return RGB{}, ErrHexCodeIsInvalid | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	i64, err := strconv.ParseInt(hex, 16, 32) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return RGB{}, err | ||||||
|  | 	} | ||||||
|  | 	c := int(i64) | ||||||
|  | 
 | ||||||
|  | 	return RGB{ | ||||||
|  | 		R: uint8(c >> 16), | ||||||
|  | 		G: uint8((c & 0x00FF00) >> 8), | ||||||
|  | 		B: uint8(c & 0x0000FF), | ||||||
|  | 	}, nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Fade fades one RGB value (over other RGB values) to another RGB value, by giving the function a minimum, maximum and current value.
 | ||||||
|  | func (p RGB) Fade(min, max, current float32, end ...RGB) RGB { | ||||||
|  | 	if min < 0 { | ||||||
|  | 		max -= min | ||||||
|  | 		current -= min | ||||||
|  | 		min = 0 | ||||||
|  | 	} | ||||||
|  | 	if len(end) == 1 { | ||||||
|  | 		return RGB{ | ||||||
|  | 			R: uint8(internal.MapRangeToRange(min, max, float32(p.R), float32(end[0].R), current)), | ||||||
|  | 			G: uint8(internal.MapRangeToRange(min, max, float32(p.G), float32(end[0].G), current)), | ||||||
|  | 			B: uint8(internal.MapRangeToRange(min, max, float32(p.B), float32(end[0].B), current)), | ||||||
|  | 		} | ||||||
|  | 	} else if len(end) > 1 { | ||||||
|  | 		f := (max - min) / float32(len(end)) | ||||||
|  | 		tempCurrent := current | ||||||
|  | 		if f > current { | ||||||
|  | 			return p.Fade(min, f, current, end[0]) | ||||||
|  | 		} else { | ||||||
|  | 			for i := 0; i < len(end)-1; i++ { | ||||||
|  | 				tempCurrent -= f | ||||||
|  | 				if f > tempCurrent { | ||||||
|  | 					return end[i].Fade(min, min+f, tempCurrent, end[i+1]) | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Sprint formats using the default formats for its operands and returns the resulting string.
 | ||||||
|  | // Spaces are added between operands when neither is a string.
 | ||||||
|  | func (p RGB) Sprint(a ...interface{}) string { | ||||||
|  | 	return color.RGB(p.R, p.G, p.B).Sprint(a...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Sprintln formats using the default formats for its operands and returns the resulting string.
 | ||||||
|  | // Spaces are always added between operands and a newline is appended.
 | ||||||
|  | func (p RGB) Sprintln(a ...interface{}) string { | ||||||
|  | 	return p.Sprint(Sprintln(a...)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Sprintf formats according to a format specifier and returns the resulting string.
 | ||||||
|  | func (p RGB) Sprintf(format string, a ...interface{}) string { | ||||||
|  | 	return p.Sprint(Sprintf(format, a...)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Sprintfln formats according to a format specifier and returns the resulting string.
 | ||||||
|  | // Spaces are always added between operands and a newline is appended.
 | ||||||
|  | func (p RGB) Sprintfln(format string, a ...interface{}) string { | ||||||
|  | 	return p.Sprintf(format, a...) + "\n" | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Print formats using the default formats for its operands and writes to standard output.
 | ||||||
|  | // Spaces are added between operands when neither is a string.
 | ||||||
|  | // It returns the number of bytes written and any write error encountered.
 | ||||||
|  | func (p RGB) Print(a ...interface{}) *TextPrinter { | ||||||
|  | 	Print(p.Sprint(a...)) | ||||||
|  | 	tp := TextPrinter(p) | ||||||
|  | 	return &tp | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Println formats using the default formats for its operands and writes to standard output.
 | ||||||
|  | // Spaces are always added between operands and a newline is appended.
 | ||||||
|  | // It returns the number of bytes written and any write error encountered.
 | ||||||
|  | func (p RGB) Println(a ...interface{}) *TextPrinter { | ||||||
|  | 	Print(p.Sprintln(a...)) | ||||||
|  | 	tp := TextPrinter(p) | ||||||
|  | 	return &tp | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Printf formats according to a format specifier and writes to standard output.
 | ||||||
|  | // It returns the number of bytes written and any write error encountered.
 | ||||||
|  | func (p RGB) Printf(format string, a ...interface{}) *TextPrinter { | ||||||
|  | 	Print(p.Sprintf(format, a...)) | ||||||
|  | 	tp := TextPrinter(p) | ||||||
|  | 	return &tp | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Printfln formats according to a format specifier and writes to standard output.
 | ||||||
|  | // Spaces are always added between operands and a newline is appended.
 | ||||||
|  | // It returns the number of bytes written and any write error encountered.
 | ||||||
|  | func (p RGB) Printfln(format string, a ...interface{}) *TextPrinter { | ||||||
|  | 	Print(p.Sprintfln(format, a...)) | ||||||
|  | 	tp := TextPrinter(p) | ||||||
|  | 	return &tp | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // PrintOnError prints every error which is not nil.
 | ||||||
|  | // If every error is nil, nothing will be printed.
 | ||||||
|  | // This can be used for simple error checking.
 | ||||||
|  | func (p RGB) PrintOnError(a ...interface{}) *TextPrinter { | ||||||
|  | 	for _, arg := range a { | ||||||
|  | 		if err, ok := arg.(error); ok { | ||||||
|  | 			if err != nil { | ||||||
|  | 				p.Println(err) | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	tp := TextPrinter(p) | ||||||
|  | 	return &tp | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // PrintOnErrorf wraps every error which is not nil and prints it.
 | ||||||
|  | // If every error is nil, nothing will be printed.
 | ||||||
|  | // This can be used for simple error checking.
 | ||||||
|  | func (p RGB) PrintOnErrorf(format string, a ...interface{}) *TextPrinter { | ||||||
|  | 	for _, arg := range a { | ||||||
|  | 		if err, ok := arg.(error); ok { | ||||||
|  | 			if err != nil { | ||||||
|  | 				p.Println(fmt.Errorf(format, err)) | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	tp := TextPrinter(p) | ||||||
|  | 	return &tp | ||||||
|  | } | ||||||
							
								
								
									
										166
									
								
								vendor/github.com/pterm/pterm/section_printer.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										166
									
								
								vendor/github.com/pterm/pterm/section_printer.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,166 @@ | |||||||
|  | package pterm | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  | 	"strings" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // DefaultSection is the default section printer.
 | ||||||
|  | var DefaultSection = SectionPrinter{ | ||||||
|  | 	Style:           &ThemeDefault.SectionStyle, | ||||||
|  | 	Level:           1, | ||||||
|  | 	TopPadding:      1, | ||||||
|  | 	BottomPadding:   1, | ||||||
|  | 	IndentCharacter: "#", | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // SectionPrinter prints a new section title.
 | ||||||
|  | // It can be used to structure longer text, or different chapters of your program.
 | ||||||
|  | type SectionPrinter struct { | ||||||
|  | 	Style           *Style | ||||||
|  | 	Level           int | ||||||
|  | 	IndentCharacter string | ||||||
|  | 	TopPadding      int | ||||||
|  | 	BottomPadding   int | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithStyle returns a new SectionPrinter with a specific style.
 | ||||||
|  | func (p SectionPrinter) WithStyle(style *Style) *SectionPrinter { | ||||||
|  | 	p.Style = style | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithLevel returns a new SectionPrinter with a specific level.
 | ||||||
|  | func (p SectionPrinter) WithLevel(level int) *SectionPrinter { | ||||||
|  | 	p.Level = level | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithIndentCharacter returns a new SectionPrinter with a specific IndentCharacter.
 | ||||||
|  | func (p SectionPrinter) WithIndentCharacter(char string) *SectionPrinter { | ||||||
|  | 	p.IndentCharacter = char | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithTopPadding returns a new SectionPrinter with a specific top padding.
 | ||||||
|  | func (p SectionPrinter) WithTopPadding(padding int) *SectionPrinter { | ||||||
|  | 	p.TopPadding = padding | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithBottomPadding returns a new SectionPrinter with a specific top padding.
 | ||||||
|  | func (p SectionPrinter) WithBottomPadding(padding int) *SectionPrinter { | ||||||
|  | 	p.BottomPadding = padding | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Sprint formats using the default formats for its operands and returns the resulting string.
 | ||||||
|  | // Spaces are added between operands when neither is a string.
 | ||||||
|  | func (p SectionPrinter) Sprint(a ...interface{}) string { | ||||||
|  | 	if p.Style == nil { | ||||||
|  | 		p.Style = NewStyle() | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	var ret string | ||||||
|  | 
 | ||||||
|  | 	for i := 0; i < p.TopPadding; i++ { | ||||||
|  | 		ret += "\n" | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if p.Level > 0 { | ||||||
|  | 		ret += strings.Repeat(p.IndentCharacter, p.Level) + " " | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	ret += p.Style.Sprint(a...) | ||||||
|  | 
 | ||||||
|  | 	for i := 0; i < p.BottomPadding; i++ { | ||||||
|  | 		ret += "\n" | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return ret | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Sprintln formats using the default formats for its operands and returns the resulting string.
 | ||||||
|  | // Spaces are always added between operands and a newline is appended.
 | ||||||
|  | func (p SectionPrinter) Sprintln(a ...interface{}) string { | ||||||
|  | 	str := fmt.Sprintln(a...) | ||||||
|  | 	return Sprint(p.Sprint(str)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Sprintf formats according to a format specifier and returns the resulting string.
 | ||||||
|  | func (p SectionPrinter) Sprintf(format string, a ...interface{}) string { | ||||||
|  | 	return p.Sprint(Sprintf(format, a...)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Sprintfln formats according to a format specifier and returns the resulting string.
 | ||||||
|  | // Spaces are always added between operands and a newline is appended.
 | ||||||
|  | func (p SectionPrinter) Sprintfln(format string, a ...interface{}) string { | ||||||
|  | 	return p.Sprintf(format, a...) + "\n" | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Print formats using the default formats for its operands and writes to standard output.
 | ||||||
|  | // Spaces are added between operands when neither is a string.
 | ||||||
|  | // It returns the number of bytes written and any write error encountered.
 | ||||||
|  | func (p *SectionPrinter) Print(a ...interface{}) *TextPrinter { | ||||||
|  | 	Print(p.Sprint(a...)) | ||||||
|  | 	tp := TextPrinter(p) | ||||||
|  | 	return &tp | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Println formats using the default formats for its operands and writes to standard output.
 | ||||||
|  | // Spaces are always added between operands and a newline is appended.
 | ||||||
|  | // It returns the number of bytes written and any write error encountered.
 | ||||||
|  | func (p *SectionPrinter) Println(a ...interface{}) *TextPrinter { | ||||||
|  | 	Print(p.Sprintln(a...)) | ||||||
|  | 	tp := TextPrinter(p) | ||||||
|  | 	return &tp | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Printf formats according to a format specifier and writes to standard output.
 | ||||||
|  | // It returns the number of bytes written and any write error encountered.
 | ||||||
|  | func (p *SectionPrinter) Printf(format string, a ...interface{}) *TextPrinter { | ||||||
|  | 	Print(p.Sprintf(format, a...)) | ||||||
|  | 	tp := TextPrinter(p) | ||||||
|  | 	return &tp | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Printfln formats according to a format specifier and writes to standard output.
 | ||||||
|  | // Spaces are always added between operands and a newline is appended.
 | ||||||
|  | // It returns the number of bytes written and any write error encountered.
 | ||||||
|  | func (p *SectionPrinter) Printfln(format string, a ...interface{}) *TextPrinter { | ||||||
|  | 	Print(p.Sprintfln(format, a...)) | ||||||
|  | 	tp := TextPrinter(p) | ||||||
|  | 	return &tp | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // PrintOnError prints every error which is not nil.
 | ||||||
|  | // If every error is nil, nothing will be printed.
 | ||||||
|  | // This can be used for simple error checking.
 | ||||||
|  | func (p *SectionPrinter) PrintOnError(a ...interface{}) *TextPrinter { | ||||||
|  | 	for _, arg := range a { | ||||||
|  | 		if err, ok := arg.(error); ok { | ||||||
|  | 			if err != nil { | ||||||
|  | 				p.Println(err) | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	tp := TextPrinter(p) | ||||||
|  | 	return &tp | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // PrintOnErrorf wraps every error which is not nil and prints it.
 | ||||||
|  | // If every error is nil, nothing will be printed.
 | ||||||
|  | // This can be used for simple error checking.
 | ||||||
|  | func (p *SectionPrinter) PrintOnErrorf(format string, a ...interface{}) *TextPrinter { | ||||||
|  | 	for _, arg := range a { | ||||||
|  | 		if err, ok := arg.(error); ok { | ||||||
|  | 			if err != nil { | ||||||
|  | 				p.Println(fmt.Errorf(format, err)) | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	tp := TextPrinter(p) | ||||||
|  | 	return &tp | ||||||
|  | } | ||||||
							
								
								
									
										223
									
								
								vendor/github.com/pterm/pterm/spinner_printer.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										223
									
								
								vendor/github.com/pterm/pterm/spinner_printer.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,223 @@ | |||||||
|  | package pterm | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"time" | ||||||
|  | 
 | ||||||
|  | 	"github.com/pterm/pterm/internal" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | var activeSpinnerPrinters []*SpinnerPrinter | ||||||
|  | 
 | ||||||
|  | // DefaultSpinner is the default SpinnerPrinter.
 | ||||||
|  | var DefaultSpinner = SpinnerPrinter{ | ||||||
|  | 	Sequence:            []string{"▀ ", " ▀", " ▄", "▄ "}, | ||||||
|  | 	Style:               &ThemeDefault.SpinnerStyle, | ||||||
|  | 	Delay:               time.Millisecond * 200, | ||||||
|  | 	ShowTimer:           true, | ||||||
|  | 	TimerRoundingFactor: time.Second, | ||||||
|  | 	TimerStyle:          &ThemeDefault.TimerStyle, | ||||||
|  | 	MessageStyle:        &ThemeDefault.SpinnerTextStyle, | ||||||
|  | 	SuccessPrinter:      &Success, | ||||||
|  | 	FailPrinter:         &Error, | ||||||
|  | 	WarningPrinter:      &Warning, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // SpinnerPrinter is a loading animation, which can be used if the progress is unknown.
 | ||||||
|  | // It's an animation loop, which can have a text and supports throwing errors or warnings.
 | ||||||
|  | // A TextPrinter is used to display all outputs, after the SpinnerPrinter is done.
 | ||||||
|  | type SpinnerPrinter struct { | ||||||
|  | 	Text                string | ||||||
|  | 	Sequence            []string | ||||||
|  | 	Style               *Style | ||||||
|  | 	Delay               time.Duration | ||||||
|  | 	MessageStyle        *Style | ||||||
|  | 	SuccessPrinter      TextPrinter | ||||||
|  | 	FailPrinter         TextPrinter | ||||||
|  | 	WarningPrinter      TextPrinter | ||||||
|  | 	RemoveWhenDone      bool | ||||||
|  | 	ShowTimer           bool | ||||||
|  | 	TimerRoundingFactor time.Duration | ||||||
|  | 	TimerStyle          *Style | ||||||
|  | 
 | ||||||
|  | 	IsActive bool | ||||||
|  | 
 | ||||||
|  | 	startedAt       time.Time | ||||||
|  | 	currentSequence string | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithText adds a text to the SpinnerPrinter.
 | ||||||
|  | func (s SpinnerPrinter) WithText(text string) *SpinnerPrinter { | ||||||
|  | 	s.Text = text | ||||||
|  | 	return &s | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithSequence adds a sequence to the SpinnerPrinter.
 | ||||||
|  | func (s SpinnerPrinter) WithSequence(sequence ...string) *SpinnerPrinter { | ||||||
|  | 	s.Sequence = sequence | ||||||
|  | 	return &s | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithStyle adds a style to the SpinnerPrinter.
 | ||||||
|  | func (s SpinnerPrinter) WithStyle(style *Style) *SpinnerPrinter { | ||||||
|  | 	s.Style = style | ||||||
|  | 	return &s | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithDelay adds a delay to the SpinnerPrinter.
 | ||||||
|  | func (s SpinnerPrinter) WithDelay(delay time.Duration) *SpinnerPrinter { | ||||||
|  | 	s.Delay = delay | ||||||
|  | 	return &s | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithMessageStyle adds a style to the SpinnerPrinter message.
 | ||||||
|  | func (s SpinnerPrinter) WithMessageStyle(style *Style) *SpinnerPrinter { | ||||||
|  | 	s.MessageStyle = style | ||||||
|  | 	return &s | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithRemoveWhenDone removes the SpinnerPrinter after it is done.
 | ||||||
|  | func (s SpinnerPrinter) WithRemoveWhenDone(b ...bool) *SpinnerPrinter { | ||||||
|  | 	s.RemoveWhenDone = internal.WithBoolean(b) | ||||||
|  | 	return &s | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithShowTimer shows how long the spinner is running.
 | ||||||
|  | func (s SpinnerPrinter) WithShowTimer(b ...bool) *SpinnerPrinter { | ||||||
|  | 	s.ShowTimer = internal.WithBoolean(b) | ||||||
|  | 	return &s | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithTimerRoundingFactor sets the rounding factor for the timer.
 | ||||||
|  | func (s SpinnerPrinter) WithTimerRoundingFactor(factor time.Duration) *SpinnerPrinter { | ||||||
|  | 	s.TimerRoundingFactor = factor | ||||||
|  | 	return &s | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithTimerStyle adds a style to the SpinnerPrinter timer.
 | ||||||
|  | func (s SpinnerPrinter) WithTimerStyle(style *Style) *SpinnerPrinter { | ||||||
|  | 	s.TimerStyle = style | ||||||
|  | 	return &s | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // UpdateText updates the message of the active SpinnerPrinter.
 | ||||||
|  | // Can be used live.
 | ||||||
|  | func (s *SpinnerPrinter) UpdateText(text string) { | ||||||
|  | 	s.Text = text | ||||||
|  | 	if !RawOutput { | ||||||
|  | 		clearLine() | ||||||
|  | 		Printo(s.Style.Sprint(s.currentSequence) + " " + s.MessageStyle.Sprint(s.Text)) | ||||||
|  | 	} | ||||||
|  | 	if RawOutput { | ||||||
|  | 		Println(s.Text) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Start the SpinnerPrinter.
 | ||||||
|  | func (s SpinnerPrinter) Start(text ...interface{}) (*SpinnerPrinter, error) { | ||||||
|  | 	s.IsActive = true | ||||||
|  | 	s.startedAt = time.Now() | ||||||
|  | 	activeSpinnerPrinters = append(activeSpinnerPrinters, &s) | ||||||
|  | 
 | ||||||
|  | 	if len(text) != 0 { | ||||||
|  | 		s.Text = Sprint(text...) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if RawOutput { | ||||||
|  | 		Println(s.Text) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	go func() { | ||||||
|  | 		for s.IsActive { | ||||||
|  | 			for _, seq := range s.Sequence { | ||||||
|  | 				if !s.IsActive || RawOutput { | ||||||
|  | 					continue | ||||||
|  | 				} | ||||||
|  | 
 | ||||||
|  | 				var timer string | ||||||
|  | 				if s.ShowTimer { | ||||||
|  | 					timer = " (" + time.Since(s.startedAt).Round(s.TimerRoundingFactor).String() + ")" | ||||||
|  | 				} | ||||||
|  | 				Printo(s.Style.Sprint(seq) + " " + s.MessageStyle.Sprint(s.Text) + s.TimerStyle.Sprint(timer)) | ||||||
|  | 				s.currentSequence = seq | ||||||
|  | 				time.Sleep(s.Delay) | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	}() | ||||||
|  | 	return &s, nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Stop terminates the SpinnerPrinter immediately.
 | ||||||
|  | // The SpinnerPrinter will not resolve into anything.
 | ||||||
|  | func (s *SpinnerPrinter) Stop() error { | ||||||
|  | 	s.IsActive = false | ||||||
|  | 	if s.RemoveWhenDone { | ||||||
|  | 		clearLine() | ||||||
|  | 		Printo() | ||||||
|  | 	} else { | ||||||
|  | 		Println() | ||||||
|  | 	} | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // GenericStart runs Start, but returns a LivePrinter.
 | ||||||
|  | // This is used for the interface LivePrinter.
 | ||||||
|  | // You most likely want to use Start instead of this in your program.
 | ||||||
|  | func (s *SpinnerPrinter) GenericStart() (*LivePrinter, error) { | ||||||
|  | 	_, _ = s.Start() | ||||||
|  | 	lp := LivePrinter(s) | ||||||
|  | 	return &lp, nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // GenericStop runs Stop, but returns a LivePrinter.
 | ||||||
|  | // This is used for the interface LivePrinter.
 | ||||||
|  | // You most likely want to use Stop instead of this in your program.
 | ||||||
|  | func (s *SpinnerPrinter) GenericStop() (*LivePrinter, error) { | ||||||
|  | 	_ = s.Stop() | ||||||
|  | 	lp := LivePrinter(s) | ||||||
|  | 	return &lp, nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Success displays the success printer.
 | ||||||
|  | // If no message is given, the text of the SpinnerPrinter will be reused as the default message.
 | ||||||
|  | func (s *SpinnerPrinter) Success(message ...interface{}) { | ||||||
|  | 	if s.SuccessPrinter == nil { | ||||||
|  | 		s.SuccessPrinter = &Success | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if len(message) == 0 { | ||||||
|  | 		message = []interface{}{s.Text} | ||||||
|  | 	} | ||||||
|  | 	clearLine() | ||||||
|  | 	Printo(s.SuccessPrinter.Sprint(message...)) | ||||||
|  | 	_ = s.Stop() | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Fail displays the fail printer.
 | ||||||
|  | // If no message is given, the text of the SpinnerPrinter will be reused as the default message.
 | ||||||
|  | func (s *SpinnerPrinter) Fail(message ...interface{}) { | ||||||
|  | 	if s.FailPrinter == nil { | ||||||
|  | 		s.FailPrinter = &Error | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if len(message) == 0 { | ||||||
|  | 		message = []interface{}{s.Text} | ||||||
|  | 	} | ||||||
|  | 	clearLine() | ||||||
|  | 	Printo(s.FailPrinter.Sprint(message...)) | ||||||
|  | 	_ = s.Stop() | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Warning displays the warning printer.
 | ||||||
|  | // If no message is given, the text of the SpinnerPrinter will be reused as the default message.
 | ||||||
|  | func (s *SpinnerPrinter) Warning(message ...interface{}) { | ||||||
|  | 	if s.WarningPrinter == nil { | ||||||
|  | 		s.WarningPrinter = &Warning | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if len(message) == 0 { | ||||||
|  | 		message = []interface{}{s.Text} | ||||||
|  | 	} | ||||||
|  | 	clearLine() | ||||||
|  | 	Printo(s.WarningPrinter.Sprint(message...)) | ||||||
|  | 	_ = s.Stop() | ||||||
|  | } | ||||||
							
								
								
									
										168
									
								
								vendor/github.com/pterm/pterm/table_printer.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										168
									
								
								vendor/github.com/pterm/pterm/table_printer.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,168 @@ | |||||||
|  | package pterm | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"encoding/csv" | ||||||
|  | 	"strings" | ||||||
|  | 	"unicode/utf8" | ||||||
|  | 
 | ||||||
|  | 	"github.com/pterm/pterm/internal" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // DefaultTable contains standards, which can be used to print a TablePrinter.
 | ||||||
|  | var DefaultTable = TablePrinter{ | ||||||
|  | 	Style:          &ThemeDefault.TableStyle, | ||||||
|  | 	HeaderStyle:    &ThemeDefault.TableHeaderStyle, | ||||||
|  | 	Separator:      " | ", | ||||||
|  | 	SeparatorStyle: &ThemeDefault.TableSeparatorStyle, | ||||||
|  | 	LeftAlignment:  true, | ||||||
|  | 	RightAlignment: false, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // TableData is the type that contains the data of a TablePrinter.
 | ||||||
|  | type TableData [][]string | ||||||
|  | 
 | ||||||
|  | // TablePrinter is able to render tables.
 | ||||||
|  | type TablePrinter struct { | ||||||
|  | 	Style          *Style | ||||||
|  | 	HasHeader      bool | ||||||
|  | 	HeaderStyle    *Style | ||||||
|  | 	Separator      string | ||||||
|  | 	SeparatorStyle *Style | ||||||
|  | 	Data           TableData | ||||||
|  | 	Boxed          bool | ||||||
|  | 	LeftAlignment  bool | ||||||
|  | 	RightAlignment bool | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithStyle returns a new TablePrinter with a specific Style.
 | ||||||
|  | func (p TablePrinter) WithStyle(style *Style) *TablePrinter { | ||||||
|  | 	p.Style = style | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithHasHeader returns a new TablePrinter, where the first line is marked as a header.
 | ||||||
|  | func (p TablePrinter) WithHasHeader(b ...bool) *TablePrinter { | ||||||
|  | 	p.HasHeader = internal.WithBoolean(b) | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithHeaderStyle returns a new TablePrinter with a specific HeaderStyle.
 | ||||||
|  | func (p TablePrinter) WithHeaderStyle(style *Style) *TablePrinter { | ||||||
|  | 	p.HeaderStyle = style | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithSeparator returns a new TablePrinter with a specific separator.
 | ||||||
|  | func (p TablePrinter) WithSeparator(separator string) *TablePrinter { | ||||||
|  | 	p.Separator = separator | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithSeparatorStyle returns a new TablePrinter with a specific SeparatorStyle.
 | ||||||
|  | func (p TablePrinter) WithSeparatorStyle(style *Style) *TablePrinter { | ||||||
|  | 	p.SeparatorStyle = style | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithData returns a new TablePrinter with specific Data.
 | ||||||
|  | func (p TablePrinter) WithData(data [][]string) *TablePrinter { | ||||||
|  | 	p.Data = data | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithCSVReader return a new TablePrinter with specified Data extracted from CSV.
 | ||||||
|  | func (p TablePrinter) WithCSVReader(reader *csv.Reader) *TablePrinter { | ||||||
|  | 	if records, err := reader.ReadAll(); err == nil { | ||||||
|  | 		p.Data = records | ||||||
|  | 	} | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithBoxed returns a new TablePrinter with a box around the table.
 | ||||||
|  | func (p TablePrinter) WithBoxed(b ...bool) *TablePrinter { | ||||||
|  | 	p.Boxed = internal.WithBoolean(b) | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithLeftAlignment returns a new TablePrinter with left alignment.
 | ||||||
|  | func (p TablePrinter) WithLeftAlignment(b ...bool) *TablePrinter { | ||||||
|  | 	b2 := internal.WithBoolean(b) | ||||||
|  | 	p.LeftAlignment = b2 | ||||||
|  | 	p.RightAlignment = false | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithRightAlignment returns a new TablePrinter with right alignment.
 | ||||||
|  | func (p TablePrinter) WithRightAlignment(b ...bool) *TablePrinter { | ||||||
|  | 	b2 := internal.WithBoolean(b) | ||||||
|  | 	p.LeftAlignment = false | ||||||
|  | 	p.RightAlignment = b2 | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Srender renders the TablePrinter as a string.
 | ||||||
|  | func (p TablePrinter) Srender() (string, error) { | ||||||
|  | 	if p.Style == nil { | ||||||
|  | 		p.Style = NewStyle() | ||||||
|  | 	} | ||||||
|  | 	if p.SeparatorStyle == nil { | ||||||
|  | 		p.SeparatorStyle = NewStyle() | ||||||
|  | 	} | ||||||
|  | 	if p.HeaderStyle == nil { | ||||||
|  | 		p.HeaderStyle = NewStyle() | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	var ret string | ||||||
|  | 	maxColumnWidth := make(map[int]int) | ||||||
|  | 
 | ||||||
|  | 	for _, row := range p.Data { | ||||||
|  | 		for ci, column := range row { | ||||||
|  | 			columnLength := utf8.RuneCountInString(RemoveColorFromString(column)) | ||||||
|  | 			if columnLength > maxColumnWidth[ci] { | ||||||
|  | 				maxColumnWidth[ci] = columnLength | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	for ri, row := range p.Data { | ||||||
|  | 		for ci, column := range row { | ||||||
|  | 			columnString := p.createColumnString(column, maxColumnWidth[ci]) | ||||||
|  | 
 | ||||||
|  | 			if ci != len(row) && ci != 0 { | ||||||
|  | 				ret += p.Style.Sprint(p.SeparatorStyle.Sprint(p.Separator)) | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			if p.HasHeader && ri == 0 { | ||||||
|  | 				ret += p.Style.Sprint(p.HeaderStyle.Sprint(columnString)) | ||||||
|  | 			} else { | ||||||
|  | 				ret += p.Style.Sprint(columnString) | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		ret += "\n" | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	ret = strings.TrimSuffix(ret, "\n") | ||||||
|  | 
 | ||||||
|  | 	if p.Boxed { | ||||||
|  | 		ret = DefaultBox.Sprint(ret) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return ret, nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (p TablePrinter) createColumnString(data string, maxColumnWidth int) string { | ||||||
|  | 	columnLength := utf8.RuneCountInString(RemoveColorFromString(data)) | ||||||
|  | 	if p.RightAlignment { | ||||||
|  | 		return strings.Repeat(" ", maxColumnWidth-columnLength) + data | ||||||
|  | 	} | ||||||
|  | 	return data + strings.Repeat(" ", maxColumnWidth-columnLength) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Render prints the TablePrinter to the terminal.
 | ||||||
|  | func (p TablePrinter) Render() error { | ||||||
|  | 	s, _ := p.Srender() | ||||||
|  | 	Println(s) | ||||||
|  | 
 | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
							
								
								
									
										64
									
								
								vendor/github.com/pterm/pterm/terminal.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								vendor/github.com/pterm/pterm/terminal.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,64 @@ | |||||||
|  | package pterm | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"os" | ||||||
|  | 
 | ||||||
|  | 	"golang.org/x/term" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // FallbackTerminalWidth is the value used for GetTerminalWidth, if the actual width can not be detected
 | ||||||
|  | // You can override that value if necessary.
 | ||||||
|  | var FallbackTerminalWidth = 80 | ||||||
|  | 
 | ||||||
|  | // FallbackTerminalHeight is the value used for GetTerminalHeight, if the actual height can not be detected
 | ||||||
|  | // You can override that value if necessary.
 | ||||||
|  | var FallbackTerminalHeight = 10 | ||||||
|  | 
 | ||||||
|  | // forcedTerminalWidth, when set along with forcedTerminalHeight, forces the terminal width value.
 | ||||||
|  | var forcedTerminalWidth int = 0 | ||||||
|  | 
 | ||||||
|  | // forcedTerminalHeight, when set along with forcedTerminalWidth, forces the terminal height value.
 | ||||||
|  | var forcedTerminalHeight int = 0 | ||||||
|  | 
 | ||||||
|  | // GetTerminalWidth returns the terminal width of the active terminal.
 | ||||||
|  | func GetTerminalWidth() int { | ||||||
|  | 	if forcedTerminalWidth > 0 { | ||||||
|  | 		return forcedTerminalWidth | ||||||
|  | 	} | ||||||
|  | 	width, _, _ := GetTerminalSize() | ||||||
|  | 	return width | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // GetTerminalHeight returns the terminal height of the active terminal.
 | ||||||
|  | func GetTerminalHeight() int { | ||||||
|  | 	if forcedTerminalHeight > 0 { | ||||||
|  | 		return forcedTerminalHeight | ||||||
|  | 	} | ||||||
|  | 	_, height, _ := GetTerminalSize() | ||||||
|  | 	return height | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // GetTerminalSize returns the width and the height of the active terminal.
 | ||||||
|  | func GetTerminalSize() (width, height int, err error) { | ||||||
|  | 	if forcedTerminalWidth > 0 && forcedTerminalHeight > 0 { | ||||||
|  | 		return forcedTerminalWidth, forcedTerminalHeight, nil | ||||||
|  | 	} | ||||||
|  | 	w, h, err := term.GetSize(int(os.Stdout.Fd())) | ||||||
|  | 	if w <= 0 { | ||||||
|  | 		w = FallbackTerminalWidth | ||||||
|  | 	} | ||||||
|  | 	if h <= 0 { | ||||||
|  | 		h = FallbackTerminalHeight | ||||||
|  | 	} | ||||||
|  | 	if err != nil { | ||||||
|  | 		err = ErrTerminalSizeNotDetectable | ||||||
|  | 	} | ||||||
|  | 	return w, h, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // setForcedTerminalSize turns off terminal size autodetection. Usuful for unified tests.
 | ||||||
|  | func SetForcedTerminalSize(width int, height int) { | ||||||
|  | 	forcedTerminalWidth = width | ||||||
|  | 	forcedTerminalHeight = height | ||||||
|  | 	RecalculateTerminalSize() | ||||||
|  | } | ||||||
							
								
								
									
										246
									
								
								vendor/github.com/pterm/pterm/theme.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										246
									
								
								vendor/github.com/pterm/pterm/theme.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,246 @@ | |||||||
|  | package pterm | ||||||
|  | 
 | ||||||
|  | var ( | ||||||
|  | 	// ThemeDefault is the default theme used by PTerm.
 | ||||||
|  | 	// If this variable is overwritten, the new value is used as default theme.
 | ||||||
|  | 	ThemeDefault = Theme{ | ||||||
|  | 		PrimaryStyle:            Style{FgCyan}, | ||||||
|  | 		SecondaryStyle:          Style{FgLightMagenta}, | ||||||
|  | 		HighlightStyle:          Style{Bold, FgYellow}, | ||||||
|  | 		InfoMessageStyle:        Style{FgLightCyan}, | ||||||
|  | 		InfoPrefixStyle:         Style{FgBlack, BgCyan}, | ||||||
|  | 		SuccessMessageStyle:     Style{FgGreen}, | ||||||
|  | 		SuccessPrefixStyle:      Style{FgBlack, BgGreen}, | ||||||
|  | 		WarningMessageStyle:     Style{FgYellow}, | ||||||
|  | 		WarningPrefixStyle:      Style{FgBlack, BgYellow}, | ||||||
|  | 		ErrorMessageStyle:       Style{FgLightRed}, | ||||||
|  | 		ErrorPrefixStyle:        Style{FgBlack, BgLightRed}, | ||||||
|  | 		FatalMessageStyle:       Style{FgLightRed}, | ||||||
|  | 		FatalPrefixStyle:        Style{FgBlack, BgLightRed}, | ||||||
|  | 		DescriptionMessageStyle: Style{FgDefault}, | ||||||
|  | 		DescriptionPrefixStyle:  Style{FgLightWhite, BgDarkGray}, | ||||||
|  | 		ScopeStyle:              Style{FgGray}, | ||||||
|  | 		ProgressbarBarStyle:     Style{FgCyan}, | ||||||
|  | 		ProgressbarTitleStyle:   Style{FgLightCyan}, | ||||||
|  | 		HeaderTextStyle:         Style{FgLightWhite, Bold}, | ||||||
|  | 		HeaderBackgroundStyle:   Style{BgGray}, | ||||||
|  | 		SpinnerStyle:            Style{FgLightCyan}, | ||||||
|  | 		SpinnerTextStyle:        Style{FgLightWhite}, | ||||||
|  | 		TableStyle:              Style{FgDefault}, | ||||||
|  | 		TableHeaderStyle:        Style{FgLightCyan}, | ||||||
|  | 		TableSeparatorStyle:     Style{FgGray}, | ||||||
|  | 		SectionStyle:            Style{Bold, FgYellow}, | ||||||
|  | 		BulletListTextStyle:     Style{FgDefault}, | ||||||
|  | 		BulletListBulletStyle:   Style{FgGray}, | ||||||
|  | 		TreeStyle:               Style{FgGray}, | ||||||
|  | 		TreeTextStyle:           Style{FgDefault}, | ||||||
|  | 		LetterStyle:             Style{FgDefault}, | ||||||
|  | 		DebugMessageStyle:       Style{FgGray}, | ||||||
|  | 		DebugPrefixStyle:        Style{FgBlack, BgGray}, | ||||||
|  | 		BoxStyle:                Style{FgDefault}, | ||||||
|  | 		BoxTextStyle:            Style{FgDefault}, | ||||||
|  | 		BarLabelStyle:           Style{FgLightCyan}, | ||||||
|  | 		BarStyle:                Style{FgCyan}, | ||||||
|  | 		TimerStyle:              Style{FgGray}, | ||||||
|  | 	} | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // Theme for PTerm.
 | ||||||
|  | // Theme contains every Style used in PTerm. You can create own themes for your application or use one
 | ||||||
|  | // of the existing themes.
 | ||||||
|  | type Theme struct { | ||||||
|  | 	PrimaryStyle            Style | ||||||
|  | 	SecondaryStyle          Style | ||||||
|  | 	HighlightStyle          Style | ||||||
|  | 	InfoMessageStyle        Style | ||||||
|  | 	InfoPrefixStyle         Style | ||||||
|  | 	SuccessMessageStyle     Style | ||||||
|  | 	SuccessPrefixStyle      Style | ||||||
|  | 	WarningMessageStyle     Style | ||||||
|  | 	WarningPrefixStyle      Style | ||||||
|  | 	ErrorMessageStyle       Style | ||||||
|  | 	ErrorPrefixStyle        Style | ||||||
|  | 	FatalMessageStyle       Style | ||||||
|  | 	FatalPrefixStyle        Style | ||||||
|  | 	DescriptionMessageStyle Style | ||||||
|  | 	DescriptionPrefixStyle  Style | ||||||
|  | 	ScopeStyle              Style | ||||||
|  | 	ProgressbarBarStyle     Style | ||||||
|  | 	ProgressbarTitleStyle   Style | ||||||
|  | 	HeaderTextStyle         Style | ||||||
|  | 	HeaderBackgroundStyle   Style | ||||||
|  | 	SpinnerStyle            Style | ||||||
|  | 	SpinnerTextStyle        Style | ||||||
|  | 	TimerStyle              Style | ||||||
|  | 	TableStyle              Style | ||||||
|  | 	TableHeaderStyle        Style | ||||||
|  | 	TableSeparatorStyle     Style | ||||||
|  | 	SectionStyle            Style | ||||||
|  | 	BulletListTextStyle     Style | ||||||
|  | 	BulletListBulletStyle   Style | ||||||
|  | 	TreeStyle               Style | ||||||
|  | 	TreeTextStyle           Style | ||||||
|  | 	LetterStyle             Style | ||||||
|  | 	DebugMessageStyle       Style | ||||||
|  | 	DebugPrefixStyle        Style | ||||||
|  | 	BoxStyle                Style | ||||||
|  | 	BoxTextStyle            Style | ||||||
|  | 	BarLabelStyle           Style | ||||||
|  | 	BarStyle                Style | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithPrimaryStyle returns a new theme with overridden value.
 | ||||||
|  | func (t Theme) WithPrimaryStyle(style Style) Theme { | ||||||
|  | 	t.PrimaryStyle = style | ||||||
|  | 	return t | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithSecondaryStyle returns a new theme with overridden value.
 | ||||||
|  | func (t Theme) WithSecondaryStyle(style Style) Theme { | ||||||
|  | 	t.SecondaryStyle = style | ||||||
|  | 	return t | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithHighlightStyle returns a new theme with overridden value.
 | ||||||
|  | func (t Theme) WithHighlightStyle(style Style) Theme { | ||||||
|  | 	t.HighlightStyle = style | ||||||
|  | 	return t | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithInfoMessageStyle returns a new theme with overridden value.
 | ||||||
|  | func (t Theme) WithInfoMessageStyle(style Style) Theme { | ||||||
|  | 	t.InfoMessageStyle = style | ||||||
|  | 	return t | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithInfoPrefixStyle returns a new theme with overridden value.
 | ||||||
|  | func (t Theme) WithInfoPrefixStyle(style Style) Theme { | ||||||
|  | 	t.InfoPrefixStyle = style | ||||||
|  | 	return t | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithSuccessMessageStyle returns a new theme with overridden value.
 | ||||||
|  | func (t Theme) WithSuccessMessageStyle(style Style) Theme { | ||||||
|  | 	t.SuccessMessageStyle = style | ||||||
|  | 	return t | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithSuccessPrefixStyle returns a new theme with overridden value.
 | ||||||
|  | func (t Theme) WithSuccessPrefixStyle(style Style) Theme { | ||||||
|  | 	t.SuccessPrefixStyle = style | ||||||
|  | 	return t | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithWarningMessageStyle returns a new theme with overridden value.
 | ||||||
|  | func (t Theme) WithWarningMessageStyle(style Style) Theme { | ||||||
|  | 	t.WarningMessageStyle = style | ||||||
|  | 	return t | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithWarningPrefixStyle returns a new theme with overridden value.
 | ||||||
|  | func (t Theme) WithWarningPrefixStyle(style Style) Theme { | ||||||
|  | 	t.WarningPrefixStyle = style | ||||||
|  | 	return t | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithErrorMessageStyle returns a new theme with overridden value.
 | ||||||
|  | func (t Theme) WithErrorMessageStyle(style Style) Theme { | ||||||
|  | 	t.ErrorMessageStyle = style | ||||||
|  | 	return t | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithErrorPrefixStyle returns a new theme with overridden value.
 | ||||||
|  | func (t Theme) WithErrorPrefixStyle(style Style) Theme { | ||||||
|  | 	t.ErrorPrefixStyle = style | ||||||
|  | 	return t | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithFatalMessageStyle returns a new theme with overridden value.
 | ||||||
|  | func (t Theme) WithFatalMessageStyle(style Style) Theme { | ||||||
|  | 	t.FatalMessageStyle = style | ||||||
|  | 	return t | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithFatalPrefixStyle returns a new theme with overridden value.
 | ||||||
|  | func (t Theme) WithFatalPrefixStyle(style Style) Theme { | ||||||
|  | 	t.FatalPrefixStyle = style | ||||||
|  | 	return t | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithDescriptionMessageStyle returns a new theme with overridden value.
 | ||||||
|  | func (t Theme) WithDescriptionMessageStyle(style Style) Theme { | ||||||
|  | 	t.DescriptionMessageStyle = style | ||||||
|  | 	return t | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithDescriptionPrefixStyle returns a new theme with overridden value.
 | ||||||
|  | func (t Theme) WithDescriptionPrefixStyle(style Style) Theme { | ||||||
|  | 	t.DescriptionPrefixStyle = style | ||||||
|  | 	return t | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithBulletListTextStyle returns a new theme with overridden value.
 | ||||||
|  | func (t Theme) WithBulletListTextStyle(style Style) Theme { | ||||||
|  | 	t.BulletListTextStyle = style | ||||||
|  | 	return t | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithBulletListBulletStyle returns a new theme with overridden value.
 | ||||||
|  | func (t Theme) WithBulletListBulletStyle(style Style) Theme { | ||||||
|  | 	t.BulletListBulletStyle = style | ||||||
|  | 	return t | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithLetterStyle returns a new theme with overridden value.
 | ||||||
|  | func (t Theme) WithLetterStyle(style Style) Theme { | ||||||
|  | 	t.LetterStyle = style | ||||||
|  | 	return t | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithDebugMessageStyle returns a new theme with overridden value.
 | ||||||
|  | func (t Theme) WithDebugMessageStyle(style Style) Theme { | ||||||
|  | 	t.DebugMessageStyle = style | ||||||
|  | 	return t | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithDebugPrefixStyle returns a new theme with overridden value.
 | ||||||
|  | func (t Theme) WithDebugPrefixStyle(style Style) Theme { | ||||||
|  | 	t.DebugPrefixStyle = style | ||||||
|  | 	return t | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithTreeStyle returns a new theme with overridden value.
 | ||||||
|  | func (t Theme) WithTreeStyle(style Style) Theme { | ||||||
|  | 	t.TreeStyle = style | ||||||
|  | 	return t | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithTreeTextStyle returns a new theme with overridden value.
 | ||||||
|  | func (t Theme) WithTreeTextStyle(style Style) Theme { | ||||||
|  | 	t.TreeTextStyle = style | ||||||
|  | 	return t | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithBoxStyle returns a new theme with overridden value.
 | ||||||
|  | func (t Theme) WithBoxStyle(style Style) Theme { | ||||||
|  | 	t.BoxStyle = style | ||||||
|  | 	return t | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithBoxTextStyle returns a new theme with overridden value.
 | ||||||
|  | func (t Theme) WithBoxTextStyle(style Style) Theme { | ||||||
|  | 	t.BoxTextStyle = style | ||||||
|  | 	return t | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithBarLabelStyle returns a new theme with overridden value.
 | ||||||
|  | func (t Theme) WithBarLabelStyle(style Style) Theme { | ||||||
|  | 	t.BarLabelStyle = style | ||||||
|  | 	return t | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithBarStyle returns a new theme with overridden value.
 | ||||||
|  | func (t Theme) WithBarStyle(style Style) Theme { | ||||||
|  | 	t.BarStyle = style | ||||||
|  | 	return t | ||||||
|  | } | ||||||
							
								
								
									
										185
									
								
								vendor/github.com/pterm/pterm/tree_printer.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										185
									
								
								vendor/github.com/pterm/pterm/tree_printer.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,185 @@ | |||||||
|  | package pterm | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"strings" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // TreeNode is used as items in a TreePrinter.
 | ||||||
|  | type TreeNode struct { | ||||||
|  | 	Children []TreeNode | ||||||
|  | 	Text     string | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // LeveledList is a list, which contains multiple LeveledListItem.
 | ||||||
|  | type LeveledList []LeveledListItem | ||||||
|  | 
 | ||||||
|  | // LeveledListItem combines a text with a specific level.
 | ||||||
|  | // The level is the indent, which would normally be seen in a BulletListPrinter.
 | ||||||
|  | type LeveledListItem struct { | ||||||
|  | 	Level int | ||||||
|  | 	Text  string | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // DefaultTree contains standards, which can be used to render a TreePrinter.
 | ||||||
|  | var DefaultTree = TreePrinter{ | ||||||
|  | 	TreeStyle:            &ThemeDefault.TreeStyle, | ||||||
|  | 	TextStyle:            &ThemeDefault.TreeTextStyle, | ||||||
|  | 	TopRightCornerString: "└", | ||||||
|  | 	HorizontalString:     "─", | ||||||
|  | 	TopRightDownString:   "├", | ||||||
|  | 	VerticalString:       "│", | ||||||
|  | 	RightDownLeftString:  "┬", | ||||||
|  | 	Indent:               2, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // TreePrinter is able to render a list.
 | ||||||
|  | type TreePrinter struct { | ||||||
|  | 	Root                 TreeNode | ||||||
|  | 	TreeStyle            *Style | ||||||
|  | 	TextStyle            *Style | ||||||
|  | 	TopRightCornerString string | ||||||
|  | 	TopRightDownString   string | ||||||
|  | 	HorizontalString     string | ||||||
|  | 	VerticalString       string | ||||||
|  | 	RightDownLeftString  string | ||||||
|  | 	Indent               int | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithTreeStyle returns a new list with a specific tree style.
 | ||||||
|  | func (p TreePrinter) WithTreeStyle(style *Style) *TreePrinter { | ||||||
|  | 	p.TreeStyle = style | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithTextStyle returns a new list with a specific text style.
 | ||||||
|  | func (p TreePrinter) WithTextStyle(style *Style) *TreePrinter { | ||||||
|  | 	p.TextStyle = style | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithTopRightCornerString returns a new list with a specific TopRightCornerString.
 | ||||||
|  | func (p TreePrinter) WithTopRightCornerString(s string) *TreePrinter { | ||||||
|  | 	p.TopRightCornerString = s | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithTopRightDownStringOngoing returns a new list with a specific TopRightDownString.
 | ||||||
|  | func (p TreePrinter) WithTopRightDownStringOngoing(s string) *TreePrinter { | ||||||
|  | 	p.TopRightDownString = s | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithHorizontalString returns a new list with a specific HorizontalString.
 | ||||||
|  | func (p TreePrinter) WithHorizontalString(s string) *TreePrinter { | ||||||
|  | 	p.HorizontalString = s | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithVerticalString returns a new list with a specific VerticalString.
 | ||||||
|  | func (p TreePrinter) WithVerticalString(s string) *TreePrinter { | ||||||
|  | 	p.VerticalString = s | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithRoot returns a new list with a specific Root.
 | ||||||
|  | func (p TreePrinter) WithRoot(root TreeNode) *TreePrinter { | ||||||
|  | 	p.Root = root | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithIndent returns a new list with a specific amount of spacing between the levels.
 | ||||||
|  | // Indent must be at least 1.
 | ||||||
|  | func (p TreePrinter) WithIndent(indent int) *TreePrinter { | ||||||
|  | 	if indent < 1 { | ||||||
|  | 		indent = 1 | ||||||
|  | 	} | ||||||
|  | 	p.Indent = indent | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Render prints the list to the terminal.
 | ||||||
|  | func (p TreePrinter) Render() error { | ||||||
|  | 	s, _ := p.Srender() | ||||||
|  | 	Println(s) | ||||||
|  | 
 | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Srender renders the list as a string.
 | ||||||
|  | func (p TreePrinter) Srender() (string, error) { | ||||||
|  | 	if p.TreeStyle == nil { | ||||||
|  | 		p.TreeStyle = NewStyle() | ||||||
|  | 	} | ||||||
|  | 	if p.TextStyle == nil { | ||||||
|  | 		p.TextStyle = NewStyle() | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return walkOverTree(p.Root.Children, p, ""), nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // walkOverTree is a recursive function,
 | ||||||
|  | // which analyzes a TreePrinter and connects the items with specific characters.
 | ||||||
|  | // Returns TreePrinter as string.
 | ||||||
|  | func walkOverTree(list []TreeNode, p TreePrinter, prefix string) string { | ||||||
|  | 	var ret string | ||||||
|  | 	for i, item := range list { | ||||||
|  | 		if len(list) > i+1 { // if not last in list
 | ||||||
|  | 			if len(item.Children) == 0 { // if there are no children
 | ||||||
|  | 				ret += prefix + p.TreeStyle.Sprint(p.TopRightDownString) + strings.Repeat(p.TreeStyle.Sprint(p.HorizontalString), p.Indent) + | ||||||
|  | 					p.TextStyle.Sprint(item.Text) + "\n" | ||||||
|  | 			} else { // if there are children
 | ||||||
|  | 				ret += prefix + p.TreeStyle.Sprint(p.TopRightDownString) + strings.Repeat(p.TreeStyle.Sprint(p.HorizontalString), p.Indent-1) + | ||||||
|  | 					p.TreeStyle.Sprint(p.RightDownLeftString) + p.TextStyle.Sprint(item.Text) + "\n" | ||||||
|  | 				ret += walkOverTree(item.Children, p, prefix+p.TreeStyle.Sprint(p.VerticalString)+strings.Repeat(" ", p.Indent-1)) | ||||||
|  | 			} | ||||||
|  | 		} else if len(list) == i+1 { // if last in list
 | ||||||
|  | 			if len(item.Children) == 0 { // if there are no children
 | ||||||
|  | 				ret += prefix + p.TreeStyle.Sprint(p.TopRightCornerString) + strings.Repeat(p.TreeStyle.Sprint(p.HorizontalString), p.Indent) + | ||||||
|  | 					p.TextStyle.Sprint(item.Text) + "\n" | ||||||
|  | 			} else { // if there are children
 | ||||||
|  | 				ret += prefix + p.TreeStyle.Sprint(p.TopRightCornerString) + strings.Repeat(p.TreeStyle.Sprint(p.HorizontalString), p.Indent-1) + | ||||||
|  | 					p.TreeStyle.Sprint(p.RightDownLeftString) + p.TextStyle.Sprint(item.Text) + "\n" | ||||||
|  | 				ret += walkOverTree(item.Children, p, prefix+strings.Repeat(" ", p.Indent)) | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return ret | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // NewTreeFromLeveledList converts a TreeItems list to a TreeNode and returns it.
 | ||||||
|  | func NewTreeFromLeveledList(leveledListItems LeveledList) TreeNode { | ||||||
|  | 	if len(leveledListItems) == 0 { | ||||||
|  | 		return TreeNode{} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	root := &TreeNode{ | ||||||
|  | 		Children: []TreeNode{}, | ||||||
|  | 		Text:     leveledListItems[0].Text, | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	for i, record := range leveledListItems { | ||||||
|  | 		last := root | ||||||
|  | 
 | ||||||
|  | 		if record.Level < 0 { | ||||||
|  | 			record.Level = 0 | ||||||
|  | 			leveledListItems[i].Level = 0 | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if len(leveledListItems)-1 != i { | ||||||
|  | 			if leveledListItems[i+1].Level-1 > record.Level { | ||||||
|  | 				leveledListItems[i+1].Level = record.Level + 1 | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		for i := 0; i < record.Level; i++ { | ||||||
|  | 			lastIndex := len(last.Children) - 1 | ||||||
|  | 			last = &last.Children[lastIndex] | ||||||
|  | 		} | ||||||
|  | 		last.Children = append(last.Children, TreeNode{ | ||||||
|  | 			Children: []TreeNode{}, | ||||||
|  | 			Text:     record.Text, | ||||||
|  | 		}) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return *root | ||||||
|  | } | ||||||
							
								
								
									
										21
									
								
								vendor/github.com/rivo/uniseg/LICENSE.txt
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								vendor/github.com/rivo/uniseg/LICENSE.txt
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,21 @@ | |||||||
|  | MIT License | ||||||
|  | 
 | ||||||
|  | Copyright (c) 2019 Oliver Kuederle | ||||||
|  | 
 | ||||||
|  | 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. | ||||||
							
								
								
									
										62
									
								
								vendor/github.com/rivo/uniseg/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								vendor/github.com/rivo/uniseg/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,62 @@ | |||||||
|  | # Unicode Text Segmentation for Go | ||||||
|  | 
 | ||||||
|  | [](https://godoc.org/github.com/rivo/uniseg) | ||||||
|  | [](https://goreportcard.com/report/github.com/rivo/uniseg) | ||||||
|  | 
 | ||||||
|  | This Go package implements Unicode Text Segmentation according to [Unicode Standard Annex #29](http://unicode.org/reports/tr29/) (Unicode version 12.0.0). | ||||||
|  | 
 | ||||||
|  | At this point, only the determination of grapheme cluster boundaries is implemented. | ||||||
|  | 
 | ||||||
|  | ## Background | ||||||
|  | 
 | ||||||
|  | In Go, [strings are read-only slices of bytes](https://blog.golang.org/strings). They can be turned into Unicode code points using the `for` loop or by casting: `[]rune(str)`. However, multiple code points may be combined into one user-perceived character or what the Unicode specification calls "grapheme cluster". Here are some examples: | ||||||
|  | 
 | ||||||
|  | |String|Bytes (UTF-8)|Code points (runes)|Grapheme clusters| | ||||||
|  | |-|-|-|-| | ||||||
|  | |Käse|6 bytes: `4b 61 cc 88 73 65`|5 code points: `4b 61 308 73 65`|4 clusters: `[4b],[61 308],[73],[65]`| | ||||||
|  | |🏳️🌈|14 bytes: `f0 9f 8f b3 ef b8 8f e2 80 8d f0 9f 8c 88`|4 code points: `1f3f3 fe0f 200d 1f308`|1 cluster: `[1f3f3 fe0f 200d 1f308]`| | ||||||
|  | |🇩🇪|8 bytes: `f0 9f 87 a9 f0 9f 87 aa`|2 code points: `1f1e9 1f1ea`|1 cluster: `[1f1e9 1f1ea]`| | ||||||
|  | 
 | ||||||
|  | This package provides a tool to iterate over these grapheme clusters. This may be used to determine the number of user-perceived characters, to split strings in their intended places, or to extract individual characters which form a unit. | ||||||
|  | 
 | ||||||
|  | ## Installation | ||||||
|  | 
 | ||||||
|  | ```bash | ||||||
|  | go get github.com/rivo/uniseg | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ## Basic Example | ||||||
|  | 
 | ||||||
|  | ```go | ||||||
|  | package uniseg | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  | 
 | ||||||
|  | 	"github.com/rivo/uniseg" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | func main() { | ||||||
|  | 	gr := uniseg.NewGraphemes("👍🏼!") | ||||||
|  | 	for gr.Next() { | ||||||
|  | 		fmt.Printf("%x ", gr.Runes()) | ||||||
|  | 	} | ||||||
|  | 	// Output: [1f44d 1f3fc] [21] | ||||||
|  | } | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ## Documentation | ||||||
|  | 
 | ||||||
|  | Refer to https://godoc.org/github.com/rivo/uniseg for the package's documentation. | ||||||
|  | 
 | ||||||
|  | ## Dependencies | ||||||
|  | 
 | ||||||
|  | This package does not depend on any packages outside the standard library. | ||||||
|  | 
 | ||||||
|  | ## Your Feedback | ||||||
|  | 
 | ||||||
|  | Add your issue here on GitHub. Feel free to get in touch if you have any questions. | ||||||
|  | 
 | ||||||
|  | ## Version | ||||||
|  | 
 | ||||||
|  | Version tags will be introduced once Golang modules are official. Consider this version 0.1. | ||||||
							
								
								
									
										8
									
								
								vendor/github.com/rivo/uniseg/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								vendor/github.com/rivo/uniseg/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,8 @@ | |||||||
|  | /* | ||||||
|  | Package uniseg implements Unicode Text Segmentation according to Unicode | ||||||
|  | Standard Annex #29 (http://unicode.org/reports/tr29/).
 | ||||||
|  | 
 | ||||||
|  | At this point, only the determination of grapheme cluster boundaries is | ||||||
|  | implemented. | ||||||
|  | */ | ||||||
|  | package uniseg | ||||||
							
								
								
									
										3
									
								
								vendor/github.com/rivo/uniseg/go.mod
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								vendor/github.com/rivo/uniseg/go.mod
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,3 @@ | |||||||
|  | module github.com/rivo/uniseg | ||||||
|  | 
 | ||||||
|  | go 1.12 | ||||||
							
								
								
									
										268
									
								
								vendor/github.com/rivo/uniseg/grapheme.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										268
									
								
								vendor/github.com/rivo/uniseg/grapheme.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,268 @@ | |||||||
|  | package uniseg | ||||||
|  | 
 | ||||||
|  | import "unicode/utf8" | ||||||
|  | 
 | ||||||
|  | // The states of the grapheme cluster parser.
 | ||||||
|  | const ( | ||||||
|  | 	grAny = iota | ||||||
|  | 	grCR | ||||||
|  | 	grControlLF | ||||||
|  | 	grL | ||||||
|  | 	grLVV | ||||||
|  | 	grLVTT | ||||||
|  | 	grPrepend | ||||||
|  | 	grExtendedPictographic | ||||||
|  | 	grExtendedPictographicZWJ | ||||||
|  | 	grRIOdd | ||||||
|  | 	grRIEven | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // The grapheme cluster parser's breaking instructions.
 | ||||||
|  | const ( | ||||||
|  | 	grNoBoundary = iota | ||||||
|  | 	grBoundary | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // The grapheme cluster parser's state transitions. Maps (state, property) to
 | ||||||
|  | // (new state, breaking instruction, rule number). The breaking instruction
 | ||||||
|  | // always refers to the boundary between the last and next code point.
 | ||||||
|  | //
 | ||||||
|  | // This map is queried as follows:
 | ||||||
|  | //
 | ||||||
|  | //   1. Find specific state + specific property. Stop if found.
 | ||||||
|  | //   2. Find specific state + any property.
 | ||||||
|  | //   3. Find any state + specific property.
 | ||||||
|  | //   4. If only (2) or (3) (but not both) was found, stop.
 | ||||||
|  | //   5. If both (2) and (3) were found, use state and breaking instruction from
 | ||||||
|  | //      the transition with the lower rule number, prefer (3) if rule numbers
 | ||||||
|  | //      are equal. Stop.
 | ||||||
|  | //   6. Assume grAny and grBoundary.
 | ||||||
|  | var grTransitions = map[[2]int][3]int{ | ||||||
|  | 	// GB5
 | ||||||
|  | 	{grAny, prCR}:      {grCR, grBoundary, 50}, | ||||||
|  | 	{grAny, prLF}:      {grControlLF, grBoundary, 50}, | ||||||
|  | 	{grAny, prControl}: {grControlLF, grBoundary, 50}, | ||||||
|  | 
 | ||||||
|  | 	// GB4
 | ||||||
|  | 	{grCR, prAny}:        {grAny, grBoundary, 40}, | ||||||
|  | 	{grControlLF, prAny}: {grAny, grBoundary, 40}, | ||||||
|  | 
 | ||||||
|  | 	// GB3.
 | ||||||
|  | 	{grCR, prLF}: {grAny, grNoBoundary, 30}, | ||||||
|  | 
 | ||||||
|  | 	// GB6.
 | ||||||
|  | 	{grAny, prL}: {grL, grBoundary, 9990}, | ||||||
|  | 	{grL, prL}:   {grL, grNoBoundary, 60}, | ||||||
|  | 	{grL, prV}:   {grLVV, grNoBoundary, 60}, | ||||||
|  | 	{grL, prLV}:  {grLVV, grNoBoundary, 60}, | ||||||
|  | 	{grL, prLVT}: {grLVTT, grNoBoundary, 60}, | ||||||
|  | 
 | ||||||
|  | 	// GB7.
 | ||||||
|  | 	{grAny, prLV}: {grLVV, grBoundary, 9990}, | ||||||
|  | 	{grAny, prV}:  {grLVV, grBoundary, 9990}, | ||||||
|  | 	{grLVV, prV}:  {grLVV, grNoBoundary, 70}, | ||||||
|  | 	{grLVV, prT}:  {grLVTT, grNoBoundary, 70}, | ||||||
|  | 
 | ||||||
|  | 	// GB8.
 | ||||||
|  | 	{grAny, prLVT}: {grLVTT, grBoundary, 9990}, | ||||||
|  | 	{grAny, prT}:   {grLVTT, grBoundary, 9990}, | ||||||
|  | 	{grLVTT, prT}:  {grLVTT, grNoBoundary, 80}, | ||||||
|  | 
 | ||||||
|  | 	// GB9.
 | ||||||
|  | 	{grAny, prExtend}: {grAny, grNoBoundary, 90}, | ||||||
|  | 	{grAny, prZWJ}:    {grAny, grNoBoundary, 90}, | ||||||
|  | 
 | ||||||
|  | 	// GB9a.
 | ||||||
|  | 	{grAny, prSpacingMark}: {grAny, grNoBoundary, 91}, | ||||||
|  | 
 | ||||||
|  | 	// GB9b.
 | ||||||
|  | 	{grAny, prPreprend}: {grPrepend, grBoundary, 9990}, | ||||||
|  | 	{grPrepend, prAny}:  {grAny, grNoBoundary, 92}, | ||||||
|  | 
 | ||||||
|  | 	// GB11.
 | ||||||
|  | 	{grAny, prExtendedPictographic}:                     {grExtendedPictographic, grBoundary, 9990}, | ||||||
|  | 	{grExtendedPictographic, prExtend}:                  {grExtendedPictographic, grNoBoundary, 110}, | ||||||
|  | 	{grExtendedPictographic, prZWJ}:                     {grExtendedPictographicZWJ, grNoBoundary, 110}, | ||||||
|  | 	{grExtendedPictographicZWJ, prExtendedPictographic}: {grExtendedPictographic, grNoBoundary, 110}, | ||||||
|  | 
 | ||||||
|  | 	// GB12 / GB13.
 | ||||||
|  | 	{grAny, prRegionalIndicator}:    {grRIOdd, grBoundary, 9990}, | ||||||
|  | 	{grRIOdd, prRegionalIndicator}:  {grRIEven, grNoBoundary, 120}, | ||||||
|  | 	{grRIEven, prRegionalIndicator}: {grRIOdd, grBoundary, 120}, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Graphemes implements an iterator over Unicode extended grapheme clusters,
 | ||||||
|  | // specified in the Unicode Standard Annex #29. Grapheme clusters correspond to
 | ||||||
|  | // "user-perceived characters". These characters often consist of multiple
 | ||||||
|  | // code points (e.g. the "woman kissing woman" emoji consists of 8 code points:
 | ||||||
|  | // woman + ZWJ + heavy black heart (2 code points) + ZWJ + kiss mark + ZWJ +
 | ||||||
|  | // woman) and the rules described in Annex #29 must be applied to group those
 | ||||||
|  | // code points into clusters perceived by the user as one character.
 | ||||||
|  | type Graphemes struct { | ||||||
|  | 	// The code points over which this class iterates.
 | ||||||
|  | 	codePoints []rune | ||||||
|  | 
 | ||||||
|  | 	// The (byte-based) indices of the code points into the original string plus
 | ||||||
|  | 	// len(original string). Thus, len(indices) = len(codePoints) + 1.
 | ||||||
|  | 	indices []int | ||||||
|  | 
 | ||||||
|  | 	// The current grapheme cluster to be returned. These are indices into
 | ||||||
|  | 	// codePoints/indices. If start == end, we either haven't started iterating
 | ||||||
|  | 	// yet (0) or the iteration has already completed (1).
 | ||||||
|  | 	start, end int | ||||||
|  | 
 | ||||||
|  | 	// The index of the next code point to be parsed.
 | ||||||
|  | 	pos int | ||||||
|  | 
 | ||||||
|  | 	// The current state of the code point parser.
 | ||||||
|  | 	state int | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // NewGraphemes returns a new grapheme cluster iterator.
 | ||||||
|  | func NewGraphemes(s string) *Graphemes { | ||||||
|  | 	l := utf8.RuneCountInString(s) | ||||||
|  | 	codePoints := make([]rune, l) | ||||||
|  | 	indices := make([]int, l+1) | ||||||
|  | 	i := 0 | ||||||
|  | 	for pos, r := range s { | ||||||
|  | 		codePoints[i] = r | ||||||
|  | 		indices[i] = pos | ||||||
|  | 		i++ | ||||||
|  | 	} | ||||||
|  | 	indices[l] = len(s) | ||||||
|  | 	g := &Graphemes{ | ||||||
|  | 		codePoints: codePoints, | ||||||
|  | 		indices:    indices, | ||||||
|  | 	} | ||||||
|  | 	g.Next() // Parse ahead.
 | ||||||
|  | 	return g | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Next advances the iterator by one grapheme cluster and returns false if no
 | ||||||
|  | // clusters are left. This function must be called before the first cluster is
 | ||||||
|  | // accessed.
 | ||||||
|  | func (g *Graphemes) Next() bool { | ||||||
|  | 	g.start = g.end | ||||||
|  | 
 | ||||||
|  | 	// The state transition gives us a boundary instruction BEFORE the next code
 | ||||||
|  | 	// point so we always need to stay ahead by one code point.
 | ||||||
|  | 
 | ||||||
|  | 	// Parse the next code point.
 | ||||||
|  | 	for g.pos <= len(g.codePoints) { | ||||||
|  | 		// GB2.
 | ||||||
|  | 		if g.pos == len(g.codePoints) { | ||||||
|  | 			g.end = g.pos | ||||||
|  | 			g.pos++ | ||||||
|  | 			break | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		// Determine the property of the next character.
 | ||||||
|  | 		nextProperty := property(g.codePoints[g.pos]) | ||||||
|  | 		g.pos++ | ||||||
|  | 
 | ||||||
|  | 		// Find the applicable transition.
 | ||||||
|  | 		var boundary bool | ||||||
|  | 		transition, ok := grTransitions[[2]int{g.state, nextProperty}] | ||||||
|  | 		if ok { | ||||||
|  | 			// We have a specific transition. We'll use it.
 | ||||||
|  | 			g.state = transition[0] | ||||||
|  | 			boundary = transition[1] == grBoundary | ||||||
|  | 		} else { | ||||||
|  | 			// No specific transition found. Try the less specific ones.
 | ||||||
|  | 			transAnyProp, okAnyProp := grTransitions[[2]int{g.state, prAny}] | ||||||
|  | 			transAnyState, okAnyState := grTransitions[[2]int{grAny, nextProperty}] | ||||||
|  | 			if okAnyProp && okAnyState { | ||||||
|  | 				// Both apply. We'll use a mix (see comments for grTransitions).
 | ||||||
|  | 				g.state = transAnyState[0] | ||||||
|  | 				boundary = transAnyState[1] == grBoundary | ||||||
|  | 				if transAnyProp[2] < transAnyState[2] { | ||||||
|  | 					g.state = transAnyProp[0] | ||||||
|  | 					boundary = transAnyProp[1] == grBoundary | ||||||
|  | 				} | ||||||
|  | 			} else if okAnyProp { | ||||||
|  | 				// We only have a specific state.
 | ||||||
|  | 				g.state = transAnyProp[0] | ||||||
|  | 				boundary = transAnyProp[1] == grBoundary | ||||||
|  | 				// This branch will probably never be reached because okAnyState will
 | ||||||
|  | 				// always be true given the current transition map. But we keep it here
 | ||||||
|  | 				// for future modifications to the transition map where this may not be
 | ||||||
|  | 				// true anymore.
 | ||||||
|  | 			} else if okAnyState { | ||||||
|  | 				// We only have a specific property.
 | ||||||
|  | 				g.state = transAnyState[0] | ||||||
|  | 				boundary = transAnyState[1] == grBoundary | ||||||
|  | 			} else { | ||||||
|  | 				// No known transition. GB999: Any x Any.
 | ||||||
|  | 				g.state = grAny | ||||||
|  | 				boundary = true | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		// If we found a cluster boundary, let's stop here. The current cluster will
 | ||||||
|  | 		// be the one that just ended.
 | ||||||
|  | 		if g.pos-1 == 0 /* GB1 */ || boundary { | ||||||
|  | 			g.end = g.pos - 1 | ||||||
|  | 			break | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return g.start != g.end | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Runes returns a slice of runes (code points) which corresponds to the current
 | ||||||
|  | // grapheme cluster. If the iterator is already past the end or Next() has not
 | ||||||
|  | // yet been called, nil is returned.
 | ||||||
|  | func (g *Graphemes) Runes() []rune { | ||||||
|  | 	if g.start == g.end { | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  | 	return g.codePoints[g.start:g.end] | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Str returns a substring of the original string which corresponds to the
 | ||||||
|  | // current grapheme cluster. If the iterator is already past the end or Next()
 | ||||||
|  | // has not yet been called, an empty string is returned.
 | ||||||
|  | func (g *Graphemes) Str() string { | ||||||
|  | 	if g.start == g.end { | ||||||
|  | 		return "" | ||||||
|  | 	} | ||||||
|  | 	return string(g.codePoints[g.start:g.end]) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Bytes returns a byte slice which corresponds to the current grapheme cluster.
 | ||||||
|  | // If the iterator is already past the end or Next() has not yet been called,
 | ||||||
|  | // nil is returned.
 | ||||||
|  | func (g *Graphemes) Bytes() []byte { | ||||||
|  | 	if g.start == g.end { | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  | 	return []byte(string(g.codePoints[g.start:g.end])) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Positions returns the interval of the current grapheme cluster as byte
 | ||||||
|  | // positions into the original string. The first returned value "from" indexes
 | ||||||
|  | // the first byte and the second returned value "to" indexes the first byte that
 | ||||||
|  | // is not included anymore, i.e. str[from:to] is the current grapheme cluster of
 | ||||||
|  | // the original string "str". If Next() has not yet been called, both values are
 | ||||||
|  | // 0. If the iterator is already past the end, both values are 1.
 | ||||||
|  | func (g *Graphemes) Positions() (int, int) { | ||||||
|  | 	return g.indices[g.start], g.indices[g.end] | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Reset puts the iterator into its initial state such that the next call to
 | ||||||
|  | // Next() sets it to the first grapheme cluster again.
 | ||||||
|  | func (g *Graphemes) Reset() { | ||||||
|  | 	g.start, g.end, g.pos, g.state = 0, 0, 0, grAny | ||||||
|  | 	g.Next() // Parse ahead again.
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // GraphemeClusterCount returns the number of user-perceived characters
 | ||||||
|  | // (grapheme clusters) for the given string. To calculate this number, it
 | ||||||
|  | // iterates through the string using the Graphemes iterator.
 | ||||||
|  | func GraphemeClusterCount(s string) (n int) { | ||||||
|  | 	g := NewGraphemes(s) | ||||||
|  | 	for g.Next() { | ||||||
|  | 		n++ | ||||||
|  | 	} | ||||||
|  | 	return | ||||||
|  | } | ||||||
							
								
								
									
										1658
									
								
								vendor/github.com/rivo/uniseg/properties.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1658
									
								
								vendor/github.com/rivo/uniseg/properties.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										8
									
								
								vendor/github.com/russross/blackfriday/v2/.gitignore
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								vendor/github.com/russross/blackfriday/v2/.gitignore
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,8 @@ | |||||||
|  | *.out | ||||||
|  | *.swp | ||||||
|  | *.8 | ||||||
|  | *.6 | ||||||
|  | _obj | ||||||
|  | _test* | ||||||
|  | markdown | ||||||
|  | tags | ||||||
Some files were not shown because too many files have changed in this diff Show More
		Loading…
	
		Reference in New Issue
	
	Block a user