From 64ee70827a69fc82f27a0f78515ee8408cc1e328 Mon Sep 17 00:00:00 2001 From: hejl Date: Thu, 22 May 2025 11:18:37 +0800 Subject: [PATCH] =?UTF-8?q?=E6=90=9C=E7=B4=A2=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../content_search_controller.dart | 29 +++++++++++++++++-- .../services/content_search_service.dart | 17 ++++++++--- .../content_search/widgets/results_view.dart | 4 +-- .../widgets/search_settings.dart | 22 ++++++++++++++ 4 files changed, 63 insertions(+), 9 deletions(-) diff --git a/win_text_editor/lib/modules/content_search/controllers/content_search_controller.dart b/win_text_editor/lib/modules/content_search/controllers/content_search_controller.dart index 8a3d019..96c66c2 100644 --- a/win_text_editor/lib/modules/content_search/controllers/content_search_controller.dart +++ b/win_text_editor/lib/modules/content_search/controllers/content_search_controller.dart @@ -20,6 +20,8 @@ class ContentSearchController extends BaseContentController { bool _customRule = false; SearchMode _searchMode = SearchMode.locate; final List _results = []; + List _allResults = []; + bool _includeZeroCounts = false; // Getters String get searchQuery => _searchQuery; @@ -31,6 +33,7 @@ class ContentSearchController extends BaseContentController { bool get customRule => _customRule; SearchMode get searchMode => _searchMode; List get results => _results; + bool get includeZeroCounts => _includeZeroCounts; set customRule(bool value) { _customRule = value; @@ -86,11 +89,30 @@ class ContentSearchController extends BaseContentController { void clearResults() { results.clear(); + _allResults.clear(); notifyListeners(); } + set includeZeroCounts(bool value) { + _includeZeroCounts = value; + _filterResults(); + notifyListeners(); + } + + void _filterResults() { + _results.clear(); + if (_searchMode == SearchMode.count) { + _results.addAll( + _includeZeroCounts ? _allResults : _allResults.where((r) => r.lineNumber > 0), + ); + } else { + _results.addAll(_allResults); + } + } + Future startSearch() async { _results.clear(); + _allResults.clear(); // 校验搜索内容 if (searchQuery.isEmpty) { @@ -112,7 +134,7 @@ class ContentSearchController extends BaseContentController { return; } - _results.addAll( + _allResults.addAll( await ContentSearchService.performCustomSearch( directory: searchDirectory, fileType: fileType, @@ -123,7 +145,7 @@ class ContentSearchController extends BaseContentController { } else { try { if (searchMode == SearchMode.locate) { - _results.addAll( + _allResults.addAll( await ContentSearchService.performLocateSearch( directory: searchDirectory, query: searchQuery, @@ -144,7 +166,7 @@ class ContentSearchController extends BaseContentController { ); counts.forEach((keyword, count) { - _results.add( + _allResults.add( SearchResult( filePath: keyword, lineNumber: count, @@ -158,6 +180,7 @@ class ContentSearchController extends BaseContentController { } catch (e) { Logger().error("搜索出错: $e"); } finally { + _filterResults(); notifyListeners(); } } diff --git a/win_text_editor/lib/modules/content_search/services/content_search_service.dart b/win_text_editor/lib/modules/content_search/services/content_search_service.dart index 511d712..8950ee5 100644 --- a/win_text_editor/lib/modules/content_search/services/content_search_service.dart +++ b/win_text_editor/lib/modules/content_search/services/content_search_service.dart @@ -22,7 +22,7 @@ class ContentSearchService { final results = []; final dir = Directory(directory); final queries = _splitQuery(query); // 分割查询字符串 - + int speed = 0; for (final q in queries) { final pattern = _buildSearchPattern( query: q, @@ -30,12 +30,15 @@ class ContentSearchService { wholeWord: wholeWord, useRegex: useRegex, ); - + Logger().info("搜索词 $q 开始[${++speed}/${queries.length}]"); + int fileCount = 0; await for (final entity in dir.list(recursive: true)) { if (entity is File && _matchesFileType(entity.path, fileType)) { + fileCount++; await _searchInFile(entity, pattern, results, q); // 传递当前查询项 } } + Logger().info("搜索词 $q 结束[$speed/${queries.length}],搜索文件 $fileCount 个,"); } return results; @@ -53,7 +56,7 @@ class ContentSearchService { final counts = {}; final dir = Directory(directory); final queries = _splitQuery(query); // 分割查询字符串 - + int speed = 0; for (final q in queries) { final pattern = _buildSearchPattern( query: q, @@ -62,11 +65,17 @@ class ContentSearchService { useRegex: useRegex, ); + Logger().info("搜索词 $q 开始[${++speed}/${queries.length}]"); + counts[q] = 0; + int fileCount = 0; await for (final entity in dir.list(recursive: true)) { if (entity is File && _matchesFileType(entity.path, fileType)) { + fileCount++; await _countInFile(entity, pattern, counts, q); // 传递当前查询项 } } + + Logger().info("搜索词 $q 结束[$speed/${queries.length}],搜索文件 $fileCount 个,"); } return counts; @@ -266,7 +275,7 @@ class ContentSearchService { } } } catch (e) { - print('Error reading file ${file.path}: $e'); + Logger().error('Error reading file ${file.path}: $e'); } } diff --git a/win_text_editor/lib/modules/content_search/widgets/results_view.dart b/win_text_editor/lib/modules/content_search/widgets/results_view.dart index b9246e1..252ce09 100644 --- a/win_text_editor/lib/modules/content_search/widgets/results_view.dart +++ b/win_text_editor/lib/modules/content_search/widgets/results_view.dart @@ -110,7 +110,7 @@ class ResultsView extends StatelessWidget { columns: [ GridColumn( columnName: 'file', - width: 300, + minimumWidth: 300, label: Container( alignment: Alignment.center, color: Colors.grey[200], @@ -145,7 +145,7 @@ class ResultsView extends StatelessWidget { columns: [ GridColumn( columnName: 'keyword', - width: 300, + minimumWidth: 300, label: Container( alignment: Alignment.center, color: Colors.grey[200], diff --git a/win_text_editor/lib/modules/content_search/widgets/search_settings.dart b/win_text_editor/lib/modules/content_search/widgets/search_settings.dart index fc9c6a2..a619aa2 100644 --- a/win_text_editor/lib/modules/content_search/widgets/search_settings.dart +++ b/win_text_editor/lib/modules/content_search/widgets/search_settings.dart @@ -84,6 +84,28 @@ class SearchSettings extends StatelessWidget { ), ], ), + const SizedBox(height: 4), + Visibility( + visible: controller.searchMode == SearchMode.count, + child: Column( + children: [ + CheckboxListTile( + dense: true, + contentPadding: EdgeInsets.zero, + controlAffinity: ListTileControlAffinity.leading, + title: const Text('包含匹配数量0', style: TextStyle(fontSize: 12)), + value: controller.includeZeroCounts, + onChanged: + controller.searchMode == SearchMode.count + ? (value) { + controller.includeZeroCounts = value!; + } + : null, + ), + const SizedBox(height: 4), + ], + ), + ), const SizedBox(height: 8), // 匹配规则 const Text('匹配规则:', style: TextStyle(fontSize: 12)),