#25 - quoted expressions for Vault search ok
This commit is contained in:
@@ -40,14 +40,14 @@ onDestroy(() => {
|
||||
eventBus.enable("vault")
|
||||
})
|
||||
|
||||
$: {
|
||||
$: (async () => {
|
||||
if (searchQuery) {
|
||||
note = getSuggestions(searchQuery, { singleFilePath })[0] ?? null
|
||||
note = (await getSuggestions(searchQuery, { singleFilePath }))[0] ?? null
|
||||
lastSearch = searchQuery
|
||||
}
|
||||
selectedIndex = 0
|
||||
scrollIntoView()
|
||||
}
|
||||
})()
|
||||
|
||||
$: {
|
||||
if (note) {
|
||||
|
||||
@@ -20,14 +20,14 @@ let searchQuery: string
|
||||
let resultNotes: ResultNote[] = []
|
||||
$: selectedNote = resultNotes[selectedIndex]
|
||||
|
||||
$: {
|
||||
$: (async() => {
|
||||
if (searchQuery) {
|
||||
resultNotes = getSuggestions(searchQuery)
|
||||
resultNotes = await getSuggestions(searchQuery)
|
||||
lastSearch = searchQuery
|
||||
}
|
||||
selectedIndex = 0
|
||||
scrollIntoView()
|
||||
}
|
||||
})()
|
||||
|
||||
onMount(() => {
|
||||
searchQuery = lastSearch
|
||||
|
||||
@@ -6,7 +6,13 @@ import {
|
||||
type ResultNote,
|
||||
type SearchMatch,
|
||||
} from './globals'
|
||||
import { extractHeadingsFromCache, stringsToRegex, wait } from './utils'
|
||||
import {
|
||||
extractHeadingsFromCache,
|
||||
splitQuotes,
|
||||
stringsToRegex,
|
||||
stripMarkdownCharacters,
|
||||
wait,
|
||||
} from './utils'
|
||||
|
||||
let minisearchInstance: MiniSearch<IndexedNote>
|
||||
|
||||
@@ -57,9 +63,9 @@ export async function initGlobalSearchIndex(): Promise<void> {
|
||||
* @param query
|
||||
* @returns
|
||||
*/
|
||||
function search(query: string): SearchResult[] {
|
||||
async function search(query: string): Promise<SearchResult[]> {
|
||||
if (!query) return []
|
||||
return minisearchInstance.search(query, {
|
||||
let results = minisearchInstance.search(query, {
|
||||
prefix: true,
|
||||
fuzzy: term => (term.length > 4 ? 0.2 : false),
|
||||
combineWith: 'AND',
|
||||
@@ -70,6 +76,17 @@ function search(query: string): SearchResult[] {
|
||||
headings3: 1.1,
|
||||
},
|
||||
})
|
||||
const quoted = splitQuotes(query.toLowerCase())
|
||||
|
||||
if (quoted.length) {
|
||||
results = results.filter(r => {
|
||||
const content = stripMarkdownCharacters(
|
||||
indexedNotes[r.id]?.content ?? '',
|
||||
).toLowerCase()
|
||||
return quoted.every(q => content.includes(q))
|
||||
})
|
||||
}
|
||||
return results
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -96,12 +113,12 @@ export function getMatches(text: string, reg: RegExp): SearchMatch[] {
|
||||
* @param options
|
||||
* @returns
|
||||
*/
|
||||
export function getSuggestions(
|
||||
export async function getSuggestions(
|
||||
query: string,
|
||||
options?: Partial<{ singleFilePath: string | null }>,
|
||||
): ResultNote[] {
|
||||
): Promise<ResultNote[]> {
|
||||
// Get the raw results
|
||||
let results = search(query)
|
||||
let results = await search(query)
|
||||
if (!results.length) return []
|
||||
|
||||
// Either keep the 50 first results,
|
||||
|
||||
39
src/utils.ts
39
src/utils.ts
@@ -97,3 +97,42 @@ export function makeExcerpt(content: string, offset: number): string {
|
||||
}
|
||||
return escapeHTML(content)
|
||||
}
|
||||
|
||||
/**
|
||||
* splits a string in words or "expressions in quotes"
|
||||
* @param str
|
||||
* @returns
|
||||
*/
|
||||
export function splitQuotes(str: string): string[] {
|
||||
return str.match(/"(.*?)"/g)?.map(s => s.replace(/"/g, '')) ?? []
|
||||
}
|
||||
|
||||
function mapAsync<T, U>(
|
||||
array: T[],
|
||||
callbackfn: (value: T, index: number, array: T[]) => Promise<U>,
|
||||
): Promise<U[]> {
|
||||
return Promise.all(array.map(callbackfn))
|
||||
}
|
||||
|
||||
/**
|
||||
* https://stackoverflow.com/a/53508547
|
||||
* @param arr
|
||||
* @param callback
|
||||
* @returns
|
||||
*/
|
||||
export async function filterAsync<T>(
|
||||
array: T[],
|
||||
callbackfn: (value: T, index: number, array: T[]) => Promise<boolean>,
|
||||
): Promise<T[]> {
|
||||
const filterMap = await mapAsync(array, callbackfn)
|
||||
return array.filter((value, index) => filterMap[index])
|
||||
}
|
||||
|
||||
/**
|
||||
* A simple function to strip bold and italic markdown chars from a string
|
||||
* @param text
|
||||
* @returns
|
||||
*/
|
||||
export function stripMarkdownCharacters(text: string): string {
|
||||
return text.replace(/(\*|\_)+(.+?)(\*|\_)+/g, (match, p1, p2) => p2)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user