Skip to content

Commit

Permalink
[prompt] show help fix multiline suggestion issue
Browse files Browse the repository at this point in the history
  • Loading branch information
tstack committed Feb 19, 2025
1 parent f321d6c commit eba8e7e
Show file tree
Hide file tree
Showing 11 changed files with 145 additions and 63 deletions.
6 changes: 6 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,15 @@ Features:
* The `:comment` command will now switch the prompt to multi-line
mode and does syntax highlighting for Markdown directives in the
comment.
* Added a `fuzzy_match()` SQL function that compares a pattern to
a string and returns a score.
The algorithm used is the same as in lnav itself.

Interface changes:
* The prompt is now a custom implementation instead of readline.
* Pressing `F1` in the prompt will show the help text for the
prompt itself.
The size of the prompt panel is expanded for readability.

## lnav v0.12.4

Expand Down
17 changes: 13 additions & 4 deletions src/base/string_util.cc
Original file line number Diff line number Diff line change
Expand Up @@ -277,11 +277,20 @@ abbreviate_str(char* str, size_t len, size_t max_len)
void
split_ws(const std::string& str, std::vector<std::string>& toks_out)
{
std::stringstream ss(str);
std::string buf;
auto str_sf = string_fragment::from_str(str);

while (ss >> buf) {
toks_out.push_back(buf);
while (true) {
auto split_pair = str_sf.split_when(isspace);
if (split_pair.first.empty()) {
if (split_pair.second.empty()) {
break;
}
str_sf = split_pair.second;
continue;
}

toks_out.emplace_back(split_pair.first.to_string());
str_sf = split_pair.second;
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/internals/cmd-ref.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1071,7 +1071,7 @@
Open the given prompt

**Parameters**
* **type\*** --- The type of prompt -- command, script, search, sql, user
* **type\*** --- The type of prompt
* **--alt** --- Perform the alternate action for this prompt by default
* **prompt** --- The prompt to display
* **initial-value** --- The initial value to fill in for the prompt
Expand Down
1 change: 1 addition & 0 deletions src/lnav.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1370,6 +1370,7 @@ VALUES ('org.lnav.mouse-support', -1, DATETIME('now', '+1 minute'),
prompt.p_editor.tc_window = lnav_data.ld_window;
prompt.p_editor.tc_height = 1;
prompt.p_editor.tc_text_format = text_format_t::TF_LNAV_SCRIPT;
prompt.p_editor.tc_on_help = bind_mem(&lnav::prompt::rl_help, &prompt);
prompt.p_editor.tc_on_focus = rl_focus;
prompt.p_editor.tc_on_change = rl_change;
prompt.p_editor.tc_on_perform = rl_callback;
Expand Down
21 changes: 18 additions & 3 deletions src/lnav.prompt.cc
Original file line number Diff line number Diff line change
Expand Up @@ -176,14 +176,18 @@ prompt::get()
}

void
prompt::focus_for(char sigil)
prompt::focus_for(char sigil, const std::vector<std::string>& args)
{
this->p_editor.tc_prefix.clear();
if (sigil) {
if (args.size() >= 3) {
this->p_editor.tc_prefix.al_string = args[2];
} else if (sigil) {
this->p_editor.tc_prefix.al_string.push_back(sigil);
}
this->p_editor.tc_height = 1;
this->p_editor.set_content("");
this->p_editor.set_content(cget(args, 3).value_or(""));
this->p_editor.move_cursor_to(textinput_curses::input_point::end());
this->p_editor.tc_popup.set_title("");
this->p_editor.focus();
}

Expand Down Expand Up @@ -255,6 +259,17 @@ prompt::refresh_sql_completions(textview_curses& tc)
}
}

void
prompt::rl_help(textinput_curses& tc)
{
if (tc.tc_height == 1) {
tc.set_height(8);
}

tc.tc_mode = textinput_curses::mode_t::show_help;
tc.set_needs_update();
}

void
prompt::rl_history(textinput_curses& tc)
{
Expand Down
3 changes: 2 additions & 1 deletion src/lnav.prompt.hh
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ struct prompt {
std::multimap<std::string, sql_item_t> p_sql_completions;
textinput_curses p_editor;

void focus_for(char sigil);
void focus_for(char sigil, const std::vector<std::string>& args);

void refresh_sql_completions(textview_curses& tc);
void insert_sql_completion(const std::string& name, const sql_item_t& item);
Expand All @@ -113,6 +113,7 @@ struct prompt {
std::vector<attr_line_t> get_cmd_parameter_completion(
textview_curses& tc, const help_text* ht, const std::string& str);

void rl_help(textinput_curses& tc);
void rl_history(textinput_curses& tc);
void rl_completion(textinput_curses& tc);
};
Expand Down
85 changes: 42 additions & 43 deletions src/lnav_commands.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3611,7 +3611,7 @@ command_prompt(std::vector<std::string>& args)
"commands.html") " for more details");

set_view_mode(ln_mode_t::COMMAND);
prompt.focus_for(':');
prompt.focus_for(':', args);

rl_set_help();
}
Expand All @@ -3628,7 +3628,7 @@ script_prompt(std::vector<std::string>& args)

lnav_data.ld_exec_context.ec_top_line = tc->get_selection();
find_format_scripts(lnav_data.ld_config_paths, scripts);
prompt.focus_for('|');
prompt.focus_for('|', args);
lnav_data.ld_bottom_source.set_prompt(
"Enter a script to execute: (Press " ANSI_BOLD("CTRL+]") " to abort)");
}
Expand All @@ -3643,7 +3643,7 @@ search_prompt(std::vector<std::string>& args)
log_debug("search prompt");
set_view_mode(ln_mode_t::SEARCH);
lnav_data.ld_search_start_line = tc->get_selection();
prompt.focus_for('/');
prompt.focus_for('/', args);
lnav_data.ld_doc_status_source.set_title("Syntax Help");
lnav_data.ld_doc_status_source.set_description("");
rl_set_help();
Expand All @@ -3660,7 +3660,7 @@ search_filters_prompt(std::vector<std::string>& args)

set_view_mode(ln_mode_t::SEARCH_FILTERS);
lnav_data.ld_filter_view.reload_data();
prompt.focus_for('/');
prompt.focus_for('/', args);
lnav_data.ld_bottom_source.set_prompt(
"Search for: "
"(Press " ANSI_BOLD("CTRL+J") " to jump to a previous hit and "
Expand All @@ -3674,7 +3674,7 @@ search_files_prompt(std::vector<std::string>& args)
static auto& prompt = lnav::prompt::get();

set_view_mode(ln_mode_t::SEARCH_FILES);
prompt.focus_for('/');
prompt.focus_for('/', args);
lnav_data.ld_bottom_source.set_prompt(
"Search for: "
"(Press " ANSI_BOLD("CTRL+J") " to jump to a previous hit and "
Expand All @@ -3687,7 +3687,7 @@ search_spectro_details_prompt(std::vector<std::string>& args)
static auto& prompt = lnav::prompt::get();

set_view_mode(ln_mode_t::SEARCH_SPECTRO_DETAILS);
prompt.focus_for('/');
prompt.focus_for('/', args);

lnav_data.ld_bottom_source.set_prompt(
"Search for: "
Expand All @@ -3708,7 +3708,7 @@ sql_prompt(std::vector<std::string>& args)
set_view_mode(ln_mode_t::SQL);
setup_logline_table(lnav_data.ld_exec_context);
prompt.refresh_sql_completions(*tc);
prompt.focus_for(';');
prompt.focus_for(';', args);

lnav_data.ld_doc_status_source.set_title("Query Help");
lnav_data.ld_doc_status_source.set_description(
Expand Down Expand Up @@ -3736,7 +3736,7 @@ user_prompt(std::vector<std::string>& args)

set_view_mode(ln_mode_t::USER);
setup_logline_table(lnav_data.ld_exec_context);
prompt.focus_for('\0');
prompt.focus_for('\0', args);

lnav_data.ld_bottom_source.update_loading(0, 0);
lnav_data.ld_status[LNS_BOTTOM].do_update();
Expand All @@ -3760,8 +3760,7 @@ com_prompt(exec_context& ec,
{"user", user_prompt},
};

if (args.empty()) {
} else if (!ec.ec_dry_run) {
if (!ec.ec_dry_run) {
static const intern_string_t SRC = intern_string::lookup("flags");

auto lexer = shlex(cmdline);
Expand Down Expand Up @@ -3803,39 +3802,39 @@ com_prompt(exec_context& ec,
}

readline_context::command_t STD_COMMANDS[] = {
{"prompt",
com_prompt,

help_text(":prompt")
.with_summary("Open the given prompt")
.with_parameter({"type",
"The type of prompt -- command, script, "
"search, sql, user"})
.with_parameter(help_text("--alt",
"Perform the alternate action "
"for this prompt by default")
.optional())
.with_parameter(help_text("prompt", "The prompt to display")
.with_enum_values({
"breadcrumb",
"command",
"script",
"search",
"sql",
})
.optional())
.with_parameter(
help_text("initial-value",
"The initial value to fill in for the prompt")
.optional())
.with_example({
"To open the command prompt with 'filter-in' already filled in",
"command : 'filter-in '",
})
.with_example({
"To ask the user a question",
"user 'Are you sure? '",
})},
{
"prompt",
com_prompt,

help_text(":prompt")
.with_summary("Open the given prompt")
.with_parameter(
help_text{"type", "The type of prompt"}.with_enum_values({
"breadcrumb",
"command",
"script",
"search",
"sql",
}))
.with_parameter(help_text("--alt",
"Perform the alternate action "
"for this prompt by default")
.optional())
.with_parameter(
help_text("prompt", "The prompt to display").optional())
.with_parameter(
help_text("initial-value",
"The initial value to fill in for the prompt")
.optional())
.with_example({
"To open the command prompt with 'filter-in' already filled in",
"command : 'filter-in '",
})
.with_example({
"To ask the user a question",
"user 'Are you sure? '",
}),
},

{"adjust-log-time",
com_adjust_log_time,
Expand Down
13 changes: 11 additions & 2 deletions src/readline_callbacks.cc
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,7 @@ rl_cmd_change(textinput_curses& rc, bool is_req)
iter = lnav_commands.find(args[0]);
}
if (iter == lnav_commands.end()
|| (args.size() == 1 && !endswith(line, " ")))
|| (args.size() == 1 && !endswith(line, " ") && !endswith(line, "\n")))
{
switch (rc.tc_popup_type) {
case textinput_curses::popup_type_t::history: {
Expand Down Expand Up @@ -398,6 +398,8 @@ rl_cmd_change(textinput_curses& rc, bool is_req)
}
}
prompt.p_editor.tc_height = std::min(
prompt.p_editor.tc_height, (int) prompt.p_editor.tc_lines.size());
lnav_data.ld_doc_source.replace_with(CMD_HELP);
lnav_data.ld_example_source.replace_with(CMD_EXAMPLE);
lnav_data.ld_bottom_source.set_prompt(LNAV_CMD_PROMPT);
Expand Down Expand Up @@ -514,7 +516,10 @@ rl_cmd_change(textinput_curses& rc, bool is_req)
== help_parameter_format_t::HPF_MULTILINE_TEXT)
{
prompt.p_editor.tc_height = 5;
} else {
} else if (prompt.p_editor.tc_height > 1) {
auto ml_content = prompt.p_editor.get_content();
std::replace(ml_content.begin(), ml_content.end(), '\n', ' ');
prompt.p_editor.set_content(ml_content);
prompt.p_editor.tc_height = 1;
}
Expand All @@ -539,6 +544,10 @@ rl_change(textinput_curses& rc)
log_debug("rl_change");
if (prompt.p_editor.tc_mode == textinput_curses::mode_t::show_help) {
return;
}
switch (lnav_data.ld_mode) {
case ln_mode_t::SEARCH: {
if (rc.get_content().empty() && tc->tc_selected_text) {
Expand Down
Loading

0 comments on commit eba8e7e

Please sign in to comment.