Allowed for optional boolean to better match filenames. (#180)
This commit is contained in:
parent
9c9fbe4c8b
commit
c7b1a6f53e
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue