Skip to content

Commit a020032

Browse files
authored
text: 256-colors support (#388)
1 parent b9f2816 commit a020032

File tree

10 files changed

+1024
-126
lines changed

10 files changed

+1024
-126
lines changed

Makefile

Lines changed: 58 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,84 @@
1-
.PHONY: all profile test
1+
# Declare all phony targets (targets that don't create files)
2+
.PHONY: all bench cyclo default demo-colors demo-list demo-progress demo-table fmt help profile test test-race tools vet
23

4+
# ============================================================================
5+
# Main targets
6+
# ============================================================================
7+
8+
## default: Run tests (default target)
39
default: test
410

11+
## all: Run all checks: tests and benchmarks
512
all: test bench
613

7-
tools:
8-
go install github.com/fzipp/gocyclo/cmd/[email protected]
9-
go install github.com/rinchsan/gosimports/cmd/[email protected]
14+
# ============================================================================
15+
# Testing targets
16+
# ============================================================================
1017

18+
## bench: Run benchmark tests with memory profiling
1119
bench:
1220
go test -bench=. -benchmem
1321

22+
## test: Run tests with coverage (runs fmt, vet, and cyclo first)
23+
test: fmt vet cyclo
24+
go test -cover -coverprofile=.coverprofile ./...
25+
26+
## test-race: Run progress demo with race detector
27+
test-race:
28+
go run -race ./cmd/demo-progress/demo.go
29+
30+
# ============================================================================
31+
# Code quality targets
32+
# ============================================================================
33+
34+
## cyclo: Check cyclomatic complexity (warns if complexity > 13)
1435
cyclo:
1536
gocyclo -over 13 ./*/*.go
1637

38+
## fmt: Format code and organize imports
39+
fmt:
40+
go fmt ./...
41+
gosimports -w .
42+
43+
## vet: Run go vet static analysis
44+
vet:
45+
go vet ./...
46+
47+
# ============================================================================
48+
# Demo targets
49+
# ============================================================================
50+
51+
## demo-colors: Run the colors demo
52+
demo-colors:
53+
go run cmd/demo-colors/demo.go
54+
55+
## demo-list: Run the list demo
1756
demo-list:
1857
go run cmd/demo-list/demo.go
1958

59+
## demo-progress: Run the progress demo
2060
demo-progress:
2161
go run cmd/demo-progress/demo.go
2262

63+
## demo-table: Run the table demo
2364
demo-table:
2465
go run cmd/demo-table/demo.go
2566

26-
fmt:
27-
go fmt ./...
28-
gosimports -w .
67+
# ============================================================================
68+
# Utility targets
69+
# ============================================================================
2970

71+
## help: Display help information for all available targets
72+
help:
73+
@echo "\033[1mAvailable targets:\033[0m"
74+
@awk '/^# [A-Z].*targets$$/ {gsub(/^# /, ""); print "\n\033[1;36m" $$0 "\033[0m"} /^##/ {gsub(/^##\s*/, ""); idx=match($$0, /: /); if(idx) {target=substr($$0,1,idx-1); desc=substr($$0,idx+2); printf " \033[36mmake\033[0m \033[32m%-15s\033[0m \033[33m- %s\033[0m\n", target, desc}}' $(MAKEFILE_LIST)
75+
76+
## profile: Run profiling script
3077
profile:
3178
sh profile.sh
3279

33-
test: fmt vet cyclo
34-
go test -cover -coverprofile=.coverprofile ./...
35-
36-
test-race:
37-
go run -race ./cmd/demo-progress/demo.go
38-
39-
vet:
40-
go vet ./...
80+
## tools: Install required development tools
81+
tools:
82+
go install github.com/fzipp/gocyclo/cmd/[email protected]
83+
go install github.com/rinchsan/gosimports/cmd/[email protected]
4184

cmd/demo-colors/README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# 256-Color Palette Demo
2+
3+
This demo showcases the 256-color ANSI palette support in go-pretty.
4+
5+
## Usage
6+
7+
```bash
8+
go run ./cmd/demo-colors
9+
```
10+
11+
## Screenshot
12+
13+
![256-Color Palette Demo](demo.png)

