Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 58 additions & 15 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,41 +1,84 @@
.PHONY: all profile test
# Declare all phony targets (targets that don't create files)
.PHONY: all bench cyclo default demo-colors demo-list demo-progress demo-table fmt help profile test test-race tools vet

# ============================================================================
# Main targets
# ============================================================================

## default: Run tests (default target)
default: test

## all: Run all checks: tests and benchmarks
all: test bench

tools:
go install github.com/fzipp/gocyclo/cmd/gocyclo@v0.5.1
go install github.com/rinchsan/gosimports/cmd/gosimports@v0.3.8
# ============================================================================
# Testing targets
# ============================================================================

## bench: Run benchmark tests with memory profiling
bench:
go test -bench=. -benchmem

## test: Run tests with coverage (runs fmt, vet, and cyclo first)
test: fmt vet cyclo
go test -cover -coverprofile=.coverprofile ./...

## test-race: Run progress demo with race detector
test-race:
go run -race ./cmd/demo-progress/demo.go

# ============================================================================
# Code quality targets
# ============================================================================

## cyclo: Check cyclomatic complexity (warns if complexity > 13)
cyclo:
gocyclo -over 13 ./*/*.go

## fmt: Format code and organize imports
fmt:
go fmt ./...
gosimports -w .

## vet: Run go vet static analysis
vet:
go vet ./...

# ============================================================================
# Demo targets
# ============================================================================

## demo-colors: Run the colors demo
demo-colors:
go run cmd/demo-colors/demo.go

## demo-list: Run the list demo
demo-list:
go run cmd/demo-list/demo.go

## demo-progress: Run the progress demo
demo-progress:
go run cmd/demo-progress/demo.go

## demo-table: Run the table demo
demo-table:
go run cmd/demo-table/demo.go

fmt:
go fmt ./...
gosimports -w .
# ============================================================================
# Utility targets
# ============================================================================

## help: Display help information for all available targets
help:
@echo "\033[1mAvailable targets:\033[0m"
@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)

## profile: Run profiling script
profile:
sh profile.sh

test: fmt vet cyclo
go test -cover -coverprofile=.coverprofile ./...

test-race:
go run -race ./cmd/demo-progress/demo.go

vet:
go vet ./...
## tools: Install required development tools
tools:
go install github.com/fzipp/gocyclo/cmd/gocyclo@v0.5.1
go install github.com/rinchsan/gosimports/cmd/gosimports@v0.3.8

13 changes: 13 additions & 0 deletions cmd/demo-colors/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# 256-Color Palette Demo

This demo showcases the 256-color ANSI palette support in go-pretty.

## Usage

```bash
go run ./cmd/demo-colors
```

## Screenshot

![256-Color Palette Demo](demo.png)
117 changes: 117 additions & 0 deletions cmd/demo-colors/demo.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
package main

import (
"fmt"

"github.com/jedib0t/go-pretty/v6/table"
"github.com/jedib0t/go-pretty/v6/text"
)

func main() {
tw := table.NewWriter()
tw.AppendRows([]table.Row{
{renderGrid(false)},
{renderGrid(true)},
})
tw.SetTitle("256-Color Palette")
tw.SetStyle(table.StyleLight)
tw.Style().Options.SeparateRows = true
tw.Style().Title.Align = text.AlignCenter
fmt.Println(tw.Render())
}

func alignCode(code int) string {
return " " + text.AlignRight.Apply(fmt.Sprint(code), 3) + " "
}

func blankTable() table.Writer {
tw := table.NewWriter()
tw.SetStyle(table.StyleLight)
style := tw.Style()
style.Box.PaddingLeft = ""
style.Box.PaddingRight = ""
style.Options.DrawBorder = false
style.Options.SeparateRows = false
style.Options.SeparateColumns = false
return tw
}

func buildRow(start, end int, isBackground bool) table.Row {
row := make(table.Row, 0, end-start)
for i := start; i < end; i++ {
row = append(row, cellValue(i, isBackground))
}
return row
}

func cellValue(code int, isBackground bool) string {
if isBackground {
return text.Colors{text.Bg256Color(code), text.FgBlack}.Sprint(alignCode(code))
}
return text.Colors{text.BgBlack, text.Fg256Color(code)}.Sprint(alignCode(code))
}

func renderGrid(isBackground bool) string {
tw := table.NewWriter()
tw.SetIndexColumn(1)
title := "Foreground Colors"
if isBackground {
title = "Background Colors"
}
tw.SetTitle(text.Underline.Sprint(title) + "\n")
tw.SetStyle(table.StyleLight)
style := tw.Style()
style.Box.PaddingLeft = ""
style.Box.PaddingRight = ""
style.Options.DrawBorder = false
style.Options.SeparateRows = false
style.Options.SeparateColumns = false
style.Title.Align = text.AlignCenter
tw.SetColumnConfigs([]table.ColumnConfig{
{Number: 1, Align: text.AlignCenter},
})

// Standard 16 colors (0-15)
row16 := blankTable()
row16.AppendRow(buildRow(0, 16, isBackground))
tw.AppendRows([]table.Row{{row16.Render()}, {""}})

// RGB cube colors (16-231) - 216 colors in 6 blocks of 36
row216 := blankTable()
blockRow := make(table.Row, 0)
for block := 0; block < 6; block++ {
blockStart := 16 + 36*block
blockTable := blankTable()
colors := buildRow(blockStart, blockStart+36, isBackground)
for i := 0; i < len(colors); i += 6 {
end := i + 6
if end > len(colors) {
end = len(colors)
}
blockTable.AppendRow(colors[i:end])
}
blockRow = append(blockRow, blockTable.Render())
if len(blockRow) == 3 {
row216.AppendRow(blockRow)
blockRow = make(table.Row, 0)
}
}
if len(blockRow) > 0 {
row216.AppendRow(blockRow)
}
tw.AppendRows([]table.Row{{row216.Render()}, {""}})

// Grayscale colors (232-255) - 24 colors
rowGrayscale := blankTable()
colors := buildRow(232, 256, isBackground)
for i := 0; i < len(colors); i += 12 {
end := i + 12
if end > len(colors) {
end = len(colors)
}
rowGrayscale.AppendRow(colors[i:end])
}
tw.AppendRows([]table.Row{{rowGrayscale.Render()}})

return tw.Render()
}
Binary file added cmd/demo-colors/demo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions text/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ Used heavily in the other packages in this repo ([list](../list),
- Foreground colors (Black, Red, Green, Yellow, Blue, Magenta, Cyan, White)
- Background colors (matching foreground set)
- Hi-intensity variants for both foreground and background
- **256-color palette support** - Extended color support for terminals
- Standard 16 colors (0-15)
- RGB cube colors (16-231) - 216 colors organized in a 6x6x6 cube
- Grayscale colors (232-255) - 24 shades of gray
- Helper functions: `Fg256Color(index)`, `Bg256Color(index)`, `Fg256RGB(r, g, b)`, `Bg256RGB(r, g, b)`
- Text attributes (Bold, Faint, Italic, Underline, Blink, Reverse, Concealed, CrossedOut)
- Automatic color detection based on environment variables (`NO_COLOR`, `FORCE_COLOR`, `TERM`)
- Global enable/disable functions for colors
Expand Down Expand Up @@ -76,6 +81,7 @@ Used heavily in the other packages in this repo ([list](../list),
- `EscSeqParser` - Parser for advanced escape sequence parsing and tracking
- Supports both CSI (Control Sequence Introducer) and OSI (Operating System Command) formats
- Tracks active formatting codes and can generate consolidated escape sequences
- Full support for 256-color escape sequences (`\x1b[38;5;n`m` and `\x1b[48;5;n`m`)

### Cursor Control

Expand Down
8 changes: 7 additions & 1 deletion text/ansi_unix.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@

package text

import "os"

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