diff --git a/base/repl/LineEdit.jl b/base/repl/LineEdit.jl index 8dbc14f0c254d..4beccbff1841b 100644 --- a/base/repl/LineEdit.jl +++ b/base/repl/LineEdit.jl @@ -15,14 +15,32 @@ abstract type ModeState end export run_interface, Prompt, ModalInterface, transition, reset_state, edit_insert, keymap struct ModalInterface <: TextInterface - modes + modes::Array{Base.LineEdit.TextInterface,1} end +mutable struct Prompt <: TextInterface + prompt::String + # A string or function to be printed before the prompt. May not change the length of the prompt. + # This may be used for changing the color, issuing other terminal escape codes, etc. + prompt_prefix::Union{String,Function} + # Same as prefix except after the prompt + prompt_suffix::Union{String,Function} + keymap_dict::Dict{Char} + keymap_func_data # ::AbstractREPL + complete # ::REPLCompletionProvider + on_enter::Function + on_done::Function + hist # ::REPLHistoryProvider + sticky::Bool +end + +show(io::IO, x::Prompt) = show(io, string("Prompt(\"", x.prompt, "\",...)")) + mutable struct MIState interface::ModalInterface - current_mode + current_mode::TextInterface aborted::Bool - mode_state + mode_state::Dict kill_buffer::String previous_key::Array{Char,1} key_repeats::Int @@ -33,31 +51,13 @@ function show(io::IO, s::MIState) print(io, "MI State (", s.current_mode, " active)") end -mutable struct Prompt <: TextInterface - prompt - # A string or function to be printed before the prompt. May not change the length of the prompt. - # This may be used for changing the color, issuing other terminal escape codes, etc. - prompt_prefix - # Same as prefix except after the prompt - prompt_suffix - keymap_dict - keymap_func_data - complete - on_enter - on_done - hist - sticky::Bool -end - -show(io::IO, x::Prompt) = show(io, string("Prompt(\"", x.prompt, "\",...)")) - struct InputAreaState num_rows::Int64 curs_row::Int64 end mutable struct PromptState <: ModeState - terminal + terminal::AbstractTerminal p::Prompt input_buffer::IOBuffer ias::InputAreaState @@ -967,15 +967,15 @@ function write_response_buffer(s::PromptState, data) end mutable struct SearchState <: ModeState - terminal - histprompt + terminal::AbstractTerminal + histprompt # ::HistoryPrompt #rsearch (true) or ssearch (false) backward::Bool query_buffer::IOBuffer response_buffer::IOBuffer ias::InputAreaState #The prompt whose input will be replaced by the matched history - parent + parent::Prompt SearchState(terminal, histprompt, backward, query_buffer, response_buffer) = new(terminal, histprompt, backward, query_buffer, response_buffer, InputAreaState(0,0)) end @@ -1012,7 +1012,7 @@ end mutable struct HistoryPrompt{T<:HistoryProvider} <: TextInterface hp::T - complete + complete # ::CompletionProvider keymap_dict::Dict{Char,Any} HistoryPrompt{T}(hp) where T<:HistoryProvider = new(hp, EmptyCompletionProvider()) end @@ -1021,16 +1021,16 @@ HistoryPrompt(hp::T) where T<:HistoryProvider = HistoryPrompt{T}(hp) init_state(terminal, p::HistoryPrompt) = SearchState(terminal, p, true, IOBuffer(), IOBuffer()) mutable struct PrefixSearchState <: ModeState - terminal - histprompt + terminal::AbstractTerminal + histprompt # ::HistoryPrompt prefix::String response_buffer::IOBuffer ias::InputAreaState indent::Int # The modal interface state, if present - mi + mi::MIState #The prompt whose input will be replaced by the matched history - parent + parent::Prompt PrefixSearchState(terminal, histprompt, prefix, response_buffer) = new(terminal, histprompt, prefix, response_buffer, InputAreaState(0,0), 0) end @@ -1052,7 +1052,7 @@ input_string(s::PrefixSearchState) = String(s.response_buffer) mutable struct PrefixHistoryPrompt{T<:HistoryProvider} <: TextInterface hp::T parent_prompt::Prompt - complete + complete # ::CompletionProvider keymap_dict::Dict{Char,Any} PrefixHistoryPrompt{T}(hp, parent_prompt) where T<:HistoryProvider = new(hp, parent_prompt, EmptyCompletionProvider()) diff --git a/base/repl/REPL.jl b/base/repl/REPL.jl index 9681a2a6b74cc..898da7b8e2ca5 100644 --- a/base/repl/REPL.jl +++ b/base/repl/REPL.jl @@ -8,6 +8,7 @@ using ..LineEdit using ..REPLCompletions export + AbstractREPL, BasicREPL, LineEditREPL, StreamREPL @@ -172,7 +173,7 @@ struct REPLBackendRef response_channel::Channel end -function run_repl(repl::AbstractREPL, consumer = x->nothing) +function run_repl(repl::AbstractREPL, consumer::Function = x->nothing) repl_channel = Channel(1) response_channel = Channel(1) backend = start_repl_backend(repl_channel, response_channel) @@ -266,14 +267,15 @@ specialdisplay(r::LineEditREPL) = r.specialdisplay specialdisplay(r::AbstractREPL) = nothing terminal(r::LineEditREPL) = r.t -LineEditREPL(t::TextTerminal, envcolors = false) = LineEditREPL(t, - true, - Base.text_colors[:green], - Base.input_color(), - Base.answer_color(), - Base.text_colors[:red], - Base.text_colors[:yellow], - false, false, false, envcolors) +LineEditREPL(t::TextTerminal, envcolors::Bool=false) = + LineEditREPL(t, true, + Base.text_colors[:green], + Base.input_color(), + Base.answer_color(), + Base.text_colors[:red], + Base.text_colors[:yellow], + false, false, false, envcolors + ) mutable struct REPLCompletionProvider <: CompletionProvider end mutable struct ShellCompletionProvider <: CompletionProvider end @@ -310,7 +312,7 @@ mutable struct REPLHistoryProvider <: HistoryProvider cur_idx::Int last_idx::Int last_buffer::IOBuffer - last_mode + last_mode::Union{Void,Prompt} mode_mapping::Dict modes::Array{Symbol,1} end @@ -616,7 +618,9 @@ end backend(r::AbstractREPL) = r.backendref -send_to_backend(ast, backend::REPLBackendRef) = send_to_backend(ast, backend.repl_channel, backend.response_channel) +send_to_backend(ast, backend::REPLBackendRef) = + send_to_backend(ast, backend.repl_channel, backend.response_channel) + function send_to_backend(ast, req, rep) put!(req, (ast, 1)) return take!(rep) # (val, bt) @@ -658,7 +662,7 @@ function prepare_next(repl::LineEditREPL) println(terminal(repl)) end -function mode_keymap(julia_prompt) +function mode_keymap(julia_prompt::Prompt) AnyDict( '\b' => function (s,o...) if isempty(s) || position(LineEdit.buffer(s)) == 0 @@ -686,7 +690,11 @@ repl_filename(repl, hp) = "REPL" const JL_PROMPT_PASTE = Ref(true) enable_promptpaste(v::Bool) = JL_PROMPT_PASTE[] = v -function setup_interface(repl::LineEditREPL; hascolor = repl.hascolor, extra_repl_keymap = Dict{Any,Any}[]) +function setup_interface( + repl::LineEditREPL; + hascolor::Bool = repl.hascolor, + extra_repl_keymap::Vector{<:Dict} = Dict{Any,Any}[] +) ### # # This function returns the main interface that describes the REPL @@ -927,7 +935,7 @@ function setup_interface(repl::LineEditREPL; hascolor = repl.hascolor, extra_rep ModalInterface([julia_prompt, shell_mode, help_mode, search_prompt, prefix_prompt]) end -function run_frontend(repl::LineEditREPL, backend) +function run_frontend(repl::LineEditREPL, backend::REPLBackendRef) d = REPLDisplay(repl) dopushdisplay = repl.specialdisplay === nothing && !in(d,Base.Multimedia.displays) dopushdisplay && pushdisplay(d) @@ -970,7 +978,7 @@ input_color(r::StreamREPL) = r.input_color # heuristic function to decide if the presence of a semicolon # at the end of the expression was intended for suppressing output -function ends_with_semicolon(line) +function ends_with_semicolon(line::AbstractString) match = rsearch(line, ';') if match != 0 # state for comment parser, assuming that the `;` isn't in a string or comment @@ -1052,7 +1060,7 @@ function run_frontend(repl::StreamREPL, backend::REPLBackendRef) dopushdisplay && popdisplay(d) end -function start_repl_server(port) +function start_repl_server(port::Int) listen(port) do server, status client = accept(server) run_repl(client)