mirror of
https://github.com/MihailRis/voxelcore.git
synced 2026-10-12 06:21:50 +00:00
Merge 82801c52bc into dacebf94bc
This commit is contained in:
commit
258671b7fd
4 changed files with 254 additions and 47 deletions
|
|
@ -1,3 +1,7 @@
|
||||||
|
local search_utils = require("search_utils")
|
||||||
|
|
||||||
|
local score_func = search_utils.fuzzy_score
|
||||||
|
|
||||||
function on_open(params)
|
function on_open(params)
|
||||||
if params then
|
if params then
|
||||||
mode = params.mode
|
mode = params.mode
|
||||||
|
|
@ -50,7 +54,10 @@ function reposition_func(_pack)
|
||||||
else
|
else
|
||||||
tbl = packs_excluded
|
tbl = packs_excluded
|
||||||
local packinfo = pack.get_info(_pack)
|
local packinfo = pack.get_info(_pack)
|
||||||
packinfo[packinfo.id] = {packinfo.id, packinfo.title}
|
packinfo[packinfo.id] = {
|
||||||
|
id = packinfo.id,
|
||||||
|
title = packinfo.title
|
||||||
|
}
|
||||||
table.insert(packs_excluded, packinfo.id)
|
table.insert(packs_excluded, packinfo.id)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -60,6 +67,18 @@ function reposition_func(_pack)
|
||||||
return pos[1], pos[2]
|
return pos[1], pos[2]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function update_pack_id_title(packinfo)
|
||||||
|
local id_el = document["pack_"..packinfo.id.."_id"]
|
||||||
|
local title_el = document["pack_"..packinfo.id.."_title"]
|
||||||
|
|
||||||
|
local id_md = packinfo.id_md or packinfo.id
|
||||||
|
if packinfo.has_indices then
|
||||||
|
id_md = id_md .. "\\*"
|
||||||
|
end
|
||||||
|
id_el.text = string.format("[%s %s]", id_md, packinfo.version)
|
||||||
|
|
||||||
|
title_el.text = packinfo.title_md or packinfo.title
|
||||||
|
end
|
||||||
|
|
||||||
function refresh_search()
|
function refresh_search()
|
||||||
local search_text = document.search_textbox.text:lower()
|
local search_text = document.search_textbox.text:lower()
|
||||||
|
|
@ -67,26 +86,38 @@ function refresh_search()
|
||||||
local new_included = table.copy(packs_included)
|
local new_included = table.copy(packs_included)
|
||||||
local new_excluded = table.copy(packs_excluded)
|
local new_excluded = table.copy(packs_excluded)
|
||||||
|
|
||||||
local function score(pack_id, pack_name)
|
local smart_score_cache = {}
|
||||||
if pack_name:lower():find(search_text) or pack_id:lower():find(search_text) then
|
local colored_ids = {}
|
||||||
return 1
|
local colored_titles = {}
|
||||||
|
|
||||||
|
local function smart_score(id)
|
||||||
|
if smart_score_cache[id] then
|
||||||
|
return smart_score_cache[id]
|
||||||
end
|
end
|
||||||
return 0
|
local id_score, colored_id = score_func(id, search_text, true)
|
||||||
|
local title_score, colored_title = score_func(
|
||||||
|
packs_info[id].title, search_text, true)
|
||||||
|
local res = math.max(id_score, title_score)
|
||||||
|
|
||||||
|
smart_score_cache[id] = res
|
||||||
|
colored_ids[id] = colored_id
|
||||||
|
colored_titles[id] = colored_title
|
||||||
|
return res
|
||||||
end
|
end
|
||||||
|
|
||||||
local function sorting(a, b)
|
local function cmp(a, b)
|
||||||
local score_a = score(a, packs_info[a][2])
|
local score_a = smart_score(a)
|
||||||
local score_b = score(b, packs_info[b][2])
|
local score_b = smart_score(b)
|
||||||
|
|
||||||
if score_a ~= score_b then
|
if score_a ~= score_b then
|
||||||
return score_a > score_b
|
return score_a > score_b
|
||||||
else
|
else
|
||||||
return packs_info[a][2] < packs_info[b][2]
|
return packs_info[a].title < packs_info[b].title
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
table.sort(new_included, sorting)
|
table.sort(new_included, cmp)
|
||||||
table.sort(new_excluded, sorting)
|
table.sort(new_excluded, cmp)
|
||||||
|
|
||||||
packs_included = new_included
|
packs_included = new_included
|
||||||
packs_excluded = new_excluded
|
packs_excluded = new_excluded
|
||||||
|
|
@ -94,6 +125,10 @@ function refresh_search()
|
||||||
for _, id in ipairs(table.merge(table.copy(packs_included), packs_excluded)) do
|
for _, id in ipairs(table.merge(table.copy(packs_included), packs_excluded)) do
|
||||||
local content = document["pack_" .. id]
|
local content = document["pack_" .. id]
|
||||||
content:reposition()
|
content:reposition()
|
||||||
|
local packinfo = pack.get_info(id)
|
||||||
|
packinfo.id_md = colored_ids[id]
|
||||||
|
packinfo.title_md = colored_titles[id]
|
||||||
|
update_pack_id_title(packinfo)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -162,21 +197,20 @@ function move_right()
|
||||||
refresh_changes()
|
refresh_changes()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function place_pack(panel, packinfo, callback, position_func)
|
function place_pack(panel, packinfo, callback, position_func)
|
||||||
if packinfo.error then
|
if packinfo.error then
|
||||||
callback = nil
|
callback = nil
|
||||||
end
|
end
|
||||||
if packinfo.has_indices then
|
packinfo.id_verbose = ""
|
||||||
packinfo.id_verbose = packinfo.id.."*"
|
|
||||||
else
|
|
||||||
packinfo.id_verbose = packinfo.id
|
|
||||||
end
|
|
||||||
packinfo.callback = callback
|
packinfo.callback = callback
|
||||||
packinfo.position_func = position_func or function () end
|
packinfo.position_func = position_func or function () end
|
||||||
panel:add(gui.template("pack", packinfo))
|
panel:add(gui.template("pack", packinfo))
|
||||||
if not callback then
|
if not callback then
|
||||||
document["pack_"..packinfo.id].enabled = false
|
document["pack_"..packinfo.id].enabled = false
|
||||||
end
|
end
|
||||||
|
update_pack_id_title(packinfo)
|
||||||
end
|
end
|
||||||
|
|
||||||
local Version = {}
|
local Version = {}
|
||||||
|
|
@ -346,12 +380,18 @@ function refresh()
|
||||||
|
|
||||||
for _,id in ipairs(base_packs) do
|
for _,id in ipairs(base_packs) do
|
||||||
local packinfo = pack.get_info(id)
|
local packinfo = pack.get_info(id)
|
||||||
packs_info[id] = {packinfo.id, packinfo.title}
|
packs_info[id] = {
|
||||||
|
id = packinfo.id,
|
||||||
|
title = packinfo.title
|
||||||
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
for _,id in ipairs(packs_all) do
|
for _,id in ipairs(packs_all) do
|
||||||
local packinfo = pack.get_info(id)
|
local packinfo = pack.get_info(id)
|
||||||
packs_info[id] = {packinfo.id, packinfo.title}
|
packs_info[id] = {
|
||||||
|
id = packinfo.id,
|
||||||
|
title = packinfo.title
|
||||||
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
if #packs_excluded == 0 then packs_excluded = table.copy(packs_available) end
|
if #packs_excluded == 0 then packs_excluded = table.copy(packs_available) end
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,7 @@
|
||||||
|
local search_utils = require("search_utils")
|
||||||
|
|
||||||
|
local score_func = search_utils.fuzzy_score
|
||||||
|
|
||||||
local packs_installed = {}
|
local packs_installed = {}
|
||||||
local pack_open = {}
|
local pack_open = {}
|
||||||
local PARSERS = {
|
local PARSERS = {
|
||||||
|
|
@ -14,17 +18,28 @@ function on_open()
|
||||||
document.search_textbox.focused = true
|
document.search_textbox.focused = true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function update_pack_id_title(packinfo)
|
||||||
|
local id_el = document["pack_"..packinfo.id.."_id"]
|
||||||
|
local title_el = document["pack_"..packinfo.id.."_title"]
|
||||||
|
|
||||||
|
local id_md = packinfo.id_md or packinfo.id
|
||||||
|
if packinfo.has_indices then
|
||||||
|
id_md = id_md .. "\\*"
|
||||||
|
end
|
||||||
|
id_el.text = string.format("[%s %s]", id_md, packinfo.version)
|
||||||
|
|
||||||
|
title_el.text = packinfo.title_md or packinfo.title
|
||||||
|
end
|
||||||
|
|
||||||
function place_pack(panel, packinfo, callback)
|
function place_pack(panel, packinfo, callback)
|
||||||
if packinfo.error then
|
if packinfo.error then
|
||||||
callback = nil
|
callback = nil
|
||||||
end
|
end
|
||||||
if packinfo.has_indices then
|
packinfo.id_verbose = ""
|
||||||
packinfo.id_verbose = packinfo.id.."*"
|
|
||||||
else
|
|
||||||
packinfo.id_verbose = packinfo.id
|
|
||||||
end
|
|
||||||
packinfo.callback = callback
|
packinfo.callback = callback
|
||||||
panel:add(gui.template("pack", packinfo))
|
panel:add(gui.template("pack", packinfo))
|
||||||
|
update_pack_id_title(packinfo)
|
||||||
end
|
end
|
||||||
|
|
||||||
function refresh_search()
|
function refresh_search()
|
||||||
|
|
@ -33,20 +48,66 @@ function refresh_search()
|
||||||
local interval = 4
|
local interval = 4
|
||||||
local step = -1
|
local step = -1
|
||||||
|
|
||||||
for i, v in ipairs(packs_installed) do
|
local packs = table.copy(packs_installed)
|
||||||
local id = v[1]
|
|
||||||
local title = v[2]
|
local score_non_zero_num = 0
|
||||||
|
local smart_score_cache = {}
|
||||||
|
local colored_ids = {}
|
||||||
|
local colored_titles = {}
|
||||||
|
|
||||||
|
local function smart_score(a)
|
||||||
|
if smart_score_cache[a.id] then
|
||||||
|
return smart_score_cache[a.id]
|
||||||
|
end
|
||||||
|
local id_score, colored_id = score_func(a.id, search_text, true)
|
||||||
|
local title_score, colored_title = score_func(a.title, search_text, true)
|
||||||
|
local res = math.max(id_score, title_score)
|
||||||
|
|
||||||
|
smart_score_cache[a.id] = res
|
||||||
|
colored_ids[a.id] = colored_id
|
||||||
|
colored_titles[a.id] = colored_title
|
||||||
|
|
||||||
|
if res > 0 then
|
||||||
|
score_non_zero_num = score_non_zero_num + 1
|
||||||
|
end
|
||||||
|
return res
|
||||||
|
end
|
||||||
|
|
||||||
|
local function cmp(a, b)
|
||||||
|
local score_a = smart_score(a)
|
||||||
|
local score_b = smart_score(b)
|
||||||
|
if score_a == score_b then
|
||||||
|
return a.title > b.title
|
||||||
|
else
|
||||||
|
return score_a > score_b
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
table.sort(packs, cmp)
|
||||||
|
|
||||||
|
for i, v in ipairs(packs) do
|
||||||
|
local id = v.id
|
||||||
|
|
||||||
|
local packinfo = table.copy(packs[i])
|
||||||
|
if colored_ids[id] then
|
||||||
|
packinfo.id_md = colored_ids[id]
|
||||||
|
end
|
||||||
|
if colored_titles[id] then
|
||||||
|
packinfo.title_md = colored_titles[id]
|
||||||
|
end
|
||||||
|
update_pack_id_title(packinfo)
|
||||||
|
|
||||||
local content = document["pack_" .. id]
|
local content = document["pack_" .. id]
|
||||||
local pos = content.pos
|
local pos = content.pos
|
||||||
local size = content.size
|
local size = content.size
|
||||||
|
|
||||||
if title:lower():find(search_text) or id:lower():find(search_text) or search_text == '' then
|
if i <= score_non_zero_num then
|
||||||
content.enabled = true
|
content.enabled = true
|
||||||
content.pos = {pos[1], visible * (size[2] + interval) - step}
|
content.pos = { pos[1], visible * (size[2] + interval) - step }
|
||||||
visible = visible + 1
|
visible = visible + 1
|
||||||
else
|
else
|
||||||
content.enabled = false
|
content.enabled = false
|
||||||
content.pos = {pos[1], (visible + #packs_installed - i) * (size[2] + interval) - step}
|
content.pos = { pos[1], (visible + #packs_installed - i) * (size[2] + interval) - step }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
@ -74,7 +135,7 @@ local function create_trackbar(id, name, val)
|
||||||
"<label id='%s'>%s (%s)</label>",
|
"<label id='%s'>%s (%s)</label>",
|
||||||
id .. "_label", name:gsub("^%l", string.upper), val
|
id .. "_label", name:gsub("^%l", string.upper), val
|
||||||
))
|
))
|
||||||
document.configs:add(string.format(
|
document.configs:add(string.format(
|
||||||
"<trackbar id='%s' consumer='function(x) set_value(\"%s\", \"%s\", x) end' value='%s' min='0' max='1000' step='10'>%s</trackbar>",
|
"<trackbar id='%s' consumer='function(x) set_value(\"%s\", \"%s\", x) end' value='%s' min='0' max='1000' step='10'>%s</trackbar>",
|
||||||
id, name, id, val, name
|
id, name, id, val, name
|
||||||
))
|
))
|
||||||
|
|
@ -96,7 +157,7 @@ end
|
||||||
|
|
||||||
local function create_config(i, config, name, path)
|
local function create_config(i, config, name, path)
|
||||||
create_label(name, ('**[' .. name .. ']**'):upper(), "#FFFFFF")
|
create_label(name, ('**[' .. name .. ']**'):upper(), "#FFFFFF")
|
||||||
pack_open[2][i] = {elements = {}, path = path}
|
pack_open[2][i] = { elements = {}, path = path }
|
||||||
for _, a in ipairs(config.checkboxes) do
|
for _, a in ipairs(config.checkboxes) do
|
||||||
create_checkbox(i .. '_' .. a[1], a[1], a[2])
|
create_checkbox(i .. '_' .. a[1], a[1], a[2])
|
||||||
pack_open[2][i]["elements"][a[1]] = type(a[2])
|
pack_open[2][i]["elements"][a[1]] = type(a[2])
|
||||||
|
|
@ -145,7 +206,6 @@ local function has_valid_config(id)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function load_config_file(path)
|
local function load_config_file(path)
|
||||||
|
|
||||||
local extension = path:match("^.+%.(.+)$")
|
local extension = path:match("^.+%.(.+)$")
|
||||||
local name = path:match("([^/]+)%.([^%.]+)$")
|
local name = path:match("([^/]+)%.([^%.]+)$")
|
||||||
|
|
||||||
|
|
@ -162,10 +222,11 @@ end
|
||||||
local function load_config(path)
|
local function load_config(path)
|
||||||
if file.exists(path) then
|
if file.exists(path) then
|
||||||
local value = load_config_file(path)
|
local value = load_config_file(path)
|
||||||
local config = {checkboxes = {},
|
local config = {
|
||||||
trackbars = {},
|
checkboxes = {},
|
||||||
textboxes = {}
|
trackbars = {},
|
||||||
}
|
textboxes = {}
|
||||||
|
}
|
||||||
|
|
||||||
if not value then
|
if not value then
|
||||||
return
|
return
|
||||||
|
|
@ -173,11 +234,11 @@ local function load_config(path)
|
||||||
|
|
||||||
for i, v in pairs(value) do
|
for i, v in pairs(value) do
|
||||||
if type(v) == "string" then
|
if type(v) == "string" then
|
||||||
table.insert(config.textboxes, {i, v})
|
table.insert(config.textboxes, { i, v })
|
||||||
elseif type(v) == "boolean" then
|
elseif type(v) == "boolean" then
|
||||||
table.insert(config.checkboxes, {i, v})
|
table.insert(config.checkboxes, { i, v })
|
||||||
elseif type(v) == "number" then
|
elseif type(v) == "number" then
|
||||||
table.insert(config.trackbars, {i, v})
|
table.insert(config.trackbars, { i, v })
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -217,16 +278,18 @@ end
|
||||||
|
|
||||||
function open_pack(id)
|
function open_pack(id)
|
||||||
local packinfo = pack.get_info(id)
|
local packinfo = pack.get_info(id)
|
||||||
pack_open = {id, {}}
|
pack_open = { id, {} }
|
||||||
|
|
||||||
document.configs.visible = false
|
document.configs.visible = false
|
||||||
document.content_info.visible = true
|
document.content_info.visible = true
|
||||||
if has_valid_config(id) then document.open_config.enabled = true else document.open_config.enabled = false end
|
if has_valid_config(id) then document.open_config.enabled = true else document.open_config.enabled = false end
|
||||||
|
|
||||||
if packinfo['dependencies'] == nil then document.dependencies.text = 'None' else document.dependencies.text = table.tostring(packinfo['dependencies']) end
|
if packinfo['dependencies'] == nil then document.dependencies.text = 'None' else document.dependencies.text = table
|
||||||
|
.tostring(packinfo['dependencies']) end
|
||||||
if packinfo['creator'] == '' then document.author.text = 'None' else document.author.text = packinfo['creator'] end
|
if packinfo['creator'] == '' then document.author.text = 'None' else document.author.text = packinfo['creator'] end
|
||||||
if packinfo['version'] == nil then document.version.text = 'None' else document.version.text = packinfo['version'] end
|
if packinfo['version'] == nil then document.version.text = 'None' else document.version.text = packinfo['version'] end
|
||||||
if packinfo['description'] == nil then document.description.text = 'None' else document.description.text = packinfo['description'] end
|
if packinfo['description'] == nil then document.description.text = 'None' else document.description.text = packinfo
|
||||||
|
['description'] end
|
||||||
end
|
end
|
||||||
|
|
||||||
function open_config()
|
function open_config()
|
||||||
|
|
@ -269,9 +332,9 @@ function refresh()
|
||||||
local packinfos = pack.get_info(packs_installed)
|
local packinfos = pack.get_info(packs_installed)
|
||||||
for i, id in ipairs(packs_installed) do
|
for i, id in ipairs(packs_installed) do
|
||||||
local packinfo = packinfos[id]
|
local packinfo = packinfos[id]
|
||||||
|
|
||||||
packinfo.id = id
|
packinfo.id = id
|
||||||
packs_installed[i] = {packinfo.id, packinfo.title}
|
packs_installed[i] = packinfo
|
||||||
|
|
||||||
local callback = string.format('open_pack("%s")', id)
|
local callback = string.format('open_pack("%s")', id)
|
||||||
place_pack(contents, packinfo, callback)
|
place_pack(contents, packinfo, callback)
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,10 @@
|
||||||
<container id='pack_%{id}' onclick='%{callback}' size='0,80' color='#00000040' hover-color='#00000080' position-func="%{position_func}" z-index="%{index}">
|
<container id='pack_%{id}' onclick='%{callback}' size='0,80' color='#00000040' hover-color='#00000080' position-func="%{position_func}" z-index="%{index}">
|
||||||
<label color='#FFFFFF80' size='340,25' align='right' gravity='top-right'>
|
<label id='pack_%{id}_id' color='#FFFFFF80' size='340,25' align='right' gravity='top-right' markup='md'>
|
||||||
[%{id_verbose} %{version}]
|
[%{id_verbose} %{version}]
|
||||||
|
</label>
|
||||||
|
<label id='pack_%{id}_title' pos='78,6' markup='md'>
|
||||||
|
%{title}
|
||||||
</label>
|
</label>
|
||||||
<label pos='78,6'>%{title}</label>
|
|
||||||
<label if='%{creator}' color='#CCFFE5B2' size='300,20' align='right'
|
<label if='%{creator}' color='#CCFFE5B2' size='300,20' align='right'
|
||||||
gravity='bottom-right'>
|
gravity='bottom-right'>
|
||||||
%{creator}
|
%{creator}
|
||||||
|
|
|
||||||
102
res/modules/search_utils.lua
Normal file
102
res/modules/search_utils.lua
Normal file
|
|
@ -0,0 +1,102 @@
|
||||||
|
local M = {}
|
||||||
|
|
||||||
|
M.MATCHED_COLOR_DEFAULT = "[#4FC3F7]"
|
||||||
|
M.NORMAL_COLOR_DEFAULT = "[#FFFFFF]"
|
||||||
|
|
||||||
|
---Calculate fuzzy score
|
||||||
|
---@param sample str
|
||||||
|
---@param pattern str
|
||||||
|
---@param do_coloring? bool if passed, then function will also return colored_sample, where matched
|
||||||
|
---characters batched will be wrapped in color_matched and color_normal strings
|
||||||
|
---@param color_matched? str if not passed, uses the default M.MATCHED_COLOR_DEFAULT
|
||||||
|
---@param color_normal? str if not passed, uses the default M.NORMAL_COLOR_DEFAULT
|
||||||
|
---@return int match pattern match intensity, 0 for absence
|
||||||
|
---@return str? colored_sample
|
||||||
|
function M.fuzzy_score(sample, pattern, do_coloring, color_matched, color_normal)
|
||||||
|
if pattern == "" then return 0 end
|
||||||
|
|
||||||
|
color_matched = color_matched or M.MATCHED_COLOR_DEFAULT
|
||||||
|
color_normal = color_normal or M.NORMAL_COLOR_DEFAULT
|
||||||
|
local colored_sample
|
||||||
|
if do_coloring then
|
||||||
|
colored_sample = ""
|
||||||
|
end
|
||||||
|
|
||||||
|
local sample_lower = string.lower(sample)
|
||||||
|
local pattern_lower = string.lower(pattern)
|
||||||
|
|
||||||
|
local sample_len = #sample_lower
|
||||||
|
local pattern_len = #pattern_lower
|
||||||
|
|
||||||
|
if pattern_len > sample_len then return 0 end
|
||||||
|
|
||||||
|
local pattern_idx = 1
|
||||||
|
local consecutive = 0
|
||||||
|
local max_consecutive = 0
|
||||||
|
local matched_chars = 0
|
||||||
|
local total_distance = 0
|
||||||
|
local last_match_pos = -1
|
||||||
|
|
||||||
|
for i = 1, sample_len do
|
||||||
|
if pattern_idx <= pattern_len and (
|
||||||
|
sample_lower:sub(i, i) ==
|
||||||
|
pattern_lower:sub(pattern_idx, pattern_idx)) then
|
||||||
|
matched_chars = matched_chars + 1
|
||||||
|
if consecutive == 0 and do_coloring then
|
||||||
|
colored_sample = colored_sample .. color_matched
|
||||||
|
end
|
||||||
|
consecutive = consecutive + 1
|
||||||
|
if consecutive > max_consecutive then
|
||||||
|
max_consecutive = consecutive
|
||||||
|
end
|
||||||
|
|
||||||
|
if last_match_pos ~= -1 then
|
||||||
|
total_distance = total_distance + (i - last_match_pos - 1)
|
||||||
|
end
|
||||||
|
last_match_pos = i
|
||||||
|
|
||||||
|
pattern_idx = pattern_idx + 1
|
||||||
|
else
|
||||||
|
if consecutive ~= 0 and do_coloring then
|
||||||
|
colored_sample = colored_sample .. color_normal
|
||||||
|
end
|
||||||
|
consecutive = 0
|
||||||
|
end
|
||||||
|
if do_coloring then
|
||||||
|
colored_sample = colored_sample .. sample:sub(i, i)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if consecutive ~= 0 and do_coloring then
|
||||||
|
colored_sample = colored_sample .. color_normal
|
||||||
|
end
|
||||||
|
|
||||||
|
if pattern_idx <= pattern_len then
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
|
||||||
|
local coverage = matched_chars / pattern_len * 20
|
||||||
|
|
||||||
|
local consecutive_bonus = max_consecutive * 10
|
||||||
|
|
||||||
|
local start_bonus = 0
|
||||||
|
if sample_lower:sub(1, 1) == pattern_lower:sub(1, 1) then
|
||||||
|
start_bonus = 15
|
||||||
|
end
|
||||||
|
|
||||||
|
local prefix_bonus = 0
|
||||||
|
if sample_lower:find(pattern_lower, 1, true) == 1 then
|
||||||
|
prefix_bonus = 25
|
||||||
|
end
|
||||||
|
|
||||||
|
local distance_penalty = total_distance * 2
|
||||||
|
|
||||||
|
local score = coverage + consecutive_bonus + start_bonus + prefix_bonus - distance_penalty
|
||||||
|
|
||||||
|
if sample_lower:find(pattern_lower, 1, true) then
|
||||||
|
score = score + 30
|
||||||
|
end
|
||||||
|
|
||||||
|
return math.max(0, score), colored_sample
|
||||||
|
end
|
||||||
|
|
||||||
|
return M
|
||||||
Loading…
Add table
Add a link
Reference in a new issue