diff --git a/Plugins/Flow.Launcher.Plugin.Folder/Main.cs b/Plugins/Flow.Launcher.Plugin.Folder/Main.cs index 74ce0c92d..dafd1a90e 100644 --- a/Plugins/Flow.Launcher.Plugin.Folder/Main.cs +++ b/Plugins/Flow.Launcher.Plugin.Folder/Main.cs @@ -27,6 +27,8 @@ namespace Flow.Launcher.Plugin.Folder private readonly PluginJsonStorage _storage; private IContextMenu _contextMenuLoader; + private static Dictionary _envStringPaths; + public Main() { _storage = new PluginJsonStorage(); @@ -48,6 +50,7 @@ namespace Flow.Launcher.Plugin.Folder _context = context; _contextMenuLoader = new ContextMenuLoader(context); InitialDriverList(); + LoadEnvironmentStringPaths(); } public List Query(Query query) @@ -58,7 +61,14 @@ namespace Flow.Launcher.Plugin.Folder if (!IsDriveOrSharedFolder(search)) return results; - results.AddRange(QueryInternal_Directory_Exists(query)); + if (search.StartsWith("%")) + { + results.AddRange(GetEnvironmentStringPathResults(search, query)); + } + else + { + results.AddRange(QueryInternal_Directory_Exists(query.Search, query)); + } // todo why was this hack here? foreach (var result in results) @@ -72,7 +82,12 @@ namespace Flow.Launcher.Plugin.Folder private static bool IsDriveOrSharedFolder(string search) { if (search.StartsWith(@"\\")) - { // share folder + { // shared folder + return true; + } + + if (_envStringPaths != null && search.StartsWith("%")) + { // environment string formatted folder return true; } @@ -146,14 +161,37 @@ namespace Flow.Launcher.Plugin.Folder } } + private void LoadEnvironmentStringPaths() + { + _envStringPaths = new Dictionary(); + + var specialPaths = + new Dictionary { + { "appdata", Environment.SpecialFolder.ApplicationData }, + { "localappdata", Environment.SpecialFolder.LocalApplicationData }, + { "programfiles", Environment.SpecialFolder.ProgramFiles }, + { "programfiles(x86)", Environment.SpecialFolder.ProgramFilesX86 }, + { "programdata", Environment.SpecialFolder.CommonApplicationData }, + { "userprofile", Environment.SpecialFolder.UserProfile } + }; + + foreach (var special in specialPaths) + { + _envStringPaths.Add(special.Key, Environment.GetFolderPath(special.Value)); + } + + var tempDirectoryPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Temp"); + + _envStringPaths.Add("temp", tempDirectoryPath); + } + private static readonly char[] _specialSearchChars = new char[] { '?', '*', '>' }; - private List QueryInternal_Directory_Exists(Query query) + private List QueryInternal_Directory_Exists(string search, Query query) { - var search = query.Search; var results = new List(); var hasSpecial = search.IndexOfAny(_specialSearchChars) >= 0; string incompleteName = ""; @@ -243,6 +281,63 @@ namespace Flow.Launcher.Plugin.Folder return results.Concat(folderList.OrderBy(x => x.Title)).Concat(fileList.OrderBy(x => x.Title)).ToList(); } + private List GetEnvironmentStringPathSuggestions(string search, Query query) + { + var results = new List(); + foreach (var p in _envStringPaths) + { + if (p.Key.StartsWith(search)) + { + results.Add(CreateFolderResult($"%{p.Key}%", p.Value, p.Value, query)); + } + } + return results; + } + + private List GetEnvironmentStringPathResults(string envStringSearch, Query query) + { + if (envStringSearch == "%") + { // return all environment string options as path suggestions + return GetEnvironmentStringPathSuggestions("", query); + } + + var results = new List(); + var search = envStringSearch.Substring(1); + + if (search.EndsWith("%") && search.Length > 1) + { // query starts and ends with a %, find an exact match from env-string paths + var exactEnvStringPath = search.Substring(0, search.Length-1); + + if (_envStringPaths.ContainsKey(exactEnvStringPath)) + { + var expandedPath = _envStringPaths[exactEnvStringPath]; + results.Add(CreateFolderResult($"%{exactEnvStringPath}%", expandedPath, expandedPath, query)); + } + } + else if (search.Contains("%")) + { // query starts with a % and contains another % somewhere before the end + var splitSearch = search.Split("%"); + var exactEnvStringPath = splitSearch[0]; + + // if there are more than 2 % characters in the query, don't bother + if (splitSearch.Length == 2 && _envStringPaths.ContainsKey(exactEnvStringPath)) + { + var queryPartToReplace = $"%{exactEnvStringPath}%"; + var expandedPath = _envStringPaths[exactEnvStringPath]; + // replace the %envstring% part of the query with its expanded equivalent + var updatedSearch = envStringSearch.Replace(queryPartToReplace, expandedPath); + + results.AddRange(QueryInternal_Directory_Exists(updatedSearch, query)); + } + } + else + { // query simply starts wtih a %, suggest env-string paths that match the rest of the search + results.AddRange(GetEnvironmentStringPathSuggestions(search, query)); + } + + return results; + } + private static Result CreateFileResult(string filePath, Query query) { var result = new Result