Skip to content

Commit

Permalink
Fix 'incsearch'+'wrapscan' at bottom of file
Browse files Browse the repository at this point in the history
If all results are before the caret, make sure it's still possible to highlight the closest match if 'wrapscan' is enabled

Fixes VIM-3505
  • Loading branch information
citizenmatt authored and AlexPl292 committed Jun 28, 2024
1 parent 4255ef6 commit 750db8e
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -210,12 +210,28 @@ private fun findClosestMatch(
return -1
}

val sortedResults = results.sortedBy { it.startOffset }.let { if (!forwards) it.reversed() else it }
val nextIndex = sortedResults.indexOfFirst {
if (forwards) it.startOffset > initialOffset else it.startOffset < initialOffset
val sortedResults = if (forwards) {
results.sortedBy { it.startOffset }
} else {
results.sortedByDescending { it.startOffset }
}
val toDrop = (nextIndex + count - 1).let { if (injector.globalOptions().wrapscan) it % results.size else it }
return sortedResults.drop(toDrop).firstOrNull()?.startOffset ?: -1
val closestIndex = if (forwards) {
sortedResults.indexOfFirst { it.startOffset > initialOffset }
}
else {
sortedResults.indexOfFirst { it.startOffset < initialOffset }
}

if (closestIndex == -1 && !injector.globalOptions().wrapscan) {
return -1
}

val nextIndex = closestIndex.coerceAtLeast(0) + (count - 1)
if (nextIndex >= sortedResults.size && !injector.globalOptions().wrapscan) {
return -1
}

return sortedResults[nextIndex % results.size].startOffset
}

internal fun highlightSearchResults(editor: Editor, pattern: String, results: List<TextRange>, currentMatchOffset: Int) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1063,6 +1063,38 @@ class SearchGroupTest : VimTestCase() {
assertPosition(1, 14)
}

@Test
fun `test incsearch + hlsearch at bottom of file with wrapscan`() {
// Make sure the caret wraps during incsearch
configureByText(
"""
|Lorem ipsum dolor sit amet,
|consectetur adipiscing elit
|Sed in orci ${c}mauris.
|Cras id tellus in ex imperdiet egestas.
""".trimMargin()
)
enterCommand("set incsearch hlsearch wrapscan")
typeText("/it")
assertPosition(0, 19)
}

@Test
fun `test incsearch + hlsearch at bottom of file with nowrapscan`() {
// This will highlight the occurrences above/before the caret, but should not move the caret
configureByText(
"""
|Lorem ipsum dolor sit amet,
|consectetur adipiscing elit
|Sed in orci ${c}mauris.
|Cras id tellus in ex imperdiet egestas.
""".trimMargin()
)
enterCommand("set incsearch hlsearch nowrapscan")
typeText("/it")
assertPosition(2, 12)
}

@TestWithoutNeovim(SkipNeovimReason.OPTION)
@Test
fun `test incsearch moves caret to start of first match (backwards)`() {
Expand Down

0 comments on commit 750db8e

Please sign in to comment.