Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
eef6142
rename `DefaultSearch` to `StandardSearch`
Odotocodot Mar 18, 2026
08b7f46
refactor standard and scope search
Odotocodot Mar 18, 2026
d68eb89
refactor notebook explorer
Odotocodot Mar 18, 2026
568c3b5
add sort by last modified
Odotocodot Mar 19, 2026
aaaaec6
Style changes
Odotocodot Mar 26, 2026
c312877
Fix incorrect sorting
Odotocodot Mar 27, 2026
c321430
Allow recent pages to be searchable
Odotocodot Mar 27, 2026
f8e147c
Move keyword check and sorting
Odotocodot Mar 30, 2026
26bcead
wip: refactor Search manager again
Odotocodot Apr 11, 2026
5f486de
wip: refactor make SearchData mutable
Odotocodot Apr 11, 2026
f47bab8
wip: finish search functions
Odotocodot Apr 11, 2026
17f1934
Fixes to the refactor
Odotocodot Apr 11, 2026
078bb61
fix incorrect results in `NotebookExplorer`
Odotocodot Apr 11, 2026
7539029
Fix notebooks not sorting
Odotocodot Apr 12, 2026
7ee9bd0
Refactor again
Odotocodot Apr 13, 2026
66ac6a2
Implement the search rework
Odotocodot Apr 13, 2026
c7c9306
Refactor keywords
Odotocodot Apr 13, 2026
fae4396
Refactor all of search
Odotocodot Apr 13, 2026
cdc9629
Add the to limit max number of results, remove default recent pages c…
Odotocodot Apr 13, 2026
da4ff24
Renamed `RecentPages` to `SortByLastModified`
Odotocodot Apr 14, 2026
039771f
Update changelog, readme and plugin.json
Odotocodot Apr 25, 2026
442ffc9
Merge pull request #41 from Odotocodot/feature/recently-modified
Odotocodot Apr 25, 2026
d541fa7
Added setting to allow users to always open items in a new OneNote wi…
Odotocodot Apr 25, 2026
f9a24a2
Tweaks and cleanup
Odotocodot Apr 25, 2026
cd3b09c
Update logo and doc images
Odotocodot Apr 25, 2026
2fd0df5
Update Changelog.md and Readme.md
Odotocodot Apr 25, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -354,3 +354,4 @@ MigrationBackup/
#VSCode
.vscode/
.idea/
*.lscache
15 changes: 14 additions & 1 deletion Changelog.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,24 @@
# Changelog

## 3.1.0

