From f36ee61de4e08ef7023d4ae7741da16f7b219833 Mon Sep 17 00:00:00 2001 From: Koisu Date: Mon, 23 Jun 2025 17:59:33 -0700 Subject: [PATCH] feat: :sparkles: Added keybind to rename files --- Flow.Launcher/ViewModel/MainViewModel.cs | 35 +++++++---- .../Helper/RenameThing.cs | 60 ++++++++++++++++++- .../Languages/en.xaml | 1 + .../Search/ResultManager.cs | 1 + .../Flow.Launcher.Plugin.Explorer/Settings.cs | 13 ++-- .../ViewModels/SettingsViewModel.cs | 2 - .../Views/ActionKeywordSetting.xaml.cs | 1 + .../Views/RenameFile.xaml.cs | 44 +------------- 8 files changed, 93 insertions(+), 64 deletions(-) diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs index 6355b61a1..9b89f4865 100644 --- a/Flow.Launcher/ViewModel/MainViewModel.cs +++ b/Flow.Launcher/ViewModel/MainViewModel.cs @@ -932,27 +932,40 @@ namespace Flow.Launcher.ViewModel [RelayCommand] private void RenameFile() { + const string explorerPluginID = "572be03c74c642baae319fc283e561a8"; // check if explorer plugin is enabled - var explorerPluginMatches = App.API.GetAllPlugins().Where(plugin => plugin.Metadata.ID == "572be03c74c642baae319fc283e561a8"); + IEnumerable explorerPluginMatches = App.API.GetAllPlugins().Where( + plugin => plugin.Metadata.ID == explorerPluginID); - if (!explorerPluginMatches.Any()) + if (!explorerPluginMatches.Any() || explorerPluginMatches == null) { + timesTriedToRenameFileWithExplorerDisabled++; return; } - else if (!explorerPluginMatches.Any() && timesTriedToRenameFileWithExplorerDisabled > 3) + else if ((!explorerPluginMatches.Any() || explorerPluginMatches == null) && timesTriedToRenameFileWithExplorerDisabled > 3) { App.API.ShowMsg("Are you trying to rename a file?", "The explorer plugin needs to be enabled for the hotkey to rename files to work."); timesTriedToRenameFileWithExplorerDisabled = 0; + return; } else { - dynamic explorerPlugin = explorerPluginMatches.First(); - string path = SelectedResults.SelectedItem.Result.SubTitle; - if (File.Exists(path) || Directory.Exists(path)) + // at runtime the type of the will be + dynamic explorerPlugin = explorerPluginMatches.First(); // assuming there's only one match + string path = SelectedResults?.SelectedItem?.Result.SubTitle ?? ""; + string name = SelectedResults?.SelectedItem?.Result.Title ?? ""; + if (path.Trim() == "" || name.Trim() == "") return; + if (File.Exists(Path.Join(path, name))) { - explorerPlugin.Plugin.RenameDialog(new FileInfo(path), App.API ); // this feels kinda hacky + explorerPlugin.Plugin.RenameDialog(new FileInfo(Path.Join(path, name)), App.API); + return; + } + if (Directory.Exists(path)) + { + File.AppendAllText("YEE.idi", "YYEEE"); + explorerPlugin.Plugin.RenameDialog(new DirectoryInfo(path), App.API); // this feels kinda hacky return; } else if (new DirectoryInfo(path).Parent == null) // check if isn't a root directory like C:\ @@ -960,10 +973,10 @@ namespace Flow.Launcher.ViewModel App.API.ShowMsgError("Cannot rename this."); return; } - - - - + + + + } } #endregion diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Helper/RenameThing.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Helper/RenameThing.cs index e963b5b4b..4501d4337 100644 --- a/Plugins/Flow.Launcher.Plugin.Explorer/Helper/RenameThing.cs +++ b/Plugins/Flow.Launcher.Plugin.Explorer/Helper/RenameThing.cs @@ -4,12 +4,13 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading.Tasks; +using JetBrains.Annotations; namespace Flow.Launcher.Plugin.Explorer.Helper { public static class RenameThing { - public static void Rename(this FileSystemInfo info, string newName, IPublicAPI api) + private static void _rename(this FileSystemInfo info, string newName, IPublicAPI api) { if (info is FileInfo) { @@ -47,13 +48,66 @@ namespace Flow.Launcher.Plugin.Explorer.Helper } Directory.Move(info.FullName, Path.Join(parent.FullName, newName)); - }else + } + else { throw new ArgumentException($"{nameof(info)} must be either, {nameof(FileInfo)} or {nameof(DirectoryInfo)}"); } - } } + /// + /// Renames a file system elemnt (directory or file) + /// + /// The requested new name + /// The or representing the old file + /// An instance of so this can create msgboxes + + public static void Rename(string NewFileName, FileSystemInfo oldInfo, IPublicAPI api) + { + // if it's just whitespace and nothing else + if (NewFileName.Trim() == "" || NewFileName == "") + { + api.ShowMsgError(string.Format(api.GetTranslation("plugin_explorer_field_may_not_be_empty"), "New file name")); + return; + } + + try + { + oldInfo._rename(NewFileName, api); + } + catch (Exception exception) + { + switch (exception) + { + case FileNotFoundException: + + api.ShowMsgError(string.Format(api.GetTranslation("plugin_explorer_file_not_found"), oldInfo.FullName)); + return; + case NotANewNameException: + api.ShowMsgError(string.Format(api.GetTranslation("plugin_explorer_not_a_new_name"), NewFileName)); + api.ShowMainWindow(); + return; + case InvalidNameException: + api.ShowMsgError(string.Format(api.GetTranslation("plugin_explorer_invalid_name"), NewFileName)); + return; + case IOException iOException: + if (iOException.Message.Contains("incorrect")) + { + api.ShowMsgError(string.Format(api.GetTranslation("plugin_explorer_invalid_name"), NewFileName)); + return; + } + else + { + goto default; + } + default: + api.ShowMsgError(exception.ToString()); + return; + } + } + api.ShowMsg(string.Format(api.GetTranslation("plugin_explorer_successful_rename"), NewFileName)); + } + } } internal class NotANewNameException : IOException diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml index 688d177ab..291d28eba 100644 --- a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml +++ b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml @@ -201,4 +201,5 @@ The specified file: {0} was not found Open a dialog to rename this. This cannot be renamed. + Successfully renamed it to: {0} diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs index e87d2df97..8c9db37aa 100644 --- a/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs +++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs @@ -60,6 +60,7 @@ namespace Flow.Launcher.Plugin.Explorer.Search public static Result CreateResult(Query query, SearchResult result) { + return result.Type switch { ResultType.Folder or ResultType.Volume => diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs index ac0e54062..cf380ee00 100644 --- a/Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs +++ b/Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs @@ -1,6 +1,7 @@ using System; using System.Collections.ObjectModel; using System.ComponentModel; +using System.IO; using System.Text.Json.Serialization; using Flow.Launcher.Plugin.Everything.Everything; using Flow.Launcher.Plugin.Explorer.Search; @@ -9,6 +10,8 @@ using Flow.Launcher.Plugin.Explorer.Search.IProvider; using Flow.Launcher.Plugin.Explorer.Search.QuickAccessLinks; using Flow.Launcher.Plugin.Explorer.Search.WindowsIndex; using Flow.Launcher.Plugin.Explorer.ViewModels; +using Flow.Launcher.Plugin.Explorer.Views; + namespace Flow.Launcher.Plugin.Explorer { @@ -185,7 +188,7 @@ namespace Flow.Launcher.Plugin.Explorer FileContentSearchActionKeyword, IndexSearchActionKeyword, QuickAccessActionKeyword, - RenameActionKeyword + } internal string GetActionKeyword(ActionKeyword actionKeyword) => @@ -196,7 +199,7 @@ namespace Flow.Launcher.Plugin.Explorer ActionKeyword.FileContentSearchActionKeyword => FileContentSearchActionKeyword, ActionKeyword.IndexSearchActionKeyword => IndexSearchActionKeyword, ActionKeyword.QuickAccessActionKeyword => QuickAccessActionKeyword, - ActionKeyword.RenameActionKeyword => RenameActionKeyword, + _ => throw new ArgumentOutOfRangeException( nameof(actionKeyword), @@ -214,7 +217,7 @@ namespace Flow.Launcher.Plugin.Explorer => FileContentSearchActionKeyword = keyword, ActionKeyword.IndexSearchActionKeyword => IndexSearchActionKeyword = keyword, ActionKeyword.QuickAccessActionKeyword => QuickAccessActionKeyword = keyword, - ActionKeyword.RenameActionKeyword => RenameActionKeyword = keyword, + _ => throw new ArgumentOutOfRangeException( nameof(actionKeyword), @@ -231,7 +234,7 @@ namespace Flow.Launcher.Plugin.Explorer ActionKeyword.IndexSearchActionKeyword => IndexSearchKeywordEnabled, ActionKeyword.FileContentSearchActionKeyword => FileContentSearchKeywordEnabled, ActionKeyword.QuickAccessActionKeyword => QuickAccessKeywordEnabled, - ActionKeyword.RenameActionKeyword => RenameActionKeywordEnabled, + _ => throw new ArgumentOutOfRangeException( nameof(actionKeyword), @@ -249,7 +252,7 @@ namespace Flow.Launcher.Plugin.Explorer ActionKeyword.FileContentSearchActionKeyword => FileContentSearchKeywordEnabled = enable, ActionKeyword.QuickAccessActionKeyword => QuickAccessKeywordEnabled = enable, - ActionKeyword.RenameActionKeyword => RenameActionKeywordEnabled = enable, + _ => throw new ArgumentOutOfRangeException( nameof(actionKeyword), diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs b/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs index 48ea82155..49e6d41a8 100644 --- a/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs +++ b/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs @@ -280,8 +280,6 @@ namespace Flow.Launcher.Plugin.Explorer.ViewModels "plugin_explorer_actionkeywordview_indexsearch"), new(Settings.ActionKeyword.QuickAccessActionKeyword, "plugin_explorer_actionkeywordview_quickaccess"), - new (Settings.ActionKeyword.RenameActionKeyword, - "plugin_explorer_actionkeywordview_rename") }; } diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ActionKeywordSetting.xaml.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ActionKeywordSetting.xaml.cs index 829a2feed..247ed5779 100644 --- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/ActionKeywordSetting.xaml.cs +++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/ActionKeywordSetting.xaml.cs @@ -98,6 +98,7 @@ namespace Flow.Launcher.Plugin.Explorer.Views } } + private void TextBox_Pasting(object sender, DataObjectPastingEventArgs e) { if (e.DataObject.GetDataPresent(DataFormats.Text)) diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Views/RenameFile.xaml.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Views/RenameFile.xaml.cs index d27ef0e29..4c33be2cf 100644 --- a/Plugins/Flow.Launcher.Plugin.Explorer/Views/RenameFile.xaml.cs +++ b/Plugins/Flow.Launcher.Plugin.Explorer/Views/RenameFile.xaml.cs @@ -57,49 +57,7 @@ namespace Flow.Launcher.Plugin.Explorer.Views private void OnDoneButtonClick(object sender, RoutedEventArgs e) { - - // if it's just whitespace and nothing else - _api.LogInfo(nameof(RenameFile), $"THIS IS NEW FILE NAME: {NewFileName}"); - if (NewFileName.Trim() == "" || NewFileName == "") - { - _api.ShowMsgError(string.Format(_api.GetTranslation("plugin_explorer_field_may_not_be_empty"), "New file name")); - return; - } - - try - { - _info.Rename(NewFileName, _api); - } - catch (Exception exception) - { - switch (exception) - { - case FileNotFoundException: - - _api.ShowMsgError(string.Format(_api.GetTranslation("plugin_explorer_file_not_found"), _oldFilePath)); - break; - case NotANewNameException: - _api.ShowMsgError(string.Format(_api.GetTranslation("plugin_explorer_not_a_new_name"), NewFileName)); - _api.ShowMainWindow(); - break; - case InvalidNameException: - _api.ShowMsgError(string.Format(_api.GetTranslation("plugin_explorer_invalid_name"), NewFileName)); - break; - case IOException iOException: - if (iOException.Message.Contains("incorrect")) - { - _api.ShowMsgError(string.Format(_api.GetTranslation("plugin_explorer_invalid_name"), NewFileName)); - break; - } - else - { - goto default; - } - default: - _api.ShowMsgError(exception.ToString()); - break; - } - } + RenameThing.Rename(NewFileName, _info, _api); Close(); }