diff --git a/base/LineEdit.jl b/base/LineEdit.jl index ae777dcf86fb4..88972b7f00a0c 100644 --- a/base/LineEdit.jl +++ b/base/LineEdit.jl @@ -8,6 +8,7 @@ import ..Terminals: raw!, width, height, cmove, getX, import Base: ensureroom, peek, show, AnyDict abstract TextInterface +abstract ModeState export run_interface, Prompt, ModalInterface, transition, reset_state, edit_insert, keymap @@ -26,9 +27,6 @@ type MIState end MIState(i, c, a, m) = MIState(i, c, a, m, "", Char[], 0) -type Mode <: TextInterface -end - type Prompt <: TextInterface prompt first_prompt @@ -37,7 +35,7 @@ type Prompt <: TextInterface prompt_prefix # Same as prefix except after the prompt prompt_suffix - keymap_func + keymap_dict keymap_func_data complete on_enter @@ -53,7 +51,7 @@ immutable InputAreaState curs_row::Int64 end -type PromptState +type PromptState <: ModeState terminal::TextTerminal p::Prompt input_buffer::IOBuffer @@ -61,7 +59,7 @@ type PromptState indent::Int end -input_string(s::PromptState) = bytestring(pointer(s.input_buffer.data), s.input_buffer.size) +input_string(s::PromptState) = bytestring(s.input_buffer) input_string_newlines(s::PromptState) = count(c->(c == '\n'), input_string(s)) function input_string_newlines_aftercursor(s::PromptState) @@ -185,9 +183,10 @@ end prompt_string(s::PromptState) = s.p.prompt prompt_string(s::AbstractString) = s -refresh_multi_line(termbuf::TerminalBuffer, s::PromptState) = s.ias = +refresh_multi_line(s::ModeState) = refresh_multi_line(terminal(s), s) +refresh_multi_line(termbuf::TerminalBuffer, s::ModeState) = s.ias = refresh_multi_line(termbuf, terminal(s), buffer(s), s.ias, s, indent = s.indent) - +refresh_multi_line(termbuf::TerminalBuffer, term, s::ModeState) = (@assert term == terminal(s); refresh_multi_line(termbuf,s)) function refresh_multi_line(termbuf::TerminalBuffer, terminal::UnixTerminal, buf, state::InputAreaState, prompt = ""; indent = 0) cols = width(terminal) @@ -299,6 +298,16 @@ function refresh_multi_line(termbuf::TerminalBuffer, terminal::UnixTerminal, buf return InputAreaState(cur_row, curs_row) end +function refresh_multi_line(terminal::UnixTerminal, args...; kwargs...) + outbuf = IOBuffer() + termbuf = TerminalBuffer(outbuf) + ret = refresh_multi_line(termbuf, terminal, args...;kwargs...) + # Output the entire refresh at once + write(terminal, takebuf_array(outbuf)) + flush(terminal) + return ret +end + # Edit functionality is_non_word_char(c) = c in " \t\n\"\\'`@\$><=:;|&{}()[].,+-*/?%^~" @@ -609,8 +618,8 @@ history_next(::EmptyHistoryProvider) = ("", false) history_search(::EmptyHistoryProvider, args...) = false add_history(::EmptyHistoryProvider, s) = nothing add_history(s::PromptState) = add_history(mode(s).hist, s) -history_next_prefix(s, hist) = false -history_prev_prefix(s, hist) = false +history_next_prefix(s, hist, prefix) = false +history_prev_prefix(s, hist, prefix) = false function history_prev(s, hist) l, ok = history_prev(mode(s).hist) @@ -639,12 +648,12 @@ refresh_line(s, termbuf) = refresh_multi_line(termbuf, s) default_completion_cb(::IOBuffer) = [] default_enter_cb(_) = true -write_prompt(terminal, s::PromptState) = write_prompt(terminal, s, s.p.prompt) -function write_prompt(terminal, s::PromptState, prompt) - prefix = isa(s.p.prompt_prefix,Function) ? s.p.prompt_prefix() : s.p.prompt_prefix - suffix = isa(s.p.prompt_suffix,Function) ? s.p.prompt_suffix() : s.p.prompt_suffix +write_prompt(terminal, s::PromptState) = write_prompt(terminal, s.p) +function write_prompt(terminal, p::Prompt) + prefix = isa(p.prompt_prefix,Function) ? p.prompt_prefix() : p.prompt_prefix + suffix = isa(p.prompt_suffix,Function) ? p.prompt_suffix() : p.prompt_suffix write(terminal, prefix) - write(terminal, prompt) + write(terminal, p.prompt) write(terminal, Base.text_colors[:normal]) write(terminal, suffix) end @@ -725,18 +734,21 @@ function normalize_keymap(keymap::Dict) ret end -match_input(k::Function, s, cs) = (update_key_repeats(s, cs); return keymap_fcn(k, s, last(cs))) -match_input(k::Void, s, cs) = (s,p) -> return :ok -function match_input(keymap::Dict, s, cs=Char[]) - c = read(terminal(s), Char) +match_input(k::Function, s, term, cs) = (update_key_repeats(s, cs); return keymap_fcn(k, s, ByteString(cs))) +match_input(k::Void, s, term, cs) = (s,p) -> return :ok +function match_input(keymap::Dict, s, term=terminal(s), cs=Char[]) + # if we run out of characters to match before resolving an action, + # return an empty keymap function + eof(term) && return keymap_fcn(nothing, s, "") + c = read(term, Char) push!(cs, c) k = haskey(keymap, c) ? c : '\0' # if we don't match on the key, look for a default action then fallback on 'nothing' to ignore - return match_input(get(keymap, k, nothing), s, cs) + return match_input(get(keymap, k, nothing), s, term, cs) end keymap_fcn(f::Void, s, c) = (s, p) -> return :ok -function keymap_fcn(f::Function, s, c::Char) +function keymap_fcn(f::Function, s, c) return (s, p) -> begin r = f(s, p, c) if isa(r, Symbol) @@ -829,8 +841,7 @@ end function keymap{D<:Dict}(keymaps::Array{D}) # keymaps is a vector of prioritized keymaps, with highest priority first dict = map(normalize_keys, keymaps) - dict = keymap_prepare(merge(reverse(dict)...)) - return (s,p)->match_input(dict, s)(s,p) + return keymap_prepare(merge(reverse(dict)...)) end const escape_defaults = merge!( @@ -868,7 +879,7 @@ function write_response_buffer(s::PromptState, data) refresh_line(s) end -type SearchState +type SearchState <: ModeState terminal histprompt #rsearch (true) or ssearch (false) @@ -898,35 +909,7 @@ function history_set_backward(s::SearchState, backward) s.backward = backward end -input_string(s::SearchState) = bytestring(pointer(s.query_buffer.data), s.query_buffer.size) - -refresh_multi_line(termbuf::TerminalBuffer, term, s::Union(SearchState,PromptState)) = (@assert term == terminal(s); refresh_multi_line(termbuf,s)) -function refresh_multi_line(termbuf::TerminalBuffer, s::SearchState) - buf = IOBuffer() - write(buf, pointer(s.query_buffer.data), s.query_buffer.ptr-1) - write(buf, "': ") - offset = buf.ptr - ptr = s.response_buffer.ptr - seek(s.response_buffer, 0) - write(buf, readall(s.response_buffer)) - buf.ptr = offset + ptr - 1 - s.response_buffer.ptr = ptr - s.ias = refresh_multi_line(termbuf, s.terminal, buf, s.ias, s.backward ? "(reverse-i-search)`" : "(forward-i-search)`") -end - -function refresh_multi_line(s::Union(SearchState,PromptState)) - refresh_multi_line(terminal(s), s) -end - -function refresh_multi_line(terminal::UnixTerminal, args...; kwargs...) - outbuf = IOBuffer() - termbuf = TerminalBuffer(outbuf) - ret = refresh_multi_line(termbuf, terminal, args...;kwargs...) - # Output the entire refresh at once - write(terminal, takebuf_array(outbuf)) - flush(terminal) - return ret -end +input_string(s::SearchState) = bytestring(s.query_buffer) function reset_state(s::SearchState) if s.query_buffer.size != 0 @@ -943,18 +926,84 @@ end type HistoryPrompt{T<:HistoryProvider} <: TextInterface hp::T complete - keymap_func::Function + keymap_dict::Dict{Char,Any} HistoryPrompt(hp) = new(hp, EmptyCompletionProvider()) end HistoryPrompt{T<:HistoryProvider}(hp::T) = HistoryPrompt{T}(hp) init_state(terminal, p::HistoryPrompt) = SearchState(terminal, p, true, IOBuffer(), IOBuffer()) +type PrefixSearchState <: ModeState + terminal + histprompt + prefix::ByteString + response_buffer::IOBuffer + ias::InputAreaState + indent::Int + #The prompt whose input will be replaced by the matched history + parent + PrefixSearchState(terminal, histprompt, prefix, response_buffer) = + new(terminal, histprompt, prefix, response_buffer, InputAreaState(0,0), 0) +end + +input_string(s::PrefixSearchState) = bytestring(s.response_buffer) + +# a meta-prompt that presents itself as parent_prompt, but which has an independent keymap +# for prefix searching +type PrefixHistoryPrompt{T<:HistoryProvider} <: TextInterface + hp::T + parent_prompt::Prompt + complete + keymap_dict::Dict{Char,Any} + PrefixHistoryPrompt(hp, parent_prompt) = new(hp, parent_prompt, EmptyCompletionProvider()) +end + +PrefixHistoryPrompt{T<:HistoryProvider}(hp::T, parent_prompt) = PrefixHistoryPrompt{T}(hp, parent_prompt) +init_state(terminal, p::PrefixHistoryPrompt) = PrefixSearchState(terminal, p, "", IOBuffer()) + +write_prompt(terminal, s::PrefixSearchState) = write_prompt(terminal, s.histprompt.parent_prompt) +prompt_string(s::PrefixSearchState) = s.histprompt.parent_prompt.prompt + +terminal(s::PrefixSearchState) = s.terminal + +function reset_state(s::PrefixSearchState) + if s.response_buffer.size != 0 + s.response_buffer.size = 0 + s.response_buffer.ptr = 1 + end +end + +function transition(s::PrefixSearchState, mode) + s.parent = mode + s.histprompt.parent_prompt = mode +end + +replace_line(s::PrefixSearchState, l::IOBuffer) = s.response_buffer = l +function replace_line(s::PrefixSearchState, l) + s.response_buffer.ptr = 1 + s.response_buffer.size = 0 + write(s.response_buffer, l) +end + +function refresh_multi_line(termbuf::TerminalBuffer, s::SearchState) + buf = IOBuffer() + write(buf, pointer(s.query_buffer.data), s.query_buffer.ptr-1) + write(buf, "': ") + offset = buf.ptr + ptr = s.response_buffer.ptr + seek(s.response_buffer, 0) + write(buf, readall(s.response_buffer)) + buf.ptr = offset + ptr - 1 + s.response_buffer.ptr = ptr + s.ias = refresh_multi_line(termbuf, s.terminal, buf, s.ias, s.backward ? "(reverse-i-search)`" : "(forward-i-search)`") +end + state(s::MIState, p) = s.mode_state[p] state(s::PromptState, p) = (@assert s.p == p; s) mode(s::MIState) = s.current_mode mode(s::PromptState) = s.p mode(s::SearchState) = @assert false +mode(s::PrefixSearchState) = s.histprompt.parent_prompt # Search Mode completions function complete_line(s::SearchState, repeats) @@ -995,6 +1044,22 @@ function enter_search(s::MIState, p::HistoryPrompt, backward::Bool) transition(s, p) end +function enter_prefix_search(s::MIState, p::PrefixHistoryPrompt, backward::Bool) + buf = buffer(s) + + pss = state(s, p) + pss.parent = mode(s) + pss.prefix = bytestring(pointer(buf.data), position(buf)) + copybuf!(pss.response_buffer, buf) + pss.indent = state(s, mode(s)).indent + transition(s, p) + if backward + history_prev_prefix(pss, pss.histprompt.hp, pss.prefix) + else + history_next_prefix(pss, pss.histprompt.hp, pss.prefix) + end +end + function setup_search_keymap(hp) p = HistoryPrompt(hp) pkeymap = AnyDict( @@ -1067,7 +1132,7 @@ function setup_search_keymap(hp) end, "*" => (s,data,c)->(edit_insert(data.query_buffer, c); update_display_buffer(s, data)) ) - p.keymap_func = keymap([pkeymap, escape_defaults]) + p.keymap_dict = keymap([pkeymap, escape_defaults]) skeymap = AnyDict( "^R" => (s,o...)->(enter_search(s, p, true)), "^S" => (s,o...)->(enter_search(s, p, false)), @@ -1075,8 +1140,8 @@ function setup_search_keymap(hp) (p, skeymap) end -keymap(state, p::HistoryPrompt) = p.keymap_func -keymap_data(state, ::HistoryPrompt) = state +keymap(state, p::Union(HistoryPrompt,PrefixHistoryPrompt)) = p.keymap_dict +keymap_data(state, ::Union(HistoryPrompt, PrefixHistoryPrompt)) = state Base.isempty(s::PromptState) = s.input_buffer.size == 0 @@ -1225,33 +1290,69 @@ AnyDict( end edit_insert(s, input) end, - "^T" => (s,o...)->edit_transpose(s), + "^T" => (s,o...)->edit_transpose(s) ) const history_keymap = AnyDict( "^P" => (s,o...)->(history_prev(s, mode(s).hist)), "^N" => (s,o...)->(history_next(s, mode(s).hist)), # Up Arrow - "\e[A" => (s,o...)->(edit_move_up(s) || history_prev_prefix(s, mode(s).hist)), + "\e[A" => (s,o...)->(edit_move_up(s) || history_prev(s, mode(s).hist)), # Down Arrow - "\e[B" => (s,o...)->(edit_move_down(s) || history_next_prefix(s, mode(s).hist)), + "\e[B" => (s,o...)->(edit_move_down(s) || history_next(s, mode(s).hist)), # Page Up "\e[5~" => (s,o...)->(history_prev(s, mode(s).hist)), # Page Down "\e[6~" => (s,o...)->(history_next(s, mode(s).hist)) ) -function deactivate(p::Union(Prompt,HistoryPrompt), s::Union(SearchState,PromptState), termbuf) +const prefix_history_keymap = AnyDict( + # Up Arrow + "\e[A" => (s,data,c)->history_prev_prefix(data, data.histprompt.hp, data.prefix), + # Down Arrow + "\e[B" => (s,data,c)->history_next_prefix(data, data.histprompt.hp, data.prefix), + # by default, pass thru to the parent mode + "*" => (s,data,c)->begin + accept_result(s, data.histprompt); + ps = state(s, mode(s)) + match_input(keymap(ps, mode(s)), s, IOBuffer(c))(s, keymap_data(ps, mode(s))) + end, + # match escape sequences for pass thru + "\e*" => "*", + "\e[*" => "*", + "\e[1~" => "*", + "\e[3~" => "*", + "\e[4~" => "*", + "\e[5~" => "*", + "\e[6~" => "*", + "\e[7~" => "*", + "\e[8~" => "*", + "\e[200~" => "*" +) + +function setup_prefix_keymap(hp, parent_prompt) + p = PrefixHistoryPrompt(hp, parent_prompt) + p.keymap_dict = keymap([prefix_history_keymap]) + pkeymap = AnyDict( + # Up Arrow + "\e[A" => (s,o...)->(edit_move_up(s) || enter_prefix_search(s, p, true)), + # Down Arrow + "\e[B" => (s,o...)->(edit_move_down(s) || enter_prefix_search(s, p, false)), + ) + (p, pkeymap) +end + +function deactivate(p::TextInterface, s::ModeState, termbuf) clear_input_area(termbuf, s) s end -function activate(p::Union(Prompt,HistoryPrompt), s::Union(SearchState,PromptState), termbuf) +function activate(p::TextInterface, s::ModeState, termbuf) s.ias = InputAreaState(0, 0) refresh_line(s, termbuf) end -function activate(p::Union(Prompt,HistoryPrompt), s::MIState, termbuf) +function activate(p::TextInterface, s::MIState, termbuf) @assert p == s.current_mode activate(p, s.mode_state[s.current_mode], termbuf) end @@ -1287,13 +1388,13 @@ function reset_state(s::MIState) end end -const default_keymap_func = keymap([default_keymap, escape_defaults]) +const default_keymap_dict = keymap([default_keymap, escape_defaults]) function Prompt(prompt; first_prompt = prompt, prompt_prefix = "", prompt_suffix = "", - keymap_func = default_keymap_func, + keymap_dict = default_keymap_dict, keymap_func_data = nothing, complete = EmptyCompletionProvider(), on_enter = default_enter_cb, @@ -1301,7 +1402,7 @@ function Prompt(prompt; hist = EmptyHistoryProvider(), sticky = false) - Prompt(prompt, first_prompt, prompt_prefix, prompt_suffix, keymap_func, keymap_func_data, + Prompt(prompt, first_prompt, prompt_prefix, prompt_suffix, keymap_dict, keymap_func_data, complete, on_enter, on_done, hist, sticky) end @@ -1332,30 +1433,31 @@ end buffer(s::PromptState) = s.input_buffer buffer(s::SearchState) = s.query_buffer +buffer(s::PrefixSearchState) = s.response_buffer -keymap(s::PromptState, prompt::Prompt) = prompt.keymap_func +keymap(s::PromptState, prompt::Prompt) = prompt.keymap_dict keymap_data(s::PromptState, prompt::Prompt) = prompt.keymap_func_data keymap(ms::MIState, m::ModalInterface) = keymap(ms.mode_state[ms.current_mode], ms.current_mode) keymap_data(ms::MIState, m::ModalInterface) = keymap_data(ms.mode_state[ms.current_mode], ms.current_mode) -function prompt!(terminal, prompt, s = init_state(terminal, prompt)) - Base.reseteof(terminal) - raw!(terminal, true) - enable_bracketed_paste(terminal) +function prompt!(term, prompt, s = init_state(term, prompt)) + Base.reseteof(term) + raw!(term, true) + enable_bracketed_paste(term) try - start_reading(terminal) - activate(prompt, s, terminal) + start_reading(term) + activate(prompt, s, term) while true - state = keymap(s, prompt)(s, keymap_data(s, prompt)) + state = match_input(keymap(s, prompt), s)(s, keymap_data(s, prompt)) if state == :abort - stop_reading(terminal) + stop_reading(term) return buffer(s), false, false elseif state == :done - stop_reading(terminal) + stop_reading(term) return buffer(s), true, false elseif state == :suspend @unix_only begin - stop_reading(terminal) + stop_reading(term) return buffer(s), true, true end else @@ -1363,7 +1465,7 @@ function prompt!(terminal, prompt, s = init_state(terminal, prompt)) end end finally - raw!(terminal, false) && disable_bracketed_paste(terminal) + raw!(term, false) && disable_bracketed_paste(term) end end diff --git a/base/REPL.jl b/base/REPL.jl index a0b5d57146813..e244d493c3b51 100644 --- a/base/REPL.jl +++ b/base/REPL.jl @@ -384,7 +384,7 @@ function add_history(hist::REPLHistoryProvider, s) flush(hist.history_file) end -function history_move(s::LineEdit.MIState, hist::REPLHistoryProvider, idx::Int, save_idx::Int = hist.cur_idx) +function history_move(s::Union(LineEdit.MIState,LineEdit.PrefixSearchState), hist::REPLHistoryProvider, idx::Int, save_idx::Int = hist.cur_idx) max_idx = length(hist.history) + 1 @assert 1 <= hist.cur_idx <= max_idx (1 <= idx <= max_idx) || return :none @@ -469,34 +469,39 @@ function history_next(s::LineEdit.MIState, hist::REPLHistoryProvider, end end -function history_move_prefix(s::LineEdit.MIState, +function history_move_prefix(s::LineEdit.PrefixSearchState, hist::REPLHistoryProvider, + prefix::AbstractString, backwards::Bool) - buf = LineEdit.buffer(s) - pos = position(buf) - prefix = bytestring_beforecursor(buf) - allbuf = bytestring(buf) + cur_response = bytestring(LineEdit.buffer(s)) cur_idx = hist.cur_idx # when searching forward, start at last_idx if !backwards && hist.last_idx > 0 cur_idx = hist.last_idx end hist.last_idx = -1 - idxs = backwards ? ((cur_idx-1):-1:1) : ((cur_idx+1):length(hist.history)) + max_idx = length(hist.history)+1 + idxs = backwards ? ((cur_idx-1):-1:1) : ((cur_idx+1):max_idx) for idx in idxs - if beginswith(hist.history[idx], prefix) && hist.history[idx] != allbuf + if (idx == max_idx) || (beginswith(hist.history[idx], prefix) && (hist.history[idx] != cur_response || hist.modes[idx] != LineEdit.mode(s))) history_move(s, hist, idx) - seek(LineEdit.buffer(s), pos) + if length(prefix) == 0 + # on empty prefix search, move cursor to the end + LineEdit.move_input_end(s) + else + # otherwise, keep cursor at the prefix position as a visual cue + seek(LineEdit.buffer(s), length(prefix)) + end LineEdit.refresh_line(s) return :ok end end Terminals.beep(LineEdit.terminal(s)) end -history_next_prefix(s::LineEdit.MIState, hist::REPLHistoryProvider) = - history_move_prefix(s, hist, false) -history_prev_prefix(s::LineEdit.MIState, hist::REPLHistoryProvider) = - history_move_prefix(s, hist, true) +history_next_prefix(s::LineEdit.PrefixSearchState, hist::REPLHistoryProvider, prefix::AbstractString) = + history_move_prefix(s, hist, prefix, false) +history_prev_prefix(s::LineEdit.PrefixSearchState, hist::REPLHistoryProvider, prefix::AbstractString) = + history_move_prefix(s, hist, prefix, true) function history_search(hist::REPLHistoryProvider, query_buffer::IOBuffer, response_buffer::IOBuffer, backwards::Bool=false, skip_current::Bool=false) @@ -695,9 +700,8 @@ function setup_interface(repl::LineEditREPL; hascolor = repl.hascolor, extra_rep shell_mode.hist = hp help_mode.hist = hp - hkp, hkeymap = LineEdit.setup_search_keymap(hp) - - hkp.complete = LatexCompletions() + search_prompt, skeymap = LineEdit.setup_search_keymap(hp) + search_prompt.complete = LatexCompletions() # Canonicalize user keymap input if isa(extra_repl_keymap, Dict) @@ -777,10 +781,12 @@ function setup_interface(repl::LineEditREPL; hascolor = repl.hascolor, extra_rep end, ) - a = Dict{Any,Any}[hkeymap, repl_keymap, LineEdit.history_keymap, LineEdit.default_keymap, LineEdit.escape_defaults] + prefix_prompt, prefix_keymap = LineEdit.setup_prefix_keymap(hp, julia_prompt) + + a = Dict{Any,Any}[skeymap, repl_keymap, prefix_keymap, LineEdit.history_keymap, LineEdit.default_keymap, LineEdit.escape_defaults] prepend!(a, extra_repl_keymap) - julia_prompt.keymap_func = LineEdit.keymap(a) + julia_prompt.keymap_dict = LineEdit.keymap(a) const mode_keymap = AnyDict( '\b' => function (s,o...) @@ -803,12 +809,12 @@ function setup_interface(repl::LineEditREPL; hascolor = repl.hascolor, extra_rep end ) - b = Dict{Any,Any}[hkeymap, mode_keymap, LineEdit.history_keymap, LineEdit.default_keymap, LineEdit.escape_defaults] + b = Dict{Any,Any}[skeymap, mode_keymap, prefix_keymap, LineEdit.history_keymap, LineEdit.default_keymap, LineEdit.escape_defaults] prepend!(b, extra_repl_keymap) - shell_mode.keymap_func = help_mode.keymap_func = LineEdit.keymap(b) + shell_mode.keymap_dict = help_mode.keymap_dict = LineEdit.keymap(b) - ModalInterface([julia_prompt, shell_mode, help_mode,hkp]) + ModalInterface([julia_prompt, shell_mode, help_mode, search_prompt, prefix_prompt]) end function run_frontend(repl::LineEditREPL, backend) diff --git a/base/Terminals.jl b/base/Terminals.jl index d0a56c7cca152..9ac5db6ef1def 100644 --- a/base/Terminals.jl +++ b/base/Terminals.jl @@ -32,7 +32,8 @@ import Base: stop_reading, write, writemime, - reseteof + reseteof, + eof ## TextTerminal ## @@ -193,6 +194,7 @@ readuntil(t::UnixTerminal, s) = readuntil(t.in_stream, s) read(t::UnixTerminal, ::Type{UInt8}) = read(t.in_stream, UInt8) start_reading(t::UnixTerminal) = start_reading(t.in_stream) stop_reading(t::UnixTerminal) = stop_reading(t.in_stream) +eof(t::UnixTerminal) = eof(t.in_stream) @unix_only hascolor(t::TTYTerminal) = (beginswith(t.term_type, "xterm") || success(`tput setaf 0`)) @windows_only hascolor(t::TTYTerminal) = true diff --git a/base/precompile.jl b/base/precompile.jl index 918bfd704bf47..277adf6669946 100644 --- a/base/precompile.jl +++ b/base/precompile.jl @@ -72,11 +72,11 @@ precompile(Base.LineEdit.init_state, (Base.Terminals.TTYTerminal, Base.LineEdit. precompile(Base.LineEdit.input_string, (Base.LineEdit.PromptState,)) precompile(Base.LineEdit.keymap, (Base.LineEdit.PromptState, Base.LineEdit.Prompt)) precompile(Base.LineEdit.keymap_data, (Base.LineEdit.PromptState, Base.LineEdit.Prompt)) -precompile(Base.LineEdit.keymap_fcn, (Function, Base.LineEdit.MIState, Char)) -precompile(Base.LineEdit.keymap_fcn, (Function, Base.LineEdit.MIState,Char)) +precompile(Base.LineEdit.keymap_fcn, (Function, Base.LineEdit.MIState, ByteString)) +precompile(Base.LineEdit.keymap_fcn, (Function, Base.LineEdit.MIState, ByteString)) precompile(Base.LineEdit.match_input, (Dict{Char,Any},Base.LineEdit.MIState)) -precompile(Base.LineEdit.match_input, (Function, Base.LineEdit.MIState, Array{Char, 1})) -precompile(Base.LineEdit.match_input, (Function, Base.LineEdit.MIState, Array{Char,1})) +precompile(Base.LineEdit.match_input, (Dict{Char, Any}, Base.LineEdit.MIState, Base.Terminals.TTYTerminal)) +precompile(Base.LineEdit.match_input, (Function, Base.LineEdit.MIState, Base.Terminals.TTYTerminal, Array{Char,1})) precompile(Base.LineEdit.mode, (Base.LineEdit.MIState,)) precompile(Base.LineEdit.move_line_end, (Base.LineEdit.MIState,)) precompile(Base.LineEdit.on_enter, (Base.LineEdit.MIState,)) @@ -104,8 +104,8 @@ precompile(Base.LineEdit.transition, (Base.LineEdit.MIState, Base.LineEdit.Promp precompile(Base.LineEdit.transition, (Base.LineEdit.MIState, Symbol)) precompile(Base.LineEdit.update_key_repeats, (Base.LineEdit.MIState, Array{Char, 1})) precompile(Base.LineEdit.update_key_repeats, (Base.LineEdit.MIState, Array{Char,1})) -precompile(Base.LineEdit.write_prompt, (Base.Terminals.TTYTerminal, Base.LineEdit.PromptState, ASCIIString)) -precompile(Base.LineEdit.write_prompt, (Base.Terminals.TerminalBuffer, Base.LineEdit.PromptState, ASCIIString)) +precompile(Base.LineEdit.write_prompt, (Base.Terminals.TTYTerminal, Base.LineEdit.Prompt)) +precompile(Base.LineEdit.write_prompt, (Base.Terminals.TerminalBuffer, Base.LineEdit.PromptState)) precompile(Base.Multimedia.TextDisplay, (Base.TTY,)) precompile(Base.Multimedia.display, (Int,)) precompile(Base.ProcessGroup, (Int, Array{Any,1}, Array{Any,1})) diff --git a/test/lineedit.jl b/test/lineedit.jl index c5cf284f12be4..b23a5fa9b07cf 100644 --- a/test/lineedit.jl +++ b/test/lineedit.jl @@ -21,28 +21,28 @@ const bar_keymap = Dict( 'b' => (o...)->(global b_bar; b_bar += 1) ) -test1_func = LineEdit.keymap([foo_keymap]) +test1_dict = LineEdit.keymap([foo_keymap]) -function run_test(f,buf) +function run_test(d,buf) global a_foo, a_bar, b_bar a_foo = a_bar = b_bar = 0 while !eof(buf) - f(buf,nothing) + LineEdit.match_input(d, nothing, buf)(nothing,nothing) end end -run_test(test1_func,IOBuffer("aa")) +run_test(test1_dict,IOBuffer("aa")) @test a_foo == 2 -test2_func = LineEdit.keymap([foo2_keymap, foo_keymap]) +test2_dict = LineEdit.keymap([foo2_keymap, foo_keymap]) -run_test(test2_func,IOBuffer("aaabb")) +run_test(test2_dict,IOBuffer("aaabb")) @test a_foo == 3 @test b_foo == 2 -test3_func = LineEdit.keymap([bar_keymap, foo_keymap]) +test3_dict = LineEdit.keymap([bar_keymap, foo_keymap]) -run_test(test3_func,IOBuffer("aab")) +run_test(test3_dict,IOBuffer("aab")) @test a_bar == 2 @test b_bar == 1