Allowed for optional boolean to better match filenames. (#180)

This commit is contained in:
Adam 2021-05-16 13:23:17 -04:00 committed by GitHub
parent 9c9fbe4c8b
commit c7b1a6f53e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 51 additions and 24 deletions

View File

@ -58,10 +58,10 @@ local function compare_score(a, b)
return a.score > b.score
end
local function fuzzy_match_items(items, needle)
local function fuzzy_match_items(items, needle, files)
local res = {}
for _, item in ipairs(items) do
local score = system.fuzzy_match(tostring(item), needle)
local score = system.fuzzy_match(tostring(item), needle, files)
if score then
table.insert(res, { text = item, score = score })
end
@ -74,11 +74,11 @@ local function fuzzy_match_items(items, needle)
end
function common.fuzzy_match(haystack, needle)
function common.fuzzy_match(haystack, needle, files)
if type(haystack) == "table" then
return fuzzy_match_items(haystack, needle)
return fuzzy_match_items(haystack, needle, files)
end
return system.fuzzy_match(haystack, needle)
return system.fuzzy_match(haystack, needle, files)
end
@ -86,16 +86,16 @@ function common.fuzzy_match_with_recents(haystack, recents, needle)
if needle == "" then
local recents_ext = {}
for i = 2, #recents do
table.insert(recents_ext, recents[i])
table.insert(recents_ext, recents[i])
end
table.insert(recents_ext, recents[1])
local others = common.fuzzy_match(haystack, "")
local others = common.fuzzy_match(haystack, "", true)
for i = 1, #others do
table.insert(recents_ext, others[i])
end
return recents_ext
else
return fuzzy_match_items(haystack, needle)
return fuzzy_match_items(haystack, needle, true)
end
end

View File

@ -517,27 +517,54 @@ static int f_exec(lua_State *L) {
static int f_fuzzy_match(lua_State *L) {
const char *str = luaL_checkstring(L, 1);
const char *ptn = luaL_checkstring(L, 2);
size_t strLen, ptnLen;
const char *str = luaL_checklstring(L, 1, &strLen);
const char *ptn = luaL_checklstring(L, 2, &ptnLen);
bool files = false;
if (lua_gettop(L) > 2 && lua_isboolean(L,3))
files = lua_toboolean(L, 3);
int score = 0;
int run = 0;
while (*str && *ptn) {
while (*str == ' ') { str++; }
while (*ptn == ' ') { ptn++; }
if (tolower(*str) == tolower(*ptn)) {
score += run * 10 - (*str != *ptn);
run++;
ptn++;
} else {
score -= 10;
run = 0;
// Match things *backwards*. This allows for better matching on filenames than the above
// function. For example, in the lite project, opening "renderer" has lib/font_render/build.sh
// as the first result, rather than src/renderer.c. Clearly that's wrong.
if (files) {
const char* strEnd = str + strLen - 1;
const char* ptnEnd = ptn + ptnLen - 1;
while (strEnd >= str && ptnEnd >= ptn) {
while (*strEnd == ' ') { strEnd--; }
while (*ptnEnd == ' ') { ptnEnd--; }
if (tolower(*strEnd) == tolower(*ptnEnd)) {
score += run * 10 - (*strEnd != *ptnEnd);
run++;
ptnEnd--;
} else {
score -= 10;
run = 0;
}
strEnd--;
}
str++;
if (ptnEnd >= ptn) { return 0; }
} else {
while (*str && *ptn) {
while (*str == ' ') { str++; }
while (*ptn == ' ') { ptn++; }
if (tolower(*str) == tolower(*ptn)) {
score += run * 10 - (*str != *ptn);
run++;
ptn++;
} else {
score -= 10;
run = 0;
}
str++;
}
if (*ptn) { return 0; }
}
if (*ptn) { return 0; }
lua_pushnumber(L, score - (int) strlen(str));
lua_pushnumber(L, score - (int)strLen);
return 1;
}