Skip to content

Commit deebe23

Browse files
committed
Highlight the closes element to the users cursor
- If the users cursor is in view, the highlighted item will be next to the cursor - If the users cursor is out of view, we'll highlight the closed item to the visibe area
1 parent 66d8508 commit deebe23

File tree

1 file changed

+24
-29
lines changed

1 file changed

+24
-29
lines changed

Sources/CodeEditSourceEditor/Find/FindViewController.swift

Lines changed: 24 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ extension FindViewController: FindPanelDelegate {
177177
let range = emphasizeAPI.emphasizedRanges[activeIndex].range
178178
textViewController.textView.scrollToRange(range)
179179
textViewController.setCursorPositions([CursorPosition(range: range)])
180-
180+
181181
// Show bezel notification if we cycled from last to first match
182182
if previousIndex == emphasizeAPI.emphasizedRanges.count - 1 && activeIndex == 0 {
183183
BezelNotification.show(
@@ -324,10 +324,8 @@ extension FindViewController: FindPanelDelegate {
324324
let searchResults = matches.map { $0.range }
325325
findPanel.searchDelegate?.findPanelUpdateMatchCount(searchResults.count)
326326

327-
// If we have an active highlight and the same number of matches, try to preserve the active index
328-
let currentActiveIndex = target.emphasizeAPI?.emphasizedRangeIndex ?? 0
329-
let activeIndex = (target.emphasizeAPI?.emphasizedRanges.count == searchResults.count) ?
330-
currentActiveIndex : 0
327+
// Get the nearest match to either the cursor or visible area
328+
let activeIndex = getNearestHighlightIndex(matchRanges: searchResults) ?? 0
331329

332330
emphasizeAPI.emphasizeRanges(ranges: searchResults, activeIndex: activeIndex)
333331

@@ -338,49 +336,46 @@ extension FindViewController: FindPanelDelegate {
338336
}
339337
}
340338

341-
private func getNearestHighlightIndex(matchRanges: [NSRange]) -> Int? {
342-
// order the array as follows
343-
// Found: 1 -> 2 -> 3 -> 4
344-
// Cursor: |
345-
// Result: 3 -> 4 -> 1 -> 2
346-
guard let cursorPosition = target?.cursorPositions.first else { return nil }
347-
let start = cursorPosition.range.location
339+
private func getNearestHighlightIndex(matchRanges: borrowing [NSRange]) -> Int? {
340+
guard !matchRanges.isEmpty,
341+
let textViewController = target as? TextViewController,
342+
let textView = textViewController.textView,
343+
let visibleRange = textView.visibleTextRange else { return nil }
344+
345+
// Determine target position based on cursor visibility
346+
let targetPosition: Int
347+
if let cursorPosition = textViewController.cursorPositions.first?.range.location,
348+
visibleRange.contains(cursorPosition) {
349+
targetPosition = cursorPosition
350+
} else {
351+
targetPosition = visibleRange.location
352+
}
348353

349-
var left = 0
350-
var right = matchRanges.count - 1
351-
var bestIndex = -1
352-
var bestDiff = Int.max // Stores the closest difference
354+
// Binary search for the nearest match
355+
var left = 0, right = matchRanges.count - 1
356+
var bestIndex: Int? = nil
357+
var bestDiff = Int.max
353358

354359
while left <= right {
355360
let mid = left + (right - left) / 2
356361
let midStart = matchRanges[mid].location
357-
let diff = abs(midStart - start)
362+
let diff = abs(midStart - targetPosition)
358363

359-
// If it's an exact match, return immediately
360-
if diff == 0 {
361-
return mid
362-
}
363-
364-
// If this is the closest so far, update the best index
365364
if diff < bestDiff {
366365
bestDiff = diff
367366
bestIndex = mid
368367
}
369368

370-
// Move left or right based on the cursor position
371-
if midStart < start {
369+
if midStart < targetPosition {
372370
left = mid + 1
373371
} else {
374372
right = mid - 1
375373
}
376374
}
377375

378-
return bestIndex >= 0 ? bestIndex : nil
376+
return bestIndex
379377
}
380378

381-
// Only re-serach the part of the file that changed upwards
382-
private func reSearch() { }
383-
384379
// Returns true if string contains uppercase letter
385380
// used for: ignores letter case if the search query is all lowercase
386381
private func smartCase(str: String) -> Bool {

0 commit comments

Comments
 (0)