Skip to content

Commit 70bfcef

Browse files
committed
[breakpoints] mouse stuff
1 parent 063e407 commit 70bfcef

13 files changed

Lines changed: 119 additions & 56 deletions

NEWS.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,10 +105,14 @@ Features:
105105
- If the log format specifies source file/line fields
106106
and a breakpoint is set, a red bullet point will be
107107
inserted to signify the presence of a breakpoint.
108+
Left-clicking on the bullet will toggle enabling/
109+
disabling the breakpoint. A right-click will
110+
delete the breakpoint.
108111
In addition, if the `:add-source-path` command has
109112
been used, the first character of the source file
110-
will be underlined and can be clicked to open the
111-
source file at the given log message.
113+
will be underlined and can be left-clicked to open
114+
the source file at the given log message. A
115+
right-click will set a breakpoint.
112116
* The `all_opids` and `all_thread_ids` virtual tables
113117
have been added to make it simple to discover all of
114118
the operations and threads across all log files. The

docs/source/ui.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,7 @@ message. Inside the overlay, the following hotkeys are supported:
294294
link in a log message comment, or compared to the :code:`log_line_link`
295295
link in log tables.
296296

297-
The source file name for each message can be displayed by scrolling left.
297+
The log file name for each message can be displayed by scrolling left.
298298
Scrolling left once will show the shortened version of the file name relative
299299
to the other files that are loaded. In the shortened version, the unique
300300
portion of the file name will be in square brackets. Scrolling left a second

src/init.sql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ END;
109109

110110
CREATE VIEW lnav_db.lnav_focused_msg AS
111111
SELECT *,
112+
log_msg_schema,
112113
log_part,
113114
log_actual_time,
114115
log_idle_msecs,

