diff --git a/Changelog.md b/Changelog.md index 180487f..2031a04 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,5 +1,18 @@ # Changelog +## 2.1.1 - 2025-1-4 + +### Changes + +- Indicated Windows/Microsoft Search is required for default and scoped search in readme. ([#24](https://github.com/Odotocodot/Flow.Launcher.Plugin.OneNote/issues/24)) +- Added some badges. +- Updated OneNote page result tooltips. +- Changed recent pages default keyword from `rcntpgs:` to `rp:`. + +### Fixes + +- Fixed spelling and grammar mistakes. + ## 2.1.0 - 2024-6-24 ### Added diff --git a/Flow.Launcher.Plugin.OneNote/Flow.Launcher.Plugin.OneNote.csproj b/Flow.Launcher.Plugin.OneNote/Flow.Launcher.Plugin.OneNote.csproj index 0633013..ffdf7d0 100644 --- a/Flow.Launcher.Plugin.OneNote/Flow.Launcher.Plugin.OneNote.csproj +++ b/Flow.Launcher.Plugin.OneNote/Flow.Launcher.Plugin.OneNote.csproj @@ -11,7 +11,8 @@ false true true - true + true + en diff --git a/Flow.Launcher.Plugin.OneNote/Keywords.cs b/Flow.Launcher.Plugin.OneNote/Keywords.cs index 540831f..0273790 100644 --- a/Flow.Launcher.Plugin.OneNote/Keywords.cs +++ b/Flow.Launcher.Plugin.OneNote/Keywords.cs @@ -4,7 +4,7 @@ public class Keywords { public const string NotebookExplorerSeparator = "\\"; public string NotebookExplorer { get; set; } = $"nb:{NotebookExplorerSeparator}"; - public string RecentPages { get; set; } = "rcntpgs:"; + public string RecentPages { get; set; } = "rp:"; public string TitleSearch { get; set; } = "*"; public string ScopedSearch { get; set; } = ">"; } diff --git a/Flow.Launcher.Plugin.OneNote/ResultCreator.cs b/Flow.Launcher.Plugin.OneNote/ResultCreator.cs index b2d17aa..11e813e 100644 --- a/Flow.Launcher.Plugin.OneNote/ResultCreator.cs +++ b/Flow.Launcher.Plugin.OneNote/ResultCreator.cs @@ -68,7 +68,7 @@ public List EmptyQuery() new Result { Title = "View notebook explorer", - SubTitle = $"Type \"{settings.Keywords.NotebookExplorer}\" or select this option to search by notebook structure ", + SubTitle = $"Type \"{settings.Keywords.NotebookExplorer}\" or select this option to search by notebook structure", AutoCompleteText = $"{ActionKeyword} {settings.Keywords.NotebookExplorer}", IcoPath = iconProvider.NotebookExplorer, Score = 2000, @@ -194,9 +194,10 @@ public Result CreateOneNoteItemResult(IOneNoteItem item, bool actionIsAutoComple subTitle = subTitle[..^(page.Name.Length + PathSeparator.Length)]; toolTip = - $"Created:\t\t{page.Created:F}\n" + - $"Last Modified:\t{page.LastModified:F}"; - + $""" + {"Created:",-15} {page.Created:F} + {"Last Modified:",-15} {page.LastModified:F} + """; iconInfo = new IconGeneratorInfo(page); break; default: @@ -239,7 +240,7 @@ public Result CreatePageResult(OneNotePage page, string query) public Result CreateRecentPageResult(OneNotePage page) { var result = CreateOneNoteItemResult(page, false, null); - result.SubTitle = $"{page.LastModified.Humanize()}\t{result.SubTitle}"; + result.SubTitle = $"{page.LastModified.Humanize()} | {result.SubTitle}"; result.IcoPath = iconProvider.Recent; return result; } @@ -454,7 +455,7 @@ private Lazy GetNewPagePreviewPanel(OneNoteSection section, string public static List NoMatchesFound() { return SingleResult("No matches found", - "Try searching something else, or syncing your notebooks.", + "Try searching something else, or syncing your notebooks", IconProvider.Logo); } public List InvalidQuery() diff --git a/Flow.Launcher.Plugin.OneNote/SearchManager.NotebookExplorer.cs b/Flow.Launcher.Plugin.OneNote/SearchManager.NotebookExplorer.cs new file mode 100644 index 0000000..c21b239 --- /dev/null +++ b/Flow.Launcher.Plugin.OneNote/SearchManager.NotebookExplorer.cs @@ -0,0 +1,173 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Odotocodot.OneNote.Linq; + +namespace Flow.Launcher.Plugin.OneNote +{ + public partial class SearchManager + { + private sealed class NotebookExplorer + { + private readonly SearchManager searchManager; + private readonly ResultCreator resultCreator; + + private Keywords Keywords => searchManager.settings.Keywords; + internal NotebookExplorer(SearchManager searchManager, ResultCreator resultCreator) + { + this.searchManager = searchManager; + this.resultCreator = resultCreator; + } + + internal List Query(Query query) + { + var results = new List(); + + string fullSearch = query.Search[(query.Search.IndexOf(Keywords.NotebookExplorer, StringComparison.Ordinal) + Keywords.NotebookExplorer.Length)..]; + + IOneNoteItem parent = null; + IEnumerable collection = OneNoteApplication.GetNotebooks(); + + string[] searches = fullSearch.Split(Keywords.NotebookExplorerSeparator, StringSplitOptions.None); + + for (int i = -1; i < searches.Length - 1; i++) + { + if (i < 0) + { + continue; + } + + parent = collection.FirstOrDefault(item => item.Name.Equals(searches[i])); + if (parent == null) + { + return results; + } + + collection = parent.Children; + } + + string lastSearch = searches[^1]; + + results = lastSearch switch + { + // Empty search so show all in collection + string search when string.IsNullOrWhiteSpace(search) + => EmptySearch(parent, collection), + + // Search by title + string search when search.StartsWith(Keywords.TitleSearch) && parent is not OneNotePage + => searchManager.TitleSearch(search, parent, collection), + + // Scoped search + string search when search.StartsWith(Keywords.ScopedSearch) && parent is OneNoteNotebook or OneNoteSectionGroup + => ScopedSearch(search, parent), + + // Default search + _ => Explorer(lastSearch, parent, collection), + }; + + if (parent != null) + { + var result = resultCreator.CreateOneNoteItemResult(parent, false, score: 4000); + result.Title = $"Open \"{parent.Name}\" in OneNote"; + result.SubTitle = lastSearch switch + { + string search when search.StartsWith(Keywords.TitleSearch) + => $"Now searching by title in \"{parent.Name}\"", + + string search when search.StartsWith(Keywords.ScopedSearch) + => $"Now searching all pages in \"{parent.Name}\"", + + _ => $"Use \'{Keywords.ScopedSearch}\' to search this item. Use \'{Keywords.TitleSearch}\' to search by title in this item", + }; + + results.Add(result); + } + + return results; + } + + private List EmptySearch(IOneNoteItem parent, IEnumerable collection) + { + List results = collection.Where(searchManager.SettingsCheck) + .Select(item => resultCreator.CreateOneNoteItemResult(item, true)) + .ToList(); + if (results.Any()) + return results; + return resultCreator.NoItemsInCollection(results, parent); + } + + private List ScopedSearch(string query, IOneNoteItem parent) + { + if (query.Length == Keywords.ScopedSearch.Length) + { + return ResultCreator.NoMatchesFound(); + } + + if (!char.IsLetterOrDigit(query[Keywords.ScopedSearch.Length])) + { + return resultCreator.InvalidQuery(); + } + + string currentSearch = query[Keywords.TitleSearch.Length..]; + + var results = OneNoteApplication.FindPages(currentSearch, parent) + .Select(pg => resultCreator.CreatePageResult(pg, currentSearch)) + .ToList(); + + if (!results.Any()) + { + results = ResultCreator.NoMatchesFound(); + } + + return results; + } +#nullable enable + private List Explorer(string search, IOneNoteItem? parent, IEnumerable collection) + { + List? highlightData = null; + int score = 0; + + var results = collection.Where(searchManager.SettingsCheck) + .Where(item => searchManager.FuzzySearch(item.Name, search, out highlightData, out score)) + .Select(item => resultCreator.CreateOneNoteItemResult(item, true, highlightData, score)) + .ToList(); + + AddCreateNewOneNoteItemResults(search, parent, results); + return results; + } + + private void AddCreateNewOneNoteItemResults(string newItemName, IOneNoteItem? parent, List results) + { + if (results.Any(result => string.Equals(newItemName.Trim(), result.Title, StringComparison.OrdinalIgnoreCase))) + { + return; + } + + if (parent?.IsInRecycleBin() == true) + { + return; + } + + switch (parent) + { + case null: + results.Add(resultCreator.CreateNewNotebookResult(newItemName)); + break; + case OneNoteNotebook: + case OneNoteSectionGroup: + results.Add(resultCreator.CreateNewSectionResult(newItemName, parent)); + results.Add(resultCreator.CreateNewSectionGroupResult(newItemName, parent)); + break; + case OneNoteSection section: + if (!section.Locked) + { + results.Add(resultCreator.CreateNewPageResult(newItemName, section)); + } + + break; + } + } + } + } +} diff --git a/Flow.Launcher.Plugin.OneNote/SearchManager.cs b/Flow.Launcher.Plugin.OneNote/SearchManager.cs index 21ed884..fbd7faa 100644 --- a/Flow.Launcher.Plugin.OneNote/SearchManager.cs +++ b/Flow.Launcher.Plugin.OneNote/SearchManager.cs @@ -1,11 +1,10 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; using Odotocodot.OneNote.Linq; namespace Flow.Launcher.Plugin.OneNote { - public class SearchManager + public partial class SearchManager { private readonly PluginInitContext context; private readonly Settings settings; @@ -73,10 +72,10 @@ private List TitleSearch(string query, IOneNoteItem parent, IEnumerable< private List RecentPages(string query) { int count = settings.DefaultRecentsCount; - + if (query.Length > settings.Keywords.RecentPages.Length && int.TryParse(query[settings.Keywords.RecentPages.Length..], out int userChosenCount)) count = userChosenCount; - + return OneNoteApplication.GetNotebooks() .GetPages() .Where(SettingsCheck) @@ -102,166 +101,5 @@ private bool SettingsCheck(IOneNoteItem item) success = false; return success; } - private sealed class NotebookExplorer - { - private readonly SearchManager searchManager; - private readonly ResultCreator resultCreator; - - private Keywords Keywords => searchManager.settings.Keywords; - internal NotebookExplorer(SearchManager searchManager, ResultCreator resultCreator) - { - this.searchManager = searchManager; - this.resultCreator = resultCreator; - } - - internal List Query(Query query) - { - var results = new List(); - - string fullSearch = query.Search[(query.Search.IndexOf(Keywords.NotebookExplorer, StringComparison.Ordinal) + Keywords.NotebookExplorer.Length)..]; - - IOneNoteItem parent = null; - IEnumerable collection = OneNoteApplication.GetNotebooks(); - - string[] searches = fullSearch.Split(Keywords.NotebookExplorerSeparator, StringSplitOptions.None); - - for (int i = -1; i < searches.Length - 1; i++) - { - if (i < 0) - { - continue; - } - - parent = collection.FirstOrDefault(item => item.Name.Equals(searches[i])); - if (parent == null) - { - return results; - } - - collection = parent.Children; - } - - string lastSearch = searches[^1]; - - results = lastSearch switch - { - // Empty search so show all in collection - string search when string.IsNullOrWhiteSpace(search) - => EmptySearch(parent, collection), - - // Search by title - string search when search.StartsWith(Keywords.TitleSearch) && parent is not OneNotePage - => searchManager.TitleSearch(search, parent, collection), - - // Scoped search - string search when search.StartsWith(Keywords.ScopedSearch) && parent is OneNoteNotebook or OneNoteSectionGroup - => ScopedSearch(search, parent), - - // Default search - _ => Explorer(lastSearch, parent, collection), - }; - - if (parent != null) - { - var result = resultCreator.CreateOneNoteItemResult(parent, false, score: 4000); - result.Title = $"Open \"{parent.Name}\" in OneNote"; - result.SubTitle = lastSearch switch - { - string search when search.StartsWith(Keywords.TitleSearch) - => $"Now search by title in \"{parent.Name}\"", - - string search when search.StartsWith(Keywords.ScopedSearch) - => $"Now searching all pages in \"{parent.Name}\"", - - _ => $"Use \'{Keywords.ScopedSearch}\' to search this item. Use \'{Keywords.TitleSearch}\' to search by title in this item", - }; - - results.Add(result); - } - - return results; - } - - private List EmptySearch(IOneNoteItem parent, IEnumerable collection) - { - List results = collection.Where(searchManager.SettingsCheck) - .Select(item => resultCreator.CreateOneNoteItemResult(item, true)) - .ToList(); - if (results.Any()) - return results; - return resultCreator.NoItemsInCollection(results, parent); - } - - private List ScopedSearch(string query, IOneNoteItem parent) - { - if (query.Length == Keywords.ScopedSearch.Length) - { - return ResultCreator.NoMatchesFound(); - } - - if (!char.IsLetterOrDigit(query[Keywords.ScopedSearch.Length])) - { - return resultCreator.InvalidQuery(); - } - - string currentSearch = query[Keywords.TitleSearch.Length..]; - var results = new List(); - - results = OneNoteApplication.FindPages(currentSearch, parent) - .Select(pg => resultCreator.CreatePageResult(pg, currentSearch)) - .ToList(); - - if (!results.Any()) - { - results = ResultCreator.NoMatchesFound(); - } - - return results; - } -#nullable enable - private List Explorer(string search, IOneNoteItem? parent, IEnumerable collection) - { - List? highlightData = null; - int score = 0; - - var results = collection.Where(searchManager.SettingsCheck) - .Where(item => searchManager.FuzzySearch(item.Name, search, out highlightData, out score)) - .Select(item => resultCreator.CreateOneNoteItemResult(item, true, highlightData, score)) - .ToList(); - - AddCreateNewOneNoteItemResults(search, parent, results); - return results; - } - - private void AddCreateNewOneNoteItemResults(string newItemName, IOneNoteItem? parent, List results) - { - if (!results.Any(result => string.Equals(newItemName.Trim(), result.Title, StringComparison.OrdinalIgnoreCase))) - { - if (parent?.IsInRecycleBin() == true) - { - return; - } - - switch (parent) - { - case null: - results.Add(resultCreator.CreateNewNotebookResult(newItemName)); - break; - case OneNoteNotebook: - case OneNoteSectionGroup: - results.Add(resultCreator.CreateNewSectionResult(newItemName, parent)); - results.Add(resultCreator.CreateNewSectionGroupResult(newItemName, parent)); - break; - case OneNoteSection section: - if (!section.Locked) - { - results.Add(resultCreator.CreateNewPageResult(newItemName, section)); - } - - break; - } - } - } - } } } diff --git a/Flow.Launcher.Plugin.OneNote/UI/Styles.xaml b/Flow.Launcher.Plugin.OneNote/UI/Styles.xaml index bf94a1d..c5dc3ab 100644 --- a/Flow.Launcher.Plugin.OneNote/UI/Styles.xaml +++ b/Flow.Launcher.Plugin.OneNote/UI/Styles.xaml @@ -6,9 +6,9 @@ ## Contents @@ -26,6 +34,7 @@ A [OneNote](https://www.microsoft.com/en-gb/microsoft-365/onenote/digital-note-t - [Settings](#settings) - [Keywords](#keywords) - [Changelog](#changelog) +- [Additional Information](#additional-information) - [Acknowledgements](#acknowledgements) ## Installation @@ -37,12 +46,10 @@ pm install OneNote ``` > [!IMPORTANT] -> For [version 2.0+](#changelog) requires at Flow Launcher version 1.16+. For earlier versions see [releases](https://github.com/Odotocodot/Flow.Launcher.Plugin.OneNote/releases). - - -> [!IMPORTANT] -> This plugin is local only! It requires an installation of OneNote on you system! - +> +> - [Versions 2.0+](Changelog.md#200---2023-10-05) requires Flow Launcher version 1.16+. For earlier versions see [releases](https://github.com/Odotocodot/Flow.Launcher.Plugin.OneNote/releases). +> - This plugin is local only! It requires an installation of OneNote on you system! +> - Some features require Windows/Microsoft Search to be enabled on your system. See more info [here](#additional-information). ## Features @@ -215,7 +222,13 @@ All the keywords used can be changed according to user preference. See [here](Changelog.md) for the full list of changes. +## Additional Information + +In order to use [default](#default-search) and [scoped](#scoped-search) Windows/Microsoft Search must be enabled on your system. This is due to the [API](https://learn.microsoft.com/en-us/office/client-developer/onenote/application-interface-onenote#findpages-method) that these features rely on, requiring Windows Search. +This will only be an issue if you have explicit turned off Windows Search. +Other features should work as intended. + ## Acknowledgements - Made with [Linq2OneNote](https://github.com/Odotocodot/Linq2OneNote) a library for exposing the OneNote API also made by me :smiley: -- Inspired by the OneNote plugin for [PowerToys](https://github.com/microsoft/PowerToys/tree/main/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.OneNote) \ No newline at end of file +- Inspired by the OneNote plugin for [PowerToys](https://github.com/microsoft/PowerToys/tree/main/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.OneNote)