|
36 | 36 | #include "base/attr_line.builder.hh" |
37 | 37 | #include "base/auto_mem.hh" |
38 | 38 | #include "base/func_util.hh" |
| 39 | +#include "base/itertools.hh" |
39 | 40 | #include "base/opt_util.hh" |
40 | 41 | #include "base/relative_time.hh" |
41 | 42 | #include "base/text_format_enum.hh" |
42 | 43 | #include "cmd.parser.hh" |
43 | 44 | #include "config.h" |
| 45 | +#include "itertools.similar.hh" |
44 | 46 | #include "lnav.hh" |
45 | 47 | #include "lnav.prompt.hh" |
46 | 48 | #include "readline_highlighters.hh" |
@@ -158,6 +160,25 @@ filter_sub_source::list_input_handle_key(listview_curses& lv, const ncinput& ch) |
158 | 160 | } |
159 | 161 | return true; |
160 | 162 | } |
| 163 | + case 'l': { |
| 164 | + auto* top_view = *lnav_data.ld_view_stack.top(); |
| 165 | + auto* tss = top_view->get_sub_source(); |
| 166 | + if (tss->get_min_log_level() == LEVEL_UNKNOWN) { |
| 167 | + tss->set_min_log_level(LEVEL_TRACE); |
| 168 | + } |
| 169 | + const auto& [index, row] |
| 170 | + = this->find_row<level_filter_row>(top_view); |
| 171 | + lv.set_selection(index); |
| 172 | + lv.reload_data(); |
| 173 | + this->fss_editing = true; |
| 174 | + this->tss_view->set_enabled(false); |
| 175 | + row->prime_text_input(top_view, *this->fss_editor, *this); |
| 176 | + this->fss_editor->set_y(lv.get_y_for_selection()); |
| 177 | + this->fss_editor->set_visible(true); |
| 178 | + this->fss_editor->focus(); |
| 179 | + this->tss_view->reload_data(); |
| 180 | + return true; |
| 181 | + } |
161 | 182 | case 'm': { |
162 | 183 | auto* top_view = *lnav_data.ld_view_stack.top(); |
163 | 184 | auto* ttt = dynamic_cast<text_time_translator*>( |
@@ -186,11 +207,10 @@ filter_sub_source::list_input_handle_key(listview_curses& lv, const ncinput& ch) |
186 | 207 | ttt->ttt_preview_min_time = this->fss_min_time; |
187 | 208 | } |
188 | 209 |
|
189 | | - lv.set_selection(0_vl); |
| 210 | + const auto& [index, row] |
| 211 | + = this->find_row<min_time_filter_row>(top_view); |
| 212 | + lv.set_selection(index); |
190 | 213 | lv.reload_data(); |
191 | | - |
192 | | - auto rows = this->rows_for(top_view); |
193 | | - auto& row = rows[0]; |
194 | 214 | this->fss_editing = true; |
195 | 215 | this->tss_view->set_enabled(false); |
196 | 216 | row->prime_text_input(top_view, *this->fss_editor, *this); |
@@ -230,12 +250,10 @@ filter_sub_source::list_input_handle_key(listview_curses& lv, const ncinput& ch) |
230 | 250 | ttt->ttt_preview_max_time = this->fss_max_time; |
231 | 251 | } |
232 | 252 |
|
233 | | - auto new_sel = ttt->get_min_row_time() ? 1_vl : 0_vl; |
234 | | - lv.set_selection(new_sel); |
| 253 | + const auto& [index, row] |
| 254 | + = this->find_row<level_filter_row>(top_view); |
| 255 | + lv.set_selection(index); |
235 | 256 | lv.reload_data(); |
236 | | - |
237 | | - auto rows = this->rows_for(top_view); |
238 | | - auto& row = rows[new_sel]; |
239 | 257 | this->fss_editing = true; |
240 | 258 | this->tss_view->set_enabled(false); |
241 | 259 | row->prime_text_input(top_view, *this->fss_editor, *this); |
@@ -670,6 +688,103 @@ filter_sub_source::min_time_filter_row::ti_abort(textview_curses* top_view, |
670 | 688 | tss->text_filters_changed(); |
671 | 689 | } |
672 | 690 |
|
| 691 | +void |
| 692 | +filter_sub_source::level_filter_row::value_for(const render_state& rs, |
| 693 | + attr_line_t& al) |
| 694 | +{ |
| 695 | + auto lev = rs.rs_top_view->get_sub_source()->get_min_log_level(); |
| 696 | + |
| 697 | + al.append(" ").append("Level"_table_header).append(" "); |
| 698 | + if (rs.rs_editing) { |
| 699 | + al.append(fmt::format(FMT_STRING("{:>9}"), "-"), |
| 700 | + VC_ROLE.value(role_t::VCR_NUMBER)); |
| 701 | + } else { |
| 702 | + al.append( |
| 703 | + fmt::format( |
| 704 | + FMT_STRING("{:>9}"), |
| 705 | + rs.rs_top_view->get_sub_source()->tss_level_filtered_count), |
| 706 | + VC_ROLE.value(role_t::VCR_NUMBER)); |
| 707 | + } |
| 708 | + al.append(" hits ") |
| 709 | + .append("|", VC_GRAPHIC.value(NCACS_VLINE)) |
| 710 | + .append(" ") |
| 711 | + .append(level_names[lev]); |
| 712 | +} |
| 713 | + |
| 714 | +bool |
| 715 | +filter_sub_source::level_filter_row::handle_key(textview_curses* top_view, |
| 716 | + const ncinput& ch) |
| 717 | +{ |
| 718 | + switch (ch.eff_text[0]) { |
| 719 | + case 'D': |
| 720 | + top_view->get_sub_source()->set_min_log_level(LEVEL_UNKNOWN); |
| 721 | + return true; |
| 722 | + } |
| 723 | + return false; |
| 724 | +} |
| 725 | + |
| 726 | +bool |
| 727 | +filter_sub_source::level_filter_row::prime_text_input(textview_curses* top_view, |
| 728 | + textinput_curses& ti, |
| 729 | + filter_sub_source& parent) |
| 730 | +{ |
| 731 | + auto* tss = top_view->get_sub_source(); |
| 732 | + auto lev = tss->get_min_log_level(); |
| 733 | + parent.fss_curr_level = lev; |
| 734 | + tss->set_min_log_level(LEVEL_TRACE); |
| 735 | + tss->text_filters_changed(); |
| 736 | + ti.set_content(level_names[lev].to_string()); |
| 737 | + ti.tc_selection |
| 738 | + = ti.clamp_selection(textinput_curses::selected_range::from_mouse( |
| 739 | + textinput_curses::input_point::home(), |
| 740 | + textinput_curses::input_point::end())); |
| 741 | + return true; |
| 742 | +} |
| 743 | + |
| 744 | +void |
| 745 | +filter_sub_source::level_filter_row::ti_change(textview_curses* top_view, |
| 746 | + textinput_curses& rc) |
| 747 | +{ |
| 748 | + auto lev = rc.get_content(); |
| 749 | + top_view->get_sub_source()->tss_preview_min_log_level |
| 750 | + = string2level(lev.c_str(), lev.size(), false); |
| 751 | + this->ti_completion_request( |
| 752 | + top_view, rc, completion_request_type_t::partial); |
| 753 | +} |
| 754 | + |
| 755 | +void |
| 756 | +filter_sub_source::level_filter_row::ti_completion_request( |
| 757 | + textview_curses* top_view, |
| 758 | + textinput_curses& tc, |
| 759 | + completion_request_type_t crt) |
| 760 | +{ |
| 761 | + auto lev = tc.get_content(); |
| 762 | + auto poss = level_names | lnav::itertools::similar_to(lev) |
| 763 | + | lnav::itertools::map([](const auto& elem) { |
| 764 | + return attr_line_t().append(elem).with_attr_for_all( |
| 765 | + lnav::prompt::SUBST_TEXT.value(elem.to_string())); |
| 766 | + }); |
| 767 | + tc.open_popup_for_completion(0, poss); |
| 768 | +} |
| 769 | + |
| 770 | +void |
| 771 | +filter_sub_source::level_filter_row::ti_perform(textview_curses* top_view, |
| 772 | + textinput_curses& tc, |
| 773 | + filter_sub_source& parent) |
| 774 | +{ |
| 775 | + auto lev = tc.get_content(); |
| 776 | + auto new_level = string2level(lev.c_str(), lev.size(), false); |
| 777 | + top_view->get_sub_source()->set_min_log_level(new_level); |
| 778 | +} |
| 779 | + |
| 780 | +void |
| 781 | +filter_sub_source::level_filter_row::ti_abort(textview_curses* top_view, |
| 782 | + textinput_curses& tc, |
| 783 | + filter_sub_source& parent) |
| 784 | +{ |
| 785 | + top_view->get_sub_source()->set_min_log_level(parent.fss_curr_level); |
| 786 | +} |
| 787 | + |
673 | 788 | bool |
674 | 789 | filter_sub_source::time_filter_row::prime_text_input(textview_curses* top_view, |
675 | 790 | textinput_curses& ti, |
@@ -1227,6 +1342,10 @@ filter_sub_source::rows_for(textview_curses* tc) const |
1227 | 1342 | } |
1228 | 1343 | } |
1229 | 1344 |
|
| 1345 | + if (tss->get_min_log_level() != LEVEL_UNKNOWN) { |
| 1346 | + retval.emplace_back(std::make_unique<level_filter_row>()); |
| 1347 | + } |
| 1348 | + |
1230 | 1349 | auto& fs = tss->get_filters(); |
1231 | 1350 | for (auto& tf : fs) { |
1232 | 1351 | retval.emplace_back(std::make_unique<text_filter_row>(tf)); |
|
0 commit comments