f92e0f53a5
* LSCOLORS & LS_COLORS support * Renamed lsColors to gColors * Fixed gOptWords & setExpr.eval()
149 lines
3.6 KiB
Go
149 lines
3.6 KiB
Go
package main
|
|
|
|
import (
|
|
"log"
|
|
"os"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"github.com/nsf/termbox-go"
|
|
)
|
|
|
|
func init() {
|
|
if lscolors := os.Getenv("LSCOLORS"); lscolors != "" {
|
|
gColors.parseBSD(lscolors)
|
|
gOpts.lscolors = true
|
|
}
|
|
if ls_colors := os.Getenv("LS_COLORS"); ls_colors != "" {
|
|
gColors.parseLinux(ls_colors)
|
|
gOpts.lscolors = true
|
|
}
|
|
}
|
|
|
|
type lsColorsEntry struct {
|
|
fg termbox.Attribute
|
|
bg termbox.Attribute
|
|
}
|
|
|
|
type lsColorsT map[string]lsColorsEntry
|
|
|
|
var gColors = make(lsColorsT)
|
|
|
|
// This function parses LS_COLORS environment variable
|
|
func (lsc lsColorsT) parseLinux(env string) {
|
|
e := strings.Split(env, ":")
|
|
for _, e := range e {
|
|
i := strings.IndexRune(e, '=')
|
|
if i >= 0 {
|
|
key := e[:i]
|
|
values := strings.Split(e[i+1:], ";")
|
|
var fg, bg termbox.Attribute
|
|
for _, a := range values {
|
|
i, _ := strconv.Atoi(a) // strconv.Atoi() will returns 0 on error which is termbox.ColorDefault. No need to check the error.
|
|
|
|
switch {
|
|
case i == 1:
|
|
fg = fg | termbox.AttrBold
|
|
case i == 4:
|
|
fg = fg | termbox.AttrUnderline
|
|
case i == 5:
|
|
// Flashing text
|
|
case i == 7:
|
|
fg = fg | termbox.AttrReverse
|
|
case i == 8:
|
|
// Concealed
|
|
case 30 <= i && i <= 37:
|
|
fg = fg | termbox.Attribute(i-29)
|
|
case 40 <= i && i <= 47:
|
|
bg = bg | termbox.Attribute(i-39)
|
|
}
|
|
}
|
|
lsc[key] = lsColorsEntry{fg: fg, bg: bg}
|
|
}
|
|
}
|
|
}
|
|
|
|
// This function parses LSCOLORS variable. See http://www.manpages.info/freebsd/ls.1.html
|
|
func (lsc lsColorsT) parseBSD(env string) {
|
|
if len(env) != 22 {
|
|
log.Print("LSCOLORS variable invalid")
|
|
return
|
|
}
|
|
|
|
unixLsColors := []string{"di", "so", "ln", "pi", "ex", "bd", "cd", "su", "sg", "tw", "ow"}
|
|
unixColors := map[byte]termbox.Attribute{
|
|
'a': termbox.ColorBlack,
|
|
'b': termbox.ColorRed,
|
|
'c': termbox.ColorGreen,
|
|
'd': termbox.ColorYellow, // should be brown
|
|
'e': termbox.ColorBlue,
|
|
'f': termbox.ColorMagenta,
|
|
'g': termbox.ColorCyan,
|
|
'h': termbox.ColorWhite, // should be light grey
|
|
'A': termbox.AttrBold | termbox.ColorBlack,
|
|
'B': termbox.AttrBold | termbox.ColorRed,
|
|
'C': termbox.AttrBold | termbox.ColorGreen,
|
|
'D': termbox.AttrBold | termbox.ColorWhite, // brown
|
|
'E': termbox.AttrBold | termbox.ColorBlue,
|
|
'F': termbox.AttrBold | termbox.ColorMagenta,
|
|
'G': termbox.AttrBold | termbox.ColorCyan,
|
|
'H': termbox.AttrBold | termbox.ColorWhite, // light grey
|
|
}
|
|
|
|
getColor := func(r byte) termbox.Attribute {
|
|
if color, ok := unixColors[r]; ok {
|
|
return color
|
|
} else {
|
|
return termbox.ColorDefault
|
|
}
|
|
}
|
|
|
|
for i, key := range unixLsColors {
|
|
lsc[key] = lsColorsEntry{fg: getColor(env[i*2]), bg: getColor(env[i*2+1])}
|
|
}
|
|
}
|
|
|
|
// This function returns foreground and background colors for given file
|
|
func (lsc lsColorsT) getColors(f *file) (termbox.Attribute, termbox.Attribute) {
|
|
var key = ""
|
|
|
|
switch {
|
|
case f.Mode()&os.ModeSticky != 0:
|
|
key = "st"
|
|
case f.Mode()&os.ModeSetuid != 0:
|
|
key = "su"
|
|
case f.Mode()&os.ModeSetgid != 0:
|
|
key = "sg"
|
|
case f.IsDir():
|
|
key = "di"
|
|
case f.linkState == working:
|
|
key = "ln"
|
|
case f.Mode()&os.ModeNamedPipe != 0:
|
|
key = "pi"
|
|
case f.Mode()&os.ModeSocket != 0:
|
|
key = "so"
|
|
case f.Mode()&os.ModeCharDevice != 0:
|
|
key = "cd"
|
|
case f.Mode()&os.ModeDevice != 0:
|
|
key = "bd"
|
|
case f.linkState == broken:
|
|
key = "or"
|
|
case f.Mode().IsRegular() && f.Mode()&0111 != 0:
|
|
key = "ex"
|
|
default:
|
|
if extI := strings.LastIndexByte(f.Name(), '.'); extI > 0 {
|
|
key = "*" + f.Name()[extI:]
|
|
}
|
|
}
|
|
|
|
if val, ok := lsc[key]; ok {
|
|
return val.fg, val.bg
|
|
} else {
|
|
if val, ok = lsc["no"]; ok {
|
|
return val.fg, val.bg
|
|
} else {
|
|
return termbox.ColorDefault, termbox.ColorDefault
|
|
}
|
|
}
|
|
}
|