Pigment
A terminal color library for Lean 4.
Contents
Features
- Chainable API using the pipe operator
- Multiple color modes: 8, 16, 256, and 24-bit RGB
- Automatic terminal capability detection
- Text styling (bold, italic, underline, dim, etc.)
- Hex color codes support
- Inline color composition
- Zero dependencies
Installation
Add Pigment to your lakefile.toml:
[[require]]
name = "Pigment"
git = "https://github.com/RSoulatIOHK/Pigment"
rev = "main"
Then import it in your Lean file:
import Pigment
open Pigment
Quick Start
import Pigment
open Pigment
def main : IO Unit := run do
println ("Hello, World!".style |> green |> bold)
Colors and styles are chained with the pipe operator:
"Error".style |> red |> bold |> underline
Available color modes:
-- Basic colors
"text".style |> red
-- RGB
"text".style |> rgb 255 128 64
-- Hex codes
"text".style |> hex "#FF1493"
-- 256-color palette
"text".style |> color256 196
-- Backgrounds
"text".style |> white |> bgRed
Examples
Success/Error Messages
def showBuildStatus : IO Unit := run do
Quicky.success "Build completed successfully"
Quicky.error "Failed to connect to database"
Quicky.warning "Disk space running low (85%)"
Quicky.info "Processing 1000 items..."
Quicky.debug "Cache hit: 95%"
Progress Bars
def showProgress (percent : Nat) : IO Unit := run do
let done := "█".style |> green
let pending := "░".style |> dim
let pct := s!"{percent}%".style |> yellow |> bold
let doneCount := percent / 10
let pendingCount := 10 - doneCount
let blocks := List.replicate doneCount done ++ List.replicate pendingCount pending
printLine (blocks ++ [" ".style, pct])
Inline Status Messages
def compileStatus (file : String) (status : String) : IO Unit := run do
let label := "[".style |> dim
let statusText := if status == "OK"
then "OK".style |> green |> bold
else "FAIL".style |> red |> bold
let close := "]".style |> dim
let filename := file.style |> cyan
printLine [label, statusText, close, " ".style, filename]
Code Syntax Highlighting
def showCode : IO Unit := run do
let kw := "def".style |> magenta |> bold
let name := "factorial".style |> blue |> bold
let punct := "(".style |> dim
let param := "n".style |> cyan
let punct2 := ":".style |> dim
let type_ := "Nat".style |> yellow
let punct3 := ")".style |> dim
printLine [kw, " ".style, name, punct, param, punct2, " ".style, type_, punct3]
Dashboards
def systemDashboard : IO Unit := run do
let title := "System Status".style |> hex "#00BFFF" |> bold |> underline
println title
IO.println ""
Quicky.success "CPU: 25% (Normal)"
Quicky.success "Memory: 4.2 GB / 16 GB"
Quicky.warning "Disk: 85% used (127 GB free)"
Quicky.error "Network: Connection lost"
IO.println ""
let time := "Last updated: 14:32:05".style |> dim
println time
API Reference
Colors
Basic: red, green, blue, yellow, cyan, magenta, white, black
Backgrounds: bgRed, bgGreen, bgBlue, bgYellow, bgCyan, bgMagenta, bgWhite, bgBlack
Advanced:
rgb r g b- 24-bit RGBbgRgb r g b- RGB backgroundhex "#RRGGBB"- Hex colorbgHex "#RRGGBB"- Hex backgroundcolor256 idx- 256-color palette (0-255)bgColor256 idx- 256-color background
Styles
bold, dim, italic, underline, blink, reverse, hidden, strikethrough
Output
println- Print with newlineprint- Print without newlineprintLine- Print multiple styled texts on one line
Quick Helpers
Quicky.success msg- Green checkmarkQuicky.error msg- Red XQuicky.warning msg- Yellow warningQuicky.info msg- Cyan infoQuicky.debug msg- Dim debug
Configuration
Manual configuration:
-- Force 256-color mode
def main : IO Unit := runWith { enabled := true, support := .colors256 } do
println ("256-color mode".style |> color256 196)
-- Disable colors
def main : IO Unit := runPlain do
println ("No colors".style |> red)
-- Conditional colors
def main : IO Unit := run do
println ("Colored".style |> green)
withEnabled false do
println ("Plain".style |> red)
println ("Colored again".style |> blue)
Functions:
run- Auto-detected config (recommended)runWith cfg- Explicit configurationrunPlain- No colorswithEnabled bool- Toggle colors temporarilywithSupport level- Override color support level
Environment Variables
The library respects standard environment variables:
NO_COLOR- Disable all colorsCOLORTERM=truecolororCOLORTERM=24bit- Enable 24-bit RGBTERM=*256color*- Enable 256-color modeTERM=*color*- Enable basic colors
NO_COLOR=1 lake exe myapp
COLORTERM=truecolor lake exe myapp
Troubleshooting
If colors aren't showing, check your terminal:
echo $TERM
Force colors if auto-detection fails:
def main : IO Unit := runWith { enabled := true, support := .truecolor } do
-- your code
For hex colors, ensure your terminal supports truecolor (24-bit).
More Examples
The library includes 22 examples in Pigment/Examples.lean:
- Example 2: Success/Error Messages
- Example 13: Progress Bars
- Example 16: Syntax Highlighting
- Example 17: Dashboards
- Example 18: RGB Gradients
- Example 20: All Text Styles
- Example 21: Color Grid (9×6)
- Example 22: Inline Colors
Run all examples:
lake build
lake test
Tips
For CI/CD, respect NO_COLOR:
NO_COLOR=1 lake exe myapp
Contributing
Contributions welcome. Open an issue for bugs or feature requests, or submit a PR.
git clone https://github.com/RSoulatIOHK/Pigment
cd Pigment
lake build # Build library
lake test # Run examples
License
Apache License 2.0 - see LICENSE for details.