diff --git a/textarea/textarea.go b/textarea/textarea.go index fe1bceb..f572c51 100644 --- a/textarea/textarea.go +++ b/textarea/textarea.go @@ -256,6 +256,7 @@ type Model struct { MaxWidth int SyntaxHighlighter func(string) string + Formatter func(string) string // Should the input suggest to complete ShowSuggestions bool @@ -496,6 +497,7 @@ func (m *Model) insertRunesFromUserInput(runes []rune) { // Finally add the tail at the end of the last line inserted. m.value[m.row] = append(m.value[m.row], tail...) + m.format() m.SetCursor(m.col) } @@ -1018,6 +1020,7 @@ func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) { if ok && key.Matches(keyMsg, m.KeyMap.AcceptSuggestion) { if m.canAcceptSuggestion() { m.value = m.matchedSuggestions[m.currentSuggestionIndex] + m.format() m.row = len(m.value) - 1 m.CursorEnd() } @@ -1101,7 +1104,11 @@ func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) { case key.Matches(msg, m.KeyMap.CharacterForward): m.characterRight() case key.Matches(msg, m.KeyMap.LineNext): - m.CursorDown() + if m.row == 0 { + m.nextSuggestion() + } else { + m.CursorDown() + } case key.Matches(msg, m.KeyMap.WordForward): m.wordRight() case key.Matches(msg, m.KeyMap.Paste): @@ -1109,7 +1116,11 @@ func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) { case key.Matches(msg, m.KeyMap.CharacterBackward): m.characterLeft(false /* insideLine */) case key.Matches(msg, m.KeyMap.LinePrevious): - m.CursorUp() + if m.row == 0 { + m.previousSuggestion() + } else { + m.CursorUp() + } case key.Matches(msg, m.KeyMap.WordBackward): m.wordLeft() case key.Matches(msg, m.KeyMap.InputBegin): @@ -1506,6 +1517,7 @@ func (m *Model) splitLine(row, col int) { m.value[row+1] = tail m.col = 0 + m.SetHeight(m.row + 2) m.row++ } @@ -1515,14 +1527,6 @@ func (m *Model) canAcceptSuggestion() bool { return len(m.matchedSuggestions) > 0 } -func linesToString(lines [][]rune) string { - var result []string - for _, line := range lines { - result = append(result, string(line)) - } - return strings.Join(result, "\n") -} - // updateSuggestions refreshes the list of matching suggestions. func (m *Model) updateSuggestions() { if !m.ShowSuggestions { @@ -1566,6 +1570,17 @@ func (m *Model) previousSuggestion() { } } +func (m *Model) format() { + if m.Formatter == nil { + return + } + m.value = stringToLines(m.Formatter(linesToString(m.value))) + m.row = len(m.value) - 1 + if m.col > len(m.value[m.row]) { + m.col = len(m.value[m.row]) - 1 + } +} + // Paste is a command for pasting from the clipboard into the text input. func Paste() tea.Msg { str, err := clipboard.ReadAll() @@ -1664,3 +1679,19 @@ func max(a, b int) int { } return b } + +func stringToLines(s string) [][]rune { + var r [][]rune + for _, line := range strings.Split(s, "\n") { + r = append(r, []rune(line)) + } + return r +} + +func linesToString(lines [][]rune) string { + var result []string + for _, line := range lines { + result = append(result, string(line)) + } + return strings.Join(result, "\n") +}