mirror of
https://github.com/mpv-player/mpv
synced 2025-03-11 08:37:59 +00:00
console.lua: cycle through completions
This commit is contained in:
parent
c16f868dd7
commit
f886eb5678
@ -86,7 +86,11 @@ Shift+INSERT
|
|||||||
Paste text (uses the primary selection on X11 and Wayland).
|
Paste text (uses the primary selection on X11 and Wayland).
|
||||||
|
|
||||||
TAB and Ctrl+i
|
TAB and Ctrl+i
|
||||||
Complete the command or property name at the cursor.
|
Complete the text at the cursor. The first press inserts the longest common
|
||||||
|
prefix of the completions, and subsequent presses cycle through them.
|
||||||
|
|
||||||
|
Shift+TAB
|
||||||
|
Cycle through the completions backwards.
|
||||||
|
|
||||||
Ctrl+l
|
Ctrl+l
|
||||||
Clear all log messages from the console.
|
Clear all log messages from the console.
|
||||||
|
@ -72,6 +72,7 @@ local styles = {
|
|||||||
error = '{\\1c&H7a77f2&}',
|
error = '{\\1c&H7a77f2&}',
|
||||||
fatal = '{\\1c&H5791f9&\\b1}',
|
fatal = '{\\1c&H5791f9&\\b1}',
|
||||||
suggestion = '{\\1c&Hcc99cc&}',
|
suggestion = '{\\1c&Hcc99cc&}',
|
||||||
|
selected_suggestion = '{\\1c&H2fbdfa&\\b1}',
|
||||||
}
|
}
|
||||||
|
|
||||||
local repl_active = false
|
local repl_active = false
|
||||||
@ -82,10 +83,13 @@ local cursor = 1
|
|||||||
local history = {}
|
local history = {}
|
||||||
local history_pos = 1
|
local history_pos = 1
|
||||||
local log_buffer = {}
|
local log_buffer = {}
|
||||||
local suggestion_buffer = {}
|
|
||||||
local key_bindings = {}
|
local key_bindings = {}
|
||||||
local global_margins = { t = 0, b = 0 }
|
local global_margins = { t = 0, b = 0 }
|
||||||
|
|
||||||
|
local suggestion_buffer = {}
|
||||||
|
local selected_suggestion_index
|
||||||
|
local completion_start_position
|
||||||
|
local completion_append
|
||||||
local file_commands = {}
|
local file_commands = {}
|
||||||
local path_separator = platform == 'windows' and '\\' or '/'
|
local path_separator = platform == 'windows' and '\\' or '/'
|
||||||
|
|
||||||
@ -281,7 +285,9 @@ function format_table(list, width_max, rows_max)
|
|||||||
|
|
||||||
local spaces = math.floor((width_max - width_total) / (column_count - 1))
|
local spaces = math.floor((width_max - width_total) / (column_count - 1))
|
||||||
spaces = math.max(spaces_min, math.min(spaces_max, spaces))
|
spaces = math.max(spaces_min, math.min(spaces_max, spaces))
|
||||||
local spacing = column_count > 1 and string.format('%' .. spaces .. 's', ' ') or ''
|
local spacing = column_count > 1
|
||||||
|
and ass_escape(string.format('%' .. spaces .. 's', ' '))
|
||||||
|
or ''
|
||||||
|
|
||||||
local rows = {}
|
local rows = {}
|
||||||
for row = 1, row_count do
|
for row = 1, row_count do
|
||||||
@ -292,12 +298,17 @@ function format_table(list, width_max, rows_max)
|
|||||||
-- more then 99 leads to 'invalid format (width or precision too long)'
|
-- more then 99 leads to 'invalid format (width or precision too long)'
|
||||||
local format_string = column == column_count and '%s'
|
local format_string = column == column_count and '%s'
|
||||||
or '%-' .. math.min(column_widths[column], 99) .. 's'
|
or '%-' .. math.min(column_widths[column], 99) .. 's'
|
||||||
columns[column] = string.format(format_string, list[i])
|
columns[column] = ass_escape(string.format(format_string, list[i]))
|
||||||
|
|
||||||
|
if i == selected_suggestion_index then
|
||||||
|
columns[column] = styles.selected_suggestion .. columns[column]
|
||||||
|
.. '{\\b0}'.. styles.suggestion
|
||||||
|
end
|
||||||
end
|
end
|
||||||
-- first row is at the bottom
|
-- first row is at the bottom
|
||||||
rows[row_count - row + 1] = table.concat(columns, spacing)
|
rows[row_count - row + 1] = table.concat(columns, spacing)
|
||||||
end
|
end
|
||||||
return table.concat(rows, '\n'), row_count
|
return table.concat(rows, ass_escape('\n')), row_count
|
||||||
end
|
end
|
||||||
|
|
||||||
local function print_to_terminal()
|
local function print_to_terminal()
|
||||||
@ -390,7 +401,7 @@ function update()
|
|||||||
local width_max = math.ceil(screenx / opts.font_size * get_font_hw_ratio())
|
local width_max = math.ceil(screenx / opts.font_size * get_font_hw_ratio())
|
||||||
|
|
||||||
local suggestions, rows = format_table(suggestion_buffer, width_max, lines_max)
|
local suggestions, rows = format_table(suggestion_buffer, width_max, lines_max)
|
||||||
local suggestion_ass = style .. styles.suggestion .. ass_escape(suggestions)
|
local suggestion_ass = style .. styles.suggestion .. suggestions
|
||||||
|
|
||||||
local log_ass = ''
|
local log_ass = ''
|
||||||
local log_messages = #log_buffer
|
local log_messages = #log_buffer
|
||||||
@ -943,8 +954,29 @@ function max_overlap_length(s1, s2)
|
|||||||
return 0
|
return 0
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function cycle_through_suggestions(backwards)
|
||||||
|
selected_suggestion_index = selected_suggestion_index + (backwards and -1 or 1)
|
||||||
|
|
||||||
|
if selected_suggestion_index > #suggestion_buffer then
|
||||||
|
selected_suggestion_index = 1
|
||||||
|
elseif selected_suggestion_index < 1 then
|
||||||
|
selected_suggestion_index = #suggestion_buffer
|
||||||
|
end
|
||||||
|
|
||||||
|
local before_cur = line:sub(1, completion_start_position - 1) ..
|
||||||
|
suggestion_buffer[selected_suggestion_index] .. completion_append
|
||||||
|
line = before_cur .. line:sub(cursor)
|
||||||
|
cursor = before_cur:len() + 1
|
||||||
|
update()
|
||||||
|
end
|
||||||
|
|
||||||
-- Complete the option or property at the cursor (TAB)
|
-- Complete the option or property at the cursor (TAB)
|
||||||
function complete()
|
function complete(backwards)
|
||||||
|
if #suggestion_buffer > 0 then
|
||||||
|
cycle_through_suggestions(backwards)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
local before_cur = line:sub(1, cursor - 1)
|
local before_cur = line:sub(1, cursor - 1)
|
||||||
local after_cur = line:sub(cursor)
|
local after_cur = line:sub(cursor)
|
||||||
|
|
||||||
@ -952,45 +984,49 @@ function complete()
|
|||||||
for _, completer in ipairs(build_completers()) do
|
for _, completer in ipairs(build_completers()) do
|
||||||
-- Completer patterns should return the start of the word to be
|
-- Completer patterns should return the start of the word to be
|
||||||
-- completed as the first capture.
|
-- completed as the first capture.
|
||||||
local s, s2 = before_cur:match(completer.pattern)
|
local s2
|
||||||
if not s then
|
completion_start_position, s2 = before_cur:match(completer.pattern)
|
||||||
|
if not completion_start_position then
|
||||||
-- Multiple input commands can be separated by semicolons, so all
|
-- Multiple input commands can be separated by semicolons, so all
|
||||||
-- completions that are anchored at the start of the string with
|
-- completions that are anchored at the start of the string with
|
||||||
-- '^' can start from a semicolon as well. Replace ^ with ; and try
|
-- '^' can start from a semicolon as well. Replace ^ with ; and try
|
||||||
-- to match again.
|
-- to match again.
|
||||||
s, s2 = before_cur:match(completer.pattern:gsub('^^', ';'))
|
completion_start_position, s2 =
|
||||||
|
before_cur:match(completer.pattern:gsub('^^', ';'))
|
||||||
end
|
end
|
||||||
if s then
|
if completion_start_position then
|
||||||
local hint
|
local hint
|
||||||
if s2 then
|
if s2 then
|
||||||
hint = s
|
hint = completion_start_position
|
||||||
s = s2
|
completion_start_position = s2
|
||||||
end
|
end
|
||||||
|
|
||||||
-- If the completer's pattern found a word, check the completer's
|
-- If the completer's pattern found a word, check the completer's
|
||||||
-- list for possible completions
|
-- list for possible completions
|
||||||
local part = before_cur:sub(s)
|
local part = before_cur:sub(completion_start_position)
|
||||||
local completions, prefix = complete_match(part, completer.list(hint))
|
local completions, prefix = complete_match(part, completer.list(hint))
|
||||||
if #completions > 0 then
|
if #completions > 0 then
|
||||||
-- If there was only one full match from the list, add
|
-- If there was only one full match from the list, add
|
||||||
-- completer.append to the final string. This is normally a
|
-- completer.append to the final string. This is normally a
|
||||||
-- space or a quotation mark followed by a space.
|
-- space or a quotation mark followed by a space.
|
||||||
local after_cur_index = 1
|
local after_cur_index = 1
|
||||||
|
completion_append = completer.append or ''
|
||||||
if #completions == 1 then
|
if #completions == 1 then
|
||||||
local append = completer.append or ''
|
prefix = prefix .. completion_append
|
||||||
prefix = prefix .. append
|
|
||||||
|
|
||||||
-- calculate offset into after_cur
|
-- calculate offset into after_cur
|
||||||
local prefix_len = common_prefix_length(append, after_cur)
|
local prefix_len = common_prefix_length(completion_append, after_cur)
|
||||||
local overlap_size = max_overlap_length(append, after_cur)
|
local overlap_size = max_overlap_length(completion_append, after_cur)
|
||||||
after_cur_index = math.max(prefix_len, overlap_size) + 1
|
after_cur_index = math.max(prefix_len, overlap_size) + 1
|
||||||
else
|
else
|
||||||
table.sort(completions)
|
table.sort(completions)
|
||||||
suggestion_buffer = completions
|
suggestion_buffer = completions
|
||||||
|
selected_suggestion_index = 0
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Insert the completion and update
|
-- Insert the completion and update
|
||||||
before_cur = before_cur:sub(1, s - 1) .. prefix
|
before_cur = before_cur:sub(1, completion_start_position - 1) ..
|
||||||
|
prefix
|
||||||
cursor = before_cur:len() + 1
|
cursor = before_cur:len() + 1
|
||||||
line = before_cur .. after_cur:sub(after_cur_index)
|
line = before_cur .. after_cur:sub(after_cur_index)
|
||||||
update()
|
update()
|
||||||
@ -1157,6 +1193,7 @@ function get_bindings()
|
|||||||
{ 'alt+f', next_word },
|
{ 'alt+f', next_word },
|
||||||
{ 'tab', complete },
|
{ 'tab', complete },
|
||||||
{ 'ctrl+i', complete },
|
{ 'ctrl+i', complete },
|
||||||
|
{ 'shift+tab', function() complete(true) end },
|
||||||
{ 'ctrl+a', go_home },
|
{ 'ctrl+a', go_home },
|
||||||
{ 'home', go_home },
|
{ 'home', go_home },
|
||||||
{ 'ctrl+e', go_end },
|
{ 'ctrl+e', go_end },
|
||||||
|
Loading…
Reference in New Issue
Block a user