From ecdeea930b998e21a75b9ac6b01523c4a1549b42 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Fri, 11 Jul 2025 10:59:29 +0530 Subject: [PATCH] Implement bindings to move current to first/last --- kittens/choose_files/main.go | 18 ++++++++++++++++-- kittens/choose_files/main.py | 4 ++++ kittens/choose_files/results.go | 11 +++++++---- kittens/choose_files/scan_test.go | 2 +- 4 files changed, 28 insertions(+), 7 deletions(-) diff --git a/kittens/choose_files/main.go b/kittens/choose_files/main.go index 9cea39161..2fed3266b 100644 --- a/kittens/choose_files/main.go +++ b/kittens/choose_files/main.go @@ -98,8 +98,8 @@ func (m Mode) WindowTitle() string { } type render_state struct { - num_matches, num_of_slots, num_before, num_per_column, num_columns int - first_idx CollectionIndex + num_matches, num_of_slots, num_before, num_per_column, num_columns, num_shown int + first_idx CollectionIndex } type State struct { @@ -407,6 +407,20 @@ func (h *Handler) dispatch_action(name, args string) (err error) { h.move_sideways(true) case "right": h.move_sideways(false) + case "first": + h.state.SetCurrentIndex(CollectionIndex{}) + h.state.last_render.num_before = 0 + case "last": + matches, _ := h.get_results() + h.state.SetCurrentIndex(matches.IncrementIndexWithWrapAround(CollectionIndex{}, -1)) + h.state.last_render.num_before = 0 + case "first_on_screen": + h.state.SetCurrentIndex(h.state.last_render.first_idx) + h.state.last_render.num_before = 0 + case "last_on_screen": + matches, _ := h.get_results() + h.state.SetCurrentIndex(matches.IncrementIndexWithWrapAround(h.state.last_render.first_idx, h.state.last_render.num_shown-1)) + h.state.last_render.num_before = h.state.last_render.num_shown - 1 } } return h.draw_screen() diff --git a/kittens/choose_files/main.py b/kittens/choose_files/main.py index 8cb77e499..25a32f6da 100644 --- a/kittens/choose_files/main.py +++ b/kittens/choose_files/main.py @@ -57,6 +57,10 @@ map('Next result', 'next_result down next 1') map('Previous result', 'prev_result up next -1') map('Left result', 'left_result left next left') map('Right result', 'right_result right next right') +map('First result on screen', 'first_result_on_screen home next first_on_screen') +map('Last result on screen', 'last_result_on_screen end next last_on_screen') +map('First result', 'first_result_on_screen ctrl+home next first') +map('Last result', 'last_result_on_screen ctrl+end next last') map('Change to currently selected dir', 'cd_current tab cd current') map('Change to parent directory', 'cd_parent shift+tab cd up') diff --git a/kittens/choose_files/results.go b/kittens/choose_files/results.go index 24611d778..9d6126030 100644 --- a/kittens/choose_files/results.go +++ b/kittens/choose_files/results.go @@ -208,10 +208,10 @@ func (h *Handler) draw_column_of_matches(matches ResultsType, current_idx int, x } } -func (h *Handler) draw_list_of_results(matches *SortedResults, y, height int) int { +func (h *Handler) draw_list_of_results(matches *SortedResults, y, height int) (num_cols, num_shown int) { available_width := h.screen_size.width - 2 col_width := available_width - num_cols := 1 + num_cols = 1 calc_num_cols := func(num_matches int) int { if num_matches == 0 || height < 2 { return 0 @@ -236,9 +236,10 @@ func (h *Handler) draw_list_of_results(matches *SortedResults, y, height int) in h.lp.MoveCursorTo(x, y) h.draw_column_of_matches(col, num_before, x, y, col_width-1, i) num_before -= height + num_shown += len(col) x += col_width } - return len(columns) + return len(columns), num_shown } func (h *Handler) draw_num_of_matches(num_shown, y int) { @@ -275,13 +276,15 @@ func (h *Handler) draw_results(y, bottom_margin int, matches *SortedResults, in_ h.state.last_render.num_of_slots = height - 2 num_cols := 0 num := matches.Len() + num_shown := 0 switch num { case 0: h.draw_no_matches_message(in_progress) default: - num_cols = h.draw_list_of_results(matches, y, h.state.last_render.num_of_slots) + num_cols, num_shown = h.draw_list_of_results(matches, y, h.state.last_render.num_of_slots) } h.state.last_render.num_matches = num + h.state.last_render.num_shown = num_shown h.draw_num_of_matches(h.state.last_render.num_of_slots*num_cols, y+height-2) return } diff --git a/kittens/choose_files/scan_test.go b/kittens/choose_files/scan_test.go index 6410eb2e6..146cc8ed0 100644 --- a/kittens/choose_files/scan_test.go +++ b/kittens/choose_files/scan_test.go @@ -280,7 +280,7 @@ func TestSortedResults(t *testing.T) { } } tc := func(num_before, expected_new_before int, ci CollectionIndex, expected ...[]int) { - ac, new_num_before := r.SplitIntoColumns(func(int) int { return 2 }, 2, num_before, ci) + ac, new_num_before, _ := r.SplitIntoColumns(func(int) int { return 2 }, 2, num_before, ci) actual := make([][]int, len(ac)) for i, x := range ac { actual[i] = utils.Map(func(r *ResultItem) int { return int(r.score) }, x)