1
1
mirror of https://github.com/walles/moar.git synced 2024-09-11 12:15:43 +03:00

Fix search issue while typing

Fixes #152
This commit is contained in:
Johan Walles 2023-09-14 20:05:04 +02:00
parent 083f64dc9d
commit 524fd38587
4 changed files with 48 additions and 22 deletions

View File

@ -327,24 +327,3 @@ func createLinePrefix(fileLineNumber *int, numberPrefixLength int) []twin.Cell {
return lineNumberPrefix
}
// Is the given position visible on screen?
func (p *Pager) isVisible(scrollPosition scrollPosition) bool {
if scrollPosition.lineNumberOneBased(p) < p.lineNumberOneBased() {
// It's above the screen, not visible
return false
}
lastVisiblePosition := p.getLastVisiblePosition()
if scrollPosition.lineNumberOneBased(p) > lastVisiblePosition.lineNumberOneBased(p) {
// Line number too high, not visible
return false
}
if scrollPosition.deltaScreenLines(p) > lastVisiblePosition.deltaScreenLines(p) {
// Sub-line-number too high, not visible
return false
}
return true
}

View File

@ -188,6 +188,33 @@ func (si *scrollPositionInternal) isCanonical(pager *Pager) bool {
return false
}
// Is the given position visible on screen?
func (sp scrollPosition) isVisible(pager *Pager) bool {
if sp.internalDontTouch.deltaScreenLines < 0 {
panic(fmt.Errorf("Negative incoming deltaScreenLines: %#v", sp.internalDontTouch))
}
if sp.internalDontTouch.lineNumberOneBased < pager.lineNumberOneBased() {
// Line number too low, not visible
return false
}
lastVisiblePosition := pager.getLastVisiblePosition()
if sp.internalDontTouch.lineNumberOneBased > lastVisiblePosition.lineNumberOneBased(pager) {
// Line number too high, not visible
return false
}
// Line number is within range, now check the sub-line number
if sp.internalDontTouch.deltaScreenLines > lastVisiblePosition.deltaScreenLines(pager) {
// Sub-line-number too high, not visible
return false
}
return true
}
// Only to be called from the scrollPosition getters!!
//
// Canonicalize the scroll position vs the given pager. A canonical position can

View File

@ -42,7 +42,7 @@ func (p *Pager) scrollToSearchHits() {
return
}
if p.isVisible(*firstHitPosition) {
if firstHitPosition.isVisible(p) {
// Already on-screen, never mind
return
}

View File

@ -89,3 +89,23 @@ func TestScrollToNextSearchHit_WrapAfterFound(t *testing.T) {
assert.Equal(t, _Viewing, pager.mode)
assert.Equal(t, 5, pager.lineNumberOneBased())
}
// Ref: https://github.com/walles/moar/issues/152
func Test152(t *testing.T) {
// Show a pager on a five lines terminal
reader := NewReaderFromText("", "a\nab\nabc\nabcd\nabcde\nabcdef\n")
screen := twin.NewFakeScreen(20, 5)
pager := NewPager(reader)
pager.screen = screen
assert.Equal(t, _Viewing, pager.mode, "Initial pager state")
// Search for the first not-visible hit
pager.searchString = "abcde"
pager.mode = _Searching
// Scroll to the next search hit
pager.updateSearchPattern()
assert.Equal(t, _Searching, pager.mode)
assert.Equal(t, 3, pager.lineNumberOneBased())
}