(ctx: &mut ScriptContext<'_, API>)
| 796 | if slot >= MAX_TABS { |
| 797 | return None; |
| 798 | } |
| 799 | let idx = visible_tab_start(open_count, active) + slot; |
| 800 | (idx < open_count).then_some(idx) |
| 801 | } |
| 802 | |
| 803 | pub fn visible_tab_page_target(open_count: usize, active: usize, dir: isize) -> Option<usize> { |
| 804 | if open_count == 0 { |
| 805 | return None; |
| 806 | } |
| 807 | let start = visible_tab_start(open_count, active); |
| 808 | let page_count = open_count.div_ceil(MAX_TABS); |
| 809 | let page = start / MAX_TABS; |
| 810 | let next_page = wrap_index(page, page_count, dir); |
| 811 | let offset = active.min(open_count - 1).saturating_sub(start); |
| 812 | Some((next_page * MAX_TABS + offset).min(open_count - 1)) |
| 813 | } |
| 814 | |
| 815 | pub fn shift_visible_tab_page<API: ScriptAPI + ?Sized>( |
| 816 | ctx: &mut ScriptContext<'_, API>, |
| 817 | dir: isize, |
| 818 | ) { |
| 819 | let idx = with_state!(ctx.run, EditorState, ctx.id, |state| { |
| 820 | visible_tab_page_target(state.open_paths.len(), state.active_open, dir) |
| 821 | }).unwrap_or_default(); |
| 822 | if let Some(idx) = idx { |
| 823 | set_active_tab(ctx, idx); |
no test coverage detected