Merge pull request #1950 from TheBestPessimist/everything_update_runcount

Everything: update RunCount on file action
This commit is contained in:
Kevin Zhang 2023-03-15 14:09:37 -05:00 committed by GitHub
commit 83a44b1cee
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 135 additions and 109 deletions

View file

@ -2,3 +2,4 @@ github
https
ssh
ubuntu
runcount

View file

@ -233,8 +233,8 @@ namespace Flow.Launcher.Plugin
/// Open directory in an explorer configured by user via Flow's Settings. The default is Windows Explorer
/// </summary>
/// <param name="DirectoryPath">Directory Path to open</param>
/// <param name="FileName">Extra FileName Info</param>
public void OpenDirectory(string DirectoryPath, string FileName = null);
/// <param name="FileNameOrFilePath">Extra FileName Info</param>
public void OpenDirectory(string DirectoryPath, string FileNameOrFilePath = null);
/// <summary>
/// Opens the URL with the given Uri object.

View file

@ -178,7 +178,7 @@ namespace Flow.Launcher.Plugin
/// <inheritdoc />
public override string ToString()
{
return Title + SubTitle;
return Title + SubTitle + Score;
}
/// <summary>

View file

@ -14,8 +14,6 @@ namespace Flow.Launcher.Plugin.SharedCommands
{
private const string FileExplorerProgramName = "explorer";
private const string FileExplorerProgramEXE = "explorer.exe";
/// <summary>
/// Copies the folder and all of its files and folders
/// including subfolders to the target location
@ -151,7 +149,12 @@ namespace Flow.Launcher.Plugin.SharedCommands
/// <param name="fileOrFolderPath"></param>
public static void OpenPath(string fileOrFolderPath)
{
var psi = new ProcessStartInfo { FileName = FileExplorerProgramName, UseShellExecute = true, Arguments = '"' + fileOrFolderPath + '"' };
var psi = new ProcessStartInfo
{
FileName = FileExplorerProgramName,
UseShellExecute = true,
Arguments = '"' + fileOrFolderPath + '"'
};
try
{
if (LocationExists(fileOrFolderPath) || FileExists(fileOrFolderPath))
@ -167,15 +170,6 @@ namespace Flow.Launcher.Plugin.SharedCommands
}
}
/// <summary>
/// Open the folder that contains <paramref name="path"/>
/// </summary>
/// <param name="path"></param>
public static void OpenContainingFolder(string path)
{
Process.Start(FileExplorerProgramEXE, $" /select,\"{path}\"");
}
///<summary>
/// This checks whether a given string is a directory path or network location string.
/// It does not check if location actually exists.

View file

@ -1,4 +1,4 @@
 using System;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
@ -195,17 +195,20 @@ namespace Flow.Launcher
((PluginJsonStorage<T>)_pluginJsonStorages[type]).Save();
}
public void OpenDirectory(string DirectoryPath, string FileName = null)
public void OpenDirectory(string DirectoryPath, string FileNameOrFilePath = null)
{
using var explorer = new Process();
var explorerInfo = _settingsVM.Settings.CustomExplorer;
explorer.StartInfo = new ProcessStartInfo
{
FileName = explorerInfo.Path,
Arguments = FileName is null ?
explorerInfo.DirectoryArgument.Replace("%d", DirectoryPath) :
explorerInfo.FileArgument.Replace("%d", DirectoryPath).Replace("%f",
Path.IsPathRooted(FileName) ? FileName : Path.Combine(DirectoryPath, FileName))
Arguments = FileNameOrFilePath is null
? explorerInfo.DirectoryArgument.Replace("%d", DirectoryPath)
: explorerInfo.FileArgument
.Replace("%d", DirectoryPath)
.Replace("%f",
Path.IsPathRooted(FileNameOrFilePath) ? FileNameOrFilePath : Path.Combine(DirectoryPath, FileNameOrFilePath)
)
};
explorer.Start();
}

View file