src/lnav.cc

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1581,21 +1581,26 @@ VALUES ('org.lnav.mouse-support', -1, DATETIME('now', '+1 minute'),
15811581
auto click_handler = [](textview_curses& tc,
15821582
const attr_line_t& al,
15831583
int x,
1584-
const mouse_event& me) {
1584+
const mouse_event& me) -> bool {
15851585
if (tc.tc_selected_text) {
1586-
return;
1586+
return false;
15871587
}
15881588
static auto& prompt = lnav::prompt::get();
15891589
static auto& ec = lnav_data.ld_exec_context;
15901590
auto cmd_iter
15911591
= find_string_attr_containing(al.get_attrs(), &VC_COMMAND, x);
15921592
if (cmd_iter != al.al_attrs.end()) {
15931593
auto cmd = cmd_iter->sa_value.get<ui_command>();
1594-
auto exec_res = ec.execute(cmd.uc_location, cmd.uc_command);
1594+
auto mouse_button_sf = to_string_fragment(me.me_button);
1595+
auto exec_res = ec.execute_with(
1596+
cmd.uc_location,
1597+
cmd.uc_command,
1598+
std::make_pair("mouse_button", mouse_button_sf.to_string()));
15951599
if (exec_res.isOk()) {
15961600
auto val = exec_res.unwrap();
15971601
prompt.p_editor.set_inactive_value(val);
15981602
}
1603+
return true;
15991604
}
16001605
auto link_iter
16011606
= find_string_attr_containing(al.get_attrs(), &VC_HYPERLINK, x);
@@ -1606,7 +1611,9 @@ VALUES ('org.lnav.mouse-support', -1, DATETIME('now', '+1 minute'),
16061611
":xopen $href",
16071612
std::make_pair("href", href));
16081613
}
1614+
return true;
16091615
}
1616+
return false;
16101617
};
16111618
for (auto& ld_view : lnav_data.ld_views) {
16121619
ld_view.set_window(lnav_data.ld_window);

src/logfile_sub_source.cc

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -339,18 +339,14 @@ logfile_sub_source::text_value_for_line(textview_curses& tc,
339339
= find_string_attr(this->lss_token_al.al_attrs, &SA_SRC_FILE);
340340
if (src_file_attr != this->lss_token_al.al_attrs.end()) {
341341
auto src_file_sf = this->lss_token_al.to_string_fragment(src_file_attr);
342-
log_debug("src_file %d:%d %s",
343-
src_file_attr->sa_range.lr_start,
344-
src_file_attr->sa_range.lr_end,
345-
src_file_sf.to_string().c_str());
346342
auto lr = src_file_attr->sa_range;
347343
lr.lr_end = lr.lr_start + 1;
348344
auto break_ta = text_attrs::with_underline();
349345
this->lss_token_al.with_attr({lr, VC_STYLE.value(break_ta)})
350346
.with_attr({lr,
351347
VC_COMMAND.value(ui_command{
352348
source_location{},
353-
"|lnav-open-source",
349+
"|lnav-src-loc-handler $mouse_button",
354350
})});
355351
if (!this->lss_breakpoints.empty()) {
356352
auto src_line_attr
@@ -370,9 +366,15 @@ logfile_sub_source::text_value_for_line(textview_curses& tc,
370366
lr.lr_end = lr.lr_start;
371367
this->lss_token_al.insert(
372368
lr.lr_start,
373-
it->second.bp_enabled
374-
? ui_icon_t::breakpoint
375-
: ui_icon_t::disabled_breakpoint);
369+
it->second.bp_enabled ? ui_icon_t::breakpoint
370+
: ui_icon_t::disabled_breakpoint);
371+
lr.lr_end += 2;
372+
this->lss_token_al.with_attr(
373+
{lr,
374+
VC_COMMAND.value(ui_command{
375+
source_location{},
376+
"|lnav-breakpoint-handler $mouse_button",
377+
})});
376378
this->lss_token_values.shift_origins_by(lr, 2);
377379
}
378380
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#
2+
# @synopsis: lnav-breakpoint-handler
3+
# @description: Handle a mouse button click on a breakpoint bullet.
4+
#
5+
6+
;SELECT $1 as mouse_button
7+
;SELECT CASE $mouse_button
8+
WHEN 'left' THEN ';UPDATE lnav_log_breakpoints SET enabled = NOT enabled WHERE schema_id = (SELECT log_msg_schema FROM lnav_focused_msg)'
9+
WHEN 'right' THEN ':toggle-breakpoint'
10+
ELSE ':echo ' || $mouse_button || ' click not supported'
11+
END AS cmd
12+
13+
:eval $cmd
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#
2+
# @synopsis: lnav-src-loc-handler
3+
# @description: Handle a mouse button click on a source location.
4+
#
5+
6+
;SELECT $1 as mouse_button
7+
;SELECT CASE $mouse_button
8+
WHEN 'left' THEN '|lnav-open-source'
9+
WHEN 'right' THEN ':toggle-breakpoint'
10+
ELSE ':echo ' || $mouse_button || ' click not supported'
11+
END AS cmd
12+
13+
:eval $cmd

src/scripts/scripts.am

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,13 @@ BUILTIN_LNAVSCRIPTS = \
55
$(srcdir)/scripts/find-msg.lnav \
66
$(srcdir)/scripts/find-chained-msg.lnav \
77
$(srcdir)/scripts/journald-url-handler.lnav \
8+
$(srcdir)/scripts/lnav-breakpoint-handler.lnav \
89
$(srcdir)/scripts/lnav-copy-text.lnav \
910
$(srcdir)/scripts/lnav-link-callback.lnav \
1011
$(srcdir)/scripts/lnav-moveto-breakpoint.lnav \
1112
$(srcdir)/scripts/lnav-open-source.lnav \
1213
$(srcdir)/scripts/lnav-pop-view.lnav \
14+
$(srcdir)/scripts/lnav-src-loc-handler.lnav \
1315
$(srcdir)/scripts/lnav-write-external-access-info-to.lnav \
1416
$(srcdir)/scripts/partition-by-boot.lnav \
1517
$(srcdir)/scripts/pg-annotate-errors.lnav \

src/textview_curses.cc

Lines changed: 44 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -753,20 +753,6 @@ textview_curses::handle_mouse(mouse_event& me)
753753
}
754754
}
755755
this->tc_text_selection_active = false;
756-
if (this->tc_press_line.is<main_content>()
757-
&& mouse_line.is<main_content>()
758-
&& me.is_click_in(mouse_button_t::BUTTON_RIGHT, 0, INT_MAX))
759-
{
760-
auto* lov = this->get_overlay_source();
761-
if (lov != nullptr
762-
&& (!lov->get_show_details_in_overlay()
763-
|| this->tc_selection_at_press
764-
== this->get_selection()))
765-
{
766-
this->set_show_details_in_overlay(
767-
!lov->get_show_details_in_overlay());
768-
}
769-
}
770756
if (this->vc_enabled) {
771757
if (this->tc_selection_start) {
772758
this->toggle_user_mark(&BM_USER,
@@ -785,36 +771,55 @@ textview_curses::handle_mouse(mouse_event& me)
785771
auto cursor_sf = line_sf.sub_cell_range(
786772
mc.mc_line_range.lr_start + me.me_x,
787773
mc.mc_line_range.lr_start + me.me_x);
788-
auto link_iter = find_string_attr_containing(
789-
al.get_attrs(), &VC_HYPERLINK, cursor_sf.sf_begin);
790-
if (link_iter != al.get_attrs().end()) {
791-
auto href = link_iter->sa_value.get<std::string>();
792-
auto* ta = dynamic_cast<text_anchors*>(this->tc_sub_source);
793-
794-
if (me.me_button == mouse_button_t::BUTTON_LEFT
795-
&& ta != nullptr && startswith(href, "#")
796-
&& !startswith(href, "#/frontmatter"))
774+
auto consumed = false;
775+
if (this->tc_on_click) {
776+
consumed
777+
= this->tc_on_click(*this, al, cursor_sf.sf_begin, me);
778+
}
779+
if (!consumed) {
780+
if (this->tc_press_line.is<main_content>()
781+
&& me.is_click_in(
782+
mouse_button_t::BUTTON_RIGHT, 0, INT_MAX))
797783
{
798-
auto row_opt = ta->row_for_anchor(href);
784+
auto* lov = this->get_overlay_source();
785+
if (lov != nullptr
786+
&& (!lov->get_show_details_in_overlay()
787+
|| this->tc_selection_at_press
788+
== this->get_selection()))
789+
{
790+
this->set_show_details_in_overlay(
791+
!lov->get_show_details_in_overlay());
792+
}
793+
}
794+
auto link_iter = find_string_attr_containing(
795+
al.get_attrs(), &VC_HYPERLINK, cursor_sf.sf_begin);
796+
if (link_iter != al.get_attrs().end()) {
797+
auto href = link_iter->sa_value.get<std::string>();
798+
auto* ta
799+
= dynamic_cast<text_anchors*>(this->tc_sub_source);
800+
801+
if (me.me_button == mouse_button_t::BUTTON_LEFT
802+
&& ta != nullptr && startswith(href, "#")
803+
&& !startswith(href, "#/frontmatter"))
804+
{
805+
auto row_opt = ta->row_for_anchor(href);
799806

800-
if (row_opt.has_value()) {
801-
this->set_selection(row_opt.value());
807+
if (row_opt.has_value()) {
808+
this->set_selection(row_opt.value());
809+
}
810+
} else {
811+
this->tc_selected_text = selected_text_info{
812+
me.me_x,
813+
mc.mc_line,
814+
link_iter->sa_range,
815+
al.get_attrs(),
816+
al.to_string_fragment(link_iter).to_string(),
817+
href,
818+
};
819+
this->set_needs_update();
802820
}
803-
} else {
804-
this->tc_selected_text = selected_text_info{
805-
me.me_x,
806-
mc.mc_line,
807-
link_iter->sa_range,
808-
al.get_attrs(),
809-
al.to_string_fragment(link_iter).to_string(),
810-
href,
811-
};
812-
this->set_needs_update();
813821
}
814822
}
815-
if (this->tc_on_click) {
816-
this->tc_on_click(*this, al, cursor_sf.sf_begin, me);
817-
}
818823
}
819824
if (mouse_line.is<overlay_content>()) {
820825
const auto& oc = mouse_line.get<overlay_content>();

src/textview_curses.hh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -952,7 +952,7 @@ public:
952952
display_line_content_t tc_press_line;
953953
std::optional<vis_line_t> tc_selection_at_press;
954954
int tc_press_left{0};
955-
std::function<void(
955+
std::function<bool(
956956
textview_curses&, const attr_line_t&, int x, const mouse_event&)>
957957
tc_on_click;
958958
std::optional<string_attr_pair> tc_mark_style{

0 commit comments

Comments
 (0)