Skip to content

Commit

Permalink
Merge pull request JuliaLang#16 from nick-paul/option-overflow-fix
Browse files Browse the repository at this point in the history
Long options are trimmed to the width of the terminal (JuliaLang#15)
  • Loading branch information
Nicholas Paul authored Feb 16, 2018
2 parents 9a3511a + e0c15bb commit 13e4b6c
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 20 deletions.
8 changes: 5 additions & 3 deletions src/AbstractMenu.jl
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ These functions must be implemented for all subtypes of AbstractMenu.
- `pick(m::AbstractMenu, cursor::Int)`
- `cancel(m::AbstractMenu)`
- `options(m::AbstractMenu)`
- `writeLine(buf::IOBuffer, m::AbstractMenu, idx::Int, cur::Bool)`
- `writeLine(buf::IOBuffer, m::AbstractMenu, idx::Int, cur::Bool, term_width::Int)`
## Optional Functions
Expand Down Expand Up @@ -70,7 +70,7 @@ options(m::AbstractMenu) = error("unimplemented")
# This function must be implemented for all menu types. It should write
# the option at index `idx` to the buffer. If cursor is `true` it
# should also display the cursor
function writeLine(buf::IOBuffer, m::AbstractMenu, idx::Int, cur::Bool)
function writeLine(buf::IOBuffer, m::AbstractMenu, idx::Int, cur::Bool, term_width::Int)
error("unimplemented")
end

Expand Down Expand Up @@ -252,7 +252,9 @@ function printMenu(out, m::AbstractMenu, cursor::Int; init::Bool=false)
print(buf, " ")
end

writeLine(buf, m, i, i == cursor)
term_width = Base.Terminals.width(TerminalMenus.terminal)

writeLine(buf, m, i, i == cursor, term_width)

# dont print an \r\n on the last line
i != (m.pagesize+m.pageoffset) && print(buf, "\r\n")
Expand Down
23 changes: 15 additions & 8 deletions src/MultiSelectMenu.jl
Original file line number Diff line number Diff line change
Expand Up @@ -85,16 +85,23 @@ function pick(menu::MultiSelectMenu, cursor::Int)
return false #break out of the menu
end

function writeLine(buf::IOBuffer, menu::MultiSelectMenu, idx::Int, cursor::Bool)
function writeLine(buf::IOBuffer, menu::MultiSelectMenu, idx::Int, cursor::Bool, term_width::Int)
cursor_len = length(CONFIG[:cursor])
# print a ">" on the selected entry
cursor ? print(buf, CONFIG[:cursor]," ") : print(buf, " ")
if idx in menu.selected
print(buf, CONFIG[:checked], " ")
else
print(buf, CONFIG[:unchecked], " ")
end
cursor ? print(buf, CONFIG[:cursor]) : print(buf, repeat(" ", cursor_len))
print(buf, " ") # Space between cursor and text

# Checked or unchecked?
status = idx in menu.selected ? :checked : :unchecked

print(buf, CONFIG[status], " ")
padding = length(CONFIG[status]) + 1

line = replace(menu.options[idx], "\n", "\\n")
line = trimWidth(line, term_width, !cursor, cursor_len + padding)

print(buf, line)

print(buf, replace(menu.options[idx], "\n", "\\n"))
end

# d: Done, return from request
Expand Down
11 changes: 8 additions & 3 deletions src/RadioMenu.jl
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,14 @@ function pick(menu::RadioMenu, cursor::Int)
return true #break out of the menu
end

function writeLine(buf::IOBuffer, menu::RadioMenu, idx::Int, cursor::Bool)
function writeLine(buf::IOBuffer, menu::RadioMenu, idx::Int, cursor::Bool, term_width::Int)
cursor_len = length(CONFIG[:cursor])
# print a ">" on the selected entry
cursor ? print(buf, CONFIG[:cursor] ," ") : print(buf, " ")
cursor ? print(buf, CONFIG[:cursor]) : print(buf, repeat(" ", cursor_len))
print(buf, " ") # Space between cursor and text

print(buf, replace(menu.options[idx], "\n", "\\n"))
line = replace(menu.options[idx], "\n", "\\n")
line = trimWidth(line, term_width, !cursor, cursor_len)

print(buf, line)
end
12 changes: 12 additions & 0 deletions src/util.jl
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,18 @@ function disableRawMode(term)
return false
end

function trimWidth(str::String, term_width::Int, trim_right=true, pad::Int=2)
max_str_len = term_width - pad - 5
if length(str) <= max_str_len || length(str) < 6
return str
end
if trim_right
return string(str[1:max_str_len], "..")
else
return string("..", str[length(str) - max_str_len:end])
end
end


# Reads a single byte from STDIN
readNextChar(stream::IO=STDIN) = Char(read(stream,1)[1])
Expand Down
7 changes: 4 additions & 3 deletions test/multiselect_menu.jl
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,16 @@ multi_menu = MultiSelectMenu(string.(1:20))
TerminalMenus.config() # Use default chars
CONFIG = TerminalMenus.CONFIG

term_width = 100
multi_menu = MultiSelectMenu(string.(1:10))
buf = IOBuffer()
TerminalMenus.writeLine(buf, multi_menu, 1, true)
TerminalMenus.writeLine(buf, multi_menu, 1, true, term_width)
@test String(take!(buf)) == string(CONFIG[:cursor], " ", CONFIG[:unchecked], " 1")
TerminalMenus.config(cursor='+')
TerminalMenus.writeLine(buf, multi_menu, 1, true)
TerminalMenus.writeLine(buf, multi_menu, 1, true, term_width)
@test String(take!(buf)) == string("+ ", CONFIG[:unchecked], " 1")
TerminalMenus.config(charset=:unicode)
TerminalMenus.writeLine(buf, multi_menu, 1, true)
TerminalMenus.writeLine(buf, multi_menu, 1, true, term_width)
@test String(take!(buf)) == string(CONFIG[:cursor], " ", CONFIG[:unchecked], " 1")

# Test SDTIN
Expand Down
8 changes: 5 additions & 3 deletions test/radio_menu.jl
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,17 @@ TerminalMenus.cancel(radio_menu)
TerminalMenus.config() # Use default chars
CONFIG = TerminalMenus.CONFIG

# Test writeLine function
term_width = 100
radio_menu = RadioMenu(string.(1:10))
buf = IOBuffer()
TerminalMenus.writeLine(buf, radio_menu, 1, true)
TerminalMenus.writeLine(buf, radio_menu, 1, true, term_width)
@test String(take!(buf)) == string(CONFIG[:cursor], " 1")
TerminalMenus.config(cursor='+')
TerminalMenus.writeLine(buf, radio_menu, 1, true)
TerminalMenus.writeLine(buf, radio_menu, 1, true, term_width)
@test String(take!(buf)) == "+ 1"
TerminalMenus.config(charset=:unicode)
TerminalMenus.writeLine(buf, radio_menu, 1, true)
TerminalMenus.writeLine(buf, radio_menu, 1, true, term_width)
@test String(take!(buf)) == string(CONFIG[:cursor], " 1")

# Test using STDIN
Expand Down

0 comments on commit 13e4b6c

Please sign in to comment.