diff --git a/src/listview_curses.cc b/src/listview_curses.cc index 8e25323f..52685c6b 100644 --- a/src/listview_curses.cc +++ b/src/listview_curses.cc @@ -512,12 +512,15 @@ listview_curses::set_top(vis_line_t top, bool suppress_flash) alerter::singleton().chime("invalid top"); } } else if (this->lv_top != top) { + auto old_top = this->lv_top; this->lv_top = top; if (this->lv_selectable) { if (this->lv_selection < 0_vl) { } else if (this->lv_selection < top) { - this->set_selection(top); + auto sel_diff = this->lv_selection - old_top; + this->set_selection(top + sel_diff); } else { + auto sel_diff = this->lv_selection - old_top; auto bot = this->get_bottom(); unsigned long width; vis_line_t height; @@ -526,7 +529,7 @@ listview_curses::set_top(vis_line_t top, bool suppress_flash) if (bot != -1_vl && (bot - top) >= (height - 1)) { if (this->lv_selection > (bot - this->lv_tail_space)) { - this->set_selection(bot - this->lv_tail_space); + this->set_selection(top + sel_diff); } } } diff --git a/src/views_vtab.cc b/src/views_vtab.cc index 78574467..500ec15a 100644 --- a/src/views_vtab.cc +++ b/src/views_vtab.cc @@ -190,7 +190,8 @@ CREATE TABLE lnav_views ( search TEXT, -- The text to search for in the view. filtering INTEGER, -- Indicates if the view is applying filters. movement TEXT, -- The movement mode, either 'top' or 'cursor'. - top_meta TEXT -- A JSON object that contains metadata related to the top line in the view. + top_meta TEXT, -- A JSON object that contains metadata related to the top line in the view. + selection INTEGER -- The number of the line that is focused for selection. ); )"; @@ -340,6 +341,9 @@ CREATE TABLE lnav_views ( } break; } + case 12: + sqlite3_result_int(ctx, (int) tc.get_selection()); + break; } return SQLITE_OK; @@ -372,7 +376,8 @@ CREATE TABLE lnav_views ( const char* search, bool do_filtering, string_fragment movement, - const char* top_meta) + const char* top_meta, + int64_t selection) { auto& tc = lnav_data.ld_views[index]; auto* time_source @@ -399,6 +404,9 @@ CREATE TABLE lnav_views ( return SQLITE_ERROR; } } + if (tc.is_selectable() && tc.get_selection() != selection) { + tc.set_selection(vis_line_t(selection)); + } if (top_meta != nullptr) { static const intern_string_t SQL_SRC = intern_string::lookup("top_meta"); diff --git a/test/listview_output_cursor.6 b/test/listview_output_cursor.6 index 9706e382..2203386a 100644 --- a/test/listview_output_cursor.6 +++ b/test/listview_output_cursor.6 @@ -6,7 +6,7 @@ S -1 ┋ A └ normal CSI Reset Replace mode CSI Erase all -S 1 ┋9 x┋ +S 1 ┋+9 x┋ A └┛ alt S 2 ┋10 x┋ A └┛ alt @@ -22,7 +22,7 @@ S 7 ┋15 A └┛ alt S 8 ┋16 x┋ A └┛ alt -S 9 ┋+17 x┋ +S 9 ┋17 x┋ A └┛ alt S 10 ┋18 x┋ A └┛ alt