console: cull lines outside of visible area

Lines that would be outside of the visible area are now culled.
The log messages were already culled, however with the introduction
of suggestions, they also needed a small update.
This commit is contained in:
Christoph Heinrich 2022-06-20 22:28:04 +02:00 committed by Dudemanguy
parent ed8a919812
commit d2c92f7653
1 changed files with 25 additions and 18 deletions

View File

@ -139,11 +139,14 @@ function ass_escape(str)
return str return str
end end
-- Takes a list of strings and a max width in characters -- Takes a list of strings, a max width in characters and
-- returns a string containing the formatted table -- optionally a max row count.
function format_table(list, width_max) -- The result contains at least one column.
-- Rows are cut off from the top if rows_max is specified.
-- returns a string containing the formatted table and the row count
function format_table(list, width_max, rows_max)
if #list == 0 then if #list == 0 then
return '' return '', 0
end end
local spaces_min = 2 local spaces_min = 2
@ -188,7 +191,8 @@ function format_table(list, width_max)
local spacing = column_count > 1 and string.format('%' .. spaces .. 's', ' ') or '' local spacing = column_count > 1 and string.format('%' .. spaces .. 's', ' ') or ''
local rows = {} local rows = {}
for row = 1, row_count do local rows_truncated = math.min(row_count, rows_max)
for row = 1, rows_truncated do
local columns = {} local columns = {}
for column = 1, column_count do for column = 1, column_count do
local i = row + (column - 1) * row_count local i = row + (column - 1) * row_count
@ -198,9 +202,9 @@ function format_table(list, width_max)
columns[column] = string.format(format_string, list[i]) columns[column] = string.format(format_string, list[i])
end end
-- first row is at the bottom -- first row is at the bottom
rows[row_count - row + 1] = table.concat(columns, spacing) rows[rows_truncated - row + 1] = table.concat(columns, spacing)
end end
return table.concat(rows, '\n') return table.concat(rows, '\n'), rows_truncated
end end
-- Render the REPL and console as an ASS OSD -- Render the REPL and console as an ASS OSD
@ -246,14 +250,22 @@ function update()
local before_cur = ass_escape(line:sub(1, cursor - 1)) local before_cur = ass_escape(line:sub(1, cursor - 1))
local after_cur = ass_escape(line:sub(cursor)) local after_cur = ass_escape(line:sub(cursor))
-- Render log messages as ASS. This will render at most screeny / font_size -- Render log messages as ASS.
-- messages. -- This will render at most screeny / font_size - 1 messages.
-- lines above the prompt
-- subtract 1.5 to account for the input line
local screeny_factor = (1 - global_margins.t - global_margins.b)
local lines_max = math.ceil(screeny * screeny_factor / opts.font_size - 1.5)
-- Estimate how many characters fit in one line
local width_max = math.ceil(screenx / opts.font_size * opts.font_hw_ratio)
local suggestions, rows = format_table(suggestion_buffer, width_max, lines_max)
local suggestion_ass = style .. styles.suggestion .. ass_escape(suggestions)
local log_ass = '' local log_ass = ''
local log_messages = #log_buffer local log_messages = #log_buffer
local screeny_factor = (1 - global_margins.t - global_margins.b) local log_max_lines = math.max(0, lines_max - rows)
-- subtract 1.5 to account for the input line
local log_max_lines = screeny * screeny_factor / opts.font_size - 1.5
log_max_lines = math.ceil(log_max_lines)
if log_max_lines < log_messages then if log_max_lines < log_messages then
log_messages = log_max_lines log_messages = log_max_lines
end end
@ -261,11 +273,6 @@ function update()
log_ass = log_ass .. style .. log_buffer[i].style .. ass_escape(log_buffer[i].text) log_ass = log_ass .. style .. log_buffer[i].style .. ass_escape(log_buffer[i].text)
end end
-- estimate how many characters fit in a line
local width_max = math.ceil(screenx / opts.font_size * opts.font_hw_ratio)
local suggestions = ass_escape(format_table(suggestion_buffer, width_max))
local suggestion_ass = style .. styles.suggestion .. suggestions
ass:new_event() ass:new_event()
ass:an(1) ass:an(1)
ass:pos(2, screeny - 2 - global_margins.b * screeny) ass:pos(2, screeny - 2 - global_margins.b * screeny)