From 5bb376c738b20d873166da79f12b303dc994978f Mon Sep 17 00:00:00 2001 From: Nick Date: Thu, 15 Feb 2018 15:25:13 -0500 Subject: [PATCH] Long options are trimmed to the width of the terminal (#15) --- src/AbstractMenu.jl | 4 +++- src/MultiSelectMenu.jl | 23 +++++++++++++++-------- src/RadioMenu.jl | 11 ++++++++--- src/util.jl | 12 ++++++++++++ test/multiselect_menu.jl | 7 ++++--- test/radio_menu.jl | 8 +++++--- 6 files changed, 47 insertions(+), 18 deletions(-) diff --git a/src/AbstractMenu.jl b/src/AbstractMenu.jl index 508178f50f8a6..05ba82437223e 100644 --- a/src/AbstractMenu.jl +++ b/src/AbstractMenu.jl @@ -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") diff --git a/src/MultiSelectMenu.jl b/src/MultiSelectMenu.jl index e3ae58213fb46..05ec6e1799747 100644 --- a/src/MultiSelectMenu.jl +++ b/src/MultiSelectMenu.jl @@ -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 diff --git a/src/RadioMenu.jl b/src/RadioMenu.jl index 0217255ce4d3d..1ca91998656d8 100644 --- a/src/RadioMenu.jl +++ b/src/RadioMenu.jl @@ -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 diff --git a/src/util.jl b/src/util.jl index e56af21402008..b8128e62b5963 100644 --- a/src/util.jl +++ b/src/util.jl @@ -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]) diff --git a/test/multiselect_menu.jl b/test/multiselect_menu.jl index a12ebb23a77c5..549fddd2e8c78 100644 --- a/test/multiselect_menu.jl +++ b/test/multiselect_menu.jl @@ -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 diff --git a/test/radio_menu.jl b/test/radio_menu.jl index 05d73605d2799..a0e61c4e7c508 100644 --- a/test/radio_menu.jl +++ b/test/radio_menu.jl @@ -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