@@ -35,8 +35,9 @@ const (
35
35
EchoNone
36
36
)
37
37
38
- // ValidateFunc is a function that returns an error if the input is invalid.
39
- type ValidateFunc func (string ) error
38
+ // ValidateFunc is a function that returns an error if the input is invalid and
39
+ // a boolean indicating whether text input should be blocked.
40
+ type ValidateFunc func (string ) (bool , error )
40
41
41
42
// KeyMap is the key bindings for different actions within the textinput.
42
43
type KeyMap struct {
@@ -180,19 +181,17 @@ func (m *Model) SetValue(s string) {
180
181
// Clean up any special characters in the input provided by the
181
182
// caller. This avoids bugs due to e.g. tab characters and whatnot.
182
183
runes := m .san ().Sanitize ([]rune (s ))
183
- m .setValueInternal (runes )
184
+ blockInput , err := m .validateIfDefined (string (runes ))
185
+ m .setValueInternal (runes , err , blockInput )
184
186
}
185
187
186
- func (m * Model ) setValueInternal (runes []rune ) {
187
- if m .Validate != nil {
188
- if err := m .Validate (string (runes )); err != nil {
189
- m .Err = err
190
- return
191
- }
188
+ func (m * Model ) setValueInternal (runes []rune , err error , blockInput bool ) {
189
+ m .Err = err
190
+ if blockInput {
191
+ return
192
192
}
193
193
194
194
empty := len (m .value ) == 0
195
- m .Err = nil
196
195
197
196
if m .CharLimit > 0 && len (runes ) > m .CharLimit {
198
197
m .value = runes [:m .CharLimit ]
@@ -323,9 +322,10 @@ func (m *Model) insertRunesFromUserInput(v []rune) {
323
322
324
323
// Put it all back together
325
324
value := append (head , tail ... )
326
- m .setValueInternal (value )
325
+ blockInput , inputErr := m .validateIfDefined (string (value ))
326
+ m .setValueInternal (value , inputErr , blockInput )
327
327
328
- if m . Err != nil {
328
+ if blockInput {
329
329
m .pos = oldPos
330
330
}
331
331
}
@@ -378,6 +378,7 @@ func (m *Model) handleOverflow() {
378
378
// deleteBeforeCursor deletes all text before the cursor.
379
379
func (m * Model ) deleteBeforeCursor () {
380
380
m .value = m .value [m .pos :]
381
+ _ , m .Err = m .validateIfDefined (string (m .value ))
381
382
m .offset = 0
382
383
m .SetCursor (0 )
383
384
}
@@ -387,6 +388,7 @@ func (m *Model) deleteBeforeCursor() {
387
388
// masked input.
388
389
func (m * Model ) deleteAfterCursor () {
389
390
m .value = m .value [:m .pos ]
391
+ _ , m .Err = m .validateIfDefined (string (m .value ))
390
392
m .SetCursor (len (m .value ))
391
393
}
392
394
@@ -432,6 +434,7 @@ func (m *Model) deleteWordBackward() {
432
434
} else {
433
435
m .value = append (m .value [:m .pos ], m .value [oldPos :]... )
434
436
}
437
+ _ , m .Err = m .validateIfDefined (string (m .value ))
435
438
}
436
439
437
440
// deleteWordForward deletes the word right to the cursor. If input is masked
@@ -471,6 +474,7 @@ func (m *Model) deleteWordForward() {
471
474
} else {
472
475
m .value = append (m .value [:oldPos ], m .value [m .pos :]... )
473
476
}
477
+ _ , m .Err = m .validateIfDefined (string (m .value ))
474
478
475
479
m .SetCursor (oldPos )
476
480
}
@@ -575,12 +579,12 @@ func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) {
575
579
case tea.KeyMsg :
576
580
switch {
577
581
case key .Matches (msg , m .KeyMap .DeleteWordBackward ):
578
- m .Err = nil
579
582
m .deleteWordBackward ()
580
583
case key .Matches (msg , m .KeyMap .DeleteCharacterBackward ):
581
584
m .Err = nil
582
585
if len (m .value ) > 0 {
583
586
m .value = append (m .value [:max (0 , m .pos - 1 )], m .value [m .pos :]... )
587
+ _ , m .Err = m .validateIfDefined (string (m .value ))
584
588
if m .pos > 0 {
585
589
m .SetCursor (m .pos - 1 )
586
590
}
@@ -597,13 +601,12 @@ func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) {
597
601
if m .pos < len (m .value ) {
598
602
m .SetCursor (m .pos + 1 )
599
603
}
600
- case key .Matches (msg , m .KeyMap .DeleteWordBackward ):
601
- m .deleteWordBackward ()
602
604
case key .Matches (msg , m .KeyMap .LineStart ):
603
605
m .CursorStart ()
604
606
case key .Matches (msg , m .KeyMap .DeleteCharacterForward ):
605
607
if len (m .value ) > 0 && m .pos < len (m .value ) {
606
608
m .value = append (m .value [:m .pos ], m .value [m .pos + 1 :]... )
609
+ _ , m .Err = m .validateIfDefined (string (m .value ))
607
610
}
608
611
case key .Matches (msg , m .KeyMap .LineEnd ):
609
612
m .CursorEnd ()
@@ -859,3 +862,10 @@ func (m *Model) previousSuggestion() {
859
862
m .currentSuggestionIndex = len (m .matchedSuggestions ) - 1
860
863
}
861
864
}
865
+
866
+ func (m Model ) validateIfDefined (v string ) (bool , error ) {
867
+ if m .Validate != nil {
868
+ return m .Validate (v )
869
+ }
870
+ return false , nil
871
+ }
0 commit comments