mirror of
https://github.com/antonmedv/fx
synced 2024-11-03 15:40:12 +00:00
Add themes
This commit is contained in:
parent
49756d7ff4
commit
ae80a278b2
6
go.mod
6
go.mod
@ -6,6 +6,9 @@ require (
|
||||
github.com/charmbracelet/bubbles v0.10.3
|
||||
github.com/charmbracelet/bubbletea v0.20.0
|
||||
github.com/charmbracelet/lipgloss v0.5.0
|
||||
github.com/mattn/go-isatty v0.0.14
|
||||
github.com/mazznoer/colorgrad v0.8.1
|
||||
github.com/muesli/termenv v0.11.1-0.20220212125758-44cd13922739
|
||||
github.com/stretchr/testify v1.7.1
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211
|
||||
)
|
||||
@ -15,11 +18,10 @@ require (
|
||||
github.com/containerd/console v1.0.3 // indirect
|
||||
github.com/davecgh/go-spew v1.1.0 // indirect
|
||||
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
|
||||
github.com/mattn/go-isatty v0.0.14 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.13 // indirect
|
||||
github.com/mazznoer/csscolorparser v0.1.0 // indirect
|
||||
github.com/muesli/ansi v0.0.0-20211031195517-c9f0611b6c70 // indirect
|
||||
github.com/muesli/reflow v0.3.0 // indirect
|
||||
github.com/muesli/termenv v0.11.1-0.20220212125758-44cd13922739 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/rivo/uniseg v0.2.0 // indirect
|
||||
golang.org/x/sys v0.0.0-20220406163625-3f8b81556e12 // indirect
|
||||
|
5
go.sum
5
go.sum
@ -15,6 +15,7 @@ github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkX
|
||||
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
||||
github.com/lucasb-eyer/go-colorful v1.0.3/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
|
||||
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
|
||||
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
|
||||
github.com/mattn/go-isatty v0.0.13/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
@ -24,6 +25,10 @@ github.com/mattn/go-runewidth v0.0.10/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRC
|
||||
github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
|
||||
github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU=
|
||||
github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||
github.com/mazznoer/colorgrad v0.8.1 h1:Bw/ks+KujOOg9E6YQvPqSqTLryiFnwliAH5VMZarSTI=
|
||||
github.com/mazznoer/colorgrad v0.8.1/go.mod h1:xCjvoNkXHJIAPOUMSMrXkFdxTGQqk8zMYS3e5hSLghA=
|
||||
github.com/mazznoer/csscolorparser v0.1.0 h1:xUf1uzU1r24JleIIb2Kz3bl7vATStxy53gm67yuPP+c=
|
||||
github.com/mazznoer/csscolorparser v0.1.0/go.mod h1:Aj22+L/rYN/Y6bj3bYqO3N6g1dtdHtGfQ32xZ5PJQic=
|
||||
github.com/muesli/ansi v0.0.0-20211018074035-2e021307bc4b/go.mod h1:fQuZ0gauxyBcmsdE3ZT4NasjaRdxmbCS0jRHsrWu3Ho=
|
||||
github.com/muesli/ansi v0.0.0-20211031195517-c9f0611b6c70 h1:kMlmsLSbjkikxQJ1IPwaM+7LJ9ltFu/fi8CRzvSnQmA=
|
||||
github.com/muesli/ansi v0.0.0-20211031195517-c9f0611b6c70/go.mod h1:fQuZ0gauxyBcmsdE3ZT4NasjaRdxmbCS0jRHsrWu3Ho=
|
||||
|
55
main.go
55
main.go
@ -6,7 +6,8 @@ import (
|
||||
"github.com/charmbracelet/bubbles/key"
|
||||
"github.com/charmbracelet/bubbles/textinput"
|
||||
tea "github.com/charmbracelet/bubbletea"
|
||||
"github.com/charmbracelet/lipgloss"
|
||||
"github.com/mattn/go-isatty"
|
||||
"github.com/muesli/termenv"
|
||||
"golang.org/x/term"
|
||||
"os"
|
||||
"path"
|
||||
@ -16,30 +17,6 @@ import (
|
||||
|
||||
type number = json.Number
|
||||
|
||||
var colors = struct {
|
||||
cursor lipgloss.Style
|
||||
syntax lipgloss.Style
|
||||
key lipgloss.Style
|
||||
null lipgloss.Style
|
||||
boolean lipgloss.Style
|
||||
number lipgloss.Style
|
||||
string lipgloss.Style
|
||||
preview lipgloss.Style
|
||||
statusBar lipgloss.Style
|
||||
search lipgloss.Style
|
||||
}{
|
||||
cursor: lipgloss.NewStyle().Reverse(true),
|
||||
syntax: lipgloss.NewStyle(),
|
||||
key: lipgloss.NewStyle().Bold(true).Foreground(lipgloss.Color("4")),
|
||||
null: lipgloss.NewStyle().Bold(true).Foreground(lipgloss.Color("8")),
|
||||
boolean: lipgloss.NewStyle().Bold(true).Foreground(lipgloss.Color("3")),
|
||||
number: lipgloss.NewStyle().Bold(true).Foreground(lipgloss.Color("6")),
|
||||
string: lipgloss.NewStyle().Bold(true).Foreground(lipgloss.Color("2")),
|
||||
preview: lipgloss.NewStyle().Bold(true).Foreground(lipgloss.Color("8")),
|
||||
statusBar: lipgloss.NewStyle().Background(lipgloss.Color("7")).Foreground(lipgloss.Color("0")),
|
||||
search: lipgloss.NewStyle().Background(lipgloss.Color("11")).Foreground(lipgloss.Color("16")),
|
||||
}
|
||||
|
||||
func main() {
|
||||
cpuProfile := os.Getenv("CPU_PROFILE")
|
||||
if cpuProfile != "" {
|
||||
@ -52,6 +29,19 @@ func main() {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
themeId, ok := os.LookupEnv("FX_THEME")
|
||||
if !ok {
|
||||
themeId = "1"
|
||||
}
|
||||
theme, ok := themes[themeId]
|
||||
if !ok {
|
||||
theme = themes["1"]
|
||||
}
|
||||
if termenv.ColorProfile() == termenv.Ascii {
|
||||
theme = themes["0"]
|
||||
}
|
||||
|
||||
filePath := ""
|
||||
var args []string
|
||||
var dec *json.Decoder
|
||||
@ -75,12 +65,13 @@ func main() {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if len(args) > 0 {
|
||||
if args[0] == "--print-code" {
|
||||
tty := isatty.IsTerminal(os.Stdout.Fd())
|
||||
if len(args) > 0 || !tty {
|
||||
if len(args) > 0 && args[0] == "--print-code" {
|
||||
fmt.Print(generateCode(args[1:]))
|
||||
return
|
||||
}
|
||||
reduce(jsonObject, args)
|
||||
reduce(jsonObject, args, theme)
|
||||
return
|
||||
}
|
||||
|
||||
@ -105,10 +96,13 @@ func main() {
|
||||
canBeExpanded[it.path] = len(it.object.(array)) > 0
|
||||
}
|
||||
})
|
||||
|
||||
input := textinput.New()
|
||||
input.Prompt = ""
|
||||
|
||||
m := &model{
|
||||
fileName: path.Base(filePath),
|
||||
theme: theme,
|
||||
json: jsonObject,
|
||||
width: 80,
|
||||
height: 60,
|
||||
@ -141,6 +135,7 @@ type model struct {
|
||||
windowHeight int
|
||||
footerHeight int
|
||||
wrap bool
|
||||
theme Theme
|
||||
|
||||
fileName string
|
||||
json interface{}
|
||||
@ -394,13 +389,13 @@ func (m *model) View() string {
|
||||
if m.showHelp {
|
||||
statusBar := "Press Esc or q to close help."
|
||||
statusBar += strings.Repeat(" ", max(0, m.width-width(statusBar)))
|
||||
statusBar = colors.statusBar.Render(statusBar)
|
||||
statusBar = m.theme.statusBar(statusBar)
|
||||
return strings.Join(lines, "\n") + extraLines + "\n" + statusBar
|
||||
}
|
||||
statusBar := m.cursorPath() + " "
|
||||
statusBar += strings.Repeat(" ", max(0, m.width-width(statusBar)-width(m.fileName)))
|
||||
statusBar += m.fileName
|
||||
statusBar = colors.statusBar.Render(statusBar)
|
||||
statusBar = m.theme.statusBar(statusBar)
|
||||
output := strings.Join(lines, "\n") + extraLines + "\n" + statusBar
|
||||
if m.searchInput.Focused() {
|
||||
output += "\n/" + m.searchInput.View()
|
||||
|
68
print.go
68
print.go
@ -2,7 +2,6 @@ package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/charmbracelet/lipgloss"
|
||||
"strings"
|
||||
)
|
||||
|
||||
@ -28,21 +27,21 @@ func (m *model) print(v interface{}, level, lineNumber, keyEndPos int, path stri
|
||||
|
||||
switch v.(type) {
|
||||
case nil:
|
||||
return []string{merge(m.explode("null", searchValue, colors.null, path, selectableValues))}
|
||||
return []string{merge(m.explode("null", searchValue, m.theme.null, path, selectableValues))}
|
||||
|
||||
case bool:
|
||||
if v.(bool) {
|
||||
return []string{merge(m.explode("true", searchValue, colors.boolean, path, selectableValues))}
|
||||
return []string{merge(m.explode("true", searchValue, m.theme.boolean, path, selectableValues))}
|
||||
} else {
|
||||
return []string{merge(m.explode("false", searchValue, colors.boolean, path, selectableValues))}
|
||||
return []string{merge(m.explode("false", searchValue, m.theme.boolean, path, selectableValues))}
|
||||
}
|
||||
|
||||
case number:
|
||||
return []string{merge(m.explode(v.(number).String(), searchValue, colors.number, path, selectableValues))}
|
||||
return []string{merge(m.explode(v.(number).String(), searchValue, m.theme.number, path, selectableValues))}
|
||||
|
||||
case string:
|
||||
line := fmt.Sprintf("%q", v)
|
||||
chunks := m.explode(line, searchValue, colors.string, path, selectableValues)
|
||||
chunks := m.explode(line, searchValue, m.theme.string, path, selectableValues)
|
||||
if m.wrap && keyEndPos+width(line) > m.width {
|
||||
return wrapLines(chunks, keyEndPos, m.width, subident)
|
||||
}
|
||||
@ -66,9 +65,10 @@ func (m *model) print(v interface{}, level, lineNumber, keyEndPos int, path stri
|
||||
}
|
||||
m.connect(subpath, lineNumber)
|
||||
key := fmt.Sprintf("%q", k)
|
||||
key = merge(m.explode(key, keyRanges, colors.key, subpath, true))
|
||||
keyTheme := m.theme.key(i, len(keys))
|
||||
key = merge(m.explode(key, keyRanges, keyTheme, subpath, true))
|
||||
value, _ := v.(*dict).get(k)
|
||||
delim := merge(m.explode(": ", delimRanges, colors.syntax, subpath, false))
|
||||
delim := merge(m.explode(": ", delimRanges, m.theme.syntax, subpath, false))
|
||||
keyEndPos := width(ident) + width(key) + width(delim)
|
||||
lines := m.print(value, level+1, lineNumber, keyEndPos, subpath, false)
|
||||
lines[0] = ident + key + delim + lines[0]
|
||||
@ -110,20 +110,20 @@ func (m *model) print(v interface{}, level, lineNumber, keyEndPos int, path stri
|
||||
|
||||
func (m *model) preview(v interface{}, path string, selectableValues bool) string {
|
||||
searchResult := m.highlightIndex[path]
|
||||
previewStyle := colors.preview
|
||||
previewStyle := m.theme.preview
|
||||
if selectableValues && m.cursorPath() == path {
|
||||
previewStyle = colors.cursor
|
||||
previewStyle = m.theme.cursor
|
||||
}
|
||||
printValue := func(value interface{}) string {
|
||||
switch value.(type) {
|
||||
case nil, bool, number:
|
||||
return previewStyle.Render(fmt.Sprintf("%v", value))
|
||||
return previewStyle(fmt.Sprintf("%v", value))
|
||||
case string:
|
||||
return previewStyle.Render(fmt.Sprintf("%q", value))
|
||||
return previewStyle(fmt.Sprintf("%q", value))
|
||||
case *dict:
|
||||
return previewStyle.Render("{\u2026}")
|
||||
return previewStyle("{\u2026}")
|
||||
case array:
|
||||
return previewStyle.Render("[\u2026]")
|
||||
return previewStyle("[\u2026]")
|
||||
}
|
||||
return "..."
|
||||
}
|
||||
@ -134,13 +134,13 @@ func (m *model) preview(v interface{}, path string, selectableValues bool) strin
|
||||
keys := v.(*dict).keys
|
||||
for _, k := range keys {
|
||||
key := fmt.Sprintf("%q", k)
|
||||
output += previewStyle.Render(key + ": ")
|
||||
output += previewStyle(key + ": ")
|
||||
value, _ := v.(*dict).get(k)
|
||||
output += printValue(value)
|
||||
break
|
||||
}
|
||||
if len(keys) > 1 {
|
||||
output += previewStyle.Render(", \u2026")
|
||||
output += previewStyle(", \u2026")
|
||||
}
|
||||
output += m.printCloseBracket("}", searchResult, path, selectableValues)
|
||||
return output
|
||||
@ -153,7 +153,7 @@ func (m *model) preview(v interface{}, path string, selectableValues bool) strin
|
||||
break
|
||||
}
|
||||
if len(slice) > 1 {
|
||||
output += previewStyle.Render(", \u2026")
|
||||
output += previewStyle(", \u2026")
|
||||
}
|
||||
output += m.printCloseBracket("]", searchResult, path, selectableValues)
|
||||
return output
|
||||
@ -189,67 +189,67 @@ func wrapLines(chunks []withStyle, keyEndPos, mWidth int, subident string) []str
|
||||
}
|
||||
|
||||
func (w withStyle) Render(s string) string {
|
||||
return w.style.Render(s)
|
||||
return w.style(s)
|
||||
}
|
||||
|
||||
func (m *model) printOpenBracket(line string, s *rangeGroup, path string, selectableValues bool) string {
|
||||
if selectableValues && m.cursorPath() == path {
|
||||
return colors.cursor.Render(line)
|
||||
return m.theme.cursor(line)
|
||||
}
|
||||
if s != nil && s.openBracket != nil {
|
||||
if s.openBracket.parent.index == m.searchResultsCursor {
|
||||
return colors.cursor.Render(line)
|
||||
return m.theme.cursor(line)
|
||||
} else {
|
||||
return colors.search.Render(line)
|
||||
return m.theme.search(line)
|
||||
}
|
||||
} else {
|
||||
return colors.syntax.Render(line)
|
||||
return m.theme.syntax(line)
|
||||
}
|
||||
}
|
||||
|
||||
func (m *model) printCloseBracket(line string, s *rangeGroup, path string, selectableValues bool) string {
|
||||
if selectableValues && m.cursorPath() == path {
|
||||
return colors.cursor.Render(line)
|
||||
return m.theme.cursor(line)
|
||||
}
|
||||
if s != nil && s.closeBracket != nil {
|
||||
if s.closeBracket.parent.index == m.searchResultsCursor {
|
||||
return colors.cursor.Render(line)
|
||||
return m.theme.cursor(line)
|
||||
} else {
|
||||
return colors.search.Render(line)
|
||||
return m.theme.search(line)
|
||||
}
|
||||
} else {
|
||||
return colors.syntax.Render(line)
|
||||
return m.theme.syntax(line)
|
||||
}
|
||||
}
|
||||
|
||||
func (m *model) printComma(line string, s *rangeGroup) string {
|
||||
if s != nil && s.comma != nil {
|
||||
if s.comma.parent.index == m.searchResultsCursor {
|
||||
return colors.cursor.Render(line)
|
||||
return m.theme.cursor(line)
|
||||
} else {
|
||||
return colors.search.Render(line)
|
||||
return m.theme.search(line)
|
||||
}
|
||||
} else {
|
||||
return colors.syntax.Render(line)
|
||||
return m.theme.syntax(line)
|
||||
}
|
||||
}
|
||||
|
||||
type withStyle struct {
|
||||
value string
|
||||
style lipgloss.Style
|
||||
style Color
|
||||
}
|
||||
|
||||
func (m *model) explode(line string, highlightRanges []*foundRange, defaultStyle lipgloss.Style, path string, selectable bool) []withStyle {
|
||||
func (m *model) explode(line string, highlightRanges []*foundRange, defaultStyle Color, path string, selectable bool) []withStyle {
|
||||
if selectable && m.cursorPath() == path && m.showCursor {
|
||||
return []withStyle{{line, colors.cursor}}
|
||||
return []withStyle{{line, m.theme.cursor}}
|
||||
}
|
||||
|
||||
out := make([]withStyle, 0, 1)
|
||||
pos := 0
|
||||
for _, r := range highlightRanges {
|
||||
style := colors.search
|
||||
style := m.theme.search
|
||||
if r.parent.index == m.searchResultsCursor {
|
||||
style = colors.cursor
|
||||
style = m.theme.cursor
|
||||
}
|
||||
out = append(out, withStyle{
|
||||
value: line[pos:r.start],
|
||||
|
42
reduce.go
42
reduce.go
@ -104,7 +104,7 @@ func fold(s []string) string {
|
||||
return fmt.Sprintf("x => Object.values(%v).flatMap(%v)", obj, fold(s[1:]))
|
||||
}
|
||||
|
||||
func reduce(object interface{}, args []string) {
|
||||
func reduce(object interface{}, args []string, theme Theme) {
|
||||
var stdout, stderr bytes.Buffer
|
||||
cmd := exec.Command("node", "-e", generateCode(args))
|
||||
cmd.Env = os.Environ()
|
||||
@ -121,7 +121,7 @@ func reduce(object interface{}, args []string) {
|
||||
if str, ok := jsonObject.(string); ok {
|
||||
fmt.Println(str)
|
||||
} else {
|
||||
fmt.Println(prettyPrint(jsonObject, 1))
|
||||
fmt.Println(prettyPrint(jsonObject, 1, theme))
|
||||
}
|
||||
} else {
|
||||
_, _ = fmt.Fprint(os.Stderr, stderr.String())
|
||||
@ -137,54 +137,54 @@ func reduce(object interface{}, args []string) {
|
||||
}
|
||||
}
|
||||
|
||||
func prettyPrint(v interface{}, level int) string {
|
||||
func prettyPrint(v interface{}, level int, theme Theme) string {
|
||||
ident := strings.Repeat(" ", level)
|
||||
subident := strings.Repeat(" ", level-1)
|
||||
switch v.(type) {
|
||||
case nil:
|
||||
return colors.null.Render("null")
|
||||
return theme.null("null")
|
||||
|
||||
case bool:
|
||||
if v.(bool) {
|
||||
return colors.boolean.Render("true")
|
||||
return theme.boolean("true")
|
||||
} else {
|
||||
return colors.boolean.Render("false")
|
||||
return theme.boolean("false")
|
||||
}
|
||||
|
||||
case number:
|
||||
return colors.number.Render(v.(number).String())
|
||||
return theme.number(v.(number).String())
|
||||
|
||||
case string:
|
||||
return colors.string.Render(fmt.Sprintf("%q", v))
|
||||
return theme.string(fmt.Sprintf("%q", v))
|
||||
|
||||
case *dict:
|
||||
keys := v.(*dict).keys
|
||||
if len(keys) == 0 {
|
||||
return colors.syntax.Render("{}")
|
||||
return theme.syntax("{}")
|
||||
}
|
||||
output := colors.syntax.Render("{\n")
|
||||
output := theme.syntax("{")
|
||||
output += "\n"
|
||||
for i, k := range keys {
|
||||
key := colors.key.Render(fmt.Sprintf("%q", k))
|
||||
key := theme.key(i, len(keys))(fmt.Sprintf("%q", k))
|
||||
value, _ := v.(*dict).get(k)
|
||||
delim := ": "
|
||||
line := ident + key + delim + prettyPrint(value, level+1)
|
||||
delim := theme.syntax(": ")
|
||||
line := ident + key + delim + prettyPrint(value, level+1, theme)
|
||||
if i < len(keys)-1 {
|
||||
line += ",\n"
|
||||
} else {
|
||||
line += "\n"
|
||||
line += theme.syntax(",")
|
||||
}
|
||||
line += "\n"
|
||||
output += line
|
||||
}
|
||||
return output + subident + colors.syntax.Render("}")
|
||||
return output + subident + theme.syntax("}")
|
||||
|
||||
case array:
|
||||
slice := v.(array)
|
||||
if len(slice) == 0 {
|
||||
return colors.syntax.Render("[]")
|
||||
return theme.syntax("[]")
|
||||
}
|
||||
output := colors.syntax.Render("[\n")
|
||||
output := theme.syntax("[\n")
|
||||
for i, value := range v.(array) {
|
||||
line := ident + prettyPrint(value, level+1)
|
||||
line := ident + prettyPrint(value, level+1, theme)
|
||||
if i < len(slice)-1 {
|
||||
line += ",\n"
|
||||
} else {
|
||||
@ -192,7 +192,7 @@ func prettyPrint(v interface{}, level int) string {
|
||||
}
|
||||
output += line
|
||||
}
|
||||
return output + subident + colors.syntax.Render("]")
|
||||
return output + subident + theme.syntax("]")
|
||||
|
||||
default:
|
||||
return "unknown type"
|
||||
|
185
theme.go
Normal file
185
theme.go
Normal file
@ -0,0 +1,185 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/charmbracelet/lipgloss"
|
||||
"github.com/mazznoer/colorgrad"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type Theme struct {
|
||||
cursor Color
|
||||
syntax Color
|
||||
preview Color
|
||||
statusBar Color
|
||||
search Color
|
||||
key func(i, len int) Color
|
||||
string Color
|
||||
null Color
|
||||
boolean Color
|
||||
number Color
|
||||
}
|
||||
type Color func(s string) string
|
||||
|
||||
func fg(color string) Color {
|
||||
return lipgloss.NewStyle().Foreground(lipgloss.Color(color)).Render
|
||||
}
|
||||
|
||||
func boldFg(color string) Color {
|
||||
return lipgloss.NewStyle().Bold(true).Foreground(lipgloss.Color(color)).Render
|
||||
}
|
||||
|
||||
var (
|
||||
defaultCursor = lipgloss.NewStyle().Reverse(true).Render
|
||||
defaultPreview = lipgloss.NewStyle().Bold(true).Foreground(lipgloss.Color("8")).Render
|
||||
defaultStatusBar = lipgloss.NewStyle().Background(lipgloss.Color("7")).Foreground(lipgloss.Color("0")).Render
|
||||
defaultSearch = lipgloss.NewStyle().Background(lipgloss.Color("11")).Foreground(lipgloss.Color("16")).Render
|
||||
defaultNull = fg("8")
|
||||
)
|
||||
|
||||
var themes = map[string]Theme{
|
||||
"0": {
|
||||
cursor: defaultCursor,
|
||||
syntax: noColor,
|
||||
preview: noColor,
|
||||
statusBar: noColor,
|
||||
search: defaultSearch,
|
||||
key: func(_, _ int) Color { return noColor },
|
||||
string: noColor,
|
||||
null: noColor,
|
||||
boolean: noColor,
|
||||
number: noColor,
|
||||
},
|
||||
"1": {
|
||||
cursor: defaultCursor,
|
||||
syntax: noColor,
|
||||
preview: defaultPreview,
|
||||
statusBar: defaultStatusBar,
|
||||
search: defaultSearch,
|
||||
key: func(_, _ int) Color { return boldFg("4") },
|
||||
string: boldFg("2"),
|
||||
null: defaultNull,
|
||||
boolean: boldFg("3"),
|
||||
number: boldFg("6"),
|
||||
},
|
||||
"2": {
|
||||
cursor: defaultCursor,
|
||||
syntax: noColor,
|
||||
preview: defaultPreview,
|
||||
statusBar: defaultStatusBar,
|
||||
search: defaultSearch,
|
||||
key: func(_, _ int) Color { return fg("#00F5D4") },
|
||||
string: fg("#00BBF9"),
|
||||
null: defaultNull,
|
||||
boolean: fg("#F15BB5"),
|
||||
number: fg("#9B5DE5"),
|
||||
},
|
||||
"3": {
|
||||
cursor: defaultCursor,
|
||||
syntax: noColor,
|
||||
preview: defaultPreview,
|
||||
statusBar: defaultStatusBar,
|
||||
search: defaultSearch,
|
||||
key: func(_, _ int) Color { return fg("#faf0ca") },
|
||||
string: fg("#f4d35e"),
|
||||
null: defaultNull,
|
||||
boolean: fg("#ee964b"),
|
||||
number: fg("#ee964b"),
|
||||
},
|
||||
"4": {
|
||||
cursor: defaultCursor,
|
||||
syntax: noColor,
|
||||
preview: defaultPreview,
|
||||
statusBar: defaultStatusBar,
|
||||
search: defaultSearch,
|
||||
key: func(_, _ int) Color { return fg("#4D96FF") },
|
||||
string: fg("#6BCB77"),
|
||||
null: defaultNull,
|
||||
boolean: fg("#FF6B6B"),
|
||||
number: fg("#FFD93D"),
|
||||
},
|
||||
"5": {
|
||||
cursor: defaultCursor,
|
||||
syntax: noColor,
|
||||
preview: defaultPreview,
|
||||
statusBar: defaultStatusBar,
|
||||
search: defaultSearch,
|
||||
key: func(_, _ int) Color { return boldFg("42") },
|
||||
string: boldFg("213"),
|
||||
null: defaultNull,
|
||||
boolean: boldFg("201"),
|
||||
number: boldFg("201"),
|
||||
},
|
||||
"6": {
|
||||
cursor: defaultCursor,
|
||||
syntax: noColor,
|
||||
preview: defaultPreview,
|
||||
statusBar: defaultStatusBar,
|
||||
search: defaultSearch,
|
||||
key: func(_, _ int) Color { return gradient("rgb(125,110,221)", "rgb(90%,45%,97%)", "hsl(229,79%,85%)") },
|
||||
string: fg("195"),
|
||||
null: defaultNull,
|
||||
boolean: fg("195"),
|
||||
number: fg("195"),
|
||||
},
|
||||
"7": {
|
||||
cursor: defaultCursor,
|
||||
syntax: noColor,
|
||||
preview: defaultPreview,
|
||||
statusBar: defaultStatusBar,
|
||||
search: defaultSearch,
|
||||
key: func(_, _ int) Color { return gradient("rgb(123,216,96)", "rgb(255,255,255)") },
|
||||
string: noColor,
|
||||
null: defaultNull,
|
||||
boolean: noColor,
|
||||
number: noColor,
|
||||
},
|
||||
"8": {
|
||||
cursor: defaultCursor,
|
||||
syntax: noColor,
|
||||
preview: defaultPreview,
|
||||
statusBar: defaultStatusBar,
|
||||
search: defaultSearch,
|
||||
key: gradientKeys("#ff0000", "#ff8700", "#ffd300", "#deff0a", "#a1ff0a", "#0aff99", "#0aefff", "#147df5", "#580aff", "#be0aff"),
|
||||
string: noColor,
|
||||
null: defaultNull,
|
||||
boolean: noColor,
|
||||
number: noColor,
|
||||
},
|
||||
"9": {
|
||||
cursor: defaultCursor,
|
||||
syntax: noColor,
|
||||
preview: defaultPreview,
|
||||
statusBar: defaultStatusBar,
|
||||
search: defaultSearch,
|
||||
key: gradientKeys("rgb(34,126,34)", "rgb(168,251,60)"),
|
||||
string: gradient("rgb(34,126,34)", "rgb(168,251,60)"),
|
||||
null: defaultNull,
|
||||
boolean: noColor,
|
||||
number: noColor,
|
||||
},
|
||||
}
|
||||
|
||||
func noColor(s string) string {
|
||||
return s
|
||||
}
|
||||
|
||||
func gradient(colors ...string) Color {
|
||||
grad, _ := colorgrad.NewGradient().HtmlColors(colors...).Build()
|
||||
return func(s string) string {
|
||||
runes := []rune(s)
|
||||
colors := grad.ColorfulColors(uint(len(runes)))
|
||||
var out strings.Builder
|
||||
for i, r := range runes {
|
||||
style := lipgloss.NewStyle().Foreground(lipgloss.Color(colors[i].Hex()))
|
||||
out.WriteString(style.Render(string(r)))
|
||||
}
|
||||
return out.String()
|
||||
}
|
||||
}
|
||||
|
||||
func gradientKeys(colors ...string) func(i, len int) Color {
|
||||
grad, _ := colorgrad.NewGradient().HtmlColors(colors...).Build()
|
||||
return func(i, len int) Color {
|
||||
return lipgloss.NewStyle().Foreground(lipgloss.Color(grad.At(float64(i) / float64(len)).Hex())).Render
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user