diff --git a/stdlib/REPL/src/LineEdit.jl b/stdlib/REPL/src/LineEdit.jl index 2084a8d2e4bf5..c34728b63d373 100644 --- a/stdlib/REPL/src/LineEdit.jl +++ b/stdlib/REPL/src/LineEdit.jl @@ -3,8 +3,9 @@ module LineEdit import ..REPL -using ..Terminals +using REPL: AbstractREPL +using ..Terminals import ..Terminals: raw!, width, height, cmove, getX, getY, clear_line, beep @@ -13,6 +14,8 @@ using Base: something abstract type TextInterface end abstract type ModeState end +abstract type HistoryProvider end +abstract type CompletionProvider end export run_interface, Prompt, ModalInterface, transition, reset_state, edit_insert, keymap @@ -31,11 +34,11 @@ mutable struct Prompt <: TextInterface # Same as prefix except after the prompt prompt_suffix::Union{String,Function} keymap_dict::Dict{Char} - repl # ::AbstractREPL - complete # ::REPLCompletionProvider + repl::Union{AbstractREPL,Nothing} + complete::CompletionProvider on_enter::Function on_done::Function - hist # ::REPLHistoryProvider + hist::HistoryProvider sticky::Bool end @@ -141,9 +144,6 @@ function input_string_newlines_aftercursor(s::PromptState) return count(c->(c == '\n'), rest) end -abstract type HistoryProvider end -abstract type CompletionProvider end - struct EmptyCompletionProvider <: CompletionProvider end struct EmptyHistoryProvider <: HistoryProvider end @@ -1602,9 +1602,16 @@ const escape_defaults = merge!( AnyDict("\e[$(c)l" => nothing for c in 1:20) ) +mutable struct HistoryPrompt <: TextInterface + hp::HistoryProvider + complete::CompletionProvider + keymap_dict::Dict{Char,Any} + HistoryPrompt(hp) = new(hp, EmptyCompletionProvider()) +end + mutable struct SearchState <: ModeState terminal::AbstractTerminal - histprompt # ::HistoryPrompt + histprompt::HistoryPrompt #rsearch (true) or ssearch (false) backward::Bool query_buffer::IOBuffer @@ -1617,6 +1624,8 @@ mutable struct SearchState <: ModeState new(terminal, histprompt, backward, query_buffer, response_buffer, false, InputAreaState(0,0)) end +init_state(terminal, p::HistoryPrompt) = SearchState(terminal, p, true, IOBuffer(), IOBuffer()) + terminal(s::SearchState) = s.terminal function update_display_buffer(s::SearchState, data) @@ -1654,18 +1663,20 @@ function reset_state(s::SearchState) nothing end -mutable struct HistoryPrompt <: TextInterface - hp # ::HistoryProvider - complete # ::CompletionProvider +# a meta-prompt that presents itself as parent_prompt, but which has an independent keymap +# for prefix searching +mutable struct PrefixHistoryPrompt <: TextInterface + hp::HistoryProvider + parent_prompt::Prompt + complete::CompletionProvider keymap_dict::Dict{Char,Any} - HistoryPrompt(hp) = new(hp, EmptyCompletionProvider()) + PrefixHistoryPrompt(hp, parent_prompt) = + new(hp, parent_prompt, EmptyCompletionProvider()) end -init_state(terminal, p::HistoryPrompt) = SearchState(terminal, p, true, IOBuffer(), IOBuffer()) - mutable struct PrefixSearchState <: ModeState terminal::AbstractTerminal - histprompt # ::HistoryPrompt + histprompt::PrefixHistoryPrompt prefix::String response_buffer::IOBuffer ias::InputAreaState @@ -1678,6 +1689,8 @@ mutable struct PrefixSearchState <: ModeState new(terminal, histprompt, prefix, response_buffer, InputAreaState(0,0), 0) end +init_state(terminal, p::PrefixHistoryPrompt) = PrefixSearchState(terminal, p, "", IOBuffer()) + function show(io::IO, s::PrefixSearchState) print(io, "PrefixSearchState ", isdefined(s,:parent) ? string("(", s.parent, " active)") : "(no parent)", " for ", @@ -1696,19 +1709,6 @@ end input_string(s::PrefixSearchState) = String(take!(copy(s.response_buffer))) -# a meta-prompt that presents itself as parent_prompt, but which has an independent keymap -# for prefix searching -mutable struct PrefixHistoryPrompt <: TextInterface - hp # ::HistoryProvider - parent_prompt::Prompt - complete # ::CompletionProvider - keymap_dict::Dict{Char,Any} - PrefixHistoryPrompt(hp, parent_prompt) = - new(hp, parent_prompt, EmptyCompletionProvider()) -end - -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) = prompt_string(s.histprompt.parent_prompt.prompt) diff --git a/stdlib/REPL/src/REPL.jl b/stdlib/REPL/src/REPL.jl index 5259a4fd717e8..b892eb7b3e6eb 100644 --- a/stdlib/REPL/src/REPL.jl +++ b/stdlib/REPL/src/REPL.jl @@ -36,6 +36,8 @@ import Base: include("Terminals.jl") using .Terminals +abstract type AbstractREPL end + include("LineEdit.jl") using .LineEdit import ..LineEdit: @@ -66,8 +68,6 @@ function __init__() Base.REPL_MODULE_REF[] = REPL end -abstract type AbstractREPL end - answer_color(::AbstractREPL) = "" const JULIA_PROMPT = "julia> " @@ -481,15 +481,15 @@ function complete_line(c::LatexCompletions, s) end mutable struct REPLHistoryProvider <: HistoryProvider - history::Array{String,1} + history::Vector{String} history_file::Union{Nothing,IO} start_idx::Int cur_idx::Int last_idx::Int last_buffer::IOBuffer last_mode::Union{Nothing,Prompt} - mode_mapping::Dict - modes::Array{Symbol,1} + mode_mapping::Dict{Symbol,Prompt} + modes::Vector{Symbol} end REPLHistoryProvider(mode_mapping) = REPLHistoryProvider(String[], nothing, 0, 0, -1, IOBuffer(),