mirror of
https://github.com/sst/opencode.git
synced 2025-08-03 21:28:14 +00:00
chore: cleanup
This commit is contained in:
parent
4bb350a09b
commit
8cbfc581b5
28 changed files with 186 additions and 236 deletions
|
@ -58,4 +58,3 @@ func MarkProjectInitialized() error {
|
|||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -88,8 +88,6 @@ func (b *agentTool) Run(ctx context.Context, call tools.ToolCall) (tools.ToolRes
|
|||
}
|
||||
|
||||
parentSession.Cost += updatedSession.Cost
|
||||
parentSession.PromptTokens += updatedSession.PromptTokens
|
||||
parentSession.CompletionTokens += updatedSession.CompletionTokens
|
||||
|
||||
_, err = b.sessions.Update(ctx, parentSession)
|
||||
if err != nil {
|
||||
|
|
|
@ -300,53 +300,6 @@ func (a *agent) createUserMessage(ctx context.Context, sessionID, content string
|
|||
}
|
||||
|
||||
func (a *agent) streamAndHandleEvents(ctx context.Context, sessionID string, msgHistory []message.Message) (message.Message, *message.Message, error) {
|
||||
// Check if we need to auto-compact based on token count
|
||||
contextWindow := a.provider.Model().ContextWindow
|
||||
maxTokens := a.provider.MaxTokens()
|
||||
threshold := int64(float64(contextWindow) * 0.80)
|
||||
usage, err := a.GetUsage(ctx, sessionID)
|
||||
if err != nil || usage == nil {
|
||||
return message.Message{}, nil, fmt.Errorf("failed to get usage: %w", err)
|
||||
}
|
||||
|
||||
// If we're approaching the context window limit, trigger auto-compaction
|
||||
if false && (*usage+maxTokens) >= threshold {
|
||||
status.Info(fmt.Sprintf("Auto-compaction triggered for session %s. Estimated tokens: %d, Threshold: %d", sessionID, usage, threshold))
|
||||
|
||||
// Perform compaction with pause/resume to ensure safety
|
||||
if err := a.CompactSession(ctx, sessionID); err != nil {
|
||||
status.Error(fmt.Sprintf("Auto-compaction failed: %v", err))
|
||||
// Continue with the request even if compaction fails
|
||||
} else {
|
||||
// Re-fetch session details after compaction
|
||||
currentSession, err := a.sessions.Get(ctx, sessionID)
|
||||
if err != nil {
|
||||
return message.Message{}, nil, fmt.Errorf("failed to get session after compaction: %w", err)
|
||||
}
|
||||
|
||||
// Re-prepare messages using the new summary
|
||||
var sessionMessages []message.Message
|
||||
if currentSession.Summary != "" && currentSession.SummarizedAt > 0 {
|
||||
// If summary exists, only fetch messages after the summarization timestamp
|
||||
sessionMessages, err = a.messages.ListAfter(ctx, sessionID, currentSession.SummarizedAt)
|
||||
if err != nil {
|
||||
return message.Message{}, nil, fmt.Errorf("failed to list messages after compaction: %w", err)
|
||||
}
|
||||
|
||||
// Create a new message history with the summary and messages after summarization
|
||||
summaryMessage := message.Message{
|
||||
Role: message.Assistant,
|
||||
Parts: []message.ContentPart{
|
||||
message.TextContent{Text: currentSession.Summary},
|
||||
},
|
||||
}
|
||||
|
||||
// Replace msgHistory with the new compacted version
|
||||
msgHistory = append([]message.Message{summaryMessage}, sessionMessages...)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
eventChan := a.provider.StreamResponse(ctx, msgHistory, a.tools)
|
||||
|
||||
assistantMsg, err := a.messages.Create(ctx, sessionID, message.CreateMessageParams{
|
||||
|
@ -541,8 +494,8 @@ func (a *agent) TrackUsage(ctx context.Context, sessionID string, model models.M
|
|||
model.CostPer1MOut/1e6*float64(usage.OutputTokens)
|
||||
|
||||
sess.Cost += cost
|
||||
sess.CompletionTokens += usage.OutputTokens
|
||||
sess.PromptTokens += usage.InputTokens
|
||||
sess.CompletionTokens = usage.OutputTokens + usage.CacheReadTokens
|
||||
sess.PromptTokens = usage.InputTokens + usage.CacheCreationTokens
|
||||
|
||||
_, err = a.sessions.Update(ctx, sess)
|
||||
if err != nil {
|
||||
|
@ -646,7 +599,16 @@ func (a *agent) CompactSession(ctx context.Context, sessionID string) error {
|
|||
Role: message.System,
|
||||
Parts: []message.ContentPart{
|
||||
message.TextContent{
|
||||
Text: "You are a helpful AI assistant tasked with summarizing conversations.",
|
||||
Text: `You are a helpful AI assistant tasked with summarizing conversations.
|
||||
|
||||
When asked to summarize, provide a detailed but concise summary of the conversation.
|
||||
Focus on information that would be helpful for continuing the conversation, including:
|
||||
- What was done
|
||||
- What is currently being worked on
|
||||
- Which files are being modified
|
||||
- What needs to be done next
|
||||
|
||||
Your summary should be comprehensive enough to provide context but concise enough to be quickly understood.`,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -655,7 +617,7 @@ func (a *agent) CompactSession(ctx context.Context, sessionID string) error {
|
|||
// If there's an existing summary, include it
|
||||
if existingSummary != "" {
|
||||
messages = append(messages, message.Message{
|
||||
Role: message.Assistant, // TODO: should this be system or user instead?
|
||||
Role: message.Assistant,
|
||||
Parts: []message.ContentPart{
|
||||
message.TextContent{
|
||||
Text: existingSummary,
|
||||
|
|
|
@ -98,4 +98,3 @@ func (b *bedrockClient) stream(ctx context.Context, messages []message.Message,
|
|||
|
||||
return b.childProvider.stream(ctx, messages, tools)
|
||||
}
|
||||
|
||||
|
|
|
@ -83,19 +83,19 @@ func TestLsTool_Run(t *testing.T) {
|
|||
|
||||
response, err := tool.Run(context.Background(), call)
|
||||
require.NoError(t, err)
|
||||
|
||||
|
||||
// Check that visible directories and files are included
|
||||
assert.Contains(t, response.Content, "dir1")
|
||||
assert.Contains(t, response.Content, "dir2")
|
||||
assert.Contains(t, response.Content, "dir3")
|
||||
assert.Contains(t, response.Content, "file1.txt")
|
||||
assert.Contains(t, response.Content, "file2.txt")
|
||||
|
||||
|
||||
// Check that hidden files and directories are not included
|
||||
assert.NotContains(t, response.Content, ".hidden_dir")
|
||||
assert.NotContains(t, response.Content, ".hidden_file.txt")
|
||||
assert.NotContains(t, response.Content, ".hidden_root_file.txt")
|
||||
|
||||
|
||||
// Check that __pycache__ is not included
|
||||
assert.NotContains(t, response.Content, "__pycache__")
|
||||
})
|
||||
|
@ -122,7 +122,7 @@ func TestLsTool_Run(t *testing.T) {
|
|||
t.Run("handles empty path parameter", func(t *testing.T) {
|
||||
// For this test, we need to mock the config.WorkingDirectory function
|
||||
// Since we can't easily do that, we'll just check that the response doesn't contain an error message
|
||||
|
||||
|
||||
tool := NewLsTool()
|
||||
params := LSParams{
|
||||
Path: "",
|
||||
|
@ -138,7 +138,7 @@ func TestLsTool_Run(t *testing.T) {
|
|||
|
||||
response, err := tool.Run(context.Background(), call)
|
||||
require.NoError(t, err)
|
||||
|
||||
|
||||
// The response should either contain a valid directory listing or an error
|
||||
// We'll just check that it's not empty
|
||||
assert.NotEmpty(t, response.Content)
|
||||
|
@ -173,11 +173,11 @@ func TestLsTool_Run(t *testing.T) {
|
|||
|
||||
response, err := tool.Run(context.Background(), call)
|
||||
require.NoError(t, err)
|
||||
|
||||
|
||||
// The output format is a tree, so we need to check for specific patterns
|
||||
// Check that file1.txt is not directly mentioned
|
||||
assert.NotContains(t, response.Content, "- file1.txt")
|
||||
|
||||
|
||||
// Check that dir1/ is not directly mentioned
|
||||
assert.NotContains(t, response.Content, "- dir1/")
|
||||
})
|
||||
|
@ -189,12 +189,12 @@ func TestLsTool_Run(t *testing.T) {
|
|||
defer func() {
|
||||
os.Chdir(origWd)
|
||||
}()
|
||||
|
||||
|
||||
// Change to a directory above the temp directory
|
||||
parentDir := filepath.Dir(tempDir)
|
||||
err = os.Chdir(parentDir)
|
||||
require.NoError(t, err)
|
||||
|
||||
|
||||
tool := NewLsTool()
|
||||
params := LSParams{
|
||||
Path: filepath.Base(tempDir),
|
||||
|
@ -210,7 +210,7 @@ func TestLsTool_Run(t *testing.T) {
|
|||
|
||||
response, err := tool.Run(context.Background(), call)
|
||||
require.NoError(t, err)
|
||||
|
||||
|
||||
// Should list the temp directory contents
|
||||
assert.Contains(t, response.Content, "dir1")
|
||||
assert.Contains(t, response.Content, "file1.txt")
|
||||
|
@ -291,22 +291,22 @@ func TestCreateFileTree(t *testing.T) {
|
|||
}
|
||||
|
||||
tree := createFileTree(paths)
|
||||
|
||||
|
||||
// Check the structure of the tree
|
||||
assert.Len(t, tree, 1) // Should have one root node
|
||||
|
||||
|
||||
// Check the root node
|
||||
rootNode := tree[0]
|
||||
assert.Equal(t, "path", rootNode.Name)
|
||||
assert.Equal(t, "directory", rootNode.Type)
|
||||
assert.Len(t, rootNode.Children, 1)
|
||||
|
||||
|
||||
// Check the "to" node
|
||||
toNode := rootNode.Children[0]
|
||||
assert.Equal(t, "to", toNode.Name)
|
||||
assert.Equal(t, "directory", toNode.Type)
|
||||
assert.Len(t, toNode.Children, 3) // file1.txt, dir1, dir2
|
||||
|
||||
|
||||
// Find the dir1 node
|
||||
var dir1Node *TreeNode
|
||||
for _, child := range toNode.Children {
|
||||
|
@ -315,7 +315,7 @@ func TestCreateFileTree(t *testing.T) {
|
|||
break
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
require.NotNil(t, dir1Node)
|
||||
assert.Equal(t, "directory", dir1Node.Type)
|
||||
assert.Len(t, dir1Node.Children, 2) // file2.txt and subdir
|
||||
|
@ -354,9 +354,9 @@ func TestPrintTree(t *testing.T) {
|
|||
Type: "file",
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
result := printTree(tree, "/root")
|
||||
|
||||
|
||||
// Check the output format
|
||||
assert.Contains(t, result, "- /root/")
|
||||
assert.Contains(t, result, " - dir1/")
|
||||
|
@ -405,7 +405,7 @@ func TestListDirectory(t *testing.T) {
|
|||
files, truncated, err := listDirectory(tempDir, []string{}, 1000)
|
||||
require.NoError(t, err)
|
||||
assert.False(t, truncated)
|
||||
|
||||
|
||||
// Check that visible files and directories are included
|
||||
containsPath := func(paths []string, target string) bool {
|
||||
targetPath := filepath.Join(tempDir, target)
|
||||
|
@ -416,12 +416,12 @@ func TestListDirectory(t *testing.T) {
|
|||
}
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
assert.True(t, containsPath(files, "dir1"))
|
||||
assert.True(t, containsPath(files, "file1.txt"))
|
||||
assert.True(t, containsPath(files, "file2.txt"))
|
||||
assert.True(t, containsPath(files, "dir1/file3.txt"))
|
||||
|
||||
|
||||
// Check that hidden files and directories are not included
|
||||
assert.False(t, containsPath(files, ".hidden_dir"))
|
||||
assert.False(t, containsPath(files, ".hidden_file.txt"))
|
||||
|
@ -438,12 +438,12 @@ func TestListDirectory(t *testing.T) {
|
|||
files, truncated, err := listDirectory(tempDir, []string{"*.txt"}, 1000)
|
||||
require.NoError(t, err)
|
||||
assert.False(t, truncated)
|
||||
|
||||
|
||||
// Check that no .txt files are included
|
||||
for _, file := range files {
|
||||
assert.False(t, strings.HasSuffix(file, ".txt"), "Found .txt file: %s", file)
|
||||
}
|
||||
|
||||
|
||||
// But directories should still be included
|
||||
containsDir := false
|
||||
for _, file := range files {
|
||||
|
@ -454,4 +454,4 @@ func TestListDirectory(t *testing.T) {
|
|||
}
|
||||
assert.True(t, containsDir)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,6 @@ import (
|
|||
"os"
|
||||
"runtime/debug"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/go-logfmt/logfmt"
|
||||
|
@ -45,7 +44,6 @@ type Service interface {
|
|||
type service struct {
|
||||
db *db.Queries
|
||||
broker *pubsub.Broker[Log]
|
||||
mu sync.RWMutex
|
||||
}
|
||||
|
||||
var globalLoggingService *service
|
||||
|
@ -72,9 +70,6 @@ func GetService() Service {
|
|||
}
|
||||
|
||||
func (s *service) Create(ctx context.Context, log Log) error {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
|
||||
if log.ID == "" {
|
||||
log.ID = uuid.New().String()
|
||||
}
|
||||
|
@ -115,9 +110,6 @@ func (s *service) Create(ctx context.Context, log Log) error {
|
|||
}
|
||||
|
||||
func (s *service) ListBySession(ctx context.Context, sessionID string) ([]Log, error) {
|
||||
s.mu.RLock()
|
||||
defer s.mu.RUnlock()
|
||||
|
||||
dbLogs, err := s.db.ListLogsBySession(ctx, sql.NullString{String: sessionID, Valid: true})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("db.ListLogsBySession: %w", err)
|
||||
|
@ -126,9 +118,6 @@ func (s *service) ListBySession(ctx context.Context, sessionID string) ([]Log, e
|
|||
}
|
||||
|
||||
func (s *service) ListAll(ctx context.Context, limit int) ([]Log, error) {
|
||||
s.mu.RLock()
|
||||
defer s.mu.RUnlock()
|
||||
|
||||
dbLogs, err := s.db.ListAllLogs(ctx, int64(limit))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("db.ListAllLogs: %w", err)
|
||||
|
|
|
@ -296,4 +296,3 @@ func GetLanguageIDFromPath(path string) string {
|
|||
langKind := lsp.DetectLanguageID(uri)
|
||||
return GetLanguageIDFromProtocol(string(langKind))
|
||||
}
|
||||
|
||||
|
|
|
@ -304,4 +304,3 @@ func ConfigureLSPServers(rootDir string) (map[string]ServerInfo, error) {
|
|||
|
||||
return servers, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -142,4 +142,3 @@ func TestBrokerConcurrency(t *testing.T) {
|
|||
}
|
||||
assert.Equal(t, numSubscribers, count)
|
||||
}
|
||||
|
||||
|
|
|
@ -170,4 +170,3 @@ type ShowArgumentsDialogMsg struct {
|
|||
CommandID string
|
||||
Content string
|
||||
}
|
||||
|
||||
|
|
|
@ -115,7 +115,7 @@ func (c *commandDialogCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|||
func (c *commandDialogCmp) View() string {
|
||||
t := theme.CurrentTheme()
|
||||
baseStyle := styles.BaseStyle()
|
||||
|
||||
|
||||
if len(c.commands) == 0 {
|
||||
return baseStyle.Padding(1, 2).
|
||||
Border(lipgloss.RoundedBorder()).
|
||||
|
|
|
@ -95,7 +95,7 @@ func (m InitDialogCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|||
func (m InitDialogCmp) View() string {
|
||||
t := theme.CurrentTheme()
|
||||
baseStyle := styles.BaseStyle()
|
||||
|
||||
|
||||
// Calculate width needed for content
|
||||
maxWidth := 60 // Width for explanation text
|
||||
|
||||
|
|
|
@ -150,7 +150,7 @@ func (p *permissionDialogCmp) selectCurrentOption() tea.Cmd {
|
|||
func (p *permissionDialogCmp) renderButtons() string {
|
||||
t := theme.CurrentTheme()
|
||||
baseStyle := styles.BaseStyle()
|
||||
|
||||
|
||||
allowStyle := baseStyle
|
||||
allowSessionStyle := baseStyle
|
||||
denyStyle := baseStyle
|
||||
|
@ -196,7 +196,7 @@ func (p *permissionDialogCmp) renderButtons() string {
|
|||
func (p *permissionDialogCmp) renderHeader() string {
|
||||
t := theme.CurrentTheme()
|
||||
baseStyle := styles.BaseStyle()
|
||||
|
||||
|
||||
toolKey := baseStyle.Foreground(t.TextMuted()).Bold(true).Render("Tool")
|
||||
toolValue := baseStyle.
|
||||
Foreground(t.Text()).
|
||||
|
@ -242,13 +242,13 @@ func (p *permissionDialogCmp) renderHeader() string {
|
|||
func (p *permissionDialogCmp) renderBashContent() string {
|
||||
t := theme.CurrentTheme()
|
||||
baseStyle := styles.BaseStyle()
|
||||
|
||||
|
||||
if pr, ok := p.permission.Params.(tools.BashPermissionsParams); ok {
|
||||
content := fmt.Sprintf("```bash\n%s\n```", pr.Command)
|
||||
|
||||
// Use the cache for markdown rendering
|
||||
renderedContent := p.GetOrSetMarkdown(p.permission.ID, func() (string, error) {
|
||||
r := styles.GetMarkdownRenderer(p.width-10)
|
||||
r := styles.GetMarkdownRenderer(p.width - 10)
|
||||
s, err := r.Render(content)
|
||||
return styles.ForceReplaceBackgroundWithLipgloss(s, t.Background()), err
|
||||
})
|
||||
|
@ -302,13 +302,13 @@ func (p *permissionDialogCmp) renderWriteContent() string {
|
|||
func (p *permissionDialogCmp) renderFetchContent() string {
|
||||
t := theme.CurrentTheme()
|
||||
baseStyle := styles.BaseStyle()
|
||||
|
||||
|
||||
if pr, ok := p.permission.Params.(tools.FetchPermissionsParams); ok {
|
||||
content := fmt.Sprintf("```bash\n%s\n```", pr.URL)
|
||||
|
||||
// Use the cache for markdown rendering
|
||||
renderedContent := p.GetOrSetMarkdown(p.permission.ID, func() (string, error) {
|
||||
r := styles.GetMarkdownRenderer(p.width-10)
|
||||
r := styles.GetMarkdownRenderer(p.width - 10)
|
||||
s, err := r.Render(content)
|
||||
return styles.ForceReplaceBackgroundWithLipgloss(s, t.Background()), err
|
||||
})
|
||||
|
@ -325,12 +325,12 @@ func (p *permissionDialogCmp) renderFetchContent() string {
|
|||
func (p *permissionDialogCmp) renderDefaultContent() string {
|
||||
t := theme.CurrentTheme()
|
||||
baseStyle := styles.BaseStyle()
|
||||
|
||||
|
||||
content := p.permission.Description
|
||||
|
||||
// Use the cache for markdown rendering
|
||||
renderedContent := p.GetOrSetMarkdown(p.permission.ID, func() (string, error) {
|
||||
r := styles.GetMarkdownRenderer(p.width-10)
|
||||
r := styles.GetMarkdownRenderer(p.width - 10)
|
||||
s, err := r.Render(content)
|
||||
return styles.ForceReplaceBackgroundWithLipgloss(s, t.Background()), err
|
||||
})
|
||||
|
@ -358,7 +358,7 @@ func (p *permissionDialogCmp) styleViewport() string {
|
|||
func (p *permissionDialogCmp) render() string {
|
||||
t := theme.CurrentTheme()
|
||||
baseStyle := styles.BaseStyle()
|
||||
|
||||
|
||||
title := baseStyle.
|
||||
Bold(true).
|
||||
Width(p.width - 4).
|
||||
|
|
|
@ -84,7 +84,7 @@ func (q *quitDialogCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|||
func (q *quitDialogCmp) View() string {
|
||||
t := theme.CurrentTheme()
|
||||
baseStyle := styles.BaseStyle()
|
||||
|
||||
|
||||
yesStyle := baseStyle
|
||||
noStyle := baseStyle
|
||||
spacerStyle := baseStyle.Background(t.Background())
|
||||
|
|
|
@ -96,7 +96,7 @@ func (i *detailCmp) updateContent() {
|
|||
valueStyle := lipgloss.NewStyle().Foreground(t.Text())
|
||||
|
||||
for key, value := range i.currentLog.Attributes {
|
||||
attrLine := fmt.Sprintf("%s: %s",
|
||||
attrLine := fmt.Sprintf("%s: %s",
|
||||
keyStyle.Render(key),
|
||||
valueStyle.Render(value),
|
||||
)
|
||||
|
|
|
@ -31,7 +31,7 @@ type container struct {
|
|||
borderBottom bool
|
||||
borderLeft bool
|
||||
borderStyle lipgloss.Border
|
||||
|
||||
|
||||
focused bool // Track focus state
|
||||
}
|
||||
|
||||
|
@ -69,7 +69,7 @@ func (c *container) View() string {
|
|||
width--
|
||||
}
|
||||
style = style.Border(c.borderStyle, c.borderTop, c.borderRight, c.borderBottom, c.borderLeft)
|
||||
|
||||
|
||||
// Use primary color for border if focused
|
||||
if c.focused {
|
||||
style = style.BorderBackground(t.Background()).BorderForeground(t.Primary())
|
||||
|
|
|
@ -196,7 +196,7 @@ func (p *logsPage) Init() tea.Cmd {
|
|||
var cmds []tea.Cmd
|
||||
cmds = append(cmds, p.table.Init())
|
||||
cmds = append(cmds, p.details.Init())
|
||||
|
||||
|
||||
// Send a key down and then key up to select the first row
|
||||
// This ensures the details pane is populated when returning to the logs page
|
||||
cmds = append(cmds, func() tea.Msg {
|
||||
|
@ -205,7 +205,7 @@ func (p *logsPage) Init() tea.Cmd {
|
|||
cmds = append(cmds, func() tea.Msg {
|
||||
return tea.KeyMsg{Type: tea.KeyUp}
|
||||
})
|
||||
|
||||
|
||||
return tea.Batch(cmds...)
|
||||
}
|
||||
|
||||
|
|
|
@ -245,4 +245,4 @@ func NewCatppuccinTheme() *CatppuccinTheme {
|
|||
func init() {
|
||||
// Register the Catppuccin theme with the theme manager
|
||||
RegisterTheme("catppuccin", NewCatppuccinTheme())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -271,4 +271,4 @@ func NewDraculaTheme() *DraculaTheme {
|
|||
func init() {
|
||||
// Register the Dracula theme with the theme manager
|
||||
RegisterTheme("dracula", NewDraculaTheme())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,20 +7,20 @@ import (
|
|||
// Flexoki color palette constants
|
||||
const (
|
||||
// Base colors
|
||||
flexokiPaper = "#FFFCF0" // Paper (lightest)
|
||||
flexokiBase50 = "#F2F0E5" // bg-2 (light)
|
||||
flexokiBase100 = "#E6E4D9" // ui (light)
|
||||
flexokiBase150 = "#DAD8CE" // ui-2 (light)
|
||||
flexokiBase200 = "#CECDC3" // ui-3 (light)
|
||||
flexokiBase300 = "#B7B5AC" // tx-3 (light)
|
||||
flexokiBase500 = "#878580" // tx-2 (light)
|
||||
flexokiBase600 = "#6F6E69" // tx (light)
|
||||
flexokiBase700 = "#575653" // tx-3 (dark)
|
||||
flexokiBase800 = "#403E3C" // ui-3 (dark)
|
||||
flexokiBase850 = "#343331" // ui-2 (dark)
|
||||
flexokiBase900 = "#282726" // ui (dark)
|
||||
flexokiBase950 = "#1C1B1A" // bg-2 (dark)
|
||||
flexokiBlack = "#100F0F" // bg (darkest)
|
||||
flexokiPaper = "#FFFCF0" // Paper (lightest)
|
||||
flexokiBase50 = "#F2F0E5" // bg-2 (light)
|
||||
flexokiBase100 = "#E6E4D9" // ui (light)
|
||||
flexokiBase150 = "#DAD8CE" // ui-2 (light)
|
||||
flexokiBase200 = "#CECDC3" // ui-3 (light)
|
||||
flexokiBase300 = "#B7B5AC" // tx-3 (light)
|
||||
flexokiBase500 = "#878580" // tx-2 (light)
|
||||
flexokiBase600 = "#6F6E69" // tx (light)
|
||||
flexokiBase700 = "#575653" // tx-3 (dark)
|
||||
flexokiBase800 = "#403E3C" // ui-3 (dark)
|
||||
flexokiBase850 = "#343331" // ui-2 (dark)
|
||||
flexokiBase900 = "#282726" // ui (dark)
|
||||
flexokiBase950 = "#1C1B1A" // bg-2 (dark)
|
||||
flexokiBlack = "#100F0F" // bg (darkest)
|
||||
|
||||
// Accent colors - Light theme (600)
|
||||
flexokiRed600 = "#AF3029"
|
||||
|
@ -279,4 +279,4 @@ func NewFlexokiTheme() *FlexokiTheme {
|
|||
func init() {
|
||||
// Register the Flexoki theme with the theme manager
|
||||
RegisterTheme("flexoki", NewFlexokiTheme())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -173,11 +173,11 @@ func NewGruvboxTheme() *GruvboxTheme {
|
|||
Light: gruvboxLightRedBright,
|
||||
}
|
||||
theme.DiffAddedBgColor = lipgloss.AdaptiveColor{
|
||||
Dark: "#3C4C3C", // Darker green background
|
||||
Dark: "#3C4C3C", // Darker green background
|
||||
Light: "#E8F5E9", // Light green background
|
||||
}
|
||||
theme.DiffRemovedBgColor = lipgloss.AdaptiveColor{
|
||||
Dark: "#4C3C3C", // Darker red background
|
||||
Dark: "#4C3C3C", // Darker red background
|
||||
Light: "#FFEBEE", // Light red background
|
||||
}
|
||||
theme.DiffContextBgColor = lipgloss.AdaptiveColor{
|
||||
|
@ -189,11 +189,11 @@ func NewGruvboxTheme() *GruvboxTheme {
|
|||
Light: gruvboxLightFg4,
|
||||
}
|
||||
theme.DiffAddedLineNumberBgColor = lipgloss.AdaptiveColor{
|
||||
Dark: "#32432F", // Slightly darker green
|
||||
Dark: "#32432F", // Slightly darker green
|
||||
Light: "#C8E6C9", // Light green
|
||||
}
|
||||
theme.DiffRemovedLineNumberBgColor = lipgloss.AdaptiveColor{
|
||||
Dark: "#43322F", // Slightly darker red
|
||||
Dark: "#43322F", // Slightly darker red
|
||||
Light: "#FFCDD2", // Light red
|
||||
}
|
||||
|
||||
|
@ -299,4 +299,4 @@ func NewGruvboxTheme() *GruvboxTheme {
|
|||
func init() {
|
||||
// Register the Gruvbox theme with the theme manager
|
||||
RegisterTheme("gruvbox", NewGruvboxTheme())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -270,4 +270,4 @@ func NewMonokaiProTheme() *MonokaiProTheme {
|
|||
func init() {
|
||||
// Register the Monokai Pro theme with the theme manager
|
||||
RegisterTheme("monokai", NewMonokaiProTheme())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -271,4 +271,4 @@ func NewOneDarkTheme() *OneDarkTheme {
|
|||
func init() {
|
||||
// Register the One Dark theme with the theme manager
|
||||
RegisterTheme("onedark", NewOneDarkTheme())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -274,4 +274,3 @@ func init() {
|
|||
// Register the OpenCode theme with the theme manager
|
||||
RegisterTheme("opencode", NewOpenCodeTheme())
|
||||
}
|
||||
|
||||
|
|
|
@ -83,25 +83,25 @@ type Theme interface {
|
|||
// that can be embedded in concrete theme implementations.
|
||||
type BaseTheme struct {
|
||||
// Base colors
|
||||
PrimaryColor lipgloss.AdaptiveColor
|
||||
SecondaryColor lipgloss.AdaptiveColor
|
||||
AccentColor lipgloss.AdaptiveColor
|
||||
PrimaryColor lipgloss.AdaptiveColor
|
||||
SecondaryColor lipgloss.AdaptiveColor
|
||||
AccentColor lipgloss.AdaptiveColor
|
||||
|
||||
// Status colors
|
||||
ErrorColor lipgloss.AdaptiveColor
|
||||
WarningColor lipgloss.AdaptiveColor
|
||||
SuccessColor lipgloss.AdaptiveColor
|
||||
InfoColor lipgloss.AdaptiveColor
|
||||
ErrorColor lipgloss.AdaptiveColor
|
||||
WarningColor lipgloss.AdaptiveColor
|
||||
SuccessColor lipgloss.AdaptiveColor
|
||||
InfoColor lipgloss.AdaptiveColor
|
||||
|
||||
// Text colors
|
||||
TextColor lipgloss.AdaptiveColor
|
||||
TextMutedColor lipgloss.AdaptiveColor
|
||||
TextColor lipgloss.AdaptiveColor
|
||||
TextMutedColor lipgloss.AdaptiveColor
|
||||
TextEmphasizedColor lipgloss.AdaptiveColor
|
||||
|
||||
// Background colors
|
||||
BackgroundColor lipgloss.AdaptiveColor
|
||||
BackgroundColor lipgloss.AdaptiveColor
|
||||
BackgroundSecondaryColor lipgloss.AdaptiveColor
|
||||
BackgroundDarkerColor lipgloss.AdaptiveColor
|
||||
BackgroundDarkerColor lipgloss.AdaptiveColor
|
||||
|
||||
// Border colors
|
||||
BorderNormalColor lipgloss.AdaptiveColor
|
||||
|
@ -109,105 +109,113 @@ type BaseTheme struct {
|
|||
BorderDimColor lipgloss.AdaptiveColor
|
||||
|
||||
// Diff view colors
|
||||
DiffAddedColor lipgloss.AdaptiveColor
|
||||
DiffRemovedColor lipgloss.AdaptiveColor
|
||||
DiffContextColor lipgloss.AdaptiveColor
|
||||
DiffHunkHeaderColor lipgloss.AdaptiveColor
|
||||
DiffHighlightAddedColor lipgloss.AdaptiveColor
|
||||
DiffHighlightRemovedColor lipgloss.AdaptiveColor
|
||||
DiffAddedBgColor lipgloss.AdaptiveColor
|
||||
DiffRemovedBgColor lipgloss.AdaptiveColor
|
||||
DiffContextBgColor lipgloss.AdaptiveColor
|
||||
DiffLineNumberColor lipgloss.AdaptiveColor
|
||||
DiffAddedLineNumberBgColor lipgloss.AdaptiveColor
|
||||
DiffAddedColor lipgloss.AdaptiveColor
|
||||
DiffRemovedColor lipgloss.AdaptiveColor
|
||||
DiffContextColor lipgloss.AdaptiveColor
|
||||
DiffHunkHeaderColor lipgloss.AdaptiveColor
|
||||
DiffHighlightAddedColor lipgloss.AdaptiveColor
|
||||
DiffHighlightRemovedColor lipgloss.AdaptiveColor
|
||||
DiffAddedBgColor lipgloss.AdaptiveColor
|
||||
DiffRemovedBgColor lipgloss.AdaptiveColor
|
||||
DiffContextBgColor lipgloss.AdaptiveColor
|
||||
DiffLineNumberColor lipgloss.AdaptiveColor
|
||||
DiffAddedLineNumberBgColor lipgloss.AdaptiveColor
|
||||
DiffRemovedLineNumberBgColor lipgloss.AdaptiveColor
|
||||
|
||||
// Markdown colors
|
||||
MarkdownTextColor lipgloss.AdaptiveColor
|
||||
MarkdownHeadingColor lipgloss.AdaptiveColor
|
||||
MarkdownLinkColor lipgloss.AdaptiveColor
|
||||
MarkdownLinkTextColor lipgloss.AdaptiveColor
|
||||
MarkdownCodeColor lipgloss.AdaptiveColor
|
||||
MarkdownBlockQuoteColor lipgloss.AdaptiveColor
|
||||
MarkdownEmphColor lipgloss.AdaptiveColor
|
||||
MarkdownStrongColor lipgloss.AdaptiveColor
|
||||
MarkdownHorizontalRuleColor lipgloss.AdaptiveColor
|
||||
MarkdownListItemColor lipgloss.AdaptiveColor
|
||||
MarkdownTextColor lipgloss.AdaptiveColor
|
||||
MarkdownHeadingColor lipgloss.AdaptiveColor
|
||||
MarkdownLinkColor lipgloss.AdaptiveColor
|
||||
MarkdownLinkTextColor lipgloss.AdaptiveColor
|
||||
MarkdownCodeColor lipgloss.AdaptiveColor
|
||||
MarkdownBlockQuoteColor lipgloss.AdaptiveColor
|
||||
MarkdownEmphColor lipgloss.AdaptiveColor
|
||||
MarkdownStrongColor lipgloss.AdaptiveColor
|
||||
MarkdownHorizontalRuleColor lipgloss.AdaptiveColor
|
||||
MarkdownListItemColor lipgloss.AdaptiveColor
|
||||
MarkdownListEnumerationColor lipgloss.AdaptiveColor
|
||||
MarkdownImageColor lipgloss.AdaptiveColor
|
||||
MarkdownImageTextColor lipgloss.AdaptiveColor
|
||||
MarkdownCodeBlockColor lipgloss.AdaptiveColor
|
||||
MarkdownImageColor lipgloss.AdaptiveColor
|
||||
MarkdownImageTextColor lipgloss.AdaptiveColor
|
||||
MarkdownCodeBlockColor lipgloss.AdaptiveColor
|
||||
|
||||
// Syntax highlighting colors
|
||||
SyntaxCommentColor lipgloss.AdaptiveColor
|
||||
SyntaxKeywordColor lipgloss.AdaptiveColor
|
||||
SyntaxFunctionColor lipgloss.AdaptiveColor
|
||||
SyntaxVariableColor lipgloss.AdaptiveColor
|
||||
SyntaxStringColor lipgloss.AdaptiveColor
|
||||
SyntaxNumberColor lipgloss.AdaptiveColor
|
||||
SyntaxTypeColor lipgloss.AdaptiveColor
|
||||
SyntaxOperatorColor lipgloss.AdaptiveColor
|
||||
SyntaxCommentColor lipgloss.AdaptiveColor
|
||||
SyntaxKeywordColor lipgloss.AdaptiveColor
|
||||
SyntaxFunctionColor lipgloss.AdaptiveColor
|
||||
SyntaxVariableColor lipgloss.AdaptiveColor
|
||||
SyntaxStringColor lipgloss.AdaptiveColor
|
||||
SyntaxNumberColor lipgloss.AdaptiveColor
|
||||
SyntaxTypeColor lipgloss.AdaptiveColor
|
||||
SyntaxOperatorColor lipgloss.AdaptiveColor
|
||||
SyntaxPunctuationColor lipgloss.AdaptiveColor
|
||||
}
|
||||
|
||||
// Implement the Theme interface for BaseTheme
|
||||
func (t *BaseTheme) Primary() lipgloss.AdaptiveColor { return t.PrimaryColor }
|
||||
func (t *BaseTheme) Primary() lipgloss.AdaptiveColor { return t.PrimaryColor }
|
||||
func (t *BaseTheme) Secondary() lipgloss.AdaptiveColor { return t.SecondaryColor }
|
||||
func (t *BaseTheme) Accent() lipgloss.AdaptiveColor { return t.AccentColor }
|
||||
func (t *BaseTheme) Accent() lipgloss.AdaptiveColor { return t.AccentColor }
|
||||
|
||||
func (t *BaseTheme) Error() lipgloss.AdaptiveColor { return t.ErrorColor }
|
||||
func (t *BaseTheme) Error() lipgloss.AdaptiveColor { return t.ErrorColor }
|
||||
func (t *BaseTheme) Warning() lipgloss.AdaptiveColor { return t.WarningColor }
|
||||
func (t *BaseTheme) Success() lipgloss.AdaptiveColor { return t.SuccessColor }
|
||||
func (t *BaseTheme) Info() lipgloss.AdaptiveColor { return t.InfoColor }
|
||||
func (t *BaseTheme) Info() lipgloss.AdaptiveColor { return t.InfoColor }
|
||||
|
||||
func (t *BaseTheme) Text() lipgloss.AdaptiveColor { return t.TextColor }
|
||||
func (t *BaseTheme) TextMuted() lipgloss.AdaptiveColor { return t.TextMutedColor }
|
||||
func (t *BaseTheme) Text() lipgloss.AdaptiveColor { return t.TextColor }
|
||||
func (t *BaseTheme) TextMuted() lipgloss.AdaptiveColor { return t.TextMutedColor }
|
||||
func (t *BaseTheme) TextEmphasized() lipgloss.AdaptiveColor { return t.TextEmphasizedColor }
|
||||
|
||||
func (t *BaseTheme) Background() lipgloss.AdaptiveColor { return t.BackgroundColor }
|
||||
func (t *BaseTheme) Background() lipgloss.AdaptiveColor { return t.BackgroundColor }
|
||||
func (t *BaseTheme) BackgroundSecondary() lipgloss.AdaptiveColor { return t.BackgroundSecondaryColor }
|
||||
func (t *BaseTheme) BackgroundDarker() lipgloss.AdaptiveColor { return t.BackgroundDarkerColor }
|
||||
func (t *BaseTheme) BackgroundDarker() lipgloss.AdaptiveColor { return t.BackgroundDarkerColor }
|
||||
|
||||
func (t *BaseTheme) BorderNormal() lipgloss.AdaptiveColor { return t.BorderNormalColor }
|
||||
func (t *BaseTheme) BorderNormal() lipgloss.AdaptiveColor { return t.BorderNormalColor }
|
||||
func (t *BaseTheme) BorderFocused() lipgloss.AdaptiveColor { return t.BorderFocusedColor }
|
||||
func (t *BaseTheme) BorderDim() lipgloss.AdaptiveColor { return t.BorderDimColor }
|
||||
func (t *BaseTheme) BorderDim() lipgloss.AdaptiveColor { return t.BorderDimColor }
|
||||
|
||||
func (t *BaseTheme) DiffAdded() lipgloss.AdaptiveColor { return t.DiffAddedColor }
|
||||
func (t *BaseTheme) DiffRemoved() lipgloss.AdaptiveColor { return t.DiffRemovedColor }
|
||||
func (t *BaseTheme) DiffContext() lipgloss.AdaptiveColor { return t.DiffContextColor }
|
||||
func (t *BaseTheme) DiffHunkHeader() lipgloss.AdaptiveColor { return t.DiffHunkHeaderColor }
|
||||
func (t *BaseTheme) DiffHighlightAdded() lipgloss.AdaptiveColor { return t.DiffHighlightAddedColor }
|
||||
func (t *BaseTheme) DiffAdded() lipgloss.AdaptiveColor { return t.DiffAddedColor }
|
||||
func (t *BaseTheme) DiffRemoved() lipgloss.AdaptiveColor { return t.DiffRemovedColor }
|
||||
func (t *BaseTheme) DiffContext() lipgloss.AdaptiveColor { return t.DiffContextColor }
|
||||
func (t *BaseTheme) DiffHunkHeader() lipgloss.AdaptiveColor { return t.DiffHunkHeaderColor }
|
||||
func (t *BaseTheme) DiffHighlightAdded() lipgloss.AdaptiveColor { return t.DiffHighlightAddedColor }
|
||||
func (t *BaseTheme) DiffHighlightRemoved() lipgloss.AdaptiveColor { return t.DiffHighlightRemovedColor }
|
||||
func (t *BaseTheme) DiffAddedBg() lipgloss.AdaptiveColor { return t.DiffAddedBgColor }
|
||||
func (t *BaseTheme) DiffRemovedBg() lipgloss.AdaptiveColor { return t.DiffRemovedBgColor }
|
||||
func (t *BaseTheme) DiffContextBg() lipgloss.AdaptiveColor { return t.DiffContextBgColor }
|
||||
func (t *BaseTheme) DiffLineNumber() lipgloss.AdaptiveColor { return t.DiffLineNumberColor }
|
||||
func (t *BaseTheme) DiffAddedLineNumberBg() lipgloss.AdaptiveColor { return t.DiffAddedLineNumberBgColor }
|
||||
func (t *BaseTheme) DiffRemovedLineNumberBg() lipgloss.AdaptiveColor { return t.DiffRemovedLineNumberBgColor }
|
||||
func (t *BaseTheme) DiffAddedBg() lipgloss.AdaptiveColor { return t.DiffAddedBgColor }
|
||||
func (t *BaseTheme) DiffRemovedBg() lipgloss.AdaptiveColor { return t.DiffRemovedBgColor }
|
||||
func (t *BaseTheme) DiffContextBg() lipgloss.AdaptiveColor { return t.DiffContextBgColor }
|
||||
func (t *BaseTheme) DiffLineNumber() lipgloss.AdaptiveColor { return t.DiffLineNumberColor }
|
||||
func (t *BaseTheme) DiffAddedLineNumberBg() lipgloss.AdaptiveColor {
|
||||
return t.DiffAddedLineNumberBgColor
|
||||
}
|
||||
func (t *BaseTheme) DiffRemovedLineNumberBg() lipgloss.AdaptiveColor {
|
||||
return t.DiffRemovedLineNumberBgColor
|
||||
}
|
||||
|
||||
func (t *BaseTheme) MarkdownText() lipgloss.AdaptiveColor { return t.MarkdownTextColor }
|
||||
func (t *BaseTheme) MarkdownHeading() lipgloss.AdaptiveColor { return t.MarkdownHeadingColor }
|
||||
func (t *BaseTheme) MarkdownLink() lipgloss.AdaptiveColor { return t.MarkdownLinkColor }
|
||||
func (t *BaseTheme) MarkdownLinkText() lipgloss.AdaptiveColor { return t.MarkdownLinkTextColor }
|
||||
func (t *BaseTheme) MarkdownCode() lipgloss.AdaptiveColor { return t.MarkdownCodeColor }
|
||||
func (t *BaseTheme) MarkdownText() lipgloss.AdaptiveColor { return t.MarkdownTextColor }
|
||||
func (t *BaseTheme) MarkdownHeading() lipgloss.AdaptiveColor { return t.MarkdownHeadingColor }
|
||||
func (t *BaseTheme) MarkdownLink() lipgloss.AdaptiveColor { return t.MarkdownLinkColor }
|
||||
func (t *BaseTheme) MarkdownLinkText() lipgloss.AdaptiveColor { return t.MarkdownLinkTextColor }
|
||||
func (t *BaseTheme) MarkdownCode() lipgloss.AdaptiveColor { return t.MarkdownCodeColor }
|
||||
func (t *BaseTheme) MarkdownBlockQuote() lipgloss.AdaptiveColor { return t.MarkdownBlockQuoteColor }
|
||||
func (t *BaseTheme) MarkdownEmph() lipgloss.AdaptiveColor { return t.MarkdownEmphColor }
|
||||
func (t *BaseTheme) MarkdownStrong() lipgloss.AdaptiveColor { return t.MarkdownStrongColor }
|
||||
func (t *BaseTheme) MarkdownHorizontalRule() lipgloss.AdaptiveColor { return t.MarkdownHorizontalRuleColor }
|
||||
func (t *BaseTheme) MarkdownEmph() lipgloss.AdaptiveColor { return t.MarkdownEmphColor }
|
||||
func (t *BaseTheme) MarkdownStrong() lipgloss.AdaptiveColor { return t.MarkdownStrongColor }
|
||||
func (t *BaseTheme) MarkdownHorizontalRule() lipgloss.AdaptiveColor {
|
||||
return t.MarkdownHorizontalRuleColor
|
||||
}
|
||||
func (t *BaseTheme) MarkdownListItem() lipgloss.AdaptiveColor { return t.MarkdownListItemColor }
|
||||
func (t *BaseTheme) MarkdownListEnumeration() lipgloss.AdaptiveColor { return t.MarkdownListEnumerationColor }
|
||||
func (t *BaseTheme) MarkdownImage() lipgloss.AdaptiveColor { return t.MarkdownImageColor }
|
||||
func (t *BaseTheme) MarkdownListEnumeration() lipgloss.AdaptiveColor {
|
||||
return t.MarkdownListEnumerationColor
|
||||
}
|
||||
func (t *BaseTheme) MarkdownImage() lipgloss.AdaptiveColor { return t.MarkdownImageColor }
|
||||
func (t *BaseTheme) MarkdownImageText() lipgloss.AdaptiveColor { return t.MarkdownImageTextColor }
|
||||
func (t *BaseTheme) MarkdownCodeBlock() lipgloss.AdaptiveColor { return t.MarkdownCodeBlockColor }
|
||||
|
||||
func (t *BaseTheme) SyntaxComment() lipgloss.AdaptiveColor { return t.SyntaxCommentColor }
|
||||
func (t *BaseTheme) SyntaxKeyword() lipgloss.AdaptiveColor { return t.SyntaxKeywordColor }
|
||||
func (t *BaseTheme) SyntaxFunction() lipgloss.AdaptiveColor { return t.SyntaxFunctionColor }
|
||||
func (t *BaseTheme) SyntaxVariable() lipgloss.AdaptiveColor { return t.SyntaxVariableColor }
|
||||
func (t *BaseTheme) SyntaxString() lipgloss.AdaptiveColor { return t.SyntaxStringColor }
|
||||
func (t *BaseTheme) SyntaxNumber() lipgloss.AdaptiveColor { return t.SyntaxNumberColor }
|
||||
func (t *BaseTheme) SyntaxType() lipgloss.AdaptiveColor { return t.SyntaxTypeColor }
|
||||
func (t *BaseTheme) SyntaxOperator() lipgloss.AdaptiveColor { return t.SyntaxOperatorColor }
|
||||
func (t *BaseTheme) SyntaxComment() lipgloss.AdaptiveColor { return t.SyntaxCommentColor }
|
||||
func (t *BaseTheme) SyntaxKeyword() lipgloss.AdaptiveColor { return t.SyntaxKeywordColor }
|
||||
func (t *BaseTheme) SyntaxFunction() lipgloss.AdaptiveColor { return t.SyntaxFunctionColor }
|
||||
func (t *BaseTheme) SyntaxVariable() lipgloss.AdaptiveColor { return t.SyntaxVariableColor }
|
||||
func (t *BaseTheme) SyntaxString() lipgloss.AdaptiveColor { return t.SyntaxStringColor }
|
||||
func (t *BaseTheme) SyntaxNumber() lipgloss.AdaptiveColor { return t.SyntaxNumberColor }
|
||||
func (t *BaseTheme) SyntaxType() lipgloss.AdaptiveColor { return t.SyntaxTypeColor }
|
||||
func (t *BaseTheme) SyntaxOperator() lipgloss.AdaptiveColor { return t.SyntaxOperatorColor }
|
||||
func (t *BaseTheme) SyntaxPunctuation() lipgloss.AdaptiveColor { return t.SyntaxPunctuationColor }
|
||||
|
||||
// ParseAdaptiveColor parses a color value from the config file into a lipgloss.AdaptiveColor.
|
||||
|
@ -254,4 +262,4 @@ func ParseAdaptiveColor(value any) (lipgloss.AdaptiveColor, error) {
|
|||
}
|
||||
|
||||
return lipgloss.AdaptiveColor{}, fmt.Errorf("color must be either a hex string or an object with dark/light keys")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ import (
|
|||
func TestThemeRegistration(t *testing.T) {
|
||||
// Get list of available themes
|
||||
availableThemes := AvailableThemes()
|
||||
|
||||
|
||||
// Check if "catppuccin" theme is registered
|
||||
catppuccinFound := false
|
||||
for _, themeName := range availableThemes {
|
||||
|
@ -16,11 +16,11 @@ func TestThemeRegistration(t *testing.T) {
|
|||
break
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if !catppuccinFound {
|
||||
t.Errorf("Catppuccin theme is not registered")
|
||||
}
|
||||
|
||||
|
||||
// Check if "gruvbox" theme is registered
|
||||
gruvboxFound := false
|
||||
for _, themeName := range availableThemes {
|
||||
|
@ -29,11 +29,11 @@ func TestThemeRegistration(t *testing.T) {
|
|||
break
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if !gruvboxFound {
|
||||
t.Errorf("Gruvbox theme is not registered")
|
||||
}
|
||||
|
||||
|
||||
// Check if "monokai" theme is registered
|
||||
monokaiFound := false
|
||||
for _, themeName := range availableThemes {
|
||||
|
@ -42,48 +42,48 @@ func TestThemeRegistration(t *testing.T) {
|
|||
break
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if !monokaiFound {
|
||||
t.Errorf("Monokai theme is not registered")
|
||||
}
|
||||
|
||||
|
||||
// Try to get the themes and make sure they're not nil
|
||||
catppuccin := GetTheme("catppuccin")
|
||||
if catppuccin == nil {
|
||||
t.Errorf("Catppuccin theme is nil")
|
||||
}
|
||||
|
||||
|
||||
gruvbox := GetTheme("gruvbox")
|
||||
if gruvbox == nil {
|
||||
t.Errorf("Gruvbox theme is nil")
|
||||
}
|
||||
|
||||
|
||||
monokai := GetTheme("monokai")
|
||||
if monokai == nil {
|
||||
t.Errorf("Monokai theme is nil")
|
||||
}
|
||||
|
||||
|
||||
// Test switching theme
|
||||
originalTheme := CurrentThemeName()
|
||||
|
||||
|
||||
err := SetTheme("gruvbox")
|
||||
if err != nil {
|
||||
t.Errorf("Failed to set theme to gruvbox: %v", err)
|
||||
}
|
||||
|
||||
|
||||
if CurrentThemeName() != "gruvbox" {
|
||||
t.Errorf("Theme not properly switched to gruvbox")
|
||||
}
|
||||
|
||||
|
||||
err = SetTheme("monokai")
|
||||
if err != nil {
|
||||
t.Errorf("Failed to set theme to monokai: %v", err)
|
||||
}
|
||||
|
||||
|
||||
if CurrentThemeName() != "monokai" {
|
||||
t.Errorf("Theme not properly switched to monokai")
|
||||
}
|
||||
|
||||
|
||||
// Switch back to original theme
|
||||
_ = SetTheme(originalTheme)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -271,4 +271,4 @@ func NewTokyoNightTheme() *TokyoNightTheme {
|
|||
func init() {
|
||||
// Register the Tokyo Night theme with the theme manager
|
||||
RegisterTheme("tokyonight", NewTokyoNightTheme())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -273,4 +273,4 @@ func NewTronTheme() *TronTheme {
|
|||
func init() {
|
||||
// Register the Tron theme with the theme manager
|
||||
RegisterTheme("tron", NewTronTheme())
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue