diff --git a/src/input_handler.cc b/src/input_handler.cc index 73e3649e..794a9f5a 100644 --- a/src/input_handler.cc +++ b/src/input_handler.cc @@ -486,10 +486,10 @@ public: m_cursor_pos = start + str.char_length(); } - void reset(String line) + void reset(String line, CharCount cursor_pos = -1) { m_line = std::move(line); - m_cursor_pos = m_line.char_length(); + m_cursor_pos = cursor_pos == -1 ? m_line.char_length() : cursor_pos; m_display_pos = 0; } @@ -501,7 +501,7 @@ public: return m_line.substr(m_display_pos, m_cursor_pos).column_length(); } - DisplayLine build_display_line(ColumnCount in_width) + DisplayLine build_display_line(ColumnCount in_width, bool inactive) { CharCount width = (int)in_width; // Todo: proper handling of char/column kak_assert(m_cursor_pos <= m_line.char_length()); @@ -510,13 +510,16 @@ public: if (m_cursor_pos >= m_display_pos + width) m_display_pos = m_cursor_pos + 1 - width; + const Face line_face = get_face(inactive ? "StatusLineInfo" : "StatusLine"); + const Face cursor_face = get_face("StatusCursor"); + if (m_cursor_pos == m_line.char_length()) - return DisplayLine{{ { fix_atom_text(m_line.substr(m_display_pos, width-1)), get_face("StatusLine") }, - { " "_str, get_face("StatusCursor")} } }; + return DisplayLine{{ { fix_atom_text(m_line.substr(m_display_pos, width-1)), line_face }, + { " "_str, cursor_face} } }; else - return DisplayLine({ { fix_atom_text(m_line.substr(m_display_pos, m_cursor_pos - m_display_pos)), get_face("StatusLine") }, - { fix_atom_text(m_line.substr(m_cursor_pos,1)), get_face("StatusCursor") }, - { fix_atom_text(m_line.substr(m_cursor_pos+1, width - m_cursor_pos + m_display_pos - 1)), get_face("StatusLine") } }); + return DisplayLine({ { fix_atom_text(m_line.substr(m_display_pos, m_cursor_pos - m_display_pos)), line_face }, + { fix_atom_text(m_line.substr(m_cursor_pos,1)), cursor_face }, + { fix_atom_text(m_line.substr(m_cursor_pos+1, width - m_cursor_pos + m_display_pos - 1)), line_face } }); } private: CharCount m_cursor_pos = 0; @@ -625,7 +628,7 @@ public: { auto prompt = "filter:"_str; auto width = context().client().dimensions().column - prompt.column_length(); - auto display_line = m_filter_editor.build_display_line(width); + auto display_line = m_filter_editor.build_display_line(width, false); display_line.insert(display_line.begin(), { prompt, get_face("Prompt") }); context().print_status(display_line); } @@ -710,11 +713,17 @@ public: }} { m_history_it = ms_history[m_prompt].end(); - m_line_editor.reset(std::move(initstr)); + m_line_editor.reset(std::move(initstr), m_flags & PromptFlags::InactiveInitString ? 0 : -1); } void on_key(Key key) override { + if (m_flags & PromptFlags::InactiveInitString) + { + m_flags &= ~PromptFlags::InactiveInitString; + m_line_editor.reset(String{}); + } + History& history = ms_history[m_prompt]; const String& line = m_line_editor.line(); @@ -950,7 +959,7 @@ private: auto width = context().client().dimensions().column - m_prompt.column_length(); DisplayLine display_line; if (not (m_flags & PromptFlags::Password)) - display_line = m_line_editor.build_display_line(width); + display_line = m_line_editor.build_display_line(width, m_flags & PromptFlags::InactiveInitString); display_line.insert(display_line.begin(), { m_prompt, m_prompt_face }); context().print_status(display_line); } diff --git a/src/input_handler.hh b/src/input_handler.hh index e4cad6d0..e184a8fa 100644 --- a/src/input_handler.hh +++ b/src/input_handler.hh @@ -33,7 +33,8 @@ enum class PromptFlags { None = 0, Password = 1 << 0, - DropHistoryEntriesWithBlankPrefix = 1 << 1 + DropHistoryEntriesWithBlankPrefix = 1 << 1, + InactiveInitString = 1 << 2, }; constexpr bool with_bit_ops(Meta::Type) { return true; } diff --git a/src/normal.cc b/src/normal.cc index 3ad6a89b..bd399dc9 100644 --- a/src/normal.cc +++ b/src/normal.cc @@ -424,7 +424,8 @@ void command(Context& context, NormalParams params) CommandManager::instance().clear_last_complete_command(); context.input_handler().prompt( - ":", "", get_face("Prompt"), PromptFlags::DropHistoryEntriesWithBlankPrefix, + ":", context.main_sel_register_value(':').str(), + get_face("Prompt"), PromptFlags::DropHistoryEntriesWithBlankPrefix | PromptFlags::InactiveInitString, [](const Context& context, CompletionFlags flags, StringView cmd_line, ByteCount pos) { return CommandManager::instance().complete(context, flags, cmd_line, pos); @@ -494,8 +495,9 @@ void pipe(Context& context, NormalParams) { const char* prompt = replace ? "pipe:" : "pipe-to:"; context.input_handler().prompt( - prompt, "", get_face("Prompt"), - PromptFlags::DropHistoryEntriesWithBlankPrefix, shell_complete, + prompt, context.main_sel_register_value("|").str(), get_face("Prompt"), + PromptFlags::DropHistoryEntriesWithBlankPrefix | PromptFlags::InactiveInitString, + shell_complete, [](StringView cmdline, PromptEvent event, Context& context) { if (event != PromptEvent::Validate) @@ -562,8 +564,9 @@ void insert_output(Context& context, NormalParams) { const char* prompt = mode == InsertMode::Insert ? "insert-output:" : "append-output:"; context.input_handler().prompt( - prompt, "", get_face("Prompt"), - PromptFlags::DropHistoryEntriesWithBlankPrefix, shell_complete, + prompt, context.main_sel_register_value("|").str(), get_face("Prompt"), + PromptFlags::DropHistoryEntriesWithBlankPrefix | PromptFlags::InactiveInitString, + shell_complete, [](StringView cmdline, PromptEvent event, Context& context) { if (event != PromptEvent::Validate) @@ -685,12 +688,13 @@ void paste_all(Context& context, NormalParams params) } template -void regex_prompt(Context& context, String prompt, T func) +void regex_prompt(Context& context, String prompt, String default_regex, T func) { DisplayCoord position = context.has_window() ? context.window().position() : DisplayCoord{}; SelectionList selections = context.selections(); context.input_handler().prompt( - std::move(prompt), "", get_face("Prompt"), PromptFlags::None, complete_nothing, + std::move(prompt), default_regex, get_face("Prompt"), + PromptFlags::InactiveInitString, complete_nothing, [=](StringView str, PromptEvent event, Context& context) mutable { try { @@ -714,7 +718,7 @@ void regex_prompt(Context& context, String prompt, T func) if (event == PromptEvent::Validate) context.push_jump(); - func(str.empty() ? Regex{} : Regex{str}, event, context); + func(str.empty() ? Regex{default_regex} : Regex{str}, event, context); } catch (regex_error& err) { @@ -748,7 +752,7 @@ void search(Context& context, NormalParams params) Vector saved_reg{reg_content.begin(), reg_content.end()}; const int main_index = std::min(context.selections().main_index(), saved_reg.size()-1); - regex_prompt(context, prompt.str(), + regex_prompt(context, prompt.str(), saved_reg[main_index], [reg, count, saved_reg, main_index] (Regex regex, PromptEvent event, Context& context) { if (event == PromptEvent::Abort) @@ -756,9 +760,6 @@ void search(Context& context, NormalParams params) RegisterManager::instance()[reg].set(context, saved_reg); return; } - - if (regex.empty()) - regex = Regex{saved_reg[main_index]}; RegisterManager::instance()[reg].set(context, regex.str()); if (not regex.empty() and not regex.str().empty()) @@ -862,7 +863,7 @@ void select_regex(Context& context, NormalParams params) Vector saved_reg{reg_content.begin(), reg_content.end()}; const int main_index = std::min(context.selections().main_index(), saved_reg.size()-1); - regex_prompt(context, std::move(prompt), + regex_prompt(context, std::move(prompt), saved_reg[main_index], [reg, capture, saved_reg, main_index](Regex ex, PromptEvent event, Context& context) { if (event == PromptEvent::Abort) { @@ -870,8 +871,6 @@ void select_regex(Context& context, NormalParams params) return; } - if (ex.empty()) - ex = Regex{saved_reg[main_index]}; RegisterManager::instance()[reg].set(context, ex.str()); if (not ex.empty() and not ex.str().empty()) @@ -889,7 +888,7 @@ void split_regex(Context& context, NormalParams params) Vector saved_reg{reg_content.begin(), reg_content.end()}; const int main_index = std::min(context.selections().main_index(), saved_reg.size()-1); - regex_prompt(context, std::move(prompt), + regex_prompt(context, std::move(prompt), saved_reg[main_index], [reg, capture, saved_reg, main_index](Regex ex, PromptEvent event, Context& context) { if (event == PromptEvent::Abort) { @@ -897,8 +896,6 @@ void split_regex(Context& context, NormalParams params) return; } - if (ex.empty()) - ex = Regex{saved_reg[main_index]}; RegisterManager::instance()[reg].set(context, ex.str()); if (not ex.empty() and not ex.str().empty()) @@ -967,7 +964,8 @@ template void keep(Context& context, NormalParams) { constexpr const char* prompt = matching ? "keep matching:" : "keep not matching:"; - regex_prompt(context, prompt, [](const Regex& ex, PromptEvent event, Context& context) { + regex_prompt(context, prompt, String{}, + [](const Regex& ex, PromptEvent event, Context& context) { if (ex.empty() or event == PromptEvent::Abort) return; const Buffer& buffer = context.buffer();