diff --git a/src/renderer/src/components/editor/useRichMarkdownSearch.reuse.test.tsx b/src/renderer/src/components/editor/useRichMarkdownSearch.reuse.test.tsx index 3aa0cea32dd..563be2c0e28 100644 --- a/src/renderer/src/components/editor/useRichMarkdownSearch.reuse.test.tsx +++ b/src/renderer/src/components/editor/useRichMarkdownSearch.reuse.test.tsx @@ -86,9 +86,10 @@ describe('live rich markdown search reuse', () => { const { hook } = mountSearch() act(() => hook.result.current.openSearch()) act(() => hook.result.current.searchActions.setSearchQuery('beta')) - expect(walk).toHaveBeenCalledTimes(1) + expect(walk).not.toHaveBeenCalled() act(() => vi.advanceTimersByTime(150)) expect(hook.result.current.searchState.matchCount).toBe(2) + expect(walk).toHaveBeenCalledTimes(1) for (let index = 0; index < 20; index++) { act(() => hook.result.current.searchActions.setReplaceQuery(`replacement ${index}`)) act(() => hook.result.current.searchActions.moveToMatch(1)) @@ -97,6 +98,8 @@ describe('live rich markdown search reuse', () => { act(() => hook.result.current.searchActions.closeSearch()) act(() => hook.result.current.openSearch()) act(() => hook.result.current.searchActions.setSearchQuery('beta')) + expect(walk).toHaveBeenCalledTimes(1) + act(() => vi.advanceTimersByTime(150)) expect(walk).toHaveBeenCalledTimes(2) hook.unmount() }) @@ -109,6 +112,7 @@ describe('live rich markdown search reuse', () => { act(() => vi.advanceTimersByTime(150)) act(() => hook.result.current.searchActions.setSearchQuery('locked')) expect(hook.result.current.searchState.matchCount).toBe(2) + act(() => hook.result.current.searchActions.toggleReplaceMode()) expect(hook.result.current.searchState.replaceDisabled).toBe(true) const doc = editor.state.doc act(() => hook.result.current.searchActions.replaceAllMatches()) diff --git a/src/renderer/src/components/editor/useRichMarkdownSearch.ts b/src/renderer/src/components/editor/useRichMarkdownSearch.ts index 6d9510e8aae..d0adaa2ae09 100644 --- a/src/renderer/src/components/editor/useRichMarkdownSearch.ts +++ b/src/renderer/src/components/editor/useRichMarkdownSearch.ts @@ -89,8 +89,9 @@ export function useRichMarkdownSearch({ }) }, [editor, findMatches, isSearchOpen, matchCase, searchQuery, wholeWord]) - // Derive disabled state from the same live atom guards as replacement, including during the highlight debounce. - const replaceDisabled = getLiveMatches().some((match) => match.touchesReadOnlyAtom) + // Hidden replace controls must not bypass the find debounce with a live scan. + const replaceDisabled = + isReplaceMode && getLiveMatches().some((match) => match.touchesReadOnlyAtom) const activeMatchIndex = !isSearchOpen || matchCount === 0