cmd/demo-colors/demo.go

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
6+
"github.com/jedib0t/go-pretty/v6/table"
7+
"github.com/jedib0t/go-pretty/v6/text"
8+
)
9+
10+
func main() {
11+
tw := table.NewWriter()
12+
tw.AppendRows([]table.Row{
13+
{renderGrid(false)},
14+
{renderGrid(true)},
15+
})
16+
tw.SetTitle("256-Color Palette")
17+
tw.SetStyle(table.StyleLight)
18+
tw.Style().Options.SeparateRows = true
19+
tw.Style().Title.Align = text.AlignCenter
20+
fmt.Println(tw.Render())
21+
}
22+
23+
func alignCode(code int) string {
24+
return " " + text.AlignRight.Apply(fmt.Sprint(code), 3) + " "
25+
}
26+
27+
func blankTable() table.Writer {
28+
tw := table.NewWriter()
29+
tw.SetStyle(table.StyleLight)
30+
style := tw.Style()
31+
style.Box.PaddingLeft = ""
32+
style.Box.PaddingRight = ""
33+
style.Options.DrawBorder = false
34+
style.Options.SeparateRows = false
35+
style.Options.SeparateColumns = false
36+
return tw
37+
}
38+
39+
func buildRow(start, end int, isBackground bool) table.Row {
40+
row := make(table.Row, 0, end-start)
41+
for i := start; i < end; i++ {
42+
row = append(row, cellValue(i, isBackground))
43+
}
44+
return row
45+
}
46+
47+
func cellValue(code int, isBackground bool) string {
48+
if isBackground {
49+
return text.Colors{text.Bg256Color(code), text.FgBlack}.Sprint(alignCode(code))
50+
}
51+
return text.Colors{text.BgBlack, text.Fg256Color(code)}.Sprint(alignCode(code))
52+
}
53+
54+
func renderGrid(isBackground bool) string {
55+
tw := table.NewWriter()
56+
tw.SetIndexColumn(1)
57+
title := "Foreground Colors"
58+
if isBackground {
59+
title = "Background Colors"
60+
}
61+
tw.SetTitle(text.Underline.Sprint(title) + "\n")
62+
tw.SetStyle(table.StyleLight)
63+
style := tw.Style()
64+
style.Box.PaddingLeft = ""
65+
style.Box.PaddingRight = ""
66+
style.Options.DrawBorder = false
67+
style.Options.SeparateRows = false
68+
style.Options.SeparateColumns = false
69+
style.Title.Align = text.AlignCenter
70+
tw.SetColumnConfigs([]table.ColumnConfig{
71+
{Number: 1, Align: text.AlignCenter},
72+
})
73+
74+
// Standard 16 colors (0-15)
75+
row16 := blankTable()
76+
row16.AppendRow(buildRow(0, 16, isBackground))
77+
tw.AppendRows([]table.Row{{row16.Render()}, {""}})
78+
79+
// RGB cube colors (16-231) - 216 colors in 6 blocks of 36
80+
row216 := blankTable()
81+
blockRow := make(table.Row, 0)
82+
for block := 0; block < 6; block++ {
83+
blockStart := 16 + 36*block
84+
blockTable := blankTable()
85+
colors := buildRow(blockStart, blockStart+36, isBackground)
86+
for i := 0; i < len(colors); i += 6 {
87+
end := i + 6
88+
if end > len(colors) {
89+
end = len(colors)
90+
}
91+
blockTable.AppendRow(colors[i:end])
92+
}
93+
blockRow = append(blockRow, blockTable.Render())
94+
if len(blockRow) == 3 {
95+
row216.AppendRow(blockRow)
96+
blockRow = make(table.Row, 0)
97+
}
98+
}
99+
if len(blockRow) > 0 {
100+
row216.AppendRow(blockRow)
101+
}
102+
tw.AppendRows([]table.Row{{row216.Render()}, {""}})
103+
104+
// Grayscale colors (232-255) - 24 colors
105+
rowGrayscale := blankTable()
106+
colors := buildRow(232, 256, isBackground)
107+
for i := 0; i < len(colors); i += 12 {
108+
end := i + 12
109+
if end > len(colors) {
110+
end = len(colors)
111+
}
112+
rowGrayscale.AppendRow(colors[i:end])
113+
}
114+
tw.AppendRows([]table.Row{{rowGrayscale.Render()}})
115+
116+
return tw.Render()
117+
}

cmd/demo-colors/demo.png

444 KB
Loading

text/README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@ Used heavily in the other packages in this repo ([list](../list),
1515
- Foreground colors (Black, Red, Green, Yellow, Blue, Magenta, Cyan, White)
1616
- Background colors (matching foreground set)
1717
- Hi-intensity variants for both foreground and background
18+
- **256-color palette support** - Extended color support for terminals
19+
- Standard 16 colors (0-15)
20+
- RGB cube colors (16-231) - 216 colors organized in a 6x6x6 cube
21+
- Grayscale colors (232-255) - 24 shades of gray
22+
- Helper functions: `Fg256Color(index)`, `Bg256Color(index)`, `Fg256RGB(r, g, b)`, `Bg256RGB(r, g, b)`
1823
- Text attributes (Bold, Faint, Italic, Underline, Blink, Reverse, Concealed, CrossedOut)
1924
- Automatic color detection based on environment variables (`NO_COLOR`, `FORCE_COLOR`, `TERM`)
2025
- Global enable/disable functions for colors
@@ -76,6 +81,7 @@ Used heavily in the other packages in this repo ([list](../list),
7681
- `EscSeqParser` - Parser for advanced escape sequence parsing and tracking
7782
- Supports both CSI (Control Sequence Introducer) and OSI (Operating System Command) formats
7883
- Tracks active formatting codes and can generate consolidated escape sequences
84+
- Full support for 256-color escape sequences (`\x1b[38;5;n`m` and `\x1b[48;5;n`m`)
7985

8086
### Cursor Control
8187

text/ansi_unix.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,12 @@
33

44
package text
55

6+
import "os"
7+
68
func areANSICodesSupported() bool {
7-
return true
9+
// On Unix systems, ANSI codes are generally supported unless TERM is "dumb"
10+
// This is a basic check; 256-color sequences are ANSI sequences and will
11+
// be handled by terminals that support them (or ignored by those that don't)
12+
term := os.Getenv("TERM")
13+
return term != "dumb"
814
}

0 commit comments

Comments
 (0)