This commit is contained in:
Ayman Bagabas
2024-11-26 15:00:40 -05:00
3 changed files with 52 additions and 59 deletions
+1 -1
View File
@@ -5,7 +5,7 @@ go 1.18
require (
github.com/MakeNowJust/heredoc v1.0.0
github.com/atotto/clipboard v0.1.4
github.com/charmbracelet/bubbletea/v2 v2.0.0-alpha.2.0.20241121171714-fbd5423ea935
github.com/charmbracelet/bubbletea/v2 v2.0.0-alpha.2.0.20241126192050-a8ed96118b08
github.com/charmbracelet/harmonica v0.2.0
github.com/charmbracelet/lipgloss/v2 v2.0.0-alpha.2.0.20241121164047-8448a9be4804
github.com/charmbracelet/x/ansi v0.5.1
+2 -2
View File
@@ -6,8 +6,8 @@ github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiE
github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=
github.com/aymanbagabas/go-udiff v0.2.0 h1:TK0fH4MteXUDspT88n8CKzvK0X9O2xu9yQjWpi6yML8=
github.com/aymanbagabas/go-udiff v0.2.0/go.mod h1:RE4Ex0qsGkTAJoQdQQCA0uG+nAzJO/pI/QwceO5fgrA=
github.com/charmbracelet/bubbletea/v2 v2.0.0-alpha.2.0.20241121171714-fbd5423ea935 h1:S+hhEwWnJxDeZMtHqIHgGVilNWsez3xmFOpwSc9GbcE=
github.com/charmbracelet/bubbletea/v2 v2.0.0-alpha.2.0.20241121171714-fbd5423ea935/go.mod h1:BbC4R+6e9TLjbskxrjISt/DDCn4OiB6v+ArqfYiPyyg=
github.com/charmbracelet/bubbletea/v2 v2.0.0-alpha.2.0.20241126192050-a8ed96118b08 h1:8hwULvCHjF6JjaeosebMGbB06oCv46d4s+Lbs5ytAT4=
github.com/charmbracelet/bubbletea/v2 v2.0.0-alpha.2.0.20241126192050-a8ed96118b08/go.mod h1:BbC4R+6e9TLjbskxrjISt/DDCn4OiB6v+ArqfYiPyyg=
github.com/charmbracelet/colorprofile v0.1.8 h1:PywDeXsiAzlPtkiiKgMEVLvb6nlEuKrMj9+FJBtj4jU=
github.com/charmbracelet/colorprofile v0.1.8/go.mod h1:+jpmObxZl1Dab3H3IMVIPSZTsKcFpjJUv97G0dLqM60=
github.com/charmbracelet/harmonica v0.2.0 h1:8NxJWRWg/bzKqqEaaeFNipOu77YR5t8aSwG4pgaUBiQ=
+49 -56
View File
@@ -293,9 +293,12 @@ type Model struct {
// Cursor row.
row int
// The bubble offset in the parent model.
// The bubble offset relative to the parent bubble.
offsetX, offsetY int
// The last recorded real cursor position.
realCol, realRow int
// Last character offset, used to maintain state when the cursor is moved
// vertically such that we can maintain the same navigating position.
lastCharOffset int
@@ -383,6 +386,11 @@ func DefaultDarkStyles() Styles {
return DefaultStyles(true)
}
// SetOffset sets the offset of the textarea relative to the parent bubble.
func (m *Model) SetOffset(x, y int) {
m.offsetX, m.offsetY = x, y
}
// SetValue sets the value of the text input.
func (m *Model) SetValue(s string) {
m.Reset()
@@ -536,11 +544,6 @@ func (m Model) Line() int {
return m.row
}
// SetOffset sets the bubble offset in the parent model.
func (m *Model) SetOffset(x, y int) {
m.offsetX, m.offsetY = x, y
}
// CursorDown moves the cursor down by one line.
// Returns whether or not the cursor blink should be reset.
func (m *Model) CursorDown() {
@@ -661,6 +664,8 @@ func (m *Model) Reset() {
m.value = make([][]rune, minHeight, maxLines)
m.col = 0
m.row = 0
m.realCol = 0
m.realRow = 0
m.viewport.GotoTop()
m.SetCursor(0)
}
@@ -1026,15 +1031,16 @@ func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) {
}
// Need to check for completion before, because key is configurable and might be double assigned
keyMsg, ok := msg.(tea.KeyMsg)
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()
}
}
// keyMsg, ok := msg.(tea.KeyMsg)
// 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()
// m.SetSuggestions(nil)
// }
// }
// Used to determine if the cursor should blink.
oldRow, oldCol := m.cursorLineNumber(), m.col
@@ -1173,11 +1179,23 @@ func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) {
cmds = append(cmds, tea.SetCursorPosition(m.offsetX+newCol, m.offsetY+newRow))
m.Cursor, cmd = m.Cursor.Update(msg)
if (newRow != oldRow || newCol != oldCol) && m.Cursor.Mode() == cursor.CursorBlink {
if cmd != nil {
cmds = append(cmds, cmd)
}
if m.Cursor.Mode() == cursor.CursorBlink && (newRow != oldRow || newCol != oldCol) {
m.Cursor.Blink = false
cmd = m.Cursor.BlinkCmd()
cmds = append(cmds, m.Cursor.BlinkCmd())
}
// Ensure the real cursor is at the correct position.
row := m.cursorLineNumber()
lineInfo := m.LineInfo()
realCol, realRow := m.offsetX+lineInfo.CharOffset, m.offsetY+row-m.viewport.YOffset
if realCol != m.realCol || realRow != m.realRow {
m.realCol, m.realRow = realCol, realRow
cmds = append(cmds, tea.SetCursorPosition(realCol, realRow))
}
cmds = append(cmds, cmd)
m.repositionView()
@@ -1197,7 +1215,7 @@ func (m Model) suggestionView(offset int) string {
var lines []string
for _, line := range strings.Split(suggestion[len(m.Value())+offset:], "\n") {
lines = append(lines, m.style.Placeholder.Inline(true).Render(line))
lines = append(lines, m.activeStyle.Placeholder.Inline(true).Render(line))
}
if len(lines) > m.Height() {
m.SetHeight(len(lines) + 1)
@@ -1217,7 +1235,7 @@ func (m Model) View() string {
style lipgloss.Style
newLines int
widestLineNumber int
lineInfo = m.LineInfo()
// lineInfo = m.LineInfo()
)
displayLine := 0
@@ -1276,45 +1294,20 @@ func (m Model) View() string {
wrappedLine = []rune(strings.TrimSuffix(string(wrappedLine), " "))
padding -= m.width - strwidth
}
if m.row == l && lineInfo.RowOffset == wl {
ln := string(wrappedLine[:lineInfo.ColumnOffset])
if m.SyntaxHighlighter == nil {
ln = style.Render(ln)
} else {
ln = m.SyntaxHighlighter(ln)
}
s.WriteString(ln)
if m.col >= len(line) && lineInfo.CharOffset >= m.width {
m.Cursor.SetChar(" ")
s.WriteString(m.Cursor.View())
// XXX: suggestions?
} else {
m.Cursor.SetChar(string(wrappedLine[lineInfo.ColumnOffset]))
if m.canAcceptSuggestion() && len(m.matchedSuggestions) > 0 {
suggestion := m.matchedSuggestions[m.currentSuggestionIndex]
if len(suggestion) >= m.row {
suggestion = suggestion[m.row:]
}
m.Cursor.TextStyle = m.style.Placeholder
if len(suggestion) > m.row && len(suggestion[m.row]) > m.col {
m.Cursor.SetChar(string(suggestion[m.row][m.col]))
}
}
s.WriteString(style.Render(m.Cursor.View()))
s.WriteString(style.Render(string(wrappedLine[lineInfo.ColumnOffset+1:])))
s.WriteString(m.suggestionView(1))
// XXX: suggestions
}
ln = string(wrappedLine)
if m.SyntaxHighlighter == nil {
ln = style.Render(ln)
} else {
ln := string(wrappedLine)
if m.SyntaxHighlighter == nil {
ln = style.Render(ln)
} else {
ln = m.SyntaxHighlighter(ln)
}
s.WriteString(ln)
ln = m.SyntaxHighlighter(ln)
}
s.WriteString(ln)
// if m.col < len(line) || lineInfo.CharOffset < m.width {
// if m.canAcceptSuggestion() && len(m.matchedSuggestions) > 0 {
// s.WriteString(m.suggestionView(1))
// }
// }
pad := strings.Repeat(" ", max(0, padding))
if m.SyntaxHighlighter == nil {