mirror of
https://github.com/tstack/lnav.git
synced 2024-08-16 16:30:25 +03:00
[mouse] tweak the docs a bit
This commit is contained in:
parent
96765e3abc
commit
3bb21b25a2
4
NEWS.md
4
NEWS.md
@ -51,6 +51,10 @@ Interface changes:
|
||||
running:
|
||||
|
||||
`:config /ui/movement/mode top`
|
||||
* In the parser details panel (opened by pressing `p`), you
|
||||
can now hide/show fields by moving the cursor line to the
|
||||
given field and pressing the space bar or by clicking on
|
||||
the diamond with the mouse.
|
||||
|
||||
Bug Fixes:
|
||||
* With the recent xz backdoor shenanigans, it seems like a good
|
||||
|
@ -139,41 +139,7 @@ and can be set as the default by executing the following command:
|
||||
|
||||
:config /ui/mouse/mode enabled
|
||||
|
||||
With mouse support enabled, many of the UI elements will respond to
|
||||
mouse inputs:
|
||||
|
||||
* clicking on the main view will move the cursor to the given
|
||||
row and dragging will scroll the view as needed;
|
||||
* shift + clicking/dragging in the main view will highlight
|
||||
lines and then toggle their bookmark status on release;
|
||||
* double-clicking will select the underlying token and
|
||||
drag-selecting within a line will select the given text;
|
||||
* with selected text, pressing :kbd:`c` will copy the text to
|
||||
the clipboard and it will be used as the suggestion for
|
||||
searching/filtering;
|
||||
* clicking in the scroll area will move the view by a page and
|
||||
dragging the scrollbar will move the view to the given spot;
|
||||
* clicking on the breadcrumb bar will select a crumb and
|
||||
selecting a possibility from the popup will move to that
|
||||
location in the view;
|
||||
* clicking on portions of the bottom status bar will trigger
|
||||
a relevant action (e.g. clicking the line number will open
|
||||
the command prompt with `:goto <current-line>`);
|
||||
* clicking on the configuration panel tabs (i.e. Files/Filters)
|
||||
will open the selected panel and clicking parts of the
|
||||
display in there will perform the relevant action (e.g.
|
||||
clicking the diamond will enable/disable the file/filter);
|
||||
* clicking in a prompt will move the cursor to the location.
|
||||
|
||||
.. note::
|
||||
|
||||
A downside of enabling mouse support is that normal text
|
||||
selection and copy will no longer work. You can press
|
||||
:kbd:`F2` to quickly switch back-and-forth. Or, some
|
||||
terminals have support for switching using a modifier
|
||||
key, like `iTerm <https://iterm2.com/documentation-preferences-profiles-terminal.html>_`
|
||||
where pressing :kbd:`Option` will allow you to select
|
||||
text and copy.
|
||||
See :ref:`ui_mouse` for more details.
|
||||
|
||||
Log Formats
|
||||
^^^^^^^^^^^
|
||||
|
@ -416,3 +416,48 @@ range of values. The panel at the bottom of the view shows the data points
|
||||
themselves from the original source, the log file or the SQL query results.
|
||||
You can press :kbd:`TAB` to focus on the details panel so you can scroll
|
||||
around and get a closer look at the values.
|
||||
|
||||
.. _ui_mouse:
|
||||
|
||||
Mouse Support (v0.12.2+)
|
||||
------------------------
|
||||
|
||||
With mouse support enabled, either through the `/ui/mouse/mode`
|
||||
configuration option or by pressing :kbd:`F2`, many of the UI
|
||||
elements will respond to mouse inputs:
|
||||
|
||||
* clicking on the main view will move the cursor to the given
|
||||
row and dragging will scroll the view as needed;
|
||||
* shift + clicking/dragging in the main view will highlight
|
||||
lines and then toggle their bookmark status on release;
|
||||
* double-clicking will select the underlying token and
|
||||
drag-selecting within a line will select the given text;
|
||||
* with selected text, pressing :kbd:`c` will copy the text to
|
||||
the clipboard and it will be used as the suggestion for
|
||||
searching/filtering;
|
||||
* clicking in the scroll area will move the view by a page and
|
||||
dragging the scrollbar will move the view to the given spot;
|
||||
* clicking on the breadcrumb bar will select a crumb and
|
||||
selecting a possibility from the popup will move to that
|
||||
location in the view;
|
||||
* clicking on portions of the bottom status bar will trigger
|
||||
a relevant action (e.g. clicking the line number will open
|
||||
the command prompt with `:goto <current-line>`);
|
||||
* clicking on the configuration panel tabs (i.e. Files/Filters)
|
||||
will open the selected panel and clicking parts of the
|
||||
display in there will perform the relevant action (e.g.
|
||||
clicking the diamond will enable/disable the file/filter);
|
||||
* clicking in a prompt will move the cursor to the location.
|
||||
|
||||
.. note::
|
||||
|
||||
A downside of enabling mouse support is that normal text
|
||||
selection and copy will no longer work. While lnav has
|
||||
some support for selection in the main view, there are
|
||||
still likely to be cases where that is insufficient.
|
||||
In those cases, you can press :kbd:`F2` to quickly
|
||||
switch back-and-forth. Or, some terminals have support
|
||||
for switching using a modifier key, like
|
||||
`iTerm <https://iterm2.com/documentation-preferences-profiles-terminal.html>_`
|
||||
where pressing :kbd:`Option` will allow you to select
|
||||
text and copy.
|
||||
|
@ -54,6 +54,7 @@ field_overlay_source::build_field_lines(const listview_curses& lv,
|
||||
auto& vc = view_colors::singleton();
|
||||
|
||||
this->fos_lines.clear();
|
||||
this->fos_row_to_field_name.clear();
|
||||
|
||||
if (lss.text_line_count() == 0) {
|
||||
this->fos_log_helper.clear();
|
||||
@ -292,7 +293,7 @@ field_overlay_source::build_field_lines(const listview_curses& lv,
|
||||
const log_format* last_format = nullptr;
|
||||
|
||||
for (const auto& lv : this->fos_log_helper.ldh_line_values.lvv_values) {
|
||||
auto& meta = lv.lv_meta;
|
||||
const auto& meta = lv.lv_meta;
|
||||
if (!meta.lvm_format) {
|
||||
continue;
|
||||
}
|
||||
@ -305,7 +306,7 @@ field_overlay_source::build_field_lines(const listview_curses& lv,
|
||||
auto* curr_elf = dynamic_cast<external_log_format*>(curr_format);
|
||||
const auto format_name = curr_format->get_name().to_string();
|
||||
attr_line_t al;
|
||||
std::string str, value_str = lv.to_string();
|
||||
std::string value_str = lv.to_string();
|
||||
|
||||
if (curr_format != last_format) {
|
||||
this->fos_lines.emplace_back(" Known message fields for table "
|
||||
@ -318,6 +319,8 @@ field_overlay_source::build_field_lines(const listview_curses& lv,
|
||||
}
|
||||
|
||||
std::string field_name, orig_field_name;
|
||||
line_range hl_range;
|
||||
al.append(" ").append("|", VC_GRAPHIC.value(ACS_LTEE)).append(" ");
|
||||
if (meta.lvm_struct_name.empty()) {
|
||||
if (curr_elf && curr_elf->elf_body_field == meta.lvm_name) {
|
||||
field_name = LOG_BODY;
|
||||
@ -332,31 +335,32 @@ field_overlay_source::build_field_lines(const listview_curses& lv,
|
||||
if (!this->fos_contexts.empty()) {
|
||||
field_name = this->fos_contexts.top().c_prefix + field_name;
|
||||
}
|
||||
str = " " + field_name;
|
||||
} else {
|
||||
str = lnav::sql::mprintf(" jget(%s, '/%q')",
|
||||
meta.lvm_struct_name.get(),
|
||||
meta.lvm_name.get());
|
||||
}
|
||||
str.append(this->fos_known_key_size - (str.length() - 3), ' ');
|
||||
if (meta.is_hidden()) {
|
||||
al.append("\u25c7"_comment);
|
||||
} else {
|
||||
al.append("\u25c6"_ok);
|
||||
}
|
||||
al.append(" ");
|
||||
auto prefix_len = al.utf8_length_or_length();
|
||||
hl_range.lr_start = al.get_string().length();
|
||||
al.append(field_name);
|
||||
hl_range.lr_end = al.get_string().length();
|
||||
al.pad_to(prefix_len + this->fos_known_key_size);
|
||||
|
||||
al.with_string(str);
|
||||
readline_sqlite_highlighter(al, 0);
|
||||
this->fos_row_to_field_name[this->fos_lines.size()] = meta.lvm_name;
|
||||
} else {
|
||||
auto jget_str = lnav::sql::mprintf("jget(%s, '/%q')",
|
||||
meta.lvm_struct_name.get(),
|
||||
meta.lvm_name.get());
|
||||
hl_range.lr_start = al.get_string().length();
|
||||
al.append(jget_str.in());
|
||||
hl_range.lr_end = al.get_string().length();
|
||||
}
|
||||
readline_sqlite_highlighter_int(al, -1, hl_range);
|
||||
|
||||
al.append(" = ").append(scrub_ws(value_str.c_str()));
|
||||
if (meta.lvm_struct_name.empty()) {
|
||||
auto prefix_len = field_name.length() - orig_field_name.length();
|
||||
al.with_attr(string_attr(
|
||||
line_range(3 + prefix_len, 3 + prefix_len + field_name.size()),
|
||||
VC_STYLE.value(vc.attrs_for_ident(orig_field_name))));
|
||||
} else {
|
||||
al.with_attr(string_attr(
|
||||
line_range(8, 8 + meta.lvm_struct_name.size()),
|
||||
VC_STYLE.value(vc.attrs_for_ident(meta.lvm_struct_name))));
|
||||
}
|
||||
|
||||
this->fos_lines.emplace_back(al);
|
||||
this->add_key_line_attrs(this->fos_known_key_size);
|
||||
|
||||
if (meta.lvm_kind == value_kind_t::VALUE_STRUCT) {
|
||||
json_string js = extract(value_str.c_str());
|
||||
@ -684,9 +688,11 @@ field_overlay_source::list_header_for_overlay(const listview_curses& lv,
|
||||
}
|
||||
|
||||
if (lv.get_overlay_selection()) {
|
||||
retval.append(" Press ")
|
||||
retval.append(" ")
|
||||
.append("SPC"_hotkey)
|
||||
.append(": hide/show field ")
|
||||
.append("Esc"_hotkey)
|
||||
.append(" to exit this panel.");
|
||||
.append(": exit this panel");
|
||||
} else {
|
||||
retval.append(" Press ")
|
||||
.append("CTRL-]"_hotkey)
|
||||
|
@ -102,6 +102,7 @@ public:
|
||||
std::vector<attr_line_t> fos_lines;
|
||||
vis_line_t fos_meta_lines_row{0_vl};
|
||||
std::vector<attr_line_t> fos_meta_lines;
|
||||
std::map<size_t, intern_string_t> fos_row_to_field_name;
|
||||
};
|
||||
|
||||
#endif // LNAV_FIELD_OVERLAY_SOURCE_H
|
||||
|
@ -42,6 +42,7 @@
|
||||
#include "bookmarks.json.hh"
|
||||
#include "command_executor.hh"
|
||||
#include "config.h"
|
||||
#include "field_overlay_source.hh"
|
||||
#include "k_merge_tree.h"
|
||||
#include "lnav_util.hh"
|
||||
#include "log_accel.hh"
|
||||
@ -1382,6 +1383,30 @@ bool
|
||||
logfile_sub_source::list_input_handle_key(listview_curses& lv, int ch)
|
||||
{
|
||||
switch (ch) {
|
||||
case ' ': {
|
||||
auto ov_vl = lv.get_overlay_selection();
|
||||
if (ov_vl) {
|
||||
auto* fos = dynamic_cast<field_overlay_source*>(
|
||||
lv.get_overlay_source());
|
||||
auto iter = fos->fos_row_to_field_name.find(ov_vl.value());
|
||||
if (iter != fos->fos_row_to_field_name.end()) {
|
||||
auto find_res = this->find_line_with_file(lv.get_top());
|
||||
if (find_res) {
|
||||
auto file_and_line = find_res.value();
|
||||
auto* format = file_and_line.first->get_format_ptr();
|
||||
auto fstates = format->get_field_states();
|
||||
auto state_iter = fstates.find(iter->second);
|
||||
if (state_iter != fstates.end()) {
|
||||
format->hide_field(iter->second,
|
||||
!state_iter->second.is_hidden());
|
||||
lv.set_needs_update();
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
case 'h':
|
||||
case 'H':
|
||||
case KEY_SLEFT:
|
||||
@ -2995,3 +3020,14 @@ logfile_sub_source::get_anchors()
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
bool
|
||||
logfile_sub_source::text_handle_mouse(textview_curses& tc, mouse_event& me)
|
||||
{
|
||||
if (tc.get_overlay_selection()
|
||||
&& me.is_click_in(mouse_button_t::BUTTON_LEFT, 2, 4))
|
||||
{
|
||||
this->list_input_handle_key(tc, ' ');
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -201,7 +201,8 @@ class logfile_sub_source
|
||||
, public text_time_translator
|
||||
, public text_accel_source
|
||||
, public list_input_delegate
|
||||
, public text_anchors {
|
||||
, public text_anchors
|
||||
, public text_delegate {
|
||||
public:
|
||||
const static bookmark_type_t BM_ERRORS;
|
||||
const static bookmark_type_t BM_WARNINGS;
|
||||
@ -688,6 +689,8 @@ public:
|
||||
|
||||
void text_crumbs_for_line(int line, std::vector<breadcrumb::crumb>& crumbs);
|
||||
|
||||
bool text_handle_mouse(textview_curses& tc, mouse_event& me);
|
||||
|
||||
Result<bool, lnav::console::user_message> eval_sql_filter(
|
||||
sqlite3_stmt* stmt, iterator ld, logfile::const_iterator ll);
|
||||
|
||||
|
@ -41,10 +41,6 @@
|
||||
#include "sql_util.hh"
|
||||
#include "view_curses.hh"
|
||||
|
||||
static void readline_sqlite_highlighter_int(attr_line_t& al,
|
||||
int x,
|
||||
line_range sub);
|
||||
|
||||
static bool
|
||||
is_bracket(const std::string& str, int index, bool is_lit)
|
||||
{
|
||||
@ -237,7 +233,7 @@ readline_command_highlighter(attr_line_t& al, int x)
|
||||
al, x, line_range{0, (int) al.get_string().length()});
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
readline_sqlite_highlighter_int(attr_line_t& al, int x, line_range sub)
|
||||
{
|
||||
static const char* brackets[] = {
|
||||
|
@ -38,6 +38,7 @@ void readline_regex_highlighter(attr_line_t& line, int x);
|
||||
|
||||
void readline_command_highlighter(attr_line_t& line, int x);
|
||||
|
||||
void readline_sqlite_highlighter_int(attr_line_t& line, int x, line_range sub);
|
||||
void readline_sqlite_highlighter(attr_line_t& line, int x);
|
||||
|
||||
void readline_shlex_highlighter_int(attr_line_t& al, int x, line_range sub);
|
||||
|
@ -462,8 +462,8 @@ textview_curses::handle_mouse(mouse_event& me)
|
||||
[](const static_overlay_content& soc) {
|
||||
|
||||
},
|
||||
[](const overlay_content& oc) {
|
||||
|
||||
[this](const overlay_content& oc) {
|
||||
this->set_overlay_selection(oc.oc_line);
|
||||
},
|
||||
[](const empty_space& es) {});
|
||||
break;
|
||||
|
@ -1,11 +1,11 @@
|
||||
2023-03-24T14:26:16.243Z renovate[7] INFO Dependency extraction complete
|
||||
Received Time: [1m2023-03-24T14:26:16.243[0m — [1min the future[0m Format: [1m%Y-%m-%dT%H:%M:%S.%L%z[0m
|
||||
Known message fields for table [1mbunyan_log[0m:
|
||||
name = [1mrenovate[0m
|
||||
hostname = [1mrenovate-gitlab-67c4bcb5-9ggbv[0m
|
||||
pid = [1m7[0m
|
||||
level = [1m30[0m
|
||||
v = [1m0[0m
|
||||
| [1m[32m◆[0m name = renovate
|
||||
| [32m◇[0m hostname = renovate-gitlab-67c4bcb5-9ggbv
|
||||
| [1m[32m◆[0m pid = 7
|
||||
| [32m◇[0m level = 30
|
||||
| [32m◇[0m v = 0
|
||||
JSON fields:
|
||||
[1mjget[0m(log_raw_text, [35m'/baseBranch'[0m) = [1mmain[0m
|
||||
[1mjget[0m(log_raw_text, [35m'/logContext'[0m) = [1mqjifsaDDI[0m
|
||||
|
@ -2,9 +2,9 @@
|
||||
Received Time: [1m2020-12-10T06:56:41.092[0m — [1min the future[0m Format: [1m%Y-%m-%d %H:%M:%S,%L[0m
|
||||
Pattern: /xml_msg_log/regex/std = [1m[36m^[0m\[[1m[32m([0m[1m[32m?[0m[1m[36m<[0mtimestamp>[1m\d[0m[1m[32m{[0m4[1m[32m}[0m-[1m\d[0m[1m[32m{[0m2[1m[32m}[0m-[1m\d[0m[1m[32m{[0m2[1m[32m}[0m [1m\d[0m[1m[32m{[0m2[1m[32m}[0m:[1m\d[0m[1m[32m{[0m2[1m[32m}[0m:[1m\d[0m[1m[32m{[0m2[1m[32m}[0m,[1m\d[0m[1m[32m{[0m3[1m[32m}[0m[1m[32m)[0m\][1m\s[0m[1m[36m+[0m[1m[32m([0m[1m[32m?[0m[1m[36m<[0mlevel>[1m\w[0m[1m[36m+[0m[1m[32m)[0m[1m\s[0m[1m[36m+[0m\[[1m[32m([0m[1m[32m?[0m[1m[36m<[0mmodule>[1m[32m[[0m[1m[36m^[0m:[1m[32m][0m[1m[36m*[0m[1m[32m)[0m:[1m[32m([0m[1m[32m?[0m[1m[36m<[0mline>[1m\d[0m[1m[36m+[0m[1m[32m)[0m\][1m\s[0m[1m[36m*[0m[1m[32m([0m[1m[32m?[0m[1m[36m<[0mbody>[1m[32m[[0m[1m[36m^[0m\n[1m[32m][0m[1m[36m*[0m[1m[32m)[0m\n[1m[36m?[0m[1m[32m([0m[1m[32m?[0m[1m[36m<[0mmsg_data>[1m[36m.[0m[1m[36m*[0m[1m[32m)[0m
|
||||
Known message fields for table [1mxml_msg_log[0m:
|
||||
module = [1mconnect.client[0m
|
||||
line = [1m69[0m
|
||||
msg_data = [1m<?xml version='1.0' encoding='iso-8859-2'?>␊<a-request>␊ <head>␊ x␊ </head>␊ <source>␊ x␊ </source>␊ <request id="1">␊ <name>␊ x␊ </name>␊ </request>␊</a-request>␊[0m
|
||||
| [1m[32m◆[0m module = connect.client
|
||||
| [1m[32m◆[0m line = 69
|
||||
| [1m[32m◆[0m msg_data = <?xml version='1.0' encoding='iso-8859-2'?>␊<a-request>␊ <head>␊ x␊ </head>␊ <source>␊ x␊ </source>␊ <request id="1">␊ <name>␊ x␊ </name>␊ </request>␊</a-request>␊
|
||||
XML fields:
|
||||
[1mxpath[0m([35m'/a-request/head/text()'[0m, xml_msg_log.msg_data) = [1mx[0m
|
||||
[1mxpath[0m([35m'/a-request/request/@id'[0m, xml_msg_log.msg_data) = [1m1[0m
|
||||
|
Loading…
Reference in New Issue
Block a user