on main help sign in
fix(bangmode): activate bang mode when ! is preceded by whitespace

๐Ÿ’˜ Generated with Crush Assisted-by: Crush:qwen3.7-max

commit11662010521e5211d825fcc21c4fdf8c72fda08e authorChristian Rocha <christian@rocha.is> dateFri 19 Jun 2026, 20:01 (4 months ago) parente74720b
1 file changed+14โˆ’8
internal/ui/model/ui.go+14โˆ’8
internal/ui/model/ui.go+14โˆ’8
@@ -17,6 +17,7 @@ import (
1717 "slices"
1818 "strconv"
1919 "strings"
20+ "unicode"
2021 "time"
2122
2223 "charm.land/bubbles/v2/help"
@@ -2182,19 +2183,24 @@ func (m *UI) handleKeyPressMsg(msg tea.KeyPressMsg) tea.Cmd {
21822183 cmds = append(cmds, m.updateTextareaWithPrevHeight(msg, prevHeight))
21832184
21842185 // Bang mode: enter when "!" is typed at the start of the
2185โˆ’ // prompt (either on an empty prompt or prepended to existing
2186โˆ’ // text). Exit on backspace clearing the last character.
2186+ // prompt, optionally preceded by whitespace (either on an
2187+ // empty/whitespace-only prompt or prepended to existing text).
2188+ // Exit on backspace clearing the last character.
21872189 newVal := m.textarea.Value()
2188โˆ’ if !m.bangMode && strings.HasPrefix(newVal, "!") && !strings.HasPrefix(curValue, "!") {
2190+ trimmedNew := strings.TrimLeftFunc(newVal, unicode.IsSpace)
2191+ trimmedCur := strings.TrimLeftFunc(curValue, unicode.IsSpace)
2192+ if !m.bangMode && strings.HasPrefix(trimmedNew, "!") && !strings.HasPrefix(trimmedCur, "!") {
21892193 m.bangMode = true
21902194 m.bangWasEmpty = len(strings.TrimSpace(curValue)) == 0
2191โˆ’ // Strip the leading "!" from the textarea while preserving
2192โˆ’ // the cursor position relative to the command text.
2195+ // Strip leading whitespace and the "!" from the textarea
2196+ // while preserving the cursor position relative to the
2197+ // command text.
21932198 col := m.textarea.Column()
21942199 line := m.textarea.Line()
2195โˆ’ m.textarea.SetValue(newVal[1:])
2196โˆ’ m.textarea.SetCursorColumn(max(0, col-1))
2197โˆ’ _ = line // cursor line doesn't change; first char removed
2200+ stripped := trimmedNew[1:]
2201+ m.textarea.SetValue(stripped)
2202+ m.textarea.SetCursorColumn(max(0, col-(len(newVal)-len(stripped))))
2203+ _ = line // cursor line doesn't change; prefix removed
21982204 yolo := m.com.Workspace.PermissionSkipRequests()
21992205 m.setEditorPrompt(yolo)
22002206 } else if m.bangMode && newVal == "" && curValue != "" {