@ -17,7 +17,7 @@ namespace Flow.Launcher.Plugin.Explorer.Search.Everything
{
private const int BufferSize = 4096;
private static SemaphoreSlim _semaphore = new(1, 1);
private static readonly SemaphoreSlim _semaphore = new(1, 1);
// cached buffer to remove redundant allocations.
private static readonly StringBuilder buffer = new(BufferSize);
@ -34,6 +34,9 @@ namespace Flow.Launcher.Plugin.Explorer.Search.Everything
InvalidCallError
}
const uint EVERYTHING_REQUEST_FULL_PATH_AND_FILE_NAME = 0x00000004u;
const uint EVERYTHING_REQUEST_RUN_COUNT = 0x00000400u;
/// <summary>
/// Checks whether the sort option is Fast Sort.
/// </summary>
@ -78,7 +81,7 @@ namespace Flow.Launcher.Plugin.Explorer.Search.Everything
if (option.MaxCount < 0)
throw new ArgumentOutOfRangeException(nameof(option.MaxCount), option.MaxCount, "MaxCount must be greater than or equal to 0");
await _semaphore.WaitAsync(token);
@ -112,6 +115,17 @@ namespace Flow.Launcher.Plugin.Explorer.Search.Everything
EverythingApiDllImport.Everything_SetSort(option.SortOption);
EverythingApiDllImport.Everything_SetMatchPath(option.IsFullPathSearch);
if (option.SortOption == SortOption.RUN_COUNT_DESCENDING)
{
EverythingApiDllImport.Everything_SetRequestFlags(EVERYTHING_REQUEST_FULL_PATH_AND_FILE_NAME | EVERYTHING_REQUEST_RUN_COUNT);
}
else
{
EverythingApiDllImport.Everything_SetRequestFlags(EVERYTHING_REQUEST_FULL_PATH_AND_FILE_NAME);
}
if (token.IsCancellationRequested) yield break;
@ -132,10 +146,12 @@ namespace Flow.Launcher.Plugin.Explorer.Search.Everything
var result = new SearchResult
{
// todo the types are wrong. Everything expects uint everywhere, but we send int just above/below. how to fix? Is EverythingApiDllImport autogenerated or handmade?
FullPath = buffer.ToString(),
Type = EverythingApiDllImport.Everything_IsFolderResult(idx) ? ResultType.Folder :
EverythingApiDllImport.Everything_IsFileResult(idx) ? ResultType.File :
ResultType.Volume
ResultType.Volume,
Score = (int)EverythingApiDllImport.Everything_GetResultRunCount( (uint)idx)
};
yield return result;
@ -172,5 +188,19 @@ namespace Flow.Launcher.Plugin.Explorer.Search.Everything
throw new ArgumentOutOfRangeException();
}
}
public static async Task IncrementRunCounterAsync(string fileOrFolder)
{
await _semaphore.WaitAsync(TimeSpan.FromSeconds(1));
try
{
_ = EverythingApiDllImport.Everything_IncRunCountFromFileName(fileOrFolder);
}
catch (Exception)
{
/*ignored*/
}
finally { _semaphore.Release(); }
}
}
}

View file

