@@ -46,6 +46,10 @@ type KeyMap struct {
46
46
Paste key.Binding
47
47
WordBackward key.Binding
48
48
WordForward key.Binding
49
+
50
+ UppercaseWordForward key.Binding
51
+ LowercaseWordForward key.Binding
52
+ CapitalizeWordForward key.Binding
49
53
}
50
54
51
55
// DefaultKeyMap is the default set of key bindings for navigating and acting
@@ -67,6 +71,10 @@ var DefaultKeyMap = KeyMap{
67
71
LineStart : key .NewBinding (key .WithKeys ("home" , "ctrl+a" )),
68
72
LineEnd : key .NewBinding (key .WithKeys ("end" , "ctrl+e" )),
69
73
Paste : key .NewBinding (key .WithKeys ("ctrl+v" )),
74
+
75
+ CapitalizeWordForward : key .NewBinding (key .WithKeys ("alt+c" )),
76
+ LowercaseWordForward : key .NewBinding (key .WithKeys ("alt+l" )),
77
+ UppercaseWordForward : key .NewBinding (key .WithKeys ("alt+u" )),
70
78
}
71
79
72
80
// LineInfo is a helper for keeping track of line information regarding
@@ -598,6 +606,10 @@ func (m *Model) wordLeft() {
598
606
// cursor blink should be reset. If the input is masked, move input to the end
599
607
// so as not to reveal word breaks in the masked input.
600
608
func (m * Model ) wordRight () {
609
+ m .doWordRight (func (int , int ) { /* nothing */ })
610
+ }
611
+
612
+ func (m * Model ) doWordRight (fn func (charIdx int , pos int )) {
601
613
// Skip spaces forward.
602
614
for {
603
615
if m .col < len (m .value [m .row ]) && ! unicode .IsSpace (m.value [m.row ][m.col ]) {
@@ -606,14 +618,40 @@ func (m *Model) wordRight() {
606
618
m .characterRight ()
607
619
}
608
620
621
+ charIdx := 0
609
622
for m .col < len (m .value [m .row ]) {
610
623
if unicode .IsSpace (m.value [m.row ][m.col ]) {
611
624
break
612
625
}
626
+ fn (charIdx , m .col )
613
627
m .SetCursor (m .col + 1 )
628
+ charIdx ++
614
629
}
615
630
}
616
631
632
+ // uppercaseRight changes the word to the right to uppercase.
633
+ func (m * Model ) uppercaseRight () {
634
+ m .doWordRight (func (_ int , i int ) {
635
+ m.value [m.row ][i ] = unicode .ToUpper (m.value [m.row ][i ])
636
+ })
637
+ }
638
+
639
+ // lowercaseRight changes the word to the right to lowercase.
640
+ func (m * Model ) lowercaseRight () {
641
+ m .doWordRight (func (_ int , i int ) {
642
+ m.value [m.row ][i ] = unicode .ToLower (m.value [m.row ][i ])
643
+ })
644
+ }
645
+
646
+ // capitalizeRight changes the word to the right to title case.
647
+ func (m * Model ) capitalizeRight () {
648
+ m .doWordRight (func (charIdx int , i int ) {
649
+ if charIdx == 0 {
650
+ m.value [m.row ][i ] = unicode .ToTitle (m.value [m.row ][i ])
651
+ }
652
+ })
653
+ }
654
+
617
655
// LineInfo returns the number of characters from the start of the
618
656
// (soft-wrapped) line and the (soft-wrapped) line width.
619
657
func (m Model ) LineInfo () LineInfo {
@@ -798,6 +836,14 @@ func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) {
798
836
m .CursorUp ()
799
837
case key .Matches (msg , m .KeyMap .WordBackward ):
800
838
m .wordLeft ()
839
+
840
+ case key .Matches (msg , m .KeyMap .LowercaseWordForward ):
841
+ m .lowercaseRight ()
842
+ case key .Matches (msg , m .KeyMap .UppercaseWordForward ):
843
+ m .uppercaseRight ()
844
+ case key .Matches (msg , m .KeyMap .CapitalizeWordForward ):
845
+ m .capitalizeRight ()
846
+
801
847
default :
802
848
if m .CharLimit > 0 && rw .StringWidth (m .Value ()) >= m .CharLimit {
803
849
break
0 commit comments