1package repl
2
3import (
4 "github.com/charmbracelet/bubbles/key"
5 tea "github.com/charmbracelet/bubbletea"
6 "github.com/kujtimiihoxha/termai/internal/app"
7 "github.com/kujtimiihoxha/termai/internal/tui/layout"
8 "github.com/kujtimiihoxha/vimtea"
9)
10
11type EditorCmp interface {
12 tea.Model
13 layout.Focusable
14 layout.Sizeable
15 layout.Bordered
16}
17
18type editorCmp struct {
19 app *app.App
20 editor vimtea.Editor
21 editorMode vimtea.EditorMode
22 sessionID string
23 focused bool
24 width int
25 height int
26}
27
28type localKeyMap struct {
29 SendMessage key.Binding
30 SendMessageI key.Binding
31}
32
33var keyMap = localKeyMap{
34 SendMessage: key.NewBinding(
35 key.WithKeys("enter"),
36 key.WithHelp("enter", "send message normal mode"),
37 ),
38 SendMessageI: key.NewBinding(
39 key.WithKeys("ctrl+s"),
40 key.WithHelp("ctrl+s", "send message insert mode"),
41 ),
42}
43
44func (m *editorCmp) Init() tea.Cmd {
45 return m.editor.Init()
46}
47
48func (m *editorCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
49 switch msg := msg.(type) {
50 case vimtea.EditorModeMsg:
51 m.editorMode = msg.Mode
52 case SelectedSessionMsg:
53 if msg.SessionID != m.sessionID {
54 m.sessionID = msg.SessionID
55 }
56 }
57 if m.IsFocused() {
58 switch msg := msg.(type) {
59 case tea.KeyMsg:
60 switch {
61 case key.Matches(msg, keyMap.SendMessage):
62 if m.editorMode == vimtea.ModeNormal {
63 return m, m.Send()
64 }
65 case key.Matches(msg, keyMap.SendMessageI):
66 if m.editorMode == vimtea.ModeInsert {
67 return m, m.Send()
68 }
69 }
70 }
71 u, cmd := m.editor.Update(msg)
72 m.editor = u.(vimtea.Editor)
73 return m, cmd
74 }
75 return m, nil
76}
77
78// Blur implements EditorCmp.
79func (m *editorCmp) Blur() tea.Cmd {
80 m.focused = false
81 return nil
82}
83
84// BorderText implements EditorCmp.
85func (m *editorCmp) BorderText() map[layout.BorderPosition]string {
86 return map[layout.BorderPosition]string{
87 layout.TopLeftBorder: "New Message",
88 }
89}
90
91// Focus implements EditorCmp.
92func (m *editorCmp) Focus() tea.Cmd {
93 m.focused = true
94 return m.editor.Tick()
95}
96
97// GetSize implements EditorCmp.
98func (m *editorCmp) GetSize() (int, int) {
99 return m.width, m.height
100}
101
102// IsFocused implements EditorCmp.
103func (m *editorCmp) IsFocused() bool {
104 return m.focused
105}
106
107// SetSize implements EditorCmp.
108func (m *editorCmp) SetSize(width int, height int) {
109 m.width = width
110 m.height = height
111 m.editor.SetSize(width, height)
112}
113
114func (m *editorCmp) Send() tea.Cmd {
115 return func() tea.Msg {
116 // TODO: Send message
117 return nil
118 }
119}
120
121func (m *editorCmp) View() string {
122 return m.editor.View()
123}
124
125func NewEditorCmp(app *app.App) EditorCmp {
126 return &editorCmp{
127 app: app,
128 editor: vimtea.NewEditor(),
129 }
130}