@ -39,6 +39,7 @@ namespace Flow.Launcher.Plugin.Explorer.Search.Everything
Main.Context.API.GetTranslation("flowlauncher_plugin_everything_sdk_issue"));
}
}
private async ValueTask<bool> ClickToInstallEverythingAsync(ActionContext _)
{
var installedPath = await EverythingDownloadHelper.PromptDownloadIfNotInstallAsync(Settings.EverythingInstalledPath, Main.Context.API);
@ -68,8 +69,8 @@ namespace Flow.Launcher.Plugin.Explorer.Search.Everything
await foreach (var result in EverythingApi.SearchAsync(option, token))
yield return result;
}
public async IAsyncEnumerable<SearchResult> ContentSearchAsync(string plainSearch,
string contentSearch,
public async IAsyncEnumerable<SearchResult> ContentSearchAsync(string plainSearch, string contentSearch,
[EnumeratorCancellation] CancellationToken token)
{
await ThrowIfEverythingNotAvailableAsync(token);
@ -102,6 +103,7 @@ namespace Flow.Launcher.Plugin.Explorer.Search.Everything
yield return result;
}
}
public async IAsyncEnumerable<SearchResult> EnumerateAsync(string path, string search, bool recursive, [EnumeratorCancellation] CancellationToken token)
{
await ThrowIfEverythingNotAvailableAsync(token);

View file

@ -27,7 +27,6 @@ namespace Flow.Launcher.Plugin.Everything.Everything
ATTRIBUTES_DESCENDING = 16u,
FILE_LIST_FILENAME_ASCENDING = 17u,
FILE_LIST_FILENAME_DESCENDING = 18u,
RUN_COUNT_ASCENDING = 19u,
RUN_COUNT_DESCENDING = 20u,
DATE_RECENTLY_CHANGED_ASCENDING = 21u,
DATE_RECENTLY_CHANGED_DESCENDING = 22u,

View file

@ -7,6 +7,7 @@ using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
using Flow.Launcher.Plugin.Explorer.Search.Everything;
namespace Flow.Launcher.Plugin.Explorer.Search
{
@ -37,13 +38,13 @@ namespace Flow.Launcher.Plugin.Explorer.Search
var keyword = usePathSearchActionKeyword ? pathSearchActionKeyword : searchActionKeyword;
var formatted_path = path;
var formattedPath = path;
if (type == ResultType.Folder)
// the separator is needed so when navigating the folder structure contents of the folder are listed
formatted_path = path.EndsWith(Constants.DirectorySeparator) ? path : path + Constants.DirectorySeparator;
formattedPath = path.EndsWith(Constants.DirectorySeparator) ? path : path + Constants.DirectorySeparator;
return $"{keyword}{formatted_path}";
return $"{keyword}{formattedPath}";
}
public static string GetAutoCompleteText(string title, Query query, string path, ResultType resultType)
@ -57,10 +58,10 @@ namespace Flow.Launcher.Plugin.Explorer.Search
{
return result.Type switch
{
ResultType.Folder or ResultType.Volume => CreateFolderResult(Path.GetFileName(result.FullPath),
result.FullPath, result.FullPath, query, 0, result.WindowsIndexed),
ResultType.File => CreateFileResult(
result.FullPath, query, 0, result.WindowsIndexed),
ResultType.Folder or ResultType.Volume =>
CreateFolderResult(Path.GetFileName(result.FullPath), result.FullPath, result.FullPath, query, result.Score, result.WindowsIndexed),
ResultType.File =>
CreateFileResult(result.FullPath, query, result.Score, result.WindowsIndexed),
_ => throw new ArgumentOutOfRangeException()
};
}
@ -77,11 +78,12 @@ namespace Flow.Launcher.Plugin.Explorer.Search
CopyText = path,
Action = c =>
{
// open folder
if (c.SpecialKeyState.CtrlPressed || (!Settings.PathSearchKeywordEnabled && !Settings.SearchActionKeywordEnabled))
{
try
{
Context.API.OpenDirectory(path);
OpenFolder(path);
return true;
}
catch (Exception ex)
@ -91,6 +93,7 @@ namespace Flow.Launcher.Plugin.Explorer.Search
}
}
// or make this folder the current query
Context.API.ChangeQuery(GetPathWithActionKeyword(path, ResultType.Folder, query.ActionKeyword));
return false;
@ -98,12 +101,7 @@ namespace Flow.Launcher.Plugin.Explorer.Search
Score = score,
TitleToolTip = InternationalizationManager.Instance.GetTranslation("plugin_explorer_plugin_ToolTipOpenDirectory"),
SubTitleToolTip = path,
ContextData = new SearchResult
{
Type = ResultType.Folder,
FullPath = path,
WindowsIndexed = windowsIndexed
}
ContextData = new SearchResult { Type = ResultType.Folder, FullPath = path, WindowsIndexed = windowsIndexed }
};
}
@ -112,7 +110,6 @@ namespace Flow.Launcher.Plugin.Explorer.Search
var progressBarColor = "#26a0da";
var title = string.Empty; // hide title when use progress bar,
var driveLetter = path[..1].ToUpper();
var driveName = driveLetter + ":\\";
DriveInfo drv = new DriveInfo(driveLetter);
var freespace = ToReadableSize(drv.AvailableFreeSpace, 2);
var totalspace = ToReadableSize(drv.TotalSize, 2);
@ -133,19 +130,14 @@ namespace Flow.Launcher.Plugin.Explorer.Search
Score = 500,
ProgressBar = progressValue,
ProgressBarColor = progressBarColor,
Action = c =>
Action = _ =>
{
Context.API.OpenDirectory(path);
OpenFolder(path);
return true;
},
TitleToolTip = path,
SubTitleToolTip = path,
ContextData = new SearchResult
{
Type = ResultType.Volume,
FullPath = path,
WindowsIndexed = windowsIndexed
}
ContextData = new SearchResult { Type = ResultType.Volume, FullPath = path, WindowsIndexed = windowsIndexed }
};
}
@ -153,7 +145,7 @@ namespace Flow.Launcher.Plugin.Explorer.Search
{
int mok = 0;
double drvSize = pDrvSize;
string Space = "Byte";
string uom = "Byte"; // Unit Of Measurement
while (drvSize > 1024.0)
{
@ -162,23 +154,23 @@ namespace Flow.Launcher.Plugin.Explorer.Search
}
if (mok == 1)
Space = "KB";
uom = "KB";
else if (mok == 2)
Space = " MB";
uom = " MB";
else if (mok == 3)
Space = " GB";
uom = " GB";
else if (mok == 4)
Space = " TB";
uom = " TB";
var returnStr = $"{Convert.ToInt32(drvSize)}{Space}";
var returnStr = $"{Convert.ToInt32(drvSize)}{uom}";
if (mok != 0)
{
returnStr = pi switch
{
1 => $"{drvSize:F1}{Space}",
2 => $"{drvSize:F2}{Space}",
3 => $"{drvSize:F3}{Space}",
_ => $"{Convert.ToInt32(drvSize)}{Space}"
1 => $"{drvSize:F1}{uom}",
2 => $"{drvSize:F2}{uom}",
3 => $"{drvSize:F3}{uom}",
_ => $"{Convert.ToInt32(drvSize)}{uom}"
};
}
@ -201,24 +193,18 @@ namespace Flow.Launcher.Plugin.Explorer.Search
CopyText = folderPath,
Action = _ =>
{
Context.API.OpenDirectory(folderPath);
OpenFolder(folderPath);
return true;
},
ContextData = new SearchResult
{
Type = ResultType.Folder,
FullPath = folderPath,
WindowsIndexed = windowsIndexed
}
ContextData = new SearchResult { Type = ResultType.Folder, FullPath = folderPath, WindowsIndexed = windowsIndexed }
};
}
internal static Result CreateFileResult(string filePath, Query query, int score = 0, bool windowsIndexed = false)
{
Result.PreviewInfo preview = IsMedia(Path.GetExtension(filePath)) ? new Result.PreviewInfo
{
IsMedia = true, PreviewImagePath = filePath,
} : Result.PreviewInfo.Default;
Result.PreviewInfo preview = IsMedia(Path.GetExtension(filePath))
? new Result.PreviewInfo { IsMedia = true, PreviewImagePath = filePath, }
: Result.PreviewInfo.Default;
var title = Path.GetFileName(filePath);
@ -236,33 +222,17 @@ namespace Flow.Launcher.Plugin.Explorer.Search
{
try
{
if (File.Exists(filePath) && c.SpecialKeyState.CtrlPressed && c.SpecialKeyState.ShiftPressed)
if (c.SpecialKeyState.CtrlPressed && c.SpecialKeyState.ShiftPressed)
{
_ = Task.Run(() =>
{
try
{
Process.Start(new ProcessStartInfo
{
FileName = filePath,
UseShellExecute = true,
WorkingDirectory = Settings.UseLocationAsWorkingDir ? Path.GetDirectoryName(filePath) : string.Empty,
Verb = "runas",
});
}
catch (Exception e)
{
MessageBox.Show(e.Message, "Could not start " + filePath);
}
});
OpenFileAsAdmin(filePath);
}
else if (c.SpecialKeyState.CtrlPressed)
{
Context.API.OpenDirectory(Path.GetDirectoryName(filePath), filePath);
OpenFolder(filePath, filePath);
}
else
{
FilesFolders.OpenPath(filePath);
OpenFile(filePath);
}
}
catch (Exception ex)
@ -274,32 +244,59 @@ namespace Flow.Launcher.Plugin.Explorer.Search
},
TitleToolTip = InternationalizationManager.Instance.GetTranslation("plugin_explorer_plugin_ToolTipOpenContainingFolder"),
SubTitleToolTip = filePath,
ContextData = new SearchResult
{
Type = ResultType.File,
FullPath = filePath,
WindowsIndexed = windowsIndexed
}
ContextData = new SearchResult { Type = ResultType.File, FullPath = filePath, WindowsIndexed = windowsIndexed }
};
return result;
}
public static bool IsMedia(string extension)
private static bool IsMedia(string extension)
{
if (string.IsNullOrEmpty(extension))
{
return false;
}
else
{
return MediaExtensions.Contains(extension.ToLowerInvariant());
}
if (string.IsNullOrEmpty(extension)) { return false; }
return MediaExtensions.Contains(extension.ToLowerInvariant());
}
public static readonly string[] MediaExtensions =
private static void OpenFile(string filePath)
{
".jpg", ".png", ".avi", ".mkv", ".bmp", ".gif", ".wmv", ".mp3", ".flac", ".mp4"
};
IncrementEverythingRunCounterIfNeeded(filePath);
FilesFolders.OpenPath(filePath);
}
private static void OpenFolder(string folderPath, string fileNameOrFilePath = null)
{
IncrementEverythingRunCounterIfNeeded(folderPath);
Context.API.OpenDirectory(Path.GetDirectoryName(folderPath), fileNameOrFilePath);
}
private static void OpenFileAsAdmin(string filePath)
{
_ = Task.Run(() =>
{
try
{
IncrementEverythingRunCounterIfNeeded(filePath);
Process.Start(new ProcessStartInfo
{
FileName = filePath,
UseShellExecute = true,
WorkingDirectory = Settings.UseLocationAsWorkingDir ? Path.GetDirectoryName(filePath) : string.Empty,
Verb = "runas",
});
}
catch (Exception e)
{
MessageBox.Show(e.Message, "Could not start " + filePath);
}
});
}
private static void IncrementEverythingRunCounterIfNeeded(string fileOrFolder)
{
if (Settings.EverythingEnabled)
_ = Task.Run(() => EverythingApi.IncrementRunCounterAsync(fileOrFolder));
}
private static readonly string[] MediaExtensions = { ".jpg", ".png", ".avi", ".mkv", ".bmp", ".gif", ".wmv", ".mp3", ".flac", ".mp4" };
}
public enum ResultType