diff --git a/src-tauri/src/search.rs b/src-tauri/src/search.rs index 40bfdf01..dc7e9641 100644 --- a/src-tauri/src/search.rs +++ b/src-tauri/src/search.rs @@ -129,12 +129,13 @@ pub fn search_vault( }) } -fn is_markdown_search_candidate(path: &Path) -> bool { +fn is_markdown_search_candidate(vault_dir: &Path, path: &Path) -> bool { if !path.extension().is_some_and(|ext| ext == "md") { return false; } - !path + let vault_relative_path = path.strip_prefix(vault_dir).unwrap_or(path); + !vault_relative_path .components() .any(|component| component.as_os_str().to_string_lossy().starts_with('.')) } @@ -144,7 +145,7 @@ fn collect_markdown_paths(vault_dir: &Path, hide_gitignored_files: bool) -> Vec< .into_iter() .filter_map(|entry| entry.ok()) .map(|entry| entry.into_path()) - .filter(|path| is_markdown_search_candidate(path)) + .filter(|path| is_markdown_search_candidate(vault_dir, path)) .collect::>(); crate::vault::filter_gitignored_paths(vault_dir, paths, hide_gitignored_files) diff --git a/src/hooks/useNeighborhoodSelection.test.ts b/src/hooks/useNeighborhoodSelection.test.ts index c1c0b452..097a56b9 100644 --- a/src/hooks/useNeighborhoodSelection.test.ts +++ b/src/hooks/useNeighborhoodSelection.test.ts @@ -53,6 +53,24 @@ const inboxSelection: SidebarSelection = { kind: 'filter', filter: 'inbox' } const alphaSelection: SidebarSelection = { kind: 'entity', entry: buildEntry('/vault/alpha.md', 'Alpha') } const betaSelection: SidebarSelection = { kind: 'entity', entry: buildEntry('/vault/beta.md', 'Beta') } +function renderNeighborhoodEntry( + currentSelection: SidebarSelection, + history: SidebarSelection[], +) { + const selectionRef = ref(currentSelection) + const historyRef = ref(history) + const setSelection = vi.fn((selection: SidebarSelection) => { + selectionRef.current = selection + }) + const hook = renderHook(() => useNeighborhoodEntry({ + neighborhoodHistoryRef: historyRef, + selectionRef, + setSelection, + })) + + return { historyRef, hook, setSelection } +} + describe('useNeighborhoodEntry', () => { beforeEach(() => { vi.stubGlobal('requestAnimationFrame', (callback: FrameRequestCallback) => { @@ -67,36 +85,29 @@ describe('useNeighborhoodEntry', () => { document.body.innerHTML = '' }) - it('toggles the repeated active neighborhood action back to all notes', () => { - const selectionRef = ref(alphaSelection) - const historyRef = ref([inboxSelection]) - const setSelection = vi.fn((selection: SidebarSelection) => { - selectionRef.current = selection - }) - const { result } = renderHook(() => useNeighborhoodEntry({ - neighborhoodHistoryRef: historyRef, - selectionRef, - setSelection, - })) + it('toggles the repeated active neighborhood action back to the previous list', () => { + const { historyRef, hook, setSelection } = renderNeighborhoodEntry(alphaSelection, [inboxSelection]) - act(() => result.current(alphaSelection.entry)) + act(() => hook.result.current(alphaSelection.entry)) - expect(setSelection).toHaveBeenCalledWith({ kind: 'filter', filter: 'all' }) - expect(historyRef.current).toEqual([inboxSelection]) + expect(setSelection).toHaveBeenCalledWith(inboxSelection, { preserveNeighborhoodHistory: true }) + expect(historyRef.current).toEqual([]) expect(document.activeElement).toBe(document.querySelector('[data-testid="note-list-container"]')) }) - it('switches between neighborhoods without collapsing to all notes', () => { - const selectionRef = ref(alphaSelection) - const historyRef = ref([inboxSelection]) - const setSelection = vi.fn() - const { result } = renderHook(() => useNeighborhoodEntry({ - neighborhoodHistoryRef: historyRef, - selectionRef, - setSelection, - })) + it('uses the same stacked history as Escape when toggling the active neighborhood off', () => { + const { historyRef, hook, setSelection } = renderNeighborhoodEntry(betaSelection, [inboxSelection, alphaSelection]) - act(() => result.current(betaSelection.entry)) + act(() => hook.result.current(betaSelection.entry)) + + expect(setSelection).toHaveBeenCalledWith(alphaSelection, { preserveNeighborhoodHistory: true }) + expect(historyRef.current).toEqual([inboxSelection]) + }) + + it('switches between neighborhoods without collapsing to all notes', () => { + const { historyRef, hook, setSelection } = renderNeighborhoodEntry(alphaSelection, [inboxSelection]) + + act(() => hook.result.current(betaSelection.entry)) expect(setSelection).toHaveBeenCalledWith(betaSelection, { preserveNeighborhoodHistory: true }) expect(historyRef.current).toEqual([inboxSelection, alphaSelection]) diff --git a/src/hooks/useNeighborhoodSelection.ts b/src/hooks/useNeighborhoodSelection.ts index edfad260..27a2da45 100644 --- a/src/hooks/useNeighborhoodSelection.ts +++ b/src/hooks/useNeighborhoodSelection.ts @@ -63,7 +63,9 @@ export function useNeighborhoodEntry({ trackEvent('neighborhood_mode_toggled', { action: nextSelection.action }) if (nextSelection.action === 'exit') { - setSelection(nextSelection.selection) + const { previousSelection, nextHistory } = popNeighborhoodHistory(neighborhoodHistoryRef.current) + neighborhoodHistoryRef.current = nextHistory + setSelection(previousSelection ?? nextSelection.selection, previousSelection ? { preserveNeighborhoodHistory: true } : undefined) focusNoteListOnNextFrame() return }