-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Updated command palette matching algorithm (#175)
- Suppressed `IDE0045: Convert to conditional expression`. ## Core - Added `VeryObservableCollection`, which listens changes in its children. - Renamed `KeybindManager` to `KeybindHook`, as its primary purpose is to listen to keyboard events. - Updated descriptiveness of `KeybindsMap`. - Removed `IKeybindManager`, as it's superfluous. - Updated the core to deal with `CommandItem` instead of `(ICommand, IKeybind?)`. - Updated `ICommandItems` to be `ICommandKeybindDictionary`. - Fixed renaming of a workspace. - Added a few tests for `Workspace`. ## Bar - The bar will show the updated name of a workspace. ## Palette - Ported [filters from Visual Studio Code](https://github.com/microsoft/vscode/blob/bd782eb059e133d3a20fdb446b8feb0010a278ad/src/vs/base/common/filters.ts) for text matching. - Removed `MostOftenUsedMatcher`. - The height, width, and y-position of the palette can be configured. - The palette can be activated in free text or menu mode. - Added a command to rename a workspace. - The palette no stays at its max height when there are less items than height. - Fixed styling binding issue.
- Loading branch information
Showing
61 changed files
with
1,764 additions
and
674 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
using Xunit; | ||
|
||
namespace Whim.CommandPalette.Tests; | ||
|
||
public class CamelCaseTests | ||
{ | ||
[InlineData("", "anything")] | ||
[InlineData("alpha", "alpha", new int[] { 0, 5 })] | ||
[InlineData("AlPhA", "alpha", new int[] { 0, 5 })] | ||
[InlineData("alpha", "alphasomething", new int[] { 0, 5 })] | ||
[InlineData("c", "CamelCaseRocks", new int[] { 0, 1 })] | ||
[InlineData("cc", "CamelCaseRocks", new int[] { 0, 1 }, new int[] { 5, 6 })] | ||
[InlineData("ccr", "CamelCaseRocks", new int[] { 0, 1 }, new int[] { 5, 6 }, new int[] { 9, 10 })] | ||
[InlineData("cacr", "CamelCaseRocks", new int[] { 0, 2 }, new int[] { 5, 6 }, new int[] { 9, 10 })] | ||
[InlineData("cacar", "CamelCaseRocks", new int[] { 0, 2 }, new int[] { 5, 7 }, new int[] { 9, 10 })] | ||
[InlineData("ccarocks", "CamelCaseRocks", new int[] { 0, 1 }, new int[] { 5, 7 }, new int[] { 9, 14 })] | ||
[InlineData("cr", "CamelCaseRocks", new int[] { 0, 1 }, new int[] { 9, 10 })] | ||
[InlineData("fba", "FooBarAbe", new int[] { 0, 1 }, new int[] { 3, 5 })] | ||
[InlineData("fbar", "FooBarAbe", new int[] { 0, 1 }, new int[] { 3, 6 })] | ||
[InlineData("fbara", "FooBarAbe", new int[] { 0, 1 }, new int[] { 3, 7 })] | ||
[InlineData("fbaa", "FooBarAbe", new int[] { 0, 1 }, new int[] { 3, 5 }, new int[] { 6, 7 })] | ||
[InlineData("fbaab", "FooBarAbe", new int[] { 0, 1 }, new int[] { 3, 5 }, new int[] { 6, 8 })] | ||
[InlineData("c2d", "canvasCreation2D", new int[] { 0, 1 }, new int[] { 14, 16 })] | ||
[InlineData("cce", "_canvasCreationEvent", new int[] { 1, 2 }, new int[] { 7, 8 }, new int[] { 15, 16 })] | ||
[InlineData("Debug Console", "Open: Debug Console", new int[] { 6, 19 })] | ||
[InlineData("Debug console", "Open: Debug Console", new int[] { 6, 19 })] | ||
[InlineData("debug console", "Open: Debug Console", new int[] { 6, 19 })] | ||
[Theory] | ||
public void MatchesCamelCase_Ok(string word, string wordToMatchAgainst, params int[][] expected) | ||
{ | ||
PaletteFilterTextMatch[] expectedMatches = FilterTestUtils.CreateExpectedMatches(expected); | ||
FilterTestUtils.FilterOk(PaletteFilters.MatchesCamelCase, word, wordToMatchAgainst, expectedMatches); | ||
} | ||
|
||
[InlineData("", "")] | ||
[InlineData("alpha", "alph")] | ||
[Theory] | ||
public void MatchesCamelCase_NotOk(string word, string wordToMatchAgainst) | ||
{ | ||
FilterTestUtils.FilterNotOk(PaletteFilters.MatchesCamelCase, word, wordToMatchAgainst); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
using Xunit; | ||
|
||
namespace Whim.CommandPalette.Tests; | ||
|
||
public class PrefixTests | ||
{ | ||
[InlineData("", "anything")] | ||
[InlineData("alpha", "alpha", new int[] { 0, 5 })] | ||
[InlineData("alpha", "alphasomething", new int[] { 0, 5 })] | ||
[InlineData("a", "alpha", new int[] { 0, 1 })] | ||
[Theory] | ||
public void MatchesStrictPrefix_Ok(string word, string wordToMatchAgainst, params int[][] expected) | ||
{ | ||
PaletteFilterTextMatch[] expectedMatches = FilterTestUtils.CreateExpectedMatches(expected); | ||
FilterTestUtils.FilterOk(PaletteFilters.MatchesStrictPrefix, word, wordToMatchAgainst, expectedMatches); | ||
} | ||
|
||
[InlineData("", "")] | ||
[InlineData("alpha", "alp")] | ||
[InlineData("x", "alpha")] | ||
[InlineData("A", "alpha")] | ||
[InlineData("AlPh", "alPHA")] | ||
[Theory] | ||
public void MatchesStrictPrefix_NotOk(string word, string wordToMatchAgainst) | ||
{ | ||
FilterTestUtils.FilterNotOk(PaletteFilters.MatchesStrictPrefix, word, wordToMatchAgainst); | ||
} | ||
|
||
[InlineData("alpha", "alpha", new int[] { 0, 5 })] | ||
[InlineData("alpha", "alphasomething", new int[] { 0, 5 })] | ||
[InlineData("a", "alpha", new int[] { 0, 1 })] | ||
[InlineData("ä", "Älpha", new int[] { 0, 1 })] | ||
[InlineData("A", "alpha", new int[] { 0, 1 })] | ||
[InlineData("AlPh", "alPHA", new int[] { 0, 4 })] | ||
[Theory] | ||
public void MatchesPrefix_Ok(string word, string wordToMatchAgainst, params int[][] expected) | ||
{ | ||
PaletteFilterTextMatch[] expectedMatches = FilterTestUtils.CreateExpectedMatches(expected); | ||
FilterTestUtils.FilterOk(PaletteFilters.MatchesPrefix, word, wordToMatchAgainst, expectedMatches); | ||
} | ||
|
||
[InlineData("alpha", "alp")] | ||
[InlineData("x", "alpha")] | ||
[InlineData("T", "4")] | ||
[Theory] | ||
public void MatchesPrefix_NotOk(string word, string wordToMatchAgainst) | ||
{ | ||
FilterTestUtils.FilterNotOk(PaletteFilters.MatchesPrefix, word, wordToMatchAgainst); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
using Xunit; | ||
|
||
namespace Whim.CommandPalette.Tests; | ||
|
||
public class SubstringTests | ||
{ | ||
[InlineData("cela", "cancelAnimationFrame()", new int[] { 3, 7 })] | ||
[Theory] | ||
public void MatchesContiguousSubString_Ok(string word, string wordToMatchAgainst, params int[][] expected) | ||
{ | ||
PaletteFilterTextMatch[] expectedMatches = FilterTestUtils.CreateExpectedMatches(expected); | ||
FilterTestUtils.FilterOk(PaletteFilters.MatchesContiguousSubString, word, wordToMatchAgainst, expectedMatches); | ||
} | ||
|
||
[InlineData("cmm", "cancelAnimationFrame()", new int[] { 0, 1 }, new int[] { 9, 10 }, new int[] { 18, 19 })] | ||
[InlineData("abc", "abcabc", new int[] { 0, 3 })] | ||
[InlineData("abc", "aaabbbccc", new int[] { 0, 1 }, new int[] { 3, 4 }, new int[] { 6, 7 })] | ||
[Theory] | ||
public void MatchesSubString_Ok(string word, string wordToMatchAgainst, params int[][] expected) | ||
{ | ||
PaletteFilterTextMatch[] expectedMatches = FilterTestUtils.CreateExpectedMatches(expected); | ||
FilterTestUtils.FilterOk(PaletteFilters.MatchesSubString, word, wordToMatchAgainst, expectedMatches); | ||
} | ||
|
||
[InlineData("aaaaaaaaaaaaaaaaaaaax", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")] | ||
[Theory] | ||
public void MatchesSubString_NotOk(string word, string wordToMatchAgainst) | ||
{ | ||
FilterTestUtils.FilterNotOk(PaletteFilters.MatchesSubString, word, wordToMatchAgainst); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
using Xunit; | ||
|
||
namespace Whim.CommandPalette.Tests; | ||
|
||
public static class FilterTestUtils | ||
{ | ||
public static void FilterOk(PaletteFilter filter, string word, string wordToMatchAgainst, PaletteFilterTextMatch[]? expectedMatches = null) | ||
{ | ||
PaletteFilterTextMatch[]? actualMatches = filter(word, wordToMatchAgainst); | ||
|
||
if (expectedMatches == null) | ||
{ | ||
Assert.Null(actualMatches); | ||
return; | ||
} | ||
|
||
Assert.NotNull(actualMatches); | ||
Assert.Equal(expectedMatches.Length, actualMatches!.Length); | ||
for (int i = 0; i < expectedMatches.Length; i++) | ||
{ | ||
PaletteFilterTextMatch expected = expectedMatches[i]; | ||
PaletteFilterTextMatch actual = actualMatches[i]; | ||
|
||
Assert.Equal(expected.Start, actual.Start); | ||
Assert.Equal(expected.End, actual.End); | ||
} | ||
} | ||
|
||
public static void FilterNotOk(PaletteFilter filter, string word, string wordToMatchAgainst) | ||
{ | ||
FilterOk(filter, word, wordToMatchAgainst, null); | ||
} | ||
|
||
public static PaletteFilterTextMatch[] CreateExpectedMatches(params int[][] expected) | ||
{ | ||
PaletteFilterTextMatch[] result = new PaletteFilterTextMatch[expected.Length]; | ||
for (int i = 0; i < expected.Length; i++) | ||
{ | ||
int[] pair = expected[i]; | ||
result[i] = new PaletteFilterTextMatch(pair[0], pair[1]); | ||
} | ||
return result; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
using Xunit; | ||
|
||
namespace Whim.CommandPalette.Tests; | ||
|
||
public class UtilsTests | ||
{ | ||
private static PaletteFilter NewFilter(int[] counters, int i, bool r) | ||
{ | ||
return (string word, string wordToMatchAgainst) => | ||
{ | ||
counters[i]++; | ||
return r ? new[] { new PaletteFilterTextMatch(0, word.Length) } : null; | ||
}; | ||
} | ||
|
||
[InlineData(0, true, 1, false, new int[] { 1, 0 })] | ||
[InlineData(0, true, 1, true, new int[] { 1, 0 })] | ||
[InlineData(0, false, 1, true, new int[] { 1, 1 })] | ||
[Theory] | ||
public void Or(int i1, bool r1, int i2, bool r2, int[] expected) | ||
{ | ||
int[] counters = new int[2]; | ||
PaletteFilter filter = PaletteFilters.Or(NewFilter(counters, i1, r1), NewFilter(counters, i2, r2)); | ||
FilterTestUtils.FilterOk(filter, "anything", "anything", new PaletteFilterTextMatch[] { new PaletteFilterTextMatch(0, 8) }); | ||
Assert.Equal(expected, counters); | ||
} | ||
|
||
[InlineData(0, false, 1, false, new int[] { 1, 1 })] | ||
[Theory] | ||
public void Or_NotOk(int i1, bool r1, int i2, bool r2, int[] expected) | ||
{ | ||
int[] counters = new int[2]; | ||
PaletteFilter filter = PaletteFilters.Or(NewFilter(counters, i1, r1), NewFilter(counters, i2, r2)); | ||
FilterTestUtils.FilterNotOk(filter, "anything", "anything"); | ||
Assert.Equal(expected, counters); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
using Xunit; | ||
|
||
namespace Whim.CommandPalette.Tests; | ||
|
||
public class WordsTests | ||
{ | ||
[InlineData("alpha", "alpha", new int[] { 0, 5 })] | ||
[InlineData("alpha", "alphasomething", new int[] { 0, 5 })] | ||
[InlineData("a", "alpha", new int[] { 0, 1 })] | ||
[InlineData("A", "alpha", new int[] { 0, 1 })] | ||
[InlineData("AlPh", "alPHA", new int[] { 0, 4 })] | ||
[InlineData("gp", "Git: Pull", new int[] { 0, 1 }, new int[] { 5, 6 })] | ||
[InlineData("g p", "Git: Pull", new int[] { 0, 1 }, new int[] { 5, 6 })] | ||
[InlineData("gipu", "Git: Pull", new int[] { 0, 2 }, new int[] { 5, 7 })] | ||
[InlineData("gp", "Category: Git: Pull", new int[] { 10, 11 }, new int[] { 15, 16 })] | ||
[InlineData("g p", "Category: Git: Pull", new int[] { 10, 11 }, new int[] { 15, 16 })] | ||
[InlineData("gipu", "Category: Git: Pull", new int[] { 10, 12 }, new int[] { 15, 17 })] | ||
[InlineData("git: プル", "git: プル", new int[] { 0, 7 })] | ||
[InlineData("git プル", "git: プル", new int[] { 0, 3 }, new int[] { 5, 7 })] | ||
[InlineData("öäk", "Öhm: Älles Klar", new int[] { 0, 1 }, new int[] { 5, 6 }, new int[] { 11, 12 })] | ||
[InlineData("C++", "C/C++: command", new int[] { 2, 5 })] | ||
[InlineData(".", ":")] | ||
[InlineData(".", ".", new int[] { 0, 1 })] | ||
[InlineData("bar", "foo-bar", new int[] { 4, 7 })] | ||
[InlineData("bar test", "foo-bar test", new int[] { 4, 12 })] | ||
[InlineData("fbt", "foo-bar test", new int[] { 0, 1 }, new int[] { 4, 5 }, new int[] { 8, 9 })] | ||
[InlineData("bar test", "foo-bar (test)", new int[] { 4, 8 }, new int[] { 9, 13 })] | ||
[InlineData("foo bar", "foo (bar)", new int[] { 0, 4 }, new int[] { 5, 8 })] | ||
[InlineData("foo bar", "foo-bar", new int[] { 0, 3 }, new int[] { 4, 7 })] | ||
[InlineData("foo bar", "123 foo-bar 456", new int[] { 4, 7 }, new int[] { 8, 11 })] | ||
[InlineData("foo-bar", "foo bar", new int[] { 0, 3 }, new int[] { 4, 7 })] | ||
[InlineData("foo:bar", "foo:bar", new int[] { 0, 7 })] | ||
[Theory] | ||
public void MatchesWordsSeparate_Ok(string query, string target, params int[][] expected) | ||
{ | ||
PaletteFilterTextMatch[] expectedMatches = FilterTestUtils.CreateExpectedMatches(expected); | ||
FilterTestUtils.FilterOk(PaletteFilters.MatchesWordsSeparate, query, target, expectedMatches); | ||
} | ||
|
||
[InlineData("alpha", "alp")] | ||
[InlineData("x", "alpha")] | ||
[InlineData("it", "Git: Pull")] | ||
[InlineData("ll", "Git: Pull")] | ||
[InlineData("bar est", "foo-bar test")] | ||
[InlineData("fo ar", "foo-bar test")] | ||
[InlineData("for", "foo-bar test")] | ||
[Theory] | ||
public void MatchesWordsSeparate_NotOk(string query, string target) | ||
{ | ||
FilterTestUtils.FilterNotOk(PaletteFilters.MatchesWordsSeparate, query, target); | ||
} | ||
|
||
[InlineData("pu", "Category: Git: Pull", new int[] { 15, 17 })] | ||
[Theory] | ||
public void MatchesWordsContiguous_Ok(string query, string target, params int[][] expected) | ||
{ | ||
PaletteFilterTextMatch[] expectedMatches = FilterTestUtils.CreateExpectedMatches(expected); | ||
FilterTestUtils.FilterOk(PaletteFilters.MatchesWordsContiguous, query, target, expectedMatches); | ||
} | ||
|
||
[InlineData("gipu", "Category: Git: Pull")] | ||
[Theory] | ||
public void MatchesWordsContiguous_NotOk(string query, string target) | ||
{ | ||
FilterTestUtils.FilterNotOk(PaletteFilters.MatchesWordsContiguous, query, target); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.