[config-ui] support for searching

This commit is contained in:
Timothy Stack 2020-10-28 21:23:34 -07:00
parent 8b38bb0970
commit 56866d8a33
9 changed files with 165 additions and 18 deletions

View File

@ -32,6 +32,7 @@
#ifndef curl_looper_hh
#define curl_looper_hh
#include <atomic>
#include <map>
#include <string>
#include <vector>
@ -234,7 +235,7 @@ private:
bool cl_started;
pthread_t cl_thread;
volatile bool cl_looping;
std::atomic<bool> cl_looping;
auto_mem<CURLM> cl_curl_multi;
pthread_mutex_t cl_mutex;
pthread_cond_t cl_cond;

View File

@ -103,6 +103,19 @@ bool files_sub_source::list_input_handle_key(listview_curses &lv, int ch)
lv.reload_data();
return true;
}
case 'n': {
execute_command(lnav_data.ld_exec_context, "next-mark search");
return true;
}
case 'N': {
execute_command(lnav_data.ld_exec_context, "prev-mark search");
return true;
}
case '/': {
execute_command(lnav_data.ld_exec_context,
"prompt search-files");
return true;
}
}
return false;
}

View File

@ -219,6 +219,19 @@ bool filter_sub_source::list_input_handle_key(listview_curses &lv, int ch)
tss->text_filters_changed();
return true;
}
case 'n': {
execute_command(lnav_data.ld_exec_context, "next-mark search");
return true;
}
case 'N': {
execute_command(lnav_data.ld_exec_context, "prev-mark search");
return true;
}
case '/': {
execute_command(lnav_data.ld_exec_context,
"prompt search-filters");
return true;
}
default:
log_debug("unhandled %x", ch);
break;

View File

@ -347,8 +347,14 @@ public:
if (this->lv_selectable) {
if (this->lv_selection < top) {
this->lv_selection = top;
} else if (this->lv_selection > this->get_bottom()) {
this->lv_selection = this->get_bottom();
} else {
auto bot = this->get_bottom();
if (bot != -1_vl) {
if (this->lv_selection > bot) {
this->lv_selection = bot;
}
}
}
}
this->invoke_scroll();
@ -367,6 +373,8 @@ public:
if (avail > 0) {
retval += vis_line_t(avail - 1);
} else {
retval = -1_vl;
}
return retval;

View File

