From eb1ac7c4e62c7d0fa6dd1d78783d016320e8cb33 Mon Sep 17 00:00:00 2001 From: Kristoffer Carlsson Date: Sat, 25 Oct 2025 21:20:39 +0200 Subject: [PATCH] fix new reverse search behavior when existing buffer is non-empty Before this would open the reverse search with an empty buffer and append the selected result to the pre-existing buffer. Now, it uses the input buffer as an input to the reverse search instead and it clears the original buffer when inserting the result. --- stdlib/REPL/src/History/prompt.jl | 5 ++++- stdlib/REPL/src/History/search.jl | 7 +++++-- stdlib/REPL/src/LineEdit.jl | 8 ++++++-- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/stdlib/REPL/src/History/prompt.jl b/stdlib/REPL/src/History/prompt.jl index 78b87e7868344..950a6fe282884 100644 --- a/stdlib/REPL/src/History/prompt.jl +++ b/stdlib/REPL/src/History/prompt.jl @@ -62,7 +62,7 @@ Initialize a custom REPL prompt tied to `events` using the existing `term`. Returns a tuple `(term, prompt, istate, pstate)` ready for input handling and display. """ -function create_prompt(events::Channel{Symbol}, term, prefix::String = "\e[90m") +function create_prompt(events::Channel{Symbol}, term, prefix::String = "\e[90m", initial_query::String = "") prompt = REPL.LineEdit.Prompt( PROMPT_TEXT, # prompt prefix, "\e[0m", # prompt_prefix, prompt_suffix @@ -78,6 +78,9 @@ function create_prompt(events::Channel{Symbol}, term, prefix::String = "\e[90m") interface = REPL.LineEdit.ModalInterface([prompt]) istate = REPL.LineEdit.init_state(term, interface) pstate = istate.mode_state[prompt] + if !isempty(initial_query) + write(pstate.input_buffer, initial_query) + end (; term, prompt, istate, pstate) end diff --git a/stdlib/REPL/src/History/search.jl b/stdlib/REPL/src/History/search.jl index 8b5e20fc0385f..8d1f95aba42de 100644 --- a/stdlib/REPL/src/History/search.jl +++ b/stdlib/REPL/src/History/search.jl @@ -8,12 +8,15 @@ Launch the interactive REPL history search interface. Spawns prompt and display tasks, waits for user confirm or abort, and returns the final selection (if any). """ -function runsearch(histfile::HistoryFile, term, prefix::String = "\e[90m") +function runsearch(histfile::HistoryFile, term, prefix::String = "\e[90m", initial_query::String = "") update!(histfile) events = Channel{Symbol}(Inf) - pspec = create_prompt(events, term, prefix) + pspec = create_prompt(events, term, prefix, initial_query) ptask = @spawn runprompt!(pspec, events) dtask = @spawn run_display!(pspec, events, histfile.records) + if !isempty(initial_query) + push!(events, :edit) + end wait(ptask) fullselection(fetch(dtask)) end diff --git a/stdlib/REPL/src/LineEdit.jl b/stdlib/REPL/src/LineEdit.jl index e11dab5ccad4a..a941c5b4f2274 100644 --- a/stdlib/REPL/src/LineEdit.jl +++ b/stdlib/REPL/src/LineEdit.jl @@ -2700,6 +2700,7 @@ function history_search(mistate::MIState) mimode = mode(mistate) mimode.hist.last_mode = mimode mimode.hist.last_buffer = copy(buffer(mistate)) + initial_query = input_string(state(mistate)) mistate.mode_state[mimode] = deactivate(mimode, state(mistate), termbuf, term) prefix = if mimode.prompt_prefix isa Function @@ -2707,7 +2708,7 @@ function history_search(mistate::MIState) else mimode.prompt_prefix end - result = histsearch(mimode.hist.history, term, prefix) + result = histsearch(mimode.hist.history, term, prefix, initial_query) mimode = if isnothing(result.mode) mistate.current_mode else @@ -2720,7 +2721,10 @@ function history_search(mistate::MIState) mistate.current_mode = mimode activate(mimode, state(mistate, mimode), termbuf, term) commit_changes(term, termbuf) - edit_insert(pstate, result.text) + if !isempty(result.text) + edit_clear(buffer(pstate)) + edit_insert(pstate, result.text) + end refresh_multi_line(mistate) nothing end