Skip to content

Commit 75d8fbc

Browse files
committed
this is more like it <3
1 parent 6ac3226 commit 75d8fbc

File tree

2 files changed

+72
-71
lines changed

2 files changed

+72
-71
lines changed

terminal/terminal.go

Lines changed: 65 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import (
55
"fmt"
66
"math/big"
77
mrand "math/rand"
8-
"strings"
98

109
"github.com/abs-lang/abs/object"
1110
"github.com/abs-lang/abs/util"
@@ -64,64 +63,72 @@ func NewTerminal(user string, env *object.Environment, runner Runner) *tea.Progr
6463
}
6564

6665
func getInitialModel(sigs signals, user string, env *object.Environment, r Runner) Model {
67-
in := textinput.New()
68-
in.Prompt = getPrompt(env)
69-
in.Placeholder = exampleStatements[mrand.Intn(len(exampleStatements))] + " # just something you can run... (tab + enter)"
7066
historyFile, maxLines := getHistoryConfiguration(env)
7167
history := getHistory(historyFile, maxLines)
72-
in.Focus()
73-
messages := []string{}
74-
messages = append(messages, fmt.Sprintf("Hello %s, welcome to the ABS (%s) programming language!", user, env.Version))
75-
messages = append(messages, "Type 'quit' when you're done, 'help' if you get lost!")
76-
77-
// check for new version about 10% of the time,
78-
// to avoid too many hangups
79-
if r, e := rand.Int(rand.Reader, big.NewInt(100)); e == nil && r.Int64() < 10 {
80-
if newver, update := util.UpdateAvailable(env.Version); update {
81-
msg := fmt.Sprintf(
82-
"\n*** Update available: %s (your version is %s) ***",
83-
newver,
84-
env.Version,
85-
)
86-
messages = append(messages, lipgloss.NewStyle().Faint(true).Render(msg))
87-
}
88-
}
8968

90-
return Model{
69+
m := Model{
9170
signals: sigs,
9271
user: user,
9372
runner: r,
94-
prompt: getPrompt,
9573
env: env,
96-
in: in,
9774
history: history,
9875
historyPoint: len(history),
9976
historyFile: historyFile,
10077
historyMaxLInes: maxLines,
10178
dirty: "",
102-
messages: messages,
103-
err: nil,
10479
}
80+
81+
m.prompt = func() string {
82+
return getPrompt(m.env)
83+
}
84+
85+
// Setup the input line of our terminal
86+
in := textinput.New()
87+
in.Prompt = m.prompt()
88+
in.Placeholder = exampleStatements[mrand.Intn(len(exampleStatements))] + " # just something you can run... (tab + enter)"
89+
in.Focus()
90+
91+
m.in = in
92+
93+
return m
10594
}
10695

10796
type Model struct {
10897
signals signals
10998
user string
11099
runner Runner
111100
env *object.Environment
112-
prompt func(*object.Environment) string
101+
prompt func() string
113102
history []string
114103
historyPoint int
115104
historyFile string
116105
historyMaxLInes int
117106
dirty string
118-
messages []string
119107
in textinput.Model
120-
err error
121108
}
122109

123110
func (m Model) Init() tea.Cmd {
124-
return tea.Batch(tea.SetWindowTitle("abs-repl"), textarea.Blink)
111+
lines := Lines{}
112+
lines.Add(fmt.Sprintf("Hello %s, welcome to the ABS (%s) programming language!", m.user, m.env.Version))
113+
lines.Add("Type 'quit' when you're done, 'help' if you get lost!")
114+
115+
// check for new version about 10% of the time,
116+
// to avoid too many hangups
117+
if r, e := rand.Int(rand.Reader, big.NewInt(100)); e == nil && r.Int64() < 10 {
118+
if newver, update := util.UpdateAvailable(m.env.Version); update {
119+
lines.Add(lipgloss.NewStyle().Faint(true).Render(fmt.Sprintf(
120+
"\n*** Update available: %s (your version is %s) ***",
121+
newver,
122+
m.env.Version,
123+
)))
124+
}
125+
}
126+
127+
return tea.Batch(
128+
tea.SetWindowTitle("abs-repl"),
129+
textarea.Blink,
130+
tea.Sequence(lines...),
131+
)
125132
}
126133

127134
func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
@@ -144,7 +151,7 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
144151
m.in.Placeholder = ""
145152

146153
if m.in.Value() == "" {
147-
return m.PrintNewline()
154+
return m, tea.Println(m.prompt())
148155
}
149156

150157
m.history = append(m.history, m.in.Value())
@@ -160,7 +167,9 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
160167
}
161168

