diff --git a/Plugins/Wox.Plugin.Folder/Main.cs b/Plugins/Wox.Plugin.Folder/Main.cs index e8f33a951b..b5c122b106 100644 --- a/Plugins/Wox.Plugin.Folder/Main.cs +++ b/Plugins/Wox.Plugin.Folder/Main.cs @@ -21,7 +21,6 @@ namespace Wox.Plugin.Folder { _storage = new PluginJsonStorage(); _settings = _storage.Load(); - InitialDriverList(); } public void Save() @@ -37,54 +36,20 @@ namespace Wox.Plugin.Folder public void Init(PluginInitContext context) { _context = context; - + InitialDriverList(); } public List Query(Query query) { + var results = GetUserFolderResults(query); + string search = query.Search.ToLower(); - - List userFolderLinks = _settings.FolderLinks.Where( - x => x.Nickname.StartsWith(search, StringComparison.OrdinalIgnoreCase)).ToList(); - List results = - userFolderLinks.Select( - item => new Result() - { - Title = item.Nickname, - IcoPath = item.Path, - SubTitle = "Ctrl + Enter to open the directory", - Action = c => - { - if (c.SpecialKeyState.CtrlPressed) - { - try - { - Process.Start(item.Path); - return true; - } - catch (Exception ex) - { - MessageBox.Show(ex.Message, "Could not start " + item.Path); - return false; - } - } - _context.API.ChangeQuery($"{query.ActionKeyword} {item.Path}{(item.Path.EndsWith("\\") ? "" : "\\")}"); - return false; - }, - ContextData = item, - }).ToList(); - if (_driverNames != null && !_driverNames.Any(search.StartsWith)) return results; - //if (!input.EndsWith("\\")) - //{ - // //"c:" means "the current directory on the C drive" whereas @"c:\" means "root of the C drive" - // input = input + "\\"; - //} results.AddRange(QueryInternal_Directory_Exists(query)); - // todo temp hack for scores + // todo why was this hack here? foreach (var result in results) { result.Score += 10; @@ -92,12 +57,53 @@ namespace Wox.Plugin.Folder return results; } + + private Result CreateFolderResult(string title, string path) + { + return new Result + { + Title = title, + IcoPath = path, + SubTitle = "Ctrl + Enter to open the directory", + Action = c => + { + if (c.SpecialKeyState.CtrlPressed) + { + try + { + Process.Start(path); + return true; + } + catch (Exception ex) + { + MessageBox.Show(ex.Message, "Could not start " + path); + return false; + } + } + + string changeTo = path.EndsWith("\\") ? path : path + "\\"; + _context.API.ChangeQuery(changeTo); + return false; + } + }; + } + + private List GetUserFolderResults(Query query) + { + string search = query.Search.ToLower(); + var userFolderLinks = _settings.FolderLinks.Where( + x => x.Nickname.StartsWith(search, StringComparison.OrdinalIgnoreCase)); + var results = userFolderLinks.Select(item => CreateFolderResult(item.Nickname, item.Path)) + .ToList(); + return results; + } + private void InitialDriverList() { if (_driverNames == null) { _driverNames = new List(); - DriveInfo[] allDrives = DriveInfo.GetDrives(); + var allDrives = DriveInfo.GetDrives(); foreach (DriveInfo driver in allDrives) { _driverNames.Add(driver.Name.ToLower().TrimEnd('\\')); @@ -105,21 +111,25 @@ namespace Wox.Plugin.Folder } } + private static readonly char[] _specialSearchChars = new char[] + { + '?', '*', '>' + }; + private List QueryInternal_Directory_Exists(Query query) { var search = query.Search.ToLower(); var results = new List(); - + var hasSpecial = search.IndexOfAny(_specialSearchChars) >= 0; string incompleteName = ""; - if (!Directory.Exists(search + "\\")) + if (hasSpecial || !Directory.Exists(search + "\\")) { - //if the last component of the path is incomplete, - //then make auto complete for it. + // 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); - incompleteName = incompleteName.ToLower(); + incompleteName = search.Substring(index + 1).ToLower(); search = search.Substring(0, index + 1); if (!Directory.Exists(search)) return results; @@ -128,15 +138,71 @@ namespace Wox.Plugin.Folder return results; } else - { + { // folder exist, add \ at the end of doesn't exist if (!search.EndsWith("\\")) search += "\\"; } + results.Add(CreateOpenCurrentFolderResult(incompleteName, search)); + + + var directoryInfo = new DirectoryInfo(search); + + var searchOption= SearchOption.TopDirectoryOnly; + incompleteName += "*"; + + if (incompleteName.StartsWith(">")) // give the ability to search all folder when starting with > + { + searchOption = SearchOption.AllDirectories; + incompleteName = incompleteName.Substring(1); + } + + // search folder and add results + var fileSystemInfos = directoryInfo.GetFileSystemInfos(incompleteName, searchOption); + + foreach (var fileSystemInfo in fileSystemInfos) + { + if ((fileSystemInfo.Attributes & FileAttributes.Hidden) == FileAttributes.Hidden) continue; + + var result = + fileSystemInfo is DirectoryInfo + ? CreateFolderResult(fileSystemInfo.Name, fileSystemInfo.FullName) + : CreateFileResult(fileSystemInfo.FullName); + results.Add(result); + } + + return results; + } + + private static Result CreateFileResult(string filePath) + { + var result = new Result + { + Title = Path.GetFileName(filePath), + IcoPath = filePath, + Action = c => + { + try + { + Process.Start(filePath); + } + catch (Exception ex) + { + MessageBox.Show(ex.Message, "Could not start " + filePath); + } + + return true; + } + }; + return result; + } + + private static Result CreateOpenCurrentFolderResult(string incompleteName, string search) + { string firstResult = "Open current directory"; if (incompleteName.Length > 0) firstResult = "Open " + search; - results.Add(new Result + return new Result { Title = firstResult, IcoPath = search, @@ -146,76 +212,7 @@ namespace Wox.Plugin.Folder Process.Start(search); return true; } - }); - - //Add children directories - DirectoryInfo[] dirs = new DirectoryInfo(search).GetDirectories(); - foreach (DirectoryInfo dir in dirs) - { - if ((dir.Attributes & FileAttributes.Hidden) == FileAttributes.Hidden) continue; - - if (incompleteName.Length != 0 && !dir.Name.ToLower().StartsWith(incompleteName)) - continue; - DirectoryInfo dirCopy = dir; - var result = new Result - { - Title = dir.Name, - IcoPath = dir.FullName, - SubTitle = "Ctrl + Enter to open the directory", - Action = c => - { - if (c.SpecialKeyState.CtrlPressed) - { - try - { - Process.Start(dirCopy.FullName); - return true; - } - catch (Exception ex) - { - MessageBox.Show(ex.Message, "Could not start " + dirCopy.FullName); - return false; - } - } - _context.API.ChangeQuery($"{query.ActionKeyword} {dirCopy.FullName}\\"); - return false; - } - }; - - results.Add(result); - } - - //Add children files - FileInfo[] files = new DirectoryInfo(search).GetFiles(); - foreach (FileInfo file in files) - { - if ((file.Attributes & FileAttributes.Hidden) == FileAttributes.Hidden) continue; - if (incompleteName.Length != 0 && !file.Name.ToLower().StartsWith(incompleteName)) - continue; - string filePath = file.FullName; - var result = new Result - { - Title = Path.GetFileName(filePath), - IcoPath = filePath, - Action = c => - { - try - { - Process.Start(filePath); - } - catch (Exception ex) - { - MessageBox.Show(ex.Message, "Could not start " + filePath); - } - - return true; - } - }; - - results.Add(result); - } - - return results; + }; } public string GetTranslatedPluginTitle()