@@ -836,35 +836,99 @@ end
836
836
--- @return MenuStackChild[]
837
837
function search_items (items , query , recursive , prefix )
838
838
local result = {}
839
+ local haystacks = {}
840
+ local flat_items = {}
839
841
local concat = table.concat
842
+ local romanization = need_romanization ()
843
+
840
844
for _ , item in ipairs (items ) do
841
845
if item .selectable ~= false then
842
846
local prefixed_title = prefix and prefix .. ' / ' .. (item .title or ' ' ) or item .title
847
+ haystacks [# haystacks + 1 ] = item .title
848
+ flat_items [# flat_items + 1 ] = item
849
+
843
850
if item .items and recursive then
844
851
itable_append (result , search_items (item .items , query , recursive , prefixed_title ))
845
- else
846
- local title = item .title and item .title :lower ()
847
- local hint = item .hint and item .hint :lower ()
848
- local initials_title = title and concat (initials (title )) --[[ @as string]]
849
- local romanization = need_romanization ()
850
- if romanization then
851
- ligature_conv_title = title and char_conv (title , true )
852
- initials_conv_title = title and concat (initials (char_conv (title , false )))
852
+ end
853
+ end
854
+ end
855
+
856
+ local seen = {}
857
+
858
+ local fuzzy = fzy .filter (query , haystacks , false )
859
+ for _ , match in ipairs (fuzzy ) do
860
+ local idx , positions , score = match [1 ], match [2 ], match [3 ]
861
+ local matched_title = haystacks [idx ]
862
+ local item = flat_items [idx ]
863
+ local prefixed_title = prefix and prefix .. ' / ' .. (item .title or ' ' ) or item .title
864
+
865
+ if item .selectable ~= false and not (item .items and recursive ) and not seen [item ] then
866
+ local bold = item .bold
867
+ local font_color = item .active and fgt or bgt
868
+ local ass_safe_title = highlight_match (matched_title , positions , font_color , bold ) or nil
869
+ local new_item = table_assign ({}, item )
870
+ new_item .title = prefixed_title
871
+ new_item .ass_safe_title = prefix and prefix .. ' / ' .. (ass_safe_title or ' ' ) or ass_safe_title
872
+ new_item .score = score
873
+ result [# result + 1 ] = new_item
874
+ seen [item ] = true
875
+ end
876
+ end
877
+
878
+ for _ , item in ipairs (items ) do
879
+ local title = item .title and item .title :lower ()
880
+ local hint = item .hint and item .hint :lower ()
881
+ local bold = item .bold
882
+ local font_color = item .active and fgt or bgt
883
+ local ass_safe_title = nil
884
+ local prefixed_title = prefix and prefix .. ' / ' .. (item .title or ' ' ) or item .title
885
+ if item .selectable ~= false and not (item .items and recursive ) and not seen [item ] then
886
+ local score = 0
887
+ local match = false
888
+
889
+ if title and romanization then
890
+ local ligature_conv_title , ligature_roman = char_conv (title , true )
891
+ local initials_arr_conv , initials_roman = char_conv (title , false )
892
+ local initials_conv_title = concat (initials (initials_arr_conv ))
893
+ if ligature_conv_title :find (query , 1 , true ) then
894
+ match = true
895
+ score = 1000
896
+ local pos = get_roman_match_positions (title , query , " ligature" , ligature_roman )
897
+ if pos then
898
+ ass_safe_title = highlight_match (item .title , pos , font_color , bold )
899
+ end
900
+ elseif initials_conv_title :find (query , 1 , true ) then
901
+ match = true
902
+ score = 900
903
+ local pos = get_roman_match_positions (title , query , " initial" , initials_roman )
904
+ if pos then
905
+ ass_safe_title = highlight_match (item .title , pos , font_color , bold )
906
+ end
853
907
end
854
- if title and title :find (query , 1 , true ) or
855
- title and romanization and ligature_conv_title :find (query , 1 , true ) or
856
- hint and hint :find (query , 1 , true ) or
857
- title and initials_title :find (query , 1 , true ) or
858
- title and romanization and initials_conv_title :find (query , 1 , true ) or
859
- hint and concat (initials (hint )):find (query , 1 , true ) then
860
- item = table_assign ({}, item )
861
- item .title = prefixed_title
862
- item .ass_safe_title = nil
863
- result [# result + 1 ] = item
908
+ end
909
+
910
+ if hint and not match then
911
+ if hint :find (query , 1 , true ) then
912
+ match = true
913
+ score = 100
914
+ elseif concat (initials (hint )):find (query , 1 , true ) then
915
+ match = true
916
+ score = 90
864
917
end
865
918
end
919
+
920
+ if match then
921
+ local new_item = table_assign ({}, item )
922
+ new_item .title = prefixed_title
923
+ new_item .ass_safe_title = prefix and prefix .. ' / ' .. (ass_safe_title or ' ' ) or ass_safe_title
924
+ new_item .score = score
925
+ result [# result + 1 ] = new_item
926
+ end
866
927
end
867
928
end
929
+
930
+ table.sort (result , function (a , b ) return a .score > b .score end )
931
+
868
932
return result
869
933
end
870
934
0 commit comments