162169
case tea.KeyTab:
163-
return m.EngagePlaceholder()
170+
if m.in.Placeholder != "" {
171+
return m.EngagePlaceholder()
172+
}
164173
case tea.KeyCtrlL:
165174
return m.Clear()
166175
case tea.KeyUp:
@@ -199,19 +208,10 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
199208
}
200209

201210
func (m Model) View() string {
202-
if len(m.messages) == 0 {
203-
return m.in.View()
204-
}
205-
206-
return fmt.Sprintf(
207-
"%s\n%s",
208-
strings.Join(m.messages, "\n"),
209-
m.in.View(),
210-
)
211+
return m.in.View()
211212
}
212213

213214
func (m Model) Clear() (Model, tea.Cmd) {
214-
m.messages = []string{}
215215
m.in.Placeholder = ""
216216

217217
return m, tea.ClearScreen
@@ -223,33 +223,34 @@ func (m Model) Quit() (Model, tea.Cmd) {
223223
return m, tea.Quit
224224
}
225225

226+
func (m Model) currentLine() string {
227+
return m.prompt() + m.in.Value()
228+
}
229+
226230
func (m Model) Help() (Model, tea.Cmd) {
227-
prompt := m.prompt(m.env)
231+
lines := Lines{}
232+
prompt := m.prompt()
228233
help := func(s string) string { return lipgloss.NewStyle().Faint(true).Render(s) }
229234

230-
m.messages = append(
231-
m.messages,
232-
help("\nTry typing something along the lines of:\n"),
233-
" "+prompt+help("current_date = `date`\n"),
234-
help("A command should be triggered in your system. Then try printing the result of that command with:\n"),
235-
" "+prompt+help("current_date\n"),
236-
help("Here some other valid examples of ABS code:\n"),
237-
)
235+
lines.Add(m.currentLine())
236+
lines.Add(help("Try typing something along the lines of:\n"))
237+
lines.Add(" " + prompt + help("current_date = `date`\n"))
238+
lines.Add(help("A command should be triggered in your system. Then try printing the result of that command with:\n"))
239+
lines.Add(" " + prompt + help("current_date\n"))
240+
lines.Add(help("Here some other valid examples of ABS code:\n"))
238241

239242
for i := 0; i < 5; i++ {
240243
ix := mrand.Intn(len(exampleStatements))
241-
m.messages = append(m.messages, " "+prompt+help(exampleStatements[ix]+"\n"))
244+
lines.Add(" " + prompt + help(exampleStatements[ix]+"\n"))
242245
}
243246

244-
m.in.SetValue("")
247+
m.in.Reset()
245248

246-
return m, nil
249+
return m, tea.Sequence(lines...)
247250
}
248251

249252
func (m Model) EngagePlaceholder() (Model, tea.Cmd) {
250-
if m.in.Placeholder != "" {
251-
m.in.SetValue(m.in.Placeholder)
252-
}
253+
m.in.SetValue(m.in.Placeholder)
253254

254255
return m, nil
255256
}
@@ -276,28 +277,21 @@ func (m Model) Eval() (Model, tea.Cmd) {
276277
}
277278

278279
func (m Model) Print(msg evalCmd) (Model, tea.Cmd) {
279-
m.messages = append(m.messages, m.prompt(m.env)+msg.code)
280-
s := msg.result
280+
lines := Lines{}
281+
lines.Add(m.prompt() + msg.code)
281282

282-
if s != "" {
283-
m.messages = append(m.messages, s)
283+
if msg.result != "" {
284+
lines.Add(msg.result)
284285
}
285286

286-
m.in.Prompt = m.prompt(m.env)
287287
m.in.Reset()
288288

289-
return m, nil
290-
}
291-
292-
func (m Model) PrintNewline() (Model, tea.Cmd) {
293-
m.messages = append(m.messages, m.prompt(m.env))
294-
295-
return m, nil
289+
return m, tea.Sequence(lines...)
296290
}
297291

298292
func (m Model) Interrupt() (Model, tea.Cmd) {
299-
m.messages = append(m.messages, m.prompt(m.env)+m.in.Value())
293+
l := m.currentLine()
300294
m.in.Reset()
301295

302-
return m, nil
296+
return m, tea.Println(l)
303297
}

terminal/util.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77

88
"github.com/abs-lang/abs/object"
99
"github.com/abs-lang/abs/util"
10+
tea "github.com/charmbracelet/bubbletea"
1011
"github.com/charmbracelet/lipgloss"
1112
)
1213

@@ -67,3 +68,9 @@ func formatLivePrefix(prefix string) string {
6768
}
6869
return livePrefix
6970
}
71+
72+
type Lines []tea.Cmd
73+
74+
func (l *Lines) Add(msg string) {
75+
*l = append(*l, tea.Println(msg))
76+
}

0 commit comments

Comments
 (0)