@ -715,7 +715,7 @@ vis_line_t next_cluster(
bookmark_type_t *bt,
const vis_line_t top)
{
textview_curses *tc = *(lnav_data.ld_view_stack.top());
textview_curses *tc = get_textview_for_mode(lnav_data.ld_mode);
vis_bookmarks &bm = tc->get_bookmarks();
bookmark_vector<vis_line_t> &bv = bm[bt];
bool top_is_marked = binary_search(bv.begin(), bv.end(), top);
@ -760,19 +760,26 @@ bool moveto_cluster(vis_line_t(bookmark_vector<vis_line_t>::*f) (vis_line_t) con
bookmark_type_t *bt,
vis_line_t top)
{
textview_curses *tc = *(lnav_data.ld_view_stack.top());
textview_curses *tc = get_textview_for_mode(lnav_data.ld_mode);
vis_line_t new_top;
new_top = next_cluster(f, bt, top);
if (new_top == -1) {
new_top = next_cluster(f, bt, tc->get_top());
new_top = next_cluster(f, bt,
tc->is_selectable() ?
tc->get_selection() :
tc->get_top());
}
if (new_top != -1) {
tc->get_sub_source()->get_location_history() | [new_top] (auto lh) {
lh->loc_history_append(new_top);
};
tc->set_top(new_top);
if (tc->is_selectable()) {
tc->set_selection(new_top);
} else {
tc->set_top(new_top);
}
return true;
}
@ -784,9 +791,14 @@ bool moveto_cluster(vis_line_t(bookmark_vector<vis_line_t>::*f) (vis_line_t) con
void previous_cluster(bookmark_type_t *bt, textview_curses *tc)
{
key_repeat_history &krh = lnav_data.ld_key_repeat_history;
vis_line_t height, new_top, initial_top = tc->get_top();
vis_line_t height, new_top, initial_top;
unsigned long width;
if (tc->is_selectable()) {
initial_top = tc->get_selection();
} else {
initial_top = tc->get_top();
}
new_top = next_cluster(&bookmark_vector<vis_line_t>::prev,
bt,
initial_top);
@ -804,7 +816,11 @@ void previous_cluster(bookmark_type_t *bt, textview_curses *tc)
lh->loc_history_append(new_top);
};
tc->set_top(new_top);
if (tc->is_selectable()) {
tc->set_selection(new_top);
} else {
tc->set_top(new_top);
}
}
else {
alerter::singleton().chime();
@ -813,7 +829,8 @@ void previous_cluster(bookmark_type_t *bt, textview_curses *tc)
vis_line_t search_forward_from(textview_curses *tc)
{
vis_line_t height, retval = tc->get_top();
vis_line_t height, retval =
tc->is_selectable() ? tc->get_selection() : tc->get_top();
key_repeat_history &krh = lnav_data.ld_key_repeat_history;
unsigned long width;
@ -1315,6 +1332,8 @@ static bool handle_key(int ch) {
case LNM_COMMAND:
case LNM_SEARCH:
case LNM_SEARCH_FILTERS:
case LNM_SEARCH_FILES:
case LNM_CAPTURE:
case LNM_SQL:
case LNM_EXEC:
@ -1479,6 +1498,8 @@ static void looper()
readline_context command_context("cmd", &lnav_commands);
readline_context search_context("search", nullptr, false);
readline_context search_filters_context("search-filters", nullptr, false);
readline_context search_files_context("search-files", nullptr, false);
readline_context index_context("capture");
readline_context sql_context("sql", nullptr, false);
readline_context exec_context("exec");
@ -1491,6 +1512,12 @@ static void looper()
search_context
.set_append_character(0)
.set_highlighter(readline_regex_highlighter);
search_filters_context
.set_append_character(0)
.set_highlighter(readline_regex_highlighter);
search_files_context
.set_append_character(0)
.set_highlighter(readline_regex_highlighter);
sql_context
.set_highlighter(readline_sqlite_highlighter)
.set_quote_chars("\"")
@ -1505,6 +1532,8 @@ static void looper()
rlc.add_context(LNM_COMMAND, command_context);
rlc.add_context(LNM_SEARCH, search_context);
rlc.add_context(LNM_SEARCH_FILTERS, search_filters_context);
rlc.add_context(LNM_SEARCH_FILES, search_files_context);
rlc.add_context(LNM_CAPTURE, index_context);
rlc.add_context(LNM_SQL, sql_context);
rlc.add_context(LNM_EXEC, exec_context);
@ -1797,6 +1826,8 @@ static void looper()
for (auto &tc : lnav_data.ld_views) {
tc.update_poll_set(pollfds);
}
lnav_data.ld_filter_view.update_poll_set(pollfds);
lnav_data.ld_files_view.update_poll_set(pollfds);
if (lnav_data.ld_input_dispatcher.in_escape()) {
to.tv_usec = 15000;
@ -1850,6 +1881,8 @@ static void looper()
rlc.check_poll_set(pollfds);
lnav_data.ld_filter_source.fss_editor.check_poll_set(pollfds);
lnav_data.ld_filter_view.check_poll_set(pollfds);
lnav_data.ld_files_view.check_poll_set(pollfds);
}
if (timer.time_to_update(overlay_counter)) {
@ -2006,6 +2039,8 @@ void wait_for_children()
for (auto &tc : lnav_data.ld_views) {
tc.update_poll_set(pollfds);
}
lnav_data.ld_filter_view.update_poll_set(pollfds);
lnav_data.ld_files_view.update_poll_set(pollfds);
if (pollfds.empty()) {
return;
@ -2030,9 +2065,25 @@ void wait_for_children()
lnav_data.ld_bottom_source.update_hits(tc);
};
}
lnav_data.ld_filter_view.check_poll_set(pollfds);
lnav_data.ld_files_view.check_poll_set(pollfds);
} while (true);
}
textview_curses *get_textview_for_mode(ln_mode_t mode)
{
switch (mode) {
case LNM_SEARCH_FILTERS:
case LNM_FILTER:
return &lnav_data.ld_filter_view;
case LNM_SEARCH_FILES:
case LNM_FILES:
return &lnav_data.ld_files_view;
default:
return *lnav_data.ld_view_stack.top();
}
}
static void print_errors(vector<string> error_list)
{
for (auto &iter : error_list) {

View File

@ -78,6 +78,8 @@ typedef enum {
LNM_FILES,
LNM_COMMAND,
LNM_SEARCH,
LNM_SEARCH_FILTERS,
LNM_SEARCH_FILES,
LNM_CAPTURE,
LNM_SQL,
LNM_EXEC,
@ -380,5 +382,6 @@ bool moveto_cluster(vis_line_t(bookmark_vector<vis_line_t>::*f) (vis_line_t) con
vis_line_t top);
void previous_cluster(bookmark_type_t *bt, textview_curses *tc);
vis_line_t search_forward_from(textview_curses *tc);
textview_curses *get_textview_for_mode(ln_mode_t mode);
#endif

View File

@ -430,7 +430,7 @@ static Result<string, string> com_goto_mark(exec_context &ec, string cmdline, ve
args.emplace_back("mark-type");
}
else {
textview_curses *tc = *lnav_data.ld_view_stack.top();
textview_curses *tc = get_textview_for_mode(lnav_data.ld_mode);
string type_name = "user";
if (args.size() > 1) {
@ -4119,6 +4119,43 @@ static void search_prompt(vector<string> &args)
ANSI_BOLD("CTRL+]") " to abort)");
}
static void search_filters_prompt(vector<string> &args)
{
lnav_data.ld_mode = LNM_SEARCH_FILTERS;
add_view_text_possibilities(lnav_data.ld_rl_view,
LNM_SEARCH_FILTERS,
"*",
&lnav_data.ld_filter_view);
lnav_data.ld_rl_view->focus(LNM_SEARCH_FILTERS,
cget(args, 2).value_or("/"),
cget(args, 3).value_or(""));
lnav_data.ld_bottom_source.set_prompt(
"Search for: "
"(Press " ANSI_BOLD("CTRL+J") " to jump to a previous hit and "
ANSI_BOLD("CTRL+]") " to abort)");
}
static void search_files_prompt(vector<string> &args)
{
static pcrecpp::RE re_escape(R"(([.\^$*+?()\[\]{}\\|]))");
lnav_data.ld_mode = LNM_SEARCH_FILES;
for (const auto& lf : lnav_data.ld_active_files.fc_files) {
auto path = lf->get_unique_path();
re_escape.GlobalReplace(R"(\\\1)", &path);
lnav_data.ld_rl_view->add_possibility(LNM_SEARCH_FILES,
"*",
path);
}
lnav_data.ld_rl_view->focus(LNM_SEARCH_FILES,
cget(args, 2).value_or("/"),
cget(args, 3).value_or(""));
lnav_data.ld_bottom_source.set_prompt(
"Search for: "
"(Press " ANSI_BOLD("CTRL+J") " to jump to a previous hit and "
ANSI_BOLD("CTRL+]") " to abort)");
}
static void sql_prompt(vector<string> &args)
{
textview_curses *tc = *lnav_data.ld_view_stack.top();
@ -4170,6 +4207,8 @@ static Result<string, string> com_prompt(exec_context &ec, string cmdline, vecto
{"command", command_prompt},
{"script", script_prompt},
{"search", search_prompt},
{"search-filters", search_filters_prompt},
{"search-files", search_files_prompt},
{"sql", sql_prompt},
{"user", user_prompt},
};

View File

@ -142,7 +142,7 @@ void rl_set_help()
void rl_change(void *dummy, readline_curses *rc)
{
textview_curses *tc = *lnav_data.ld_view_stack.top();
textview_curses *tc = get_textview_for_mode(lnav_data.ld_mode);
tc->get_highlights().erase({highlight_source_t::PREVIEW, "preview"});
tc->get_highlights().erase({highlight_source_t::PREVIEW, "bodypreview"});
@ -271,7 +271,7 @@ void rl_change(void *dummy, readline_curses *rc)
static void rl_search_internal(void *dummy, readline_curses *rc, ln_mode_t mode, bool complete = false)
{
textview_curses *tc = *lnav_data.ld_view_stack.top();
textview_curses *tc = get_textview_for_mode(mode);
string term_val;
string name;
@ -281,6 +281,8 @@ static void rl_search_internal(void *dummy, readline_curses *rc, ln_mode_t mode,
switch (mode) {
case LNM_SEARCH:
case LNM_SEARCH_FILTERS:
case LNM_SEARCH_FILES:
name = "$search";
break;
@ -440,7 +442,7 @@ static void rl_search_internal(void *dummy, readline_curses *rc, ln_mode_t mode,
void rl_search(void *dummy, readline_curses *rc)
{
textview_curses *tc = *lnav_data.ld_view_stack.top();
textview_curses *tc = get_textview_for_mode(lnav_data.ld_mode);
rl_search_internal(dummy, rc, lnav_data.ld_mode);
tc->set_follow_search_for(0, {});
@ -448,7 +450,7 @@ void rl_search(void *dummy, readline_curses *rc)
void rl_abort(void *dummy, readline_curses *rc)
{
textview_curses *tc = *lnav_data.ld_view_stack.top();
textview_curses *tc = get_textview_for_mode(lnav_data.ld_mode);
lnav_data.ld_bottom_source.set_prompt("");
lnav_data.ld_example_source.clear();
@ -480,7 +482,7 @@ void rl_abort(void *dummy, readline_curses *rc)
static void rl_callback_int(void *dummy, readline_curses *rc, bool is_alt)
{
textview_curses *tc = *lnav_data.ld_view_stack.top();
textview_curses *tc = get_textview_for_mode(lnav_data.ld_mode);
exec_context &ec = lnav_data.ld_exec_context;
string alt_msg;
@ -492,7 +494,20 @@ static void rl_callback_int(void *dummy, readline_curses *rc, bool is_alt)
tc->get_highlights().erase({highlight_source_t::PREVIEW, "preview"});
tc->get_highlights().erase({highlight_source_t::PREVIEW, "bodypreview"});
auto old_mode = std::exchange(lnav_data.ld_mode, LNM_PAGING);
auto new_mode = LNM_PAGING;
switch (lnav_data.ld_mode) {
case LNM_SEARCH_FILTERS:
new_mode = LNM_FILTER;
break;
case LNM_SEARCH_FILES:
new_mode = LNM_FILES;
break;
default:
break;
}
auto old_mode = std::exchange(lnav_data.ld_mode, new_mode);
switch (old_mode) {
case LNM_PAGING:
case LNM_FILTER:
@ -514,6 +529,8 @@ static void rl_callback_int(void *dummy, readline_curses *rc, bool is_alt)
break;
case LNM_SEARCH:
case LNM_SEARCH_FILTERS:
case LNM_SEARCH_FILES:
case LNM_CAPTURE:
rl_search_internal(dummy, rc, old_mode, true);
if (!rc->get_value().empty()) {

View File

@ -256,7 +256,9 @@ void layout_views()
bool doc_open = doc_height > 0;
bool filters_open = (lnav_data.ld_mode == LNM_FILTER ||
lnav_data.ld_mode == LNM_FILES) &&
lnav_data.ld_mode == LNM_FILES ||
lnav_data.ld_mode == LNM_SEARCH_FILTERS ||
lnav_data.ld_mode == LNM_SEARCH_FILES) &&
!preview_status_open &&
!doc_open;
int filter_height = filters_open ? 3 : 0;