Skip to content

Commit 4b88a60

Browse files
authored
TerminalMenus: initialize to cursor position, not menu start (#38330)
1 parent 07fd900 commit 4b88a60

File tree

2 files changed

+12
-3
lines changed

2 files changed

+12
-3
lines changed

stdlib/REPL/src/TerminalMenus/AbstractMenu.jl

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -295,8 +295,8 @@ end
295295
"""
296296
printmenu(out, m::AbstractMenu, cursoridx::Int; init::Bool=false, oldstate=nothing) -> newstate
297297
298-
Display the state of a menu. `init=true` causes `m.pageoffset` to be initialized to zero,
299-
and starts printing at the current cursor location; when `init` is false, the terminal will
298+
Display the state of a menu. `init=true` causes `m.pageoffset` to be initialized to start printing at
299+
or just above the current cursor location; when `init` is false, the terminal will
300300
preserve the current setting of `m.pageoffset` and overwrite the previous display.
301301
Returns `newstate`, which can be passed in as `oldstate` on the next call to allow accurate
302302
overwriting of the previous display.
@@ -314,7 +314,8 @@ function printmenu(out::IO, m::AbstractMenu, cursoridx::Int; oldstate=nothing, i
314314
ncleared = oldstate === nothing ? m.pagesize-1 : oldstate
315315

316316
if init
317-
m.pageoffset = 0
317+
# like clamp, except this takes the min if max < min
318+
m.pageoffset = max(0, min(cursoridx - m.pagesize ÷ 2, lastoption - m.pagesize))
318319
else
319320
print(buf, "\x1b[999D\x1b[$(ncleared)A") # move left 999 spaces and up `ncleared` lines
320321
end

stdlib/REPL/test/TerminalMenus/radio_menu.jl

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,14 @@ for kws in ((charset=:ascii,),
3434
TerminalMenus.printmenu(buf, radio_menu, 2; init=true)
3535
@test startswith(String(take!(buf)), string("\e[2K 1\r\n\e[2K $c 2"))
3636
end
37+
@testset begin "cursor page"
38+
radio_menu = RadioMenu(string.(1:20); charset=:ascii)
39+
buf = IOBuffer()
40+
TerminalMenus.printmenu(buf, radio_menu, 19; init=true)
41+
@test String(take!(buf)) == "\e[2K^ 11\r\n\e[2K 12\r\n\e[2K 13\r\n\e[2K 14\r\n\e[2K 15\r\n\e[2K 16\r\n\e[2K 17\r\n\e[2K 18\r\n\e[2K > 19\r\n\e[2K 20"
42+
TerminalMenus.printmenu(buf, radio_menu, 8; init=true)
43+
@test String(take!(buf)) == "\e[2K^ 4\r\n\e[2K 5\r\n\e[2K 6\r\n\e[2K 7\r\n\e[2K > 8\r\n\e[2K 9\r\n\e[2K 10\r\n\e[2K 11\r\n\e[2K 12\r\n\e[2Kv 13"
44+
end
3745

3846
# Test using stdin
3947
radio_menu = RadioMenu(string.(1:10); charset=:ascii)

0 commit comments

Comments
 (0)