@@ -2,6 +2,7 @@ package utils
2
2
3
3
import (
4
4
"fmt"
5
+ "unicode"
5
6
6
7
tea "github.com/charmbracelet/bubbletea"
7
8
"github.com/initia-labs/weave/styles"
@@ -35,39 +36,95 @@ func (ti *TextInput) WithPlaceholder(placeholder string) {
35
36
func (ti TextInput ) Update (msg tea.Msg ) (TextInput , tea.Cmd , bool ) {
36
37
switch msg := msg .(type ) {
37
38
case tea.KeyMsg :
38
- switch msg .Type {
39
- case tea .KeyEnter :
39
+ switch {
40
+ // Handle Enter key
41
+ case msg .Type == tea .KeyEnter :
40
42
ti .IsEntered = true
41
43
return ti , nil , ti .ValidationFn (ti .Text ) == nil
42
- case tea .KeyBackspace , tea .KeyCtrlH :
44
+
45
+ // Handle Backspace key
46
+ case msg .Type == tea .KeyBackspace || msg .Type == tea .KeyCtrlH :
43
47
ti .IsEntered = false
44
48
if ti .Cursor > 0 && len (ti .Text ) > 0 {
45
49
ti .Text = ti .Text [:ti .Cursor - 1 ] + ti .Text [ti .Cursor :]
46
50
ti .Cursor --
47
51
}
48
- case tea .KeyRunes , tea .KeySpace :
52
+
53
+ // Handle Option + Left (move one word left) - Detected as "alt+b"
54
+ case msg .String () == "alt+b" :
49
55
ti .IsEntered = false
50
- ti .Text = ti .Text [:ti .Cursor ] + string (msg .Runes ) + ti .Text [ti .Cursor :]
51
- ti .Cursor += len (msg .Runes )
52
- case tea .KeyLeft :
56
+ ti .Cursor = moveToPreviousWord (ti .Text , ti .Cursor )
57
+
58
+ // Handle Option + Right (move one word right) - Detected as "alt+f"
59
+ case msg .String () == "alt+f" :
60
+ ti .IsEntered = false
61
+ ti .Cursor = moveToNextWord (ti .Text , ti .Cursor )
62
+
63
+ // Handle Arrow Left (move cursor one character left)
64
+ case msg .Type == tea .KeyLeft :
53
65
ti .IsEntered = false
54
66
if ti .Cursor > 0 {
55
67
ti .Cursor --
56
68
}
57
- case tea .KeyRight :
69
+
70
+ // Handle Arrow Right (move cursor one character right)
71
+ case msg .Type == tea .KeyRight :
58
72
ti .IsEntered = false
59
73
if ti .Cursor < len (ti .Text ) {
60
74
ti .Cursor ++
61
75
}
62
- case tea .KeyCtrlC :
76
+
77
+ // Handle Ctrl+C (quit)
78
+ case msg .Type == tea .KeyCtrlC :
63
79
ti .IsEntered = false
64
80
return ti , tea .Quit , false
65
- }
66
81
82
+ default :
83
+ ti .IsEntered = false
84
+
85
+ // Normal typing
86
+ ti .Text = ti .Text [:ti .Cursor ] + string (msg .Runes ) + ti .Text [ti .Cursor :]
87
+ ti .Cursor += len (msg .Runes )
88
+
89
+ }
67
90
}
68
91
return ti , nil , false
69
92
}
70
93
94
+ // Helper function to move the cursor to the beginning of the previous word
95
+ func moveToPreviousWord (text string , cursor int ) int {
96
+ if cursor == 0 {
97
+ return 0
98
+ }
99
+
100
+ // Move cursor left while encountering spaces
101
+ for cursor > 0 && unicode .IsSpace (rune (text [cursor - 1 ])) {
102
+ cursor --
103
+ }
104
+ // Move cursor left until the beginning of the word is found
105
+ for cursor > 0 && ! unicode .IsSpace (rune (text [cursor - 1 ])) {
106
+ cursor --
107
+ }
108
+ return cursor
109
+ }
110
+
111
+ // Helper function to move the cursor to the beginning of the next word
112
+ func moveToNextWord (text string , cursor int ) int {
113
+ if cursor >= len (text ) {
114
+ return len (text )
115
+ }
116
+
117
+ // Move cursor right while encountering non-space characters (current word)
118
+ for cursor < len (text ) && ! unicode .IsSpace (rune (text [cursor ])) {
119
+ cursor ++
120
+ }
121
+ // Move cursor right while encountering spaces
122
+ for cursor < len (text ) && unicode .IsSpace (rune (text [cursor ])) {
123
+ cursor ++
124
+ }
125
+ return cursor
126
+ }
127
+
71
128
func (ti TextInput ) View () string {
72
129
var beforeCursor , cursorChar , afterCursor string
73
130
bottomText := styles .Text ("Press Enter to submit or Ctrl+C to quit." , styles .Gray )
0 commit comments