diff --git a/src/components/SearchBar.tsx b/src/components/SearchBar.tsx index 3c0f8c9..d266f7d 100644 --- a/src/components/SearchBar.tsx +++ b/src/components/SearchBar.tsx @@ -29,7 +29,7 @@ export function SearchBar({ onSearch, onFocus, value }: Props) { error: searchMode === 'regex' && !isValidRegexpSource(value), })} aria-label="search files" - placeholder={`Search files (${searchMode === 'regex' ? 'use RegExp' : 'match path'})`} + placeholder={`Search files`} onChange={({ target: { value } }) => onSearch(value, searchMode)} value={value} /> diff --git a/src/components/searchModes/fuzzyMode.tsx b/src/components/searchModes/fuzzyMode.tsx index efcb454..9aa7f8d 100644 --- a/src/components/searchModes/fuzzyMode.tsx +++ b/src/components/searchModes/fuzzyMode.tsx @@ -1,5 +1,6 @@ import * as React from 'react' import { cx } from 'utils/cx' +import { hasUpperCase } from 'utils/general' import { ModeShape } from '.' import { Highlight } from '../Highlight' @@ -7,8 +8,8 @@ export const fuzzyMode: ModeShape = { getSearchParams(searchKey) { if (!searchKey) return null - const searchKeyInLowerCase = searchKey.toLowerCase() - const matchNode = (node: TreeNode) => fuzzyMatch(searchKeyInLowerCase, node.path.toLowerCase()) + const matchNode = (node: TreeNode) => + fuzzyMatch(searchKey, hasUpperCase(searchKey) ? node.path : node.path.toLowerCase()) return { matchNode, } @@ -26,7 +27,7 @@ export const fuzzyMode: ModeShape = { return chunks.map((chunk, index, chunks) => { const chunkIndexes = indexes.filter(i => i >= progress && i < chunk.length + progress) const regexp = chunkIndexes.length - ? new RegExp(chunkIndexes.map(i => `(?<=^.{${i - progress}}).`).join('|'), 'i') + ? new RegExp(chunkIndexes.map(i => `(?<=^.{${i - progress}}).`).join('|')) : undefined progress += chunk.length + 1 return ( diff --git a/src/components/searchModes/regexMode.tsx b/src/components/searchModes/regexMode.tsx index 0e1b055..6de1b3b 100644 --- a/src/components/searchModes/regexMode.tsx +++ b/src/components/searchModes/regexMode.tsx @@ -1,6 +1,6 @@ import * as React from 'react' import { cx } from 'utils/cx' -import { isValidRegexpSource, searchKeyToRegexp } from 'utils/general' +import { hasUpperCase, isValidRegexpSource, searchKeyToRegexp } from 'utils/general' import { ModeShape } from '.' import { Highlight } from '../Highlight' @@ -21,7 +21,9 @@ export const regexMode: ModeShape = { }, renderNodeLabelText(node, searchKey) { const regex = - searchKey && isValidRegexpSource(searchKey) ? new RegExp(searchKey, 'gi') : undefined + searchKey && isValidRegexpSource(searchKey) + ? new RegExp(searchKey, 'g' + (hasUpperCase(searchKey) ? '' : 'i')) + : undefined const { name } = node return name.includes('/') ? ( name.split('/').map((chunk, index, chunks) => ( diff --git a/src/utils/general.ts b/src/utils/general.ts index 4a78db9..9bafe4e 100644 --- a/src/utils/general.ts +++ b/src/utils/general.ts @@ -147,7 +147,7 @@ export function searchKeyToRegexp(searchKey: string) { if (!searchKey) return null try { - const flags = /[A-Z]/.test(searchKey) ? '' : 'i' + const flags = hasUpperCase(searchKey) ? '' : 'i' // case-sensitive when searchKey contains uppercase char return new RegExp(searchKey, flags) } catch (err) { @@ -155,6 +155,10 @@ export function searchKeyToRegexp(searchKey: string) { } } +export function hasUpperCase(input: string) { + return /[A-Z]/.test(input) +} + export async function renderReact(element: ReactElement) { return new Promise(resolve => { const mount = document.createElement('div')