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;
|
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)
|
bool DoesFilterMatch(String entry, String filter)
|
||||||
{
|
{
|
||||||
if (filter.Length == 0)
|
if (filter.Length == 0)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
char8* entryPtr = entry.Ptr;
|
if (filter.Length > entry.Length)
|
||||||
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)
|
|
||||||
return false;
|
return false;
|
||||||
int initialLen = initialStrP - (char8*)&initialStr;
|
|
||||||
return (initialLen >= filterLen) && (String.Compare(&initialStr, filterLen, filterPtr, filterLen, true) == 0);
|
|
||||||
|
|
||||||
//*(initialStrP++) = 0;
|
int score = 0;
|
||||||
//return strnicmp(filter, initialStr, filterLen) == 0;
|
uint8[256] matches = ?;
|
||||||
|
|
||||||
|
return fts_fuzzy_match(filter.CStr(), entry.CStr(), ref score, &matches, matches.Count);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdateData(String selectString, bool changedAfterInfo)
|
void UpdateData(String selectString, bool changedAfterInfo)
|
||||||
|
@ -1718,7 +1670,7 @@ namespace IDE.ui
|
||||||
for (int i < mAutoCompleteListWidget.mFullEntryList.Count)
|
for (int i < mAutoCompleteListWidget.mFullEntryList.Count)
|
||||||
{
|
{
|
||||||
var entry = mAutoCompleteListWidget.mFullEntryList[i];
|
var entry = mAutoCompleteListWidget.mFullEntryList[i];
|
||||||
//if (String.Compare(entry.mEntryDisplay, 0, curString, 0, curString.Length, true) == 0)
|
|
||||||
if (DoesFilterMatch(entry.mEntryDisplay, curString))
|
if (DoesFilterMatch(entry.mEntryDisplay, curString))
|
||||||
{
|
{
|
||||||
mAutoCompleteListWidget.mEntryList.Add(entry);
|
mAutoCompleteListWidget.mEntryList.Add(entry);
|
||||||
|
@ -1876,6 +1828,7 @@ namespace IDE.ui
|
||||||
|
|
||||||
public void UpdateInfo(String info)
|
public void UpdateInfo(String info)
|
||||||
{
|
{
|
||||||
|
List<uint8> matchIndices = new:ScopedAlloc! .(256);
|
||||||
for (var entryView in info.Split('\n'))
|
for (var entryView in info.Split('\n'))
|
||||||
{
|
{
|
||||||
StringView entryType = StringView(entryView);
|
StringView entryType = StringView(entryView);
|
||||||
|
@ -1887,12 +1840,34 @@ namespace IDE.ui
|
||||||
entryType = StringView(entryType, 0, tabPos);
|
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;
|
StringView documentation = default;
|
||||||
int docPos = entryDisplay.IndexOf('\x03');
|
int docPos = matches.IndexOf('\x03');
|
||||||
if (docPos != -1)
|
if (docPos != -1)
|
||||||
{
|
{
|
||||||
documentation = StringView(entryDisplay, docPos + 1);
|
documentation = StringView(matches, docPos + 1);
|
||||||
entryDisplay = StringView(entryDisplay, 0, docPos);
|
matches = StringView(matches, 0, docPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
StringView entryInsert = default;
|
StringView entryInsert = default;
|
||||||
|
@ -1915,15 +1890,27 @@ namespace IDE.ui
|
||||||
case "select":
|
case "select":
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
if ((!documentation.IsEmpty) && (mAutoCompleteListWidget != null))
|
if (((!documentation.IsEmpty) || (!matchIndices.IsEmpty)) && (mAutoCompleteListWidget != null))
|
||||||
{
|
{
|
||||||
while (entryIdx < mAutoCompleteListWidget.mEntryList.Count)
|
while (entryIdx < mAutoCompleteListWidget.mEntryList.Count)
|
||||||
{
|
{
|
||||||
let entry = mAutoCompleteListWidget.mEntryList[entryIdx];
|
let entry = mAutoCompleteListWidget.mEntryList[entryIdx];
|
||||||
if ((entry.mEntryDisplay == entryDisplay) && (entry.mEntryType == entryType))
|
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);
|
entry.mDocumentation = new:(mAutoCompleteListWidget.[Friend]mAlloc) String(documentation);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
entryIdx++;
|
entryIdx++;
|
||||||
|
@ -2017,6 +2004,7 @@ namespace IDE.ui
|
||||||
entryDisplay = StringView(entryView, tabPos + 1);
|
entryDisplay = StringView(entryView, tabPos + 1);
|
||||||
entryType = StringView(entryType, 0, tabPos);
|
entryType = StringView(entryType, 0, tabPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
StringView matches = default;
|
StringView matches = default;
|
||||||
int matchesPos = entryDisplay.IndexOf('\x02');
|
int matchesPos = entryDisplay.IndexOf('\x02');
|
||||||
matchIndices.Clear();
|
matchIndices.Clear();
|
||||||
|
@ -2027,7 +2015,7 @@ namespace IDE.ui
|
||||||
|
|
||||||
for(var sub in matches.Split(','))
|
for(var sub in matches.Split(','))
|
||||||
{
|
{
|
||||||
if(sub == "X")
|
if(sub.StartsWith('X'))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
var result = int64.Parse(sub, .HexNumber);
|
var result = int64.Parse(sub, .HexNumber);
|
||||||
|
|
|
@ -508,3 +508,11 @@ Path = "X86Target.h"
|
||||||
[[ProjectFolder.Items]]
|
[[ProjectFolder.Items]]
|
||||||
Type = "Source"
|
Type = "Source"
|
||||||
Path = "X86XmmInfo.cpp"
|
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"
|
#include "BfResolvedTypeUtils.h"
|
||||||
|
|
||||||
#define FTS_FUZZY_MATCH_IMPLEMENTATION
|
#define FTS_FUZZY_MATCH_IMPLEMENTATION
|
||||||
#include "FtsFuzzyMatch.h"
|
#include "../third_party/FtsFuzzyMatch.h"
|
||||||
|
|
||||||
#pragma warning(disable:4996)
|
#pragma warning(disable:4996)
|
||||||
|
|
||||||
|
|
|
@ -8007,9 +8007,7 @@ void BfCompiler::GenerateAutocompleteInfo()
|
||||||
}
|
}
|
||||||
std::sort(entries.begin(), entries.end(), [](AutoCompleteEntry* lhs, AutoCompleteEntry* rhs)
|
std::sort(entries.begin(), entries.end(), [](AutoCompleteEntry* lhs, AutoCompleteEntry* rhs)
|
||||||
{
|
{
|
||||||
// TODO(FUZZY): SORT BY Score
|
|
||||||
return lhs->mScore > rhs->mScore;
|
return lhs->mScore > rhs->mScore;
|
||||||
//return stricmp(lhs->mDisplay, rhs->mDisplay) < 0;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
String docString;
|
String docString;
|
||||||
|
@ -8024,8 +8022,6 @@ void BfCompiler::GenerateAutocompleteInfo()
|
||||||
autoCompleteResultString += '@';
|
autoCompleteResultString += '@';
|
||||||
autoCompleteResultString += String(entry->mDisplay);
|
autoCompleteResultString += String(entry->mDisplay);
|
||||||
|
|
||||||
// TODO(FUZZY): OUTPUT
|
|
||||||
// TODO(FUZZY): this is not really efficient
|
|
||||||
autoCompleteResultString += "\x02";
|
autoCompleteResultString += "\x02";
|
||||||
for (int i = 0; i < 256; i++)
|
for (int i = 0; i < 256; i++)
|
||||||
{
|
{
|
||||||
|
|
|
@ -400,7 +400,7 @@
|
||||||
<ClInclude Include="Compiler\BfUtil.h" />
|
<ClInclude Include="Compiler\BfUtil.h" />
|
||||||
<ClInclude Include="Compiler\BfVarDeclChecker.h" />
|
<ClInclude Include="Compiler\BfVarDeclChecker.h" />
|
||||||
<ClInclude Include="Compiler\CeMachine.h" />
|
<ClInclude Include="Compiler\CeMachine.h" />
|
||||||
<ClInclude Include="Compiler\FtsFuzzyMatch.h" />
|
<ClInclude Include="third_party\FtsFuzzyMatch.h" />
|
||||||
<ClInclude Include="Compiler\MemReporter.h" />
|
<ClInclude Include="Compiler\MemReporter.h" />
|
||||||
<ClInclude Include="DbgMiniDump.h" />
|
<ClInclude Include="DbgMiniDump.h" />
|
||||||
<ClInclude Include="Debugger.h" />
|
<ClInclude Include="Debugger.h" />
|
||||||
|
|
|
@ -24,6 +24,9 @@
|
||||||
<Filter Include="Beef">
|
<Filter Include="Beef">
|
||||||
<UniqueIdentifier>{83b97406-2f83-49ad-bbbc-3ff70ecda6bb}</UniqueIdentifier>
|
<UniqueIdentifier>{83b97406-2f83-49ad-bbbc-3ff70ecda6bb}</UniqueIdentifier>
|
||||||
</Filter>
|
</Filter>
|
||||||
|
<Filter Include="third_party">
|
||||||
|
<UniqueIdentifier>{d36777f2-b326-4a8c-84a3-5c2f39153f75}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="Compiler\BfAst.cpp">
|
<ClCompile Include="Compiler\BfAst.cpp">
|
||||||
|
@ -399,6 +402,8 @@
|
||||||
<ClInclude Include="Compiler\CeMachine.h">
|
<ClInclude Include="Compiler\CeMachine.h">
|
||||||
<Filter>Compiler</Filter>
|
<Filter>Compiler</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="Compiler\FtsFuzzyMatch.h" />
|
<ClInclude Include="third_party\FtsFuzzyMatch.h">
|
||||||
|
<Filter>third_party</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
|
@ -47,6 +47,7 @@ namespace fts {
|
||||||
static bool fuzzy_match(char const* pattern, char const* str, int& outScore, uint8_t* matches, int maxMatches);
|
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
|
#ifdef FTS_FUZZY_MATCH_IMPLEMENTATION
|
||||||
namespace fts {
|
namespace fts {
|
||||||
|
@ -245,6 +246,11 @@ namespace fts {
|
||||||
}
|
}
|
||||||
} // 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_IMPLEMENTATION
|
||||||
|
|
||||||
#endif // FTS_FUZZY_MATCH_H
|
#endif // FTS_FUZZY_MATCH_H
|
Loading…
Add table
Add a link
Reference in a new issue