mirror of
https://github.com/jesseduffield/lazydocker.git
synced 2026-07-22 07:11:01 +00:00
gui: add gotoTopMain/gotoBottomMain navigation handlers
Add handlers that scroll the main panel to the top and bottom. gotoTopMain implements the vim-style "gg" double press (gocui has no native key-sequence support) by tracking the last 'g' press timestamp in the gui state, while gotoBottomMain jumps to the final line, honouring the ScrollPastBottom config. The origin math and double-press timing are factored into pure helpers so they can be unit tested.
This commit is contained in:
parent
ecad431523
commit
1a71302f11
2 changed files with 54 additions and 0 deletions
|
|
@ -87,6 +87,10 @@ type guiState struct {
|
|||
// Maintains the state of manual filtering i.e. typing in a substring
|
||||
// to filter on in the current panel.
|
||||
Filter filterState
|
||||
|
||||
// Timestamp of the last 'g' key press in the main panel, used to detect
|
||||
// the vim-style "gg" double press that jumps to the top.
|
||||
lastGPressedAt time.Time
|
||||
}
|
||||
|
||||
type filterState struct {
|
||||
|
|
|
|||
|
|
@ -2,10 +2,33 @@ package gui
|
|||
|
||||
import (
|
||||
"math"
|
||||
"time"
|
||||
|
||||
"github.com/jesseduffield/gocui"
|
||||
)
|
||||
|
||||
// gPressTimeout is the window within which two consecutive 'g' presses are
|
||||
// treated as the vim-style "gg" command to jump to the top of the main panel.
|
||||
const gPressTimeout = 250 * time.Millisecond
|
||||
|
||||
// isDoublePress reports whether `now` follows `previous` closely enough to be
|
||||
// considered the second half of a double key press.
|
||||
func isDoublePress(previous, now time.Time, timeout time.Duration) bool {
|
||||
return !previous.IsZero() && now.Sub(previous) <= timeout
|
||||
}
|
||||
|
||||
// gotoBottomOriginY returns the vertical origin that scrolls the main panel to
|
||||
// its final line. When scrollPastBottom is false the last page of content is
|
||||
// kept on screen rather than scrolling it off the top.
|
||||
func gotoBottomOriginY(totalLines, viewHeight int, scrollPastBottom bool) int {
|
||||
reservedLines := 0
|
||||
if !scrollPastBottom {
|
||||
reservedLines = viewHeight
|
||||
}
|
||||
|
||||
return int(math.Max(0, float64(totalLines-reservedLines)))
|
||||
}
|
||||
|
||||
func (gui *Gui) scrollUpMain() error {
|
||||
mainView := gui.Views.Main
|
||||
mainView.Autoscroll = false
|
||||
|
|
@ -73,6 +96,33 @@ func (gui *Gui) jumpToTopMain(g *gocui.Gui, v *gocui.View) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// gotoTopMain implements the vim-style "gg" command: the first 'g' arms the
|
||||
// sequence and the second 'g' pressed within gPressTimeout jumps to the top of
|
||||
// the main panel.
|
||||
func (gui *Gui) gotoTopMain(g *gocui.Gui, v *gocui.View) error {
|
||||
now := time.Now()
|
||||
if !isDoublePress(gui.State.lastGPressedAt, now, gPressTimeout) {
|
||||
gui.State.lastGPressedAt = now
|
||||
return nil
|
||||
}
|
||||
|
||||
gui.State.lastGPressedAt = time.Time{}
|
||||
return gui.jumpToTopMain(g, v)
|
||||
}
|
||||
|
||||
// gotoBottomMain implements the vim-style "G" command, jumping to the bottom of
|
||||
// the main panel.
|
||||
func (gui *Gui) gotoBottomMain(g *gocui.Gui, v *gocui.View) error {
|
||||
mainView := gui.Views.Main
|
||||
mainView.Autoscroll = false
|
||||
|
||||
_, viewHeight := mainView.Size()
|
||||
ox, _ := mainView.Origin()
|
||||
newOy := gotoBottomOriginY(mainView.ViewLinesHeight(), viewHeight, gui.Config.UserConfig.Gui.ScrollPastBottom)
|
||||
|
||||
return mainView.SetOrigin(ox, newOy)
|
||||
}
|
||||
|
||||
func (gui *Gui) onMainTabClick(tabIndex int) error {
|
||||
gui.Log.Warn(tabIndex)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue