summaryrefslogtreecommitdiffstats
path: root/src/textview_curses.cc
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/textview_curses.cc560
1 files changed, 405 insertions, 155 deletions
diff --git a/src/textview_curses.cc b/src/textview_curses.cc
index 6165f9e..c078366 100644
--- a/src/textview_curses.cc
+++ b/src/textview_curses.cc
@@ -33,15 +33,17 @@
#include "textview_curses.hh"
#include "base/ansi_scrubber.hh"
+#include "base/humanize.time.hh"
#include "base/injector.hh"
#include "base/time_util.hh"
#include "config.h"
-#include "data_parser.hh"
+#include "data_scanner.hh"
#include "fmt/format.h"
#include "lnav_config.hh"
-#include "log_format.hh"
+#include "log_format_fwd.hh"
#include "logfile.hh"
#include "shlex.hh"
+#include "text_overlay_menu.hh"
#include "view_curses.hh"
const auto REVERSE_SEARCH_OFFSET = 2000_vl;
@@ -81,7 +83,7 @@ text_filter::add_line(logfile_filter_state& lfs,
logfile::const_iterator ll,
const shared_buffer_ref& line)
{
- bool match_state = this->matches(*lfs.tfs_logfile, ll, line);
+ bool match_state = this->matches(line_source{*lfs.tfs_logfile, ll}, line);
if (ll->is_message()) {
this->end_of_message(lfs);
@@ -124,12 +126,66 @@ text_filter::end_of_message(logfile_filter_state& lfs)
lfs.tfs_lines_for_message[this->lf_index] = 0;
}
+log_accel::direction_t
+text_accel_source::get_line_accel_direction(vis_line_t vl)
+{
+ log_accel la;
+
+ while (vl >= 0) {
+ const auto* curr_line = this->text_accel_get_line(vl);
+
+ if (!curr_line->is_message()) {
+ --vl;
+ continue;
+ }
+
+ if (!la.add_point(curr_line->get_time_in_millis())) {
+ break;
+ }
+
+ --vl;
+ }
+
+ return la.get_direction();
+}
+
+std::string
+text_accel_source::get_time_offset_for_line(textview_curses& tc, vis_line_t vl)
+{
+ auto ll = this->text_accel_get_line(vl);
+ auto curr_tv = ll->get_timeval();
+ struct timeval diff_tv;
+
+ auto prev_umark = tc.get_bookmarks()[&textview_curses::BM_USER].prev(vl);
+ auto next_umark = tc.get_bookmarks()[&textview_curses::BM_USER].next(vl);
+ auto prev_emark
+ = tc.get_bookmarks()[&textview_curses::BM_USER_EXPR].prev(vl);
+ auto next_emark
+ = tc.get_bookmarks()[&textview_curses::BM_USER_EXPR].next(vl);
+ if (!prev_umark && !prev_emark && (next_umark || next_emark)) {
+ auto next_line = this->text_accel_get_line(
+ std::max(next_umark.value_or(0), next_emark.value_or(0)));
+
+ diff_tv = curr_tv - next_line->get_timeval();
+ } else {
+ auto prev_row
+ = std::max(prev_umark.value_or(0), prev_emark.value_or(0));
+ auto first_line = this->text_accel_get_line(prev_row);
+ auto start_tv = first_line->get_timeval();
+ diff_tv = curr_tv - start_tv;
+ }
+
+ return humanize::time::duration::from_tv(diff_tv).to_string();
+}
+
const bookmark_type_t textview_curses::BM_USER("user");
const bookmark_type_t textview_curses::BM_USER_EXPR("user-expr");
const bookmark_type_t textview_curses::BM_SEARCH("search");
const bookmark_type_t textview_curses::BM_META("meta");
+const bookmark_type_t textview_curses::BM_PARTITION("partition");
-textview_curses::textview_curses() : tc_search_action(noop_func{})
+textview_curses::textview_curses()
+ : lnav_config_listener(__FILE__), tc_search_action(noop_func{})
{
this->set_data_source(this);
}
@@ -155,11 +211,13 @@ textview_curses::reload_config(error_reporter& reporter)
iter = this->tc_highlights.erase(iter);
}
- std::map<std::string, std::string> vars;
+ std::map<std::string, scoped_value_t> vars;
auto curr_theme_iter
= lnav_config.lc_ui_theme_defs.find(lnav_config.lc_ui_theme);
if (curr_theme_iter != lnav_config.lc_ui_theme_defs.end()) {
- vars = curr_theme_iter->second.lt_vars;
+ for (const auto& vpair : curr_theme_iter->second.lt_vars) {
+ vars[vpair.first] = vpair.second;
+ }
}
for (const auto& theme_name : {DEFAULT_THEME_NAME, lnav_config.lc_ui_theme})
@@ -171,19 +229,7 @@ textview_curses::reload_config(error_reporter& reporter)
}
for (const auto& hl_pair : theme_iter->second.lt_highlights) {
- if (hl_pair.second.hc_regex.empty()) {
- continue;
- }
-
- auto regex = lnav::pcre2pp::code::from(hl_pair.second.hc_regex);
-
- if (regex.isErr()) {
- const static intern_string_t PATTERN_SRC
- = intern_string::lookup("pattern");
-
- auto ce = regex.unwrapErr();
- reporter(&hl_pair.second.hc_regex,
- lnav::console::to_user_message(PATTERN_SRC, ce));
+ if (hl_pair.second.hc_regex.pp_value == nullptr) {
continue;
}
@@ -194,8 +240,8 @@ textview_curses::reload_config(error_reporter& reporter)
fg1 = sc.sc_color;
bg1 = sc.sc_background_color;
- shlex(fg1).eval(fg_color, vars);
- shlex(bg1).eval(bg_color, vars);
+ shlex(fg1).eval(fg_color, scoped_resolver{&vars});
+ shlex(bg1).eval(bg_color, scoped_resolver{&vars});
auto fg = styling::color_unit::from_str(fg_color).unwrapOrElse(
[&](const auto& msg) {
@@ -228,7 +274,7 @@ textview_curses::reload_config(error_reporter& reporter)
attrs.ta_attrs |= A_UNDERLINE;
}
this->tc_highlights[{highlight_source_t::THEME, hl_pair.first}]
- = highlighter(regex.unwrap().to_shared())
+ = highlighter(hl_pair.second.hc_regex.pp_value)
.with_attrs(attrs)
.with_color(fg, bg)
.with_nestable(false);
@@ -241,8 +287,20 @@ textview_curses::reload_config(error_reporter& reporter)
}
void
+textview_curses::invoke_scroll()
+{
+ this->tc_selected_text = nonstd::nullopt;
+ if (this->tc_sub_source != nullptr) {
+ this->tc_sub_source->scroll_invoked(this);
+ }
+
+ listview_curses::invoke_scroll();
+}
+
+void
textview_curses::reload_data()
{
+ this->tc_selected_text = nonstd::nullopt;
if (this->tc_sub_source != nullptr) {
this->tc_sub_source->text_update_marks(this->tc_bookmarks);
}
@@ -352,79 +410,297 @@ textview_curses::handle_mouse(mouse_event& me)
unsigned long width;
vis_line_t height;
- if (this->tc_selection_start == -1_vl && listview_curses::handle_mouse(me))
- {
- return true;
+ if (!this->vc_visible || this->lv_height == 0) {
+ return false;
}
- if (this->tc_delegate != nullptr
- && this->tc_delegate->text_handle_mouse(*this, me))
- {
+ if (!this->tc_selection_start && listview_curses::handle_mouse(me)) {
return true;
}
- if (me.me_button != mouse_button_t::BUTTON_LEFT) {
- return false;
- }
-
- vis_line_t mouse_line(this->get_top() + me.me_y);
+ auto mouse_line = (me.me_y < 0 || me.me_y >= this->lv_display_lines.size())
+ ? empty_space{}
+ : this->lv_display_lines[me.me_y];
+ this->get_dimensions(height, width);
- if (mouse_line > this->get_bottom()) {
- mouse_line = this->get_bottom();
+ if (!mouse_line.is<overlay_menu>()
+ && (me.me_button != mouse_button_t::BUTTON_LEFT
+ || me.me_state != mouse_button_state_t::BUTTON_STATE_RELEASED))
+ {
+ this->tc_selected_text = nonstd::nullopt;
+ this->set_needs_update();
+ }
+
+ nonstd::optional<int> overlay_content_min_y;
+ nonstd::optional<int> overlay_content_max_y;
+ if (this->tc_press_line.is<overlay_content>()) {
+ auto main_line
+ = this->tc_press_line.get<overlay_content>().oc_main_line;
+ for (size_t lpc = 0; lpc < this->lv_display_lines.size(); lpc++) {
+ if (overlay_content_min_y
+ && !this->lv_display_lines[lpc].is<static_overlay_content>()
+ && !this->lv_display_lines[lpc].is<overlay_content>())
+ {
+ overlay_content_max_y = lpc;
+ break;
+ }
+ if (this->lv_display_lines[lpc].is<main_content>()) {
+ auto& mc = this->lv_display_lines[lpc].get<main_content>();
+ if (mc.mc_line == main_line) {
+ overlay_content_min_y = lpc;
+ }
+ }
+ }
+ if (overlay_content_min_y && !overlay_content_max_y) {
+ overlay_content_max_y = this->lv_display_lines.size();
+ }
}
- this->get_dimensions(height, width);
+ auto* sub_delegate = dynamic_cast<text_delegate*>(this->tc_sub_source);
switch (me.me_state) {
- case mouse_button_state_t::BUTTON_STATE_PRESSED:
- this->tc_selection_start = mouse_line;
- this->tc_selection_last = -1_vl;
- this->tc_selection_cleared = false;
- break;
- case mouse_button_state_t::BUTTON_STATE_DRAGGED:
- if (me.me_y <= 0) {
- this->shift_top(-1_vl);
- me.me_y = 0;
- mouse_line = this->get_top();
+ case mouse_button_state_t::BUTTON_STATE_PRESSED: {
+ this->tc_text_selection_active = true;
+ this->tc_press_line = mouse_line;
+ this->tc_press_left = this->lv_left + me.me_press_x;
+ if (!this->lv_selectable) {
+ this->set_selectable(true);
}
- if (me.me_y >= height
- && this->get_top() < this->get_top_for_last_row())
- {
- this->shift_top(1_vl);
- me.me_y = height;
- mouse_line = this->get_bottom();
+ mouse_line.match(
+ [this, &me, sub_delegate, &mouse_line](const main_content& mc) {
+ if (this->vc_enabled) {
+ if (this->tc_supports_marks
+ && me.me_button == mouse_button_t::BUTTON_LEFT
+ && me.is_modifier_pressed(
+ mouse_event::modifier_t::shift))
+ {
+ this->tc_selection_start = mc.mc_line;
+ }
+ this->set_selection_without_context(mc.mc_line);
+ this->tc_press_event = me;
+ }
+ if (this->tc_delegate != nullptr) {
+ this->tc_delegate->text_handle_mouse(
+ *this, mouse_line, me);
+ }
+ if (sub_delegate != nullptr) {
+ sub_delegate->text_handle_mouse(*this, mouse_line, me);
+ }
+ },
+ [](const overlay_menu& om) {},
+ [](const static_overlay_content& soc) {
+
+ },
+ [this](const overlay_content& oc) {
+ this->set_overlay_selection(oc.oc_line);
+ },
+ [](const empty_space& es) {});
+ break;
+ }
+ case mouse_button_state_t::BUTTON_STATE_DOUBLE_CLICK: {
+ if (!this->lv_selectable) {
+ this->set_selectable(true);
}
+ this->tc_text_selection_active = false;
+ mouse_line.match(
+ [this, &me, &mouse_line, sub_delegate](const main_content& mc) {
+ if (this->vc_enabled) {
+ if (this->tc_supports_marks
+ && me.me_button == mouse_button_t::BUTTON_LEFT)
+ {
+ attr_line_t al;
+
+ this->textview_value_for_row(mc.mc_line, al);
+ auto line_sf
+ = string_fragment::from_str(al.get_string());
+ auto cursor_sf = line_sf.sub_cell_range(
+ this->lv_left + me.me_x,
+ this->lv_left + me.me_x);
+ auto ds = data_scanner(line_sf);
+ auto tf = this->tc_sub_source->get_text_format();
+ while (true) {
+ auto tok_res = ds.tokenize2(tf);
+ if (!tok_res) {
+ break;
+ }
+
+ auto tok = tok_res.value();
+ auto tok_sf
+ = (tok.tr_token
+ == data_token_t::DT_QUOTED_STRING
+ && (cursor_sf.sf_begin
+ == tok.to_string_fragment()
+ .sf_begin
+ || cursor_sf.sf_begin
+ == tok.to_string_fragment()
+ .sf_end
+ - 1))
+ ? tok.to_string_fragment()
+ : tok.inner_string_fragment();
+ if (tok_sf.contains(cursor_sf)
+ && tok.tr_token != data_token_t::DT_WHITE)
+ {
+ auto group_tok
+ = ds.find_matching_bracket(tf, tok);
+ if (group_tok) {
+ tok_sf = group_tok.value()
+ .to_string_fragment();
+ }
+ this->tc_selected_text = selected_text_info{
+ me.me_x,
+ mc.mc_line,
+ line_range{
+ tok_sf.sf_begin,
+ tok_sf.sf_end,
+ },
+ tok_sf.to_string(),
+ };
+ this->set_needs_update();
+ break;
+ }
+ }
+ }
+ this->set_selection_without_context(mc.mc_line);
+ }
+ if (this->tc_delegate != nullptr) {
+ this->tc_delegate->text_handle_mouse(
+ *this, mouse_line, me);
+ }
+ if (sub_delegate != nullptr) {
+ sub_delegate->text_handle_mouse(*this, mouse_line, me);
+ }
+ },
+ [](const static_overlay_content& soc) {
- if (this->tc_selection_last == mouse_line)
- break;
+ },
+ [](const overlay_menu& om) {
- if (this->tc_selection_last != -1) {
- this->toggle_user_mark(&textview_curses::BM_USER,
- this->tc_selection_start,
- this->tc_selection_last);
- }
- if (this->tc_selection_start == mouse_line) {
- this->tc_selection_last = -1_vl;
+ },
+ [](const overlay_content& oc) {
+
+ },
+ [](const empty_space& es) {});
+ break;
+ }
+ case mouse_button_state_t::BUTTON_STATE_DRAGGED: {
+ this->tc_text_selection_active = true;
+ if (!this->vc_enabled) {
+ } else if (me.me_y == me.me_press_y) {
+ if (mouse_line.is<main_content>()) {
+ auto& mc = mouse_line.get<main_content>();
+ attr_line_t al;
+ auto low_x = std::min(this->tc_press_left,
+ (int) this->lv_left + me.me_x);
+ auto high_x = std::max(this->tc_press_left,
+ (int) this->lv_left + me.me_x);
+
+ this->set_selection_without_context(mc.mc_line);
+ if (this->tc_supports_marks
+ && me.me_button == mouse_button_t::BUTTON_LEFT)
+ {
+ this->textview_value_for_row(mc.mc_line, al);
+ auto line_sf
+ = string_fragment::from_str(al.get_string());
+ auto cursor_sf = line_sf.sub_cell_range(low_x, high_x);
+ if (me.me_x <= 1) {
+ this->set_left(this->lv_left - 1);
+ } else if (me.me_x >= width - 1) {
+ this->set_left(this->lv_left + 1);
+ }
+ if (!cursor_sf.empty()) {
+ this->tc_selected_text = {
+ me.me_x,
+ mc.mc_line,
+ line_range{
+ cursor_sf.sf_begin,
+ cursor_sf.sf_end,
+ },
+ cursor_sf.to_string(),
+ };
+ }
+ }
+ }
} else {
- if (!this->tc_selection_cleared) {
- if (this->tc_sub_source != nullptr) {
- this->tc_sub_source->text_clear_marks(&BM_USER);
+ if (this->tc_press_line.is<main_content>()) {
+ if (me.me_y < 0) {
+ this->shift_selection(
+ listview_curses::shift_amount_t::up_line);
+ } else if (me.me_y >= height) {
+ this->shift_selection(
+ listview_curses::shift_amount_t::down_line);
+ } else if (mouse_line.is<main_content>()) {
+ this->set_selection_without_context(
+ mouse_line.get<main_content>().mc_line);
+ }
+ } else if (this->tc_press_line.is<overlay_content>()
+ && overlay_content_min_y && overlay_content_max_y)
+ {
+ if (me.me_y < overlay_content_min_y.value()) {
+ this->set_overlay_selection(
+ this->get_overlay_selection().value_or(0_vl)
+ - 1_vl);
+ } else if (me.me_y >= overlay_content_max_y.value()) {
+ this->set_overlay_selection(
+ this->get_overlay_selection().value_or(0_vl)
+ + 1_vl);
+ } else if (mouse_line.is<overlay_content>()) {
+ this->set_overlay_selection(
+ mouse_line.get<overlay_content>().oc_line);
}
- this->tc_bookmarks[&BM_USER].clear();
-
- this->tc_selection_cleared = true;
}
- this->toggle_user_mark(
- &BM_USER, this->tc_selection_start, mouse_line);
- this->tc_selection_last = mouse_line;
}
- this->reload_data();
break;
- case mouse_button_state_t::BUTTON_STATE_RELEASED:
- this->tc_selection_start = -1_vl;
- this->tc_selection_last = -1_vl;
- this->tc_selection_cleared = false;
+ }
+ case mouse_button_state_t::BUTTON_STATE_RELEASED: {
+ auto* ov = this->get_overlay_source();
+ if (ov != nullptr && mouse_line.is<listview_curses::overlay_menu>()
+ && this->tc_selected_text)
+ {
+ auto* tom = dynamic_cast<text_overlay_menu*>(ov);
+ if (tom != nullptr) {
+ auto& om = mouse_line.get<listview_curses::overlay_menu>();
+ auto& sti = this->tc_selected_text.value();
+
+ for (const auto& mi : tom->tom_menu_items) {
+ if (om.om_line == mi.mi_line
+ && me.is_click_in(mouse_button_t::BUTTON_LEFT,
+ mi.mi_range))
+ {
+ mi.mi_action(sti.sti_value);
+ break;
+ }
+ }
+ }
+ }
+ this->tc_text_selection_active = false;
+ if (me.is_click_in(mouse_button_t::BUTTON_RIGHT, 0, INT_MAX)) {
+ auto* lov = this->get_overlay_source();
+ if (lov != nullptr) {
+ lov->set_show_details_in_overlay(
+ !lov->get_show_details_in_overlay());
+ }
+ }
+ if (this->vc_enabled) {
+ if (this->tc_selection_start) {
+ this->toggle_user_mark(&BM_USER,
+ this->tc_selection_start.value(),
+ this->get_selection());
+ this->reload_data();
+ }
+ this->tc_selection_start = nonstd::nullopt;
+ }
+ if (this->tc_delegate != nullptr) {
+ this->tc_delegate->text_handle_mouse(*this, mouse_line, me);
+ }
+ if (sub_delegate != nullptr) {
+ sub_delegate->text_handle_mouse(*this, mouse_line, me);
+ }
+ if (mouse_line.is<overlay_menu>()) {
+ this->tc_selected_text = nonstd::nullopt;
+ this->set_needs_update();
+ }
break;
+ }
}
return true;
@@ -441,6 +717,10 @@ textview_curses::textview_value_for_row(vis_line_t row, attr_line_t& value_out)
this->tc_sub_source->text_value_for_line(*this, row, str);
this->tc_sub_source->text_attrs_for_line(*this, row, sa);
+ for (const auto& attr : sa) {
+ require_ge(attr.sa_range.lr_start, 0);
+ }
+
scrub_ansi_string(str, &sa);
struct line_range body, orig_line;
@@ -461,11 +741,28 @@ textview_curses::textview_value_for_row(vis_line_t row, attr_line_t& value_out)
format_name = format_attr_opt.value().get();
}
- if (this->is_selectable() && row == this->get_selection()
- && this->tc_cursor_role)
+ if (this->is_selectable() && this->tc_cursor_role
+ && this->tc_disabled_cursor_role)
{
- sa.emplace_back(line_range{orig_line.lr_start, -1},
- VC_ROLE.value(this->tc_cursor_role.value()));
+ vis_line_t sel_start, sel_end;
+
+ sel_start = sel_end = this->get_selection();
+ if (this->tc_selection_start) {
+ if (this->tc_selection_start.value() < sel_end) {
+ sel_start = this->tc_selection_start.value();
+ } else {
+ sel_end = this->tc_selection_start.value();
+ }
+ }
+
+ if (sel_start <= row && row <= sel_end) {
+ auto role = this->get_overlay_selection()
+ ? this->tc_disabled_cursor_role.value()
+ : this->tc_cursor_role.value();
+
+ sa.emplace_back(line_range{orig_line.lr_start, -1},
+ VC_ROLE.value(role));
+ }
}
for (auto& tc_highlight : this->tc_highlights) {
@@ -502,65 +799,23 @@ textview_curses::textview_value_for_row(vis_line_t row, attr_line_t& value_out)
value_out.apply_hide();
}
-#if 0
- typedef std::map<std::string, role_t> key_map_t;
- static key_map_t key_roles;
-
- data_scanner ds(str);
- data_parser dp(&ds);
-
- dp.parse();
-
- for (list<data_parser::element>::iterator iter = dp.dp_stack.begin();
- iter != dp.dp_stack.end();
- ++iter) {
- view_colors &vc = view_colors::singleton();
-
- if (iter->e_token == DNT_PAIR) {
- list<data_parser::element>::iterator pair_iter;
- key_map_t::iterator km_iter;
- data_token_t value_token;
- struct line_range lr;
- string key;
-
- value_token =
- iter->e_sub_elements->back().e_sub_elements->front().e_token;
- if (value_token == DT_STRING) {
- continue;
- }
-
- lr.lr_start = iter->e_capture.c_begin;
- lr.lr_end = iter->e_capture.c_end;
-
- key = ds.get_input().get_substr(
- &iter->e_sub_elements->front().e_capture);
- if ((km_iter = key_roles.find(key)) == key_roles.end()) {
- key_roles[key] = vc.next_highlight();
- }
- /* fprintf(stderr, "key = %s\n", key.c_str()); */
- sa[lr].insert(make_string_attr("style",
- vc.attrs_for_role(key_roles[key])));
-
- pair_iter = iter->e_sub_elements->begin();
- ++pair_iter;
-
- lr.lr_start = pair_iter->e_capture.c_begin;
- lr.lr_end = pair_iter->e_capture.c_end;
- sa[lr].insert(make_string_attr("style",
- COLOR_PAIR(view_colors::VC_WHITE) |
- A_BOLD));
- }
- }
-#endif
-
const auto& user_marks = this->tc_bookmarks[&BM_USER];
const auto& user_expr_marks = this->tc_bookmarks[&BM_USER_EXPR];
- if (binary_search(user_marks.begin(), user_marks.end(), row)
- || binary_search(user_expr_marks.begin(), user_expr_marks.end(), row))
+ if (std::binary_search(user_marks.begin(), user_marks.end(), row)
+ || std::binary_search(
+ user_expr_marks.begin(), user_expr_marks.end(), row))
{
sa.emplace_back(line_range{orig_line.lr_start, -1},
VC_STYLE.value(text_attrs{A_REVERSE}));
}
+
+ if (this->tc_selected_text) {
+ const auto& sti = this->tc_selected_text.value();
+ if (sti.sti_line == row) {
+ sa.emplace_back(sti.sti_range,
+ VC_ROLE.value(role_t::VCR_SELECTED_TEXT));
+ }
+ }
}
void
@@ -822,11 +1077,21 @@ textview_curses::grep_value_for_line(vis_line_t line, std::string& value_out)
}
void
-text_time_translator::scroll_invoked(textview_curses* tc)
+text_sub_source::scroll_invoked(textview_curses* tc)
{
- if (tc->get_inner_height() > 0) {
+ auto* ttt = dynamic_cast<text_time_translator*>(this);
+
+ if (ttt != nullptr) {
+ ttt->ttt_scroll_invoked(tc);
+ }
+}
+
+void
+text_time_translator::ttt_scroll_invoked(textview_curses* tc)
+{
+ if (tc->get_inner_height() > 0 && tc->get_selection() >= 0_vl) {
this->time_for_row(tc->get_selection()) |
- [this](auto new_top_time) { this->ttt_top_time = new_top_time; };
+ [this](auto new_top_ri) { this->ttt_top_row_info = new_top_ri; };
}
}
@@ -834,34 +1099,19 @@ void
text_time_translator::data_reloaded(textview_curses* tc)
{
if (tc->get_inner_height() == 0) {
+ this->ttt_top_row_info = nonstd::nullopt;
return;
}
- if (tc->get_selection() > tc->get_inner_height()) {
- if (this->ttt_top_time.tv_sec != 0) {
- this->row_for_time(this->ttt_top_time) |
- [tc](auto new_top) { tc->set_selection(new_top); };
- }
- return;
+ if (this->ttt_top_row_info) {
+ this->row_for(this->ttt_top_row_info.value()) |
+ [tc](auto new_top) { tc->set_selection(new_top); };
}
- this->time_for_row(tc->get_selection()) | [this, tc](auto top_time) {
- if (top_time != this->ttt_top_time) {
- if (this->ttt_top_time.tv_sec != 0) {
- this->row_for_time(this->ttt_top_time) |
- [tc](auto new_top) { tc->set_selection(new_top); };
- }
- this->time_for_row(tc->get_selection()) |
- [this](auto new_top_time) {
- this->ttt_top_time = new_top_time;
- };
- }
- };
}
template class bookmark_vector<vis_line_t>;
bool
-empty_filter::matches(const logfile& lf,
- logfile::const_iterator ll,
+empty_filter::matches(nonstd::optional<line_source> ls,
const shared_buffer_ref& line)
{
return false;