Gim/internal/theme/theme.go
Hayden Hargreaves 1c2585b8d9 feat: Implemented syntax styles
Treesitter integration implemented! But tests are failing, need to
resolve that.
2026-04-07 22:34:42 -07:00

106 lines
2.4 KiB
Go

package theme
import (
"strings"
"git.gophernest.net/azpect/TextEditor/internal/core"
"github.com/charmbracelet/lipgloss"
)
type EditorTheme struct {
Cursors CursorTheme
Gutter GutterTheme
VisualHightlight lipgloss.Style
StatusBar StatusBarTheme
CommandLine CommandLineTheme
Line lipgloss.Style
Background lipgloss.Style
Syntax SyntaxTheme
}
type CursorTheme struct {
Normal lipgloss.Style
Insert lipgloss.Style
Command lipgloss.Style
Replace lipgloss.Style
}
type GutterTheme struct {
Default lipgloss.Style
CurrentLine lipgloss.Style
}
type StatusBarTheme struct {
Default lipgloss.Style
}
type CommandLineTheme struct {
Error lipgloss.Style
OutputBorder lipgloss.Style
ContinueMessage lipgloss.Style
}
type SyntaxTheme struct {
Exact map[string]lipgloss.Style
Group map[string]lipgloss.Style
}
func (t EditorTheme) Cursor(mode core.Mode, textStyle lipgloss.Style) lipgloss.Style {
bg := textStyle.GetBackground()
fg := textStyle.GetForeground()
switch mode {
case core.NormalMode, core.VisualLineMode, core.VisualBlockMode, core.VisualMode:
return lipgloss.NewStyle().
Background(fg).
Foreground(bg)
case core.ReplaceMode, core.WaitingMode:
return textStyle.
Underline(true)
default:
return t.Background.
Foreground(fg).
Underline(true)
}
}
func (t EditorTheme) DefaultCursor(mode core.Mode) lipgloss.Style {
switch mode {
case core.InsertMode:
return t.Cursors.Insert
case core.CommandMode:
return t.Cursors.Command
case core.ReplaceMode:
return t.Cursors.Replace
default:
return t.Cursors.Normal
}
}
// This method is preferred to raw access of EditorTheme.VisualHightlight since
// is has the proper foreground color applied
func (t EditorTheme) VisualHighlightWithTextColor(textStyle lipgloss.Style) lipgloss.Style {
return t.VisualHightlight.
Foreground(textStyle.GetForeground())
}
// Use base (Line) as fallback. Every style will use the background from the base (Line).
//
// NOTE: Maybe we keep background on the mapping? Not sure for now
func (t EditorTheme) CaptureStyle(capture string) lipgloss.Style {
base := t.Line
exact := strings.ToLower(strings.TrimSpace(capture))
group := strings.Split(exact, ".")[0]
if sty, ok := t.Syntax.Exact[exact]; ok {
return sty.Background(base.GetBackground())
}
if sty, ok := t.Syntax.Group[group]; ok {
return sty.Background(base.GetBackground())
}
return base
}