mirror of
https://github.com/Flow-Launcher/Flow.Launcher.git
synced 2026-03-11 08:54:32 +00:00
Add TopLevelDirecotry search using DirectoryInfo
This commit is contained in:
parent
d839ecab26
commit
6badecb877
5 changed files with 191 additions and 22 deletions
|
|
@ -2,6 +2,7 @@ using Flow.Launcher.Plugin;
|
|||
using Flow.Launcher.Plugin.Explorer;
|
||||
using Flow.Launcher.Plugin.Explorer.Search;
|
||||
using Flow.Launcher.Plugin.Explorer.Search.WindowsIndex;
|
||||
using Flow.Launcher.Plugin.SharedCommands;
|
||||
using NUnit.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
|
@ -16,7 +17,7 @@ namespace Flow.Launcher.Test.Plugins
|
|||
return new List<Result>();
|
||||
}
|
||||
|
||||
private List<Result> MethodDirectoryInfoClassSearchReturnsTwoResults(string dummyString)
|
||||
private List<Result> MethodDirectoryInfoClassSearchReturnsTwoResults(Query dummyQuery, string dummyString)
|
||||
{
|
||||
return new List<Result>
|
||||
{
|
||||
|
|
@ -111,7 +112,8 @@ namespace Flow.Launcher.Test.Plugins
|
|||
MethodWindowsIndexSearchReturnsZeroResults,
|
||||
MethodDirectoryInfoClassSearchReturnsTwoResults,
|
||||
MethodIndexExistsReturnsFalse,
|
||||
"path string not used");
|
||||
new Query(),
|
||||
"string not used");
|
||||
|
||||
// Then
|
||||
Assert.IsTrue(results.Count == 2,
|
||||
|
|
@ -130,7 +132,8 @@ namespace Flow.Launcher.Test.Plugins
|
|||
MethodWindowsIndexSearchReturnsZeroResults,
|
||||
MethodDirectoryInfoClassSearchReturnsTwoResults,
|
||||
MethodIndexExistsReturnsTrue,
|
||||
"path string not used");
|
||||
new Query(),
|
||||
"string not used");
|
||||
|
||||
// Then
|
||||
Assert.IsTrue(results.Count == 0,
|
||||
|
|
@ -149,9 +152,7 @@ namespace Flow.Launcher.Test.Plugins
|
|||
public void WhenGivenQuerySearchString_ThenShouldIndicateIfItIsLocationString(string querySearchString, bool expectedResult)
|
||||
{
|
||||
// When, Given
|
||||
var searchManager = new SearchManager(new Settings(), new PluginInitContext());
|
||||
|
||||
var result = searchManager.IsLocationPathString(querySearchString);
|
||||
var result = FilesFolders.IsLocationPathString(querySearchString);
|
||||
|
||||
//Then
|
||||
Assert.IsTrue(result == expectedResult,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
using Flow.Launcher.Infrastructure.Storage;
|
||||
using Flow.Launcher.Infrastructure.Storage;
|
||||
using Flow.Launcher.Plugin.Explorer.Search;
|
||||
using Flow.Launcher.Plugin.Explorer.ViewModels;
|
||||
using Flow.Launcher.Plugin.Explorer.Views;
|
||||
|
|
@ -42,8 +42,6 @@ namespace Flow.Launcher.Plugin.Explorer
|
|||
return results;
|
||||
|
||||
return new SearchManager(_settings, Context).Search(query);
|
||||
|
||||
return new SearchManager(_settings, Context).Search(query.Search);
|
||||
}
|
||||
|
||||
public void Save()
|
||||
|
|
|
|||
|
|
@ -0,0 +1,114 @@
|
|||
using Flow.Launcher.Infrastructure;
|
||||
using Flow.Launcher.Plugin.SharedCommands;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Windows;
|
||||
|
||||
namespace Flow.Launcher.Plugin.Explorer.Search.DirectoryInfo
|
||||
{
|
||||
public class DirectoryInfoSearch
|
||||
{
|
||||
private PluginInitContext _context;
|
||||
|
||||
private Settings _settings;
|
||||
|
||||
public DirectoryInfoSearch(Settings settings, PluginInitContext context)
|
||||
{
|
||||
_context = context;
|
||||
_settings = settings;
|
||||
}
|
||||
public List<Result> TopLevelDirectorySearch(Query query, string search)
|
||||
{
|
||||
var results = new List<Result>();
|
||||
//var hasSpecial = search.IndexOfAny(_specialSearchChars) >= 0;
|
||||
string incompleteName = "";
|
||||
//if (hasSpecial || !Directory.Exists(search + "\\"))
|
||||
if (!FilesFolders.LocationExists(search + "\\"))
|
||||
{
|
||||
// if folder doesn't exist, we want to take the last part and use it afterwards to help the user
|
||||
// find the right folder.
|
||||
int index = search.LastIndexOf('\\');
|
||||
if (index > 0 && index < (search.Length - 1))
|
||||
{
|
||||
incompleteName = search.Substring(index + 1).ToLower();
|
||||
search = search.Substring(0, index + 1);
|
||||
if (!FilesFolders.LocationExists(search))
|
||||
{
|
||||
return results;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return results;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// folder exist, add \ at the end of doesn't exist
|
||||
if (!search.EndsWith("\\"))
|
||||
{
|
||||
search += "\\";
|
||||
}
|
||||
}
|
||||
|
||||
results.Add(new ResultManager().CreateOpenCurrentFolderResult(incompleteName, search));
|
||||
|
||||
var searchOption = SearchOption.TopDirectoryOnly;
|
||||
incompleteName += "*";
|
||||
|
||||
//// give the ability to search all folder when starting with >
|
||||
//if (incompleteName.StartsWith(">"))
|
||||
//{
|
||||
// searchOption = SearchOption.AllDirectories;
|
||||
|
||||
// // match everything before and after search term using supported wildcard '*', ie. *searchterm*
|
||||
// incompleteName = "*" + incompleteName.Substring(1);
|
||||
//}
|
||||
|
||||
var folderList = new List<Result>();
|
||||
var fileList = new List<Result>();
|
||||
|
||||
var folderSubtitleString = Constants.DefaultFolderSubtitleString;
|
||||
|
||||
try
|
||||
{
|
||||
// search folder and add results
|
||||
var directoryInfo = new System.IO.DirectoryInfo(search);
|
||||
var fileSystemInfos = directoryInfo.GetFileSystemInfos(incompleteName, searchOption);
|
||||
|
||||
foreach (var fileSystemInfo in fileSystemInfos)
|
||||
{
|
||||
if ((fileSystemInfo.Attributes & FileAttributes.Hidden) == FileAttributes.Hidden) continue;
|
||||
|
||||
if (fileSystemInfo is System.IO.DirectoryInfo)
|
||||
{
|
||||
if (searchOption == SearchOption.AllDirectories)
|
||||
folderSubtitleString = fileSystemInfo.FullName;
|
||||
|
||||
folderList.Add(new ResultManager().CreateFolderResult(fileSystemInfo.Name, folderSubtitleString, fileSystemInfo.FullName, query));
|
||||
}
|
||||
else
|
||||
{
|
||||
fileList.Add(new ResultManager().CreateFileResult(fileSystemInfo.FullName, query));
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (e is UnauthorizedAccessException || e is ArgumentException)
|
||||
{
|
||||
results.Add(new Result { Title = e.Message, Score = 501 });
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
|
||||
// Intial ordering, this order can be updated later by UpdateResultView.MainViewModel based on history of user selection.
|
||||
return results.Concat(folderList.OrderBy(x => x.Title)).Concat(fileList.OrderBy(x => x.Title)).ToList(); //<===== MOVE ORDERING OUT
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,6 +2,8 @@
|
|||
using Flow.Launcher.Plugin.SharedCommands;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Windows;
|
||||
|
||||
|
|
@ -42,6 +44,55 @@ namespace Flow.Launcher.Plugin.Explorer.Search
|
|||
ContextData = new SearchResult { Type = ResultType.Folder, FullPath = path }
|
||||
};
|
||||
}
|
||||
|
||||
public Result CreateOpenCurrentFolderResult(string incompleteName, string search)
|
||||
{
|
||||
var firstResult = "Open current directory";
|
||||
if (incompleteName.Length > 0)
|
||||
firstResult = "Open " + search;
|
||||
|
||||
var folderName = search.TrimEnd('\\').Split(new[] { Path.DirectorySeparatorChar }, StringSplitOptions.None).Last();
|
||||
|
||||
return new Result
|
||||
{
|
||||
Title = firstResult,
|
||||
SubTitle = $"Use > to search files and subfolders within {folderName}, " +
|
||||
$"* to search for file extensions in {folderName} or both >* to combine the search",
|
||||
IcoPath = search,
|
||||
Score = 500,
|
||||
Action = c =>
|
||||
{
|
||||
FilesFolders.OpenPath(search);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public Result CreateFileResult(string filePath, Query query)
|
||||
{
|
||||
var result = new Result
|
||||
{
|
||||
Title = Path.GetFileName(filePath),
|
||||
SubTitle = filePath,
|
||||
IcoPath = filePath,
|
||||
TitleHighlightData = StringMatcher.FuzzySearch(query.Search, Path.GetFileName(filePath)).MatchData,
|
||||
Action = c =>
|
||||
{
|
||||
try
|
||||
{
|
||||
FilesFolders.OpenPath(filePath);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show(ex.Message, "Could not start " + filePath);
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
ContextData = new SearchResult { Type = ResultType.File, FullPath = filePath }
|
||||
};
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
public class SearchResult
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
using Flow.Launcher.Plugin.Explorer.Search.DirectoryInfo;
|
||||
using Flow.Launcher.Plugin.Explorer.Search.WindowsIndex;
|
||||
using Flow.Launcher.Plugin.SharedCommands;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
|
|
@ -18,7 +20,7 @@ namespace Flow.Launcher.Plugin.Explorer.Search
|
|||
searcher = new IndexSearcher(_context);
|
||||
}
|
||||
|
||||
public List<Result> Search(string querySearchString)
|
||||
internal List<Result> Search(Query query)
|
||||
{
|
||||
var querySearch = query.Search;
|
||||
|
||||
|
|
@ -34,33 +36,36 @@ namespace Flow.Launcher.Plugin.Explorer.Search
|
|||
querySearch = EnvironmentVariables.TranslateEnvironmentVariablePath(querySearch);
|
||||
}
|
||||
|
||||
if (FilesFolders.IsLocationPathString(querySearch))
|
||||
{
|
||||
return TopLevelFolderSearchBehaviour(WindowsIndexTopLevelFolderSearch,
|
||||
DirectoryInfoClassSearch,
|
||||
WindowsIndexExists,
|
||||
querySearchString);
|
||||
query,
|
||||
querySearch);
|
||||
}
|
||||
|
||||
return WindowsIndexFilesAndFoldersSearch(querySearchString);
|
||||
return WindowsIndexFilesAndFoldersSearch(querySearch);
|
||||
}
|
||||
|
||||
private List<Result> DirectoryInfoClassSearch(string arg)
|
||||
private List<Result> DirectoryInfoClassSearch(Query query, string querySearch)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
var directoryInfoSearch = new DirectoryInfoSearch(_settings, _context);
|
||||
|
||||
///<summary>
|
||||
return directoryInfoSearch.TopLevelDirectorySearch(query, querySearch);
|
||||
}
|
||||
|
||||
public List<Result> TopLevelFolderSearchBehaviour(
|
||||
Func<string, List<Result>> windowsIndexSearch,
|
||||
Func<string, List<Result>> directoryInfoClassSearch,
|
||||
Func<Query, string, List<Result>> directoryInfoClassSearch,
|
||||
Func<string, bool> indexExists,
|
||||
string path)
|
||||
Query query,
|
||||
string querySearchString)
|
||||
{
|
||||
var results = windowsIndexSearch(path);
|
||||
var results = windowsIndexSearch(querySearchString);
|
||||
|
||||
if (results.Count == 0 && !indexExists(path))
|
||||
return directoryInfoClassSearch(path);
|
||||
if (results.Count == 0 && !indexExists(querySearchString))
|
||||
return directoryInfoClassSearch(query, querySearchString);
|
||||
|
||||
return results;
|
||||
}
|
||||
|
|
@ -73,7 +78,7 @@ namespace Flow.Launcher.Plugin.Explorer.Search
|
|||
queryConstructor.CreateQueryHelper().ConnectionString,
|
||||
queryConstructor.QueryForAllFilesAndFolders);
|
||||
}
|
||||
|
||||
|
||||
private List<Result> WindowsIndexTopLevelFolderSearch(string path)
|
||||
{
|
||||
var queryConstructor = new QueryConstructor(_settings);
|
||||
|
|
|
|||
Loading…
Reference in a new issue