feat!: use bubbletea@v2-exp

This commit is contained in:
Ayman Bagabas
2024-09-09 14:12:52 -04:00
parent d3bd075ed2
commit a93bfef532
14 changed files with 48 additions and 36 deletions
+1 -1
View File
@@ -185,7 +185,7 @@ var DefaultKeyMap = KeyMap{
func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
switch msg := msg.(type) { switch msg := msg.(type) {
case tea.KeyMsg: case tea.KeyPressMsg:
switch { switch {
case key.Matches(msg, DefaultKeyMap.Up): case key.Matches(msg, DefaultKeyMap.Up):
// The user pressed up // The user pressed up
+4 -4
View File
@@ -254,7 +254,7 @@ func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) {
m.Height = msg.Height - marginBottom m.Height = msg.Height - marginBottom
} }
m.max = m.Height - 1 m.max = m.Height - 1
case tea.KeyMsg: case tea.KeyPressMsg:
switch { switch {
case key.Matches(msg, m.KeyMap.GoToTop): case key.Matches(msg, m.KeyMap.GoToTop):
m.selected = 0 m.selected = 0
@@ -463,7 +463,7 @@ func (m Model) didSelectFile(msg tea.Msg) (bool, string) {
return false, "" return false, ""
} }
switch msg := msg.(type) { switch msg := msg.(type) {
case tea.KeyMsg: case tea.KeyPressMsg:
// If the msg does not match the Select keymap then this could not have been a selection. // If the msg does not match the Select keymap then this could not have been a selection.
if !key.Matches(msg, m.KeyMap.Select) { if !key.Matches(msg, m.KeyMap.Select) {
return false, "" return false, ""
@@ -494,8 +494,8 @@ func (m Model) didSelectFile(msg tea.Msg) (bool, string) {
return true, m.Path return true, m.Path
} }
// If the msg was not a KeyMsg, then the file could not have been selected this iteration. // If the msg was not a KeyPressMsg, then the file could not have been selected this iteration.
// Only a KeyMsg can select a file. // Only a KeyPressMsg can select a file.
default: default:
return false, "" return false, ""
} }
+3 -1
View File
@@ -5,7 +5,7 @@ go 1.18
require ( require (
github.com/MakeNowJust/heredoc v1.0.0 github.com/MakeNowJust/heredoc v1.0.0
github.com/atotto/clipboard v0.1.4 github.com/atotto/clipboard v0.1.4
github.com/charmbracelet/bubbletea v1.1.0 github.com/charmbracelet/bubbletea v1.1.1-0.20240830154658-85c5adc127b3
github.com/charmbracelet/harmonica v0.2.0 github.com/charmbracelet/harmonica v0.2.0
github.com/charmbracelet/lipgloss v0.13.0 github.com/charmbracelet/lipgloss v0.13.0
github.com/charmbracelet/x/ansi v0.2.3 github.com/charmbracelet/x/ansi v0.2.3
@@ -22,12 +22,14 @@ require (
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
github.com/aymanbagabas/go-udiff v0.2.0 // indirect github.com/aymanbagabas/go-udiff v0.2.0 // indirect
github.com/charmbracelet/x/term v0.2.0 // indirect github.com/charmbracelet/x/term v0.2.0 // indirect
github.com/charmbracelet/x/windows v0.2.0 // indirect
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect
github.com/kylelemons/godebug v1.1.0 // indirect github.com/kylelemons/godebug v1.1.0 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-localereader v0.0.1 // indirect github.com/mattn/go-localereader v0.0.1 // indirect
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect
github.com/muesli/cancelreader v0.2.2 // indirect github.com/muesli/cancelreader v0.2.2 // indirect
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
golang.org/x/sync v0.8.0 // indirect golang.org/x/sync v0.8.0 // indirect
golang.org/x/sys v0.24.0 // indirect golang.org/x/sys v0.24.0 // indirect
golang.org/x/text v0.3.8 // indirect golang.org/x/text v0.3.8 // indirect
+6
View File
@@ -8,6 +8,8 @@ github.com/aymanbagabas/go-udiff v0.2.0 h1:TK0fH4MteXUDspT88n8CKzvK0X9O2xu9yQjWp
github.com/aymanbagabas/go-udiff v0.2.0/go.mod h1:RE4Ex0qsGkTAJoQdQQCA0uG+nAzJO/pI/QwceO5fgrA= github.com/aymanbagabas/go-udiff v0.2.0/go.mod h1:RE4Ex0qsGkTAJoQdQQCA0uG+nAzJO/pI/QwceO5fgrA=
github.com/charmbracelet/bubbletea v1.1.0 h1:FjAl9eAL3HBCHenhz/ZPjkKdScmaS5SK69JAK2YJK9c= github.com/charmbracelet/bubbletea v1.1.0 h1:FjAl9eAL3HBCHenhz/ZPjkKdScmaS5SK69JAK2YJK9c=
github.com/charmbracelet/bubbletea v1.1.0/go.mod h1:9Ogk0HrdbHolIKHdjfFpyXJmiCzGwy+FesYkZr7hYU4= github.com/charmbracelet/bubbletea v1.1.0/go.mod h1:9Ogk0HrdbHolIKHdjfFpyXJmiCzGwy+FesYkZr7hYU4=
github.com/charmbracelet/bubbletea v1.1.1-0.20240830154658-85c5adc127b3 h1:oqDwkNLoIVbOjX0ZomkPljMtRKZvJMpYkR1A68QcbJo=
github.com/charmbracelet/bubbletea v1.1.1-0.20240830154658-85c5adc127b3/go.mod h1:RYka31SjvShLlaYsbsBSiXnneU2JUEoKvI3nrOUaJuw=
github.com/charmbracelet/harmonica v0.2.0 h1:8NxJWRWg/bzKqqEaaeFNipOu77YR5t8aSwG4pgaUBiQ= github.com/charmbracelet/harmonica v0.2.0 h1:8NxJWRWg/bzKqqEaaeFNipOu77YR5t8aSwG4pgaUBiQ=
github.com/charmbracelet/harmonica v0.2.0/go.mod h1:KSri/1RMQOZLbw7AHqgcBycp8pgJnQMYYT8QZRqZ1Ao= github.com/charmbracelet/harmonica v0.2.0/go.mod h1:KSri/1RMQOZLbw7AHqgcBycp8pgJnQMYYT8QZRqZ1Ao=
github.com/charmbracelet/lipgloss v0.13.0 h1:4X3PPeoWEDCMvzDvGmTajSyYPcZM4+y8sCA/SsA3cjw= github.com/charmbracelet/lipgloss v0.13.0 h1:4X3PPeoWEDCMvzDvGmTajSyYPcZM4+y8sCA/SsA3cjw=
@@ -18,6 +20,8 @@ github.com/charmbracelet/x/exp/golden v0.0.0-20240815200342-61de596daa2b h1:MnAM
github.com/charmbracelet/x/exp/golden v0.0.0-20240815200342-61de596daa2b/go.mod h1:wDlXFlCrmJ8J+swcL/MnGUuYnqgQdW9rhSD61oNMb6U= github.com/charmbracelet/x/exp/golden v0.0.0-20240815200342-61de596daa2b/go.mod h1:wDlXFlCrmJ8J+swcL/MnGUuYnqgQdW9rhSD61oNMb6U=
github.com/charmbracelet/x/term v0.2.0 h1:cNB9Ot9q8I711MyZ7myUR5HFWL/lc3OpU8jZ4hwm0x0= github.com/charmbracelet/x/term v0.2.0 h1:cNB9Ot9q8I711MyZ7myUR5HFWL/lc3OpU8jZ4hwm0x0=
github.com/charmbracelet/x/term v0.2.0/go.mod h1:GVxgxAbjUrmpvIINHIQnJJKpMlHiZ4cktEQCN6GWyF0= github.com/charmbracelet/x/term v0.2.0/go.mod h1:GVxgxAbjUrmpvIINHIQnJJKpMlHiZ4cktEQCN6GWyF0=
github.com/charmbracelet/x/windows v0.2.0 h1:ilXA1GJjTNkgOm94CLPeSz7rar54jtFatdmoiONPuEw=
github.com/charmbracelet/x/windows v0.2.0/go.mod h1:ZibNFR49ZFqCXgP76sYanisxRyC+EYrBE7TTknD8s1s=
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6baUTXGLOoWe4PQhGxaX0KpnayAqC48p4= github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6baUTXGLOoWe4PQhGxaX0KpnayAqC48p4=
@@ -43,6 +47,8 @@ github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/sahilm/fuzzy v0.1.1 h1:ceu5RHF8DGgoi+/dR5PsECjCDH1BE3Fnmpo7aVXOdRA= github.com/sahilm/fuzzy v0.1.1 h1:ceu5RHF8DGgoi+/dR5PsECjCDH1BE3Fnmpo7aVXOdRA=
github.com/sahilm/fuzzy v0.1.1/go.mod h1:VFvziUEIMCrT6A6tw2RFIXPXXmzXbOsSHF0DOI8ZK9Y= github.com/sahilm/fuzzy v0.1.1/go.mod h1:VFvziUEIMCrT6A6tw2RFIXPXXmzXbOsSHF0DOI8ZK9Y=
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no=
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM=
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+1 -1
View File
@@ -20,7 +20,7 @@
// //
// func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { // func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
// switch msg := msg.(type) { // switch msg := msg.(type) {
// case tea.KeyMsg: // case tea.KeyPressMsg:
// switch { // switch {
// case key.Matches(msg, DefaultKeyMap.Up): // case key.Matches(msg, DefaultKeyMap.Up):
// // The user pressed up // // The user pressed up
+3 -3
View File
@@ -771,7 +771,7 @@ func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) {
var cmds []tea.Cmd var cmds []tea.Cmd
switch msg := msg.(type) { switch msg := msg.(type) {
case tea.KeyMsg: case tea.KeyPressMsg:
if key.Matches(msg, m.KeyMap.ForceQuit) { if key.Matches(msg, m.KeyMap.ForceQuit) {
return m, tea.Quit return m, tea.Quit
} }
@@ -806,7 +806,7 @@ func (m *Model) handleBrowsing(msg tea.Msg) tea.Cmd {
numItems := len(m.VisibleItems()) numItems := len(m.VisibleItems())
switch msg := msg.(type) { switch msg := msg.(type) {
case tea.KeyMsg: case tea.KeyPressMsg:
switch { switch {
// Note: we match clear filter before quit because, by default, they're // Note: we match clear filter before quit because, by default, they're
// both mapped to escape. // both mapped to escape.
@@ -875,7 +875,7 @@ func (m *Model) handleFiltering(msg tea.Msg) tea.Cmd {
var cmds []tea.Cmd var cmds []tea.Cmd
// Handle keys // Handle keys
if msg, ok := msg.(tea.KeyMsg); ok { if msg, ok := msg.(tea.KeyPressMsg); ok {
switch { switch {
case key.Matches(msg, m.KeyMap.CancelWhileFiltering): case key.Matches(msg, m.KeyMap.CancelWhileFiltering):
m.resetFiltering() m.resetFiltering()
+1 -1
View File
@@ -175,7 +175,7 @@ func WithPerPage(perPage int) Option {
// Update is the Tea update function which binds keystrokes to pagination. // Update is the Tea update function which binds keystrokes to pagination.
func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) { func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) {
switch msg := msg.(type) { switch msg := msg.(type) {
case tea.KeyMsg: case tea.KeyPressMsg:
switch { switch {
case key.Matches(msg, m.KeyMap.NextPage): case key.Matches(msg, m.KeyMap.NextPage):
m.NextPage() m.NextPage()
+2 -2
View File
@@ -76,7 +76,7 @@ func TestPrevPage(t *testing.T) {
model.SetTotalPages(tt.totalPages) model.SetTotalPages(tt.totalPages)
model.Page = tt.page model.Page = tt.page
model, _ = model.Update(tea.KeyMsg{Type: tea.KeyLeft, Alt: false, Runes: []rune{}}) model, _ = model.Update(tea.KeyPressMsg{Code: tea.KeyLeft})
if model.Page != tt.expected { if model.Page != tt.expected {
t.Errorf("PrevPage() = %d, expected %d", model.Page, tt.expected) t.Errorf("PrevPage() = %d, expected %d", model.Page, tt.expected)
} }
@@ -101,7 +101,7 @@ func TestNextPage(t *testing.T) {
model.SetTotalPages(tt.totalPages) model.SetTotalPages(tt.totalPages)
model.Page = tt.page model.Page = tt.page
model, _ = model.Update(tea.KeyMsg{Type: tea.KeyRight, Alt: false, Runes: []rune{}}) model, _ = model.Update(tea.KeyPressMsg{Code: tea.KeyRight})
if model.Page != tt.expected { if model.Page != tt.expected {
t.Errorf("NextPage() = %d, expected %d", model.Page, tt.expected) t.Errorf("NextPage() = %d, expected %d", model.Page, tt.expected)
} }
+2 -2
View File
@@ -205,8 +205,8 @@ func New(opts ...Option) Model {
var NewModel = New var NewModel = New
// Init exists to satisfy the tea.Model interface. // Init exists to satisfy the tea.Model interface.
func (m Model) Init() tea.Cmd { func (m Model) Init() (tea.Model, tea.Cmd) {
return nil return m, nil
} }
// Update is used to animate the progress bar during transitions. Use // Update is used to animate the progress bar during transitions. Use
+1 -1
View File
@@ -205,7 +205,7 @@ func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) {
} }
switch msg := msg.(type) { switch msg := msg.(type) {
case tea.KeyMsg: case tea.KeyPressMsg:
switch { switch {
case key.Matches(msg, m.KeyMap.LineUp): case key.Matches(msg, m.KeyMap.LineUp):
m.MoveUp(1) m.MoveUp(1)
+2 -2
View File
@@ -973,7 +973,7 @@ func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) {
} }
switch msg := msg.(type) { switch msg := msg.(type) {
case tea.KeyMsg: case tea.KeyPressMsg:
switch { switch {
case key.Matches(msg, m.KeyMap.DeleteAfterCursor): case key.Matches(msg, m.KeyMap.DeleteAfterCursor):
m.col = clamp(m.col, 0, len(m.value[m.row])) m.col = clamp(m.col, 0, len(m.value[m.row]))
@@ -1060,7 +1060,7 @@ func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) {
m.transposeLeft() m.transposeLeft()
default: default:
m.insertRunesFromUserInput(msg.Runes) m.insertRunesFromUserInput([]rune(msg.Text))
} }
case pasteMsg: case pasteMsg:
+5 -5
View File
@@ -234,7 +234,7 @@ func TestVerticalNavigationKeepsCursorHorizontalPosition(t *testing.T) {
t.Fatal("Expected cursor to be on the fourth character because there are two double width runes on the first line.") t.Fatal("Expected cursor to be on the fourth character because there are two double width runes on the first line.")
} }
downMsg := tea.KeyMsg{Type: tea.KeyDown, Alt: false, Runes: []rune{}} downMsg := tea.KeyPressMsg{Code: tea.KeyDown}
textarea, _ = textarea.Update(downMsg) textarea, _ = textarea.Update(downMsg)
lineInfo = textarea.LineInfo() lineInfo = textarea.LineInfo()
@@ -273,7 +273,7 @@ func TestVerticalNavigationShouldRememberPositionWhileTraversing(t *testing.T) {
} }
// Let's go up. // Let's go up.
upMsg := tea.KeyMsg{Type: tea.KeyUp, Alt: false, Runes: []rune{}} upMsg := tea.KeyPressMsg{Code: tea.KeyUp}
textarea, _ = textarea.Update(upMsg) textarea, _ = textarea.Update(upMsg)
// We should be at the end of the second line. // We should be at the end of the second line.
@@ -292,7 +292,7 @@ func TestVerticalNavigationShouldRememberPositionWhileTraversing(t *testing.T) {
} }
// Let's go down, twice. // Let's go down, twice.
downMsg := tea.KeyMsg{Type: tea.KeyDown, Alt: false, Runes: []rune{}} downMsg := tea.KeyPressMsg{Code: tea.KeyDown}
textarea, _ = textarea.Update(downMsg) textarea, _ = textarea.Update(downMsg)
textarea, _ = textarea.Update(downMsg) textarea, _ = textarea.Update(downMsg)
@@ -308,7 +308,7 @@ func TestVerticalNavigationShouldRememberPositionWhileTraversing(t *testing.T) {
// work. // work.
textarea, _ = textarea.Update(upMsg) textarea, _ = textarea.Update(upMsg)
leftMsg := tea.KeyMsg{Type: tea.KeyLeft, Alt: false, Runes: []rune{}} leftMsg := tea.KeyPressMsg{Code: tea.KeyLeft}
textarea, _ = textarea.Update(leftMsg) textarea, _ = textarea.Update(leftMsg)
if textarea.col != 4 || textarea.row != 1 { if textarea.col != 4 || textarea.row != 1 {
@@ -1716,7 +1716,7 @@ func newTextArea() Model {
} }
func keyPress(key rune) tea.Msg { func keyPress(key rune) tea.Msg {
return tea.KeyMsg{Type: tea.KeyRunes, Runes: []rune{key}, Alt: false} return tea.KeyPressMsg{Code: key, Text: string(key)}
} }
func sendString(m Model, str string) Model { func sendString(m Model, str string) Model {
+6 -3
View File
@@ -555,7 +555,7 @@ 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 // Need to check for completion before, because key is configurable and might be double assigned
keyMsg, ok := msg.(tea.KeyMsg) keyMsg, ok := msg.(tea.KeyPressMsg)
if ok && key.Matches(keyMsg, m.KeyMap.AcceptSuggestion) { if ok && key.Matches(keyMsg, m.KeyMap.AcceptSuggestion) {
if m.canAcceptSuggestion() { if m.canAcceptSuggestion() {
m.value = append(m.value, m.matchedSuggestions[m.currentSuggestionIndex][len(m.value):]...) m.value = append(m.value, m.matchedSuggestions[m.currentSuggestionIndex][len(m.value):]...)
@@ -568,7 +568,7 @@ func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) {
oldPos := m.pos //nolint oldPos := m.pos //nolint
switch msg := msg.(type) { switch msg := msg.(type) {
case tea.KeyMsg: case tea.KeyPressMsg:
switch { switch {
case key.Matches(msg, m.KeyMap.DeleteWordBackward): case key.Matches(msg, m.KeyMap.DeleteWordBackward):
m.deleteWordBackward() m.deleteWordBackward()
@@ -616,13 +616,16 @@ func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) {
m.previousSuggestion() m.previousSuggestion()
default: default:
// Input one or more regular characters. // Input one or more regular characters.
m.insertRunesFromUserInput(msg.Runes) m.insertRunesFromUserInput([]rune(msg.Text))
} }
// Check again if can be completed // Check again if can be completed
// because value might be something that does not match the completion prefix // because value might be something that does not match the completion prefix
m.updateSuggestions() m.updateSuggestions()
case tea.PasteMsg:
m.insertRunesFromUserInput([]rune(msg))
case pasteMsg: case pasteMsg:
m.insertRunesFromUserInput([]rune(msg)) m.insertRunesFromUserInput([]rune(msg))
+11 -10
View File
@@ -292,7 +292,7 @@ func (m Model) updateAsModel(msg tea.Msg) (Model, tea.Cmd) {
var cmd tea.Cmd var cmd tea.Cmd
switch msg := msg.(type) { switch msg := msg.(type) {
case tea.KeyMsg: case tea.KeyPressMsg:
switch { switch {
case key.Matches(msg, m.KeyMap.PageDown): case key.Matches(msg, m.KeyMap.PageDown):
lines := m.ViewDown() lines := m.ViewDown()
@@ -331,22 +331,23 @@ func (m Model) updateAsModel(msg tea.Msg) (Model, tea.Cmd) {
} }
} }
case tea.MouseMsg: case tea.MouseWheelMsg:
if !m.MouseWheelEnabled || msg.Action != tea.MouseActionPress { if !m.MouseWheelEnabled {
break break
} }
switch msg.Button {
case tea.MouseButtonWheelUp:
lines := m.LineUp(m.MouseWheelDelta)
if m.HighPerformanceRendering {
cmd = ViewUp(m, lines)
}
case tea.MouseButtonWheelDown: switch msg.Button {
case tea.MouseWheelDown:
lines := m.LineDown(m.MouseWheelDelta) lines := m.LineDown(m.MouseWheelDelta)
if m.HighPerformanceRendering { if m.HighPerformanceRendering {
cmd = ViewDown(m, lines) cmd = ViewDown(m, lines)
} }
case tea.MouseWheelUp:
lines := m.LineUp(m.MouseWheelDelta)
if m.HighPerformanceRendering {
cmd = ViewUp(m, lines)
}
} }
} }