Skip to content

Commit a7fd61a

Browse files
committed
Support uppercase/lowercase/capitalize commands.
1 parent 4e9f9fa commit a7fd61a

File tree

1 file changed

+46
-0
lines changed

1 file changed

+46
-0
lines changed

textarea/textarea.go

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@ type KeyMap struct {
4646
Paste key.Binding
4747
WordBackward key.Binding
4848
WordForward key.Binding
49+
50+
UppercaseWordForward key.Binding
51+
LowercaseWordForward key.Binding
52+
CapitalizeWordForward key.Binding
4953
}
5054

5155
// DefaultKeyMap is the default set of key bindings for navigating and acting
@@ -67,6 +71,10 @@ var DefaultKeyMap = KeyMap{
6771
LineStart: key.NewBinding(key.WithKeys("home", "ctrl+a")),
6872
LineEnd: key.NewBinding(key.WithKeys("end", "ctrl+e")),
6973
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")),
7078
}
7179

7280
// LineInfo is a helper for keeping track of line information regarding
@@ -598,6 +606,10 @@ func (m *Model) wordLeft() {
598606
// cursor blink should be reset. If the input is masked, move input to the end
599607
// so as not to reveal word breaks in the masked input.
600608
func (m *Model) wordRight() {
609+
m.doWordRight(func(int, int) { /* nothing */ })
610+
}
611+
612+
func (m *Model) doWordRight(fn func(charIdx int, pos int)) {
601613
// Skip spaces forward.
602614
for {
603615
if m.col < len(m.value[m.row]) && !unicode.IsSpace(m.value[m.row][m.col]) {
@@ -606,14 +618,40 @@ func (m *Model) wordRight() {
606618
m.characterRight()
607619
}
608620

621+
charIdx := 0
609622
for m.col < len(m.value[m.row]) {
610623
if unicode.IsSpace(m.value[m.row][m.col]) {
611624
break
612625
}
626+
fn(charIdx, m.col)
613627
m.SetCursor(m.col + 1)
628+
charIdx++
614629
}
615630
}
616631

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+
617655
// LineInfo returns the number of characters from the start of the
618656
// (soft-wrapped) line and the (soft-wrapped) line width.
619657
func (m Model) LineInfo() LineInfo {
@@ -798,6 +836,14 @@ func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) {
798836
m.CursorUp()
799837
case key.Matches(msg, m.KeyMap.WordBackward):
800838
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+
801847
default:
802848
if m.CharLimit > 0 && rw.StringWidth(m.Value()) >= m.CharLimit {
803849
break

0 commit comments

Comments
 (0)