Skip to content

Commit

Permalink
Fix layout of REPL completions with newlines (#45844)
Browse files Browse the repository at this point in the history
Co-authored-by: Jameson Nash <[email protected]>

Co-authored-by: Jameson Nash <[email protected]>
  • Loading branch information
Liozou and vtjnash committed Sep 6, 2022
1 parent 22713d8 commit 61b5a08
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 10 deletions.
25 changes: 15 additions & 10 deletions stdlib/REPL/src/LineEdit.jl
Original file line number Diff line number Diff line change
Expand Up @@ -322,23 +322,28 @@ end

# Show available completions
function show_completions(s::PromptState, completions::Vector{String})
colmax = maximum(map(length, completions))
num_cols = max(div(width(terminal(s)), colmax+2), 1)
entries_per_col, r = divrem(length(completions), num_cols)
entries_per_col += r != 0
# skip any lines of input after the cursor
cmove_down(terminal(s), input_string_newlines_aftercursor(s))
println(terminal(s))
for row = 1:entries_per_col
for col = 0:num_cols
idx = row + col*entries_per_col
if idx <= length(completions)
cmove_col(terminal(s), (colmax+2)*col+1)
if any(Base.Fix1(occursin, '\n'), completions)
foreach(Base.Fix1(println, terminal(s)), completions)
else
colmax = 2 + maximum(length, completions; init=1) # n.b. length >= textwidth
num_cols = max(div(width(terminal(s)), colmax), 1)
n = length(completions)
entries_per_col = cld(n, num_cols)
idx = 0
for _ in 1:entries_per_col
for col = 0:(num_cols-1)
idx += 1
idx > n && break
cmove_col(terminal(s), colmax*col+1)
print(terminal(s), completions[idx])
end
println(terminal(s))
end
println(terminal(s))
end

# make space for the prompt
for i = 1:input_string_newlines(s)
println(terminal(s))
Expand Down
14 changes: 14 additions & 0 deletions stdlib/REPL/test/lineedit.jl
Original file line number Diff line number Diff line change
Expand Up @@ -906,3 +906,17 @@ end
@test get_last_word("a[b[]]") == "b"
@test get_last_word("a[]") == "a[]"
end

@testset "issue #45836" begin
term = FakeTerminal(IOBuffer(), IOBuffer(), IOBuffer())
promptstate = REPL.LineEdit.init_state(term, REPL.LineEdit.mode(new_state()))
strings = ["abcdef", "123456", "ijklmn"]
REPL.LineEdit.show_completions(promptstate, strings)
completion = String(take!(term.out_stream))
@test completion == "\033[0B\n\rabcdef\r\033[8C123456\r\033[16Cijklmn\n"
strings2 = ["abcdef", "123456\nijklmn"]
promptstate = REPL.LineEdit.init_state(term, REPL.LineEdit.mode(new_state()))
REPL.LineEdit.show_completions(promptstate, strings2)
completion2 = String(take!(term.out_stream))
@test completion2 == "\033[0B\nabcdef\n123456\nijklmn\n"
end

0 comments on commit 61b5a08

Please sign in to comment.