fix: added gutter fix and basic scroll
All checks were successful
Run Test Suite / test (push) Successful in 15s
All checks were successful
Run Test Suite / test (push) Successful in 15s
Scrolling is pretty useless, but nice touch
This commit is contained in:
parent
a5ff18e1de
commit
58082afdd2
@ -23,11 +23,13 @@ func main() {
|
|||||||
prog = program.NewProgramBuilder().
|
prog = program.NewProgramBuilder().
|
||||||
EmptyProgram().
|
EmptyProgram().
|
||||||
WithOpt(tea.WithAltScreen()).
|
WithOpt(tea.WithAltScreen()).
|
||||||
|
WithOpt(tea.WithMouseCellMotion()).
|
||||||
Build()
|
Build()
|
||||||
} else {
|
} else {
|
||||||
prog = program.NewProgramBuilder().
|
prog = program.NewProgramBuilder().
|
||||||
FileProgram(args[0]).
|
FileProgram(args[0]).
|
||||||
WithOpt(tea.WithAltScreen()).
|
WithOpt(tea.WithAltScreen()).
|
||||||
|
WithOpt(tea.WithMouseCellMotion()).
|
||||||
Build()
|
Build()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,83 +1,95 @@
|
|||||||
package editor
|
package editor
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"git.gophernest.net/azpect/TextEditor/internal/core"
|
"git.gophernest.net/azpect/TextEditor/internal/core"
|
||||||
tea "github.com/charmbracelet/bubbletea"
|
"git.gophernest.net/azpect/TextEditor/internal/motion"
|
||||||
|
tea "github.com/charmbracelet/bubbletea"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Model.Update: Handles BubbleTea messages including window resizes and key
|
// Model.Update: Handles BubbleTea messages including window resizes and key
|
||||||
// presses. Routes input to the handler and adjusts scroll after updates.
|
// presses. Routes input to the handler and adjusts scroll after updates.
|
||||||
func (m *Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
func (m *Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||||
var cmd tea.Cmd
|
var cmd tea.Cmd
|
||||||
|
|
||||||
switch msg := msg.(type) {
|
switch msg := msg.(type) {
|
||||||
|
|
||||||
case tea.WindowSizeMsg:
|
case tea.WindowSizeMsg:
|
||||||
m.termHeight = msg.Height
|
m.termHeight = msg.Height
|
||||||
m.termWidth = msg.Width
|
m.termWidth = msg.Width
|
||||||
|
|
||||||
// TODO: Implement a layout method that handles this
|
// TODO: Implement a layout method that handles this
|
||||||
//
|
//
|
||||||
// func (m *Model) layoutWindows() {
|
// func (m *Model) layoutWindows() {
|
||||||
// if len(m.windows) == 0 {
|
// if len(m.windows) == 0 {
|
||||||
// return
|
// return
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// if len(m.windows) == 1 {
|
// if len(m.windows) == 1 {
|
||||||
// // Single window - full screen
|
// // Single window - full screen
|
||||||
// m.windows[0].Width = m.termWidth
|
// m.windows[0].Width = m.termWidth
|
||||||
// m.windows[0].Height = m.termHeight
|
// m.windows[0].Height = m.termHeight
|
||||||
// return
|
// return
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// // Multiple windows - distribute space
|
// // Multiple windows - distribute space
|
||||||
// // This is where you'd implement split layout logic
|
// // This is where you'd implement split layout logic
|
||||||
// // For example, horizontal split:
|
// // For example, horizontal split:
|
||||||
// halfHeight := m.termHeight / 2
|
// halfHeight := m.termHeight / 2
|
||||||
// for i, win := range m.windows {
|
// for i, win := range m.windows {
|
||||||
// win.Width = m.termWidth
|
// win.Width = m.termWidth
|
||||||
// if i < len(m.windows)-1 {
|
// if i < len(m.windows)-1 {
|
||||||
// win.Height = halfHeight
|
// win.Height = halfHeight
|
||||||
// } else {
|
// } else {
|
||||||
// // Last window gets remainder
|
// // Last window gets remainder
|
||||||
// win.Height = m.termHeight - (halfHeight * (len(m.windows) - 1))
|
// win.Height = m.termHeight - (halfHeight * (len(m.windows) - 1))
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
for i := range m.windows {
|
for i := range m.windows {
|
||||||
m.windows[i].Height = msg.Height
|
m.windows[i].Height = msg.Height
|
||||||
m.windows[i].Width = msg.Width
|
m.windows[i].Width = msg.Width
|
||||||
}
|
}
|
||||||
|
|
||||||
case tea.KeyMsg:
|
// TODO: This is not great, totally temporary. But I don't like vim's handling, so this is up to me
|
||||||
// TODO: This needs to be removed, but for now its required for the tests.
|
case tea.MouseMsg:
|
||||||
// Ctrl+C always quits regardless of mode
|
switch msg.Button {
|
||||||
if msg.Type == tea.KeyCtrlC {
|
case tea.MouseButtonWheelUp:
|
||||||
return m, tea.Quit
|
scrollAction := motion.ScrollUpPage{Divisor: 4} // Quarter page
|
||||||
}
|
cmd = scrollAction.Execute(m)
|
||||||
|
case tea.MouseButtonWheelDown:
|
||||||
|
scrollAction := motion.ScrollDownPage{Divisor: 4} // Quarter page
|
||||||
|
cmd = scrollAction.Execute(m)
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: This is not great
|
case tea.KeyMsg:
|
||||||
// TODO: Any vim action should exit also
|
// TODO: This needs to be removed, but for now its required for the tests.
|
||||||
// Simple override for command output mode for now
|
// Ctrl+C always quits regardless of mode
|
||||||
if m.Mode() == core.CommandOutputMode {
|
if msg.Type == tea.KeyCtrlC {
|
||||||
// TODO: Implement g/G/d/u
|
return m, tea.Quit
|
||||||
switch msg.String() {
|
}
|
||||||
case "enter":
|
|
||||||
m.SetMode(core.NormalMode)
|
|
||||||
m.SetCommandOutput(&core.CommandOutput{})
|
|
||||||
case "j":
|
|
||||||
m.CommandOutput().ScrollDown(m.termHeight)
|
|
||||||
case "k":
|
|
||||||
m.CommandOutput().ScrollUp()
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
cmd = m.input.Handle(m, msg.String())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Keep cursor in view after any update
|
// TODO: This is not great
|
||||||
win := m.ActiveWindow()
|
// TODO: Any vim action should exit also
|
||||||
win.AdjustScroll()
|
// Simple override for command output mode for now
|
||||||
|
if m.Mode() == core.CommandOutputMode {
|
||||||
|
// TODO: Implement g/G/d/u
|
||||||
|
switch msg.String() {
|
||||||
|
case "enter":
|
||||||
|
m.SetMode(core.NormalMode)
|
||||||
|
m.SetCommandOutput(&core.CommandOutput{})
|
||||||
|
case "j":
|
||||||
|
m.CommandOutput().ScrollDown(m.termHeight)
|
||||||
|
case "k":
|
||||||
|
m.CommandOutput().ScrollUp()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cmd = m.input.Handle(m, msg.String())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return m, cmd
|
// Keep cursor in view after any update
|
||||||
|
win := m.ActiveWindow()
|
||||||
|
win.AdjustScroll()
|
||||||
|
|
||||||
|
return m, cmd
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,6 +2,7 @@ package editor
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"git.gophernest.net/azpect/TextEditor/internal/core"
|
"git.gophernest.net/azpect/TextEditor/internal/core"
|
||||||
@ -22,6 +23,10 @@ func (m Model) View() string {
|
|||||||
styles := m.Styles()
|
styles := m.Styles()
|
||||||
options := win.Options
|
options := win.Options
|
||||||
|
|
||||||
|
// Adjust gutter to fit line len
|
||||||
|
maxLineLen := len(strconv.Itoa(win.Buffer.LineCount()))
|
||||||
|
options.GutterSize = max(options.GutterSize, maxLineLen+2)
|
||||||
|
|
||||||
// Draw window
|
// Draw window
|
||||||
view := viewWindow(win, styles, options, m.Mode())
|
view := viewWindow(win, styles, options, m.Mode())
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user