From 2a13a3315f9f07819da638ce6b3f8a02d4ca2c6f Mon Sep 17 00:00:00 2001 From: Nimish Jha Date: Thu, 24 Oct 2024 08:24:08 +1100 Subject: [PATCH] implement nano-like page up/page down functionality --- internal/action/actions.go | 48 +++++++++++++++++++++++-------------- internal/config/settings.go | 2 ++ runtime/help/options.md | 7 ++++++ 3 files changed, 39 insertions(+), 18 deletions(-) diff --git a/internal/action/actions.go b/internal/action/actions.go index 2c7157c48..ce6ee0667 100644 --- a/internal/action/actions.go +++ b/internal/action/actions.go @@ -1676,50 +1676,62 @@ func (h *BufPane) PageDown() bool { // SelectPageUp selects up one page func (h *BufPane) SelectPageUp() bool { + pageOverlap := int(h.Buf.Settings["pageoverlap"].(float64)) + scrollAmount := h.BufView().Height - pageOverlap if !h.Cursor.HasSelection() { h.Cursor.OrigSelection[0] = h.Cursor.Loc } - h.MoveCursorUp(h.BufView().Height) - h.Cursor.SelectTo(h.Cursor.Loc) + h.MoveCursorUp(scrollAmount) + if h.Cursor.Num == 0 { + h.Cursor.SelectTo(h.Cursor.Loc) + } + h.ScrollUp(scrollAmount) h.Relocate() return true } // SelectPageDown selects down one page func (h *BufPane) SelectPageDown() bool { + pageOverlap := int(h.Buf.Settings["pageoverlap"].(float64)) + scrollAmount := h.BufView().Height - pageOverlap if !h.Cursor.HasSelection() { h.Cursor.OrigSelection[0] = h.Cursor.Loc } - h.MoveCursorDown(h.BufView().Height) - h.Cursor.SelectTo(h.Cursor.Loc) + h.MoveCursorDown(scrollAmount) + if h.Cursor.Num == 0 { + h.Cursor.SelectTo(h.Cursor.Loc) + } + h.ScrollDown(scrollAmount) + h.ScrollAdjust() h.Relocate() return true } -// CursorPageUp places the cursor a page up +// CursorPageUp places the cursor a page up, +// moving the view to keep cursor at the same relative position in the view func (h *BufPane) CursorPageUp() bool { h.Cursor.Deselect(true) - - if h.Cursor.HasSelection() { - h.Cursor.Loc = h.Cursor.CurSelection[0] - h.Cursor.ResetSelection() - h.Cursor.StoreVisualX() + pageOverlap := int(h.Buf.Settings["pageoverlap"].(float64)) + scrollAmount := h.BufView().Height - pageOverlap + h.MoveCursorUp(scrollAmount) + if h.Cursor.Num == 0 { + h.ScrollUp(scrollAmount) } - h.MoveCursorUp(h.BufView().Height) h.Relocate() return true } -// CursorPageDown places the cursor a page up +// CursorPageDown places the cursor a page down, +// moving the view to keep cursor at the same relative position in the view func (h *BufPane) CursorPageDown() bool { h.Cursor.Deselect(false) - - if h.Cursor.HasSelection() { - h.Cursor.Loc = h.Cursor.CurSelection[1] - h.Cursor.ResetSelection() - h.Cursor.StoreVisualX() + pageOverlap := int(h.Buf.Settings["pageoverlap"].(float64)) + scrollAmount := h.BufView().Height - pageOverlap + h.MoveCursorDown(scrollAmount) + if h.Cursor.Num == 0 { + h.ScrollDown(scrollAmount) + h.ScrollAdjust() } - h.MoveCursorDown(h.BufView().Height) h.Relocate() return true } diff --git a/internal/config/settings.go b/internal/config/settings.go index 910a3072c..ca6d27deb 100644 --- a/internal/config/settings.go +++ b/internal/config/settings.go @@ -32,6 +32,7 @@ var optionValidators = map[string]optionValidator{ "helpsplit": validateChoice, "matchbracestyle": validateChoice, "multiopen": validateChoice, + "pageoverlap": validateNonNegativeValue, "reload": validateChoice, "scrollmargin": validateNonNegativeValue, "scrollspeed": validateNonNegativeValue, @@ -76,6 +77,7 @@ var defaultCommonSettings = map[string]interface{}{ "matchbraceleft": true, "matchbracestyle": "underline", "mkparents": false, + "pageoverlap": float64(2), "permbackup": false, "readonly": false, "reload": "prompt", diff --git a/runtime/help/options.md b/runtime/help/options.md index 0ea3b4ee1..c925d52e0 100644 --- a/runtime/help/options.md +++ b/runtime/help/options.md @@ -285,6 +285,13 @@ Here are the available options: default value: `tab` +* `pageoverlap`: the number of lines from the current view to keep in view + when paging up or down. If this is set to 2, for instance, and you page + down, the last two lines of the previous page will be the first two lines + of the next page. + + default value: `2` + * `paste`: treat characters sent from the terminal in a single chunk as a paste event rather than a series of manual key presses. If you are pasting using the terminal keybinding (not `Ctrl-v`, which is micro's default paste