# Search Module ## Quick Start ### Basic Usage ```typescript import { SearchPanelComponent } from './components/search-panel/search-panel.component'; // In your component template ``` ### Standalone Search Bar ```typescript import { SearchBarComponent } from './components/search-bar/search-bar.component'; ``` ## Supported Operators | Operator | Description | Example | |----------|-------------|---------| | `file:` | Match file name | `file:.jpg` | | `path:` | Match file path | `path:"Daily notes"` | | `content:` | Match in content | `content:"hello"` | | `tag:` | Search tags | `tag:#work` | | `line:` | Same line | `line:(mix flour)` | | `block:` | Same block | `block:(dog cat)` | | `section:` | Same section | `section:(intro)` | | `task:` | In tasks | `task:call` | | `task-todo:` | Uncompleted tasks | `task-todo:review` | | `task-done:` | Completed tasks | `task-done:meeting` | | `match-case:` | Case-sensitive | `match-case:API` | | `ignore-case:` | Case-insensitive | `ignore-case:test` | | `[property]` | Property exists | `[description]` | | `[property:value]` | Property value | `[status]:"draft"` | ## Boolean Operators - **AND** (implicit): `term1 term2` - **OR**: `term1 OR term2` - **NOT**: `-term` - **Grouping**: `(term1 OR term2) term3` ## Special Syntax - **Exact phrase**: `"hello world"` - **Wildcard**: `test*` - **Regex**: `/\d{4}/` ## Services ### SearchIndexService Indexes vault content for fast searching. ```typescript constructor(private searchIndex: SearchIndexService) {} // Rebuild index this.searchIndex.rebuildIndex(notes); // Get suggestions const suggestions = this.searchIndex.getSuggestions('tag', '#'); ``` ### SearchEvaluatorService Executes search queries. ```typescript constructor(private evaluator: SearchEvaluatorService) {} // Search const results = this.evaluator.search('tag:#work', { caseSensitive: false }); ``` ### SearchAssistantService Provides autocomplete and suggestions. ```typescript constructor(private assistant: SearchAssistantService) {} // Get filtered options const options = this.assistant.getFilteredOptions('pa'); // Get contextual suggestions const suggestions = this.assistant.getSuggestions('path:proj'); ``` ### SearchHistoryService Manages search history. ```typescript constructor(private history: SearchHistoryService) {} // Add to history this.history.add('vault', 'my query'); // Get history const items = this.history.list('vault'); // Clear history this.history.clear('vault'); ``` ## Components ### SearchBarComponent Main search input with Aa and .* buttons. **Inputs:** - `placeholder: string` - Placeholder text - `context: string` - History context - `showSearchIcon: boolean` - Show search icon - `inputClass: string` - Custom CSS classes - `initialQuery: string` - Initial query value **Outputs:** - `search: { query: string; options: SearchOptions }` - Search event - `queryChange: string` - Query change event ### SearchResultsComponent Displays search results with grouping. **Inputs:** - `results: SearchResult[]` - Search results **Outputs:** - `noteOpen: { noteId: string; line?: number }` - Note open event ### SearchPanelComponent Complete search UI (bar + results). **Inputs:** - `placeholder: string` - Placeholder text - `context: string` - History context **Outputs:** - `noteOpen: { noteId: string; line?: number }` - Note open event ## Examples ### Complex Query ```typescript const query = ` path:projects/ tag:#active (Python OR JavaScript) -deprecated file:".md" match-case:"API" `; const results = this.evaluator.search(query, { caseSensitive: false, regexMode: false }); ``` ### Custom Search Context ```typescript import { SearchContext } from './search-parser.types'; const context: SearchContext = { filePath: 'notes/test.md', fileName: 'test', fileNameWithExt: 'test.md', content: 'Hello world', tags: ['#test'], properties: { status: 'draft' }, lines: ['Hello world'], blocks: ['Hello world'], sections: [{ heading: 'Title', content: 'Hello world', level: 1 }], tasks: [{ text: 'Do something', completed: false, line: 1 }] }; const predicate = queryToPredicate(parsed); const matches = predicate(context); ``` ## Performance Tips 1. **Debounce input**: Avoid searching on every keystroke 2. **Limit results**: Cap results at reasonable number (e.g., 100) 3. **Incremental indexing**: Update index incrementally instead of full rebuild 4. **Lazy loading**: Load results as user scrolls ## Testing ```typescript import { parseSearchQuery } from './search-parser'; describe('Search Parser', () => { it('should parse file operator', () => { const parsed = parseSearchQuery('file:test.md'); expect(parsed.isEmpty).toBe(false); // Assert AST structure }); }); ```