├── .gitignore ├── LICENSE ├── README.md ├── color.go ├── color_test.go ├── esc.go ├── esc_test.go ├── go.mod ├── images ├── color_codes.png └── output.png └── type.go /.gitignore: -------------------------------------------------------------------------------- 1 | # If you prefer the allow list template instead of the deny list, see community template: 2 | # https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore 3 | # 4 | # Binaries for programs and plugins 5 | *.exe 6 | *.exe~ 7 | *.dll 8 | *.so 9 | *.dylib 10 | 11 | # Test binary, built with `go test -c` 12 | *.test 13 | 14 | # Output of the go coverage tool, specifically when used with LiteIDE 15 | *.out 16 | 17 | # Dependency directories (remove the comment below to include it) 18 | # vendor/ 19 | 20 | # Go workspace file 21 | go.work 22 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 ermanimer 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # go-color 2 | go-color is a simple color library for Go that allows you to print colored text for the Unix terminal. 3 | 4 | # Installation 5 | 6 | ```bash 7 | go install github.com/ermanimer/go-color@latest 8 | ``` 9 | 10 | # Usage 11 | 12 | ```go 13 | // use predefined colors 14 | color.Red.Println("red text") 15 | 16 | // create colors with color codes, see the color chart below. 17 | color.New(240).Println("gray text") 18 | 19 | // add background color 20 | color.New(220).With(color.Blue).Println("orange text on a blue background") 21 | 22 | // create colored strings 23 | fmt.Printf("%s %s\n", color.Green.Paint("green text"), color.Yellow.Paint("with yellow text")) 24 | ``` 25 | 26 | **Output** 27 | 28 | ![output](images/output.png) 29 | 30 | 31 | **Color Codes:** 32 | 33 | ![color_codes](images/color_codes.png) 34 | 35 | # Contribution 36 | 37 | Your contribution and feedback are always welcome. 38 | 39 | # References 40 | 41 | [ANSI Escape Code](https://en.wikipedia.org/wiki/ANSI_escape_code) 42 | -------------------------------------------------------------------------------- /color.go: -------------------------------------------------------------------------------- 1 | package color 2 | 3 | import ( 4 | "fmt" 5 | "io" 6 | ) 7 | 8 | type colorCode int 9 | 10 | const ( 11 | Black colorCode = 0 + iota 12 | Red 13 | Green 14 | Yellow 15 | Blue 16 | Magenta 17 | Cyan 18 | White 19 | BrightBlack 20 | BrightRed 21 | BrightGreen 22 | BrightYellow 23 | BrightBlue 24 | BrightMagenta 25 | BrightCyan 26 | BrightWhite 27 | ) 28 | 29 | func New(code byte) colorCode { 30 | return colorCode(code) 31 | } 32 | 33 | func (c colorCode) Fprint(w io.Writer, a ...any) { 34 | makeEscCode(fg, c).Fprint(w, a...) 35 | } 36 | 37 | func (c colorCode) Fprintf(w io.Writer, format string, a ...any) { 38 | makeEscCode(fg, c).Fprintf(w, format, a...) 39 | } 40 | 41 | func (c colorCode) Fprintln(w io.Writer, a ...any) { 42 | makeEscCode(fg, c).Fprintln(w, a...) 43 | } 44 | 45 | func (c colorCode) Print(a ...any) { 46 | makeEscCode(fg, c).Print(a...) 47 | } 48 | 49 | func (c colorCode) Printf(format string, a ...any) { 50 | makeEscCode(fg, c).Printf(format, a...) 51 | } 52 | 53 | func (c colorCode) Println(a ...any) { 54 | makeEscCode(fg, c).Println(a...) 55 | } 56 | 57 | func (c colorCode) Paint(a any) string { 58 | return makeEscCode(fg, c).Paint(a) 59 | } 60 | 61 | func (foreground colorCode) With(background colorCode) escCode { 62 | return escCode(fmt.Sprintf("%s%s", makeEscCode(fg, foreground), makeEscCode(bg, background))) 63 | } 64 | -------------------------------------------------------------------------------- /color_test.go: -------------------------------------------------------------------------------- 1 | package color 2 | 3 | import "testing" 4 | 5 | func TestWith(t *testing.T) { 6 | expected := escCode("\x1b[38;5;7;m\x1b[48;5;1;m") 7 | actual := White.With(Red) 8 | if actual != expected { 9 | t.Errorf("%s != %s", actual, expected) 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /esc.go: -------------------------------------------------------------------------------- 1 | package color 2 | 3 | import ( 4 | "fmt" 5 | "io" 6 | ) 7 | 8 | type escCode string 9 | 10 | const reset escCode = "\x1b[0m" 11 | 12 | func (c escCode) Fprint(w io.Writer, a ...any) { 13 | c.fset(w) 14 | fmt.Fprint(w, a...) 15 | reset.fset(w) 16 | } 17 | 18 | func (c escCode) Fprintf(w io.Writer, format string, a ...any) { 19 | c.fset(w) 20 | fmt.Fprintf(w, format, a...) 21 | reset.fset(w) 22 | } 23 | 24 | func (c escCode) Fprintln(w io.Writer, a ...any) { 25 | c.fset(w) 26 | fmt.Fprint(w, a...) 27 | reset.fset(w) 28 | fmt.Print("\n") 29 | } 30 | 31 | func (c escCode) Print(a ...any) { 32 | c.set() 33 | fmt.Print(a...) 34 | reset.set() 35 | } 36 | 37 | func (c escCode) Printf(format string, a ...any) { 38 | c.set() 39 | fmt.Printf(format, a...) 40 | reset.set() 41 | } 42 | 43 | func (c escCode) Println(a ...any) { 44 | c.set() 45 | fmt.Print(a...) 46 | reset.set() 47 | fmt.Print("\n") 48 | } 49 | 50 | func (c escCode) Paint(a any) string { 51 | return fmt.Sprintf("%s%v%s", c, a, reset) 52 | } 53 | 54 | func (c escCode) set() { 55 | fmt.Print(c) 56 | } 57 | 58 | func (c escCode) fset(w io.Writer) { 59 | fmt.Fprint(w, c) 60 | } 61 | 62 | func makeEscCode(typeCode typeCode, cocolorCode colorCode) escCode { 63 | return escCode(fmt.Sprintf("\x1b[%d;5;%d;m", typeCode, cocolorCode)) 64 | } 65 | -------------------------------------------------------------------------------- /esc_test.go: -------------------------------------------------------------------------------- 1 | package color 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestMakeEscCode(t *testing.T) { 8 | tests := []struct { 9 | name string 10 | typeCode typeCode 11 | colorCode colorCode 12 | expected escCode 13 | }{ 14 | { 15 | name: "fg", 16 | typeCode: fg, 17 | colorCode: White, 18 | expected: "\x1b[38;5;7;m", 19 | }, 20 | { 21 | name: "bg", 22 | typeCode: bg, 23 | colorCode: Red, 24 | expected: "\x1b[48;5;1;m", 25 | }, 26 | } 27 | for _, test := range tests { 28 | t.Run(test.name, func(tt *testing.T) { 29 | actual := makeEscCode(test.typeCode, test.colorCode) 30 | if actual != test.expected { 31 | tt.Errorf("%s != %s", actual, test.expected) 32 | } 33 | }) 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/ermanimer/go-color 2 | 3 | go 1.21.0 4 | -------------------------------------------------------------------------------- /images/color_codes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ermanimer/go-color/bcfc06e3d6ba7bbd0d40350e9d469b5fc5a46aa8/images/color_codes.png -------------------------------------------------------------------------------- /images/output.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ermanimer/go-color/bcfc06e3d6ba7bbd0d40350e9d469b5fc5a46aa8/images/output.png -------------------------------------------------------------------------------- /type.go: -------------------------------------------------------------------------------- 1 | package color 2 | 3 | type typeCode int 4 | 5 | const ( 6 | fg typeCode = 38 7 | bg typeCode = 48 8 | ) 9 | --------------------------------------------------------------------------------