From e2c3ae5472348e3166893874633c2a03dcd59b14 Mon Sep 17 00:00:00 2001 From: randogoth Date: Fri, 19 Jun 2026 17:32:48 +0300 Subject: [PATCH] fix subdirectory search and tag highlighting edge cases MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - filter notes by relative path instead of bare filename so searching "/subdir" or "subdir" matches notes inside that subdirectory - strip leading "/" from search text before matching so both forms work - tighten tag regex in _extractTags and _formatTags: require a letter after the symbol and a non-word boundary before it ((? --- lib/note_list.dart | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/lib/note_list.dart b/lib/note_list.dart index 315af1f..d1122ab 100755 --- a/lib/note_list.dart +++ b/lib/note_list.dart @@ -294,7 +294,7 @@ Happy note taking! ✨ /// Extracts unique tags sorted by +, @, # Set _extractTags(String content) { - final tagPattern = RegExp(r'([#@+][a-zA-Z][a-zA-Z0-9_]*)'); + final tagPattern = RegExp(r'(? m.group(0)!).toSet(); // Sort the tags in order: +tags first, @contexts second, #hashtags last @@ -325,8 +325,11 @@ Happy note taking! ✨ final searchTags = terms.where((t) => t.startsWith(RegExp(r'[#@+]'))).toSet(); final searchText = terms.where((t) => !t.startsWith(RegExp(r'[#@+]'))).join(' '); + // Strip leading '/' so "/subdir" and "subdir" match the same notes + final normalizedSearch = searchText.replaceFirst(RegExp(r'^/'), ''); + filteredNotes = notes.where((note) { - final filename = note.uri.pathSegments.last.toLowerCase(); + final relativePath = path.relative(note.path, from: notesDirectoryPath!).toLowerCase(); final noteTags = _extractTags(note.readAsStringSync()); // ✅ Read file content ONLY if `Include File Content` is enabled @@ -337,9 +340,9 @@ Happy note taking! ✨ noteTags.any((noteTag) => noteTag.startsWith(tag))); if (!_includeFileContent) { - return filename.contains(searchText) && matchesTags; + return relativePath.contains(normalizedSearch) && matchesTags; } else { - return (filename.contains(searchText) || content.contains(searchText)) && matchesTags; + return (relativePath.contains(normalizedSearch) || content.contains(normalizedSearch)) && matchesTags; } }).toList(); }); @@ -360,7 +363,7 @@ Happy note taking! ✨ } List _formatTags(String content) { - final tagPattern = RegExp(r'([#@+][a-zA-Z0-9_]+)'); + final tagPattern = RegExp(r'(? tagSet = {}; // Avoid duplicate tags for (final match in tagPattern.allMatches(content)) { @@ -405,7 +408,7 @@ Happy note taking! ✨ } } - if (notePath.startsWith('/')) { + if (notePath.contains('/')) { final parts = notePath.split('/'); parts.removeWhere((element) => element.isEmpty); if (parts.length > 1) {