Merge remote-tracking branch 'origin/main' into vscode-lm-provider

This commit is contained in:
Matt Rubens
2025-01-15 09:18:55 -05:00
9 changed files with 135 additions and 186 deletions

View File

@@ -1,4 +1,5 @@
import { mentionRegex } from "../../../src/shared/context-mentions"
import { Fzf } from "fzf"
export function insertMention(
text: string,
@@ -147,13 +148,21 @@ export function getContextMenuOptions(
}
}
// Get matching items, separating by type
const matchingItems = queryItems.filter((item) =>
item.value?.toLowerCase().includes(lowerQuery) ||
item.label?.toLowerCase().includes(lowerQuery) ||
item.description?.toLowerCase().includes(lowerQuery)
)
// Create searchable strings array for fzf
const searchableItems = queryItems.map(item => ({
original: item,
searchStr: [item.value, item.label, item.description].filter(Boolean).join(' ')
}))
// Initialize fzf instance for fuzzy search
const fzf = new Fzf(searchableItems, {
selector: item => item.searchStr
})
// Get fuzzy matching items
const matchingItems = query ? fzf.find(query).map(result => result.item.original) : []
// Separate matches by type
const fileMatches = matchingItems.filter(item =>
item.type === ContextMenuOptionType.File ||
item.type === ContextMenuOptionType.Folder
@@ -169,7 +178,18 @@ export function getContextMenuOptions(
// Combine suggestions with matching items in the desired order
if (suggestions.length > 0 || matchingItems.length > 0) {
return [...suggestions, ...fileMatches, ...gitMatches, ...otherMatches]
const allItems = [...suggestions, ...fileMatches, ...gitMatches, ...otherMatches]
// Remove duplicates based on type and value
const seen = new Set()
const deduped = allItems.filter(item => {
const key = `${item.type}-${item.value}`
if (seen.has(key)) return false
seen.add(key)
return true
})
return deduped
}
return [{ type: ContextMenuOptionType.NoResults }]

View File

@@ -0,0 +1,44 @@
export function highlightFzfMatch(text: string, positions: number[], highlightClassName: string = "history-item-highlight") {
if (!positions.length) return text
const parts: { text: string; highlight: boolean }[] = []
let lastIndex = 0
// Sort positions to ensure we process them in order
positions.sort((a, b) => a - b)
positions.forEach((pos) => {
// Add non-highlighted text before this position
if (pos > lastIndex) {
parts.push({
text: text.substring(lastIndex, pos),
highlight: false
})
}
// Add highlighted character
parts.push({
text: text[pos],
highlight: true
})
lastIndex = pos + 1
})
// Add any remaining text
if (lastIndex < text.length) {
parts.push({
text: text.substring(lastIndex),
highlight: false
})
}
// Build final string
return parts
.map(part =>
part.highlight
? `<span class="${highlightClassName}">${part.text}</span>`
: part.text
)
.join('')
}