Skip to content

Commit 4291249

Browse files
committed
console.lua: implement horizontal scroll
Bind Shift+LEFT, Shift+RIGHT, Shift+WHEEL_DOWN, Shift+WHEEL_UP, WHEEL_LEFT, WHEEL_RIGHT to scroll the menu horizontally. This lets you see long items that get clipped, like long history entries and key bindings. With proportional fonts items scroll in different amounts, but it's still usable.
1 parent 233e896 commit 4291249

2 files changed

Lines changed: 57 additions & 14 deletions

File tree

DOCS/man/select.rst

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,12 @@ PGUP and Ctrl+b
2828
PGDN and Ctrl+f
2929
Scroll down one page.
3030

31+
Shift+LEFT
32+
Scroll left.
33+
34+
Shift+RIGHT
35+
Scroll right.
36+
3137
Ctrl+y
3238
Copy the focused item to the clipboard.
3339

@@ -41,6 +47,12 @@ WHEEL_UP
4147
WHEEL_DOWN
4248
Scroll down.
4349

50+
WHEEL_LEFT and Shift+WHEEL_DOWN
51+
Scroll left.
52+
53+
WHEEL_RIGHT and Shift+WHEEL_UP
54+
Scroll right.
55+
4456
Typing printable characters does a fuzzy search of the presented items.
4557

4658
If the query starts with ``'``, only exact matches are filtered. You can also

player/lua/console.lua

Lines changed: 45 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ local first_match_to_print = 1
114114
local default_item
115115
local item_positions = {}
116116
local max_item_width = 0
117+
local horizontal_offset = 0
117118

118119
local complete
119120
local cycle_through_completions
@@ -197,7 +198,7 @@ local function utf8_positions(str)
197198
positions[pos] = true
198199
end
199200

200-
return positions
201+
return positions, pos
201202
end
202203

203204

@@ -564,42 +565,55 @@ local function get_matches_to_print(terminal)
564565
end
565566
end
566567

567-
local char_positions = utf8_positions(matches[i].text)
568-
local start_of_last_match = matches[i].positions[1]
568+
local char_positions, last_char_pos = utf8_positions(matches[i].text)
569+
local start = horizontal_offset
570+
repeat
571+
start = start + 1
572+
until char_positions[start] or start > last_char_pos
573+
local text = matches[i].text:sub(start)
574+
char_positions = utf8_positions(text)
575+
576+
local positions = {}
577+
for _, position in ipairs(matches[i].positions) do
578+
if position >= start then
579+
positions[#positions + 1] = position - start + 1
580+
end
581+
end
582+
local start_of_last_match = positions[1]
569583

570584
if not start_of_last_match then
571-
item = item .. escape(matches[i].text)
585+
item = item .. escape(text)
572586
elseif start_of_last_match > 1 then
573-
item = item .. escape(matches[i].text:sub(1, start_of_last_match - 1))
587+
item = item .. escape(text:sub(1, start_of_last_match - 1))
574588
end
575589

576-
for j, pos in ipairs(matches[i].positions) do
577-
local last_pos = matches[i].positions[j - 1]
590+
for j, pos in ipairs(positions) do
591+
local last_pos = positions[j - 1]
578592

579593
if last_pos and pos > last_pos + 1 then
580594
if char_positions[start_of_last_match] and char_positions[last_pos + 1] then
581595
item = item .. highlight ..
582-
escape(matches[i].text:sub(start_of_last_match, last_pos)) ..
596+
escape(text:sub(start_of_last_match, last_pos)) ..
583597
end_highlight ..
584-
escape(matches[i].text:sub(last_pos + 1, pos - 1))
598+
escape(text:sub(last_pos + 1, pos - 1))
585599
else
586-
item = item .. escape(matches[i].text:sub(start_of_last_match, pos - 1))
600+
item = item .. escape(text:sub(start_of_last_match, pos - 1))
587601
end
588602

589603
start_of_last_match = pos
590604
end
591605
end
592606

593607
if start_of_last_match then
594-
local last_pos = matches[i].positions[#matches[i].positions]
608+
local last_pos = positions[#positions]
595609

596610
if char_positions[start_of_last_match] and char_positions[last_pos + 1] then
597611
item = item .. highlight ..
598-
escape(matches[i].text:sub(start_of_last_match, last_pos)) ..
612+
escape(text:sub(start_of_last_match, last_pos)) ..
599613
end_highlight ..
600-
escape(matches[i].text:sub(last_pos + 1))
614+
escape(text:sub(last_pos + 1))
601615
else
602-
item = item .. escape(matches[i].text:sub(start_of_last_match))
616+
item = item .. escape(text:sub(start_of_last_match))
603617
end
604618
end
605619

@@ -1202,6 +1216,15 @@ local function move_history(amount, is_wheel)
12021216
render()
12031217
end
12041218

1219+
local function horizontal_scroll(amount)
1220+
if not selectable_items then
1221+
return
1222+
end
1223+
1224+
horizontal_offset = math.max(horizontal_offset + amount, 0)
1225+
render()
1226+
end
1227+
12051228
-- Go to the first command in the command history (PgUp)
12061229
local function handle_pgup()
12071230
if selectable_items then
@@ -1231,6 +1254,7 @@ local function search_history()
12311254

12321255
searching_history = true
12331256
selectable_items = {}
1257+
horizontal_offset = 0
12341258

12351259
for i = 1, #history do
12361260
selectable_items[i] = history[#history + 1 - i]
@@ -1497,6 +1521,12 @@ local function get_bindings()
14971521
{ "wheel_down", function() move_history(1, true) end },
14981522
{ "wheel_left", function() end },
14991523
{ "wheel_right", function() end },
1524+
{ "shift+left", function() horizontal_scroll(-5) end },
1525+
{ "shift+right", function() horizontal_scroll(5) end },
1526+
{ "wheel_left", function() horizontal_scroll(-5) end },
1527+
{ "wheel_right", function() horizontal_scroll(5) end },
1528+
{ "shift+wheel_up", function() horizontal_scroll(-5) end },
1529+
{ "shift+wheel_down", function() horizontal_scroll(5) end },
15001530
{ "ctrl+left", prev_word },
15011531
{ "alt+b", prev_word },
15021532
{ "ctrl+right", next_word },
@@ -1653,6 +1683,7 @@ mp.register_script_message("get-input", function (script_name, args)
16531683

16541684
if args.items then
16551685
selectable_items = {}
1686+
horizontal_offset = 0
16561687

16571688
-- Limit the number of characters to prevent libass from freezing mpv.
16581689
-- Not important for terminal output.

0 commit comments

Comments
 (0)