1package chat
2
3import (
4 "fmt"
5 "sort"
6
7 "github.com/charmbracelet/lipgloss"
8 "github.com/charmbracelet/x/ansi"
9 "github.com/opencode-ai/opencode/internal/config"
10 "github.com/opencode-ai/opencode/internal/message"
11 "github.com/opencode-ai/opencode/internal/session"
12 "github.com/opencode-ai/opencode/internal/tui/styles"
13 "github.com/opencode-ai/opencode/internal/tui/theme"
14 "github.com/opencode-ai/opencode/internal/version"
15)
16
17type SendMsg struct {
18 Text string
19 Attachments []message.Attachment
20}
21
22type SessionSelectedMsg = session.Session
23
24type SessionClearedMsg struct{}
25
26type EditorFocusMsg bool
27
28func header(width int) string {
29 return lipgloss.JoinVertical(
30 lipgloss.Top,
31 logo(width),
32 repo(width),
33 "",
34 cwd(width),
35 )
36}
37
38func lspsConfigured(width int) string {
39 cfg := config.Get()
40 title := "LSP Configuration"
41 title = ansi.Truncate(title, width, "…")
42
43 t := theme.CurrentTheme()
44 baseStyle := styles.BaseStyle()
45
46 lsps := baseStyle.
47 Width(width).
48 Foreground(t.Primary()).
49 Bold(true).
50 Render(title)
51
52 // Get LSP names and sort them for consistent ordering
53 var lspNames []string
54 for name := range cfg.LSP {
55 lspNames = append(lspNames, name)
56 }
57 sort.Strings(lspNames)
58
59 var lspViews []string
60 for _, name := range lspNames {
61 lsp := cfg.LSP[name]
62 lspName := baseStyle.
63 Foreground(t.Text()).
64 Render(fmt.Sprintf("• %s", name))
65
66 cmd := lsp.Command
67 cmd = ansi.Truncate(cmd, width-lipgloss.Width(lspName)-3, "…")
68
69 lspPath := baseStyle.
70 Foreground(t.TextMuted()).
71 Render(fmt.Sprintf(" (%s)", cmd))
72
73 lspViews = append(lspViews,
74 baseStyle.
75 Width(width).
76 Render(
77 lipgloss.JoinHorizontal(
78 lipgloss.Left,
79 lspName,
80 lspPath,
81 ),
82 ),
83 )
84 }
85
86 return baseStyle.
87 Width(width).
88 Render(
89 lipgloss.JoinVertical(
90 lipgloss.Left,
91 lsps,
92 lipgloss.JoinVertical(
93 lipgloss.Left,
94 lspViews...,
95 ),
96 ),
97 )
98}
99
100func logo(width int) string {
101 logo := fmt.Sprintf("%s %s", styles.OpenCodeIcon, "OpenCode")
102 t := theme.CurrentTheme()
103 baseStyle := styles.BaseStyle()
104
105 versionText := baseStyle.
106 Foreground(t.TextMuted()).
107 Render(version.Version)
108
109 return baseStyle.
110 Bold(true).
111 Width(width).
112 Render(
113 lipgloss.JoinHorizontal(
114 lipgloss.Left,
115 logo,
116 " ",
117 versionText,
118 ),
119 )
120}
121
122func repo(width int) string {
123 repo := "https://github.com/opencode-ai/opencode"
124 t := theme.CurrentTheme()
125
126 return styles.BaseStyle().
127 Foreground(t.TextMuted()).
128 Width(width).
129 Render(repo)
130}
131
132func cwd(width int) string {
133 cwd := fmt.Sprintf("cwd: %s", config.WorkingDirectory())
134 t := theme.CurrentTheme()
135
136 return styles.BaseStyle().
137 Foreground(t.TextMuted()).
138 Width(width).
139 Render(cwd)
140}
141