mirror of
https://github.com/mpv-player/mpv.git
synced 2026-10-25 12:42:04 +08:00
console.lua: highlight matching parts of selectable items
fzy returns which characters matched the search for every item, so use this to highlight them. This defaults to a light blue color that is readable with both black and white (selected) backgrounds. The returned positions are just bytes, so we can't put ASS tags or escape sequences around each byte because that would break displaying multibyte UTF-8 characters. Only put them around sequences of matched positions, and only when the sequences start and end at actual character positions.
This commit is contained in:
committed by
Kacper Michajłow
parent
a5700484be
commit
72bb227bf1
@@ -218,6 +218,11 @@ Configurable Options
|
||||
|
||||
The background color of the selected item.
|
||||
|
||||
``match_color``
|
||||
Default: ``#0088FF``
|
||||
|
||||
The color of characters that match the searched string.
|
||||
|
||||
``case_sensitive``
|
||||
Default: no on Windows, yes on other platforms.
|
||||
|
||||
|
||||
+73
-12
@@ -42,6 +42,7 @@ local opts = {
|
||||
scale_with_window = "auto",
|
||||
selected_color = '#222222',
|
||||
selected_back_color = '#FFFFFF',
|
||||
match_color = '#0088FF',
|
||||
case_sensitive = platform ~= 'windows' and true or false,
|
||||
history_dedup = true,
|
||||
persist_history = false,
|
||||
@@ -77,6 +78,8 @@ local terminal_styles = {
|
||||
selected_completion = '\027[7m',
|
||||
default_item = '\027[1m',
|
||||
disabled = '\027[38;5;8m',
|
||||
matched_position = '\027[34m',
|
||||
match_end = '\027[39m',
|
||||
}
|
||||
|
||||
local repl_active = false
|
||||
@@ -183,6 +186,18 @@ local function len_utf8(str)
|
||||
return len
|
||||
end
|
||||
|
||||
local function utf8_positions(str)
|
||||
local pos = 1
|
||||
local positions = {true}
|
||||
|
||||
while pos <= str:len() do
|
||||
pos = next_utf8(str, pos)
|
||||
positions[pos] = true
|
||||
end
|
||||
|
||||
return positions
|
||||
end
|
||||
|
||||
|
||||
-- Functions to calculate the font width.
|
||||
local width_length_ratio = 0.5
|
||||
@@ -467,9 +482,7 @@ local function fuzzy_find(needle, haystacks, case_sensitive)
|
||||
|
||||
return i[1] < j[1]
|
||||
end)
|
||||
for i, value in ipairs(result) do
|
||||
result[i] = value[1]
|
||||
end
|
||||
|
||||
return result
|
||||
end
|
||||
|
||||
@@ -480,6 +493,9 @@ local function get_matches_to_print(terminal)
|
||||
|
||||
local items = {}
|
||||
local max_lines = calculate_max_lines()
|
||||
local escape = terminal and function (str) return str end or ass_escape
|
||||
local highlight = terminal and terminal_styles.matched_position or
|
||||
'{\\1c&H' .. option_color_to_ass(opts.match_color) .. '}'
|
||||
|
||||
if selected_match < first_match_to_print then
|
||||
first_match_to_print = selected_match
|
||||
@@ -491,27 +507,68 @@ local function get_matches_to_print(terminal)
|
||||
#matches)
|
||||
|
||||
for i = first_match_to_print, last_match_to_print do
|
||||
local style = ''
|
||||
local item = ''
|
||||
local end_highlight = terminal and terminal_styles.match_end or '{\\1c}'
|
||||
|
||||
if terminal then
|
||||
if matches[i].index == default_item then
|
||||
style = terminal_styles.default_item
|
||||
item = terminal_styles.default_item
|
||||
end
|
||||
if i == selected_match then
|
||||
style = style .. terminal_styles.selected_completion
|
||||
item = item .. terminal_styles.selected_completion
|
||||
end
|
||||
else
|
||||
if i == selected_match then
|
||||
if searching_history and
|
||||
mp.get_property('osd-border-style') == 'outline-and-shadow' then
|
||||
style = get_selected_ass()
|
||||
item = get_selected_ass()
|
||||
else
|
||||
style = '{\\1c&H' .. option_color_to_ass(opts.selected_color) .. '&}'
|
||||
item = '{\\1c&H' .. option_color_to_ass(opts.selected_color) .. '&}'
|
||||
end
|
||||
end_highlight = item
|
||||
end
|
||||
end
|
||||
|
||||
items[#items + 1] = style .. matches[i].text
|
||||
local char_positions = utf8_positions(matches[i].text)
|
||||
local start_of_last_match = matches[i].positions[1]
|
||||
|
||||
if not start_of_last_match then
|
||||
item = item .. escape(matches[i].text)
|
||||
elseif start_of_last_match > 1 then
|
||||
item = item .. escape(matches[i].text:sub(1, start_of_last_match - 1))
|
||||
end
|
||||
|
||||
for j, pos in ipairs(matches[i].positions) do
|
||||
local last_pos = matches[i].positions[j - 1]
|
||||
|
||||
if last_pos and pos > last_pos + 1 then
|
||||
if char_positions[start_of_last_match] and char_positions[last_pos + 1] then
|
||||
item = item .. highlight ..
|
||||
escape(matches[i].text:sub(start_of_last_match, last_pos)) ..
|
||||
end_highlight ..
|
||||
escape(matches[i].text:sub(last_pos + 1, pos - 1))
|
||||
else
|
||||
item = item .. escape(matches[i].text:sub(start_of_last_match, pos - 1))
|
||||
end
|
||||
|
||||
start_of_last_match = pos
|
||||
end
|
||||
end
|
||||
|
||||
if start_of_last_match then
|
||||
local last_pos = matches[i].positions[#matches[i].positions]
|
||||
|
||||
if char_positions[start_of_last_match] and char_positions[last_pos + 1] then
|
||||
item = item .. highlight ..
|
||||
escape(matches[i].text:sub(start_of_last_match, last_pos)) ..
|
||||
end_highlight ..
|
||||
escape(matches[i].text:sub(last_pos + 1))
|
||||
else
|
||||
item = item .. escape(matches[i].text:sub(start_of_last_match))
|
||||
end
|
||||
end
|
||||
|
||||
items[#items + 1] = item
|
||||
end
|
||||
|
||||
return items
|
||||
@@ -864,7 +921,11 @@ local function handle_edit()
|
||||
if selectable_items then
|
||||
matches = {}
|
||||
for i, match in ipairs(fuzzy_find(line, selectable_items)) do
|
||||
matches[i] = { index = match, text = selectable_items[match] }
|
||||
matches[i] = {
|
||||
index = match[1],
|
||||
text = selectable_items[match[1]],
|
||||
positions = match[2],
|
||||
}
|
||||
end
|
||||
|
||||
if line == '' and default_item then
|
||||
@@ -1780,7 +1841,7 @@ complete = function ()
|
||||
completion_pos = completion_pos or 1
|
||||
for i, match in ipairs(fuzzy_find(before_cur:sub(completion_pos),
|
||||
completions, opts.case_sensitive)) do
|
||||
completion_buffer[i] = completions[match]
|
||||
completion_buffer[i] = completions[match[1]]
|
||||
end
|
||||
|
||||
render()
|
||||
@@ -2100,7 +2161,7 @@ mp.register_script_message('complete', function(list, start_pos)
|
||||
completion_append = ''
|
||||
for i, match in ipairs(fuzzy_find(line:sub(completion_pos, cursor),
|
||||
completions)) do
|
||||
completion_buffer[i] = completions[match]
|
||||
completion_buffer[i] = completions[match[1]]
|
||||
end
|
||||
|
||||
render()
|
||||
|
||||
Reference in New Issue
Block a user