@@ -3,6 +3,7 @@ package model
33import (
44 "context"
55 "log/slog"
6+ "strings"
67
78 tea "charm.land/bubbletea/v2"
89
@@ -36,6 +37,9 @@ func (m *UI) loadPromptHistory() tea.Cmd {
3637 if text := msg.Content().Text; text != "" {
3738 texts = append(texts, text)
3839 }
40+ for _, sc := range msg.ShellCommands() {
41+ texts = append(texts, "!"+sc.Command)
42+ }
3943 }
4044 return promptHistoryLoadedMsg{messages: texts}
4145 }
@@ -93,6 +97,7 @@ func (m *UI) handleHistoryEscape(msg tea.Msg) tea.Cmd {
9397 m.promptHistory.index = -1
9498 m.textarea.Reset()
9599 m.textarea.InsertString(m.promptHistory.draft)
100+ m.syncBangModeFromTextarea()
96101 return m.updateTextareaWithPrevHeight(nil, prevHeight)
97102 }
98103
@@ -108,6 +113,26 @@ func (m *UI) updateHistoryDraft(oldValue string) {
108113 }
109114}
110115
116+// syncBangModeFromTextarea engages or disengages bang mode based on
117+// whether the current textarea value starts with "!". The "!" prefix
118+// is stripped when entering bang mode and re-added when leaving it so
119+// the visible text always reflects the correct state.
120+func (m *UI) syncBangModeFromTextarea() {
121+ val := m.textarea.Value()
122+ hasBang := strings.HasPrefix(val, "!")
123+ if hasBang && !m.bangMode {
124+ m.bangMode = true
125+ m.bangWasEmpty = false
126+ m.textarea.SetValue(val[1:])
127+ m.textarea.MoveToBegin()
128+ } else if !hasBang && m.bangMode {
129+ m.bangMode = false
130+ m.bangWasEmpty = false
131+ }
132+ yolo := m.com.Workspace.PermissionSkipRequests()
133+ m.setEditorPrompt(yolo)
134+}
135+
111136// historyPrev changes the text area content to the previous message in the history
112137// it returns false if it could not find the previous message.
113138func (m *UI) historyPrev() bool {
@@ -125,6 +150,7 @@ func (m *UI) historyPrev() bool {
125150 m.textarea.Reset()
126151 m.textarea.InsertString(m.promptHistory.messages[nextIndex])
127152 m.textarea.MoveToBegin()
153+ m.syncBangModeFromTextarea()
128154 return true
129155}
130156
@@ -139,11 +165,13 @@ func (m *UI) historyNext() bool {
139165 m.promptHistory.index = -1
140166 m.textarea.Reset()
141167 m.textarea.InsertString(m.promptHistory.draft)
168+ m.syncBangModeFromTextarea()
142169 return true
143170 }
144171 m.promptHistory.index = nextIndex
145172 m.textarea.Reset()
146173 m.textarea.InsertString(m.promptHistory.messages[nextIndex])
174+ m.syncBangModeFromTextarea()
147175 return true
148176}
149177