3TLPJ57B2OD5OWJN5WMS7A4W7IGFUWJJHVIXRM34VT6KUN6R4YSAC S2NVIFXRFER4SRA37WCT5XTXHDHAL5WIGGKY4A4XOTPLTKTZSRGQC D7A7MSIHJS3IAOLEPK52M4CZLDPLO7JB3Y62XACT2AM6UUCPQ6BAC 23SFYK4Q5NKBPJG53PQNPWQH6UOUU2YKJEL7RLXYBRLJOJYV7AWQC WW36JYLR4AILV7RHQEDJWMX74P74B7G7DRBHH3O2V5TCHRTZJWZQC KWTBNTO3QUUE2YADF6SYW6G6ZOKYEWRJQKIWDGZXR33S3YNDVIZQC 5MUEECMJHU44FL5RDUR3VFBIWK3H4X2L5MVJ73J37PYHZWLUKU2AC XSZZB47UXR6KGYFZZQFQR63X2LDKOH6TPNNBRRGHUCI5JJ4JIWVAC 6YZAVBWU6E5FYOI5JGEIPXGZLIKAW6LS2AOFIQWEE5DMOPPCD5PQC WT3GA27PQ2AOAIGK65O3Q4DMX4AZDVNULBLRL6GF4QW6QCASUEAAC Key::Named(key::Named::ArrowDown)if mods == Modifiers::SHIFT =>{Some(Msg::View(app::Msg::Cursor(cursor::Msg::AltPressDir(cursor::Dir::Down,))))}Key::Named(key::Named::ArrowUp) if mods == Modifiers::SHIFT => {Some(Msg::View(app::Msg::Cursor(cursor::Msg::AltPressDir(cursor::Dir::Up,))))}Key::Named(key::Named::ArrowLeft)if mods == Modifiers::SHIFT =>{Some(Msg::View(app::Msg::Cursor(cursor::Msg::AltPressDir(cursor::Dir::Left,))))}Key::Named(key::Named::ArrowRight)if mods == Modifiers::SHIFT =>{Some(Msg::View(app::Msg::Cursor(cursor::Msg::AltPressDir(cursor::Dir::Right,))))}
let delta = state.held_key.as_ref().and_then(|HeldKey {dir: held_dir,last_tick,}| {(dir == *held_dir).then(|| {// Ceil to 50 ms, because the first key repeat in Iced// is delayed 500 ms and that creates too much of a jumpcmp::min(Duration::from_millis(50),Instant::now() - *last_tick,)})},);
let delta = {state.held_key.as_ref().and_then(|HeldKey {dir: held_dir,last_tick,}| {(dir == *held_dir).then(|| {// Ceil to 50 ms, because the first key repeat in// Iced is delayed 500// ms and that creates too much of a jumpcmp::min(Duration::from_millis(50),Instant::now() - *last_tick,)})},)};
Msg::AltPressDir(dir) => {let delta = {state.held_key.as_ref().and_then(|HeldKey {dir: held_dir,last_tick,}| {(dir == *held_dir).then(|| {// Ceil to 50 ms, because the first key repeat in// Iced is delayed 500// ms and that creates too much of a jumpcmp::min(Duration::from_millis(50),Instant::now() - *last_tick,)})},)};state.held_key = Some(HeldKey {dir,last_tick: Instant::now(),});match dir {Dir::Down => {alt_select_down(state, files_diffs, log_diffs, delta)}Dir::Up => alt_select_up(state, files_diffs, log_diffs, delta),Dir::Left | Dir::Right => {// Nothing here yetTask::none()}}}
}}fn alt_select_down<M>(state: &mut State,files_diffs: &mut diff::FilesState,logs: &mut diff::LogFilesAndState,delta: Option<Duration>,) -> Task<M> {match state.selection.as_mut() {Some(Selection::UntrackedFile {ix: _,path,diff_selected: true,}) => {let id_hash = file::id_parts_hash(&path, file::Kind::Untracked);if let Some(nav) = files_diffs.get_mut(&id_hash).and_then(|state| state.nav.as_mut()){iced_nav_scrollable::alt_scroll_down(nav, delta)} else {Task::none()}}Some(Selection::ChangedFile {ix: _,path,diff_selected: true,}) => {let id_hash = file::id_parts_hash(&path, file::Kind::Changed);if let Some(nav) = files_diffs.get_mut(&id_hash).and_then(|state| state.nav.as_mut()){iced_nav_scrollable::alt_scroll_down(nav, delta)} else {Task::none()}}Some(Selection::LogChange {ix: _,hash,message: _,file:Some(LogChangeFileSelection {ix: _,path,diff_selected: true,}),}) => {let id_hash = file::log_id_parts_hash(*hash, &path);if let Some(nav) = logs.diffs.get_mut(&id_hash).and_then(|diff| diff.state.nav.as_mut()){iced_nav_scrollable::alt_scroll_down(nav, delta)} else {Task::none()}}Some(Selection::UntrackedFile { .. })| Some(Selection::ChangedFile { .. })| Some(Selection::LogChange { .. })| None => Task::none(),}}fn alt_select_up<M>(state: &mut State,files_diffs: &mut diff::FilesState,logs: &mut diff::LogFilesAndState,delta: Option<Duration>,) -> Task<M> {match state.selection.as_mut() {Some(Selection::UntrackedFile {ix: _,path,diff_selected: true,}) => {let id_hash = file::id_parts_hash(&path, file::Kind::Untracked);if let Some(nav) = files_diffs.get_mut(&id_hash).and_then(|state| state.nav.as_mut()){iced_nav_scrollable::alt_scroll_up(nav, delta)} else {Task::none()}}Some(Selection::ChangedFile {ix: _,path,diff_selected: true,}) => {let id_hash = file::id_parts_hash(&path, file::Kind::Changed);if let Some(nav) = files_diffs.get_mut(&id_hash).and_then(|state| state.nav.as_mut()){iced_nav_scrollable::alt_scroll_up(nav, delta)} else {Task::none()}}Some(Selection::LogChange {ix: _,hash,message: _,file:Some(LogChangeFileSelection {ix: _,path,diff_selected: true,}),}) => {let id_hash = file::log_id_parts_hash(*hash, &path);if let Some(nav) = logs.diffs.get_mut(&id_hash).and_then(|diff| diff.state.nav.as_mut()){iced_nav_scrollable::alt_scroll_up(nav, delta)} else {Task::none()}}Some(Selection::UntrackedFile { .. })| Some(Selection::ChangedFile { .. })| Some(Selection::LogChange { .. })| None => Task::none(),
}/// Scroll down, skipping any sections that are marked to skippub fn alt_scroll_down<M>(nav: &mut NavScrollable,delta: Option<Duration>,) -> Task<M> {let offset_delta = delta.map(|delta| delta.as_millis() as f32).unwrap_or(DEFAULT_DELTA)/ 1_000.0* SPEED;let y = nav.offset + offset_delta;task::scroll_to(nav.id.clone(), scrollable::AbsoluteOffset { x: 0.0, y })}/// Scroll up, skipping any sections that are marked to skippub fn alt_scroll_up<M>(nav: &mut NavScrollable,delta: Option<Duration>,) -> Task<M> {let offset_delta = delta.map(|delta| delta.as_millis() as f32).unwrap_or(DEFAULT_DELTA)/ 1_000.0* SPEED;let y = saturating_sub(nav.offset, offset_delta);task::scroll_to(nav.id.clone(), scrollable::AbsoluteOffset { x: 0.0, y })