diff --git a/src/hotkeys.cc b/src/hotkeys.cc index a2c84718..12757ee6 100644 --- a/src/hotkeys.cc +++ b/src/hotkeys.cc @@ -324,7 +324,7 @@ handle_paging_key(int ch) case 'f': if (tc == &lnav_data.ld_views[LNV_LOG]) { bm[&logfile_sub_source::BM_FILES].next(tc->get_selection()) | - [&tc](auto vl) { tc->set_top(vl); }; + [&tc](auto vl) { tc->set_selection(vl); }; } else if (tc == &lnav_data.ld_views[LNV_TEXT]) { textfile_sub_source& tss = lnav_data.ld_text_source; diff --git a/src/listview_curses.cc b/src/listview_curses.cc index d49ff91b..2d57e9ab 100644 --- a/src/listview_curses.cc +++ b/src/listview_curses.cc @@ -207,10 +207,29 @@ listview_curses::do_update() } else if (this->lv_selection >= (this->lv_top + height - this->lv_tail_space - 1_vl)) { - this->set_top( - this->lv_selection - height + 1_vl + this->lv_tail_space, true); - } else if (this->lv_selection < this->lv_top) { - this->set_top(this->lv_selection, true); + auto diff = this->lv_selection + - (this->lv_top + height - this->lv_tail_space - 1_vl); + + if (diff < (height / 8_vl)) { + // for small differences between the bottom and the selection, + // just move a little bit. + this->set_top( + this->lv_selection - height + 1_vl + this->lv_tail_space, + true); + } else { + // for large differences, put the focus in the middle + this->set_top(this->lv_selection - height / 2_vl, true); + } + } else if (this->lv_selection <= this->lv_top) { + auto diff = this->lv_top - this->lv_selection; + + if (this->lv_selection > 0 && diff < (height / 8_vl)) { + this->set_top(this->lv_selection - 1_vl); + } else if (this->lv_selection < height) { + this->set_top(0_vl); + } else { + this->set_top(this->lv_selection - height / 2_vl, true); + } } } diff --git a/src/readline_callbacks.cc b/src/readline_callbacks.cc index f19bb616..9f4c92f3 100644 --- a/src/readline_callbacks.cc +++ b/src/readline_callbacks.cc @@ -676,10 +676,14 @@ rl_callback_int(readline_curses* rc, bool is_alt) } if (first_hit) { auto first_hit_vl = first_hit.value(); - if (first_hit_vl > 0_vl) { - --first_hit_vl; + if (tc->is_selectable()) { + tc->set_selection(first_hit_vl); + } else { + if (first_hit_vl > 0_vl) { + --first_hit_vl; + } + tc->set_top(first_hit_vl); } - tc->set_top(first_hit_vl); } return true; diff --git a/test/listview_output_cursor.3 b/test/listview_output_cursor.3 index 62ae2345..0bfca212 100644 --- a/test/listview_output_cursor.3 +++ b/test/listview_output_cursor.3 @@ -6,15 +6,15 @@ S -1 ┋ A └ normal CSI Reset Replace mode CSI Erase all -S 1 ┋World! x┋ +S 1 ┋2 x┋ A └┛ alt -S 2 ┋2 x┋ +S 2 ┋3 x┋ A └┛ alt -S 3 ┋3 x┋ +S 3 ┋+4 x┋ A └┛ alt -S 4 ┋+4 x┋ +S 4 ┋5 x┋ A └┛ alt -S 5 ┋5 x┋ +S 5 ┋6 x┋ A └┛ alt CSI Erase all CSI Use normal screen buffer diff --git a/test/listview_output_cursor.4 b/test/listview_output_cursor.4 index 3980a0ba..3f9e3dfc 100644 --- a/test/listview_output_cursor.4 +++ b/test/listview_output_cursor.4 @@ -6,15 +6,15 @@ S -1 ┋ A └ normal CSI Reset Replace mode CSI Erase all -S 1 ┋Hello x┋ +S 1 ┋World! x┋ A └┛ alt -S 2 ┋World! x┋ +S 2 ┋2 x┋ A └┛ alt -S 3 ┋2 x┋ +S 3 ┋+3 x┋ A └┛ alt -S 4 ┋+3 x┋ +S 4 ┋4 x┋ A └┛ alt -S 5 ┋4 x┋ +S 5 ┋5 x┋ A └┛ alt CSI Erase all CSI Use normal screen buffer diff --git a/test/listview_output_cursor.5 b/test/listview_output_cursor.5 index f25061e7..c7d432e0 100644 --- a/test/listview_output_cursor.5 +++ b/test/listview_output_cursor.5 @@ -6,25 +6,25 @@ S -1 ┋ A └ normal CSI Reset Replace mode CSI Erase all -S 1 ┋+18 x┋ +S 1 ┋17 x┋ A └┛ alt -S 2 ┋19 x┋ +S 2 ┋+18 x┋ A └┛ alt -S 3 ┋20 x┋ +S 3 ┋19 x┋ A └┛ alt -S 4 ┋21 x┋ +S 4 ┋20 x┋ A └┛ alt -S 5 ┋22 x┋ +S 5 ┋21 x┋ A └┛ alt -S 6 ┋23 x┋ +S 6 ┋22 x┋ A └┛ alt -S 7 ┋24 x┋ +S 7 ┋23 x┋ A └┛ alt -S 8 ┋25 x┋ +S 8 ┋24 x┋ A └┛ alt -S 9 ┋26 x┋ +S 9 ┋25 x┋ A └┛ alt -S 10 ┋27 x┋ +S 10 ┋26 x┋ A └┛ alt CSI Erase all CSI Use normal screen buffer diff --git a/test/listview_output_cursor.6 b/test/listview_output_cursor.6 index 2203386a..be86ee17 100644 --- a/test/listview_output_cursor.6 +++ b/test/listview_output_cursor.6 @@ -6,25 +6,25 @@ S -1 ┋ A └ normal CSI Reset Replace mode CSI Erase all -S 1 ┋+9 x┋ +S 1 ┋8 x┋ A └┛ alt -S 2 ┋10 x┋ +S 2 ┋+9 x┋ A └┛ alt -S 3 ┋11 x┋ +S 3 ┋10 x┋ A └┛ alt -S 4 ┋12 x┋ +S 4 ┋11 x┋ A └┛ alt -S 5 ┋13 x┋ +S 5 ┋12 x┋ A └┛ alt -S 6 ┋14 x┋ +S 6 ┋13 x┋ A └┛ alt -S 7 ┋15 x┋ +S 7 ┋14 x┋ A └┛ alt -S 8 ┋16 x┋ +S 8 ┋15 x┋ A └┛ alt -S 9 ┋17 x┋ +S 9 ┋16 x┋ A └┛ alt -S 10 ┋18 x┋ +S 10 ┋17 x┋ A └┛ alt CSI Erase all CSI Use normal screen buffer