Fuzzy matching instead of startsWith for filtering

Experimental, subject to change
This commit is contained in:
WebFreak001 2023-03-20 04:03:17 +01:00
parent c324b60da3
commit d6376c4881
No known key found for this signature in database
GPG Key ID: AEFC88D11109D1AA
11 changed files with 41 additions and 8 deletions

View File

@ -7,6 +7,7 @@
"targetType": "library",
"dependencies": {
"libdparse": ">=0.20.0 <1.0.0",
"emsi_containers": "~>0.9.0"
"emsi_containers": "~>0.9.0",
"fuzzymatch": "~>1.0"
}
}

View File

@ -231,12 +231,12 @@ private DSymbol*[] getUFCSSymbolsForDotCompletion(const(DSymbol)* symbolType, Sc
// local appender
FilteredAppender!((DSymbol* a) =>
a.isCallableWithArg(symbolType)
&& toUpper(a.name.data).startsWith(toUpper(partial)),
&& prettyFuzzyMatch(a.name.data, partial),
DSymbol*[]) localAppender;
// global appender
FilteredAppender!((DSymbol* a) =>
a.isCallableWithArg(symbolType, true)
&& toUpper(a.name.data).startsWith(toUpper(partial)),
&& prettyFuzzyMatch(a.name.data, partial),
DSymbol*[]) globalAppender;
getUFCSSymbols(localAppender, globalAppender, completionScope, cursorPosition);

View File

@ -153,3 +153,19 @@ unittest
i = skipParenReverseBefore(t, i, tok!")", tok!"(");
assert(i == 1);
}
/// Checks if `doesThis` roughly starts with `matchThis`, case-insensitive
bool prettyFuzzyMatch(scope const(char)[] doesThis, scope const(char)[] matchThis) @safe pure nothrow @nogc
{
import fuzzymatch;
if (!matchThis.length)
return true;
// return false if identifier starts with _, but search doesn't or vice-versa
if (doesThis.length && (doesThis[0] == '_' && matchThis[0] != '_'
|| doesThis[0] != '_' && matchThis[0] == '_'))
return false;
return fuzzyMatchesString(doesThis, matchThis);
}

View File

@ -3,6 +3,7 @@
"versions": {
"dsymbol": "0.14.1",
"emsi_containers": "0.9.0",
"fuzzymatch": "1.0.0",
"libdparse": "0.22.0",
"msgpack-d": "1.0.4",
"stdx-allocator": "2.77.5"

View File

@ -188,7 +188,6 @@ AutocompleteResponse dotCompletion(T)(T beforeTokens, const(Token)[] tokenArray,
{
partial = t.text[0 .. cursorPosition - t.index];
// issue 442 - prevent `partial` to start in the middle of a MBC
// since later there's a non-nothrow call to `toUpper`
import std.utf : validate, UTFException;
try validate(partial);
catch (UTFException)
@ -513,7 +512,7 @@ void setCompletions(T)(ref AutocompleteResponse response,
foreach (sym; s.opSlice())
{
if (sym.name !is null && sym.name.length > 0 && isPublicCompletionKind(sym.kind)
&& (p is null ? true : toUpper(sym.name.data).startsWith(toUpper(p)))
&& prettyFuzzyMatch(sym.name.data, p)
&& !r.completions.canFind!(a => a.identifier == sym.name)
&& sym.name[0] != '*'
&& mightBeRelevantInCompletionScope(sym, completionScope))
@ -531,7 +530,7 @@ void setCompletions(T)(ref AutocompleteResponse response,
{
auto currentSymbols = completionScope.getSymbolsInCursorScope(cursorPosition);
foreach (s; currentSymbols.filter!(a => isPublicCompletionKind(a.kind)
&& toUpper(a.name.data).startsWith(toUpper(partial))
&& prettyFuzzyMatch(a.name.data, partial)
&& mightBeRelevantInCompletionScope(a, completionScope)))
{
response.completions ~= makeSymbolCompletionInfo(s, s.kind);
@ -549,8 +548,7 @@ void setCompletions(T)(ref AutocompleteResponse response,
&& a.kind != CompletionKind.importSymbol
&& a.kind != CompletionKind.dummy
&& a.symbolFile == "stdin"
&& (partial !is null && toUpper(a.name.data).startsWith(toUpper(partial))
|| partial is null)
&& prettyFuzzyMatch(a.name.data, partial)
&& mightBeRelevantInCompletionScope(a, completionScope)))
{
response.completions ~= makeSymbolCompletionInfo(s, s.kind);

View File

@ -3,3 +3,6 @@ idouble k
ifloat k
int k
ireal k
string l
uint k
void k

View File

@ -6,3 +6,6 @@ cfloat k
char k
complicatedLess l
creal k
dchar k
ucent k
wchar k

View File

@ -1,3 +1,5 @@
identifiers
Foo s
cfloat k
float k
ifloat k

View File

@ -1,2 +1,7 @@
identifiers
alignof k
foo f
mangleof k
sizeof k
stringof k
tupleof k

View File

@ -1,2 +1,3 @@
identifiers
init k
internal v

View File

@ -1,3 +1,6 @@
identifiers
cfloat k cfloat
float k float
foo f void foo() stdin 26 my documentation void
foo f void foo(int i) stdin 49 my documentation void
ifloat k ifloat