- :star: **Recent pages** is dead, long live **sort by last modified**. ([#32](https://github.com/Odotocodot/Flow.Launcher.Plugin.OneNote/issues/32))
- Using the **sort by last modified** keyword, as the name implies, allows you to sort results by last modified. But unlike **recent pages** you can now use it in multiple places, i.e. with **title search**, **scoped search** and **notebook explorer**. Note it must be placed after the aforementioned keywords.
- Examples:\
(`#` = **sort by last modified** keyword, `*` = **title search** keyword, `nb:\` = **notebook explorer** keyword, `>` = **scoped search** keyword)
- ```on #{your search query}```
- ```on *#{your search query}```
- ```on nb:\PathToItem\#{your search query}```
- ```on nb:\PathToItem\>#{your search query}```
- ```on nb:\PathToItem\*#{your search query}```
- Added a setting to allow users to always open items in a new OneNote window. ([#40](https://github.com/Odotocodot/Flow.Launcher.Plugin.OneNote/issues/40))

## 3.0.1 - 2026-03-13

- Fix crash on quick note with empty title (Updated to `LinqToOneNote-2.1.1`)
- Fix incorrect **scope search** check
- Cache OneNote hierarchy when applicable
- This brings the performance improvement for Notebook Explorer from last version to **recent pages** and **title search**
- This brings the performance improvement from **notebook explorer** from last version to **recent pages** and **title search**

## 3.0.0 - 2026-03-04

Expand Down
35 changes: 16 additions & 19 deletions Flow.Launcher.Plugin.OneNote/Icons/IconGeneratorInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,30 +3,27 @@

namespace Flow.Launcher.Plugin.OneNote.Icons
{
public struct IconGeneratorInfo
public readonly struct IconGeneratorInfo
{
public readonly string prefix = string.Empty;
public readonly Color? color;

public IconGeneratorInfo(IOneNoteItem item)

private IconGeneratorInfo(string prefix, Color? color = null)
{
this.prefix = prefix;
this.color = color;
}

public static IconGeneratorInfo Create(IOneNoteItem item)
{
switch (item)
return item switch
{
case Notebook n:
prefix = IconConstants.Notebook;
color = n.Color;
break;
case SectionGroup sg:
prefix = sg.IsRecycleBin ? IconConstants.RecycleBin : IconConstants.SectionGroup;
break;
case Section s:
prefix = IconConstants.Section;
color = s.Color;
break;
case Page:
prefix = IconConstants.Page;
break;
}
Notebook n => new (IconConstants.Notebook, n.Color),
SectionGroup sg => new (sg.IsRecycleBin ? IconConstants.RecycleBin : IconConstants.SectionGroup),
Section s => new (IconConstants.Section, s.Color),
Page => new (IconConstants.Page),
_ => new (),
};
}
}
}
Binary file modified Flow.Launcher.Plugin.OneNote/Images/logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
22 changes: 11 additions & 11 deletions Flow.Launcher.Plugin.OneNote/Keywords.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,26 +8,27 @@ namespace Flow.Launcher.Plugin.OneNote
public class Keywords
{
public const string NotebookExplorerSeparator = "\\";
public Keyword NotebookExplorer { get; set; } = new($"nb:{NotebookExplorerSeparator}");
public Keyword RecentPages { get; set; } = new ("rp:");
public Keyword TitleSearch { get; set; } = new ("*");
public Keyword ScopedSearch { get; set; } = new (">");

public Keyword NotebookExplorer { get; init; } = new($"nb:{NotebookExplorerSeparator}");
[JsonPropertyName("RecentPages")]
public Keyword SortByLastModified { get; init; } = new ("rp:");
public Keyword TitleSearch { get; init; } = new ("*");
public Keyword ScopedSearch { get; init; } = new (">");

private Keyword[]? keywords;
[JsonIgnore]
public Keyword[] All => keywords ??= [NotebookExplorer, SortByLastModified, TitleSearch, ScopedSearch];
}

[JsonConverter(typeof(KeywordJsonConverter))]
public class Keyword
public class Keyword(string value)
{
public Keyword(string value) => Value = value;
public string Value { get; private set; }
public string Value { get; private set; } = value;

public void ChangeKeyword(string newValue) => Value = newValue;

public int Length => Value.Length;
public static implicit operator string(Keyword keyword) => keyword.Value;
public override string ToString() => Value;

public static Keyword Empty { get; } = new ("");
}

//Needed for legacy as keywords where just saved as a string
Expand All @@ -39,5 +40,4 @@ public override Keyword Read(ref Utf8JsonReader reader, Type typeToConvert, Json
public override void Write(Utf8JsonWriter writer, Keyword value, JsonSerializerOptions options)
=> JsonSerializer.Serialize(writer, value.Value, options);
}

}
72 changes: 37 additions & 35 deletions Flow.Launcher.Plugin.OneNote/ResultCreator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,12 @@

namespace Flow.Launcher.Plugin.OneNote
{
public class ResultCreator
public class ResultCreator(PluginInitContext context, Settings settings, IconProvider iconProvider)
{
private readonly PluginInitContext context;
private readonly Settings settings;
private readonly IconProvider iconProvider;

private const string PathSeparator = " > ";
private const string BulletPoint = "\u2022 ";
private const string TrianglePoint = "\u2023 ";
private string ActionKeyword => context.CurrentPluginMetadata.ActionKeyword;
public ResultCreator(PluginInitContext context, Settings settings, IconProvider iconProvider)
{
this.settings = settings;
this.iconProvider = iconProvider;
this.context = context;
}

private static string GetNicePath(IOneNoteItem item, string separator = PathSeparator) => item.GetRelativePath(false, separator);

Expand Down Expand Up @@ -84,14 +74,14 @@ public List<Result> EmptyQuery()
new Result
{
Title = "See recent pages",
SubTitle = $"Type \"{settings.Keywords.RecentPages}\" or select this option to see recently modified pages",
AutoCompleteText = $"{ActionKeyword} {settings.Keywords.RecentPages}",
SubTitle = $"Type \"{settings.Keywords.SortByLastModified}\" or select this option to see recently modified pages",
AutoCompleteText = $"{ActionKeyword} {settings.Keywords.SortByLastModified}",
IcoPath = iconProvider.Recent,
AddSelectedCount = false,
Score = -1000,
Action = _ =>
{
context.API.ChangeQuery($"{ActionKeyword} {settings.Keywords.RecentPages}", true);
context.API.ChangeQuery($"{ActionKeyword} {settings.Keywords.SortByLastModified}", true);
return false;
},
},
Expand All @@ -104,7 +94,7 @@ public List<Result> EmptyQuery()
PreviewPanel = GetNewPagePreviewPanel(null, null),
Action = _ =>
{
OneNoteApp.CreateQuickNote(OpenMode.ExistingOrNewWindow);
OneNoteApp.CreateQuickNote(settings.AlwaysOpenInNewWindow ? OpenMode.NewWindow : OpenMode.ExistingOrNewWindow);
WindowHelper.FocusOneNote();
return true;
},
Expand Down Expand Up @@ -142,7 +132,7 @@ public Result CreateOneNoteItemResult(IOneNoteItem item, bool actionIsAutoComple
var toolTip = string.Empty;
var subTitle = GetNicePath(item);
var autoCompleteText = GetAutoCompleteText(item);
var iconInfo = new IconGeneratorInfo(item);
var iconInfo = IconGeneratorInfo.Create(item);

switch (item)
{
Expand Down Expand Up @@ -213,27 +203,27 @@ public Result CreateOneNoteItemResult(IOneNoteItem item, bool actionIsAutoComple
await Task.Run(() =>
{
item.Sync();
item.Open();
OneNoteApp.Open(item, settings.AlwaysOpenInNewWindow);
});
WindowHelper.FocusOneNote();
return true;
},
};
}

public Result CreatePageResult(Page page, string query)
=> CreateOneNoteItemResult(page, false, string.IsNullOrWhiteSpace(query) ? null : context.API.FuzzySearch(query, page.Name).MatchData);

public Result CreateRecentPageResult(Page page)
public Result CreateRecentItemResult(IOneNoteItem item, bool actionIsAutoComplete, List<int>? highlightData = null)
{
var result = CreateOneNoteItemResult(page, false);
result.SubTitle = $"{page.LastModified.Humanize()} | {result.SubTitle}";
result.IcoPath = iconProvider.Recent;
var result = CreateOneNoteItemResult(item, actionIsAutoComplete, highlightData);
result.SubTitle = string.IsNullOrWhiteSpace(result.SubTitle)
? $"{item.LastModified.Humanize()}"
: $"{item.LastModified.Humanize()} | {result.SubTitle}";
if(item is Page)
result.IcoPath = iconProvider.Recent;
result.AddSelectedCount = false;
return result;
}

//When name can have invalid chars
//When new name can have invalid chars
private Result CreateNewItemResult<TNew, TParent>(string newName, TParent? parent, string iconPath, Func<TParent?, string, OpenMode, TNew> createFunc)
where TNew : IOneNoteItem, INameInvalidCharacters
where TParent : IOneNoteItem
Expand Down Expand Up @@ -261,7 +251,10 @@ private Result CreateNewItemResult<TNew, TParent>(string newName, TParent? paren
return false;

bool showOneNote = !c.SpecialKeyState.CtrlPressed;
createFunc(parent, newName, showOneNote ? OpenMode.ExistingOrNewWindow : OpenMode.None);
bool newWindow = settings.AlwaysOpenInNewWindow;

OpenMode openMode = showOneNote ? newWindow ? OpenMode.NewWindow : OpenMode.ExistingOrNewWindow : OpenMode.None;
createFunc(parent, newName, openMode);

context.API.ReQuery();

Expand Down Expand Up @@ -291,18 +284,27 @@ public List<Result> ContextMenu(Result selectedResult)
var results = new List<Result>();
if (selectedResult.ContextData is IOneNoteItem item)
{
var result = CreateOneNoteItemResult(item, false);
result.Title = $"Open and sync \"{item.Name}\"";
result.SubTitle = string.Empty;
result.Score = 30;
result.AddSelectedCount = false;
result.ContextData = null;
results.Add(result);
Result.IconDelegate icon = iconProvider.GetIcon(IconGeneratorInfo.Create(item));
results.Add(new Result
{
Title = $"Open and sync \"{item.Name}\"",
Icon = icon,
Score = 30,
AddSelectedCount = false,
Action = _ =>
{
OneNoteApp.Open(item);
OneNoteApp.SyncItem(item);
WindowHelper.FocusOneNote();
return true;
}
});


results.Add(new Result
{
Title = $"Open \"{item.Name}\" in new OneNote window",
Icon = result.Icon,
Icon = icon,
Score = 20,
AddSelectedCount = false,
Action = _ =>
Expand Down Expand Up @@ -381,7 +383,7 @@ Result EmptyCollectionResult(string title, string iconPath, string? subTitle = n
}

private Lazy<System.Windows.Controls.UserControl> GetNewPagePreviewPanel(Section? section, string? pageTitle)
=> new(() => new NewOneNotePagePreviewPanel(context, section, pageTitle));
=> new(() => new NewOneNotePagePreviewPanel(context, settings, section, pageTitle));

public static List<Result> NoMatchesFound()
{
Expand Down
23 changes: 0 additions & 23 deletions Flow.Launcher.Plugin.OneNote/Search/DefaultSearch.cs

This file was deleted.

Loading
Loading