Fuzzy matching instead of startsWith for filtering
Experimental, subject to change
This commit is contained in:
parent
c324b60da3
commit
d6376c4881
|
|
@ -7,6 +7,7 @@
|
||||||
"targetType": "library",
|
"targetType": "library",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"libdparse": ">=0.20.0 <1.0.0",
|
"libdparse": ">=0.20.0 <1.0.0",
|
||||||
"emsi_containers": "~>0.9.0"
|
"emsi_containers": "~>0.9.0",
|
||||||
|
"fuzzymatch": "~>1.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -231,12 +231,12 @@ private DSymbol*[] getUFCSSymbolsForDotCompletion(const(DSymbol)* symbolType, Sc
|
||||||
// local appender
|
// local appender
|
||||||
FilteredAppender!((DSymbol* a) =>
|
FilteredAppender!((DSymbol* a) =>
|
||||||
a.isCallableWithArg(symbolType)
|
a.isCallableWithArg(symbolType)
|
||||||
&& toUpper(a.name.data).startsWith(toUpper(partial)),
|
&& prettyFuzzyMatch(a.name.data, partial),
|
||||||
DSymbol*[]) localAppender;
|
DSymbol*[]) localAppender;
|
||||||
// global appender
|
// global appender
|
||||||
FilteredAppender!((DSymbol* a) =>
|
FilteredAppender!((DSymbol* a) =>
|
||||||
a.isCallableWithArg(symbolType, true)
|
a.isCallableWithArg(symbolType, true)
|
||||||
&& toUpper(a.name.data).startsWith(toUpper(partial)),
|
&& prettyFuzzyMatch(a.name.data, partial),
|
||||||
DSymbol*[]) globalAppender;
|
DSymbol*[]) globalAppender;
|
||||||
|
|
||||||
getUFCSSymbols(localAppender, globalAppender, completionScope, cursorPosition);
|
getUFCSSymbols(localAppender, globalAppender, completionScope, cursorPosition);
|
||||||
|
|
|
||||||
|
|
@ -153,3 +153,19 @@ unittest
|
||||||
i = skipParenReverseBefore(t, i, tok!")", tok!"(");
|
i = skipParenReverseBefore(t, i, tok!")", tok!"(");
|
||||||
assert(i == 1);
|
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);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
"versions": {
|
"versions": {
|
||||||
"dsymbol": "0.14.1",
|
"dsymbol": "0.14.1",
|
||||||
"emsi_containers": "0.9.0",
|
"emsi_containers": "0.9.0",
|
||||||
|
"fuzzymatch": "1.0.0",
|
||||||
"libdparse": "0.22.0",
|
"libdparse": "0.22.0",
|
||||||
"msgpack-d": "1.0.4",
|
"msgpack-d": "1.0.4",
|
||||||
"stdx-allocator": "2.77.5"
|
"stdx-allocator": "2.77.5"
|
||||||
|
|
|
||||||
|
|
@ -188,7 +188,6 @@ AutocompleteResponse dotCompletion(T)(T beforeTokens, const(Token)[] tokenArray,
|
||||||
{
|
{
|
||||||
partial = t.text[0 .. cursorPosition - t.index];
|
partial = t.text[0 .. cursorPosition - t.index];
|
||||||
// issue 442 - prevent `partial` to start in the middle of a MBC
|
// 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;
|
import std.utf : validate, UTFException;
|
||||||
try validate(partial);
|
try validate(partial);
|
||||||
catch (UTFException)
|
catch (UTFException)
|
||||||
|
|
@ -513,7 +512,7 @@ void setCompletions(T)(ref AutocompleteResponse response,
|
||||||
foreach (sym; s.opSlice())
|
foreach (sym; s.opSlice())
|
||||||
{
|
{
|
||||||
if (sym.name !is null && sym.name.length > 0 && isPublicCompletionKind(sym.kind)
|
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)
|
&& !r.completions.canFind!(a => a.identifier == sym.name)
|
||||||
&& sym.name[0] != '*'
|
&& sym.name[0] != '*'
|
||||||
&& mightBeRelevantInCompletionScope(sym, completionScope))
|
&& mightBeRelevantInCompletionScope(sym, completionScope))
|
||||||
|
|
@ -531,7 +530,7 @@ void setCompletions(T)(ref AutocompleteResponse response,
|
||||||
{
|
{
|
||||||
auto currentSymbols = completionScope.getSymbolsInCursorScope(cursorPosition);
|
auto currentSymbols = completionScope.getSymbolsInCursorScope(cursorPosition);
|
||||||
foreach (s; currentSymbols.filter!(a => isPublicCompletionKind(a.kind)
|
foreach (s; currentSymbols.filter!(a => isPublicCompletionKind(a.kind)
|
||||||
&& toUpper(a.name.data).startsWith(toUpper(partial))
|
&& prettyFuzzyMatch(a.name.data, partial)
|
||||||
&& mightBeRelevantInCompletionScope(a, completionScope)))
|
&& mightBeRelevantInCompletionScope(a, completionScope)))
|
||||||
{
|
{
|
||||||
response.completions ~= makeSymbolCompletionInfo(s, s.kind);
|
response.completions ~= makeSymbolCompletionInfo(s, s.kind);
|
||||||
|
|
@ -549,8 +548,7 @@ void setCompletions(T)(ref AutocompleteResponse response,
|
||||||
&& a.kind != CompletionKind.importSymbol
|
&& a.kind != CompletionKind.importSymbol
|
||||||
&& a.kind != CompletionKind.dummy
|
&& a.kind != CompletionKind.dummy
|
||||||
&& a.symbolFile == "stdin"
|
&& a.symbolFile == "stdin"
|
||||||
&& (partial !is null && toUpper(a.name.data).startsWith(toUpper(partial))
|
&& prettyFuzzyMatch(a.name.data, partial)
|
||||||
|| partial is null)
|
|
||||||
&& mightBeRelevantInCompletionScope(a, completionScope)))
|
&& mightBeRelevantInCompletionScope(a, completionScope)))
|
||||||
{
|
{
|
||||||
response.completions ~= makeSymbolCompletionInfo(s, s.kind);
|
response.completions ~= makeSymbolCompletionInfo(s, s.kind);
|
||||||
|
|
|
||||||
|
|
@ -3,3 +3,6 @@ idouble k
|
||||||
ifloat k
|
ifloat k
|
||||||
int k
|
int k
|
||||||
ireal k
|
ireal k
|
||||||
|
string l
|
||||||
|
uint k
|
||||||
|
void k
|
||||||
|
|
|
||||||
|
|
@ -6,3 +6,6 @@ cfloat k
|
||||||
char k
|
char k
|
||||||
complicatedLess l
|
complicatedLess l
|
||||||
creal k
|
creal k
|
||||||
|
dchar k
|
||||||
|
ucent k
|
||||||
|
wchar k
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
identifiers
|
identifiers
|
||||||
Foo s
|
Foo s
|
||||||
|
cfloat k
|
||||||
float k
|
float k
|
||||||
|
ifloat k
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1,7 @@
|
||||||
identifiers
|
identifiers
|
||||||
|
alignof k
|
||||||
foo f
|
foo f
|
||||||
|
mangleof k
|
||||||
|
sizeof k
|
||||||
|
stringof k
|
||||||
|
tupleof k
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1,3 @@
|
||||||
identifiers
|
identifiers
|
||||||
|
init k
|
||||||
internal v
|
internal v
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,6 @@
|
||||||
identifiers
|
identifiers
|
||||||
|
cfloat k cfloat
|
||||||
|
float k float
|
||||||
foo f void foo() stdin 26 my documentation void
|
foo f void foo() stdin 26 my documentation void
|
||||||
foo f void foo(int i) stdin 49 my documentation void
|
foo f void foo(int i) stdin 49 my documentation void
|
||||||
|
ifloat k ifloat
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue