From 2a69426273f81f87c9c728aa67dfea6e82b178b7 Mon Sep 17 00:00:00 2001 From: Gamosoft Date: Fri, 5 Dec 2025 12:00:53 +0100 Subject: [PATCH] reduce context search results; highlight matched text in context --- backend/utils.py | 20 ++++++++++++-------- frontend/app.js | 22 +++------------------- frontend/index.html | 15 ++++++++++++++- 3 files changed, 29 insertions(+), 28 deletions(-) diff --git a/backend/utils.py b/backend/utils.py index ba3a118..4e8e2b4 100644 --- a/backend/utils.py +++ b/backend/utils.py @@ -273,8 +273,9 @@ def search_notes(notes_dir: str, query: str) -> List[Dict]: """ Full-text search through note contents only. Does NOT search in file names, folder names, or paths - only note content. - Uses character-based context extraction for better snippet quality. + Uses character-based context extraction with highlighted matches. """ + from html import escape results = [] notes_path = Path(notes_dir) @@ -292,16 +293,19 @@ def search_notes(notes_dir: str, query: str) -> List[Dict]: for match in matches[:3]: # Limit to 3 matches per file start_index = match.start() end_index = match.end() + matched_text = match.group() # Preserve original case - # Create slice window: ±30 characters around match - context_start = max(0, start_index - 30) - context_end = min(len(content), end_index + 30) + # Create slice window: ±15 characters around match + context_start = max(0, start_index - 15) + context_end = min(len(content), end_index + 15) - # Extract snippet - snippet = content[context_start:context_end] + # Extract and clean parts (newlines → spaces) + before = escape(content[context_start:start_index].replace('\n', ' ')) + after = escape(content[end_index:context_end].replace('\n', ' ')) + matched_clean = escape(matched_text.replace('\n', ' ')) - # Replace all newlines with spaces to ensure UI doesn't break - snippet = snippet.replace('\n', ' ') + # Build snippet with highlight (styled via CSS) + snippet = f'{before}{matched_clean}{after}' # Add ellipsis if truncated at start if context_start > 0: diff --git a/frontend/app.js b/frontend/app.js index 4212642..c8960ab 100644 --- a/frontend/app.js +++ b/frontend/app.js @@ -1895,18 +1895,10 @@ function noteApp() { mark.className = 'search-highlight'; mark.setAttribute('data-match-index', matchIndex); mark.textContent = text.substring(index, index + searchTerm.length); - mark.style.padding = '2px 4px'; - mark.style.borderRadius = '3px'; - mark.style.transition = 'all 0.2s'; - // Style first match as active, others as inactive + // First match is active (styled via CSS) if (matchIndex === 0) { - mark.style.backgroundColor = 'var(--accent-primary)'; - mark.style.color = 'white'; mark.classList.add('active-match'); - } else { - mark.style.backgroundColor = 'rgba(255, 193, 7, 0.4)'; - mark.style.color = 'var(--text-primary)'; } fragment.appendChild(mark); @@ -1961,17 +1953,9 @@ function noteApp() { const allMatches = preview.querySelectorAll('mark.search-highlight'); if (index < 0 || index >= allMatches.length) return; - // Update styling - make current match prominent + // Update styling - make current match prominent (via CSS class) allMatches.forEach((mark, i) => { - if (i === index) { - mark.style.backgroundColor = 'var(--accent-primary)'; - mark.style.color = 'white'; - mark.classList.add('active-match'); - } else { - mark.style.backgroundColor = 'rgba(255, 193, 7, 0.4)'; - mark.style.color = 'var(--text-primary)'; - mark.classList.remove('active-match'); - } + mark.classList.toggle('active-match', i === index); }); // Scroll to the match diff --git a/frontend/index.html b/frontend/index.html index 08af448..d536ad4 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -289,6 +289,19 @@ .markdown-preview a[data-wikilink].wikilink-broken:hover { opacity: 1; } + + /* Search highlight base style (used in note preview and search results) */ + .search-highlight { + padding: 2px 4px; + border-radius: 3px; + background-color: rgba(255, 193, 7, 0.4); + color: var(--text-primary); + transition: all 0.2s; + } + .search-highlight.active-match { + background-color: var(--accent-primary); + color: white; + } /* Note Properties Panel */ .note-properties { @@ -956,7 +969,7 @@ :title="note.path" >
-
+