fix: not opening deepest matched fuzzy search dir

This commit is contained in:
EnixCoda 2022-04-24 21:46:23 +08:00
parent 13b4d6d2bd
commit 66da1dd903
2 changed files with 83 additions and 4 deletions

View file

@ -0,0 +1,70 @@
import { fuzzyMode } from './fuzzyMode'
type TreeNodeSource = {
[key: string]: true | TreeNodeSource
}
function createTreeNode(source: TreeNodeSource, name: string = '', paths: string[] = []): TreeNode {
const subPaths = paths.concat(name)
return {
name,
path: subPaths.join('/'),
type: 'tree',
contents: Object.entries(source).map(([key, value]) => {
return value === true
? {
name: key,
path: subPaths.concat(key).join('/'),
type: 'blob',
}
: createTreeNode(value, key, subPaths)
}),
}
}
const node = createTreeNode({
a: {
b: {
['c.json']: true,
},
},
})
it(`finds the items that matches all search key chars`, () => {
// a/b/c.json
// "b" =>
// ✅a/b
// ❌a
expect(fuzzyMode.getSearchParams('b')?.matchNode(node.contents?.[0].contents?.[0]!)).toBe(true)
expect(fuzzyMode.getSearchParams('b')?.matchNode(node.contents?.[0]!)).toBe(false)
})
it(`excludes files under the dir that matches last search key char`, () => {
// a/b/c.json
// "b" =>
// ❌a/b/c.json
expect(
fuzzyMode.getSearchParams('b')?.matchNode(node.contents?.[0].contents?.[0].contents?.[0]!),
).toBe(false)
expect(
fuzzyMode.getSearchParams('tooltip')?.matchNode({
name: '',
type: 'tree',
path: '/components/tooltip',
}),
).toBe(true)
expect(
fuzzyMode.getSearchParams('tooltip')?.matchNode({
name: '',
type: 'blob',
path: '/components/tooltip/x',
}),
).toBe(false)
expect(
fuzzyMode.getSearchParams('tooltip/')?.matchNode({
name: '',
type: 'blob',
path: '/components/tooltip/x',
}),
).toBe(true)
})

View file

@ -8,8 +8,11 @@ export const fuzzyMode: ModeShape = {
getSearchParams(searchKey) {
if (!searchKey) return null
const matchNode = (node: TreeNode) =>
fuzzyMatch(searchKey, hasUpperCase(searchKey) ? node.path : node.path.toLowerCase())
const matchNode = (node: TreeNode) => {
const path = hasUpperCase(searchKey) ? node.path : node.path.toLowerCase()
const { match, lastIndex } = fuzzyMatch(searchKey, path)
return match && (searchKey[searchKey.length - 1] === '/' || lastIndex > path.lastIndexOf('/'))
}
return {
matchNode,
}
@ -32,7 +35,10 @@ export const fuzzyMode: ModeShape = {
progress += chunk.length + 1 // not neat side effect in map function
return (
<span key={index} className={cx({ prefix: index + 1 !== chunks.length })}>
<HighlightOnIndexes indexes={highlightIndexes} text={index + 1 === chunks.length ? chunk : chunk + '/'} />
<HighlightOnIndexes
indexes={highlightIndexes}
text={index + 1 === chunks.length ? chunk : chunk + '/'}
/>
</span>
)
})
@ -45,7 +51,10 @@ function fuzzyMatch(input: string, sample: string) {
while (i < input.length && j < sample.length) {
if (input[i] === sample[j++]) i++
}
return i === input.length
return {
lastIndex: j - 1,
match: i === input.length,
}
}
function fuzzyMatchIndexes(input: string, sample: string, shift: number = 0) {