mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-08 03:28:20 +02:00
Fixed autocomplete flickering while typing
This commit is contained in:
parent
2a446afc73
commit
c2c7431620
7 changed files with 75 additions and 72 deletions
|
@ -1597,70 +1597,22 @@ namespace IDE.ui
|
|||
mInvokeWidget.mIgnoreMove += ignoreMove ? 1 : -1;
|
||||
}
|
||||
|
||||
// IDEHelper/third_party/FtsFuzzyMatch.h
|
||||
[CallingConvention(.Stdcall), CLink]
|
||||
static extern bool fts_fuzzy_match(char8* pattern, char8* str, ref int outScore, uint8* matches, int maxMatches);
|
||||
|
||||
bool DoesFilterMatch(String entry, String filter)
|
||||
{
|
||||
if (filter.Length == 0)
|
||||
return true;
|
||||
|
||||
char8* entryPtr = entry.Ptr;
|
||||
char8* filterPtr = filter.Ptr;
|
||||
|
||||
int filterLen = (int)filter.Length;
|
||||
int entryLen = (int)entry.Length;
|
||||
|
||||
bool hasUnderscore = false;
|
||||
bool checkInitials = filterLen > 1;
|
||||
for (int i = 0; i < (int)filterLen; i++)
|
||||
{
|
||||
char8 c = filterPtr[i];
|
||||
if (c == '_')
|
||||
hasUnderscore = true;
|
||||
else if (filterPtr[i].IsLower)
|
||||
checkInitials = false;
|
||||
}
|
||||
|
||||
if (hasUnderscore)
|
||||
//return strnicmp(filter, entry, filterLen) == 0;
|
||||
return (entryLen >= filterLen) && (String.Compare(entryPtr, filterLen, filterPtr, filterLen, true) == 0);
|
||||
|
||||
char8[256] initialStr;
|
||||
char8* initialStrP = &initialStr;
|
||||
|
||||
//String initialStr;
|
||||
bool prevWasUnderscore = false;
|
||||
|
||||
for (int entryIdx = 0; entryIdx < entryLen; entryIdx++)
|
||||
{
|
||||
char8 entryC = entryPtr[entryIdx];
|
||||
|
||||
if (entryC == '_')
|
||||
{
|
||||
prevWasUnderscore = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((entryIdx == 0) || (prevWasUnderscore) || (entryC.IsUpper) || (entryC.IsDigit))
|
||||
{
|
||||
/*if (strnicmp(filter, entry + entryIdx, filterLen) == 0)
|
||||
return true;*/
|
||||
if ((entryLen - entryIdx >= filterLen) && (String.Compare(entryPtr + entryIdx, filterLen, filterPtr, filterLen, true) == 0))
|
||||
return true;
|
||||
if (checkInitials)
|
||||
*(initialStrP++) = entryC;
|
||||
}
|
||||
prevWasUnderscore = false;
|
||||
|
||||
if (filterLen == 1)
|
||||
break; // Don't check inners for single-character case
|
||||
}
|
||||
|
||||
if (!checkInitials)
|
||||
if (filter.Length > entry.Length)
|
||||
return false;
|
||||
int initialLen = initialStrP - (char8*)&initialStr;
|
||||
return (initialLen >= filterLen) && (String.Compare(&initialStr, filterLen, filterPtr, filterLen, true) == 0);
|
||||
|
||||
//*(initialStrP++) = 0;
|
||||
//return strnicmp(filter, initialStr, filterLen) == 0;
|
||||
int score = 0;
|
||||
uint8[256] matches = ?;
|
||||
|
||||
return fts_fuzzy_match(filter.CStr(), entry.CStr(), ref score, &matches, matches.Count);
|
||||
}
|
||||
|
||||
void UpdateData(String selectString, bool changedAfterInfo)
|
||||
|
@ -1718,7 +1670,7 @@ namespace IDE.ui
|
|||
for (int i < mAutoCompleteListWidget.mFullEntryList.Count)
|
||||
{
|
||||
var entry = mAutoCompleteListWidget.mFullEntryList[i];
|
||||
//if (String.Compare(entry.mEntryDisplay, 0, curString, 0, curString.Length, true) == 0)
|
||||
|
||||
if (DoesFilterMatch(entry.mEntryDisplay, curString))
|
||||
{
|
||||
mAutoCompleteListWidget.mEntryList.Add(entry);
|
||||
|
@ -1876,6 +1828,7 @@ namespace IDE.ui
|
|||
|
||||
public void UpdateInfo(String info)
|
||||
{
|
||||
List<uint8> matchIndices = new:ScopedAlloc! .(256);
|
||||
for (var entryView in info.Split('\n'))
|
||||
{
|
||||
StringView entryType = StringView(entryView);
|
||||
|
@ -1887,12 +1840,34 @@ namespace IDE.ui
|
|||
entryType = StringView(entryType, 0, tabPos);
|
||||
}
|
||||
|
||||
StringView matches = default;
|
||||
int matchesPos = entryDisplay.IndexOf('\x02');
|
||||
matchIndices.Clear();
|
||||
if (matchesPos != -1)
|
||||
{
|
||||
matches = StringView(entryDisplay, matchesPos + 1);
|
||||
entryDisplay = StringView(entryDisplay, 0, matchesPos);
|
||||
|
||||
for(var sub in matches.Split(','))
|
||||
{
|
||||
if(sub.StartsWith('X'))
|
||||
break;
|
||||
|
||||
var result = int64.Parse(sub, .HexNumber);
|
||||
|
||||
Debug.Assert((result case .Ok(let value)) && value <= uint8.MaxValue);
|
||||
|
||||
// TODO(FUZZY): we could save start and length instead of single chars
|
||||
matchIndices.Add((uint8)result.Value);
|
||||
}
|
||||
}
|
||||
|
||||
StringView documentation = default;
|
||||
int docPos = entryDisplay.IndexOf('\x03');
|
||||
int docPos = matches.IndexOf('\x03');
|
||||
if (docPos != -1)
|
||||
{
|
||||
documentation = StringView(entryDisplay, docPos + 1);
|
||||
entryDisplay = StringView(entryDisplay, 0, docPos);
|
||||
documentation = StringView(matches, docPos + 1);
|
||||
matches = StringView(matches, 0, docPos);
|
||||
}
|
||||
|
||||
StringView entryInsert = default;
|
||||
|
@ -1915,15 +1890,27 @@ namespace IDE.ui
|
|||
case "select":
|
||||
default:
|
||||
{
|
||||
if ((!documentation.IsEmpty) && (mAutoCompleteListWidget != null))
|
||||
if (((!documentation.IsEmpty) || (!matchIndices.IsEmpty)) && (mAutoCompleteListWidget != null))
|
||||
{
|
||||
while (entryIdx < mAutoCompleteListWidget.mEntryList.Count)
|
||||
{
|
||||
let entry = mAutoCompleteListWidget.mEntryList[entryIdx];
|
||||
if ((entry.mEntryDisplay == entryDisplay) && (entry.mEntryType == entryType))
|
||||
{
|
||||
if (entry.mDocumentation == null)
|
||||
if (!matchIndices.IsEmpty)
|
||||
{
|
||||
if (entry.mMatchIndices == null)
|
||||
entry.mMatchIndices = new:(mAutoCompleteListWidget.[Friend]mAlloc) List<uint8>(matchIndices.GetEnumerator());
|
||||
else
|
||||
{
|
||||
entry.mMatchIndices.Clear();
|
||||
entry.mMatchIndices.AddRange(matchIndices);
|
||||
}
|
||||
}
|
||||
|
||||
if ((!documentation.IsEmpty) && entry.mDocumentation == null)
|
||||
entry.mDocumentation = new:(mAutoCompleteListWidget.[Friend]mAlloc) String(documentation);
|
||||
|
||||
break;
|
||||
}
|
||||
entryIdx++;
|
||||
|
@ -2017,6 +2004,7 @@ namespace IDE.ui
|
|||
entryDisplay = StringView(entryView, tabPos + 1);
|
||||
entryType = StringView(entryType, 0, tabPos);
|
||||
}
|
||||
|
||||
StringView matches = default;
|
||||
int matchesPos = entryDisplay.IndexOf('\x02');
|
||||
matchIndices.Clear();
|
||||
|
@ -2027,7 +2015,7 @@ namespace IDE.ui
|
|||
|
||||
for(var sub in matches.Split(','))
|
||||
{
|
||||
if(sub == "X")
|
||||
if(sub.StartsWith('X'))
|
||||
break;
|
||||
|
||||
var result = int64.Parse(sub, .HexNumber);
|
||||
|
|
|
@ -508,3 +508,11 @@ Path = "X86Target.h"
|
|||
[[ProjectFolder.Items]]
|
||||
Type = "Source"
|
||||
Path = "X86XmmInfo.cpp"
|
||||
|
||||
[[ProjectFolder.Items]]
|
||||
Type = "Folder"
|
||||
Name = "third_party"
|
||||
|
||||
[[ProjectFolder.Items.Items]]
|
||||
Type = "Source"
|
||||
Path = "third_party/FtsFuzzyMatch.h"
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
#include "BfResolvedTypeUtils.h"
|
||||
|
||||
#define FTS_FUZZY_MATCH_IMPLEMENTATION
|
||||
#include "FtsFuzzyMatch.h"
|
||||
#include "../third_party/FtsFuzzyMatch.h"
|
||||
|
||||
#pragma warning(disable:4996)
|
||||
|
||||
|
|
|
@ -8007,9 +8007,7 @@ void BfCompiler::GenerateAutocompleteInfo()
|
|||
}
|
||||
std::sort(entries.begin(), entries.end(), [](AutoCompleteEntry* lhs, AutoCompleteEntry* rhs)
|
||||
{
|
||||
// TODO(FUZZY): SORT BY Score
|
||||
return lhs->mScore > rhs->mScore;
|
||||
//return stricmp(lhs->mDisplay, rhs->mDisplay) < 0;
|
||||
});
|
||||
|
||||
String docString;
|
||||
|
@ -8024,8 +8022,6 @@ void BfCompiler::GenerateAutocompleteInfo()
|
|||
autoCompleteResultString += '@';
|
||||
autoCompleteResultString += String(entry->mDisplay);
|
||||
|
||||
// TODO(FUZZY): OUTPUT
|
||||
// TODO(FUZZY): this is not really efficient
|
||||
autoCompleteResultString += "\x02";
|
||||
for (int i = 0; i < 256; i++)
|
||||
{
|
||||
|
|
|
@ -400,7 +400,7 @@
|
|||
<ClInclude Include="Compiler\BfUtil.h" />
|
||||
<ClInclude Include="Compiler\BfVarDeclChecker.h" />
|
||||
<ClInclude Include="Compiler\CeMachine.h" />
|
||||
<ClInclude Include="Compiler\FtsFuzzyMatch.h" />
|
||||
<ClInclude Include="third_party\FtsFuzzyMatch.h" />
|
||||
<ClInclude Include="Compiler\MemReporter.h" />
|
||||
<ClInclude Include="DbgMiniDump.h" />
|
||||
<ClInclude Include="Debugger.h" />
|
||||
|
|
|
@ -24,6 +24,9 @@
|
|||
<Filter Include="Beef">
|
||||
<UniqueIdentifier>{83b97406-2f83-49ad-bbbc-3ff70ecda6bb}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="third_party">
|
||||
<UniqueIdentifier>{d36777f2-b326-4a8c-84a3-5c2f39153f75}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Compiler\BfAst.cpp">
|
||||
|
@ -399,6 +402,8 @@
|
|||
<ClInclude Include="Compiler\CeMachine.h">
|
||||
<Filter>Compiler</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Compiler\FtsFuzzyMatch.h" />
|
||||
<ClInclude Include="third_party\FtsFuzzyMatch.h">
|
||||
<Filter>third_party</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -47,6 +47,7 @@ namespace fts {
|
|||
static bool fuzzy_match(char const* pattern, char const* str, int& outScore, uint8_t* matches, int maxMatches);
|
||||
}
|
||||
|
||||
BF_EXPORT bool BF_CALLTYPE fts_fuzzy_match(char const* pattern, char const* str, int& outScore, uint8_t* matches, int maxMatches);
|
||||
|
||||
#ifdef FTS_FUZZY_MATCH_IMPLEMENTATION
|
||||
namespace fts {
|
||||
|
@ -245,6 +246,11 @@ namespace fts {
|
|||
}
|
||||
} // namespace fts
|
||||
|
||||
BF_EXPORT bool BF_CALLTYPE fts_fuzzy_match(char const* pattern, char const* str, int& outScore, uint8_t* matches, int maxMatches)
|
||||
{
|
||||
return fts::fuzzy_match(pattern, str, outScore, matches, maxMatches);
|
||||
}
|
||||
|
||||
#endif // FTS_FUZZY_MATCH_IMPLEMENTATION
|
||||
|
||||
#endif // FTS_FUZZY_MATCH_H
|
Loading…
Add table
Add a link
Reference in a new issue