nav for log changes and refactors
[?]
Jul 22, 2025, 1:15 PM
UR4J677RWA3OFG6HQTD46BUUE5YFPSBEFCJAEM5OMT4V5A7SBNNQCDependencies
- [2]
WT3GA27Padd cursor with selection - [3]
S2NVIFXRallow to enter record msg - [4]
W7IUT3ZVstart recording impl - [5]
D7A7MSIHallow to defer or abandon record, add buttons - [6]
4WO3ZJM2show untracked files' contents - [7]
BJXUYQ2Yshow untracked file contents in read-only text editor - [8]
AMPZ2BXKshow changed files diffs (only Edit atm) - [9]
DCSUCH6Radd undecoded diff view, improve decoded view style - [10]
JE44NYHMdisplay log files diffs - [11]
L6KSEFQImove cursor related stuff into its module - [12]
BFN2VHZSrefactor file stuff into sub-mod - [13]
23SFYK4Qbig view refactor into a new crate - [14]
OPXFZKEBview tests setup - [15]
3QVNMRNMtest non-empty repo app view - [16]
MYGIBRRHwip custom theme - [17]
PKJCFSBMtheme improvements - [18]
XSZZB47Urefactor stuff into lib - [19]
3BK22XE5add a test for hover btn and more refactors - [20]
ACDXXAX2refactor main's updates into smaller fns - [21]
TSFQFCB2test got repo change - [22]
7SSBM4UQview: refactor repo view - [23]
ZD56BUSUadd back +/- bg colors - [24]
I2AG42PAnew cols layout - [25]
4PNWU55Oreplace the circular hor navigation - [26]
WW36JYLRadd iced_nav_scrollable widget crate - [27]
WIFVLV37nav-scrollabe: detect size to determine if needs scrolling, msg when ready - [28]
SASAN2XCuse nav-scrollable - [29]
XZ6D3UUEavoid alloc - [30]
YKHE3XMWrefactor diffs handling - [31]
KEPKF3WOunify diffs handling, simplify view - [32]
GOLHUD6Rnav-scrollable: set skip-able sections - [33]
XHWLKCLDauto-scroll past skip sections on load - [34]
K5YUSV2Wauto-scroll to last offset - [35]
KWTBNTO3diffs selection and scrolling - [36]
5MUEECMJsmooth scrolling nav - [37]
3TLPJ57Balt scroll via context and couple fixes - [38]
BNHJU2DUclippy fixes - [39]
KQABQCCZupdate rust to 1.88 - [40]
AI3IMKC3refactor stairs - [41]
WXQBBQ2Aupdate nightly - [42]
DST3HRZZfix emoji rendering - [43]
PTWZYQFRuse nav-scrollable for repo status - [44]
RDRBP7ALauto-scroll status selection - [45]
4G6DZDO6rename diff msg for nav-scrollable - [46]
A5YBC77Vrecord! - [47]
MJDGPSHGWIP contents diff - [48]
ONRCENKTrm unnecessary state from repo's internal state - [49]
PTFDJ567add untracked files encoding - [50]
Y5ATDI2Hconvert changed file diffs and load src only if any needs it - [51]
NRCUG4R2load changed files src when selected - [52]
FR52XEMWadd action for log change file diff - [53]
ELG3UDT6allow to rm added files - [54]
I56UGW7Umake record test, fix log update - [55]
KM5PSZ4Awatch repo once loaded - [56]
ZVI4AWERwoot contents_diff - [57]
FVA36HBVrestart repo manager task if it crashes - [58]
SK3WVX7Aadd wee spacing for nav back - [59]
YBJRDOTCmake all repo actions async - [60]
65DXFP3Yfix status overflow - [61]
QMAUTRB6refactor diff - [62]
4ELJZGRJload and store all change diffs at once - [63]
V55EAIWQadd src file LRU cache - [64]
S2T7RUKWadd nav back placeholder - [*]
VCNKFNUFapp init test - [*]
6YZAVBWUInitial commit - [*]
WGID4LS4absolutely slayed testing with iced task
Change contents
- replacement in inflorescence_view/src/diff.rs at line 5
DiffWithoutContents, File, Lines, Section, UndecodableContents,DiffWithoutContents, File, Lines, Section, State, UndecodableContents, - edit in inflorescence_view/src/diff.rs at line 16[28.236]→[28.236:281](∅→∅),[28.364]→[28.364:509](∅→∅),[28.509]→[13.912:913](∅→∅),[23.578]→[13.912:913](∅→∅),[13.912]→[13.912:913](∅→∅)
#[derive(Debug, Default)]pub struct State {/// Initialized once the file is loaded and opened in viewpub nav: Option<NavScrollable>,pub state: libflorescence::diff::State,} - edit in inflorescence_view/src/diff.rs at line 23
nav: &'a NavScrollable, - replacement in inflorescence_view/src/diff.rs at line 29
view_decoded(state, decoded_file, diff_selected)view_decoded(state, nav, decoded_file, diff_selected) - replacement in inflorescence_view/src/diff.rs at line 32
view_undecodable(state, undecodable_file, diff_selected)view_undecodable(state, nav, undecodable_file, diff_selected) - replacement in inflorescence_view/src/diff.rs at line 38
state: &'a State,_state: &'a State,nav: &'a NavScrollable, - replacement in inflorescence_view/src/diff.rs at line 92[13.5499]→[31.188:247](∅→∅),[31.247]→[29.26:74](∅→∅),[28.691]→[29.26:74](∅→∅),[29.74]→[30.26:134](∅→∅),[30.134]→[45.66:92](∅→∅),[45.92]→[35.5543:5694](∅→∅),[30.166]→[35.5543:5694](∅→∅)
let sections = if let Some(nav) = state.nav.as_ref() {let children_len = sections_view.len();el(iced_nav_scrollable::view(nav,sections_view,children_len,Msg::DiffNav,).class(if diff_selected {theme::Scrollable::Selected} else {theme::Scrollable::Normal}))let children_len = sections_view.len();let sections = el(iced_nav_scrollable::view(nav,sections_view,children_len,Msg::DiffNav,).class(if diff_selected {theme::Scrollable::Selected - replacement in inflorescence_view/src/diff.rs at line 102
el(column(sections_view))};theme::Scrollable::Normal})); - replacement in inflorescence_view/src/diff.rs at line 118
state: &'a State,_state: &'a State,nav: &'a NavScrollable, - replacement in inflorescence_view/src/diff.rs at line 138[13.6315]→[31.271:315](∅→∅),[31.315]→[35.5721:5733](∅→∅),[35.5733]→[45.93:349](∅→∅),[45.349]→[35.6054:6064](∅→∅),[35.6054]→[35.6054:6064](∅→∅),[30.318]→[28.1614:1671](∅→∅),[35.6064]→[28.1614:1671](∅→∅),[28.1614]→[28.1614:1671](∅→∅)
if let Some(nav) = state.nav.as_ref() {el(iced_nav_scrollable::view(nav, diffs, diffs_len, Msg::DiffNav).class(if diff_selected {theme::Scrollable::Selected} else {theme::Scrollable::Normal}),)} else {el(column(diffs).spacing(10))}el(iced_nav_scrollable::view(nav, diffs, diffs_len, Msg::DiffNav).class(if diff_selected {theme::Scrollable::Selected} else {theme::Scrollable::Normal},),) - replacement in inflorescence_view/src/cursor.rs at line 1
use libflorescence::prelude::pijul;use libflorescence::repo; - replacement in inflorescence_view/src/cursor.rs at line 52
hash: pijul::Hash,hash: repo::ChangeHash, - replacement in inflorescence_view/src/cursor.rs at line 77
hash: pijul::Hash,hash: repo::ChangeHash, - replacement in inflorescence_view/src/app.rs at line 11
use iced::widget::{button, column, container, row, scrollable, text, text_editor,};use iced::widget::{button, column, container, row, text, text_editor}; - replacement in inflorescence_view/src/app.rs at line 31
pub selected_diff: Option<(&'a diff::File, &'a diff::State)>,pub selection: Option<Selection<'a>>, - edit in inflorescence_view/src/app.rs at line 40
}#[derive(Debug)]pub enum Selection<'a> {UntrackedFile {ix: usize,path: &'a str,diff: Option<Diff<'a>>,},ChangedFile {ix: usize,path: &'a str,diff: Option<Diff<'a>>,},Log {ix: usize,hash: repo::ChangeHash,message: &'a str,file: Option<LogChangeFileSelection<'a>>,nav: Option<&'a NavScrollable>,}, - edit in inflorescence_view/src/app.rs at line 63
#[derive(Debug)]pub struct LogChangeFileSelection<'a> {pub ix: usize,pub path: &'a str,pub diff: Option<Diff<'a>>,}#[derive(Debug)]pub struct Diff<'a> {pub is_selected: bool,pub file: &'a diff::File,pub state: &'a diff::State,pub nav: &'a NavScrollable,} - edit in inflorescence_view/src/app.rs at line 83
LogNav {hash: repo::ChangeHash,msg: iced_nav_scrollable::Msg,}, - replacement in inflorescence_view/src/app.rs at line 91
FileDiffsContentsAction {/// Message for an untracked or changed file diffFileDiff { - replacement in inflorescence_view/src/app.rs at line 94
action: diff::Msg,msg: diff::Msg, - replacement in inflorescence_view/src/app.rs at line 96
LogChangeFileDiffAction {hash: pijul::Hash,file: String,action: diff::Msg,/// Message for a log change file diffLogChangeFileDiff {id_hash: file::LogIdHash,msg: diff::Msg, - replacement in inflorescence_view/src/app.rs at line 113
let inner = if let Some(repo) = state.repo {view_repo(&state, repo)let State {window_size,repo_path,repo,cursor,record_msg,selection,} = state;let inner = if let Some(repo) = repo {view_repo(window_size, repo_path, repo, cursor, record_msg, selection) - replacement in inflorescence_view/src/app.rs at line 132
fn view_repo<'a>(state: &State<'a>, repo: &'a Repo) -> Element<'a, Msg, Theme> {fn view_repo<'a>(window_size: iced::Size,// TODO show path_repo_path: &'a Path,repo: &'a Repo,cursor: &'a cursor::State,record_msg: Option<&'a RecordMsg>,selection: Option<Selection<'a>>,) -> Element<'a, Msg, Theme> { - replacement in inflorescence_view/src/app.rs at line 142
state: repo,state:repo::State {dir_name,channel,untracked_files,changed_files,log,}, - replacement in inflorescence_view/src/app.rs at line 153
let repo_info = el(row([el(text(&repo.dir_name)),let view_repo_info = el(row([el(text(dir_name)), - replacement in inflorescence_view/src/app.rs at line 157
button(text(&repo.channel)), /* TODO* .on_press(Message) */button(text(channel)), /* TODO* .on_press(Message) */ - replacement in inflorescence_view/src/app.rs at line 162
let untracked_files = || {repo.untracked_files.iter().enumerate().map(let view_untracked_files = || {untracked_files.iter().enumerate().map( - replacement in inflorescence_view/src/app.rs at line 165
let is_selected = matches!(state.cursor.selection.as_ref() ,let is_selected = matches!(cursor.selection.as_ref() , - replacement in inflorescence_view/src/app.rs at line 181
let changed_files = || {repo.changed_files.iter().enumerate().map(let view_changed_files = || {changed_files.iter().enumerate().map( - replacement in inflorescence_view/src/app.rs at line 184
let is_selected = matches!(state.cursor.selection.as_ref(),let is_selected = matches!(cursor.selection.as_ref(), - replacement in inflorescence_view/src/app.rs at line 201
let log = || {repo.log.iter().enumerate().map(let view_log = || {log.iter().enumerate().map( - replacement in inflorescence_view/src/app.rs at line 209
let is_selected = matches!(state.cursor.selection.as_ref(),let is_selected = matches!(cursor.selection.as_ref(), - replacement in inflorescence_view/src/app.rs at line 225
let record_msg_editor = if let Some(RecordMsg::Typing(msg_content)) =state.record_msg.as_ref(){el(column([el(text_editor(msg_content).placeholder("Type something here...").on_action(Msg::EditRecordMsg)),el(row([el(button(text("Save")).on_press(Msg::SaveRecord)),el(button(text("Defer")).on_press(Msg::DeferRecord)),el(button(text("Abandon")).on_press(Msg::AbandonRecord)),])),]))} else {el(row([]))};let record_msg_editor =if let Some(RecordMsg::Typing(msg_content)) = record_msg.as_ref() {el(column([el(text_editor(msg_content).placeholder("Type something here...").on_action(Msg::EditRecordMsg)),el(row([el(button(text("Save")).on_press(Msg::SaveRecord)),el(button(text("Defer")).on_press(Msg::DeferRecord)),el(button(text("Abandon")).on_press(Msg::AbandonRecord)),])),]))} else {el(row([]))}; - replacement in inflorescence_view/src/app.rs at line 241
let selection_details = match state.cursor.selection.as_ref() {Some(cursor::Selection::UntrackedFile {ix: _,path,diff_selected,}) => {let selection_details = match selection.as_ref() {Some(Selection::UntrackedFile { ix: _, path, diff }) => { - replacement in inflorescence_view/src/app.rs at line 244
let diffs = match state.selected_diff {Some((file, state)) => diff::view(state, file, *diff_selected).map(move |msg| Msg::FileDiffsContentsAction {id_hash,action: msg,}),let diffs = match diff {Some(Diff {is_selected,file,state,nav,}) => diff::view(state, nav, file, *is_selected).map(move |msg| Msg::FileDiff { id_hash, msg }), - replacement in inflorescence_view/src/app.rs at line 261
Some(cursor::Selection::ChangedFile {path,ix: _,diff_selected,}) => {Some(Selection::ChangedFile { path, ix: _, diff }) => { - replacement in inflorescence_view/src/app.rs at line 263
let diffs = match state.selected_diff {Some((file, state)) => diff::view(state, file, *diff_selected).map(move |msg| Msg::FileDiffsContentsAction {id_hash,action: msg,}),let diffs = match diff {Some(Diff {is_selected,file,state,nav,}) => diff::view(state, nav, file, *is_selected).map(move |msg| Msg::FileDiff { id_hash, msg }), - replacement in inflorescence_view/src/app.rs at line 279
Some(cursor::Selection::LogChange {Some(Selection::Log { - edit in inflorescence_view/src/app.rs at line 283
nav, - replacement in inflorescence_view/src/app.rs at line 286
let entry = repo.log.get(*ix).unwrap();let entry = log.get(*ix).unwrap(); - replacement in inflorescence_view/src/app.rs at line 290
let files = entry.file_paths.iter().enumerate().map(|(ix, path)| {let is_selected = matches!(file, Some(cursor::LogChangeFileSelection{ path: selected_path, .. }) if selected_path == path);let view = match nav {Some(nav) => {let files_len = entry.file_paths.len();let files = entry.file_paths.iter().enumerate().map(|(ix, path)| {let is_selected = matches!(file, Some(LogChangeFileSelection{ path: selected_path, .. }) if selected_path == path); - edit in inflorescence_view/src/app.rs at line 299
let hash = *hash;el(iced_nav_scrollable::view(nav,files,files_len,move |msg| Msg::LogNav { hash, msg },).width(Length::Fill).height(Length::Fill))}None => el(text("Loading...")),}; - replacement in inflorescence_view/src/app.rs at line 314
el(text(message).shaping(text::Shaping::Advanced)),el(text(*message).shaping(text::Shaping::Advanced)), - replacement in inflorescence_view/src/app.rs at line 316
el(scrollable(column(files).width(Length::Fill))),view, - replacement in inflorescence_view/src/app.rs at line 329
state.window_size.width.floor() as usize / DEFAULT_MIN_COL_WIDTH,window_size.width.floor() as usize / DEFAULT_MIN_COL_WIDTH, - replacement in inflorescence_view/src/app.rs at line 332
let depth = if let Some(RecordMsg::Typing(_)) = state.record_msg.as_ref() {let depth = if let Some(RecordMsg::Typing(_)) = record_msg.as_ref() { - replacement in inflorescence_view/src/app.rs at line 334
} else if let Some(selection) = state.cursor.selection.as_ref() {} else if let Some(selection) = cursor.selection.as_ref() { - replacement in inflorescence_view/src/app.rs at line 347
// state.window_size.width,// window_size.width, - replacement in inflorescence_view/src/app.rs at line 355
.chain(untracked_files()).chain(view_untracked_files()) - replacement in inflorescence_view/src/app.rs at line 357
.chain(changed_files()).chain(view_changed_files()) - replacement in inflorescence_view/src/app.rs at line 359
.chain(log());.chain(view_log()); - replacement in inflorescence_view/src/app.rs at line 361
let status_nav_children_len = repo::nav_contents_count(repo);let status_nav_children_len = repo::nav_contents_count(&repo.state); - edit in inflorescence_view/src/app.rs at line 363
let status_selected = match selection.as_ref() {Some(Selection::UntrackedFile { diff, .. }) => !diff.as_ref().map(|diff| diff.is_selected).unwrap_or_default(),Some(Selection::ChangedFile { diff, .. }) => !diff.as_ref().map(|diff| diff.is_selected).unwrap_or_default(),Some(Selection::Log { file, .. }) => file.is_none(),None => true,}; - replacement in inflorescence_view/src/app.rs at line 376
repo_info,view_repo_info, - replacement in inflorescence_view/src/app.rs at line 382
)),).class(if status_selected {theme::Scrollable::Selected} else {theme::Scrollable::Normal})), - replacement in inflorescence_view/src/app.rs at line 410
let col_2 = match state.cursor.selection.as_ref() {Some(cursor::Selection::LogChange {let col_2 = match selection.as_ref() {Some(Selection::Log { - replacement in inflorescence_view/src/app.rs at line 415
file:Some(cursor::LogChangeFileSelection {ix: _,path,diff_selected,}),file: Some(LogChangeFileSelection { ix: _, path, diff }),nav: _, - replacement in inflorescence_view/src/app.rs at line 423[31.1474]→[31.1474:1563](∅→∅),[31.1563]→[35.7258:7337](∅→∅),[35.7337]→[31.1626:1685](∅→∅),[31.1626]→[31.1626:1685](∅→∅),[30.1400]→[24.2887:3024](∅→∅),[31.1685]→[24.2887:3024](∅→∅),[24.2887]→[24.2887:3024](∅→∅),[24.3024]→[31.1686:1743](∅→∅)
match state.selected_diff {Some((file, state)) => {diff::view(state, file, *diff_selected).map(|action| {Msg::LogChangeFileDiffAction {hash: *hash,file: path.clone(),action,}})match diff {Some(Diff {is_selected,file,state,nav,}) => {let id_hash = file::log_id_parts_hash(*hash, path);diff::view(state, nav, file, *is_selected).map(move |action| Msg::LogChangeFileDiff {id_hash,msg: action,},) - replacement in inflorescence_view/src/app.rs at line 462
Some(cursor::Selection::UntrackedFile { .. })| Some(cursor::Selection::ChangedFile { .. })| Some(cursor::Selection::LogChange { .. })Some(Selection::UntrackedFile { .. })| Some(Selection::ChangedFile { .. })| Some(Selection::Log { .. }) - replacement in inflorescence_view/src/app.rs at line 492
fn display_short_hash(hash: &pijul::Hash) -> String {fn display_short_hash(hash: &repo::ChangeHash) -> String { - edit in inflorescence_view/src/app/test.rs at line 6
use libflorescence::prelude::pijul; - replacement in inflorescence_view/src/app/test.rs at line 40
selected_diff: None,selection: None, - replacement in inflorescence_view/src/app/test.rs at line 68
selected_diff: None,selection: None, - replacement in inflorescence_view/src/app/test.rs at line 91
hash: pijul::Hash::None,hash: repo::ChangeHash::None, - replacement in inflorescence_view/src/app/test.rs at line 109
selected_diff: None,selection: None, - replacement in inflorescence_view/src/app/test.rs at line 123
selected_diff: None,selection: None, - replacement in inflorescence_view/src/app/test.rs at line 154
selected_diff: None,selection: None, - replacement in inflorescence/src/test.rs at line 721
assert!(task.is_none());assert!(task.is_some()); - edit in inflorescence/src/main.rs at line 139
DiffNav {id_hash: file::IdHash,msg: diff::Msg,}, - replacement in inflorescence/src/main.rs at line 179
id_hash: id,id_hash, - edit in inflorescence/src/main.rs at line 184
let diff_state = state.files_diffs.entry(id).or_default(); - replacement in inflorescence/src/main.rs at line 188[32.360]→[28.3015:3059](∅→∅),[28.3015]→[28.3015:3059](∅→∅),[28.3059]→[35.9124:9216](∅→∅),[35.9216]→[45.361:411](∅→∅),[45.411]→[28.3264:3333](∅→∅),[28.3264]→[28.3264:3333](∅→∅),[28.3333]→[35.9217:9264](∅→∅),[35.9264]→[30.3532:3603](∅→∅),[28.3376]→[30.3532:3603](∅→∅),[30.3603]→[28.3447:3505](∅→∅),[28.3447]→[28.3447:3505](∅→∅),[28.3505]→[38.113:148](∅→∅),[38.148]→[35.9265:9323](∅→∅),[28.3548]→[35.9265:9323](∅→∅),[35.9323]→[38.149:188](∅→∅),[38.188]→[28.3653:3678](∅→∅),[35.9370]→[28.3653:3678](∅→∅),[28.3653]→[28.3653:3678](∅→∅)
diff_state.nav = Some(nav);return tasks.map(move |msg| Msg::DiffNav {id_hash: id,msg: diff::Msg::DiffNav(msg),});}Task::none()}Msg::DiffNav { id_hash: id, msg } => {if let Some(diff_state) = state.files_diffs.get_mut(&id) {let task = diff::update(diff_state, msg);let id_clone = id;return task.map(move |msg| Msg::DiffNav {id_hash: id_clone,msg,state.files_diffs.diffs_nav = Some((id_hash, nav));return tasks.map(move |msg| {Msg::View(app::Msg::FileDiff {id_hash,msg: diff::Msg::DiffNav(msg),}) - replacement in inflorescence/src/main.rs at line 198
Msg::LogDiffNav { id_hash: id, msg } => {if let Some(diff::FileAndState { file: _, state }) =state.logs.diffs.get_mut(&id)Msg::LogDiffNav { id_hash, msg } => {if let Some(diff::FileAndState {file: _,state: diff_state,}) = state.logs.diffs.get_mut(&id_hash) - replacement in inflorescence/src/main.rs at line 204
let task = diff::update(state, msg);return task.map(move |msg| Msg::LogDiffNav { id_hash: id, msg });let nav = state.logs.diffs_nav.as_mut().and_then(|(nav_id_hash, nav)| {(*nav_id_hash == id_hash).then_some(nav)},);let task = diff::update(diff_state, nav, msg);return task.map(move |msg| Msg::LogDiffNav { id_hash, msg }); - replacement in inflorescence/src/main.rs at line 256[13.26390]→[34.83:164](∅→∅),[34.164]→[35.9734:9755](∅→∅),[35.9755]→[34.164:233](∅→∅),[34.164]→[34.164:233](∅→∅),[34.233]→[36.727:800](∅→∅),[36.800]→[44.37:74](∅→∅),[44.74]→[34.291:364](∅→∅),[43.4633]→[34.291:364](∅→∅),[35.9821]→[34.291:364](∅→∅),[34.291]→[34.291:364](∅→∅),[34.364]→[35.9822:9917](∅→∅),[35.9917]→[34.2256:2341](∅→∅),[34.2256]→[34.2256:2341](∅→∅),[34.2341]→[35.9918:11029](∅→∅),[35.11029]→[45.412:474](∅→∅),[45.474]→[35.11097:11197](∅→∅),[35.11097]→[35.11097:11197](∅→∅),[35.11197]→[34.3150:3172](∅→∅),[34.3150]→[34.3150:3172](∅→∅),[34.3172]→[35.11198:11788](∅→∅),[35.11788]→[34.3172:3190](∅→∅),[34.3172]→[34.3172:3190](∅→∅),[34.3190]→[35.11789:11839](∅→∅),[35.11839]→[34.3421:3437](∅→∅),[34.3421]→[34.3421:3437](∅→∅),[34.3437]→[35.11840:11914](∅→∅),[35.11914]→[34.3489:3499](∅→∅),[34.3489]→[34.3489:3499](∅→∅)
app::Msg::Cursor(msg) => {let cursor_task = cursor::update(msg,&mut state.cursor,&mut state.files,&mut state.files_diffs,&mut state.logs,state.repo.as_mut(),).map(|msg| Msg::View(app::Msg::ToRepo(msg)));let init_log_nav_task =if let Some(cursor::Selection::LogChange {ix: _,hash,message: _,file:Some(cursor::LogChangeFileSelection {ix: _,path,diff_selected: false,}),}) = state.cursor.selection.as_ref(){let id_hash = file::log_id_parts_hash(*hash, path);match state.logs.diffs.get_mut(&id_hash) {Some(log) if log.state.nav.is_none() => {let contents_count =diff::contents_count(&log.file);let unchanged_sections =diff::unchanged_sections(&log.file);let (nav, tasks) = iced_nav_scrollable::init(contents_count,unchanged_sections,);log.state.nav = Some(nav);tasks.map(move |msg| Msg::LogDiffNav {id_hash,msg: diff::Msg::DiffNav(msg),})}_ => Task::none(),}} else {Task::none()};let get_diffs_task = if let Some(cursor::Selection::LogChange {ix: _,hash,message: _,file: None,}) = state.cursor.selection.as_ref(){if !state.logs.change_hashes.contains(hash) {Task::done(Msg::View(app::Msg::ToRepo(repo::MsgIn::GetChangeDiffs { hash: *hash },)))} else {Task::none()}} else {Task::none()};Task::batch([cursor_task, get_diffs_task, init_log_nav_task])}app::Msg::Cursor(msg) => cursor::update(msg,&mut state.cursor,&mut state.files,&mut state.files_diffs,&mut state.logs,state.repo.as_mut(),), - edit in inflorescence/src/main.rs at line 274
} else {Task::none()}}app::Msg::LogNav { hash, msg } => {if let Some((selected_hash, nav)) = state.logs.changes_nav.as_mut()&& hash == *selected_hash{iced_nav_scrollable::update(nav, msg).map(move |msg| Msg::View(app::Msg::LogNav { hash, msg })) - replacement in inflorescence/src/main.rs at line 292[20.582]→[35.11915:12045](∅→∅),[20.702]→[3.772:782](∅→∅),[4.1679]→[3.772:782](∅→∅),[35.12045]→[3.772:782](∅→∅),[3.772]→[3.772:782](∅→∅),[3.782]→[20.703:850](∅→∅)
app::Msg::FileDiffsContentsAction { id_hash, action } => {file_diffs_contents_action(state, id_hash, action)}app::Msg::LogChangeFileDiffAction { hash, file, action } => {log_change_file_diff_action(state, hash, file, action)}app::Msg::FileDiff {id_hash,msg: action,} => file_diffs_contents_action(state, id_hash, action),app::Msg::LogChangeFileDiff {id_hash,msg: action,} => log_change_file_diff_action(state, id_hash, action), - edit in inflorescence/src/main.rs at line 349
let status_nav_task =status_nav_task.map(|msg| Msg::View(app::Msg::StatusNav(msg))); - replacement in inflorescence/src/main.rs at line 354
state.cursor.selection = if repo_state.untracked_files.is_empty() {Noneif repo_state.untracked_files.is_empty() {state.cursor.selection = None - replacement in inflorescence/src/main.rs at line 358
Some(cursor::untracked_file_selection(let (selection, selection_task) = cursor::untracked_file_selection( - edit in inflorescence/src/main.rs at line 360
status_nav, - replacement in inflorescence/src/main.rs at line 363
))&mut state.files_diffs,cursor::VertDir::Down,);state.cursor.selection = Some(selection);return Task::batch([status_nav_task, selection_task]); - replacement in inflorescence/src/main.rs at line 371
return status_nav_task.map(|msg| Msg::View(app::Msg::StatusNav(msg)));return status_nav_task; - edit in inflorescence/src/main.rs at line 413
let status_nav_task =status_nav_task.map(|msg| Msg::View(app::Msg::StatusNav(msg))); - replacement in inflorescence/src/main.rs at line 418
state.cursor.selection = if repo_state.changed_files.is_empty() {Noneif repo_state.changed_files.is_empty() {state.cursor.selection = None - replacement in inflorescence/src/main.rs at line 422
Some(cursor::changed_file_selection(repo_state,ix,&mut state.files,))let (selection, selection_task) =cursor::changed_file_selection(repo_state,status_nav,ix,&mut state.files,&mut state.files_diffs,cursor::VertDir::Down,);state.cursor.selection = Some(selection);return Task::batch([status_nav_task, selection_task]); - replacement in inflorescence/src/main.rs at line 436
return status_nav_task.map(|msg| Msg::View(app::Msg::StatusNav(msg)));return status_nav_task; - replacement in inflorescence/src/main.rs at line 528[20.6475]→[20.6475:6538](∅→∅),[20.6538]→[35.12402:12951](∅→∅),[7.1089]→[6.7355:7369](∅→∅),[28.6825]→[6.7355:7369](∅→∅),[20.6853]→[6.7355:7369](∅→∅),[35.12951]→[6.7355:7369](∅→∅),[6.7355]→[6.7355:7369](∅→∅),[6.7369]→[35.12952:13483](∅→∅),[28.7104]→[20.7123:7211](∅→∅),[35.13483]→[20.7123:7211](∅→∅),[20.7123]→[20.7123:7211](∅→∅),[20.7211]→[6.7394:7404](∅→∅),[6.7394]→[6.7394:7404](∅→∅),[6.7404]→[20.7212:7235](∅→∅)
if let Some(selection) = state.cursor.selection.as_mut() {match selection {cursor::Selection::UntrackedFile {ix: _,path,diff_selected: _,} => {let selection_hash =file::id_parts_hash(path, file::Kind::Untracked);if id_hash == selection_hash {let diffs = state.files_diffs.entry(id_hash).or_default();return diff::update(diffs, action).map(move |msg| Msg::DiffNav { id_hash, msg });}}cursor::Selection::ChangedFile {ix: _,path,diff_selected: _,} => {let selection_hash =file::id_parts_hash(path, file::Kind::Changed);if id_hash == selection_hash {let diffs = state.files_diffs.entry(id_hash).or_default();let task = diff::update(diffs, action);return task.map(move |msg| Msg::DiffNav { id_hash, msg });}}_ => {// Selection has changed}}}Task::none()let diffs = state.files_diffs.diffs.entry(id_hash).or_default();let nav =state.files_diffs.diffs_nav.as_mut().and_then(|(nav_id_hash, nav)| {(*nav_id_hash == id_hash).then_some(nav)});diff::update(diffs, nav, action).map(move |msg| Msg::View(app::Msg::FileDiff { id_hash, msg })) - replacement in inflorescence/src/main.rs at line 543
hash: pijul::Hash,file: String,id_hash: file::LogIdHash, - edit in inflorescence/src/main.rs at line 557
&& *selected_hash == hash&& *selected_path == file - replacement in inflorescence/src/main.rs at line 558
let id_hash = file::log_id_parts_hash(hash, &file);if let Some(diff::FileAndState { file: _, state }) =state.logs.diffs.get_mut(&id_hash)let selected_id_hash =file::log_id_parts_hash(*selected_hash, selected_path);if selected_id_hash == id_hash&& let Some(diff::FileAndState {file: _,state: diff_state,}) = state.logs.diffs.get_mut(&id_hash) - replacement in inflorescence/src/main.rs at line 566
return diff::update(state, action)let nav =state.logs.diffs_nav.as_mut().and_then(|(nav_id_hash, nav)| {(*nav_id_hash == id_hash).then_some(nav)});return diff::update(diff_state, nav, action) - replacement in inflorescence/src/main.rs at line 798
hash: pijul::Hash,hash: repo::ChangeHash, - replacement in inflorescence/src/main.rs at line 801
if let Some(cursor::Selection::LogChange {let changed_files_count = diffs.len();let task = if let Some(cursor::Selection::LogChange { - replacement in inflorescence/src/main.rs at line 807
file: _,file, - replacement in inflorescence/src/main.rs at line 811
diffs.into_iter().for_each(|(path, diffs)| {// NOTE: using unknown encoding as we don't yet have the file// for past changeslet file = diff::init_file(diff::FileContent::UnknownEncoding,Some(&diffs),);let id_hash = file::log_id_parts_hash(hash, &path);let log_file_diff = diff::FileAndState {file,// The nav is initialized only once a file is selected,// because its tasks need it to be visible to completestate: diff::State::default(),};if let Some(file) = file.as_ref() {// If a file is selected, init the nav for its difflet diff = diffs.get(&file.path).unwrap();let diff_contents_count = diff.len();let (diffs_nav, nav_task) =iced_nav_scrollable::init(diff_contents_count, HashSet::new());let id_hash = file::log_id_parts_hash(hash, &file.path);state.logs.diffs_nav = Some((id_hash, diffs_nav));nav_task.map(move |msg| {Msg::View(app::Msg::LogChangeFileDiff {id_hash,msg: diff::Msg::DiffNav(msg),})})} else {// Init scrollable nav for log changeslet (changes_nav, nav_task) =iced_nav_scrollable::init(changed_files_count, HashSet::new());state.logs.changes_nav = Some((hash, changes_nav));nav_task.map(move |msg| Msg::View(app::Msg::LogNav { hash, msg }))}} else {Task::none()};// Store the changesstate.logs.change_file_counts.insert(hash, changed_files_count);diffs.into_iter().for_each(|(path, diffs)| {// NOTE: using unknown encoding as we don't yet have the file// for past changeslet file =diff::init_file(diff::FileContent::UnknownEncoding, Some(&diffs));let id_hash = file::log_id_parts_hash(hash, &path);let log_file_diff = diff::FileAndState {file,// The nav is initialized only once a file is selected,// because its tasks need it to be visible to completestate: diff::State::default(),};state.logs.diffs.insert(id_hash, log_file_diff);}); - replacement in inflorescence/src/main.rs at line 861[30.5853]→[41.3537:3661](∅→∅),[41.3661]→[8.2921:2927](∅→∅),[8.2921]→[8.2921:2927](∅→∅),[8.2927]→[20.13703:13720](∅→∅)
state.logs.change_hashes.insert(hash);state.logs.diffs.insert(id_hash, log_file_diff);});}Task::none()task - edit in inflorescence/src/main.rs at line 1018
let log_nav_sub =if let Some((hash, _nav)) = state.logs.changes_nav.as_ref() {let hash = *hash;iced_nav_scrollable::subs().with(hash).map(|(hash, msg)| Msg::View(app::Msg::LogNav { hash, msg }))} else {Subscription::none()}; - replacement in inflorescence/src/main.rs at line 1038
.map(|(id_hash, msg)| Msg::DiffNav {id_hash,msg: diff::Msg::DiffNav(msg),.map(|(id_hash, msg)| {Msg::View(app::Msg::FileDiff {id_hash,msg: diff::Msg::DiffNav(msg),}) - replacement in inflorescence/src/main.rs at line 1053
.map(|(id_hash, msg)| Msg::DiffNav {id_hash,msg: diff::Msg::DiffNav(msg),.map(|(id_hash, msg)| {Msg::View(app::Msg::FileDiff {id_hash,msg: diff::Msg::DiffNav(msg),}) - edit in inflorescence/src/main.rs at line 1090
log_nav_sub, - replacement in inflorescence/src/main.rs at line 1107
logs: log_diffs,logs, - replacement in inflorescence/src/main.rs at line 1110
let selected_diff = match state.cursor.selection.as_ref() {let selection = match state.cursor.selection.as_ref() { - replacement in inflorescence/src/main.rs at line 1112
ix: _,ix, - replacement in inflorescence/src/main.rs at line 1114
diff_selected: _,diff_selected, - replacement in inflorescence/src/main.rs at line 1117
let file = files.diffs_cache.inner.peek(&id_hash);match file {let diff = files.diffs_cache.inner.peek(&id_hash);let diff = match diff { - replacement in inflorescence/src/main.rs at line 1120
files_diffs.get(&id_hash).map(|state| (file, state))let nav = files_diffs.diffs_nav.as_ref().and_then(|(nav_id_hash, nav)| {(*nav_id_hash == id_hash).then_some(nav)}).unwrap();files_diffs.diffs.get(&id_hash).map(|state| app::Diff {is_selected: *diff_selected,file,state,nav,}) - replacement in inflorescence/src/main.rs at line 1135
}};Some(app::Selection::UntrackedFile {ix: *ix,path,diff,}) - replacement in inflorescence/src/main.rs at line 1144
ix: _,diff_selected: _,ix,diff_selected, - replacement in inflorescence/src/main.rs at line 1148
let file = files.diffs_cache.inner.peek(&id_hash);match file {let diff = files.diffs_cache.inner.peek(&id_hash);let diff = match diff { - replacement in inflorescence/src/main.rs at line 1151
files_diffs.get(&id_hash).map(|state| (file, state))let nav = files_diffs.diffs_nav.as_ref().and_then(|(nav_id_hash, nav)| {(*nav_id_hash == id_hash).then_some(nav)}).unwrap();files_diffs.diffs.get(&id_hash).map(|state| app::Diff {is_selected: *diff_selected,file,state,nav,}) - replacement in inflorescence/src/main.rs at line 1166
}};Some(app::Selection::ChangedFile {ix: *ix,path,diff,}) - replacement in inflorescence/src/main.rs at line 1174
ix: _,ix: log_ix, - replacement in inflorescence/src/main.rs at line 1176
message: _,file:Some(cursor::LogChangeFileSelection {ix: _,path,diff_selected: _,}),message,file, - replacement in inflorescence/src/main.rs at line 1179[30.7127]→[35.18494:18558](∅→∅),[35.18558]→[30.7240:7262](∅→∅),[30.7240]→[30.7240:7262](∅→∅),[30.7262]→[35.18559:18686](∅→∅)
let id_hash = file::log_id_parts_hash(*hash, path);log_diffs.diffs.get(&id_hash).map(|diff::FileAndState { file, state }| (file, state))let file = file.as_ref().map(|cursor::LogChangeFileSelection {ix: change_ix,path,diff_selected,}| {let id_hash = file::log_id_parts_hash(*hash, path);let diff = logs.diffs.get(&id_hash).map(|diff::FileAndState { file, state }| {let nav = logs.diffs_nav.as_ref().and_then(|(nav_id_hash, nav)| {(*nav_id_hash == id_hash).then_some(nav)}).unwrap();app::Diff {is_selected: *diff_selected,file,state,nav,}},);app::LogChangeFileSelection {ix: *change_ix,path,diff,}},);let nav = logs.changes_nav.as_ref().and_then(|(nav_hash, nav)| (nav_hash == hash).then_some(nav));Some(app::Selection::Log {ix: *log_ix,hash: *hash,message,file,nav,}) - replacement in inflorescence/src/main.rs at line 1222
Some(cursor::Selection::LogChange { file: None, .. }) | None => None,None => None, - replacement in inflorescence/src/main.rs at line 1225[30.7391]→[13.28732:28768](∅→∅),[13.28732]→[13.28732:28768](∅→∅),[13.28768]→[24.5792:5831](∅→∅),[24.5831]→[13.28768:28889](∅→∅),[13.28768]→[13.28768:28889](∅→∅),[13.28889]→[30.7392:7419](∅→∅),[30.7450]→[13.28914:28944](∅→∅),[13.28914]→[13.28914:28944](∅→∅),[13.28991]→[13.28991:29017](∅→∅)
app::view(app::State {window_size: *window_size,repo_path,repo: repo.as_ref(),cursor,record_msg: record_msg.as_ref(),selected_diff,},window_id,).map(Msg::View)let state = app::State {window_size: *window_size,repo_path,repo: repo.as_ref(),cursor,record_msg: record_msg.as_ref(),selection,};app::view(state, window_id).map(Msg::View) - edit in inflorescence/src/file.rs at line 195
pub fn try_get_src_file(state: &State, id_hash: IdHash) -> Option<&diff::File> {state.diffs_cache.inner.peek(&id_hash).and_then(|diff| match diff {Diff::Loading => None,Diff::Loaded(file) => Some(file),})} - edit in inflorescence/src/diff.rs at line 13
use iced_nav_scrollable::NavScrollable; - replacement in inflorescence/src/diff.rs at line 19
use std::collections::HashSet;use std::collections::{HashMap, HashSet}; - replacement in inflorescence/src/diff.rs at line 21
pub type FilesState = file::IdMap<State>;#[derive(Debug, Default)]pub struct FilesState {pub diffs: file::IdMap<State>,/// Diffs scrollable nav.////// Only the current nav is kept because the sizes of contents have to be/// queried everytime the selection changes due to possible container size/// changes.pub diffs_nav: Option<(file::IdHash, NavScrollable)>,} - replacement in inflorescence/src/diff.rs at line 34
/// All the hashes in this set have `diffs` loadedpub change_hashes: HashSet<repo::ChangeHash>,/// All the hashes in this map have `diffs` loaded. The value is the number/// of the changed files in the change (contents count used for/// scrollable-nav).pub change_file_counts: HashMap<repo::ChangeHash, usize>, - edit in inflorescence/src/diff.rs at line 41
/// Log changes scrollable nav.////// Only the current nav is kept because the sizes of contents have to be/// queried everytime the selection changes due to possible container size/// changes.pub changes_nav: Option<(repo::ChangeHash, NavScrollable)>,/// Log diffs scrollable nav.////// Only the current nav is kept because the sizes of contents have to be/// queried everytime the selection changes due to possible container size/// changes.pub diffs_nav: Option<(file::LogIdHash, NavScrollable)>, - replacement in inflorescence/src/diff.rs at line 61
pub fn update(state: &mut State, msg: Msg) -> Task<Msg> {pub fn update(_state: &mut State,nav: Option<&mut NavScrollable>,msg: Msg,) -> Task<Msg> { - replacement in inflorescence/src/diff.rs at line 68
if let Some(nav) = state.nav.as_mut() {if let Some(nav) = nav { - replacement in inflorescence/src/diff.rs at line 235
id: file::IdHash,id_hash: file::IdHash, - replacement in inflorescence/src/diff.rs at line 239
.get(&id).and_then(|diff| diff.nav.as_ref()).diffs_nav.as_ref().and_then(|(nav_id_hash, nav)| (*nav_id_hash == id_hash).then_some(nav)) - replacement in inflorescence/src/diff.rs at line 254
logs.diffs.get(&id_hash).and_then(|diff| diff.state.nav.as_ref())logs.diffs_nav.as_ref().and_then(|(nav_id_hash, nav)| (*nav_id_hash == id_hash).then_some(nav)) - edit in inflorescence/src/cursor.rs at line 1
use iced_nav_scrollable::NavScrollable; - edit in inflorescence/src/cursor.rs at line 15
use std::collections::HashSet; - replacement in inflorescence/src/cursor.rs at line 17
pub fn update<M>(pub fn update( - replacement in inflorescence/src/cursor.rs at line 22
log_diffs: &mut diff::LogFilesAndState,logs: &mut diff::LogFilesAndState, - replacement in inflorescence/src/cursor.rs at line 24
) -> Task<M> {) -> Task<crate::Msg> { - replacement in inflorescence/src/cursor.rs at line 51
Dir::Down => select_down(state,files,repo,files_diffs,log_diffs,delta,),Dir::Down => {select_down(state, files, files_diffs, logs, repo, delta)} - replacement in inflorescence/src/cursor.rs at line 55
select_up(state, files, repo, files_diffs, log_diffs, delta)select_up(state, files, files_diffs, logs, repo, delta) - replacement in inflorescence/src/cursor.rs at line 59
select_right(state, repo.as_deref(), files_diffs, log_diffs)select_right(state, files_diffs, logs, repo.as_deref()) - replacement in inflorescence/src/cursor.rs at line 63
Msg::ReleaseDir(dir) => release(dir, state, files_diffs, log_diffs),Msg::ReleaseDir(dir) => release(dir, state, files_diffs, logs), - replacement in inflorescence/src/cursor.rs at line 89
Dir::Down => {alt_select_down(state, files_diffs, log_diffs, delta)}Dir::Up => alt_select_up(state, files_diffs, log_diffs, delta),Dir::Down => alt_select_down(state, files_diffs, logs, delta),Dir::Up => alt_select_up(state, files_diffs, logs, delta), - replacement in inflorescence/src/cursor.rs at line 103
log_diffs,logs, - edit in inflorescence/src/cursor.rs at line 105
}}pub fn untracked_file_selection(repo: &repo::State,ix: usize,files: &mut file::State,) -> Selection {let path = repo.untracked_files.iter().nth(ix).unwrap().clone();let id = file::Id {path: path.clone(),file_kind: file::Kind::Untracked,};file::load_src_file_if_not_cached(files, id);Selection::UntrackedFile {ix,path,diff_selected: false, - edit in inflorescence/src/cursor.rs at line 107
pub fn changed_file_selection(repo: &repo::State,ix: usize,files: &mut file::State,) -> Selection {let (path, diffs) = repo.changed_files.iter().nth(ix).unwrap();if diff::any_diff_has_contents(diffs) {let id = file::Id {path: path.clone(),file_kind: file::Kind::Changed,};file::load_src_file_if_not_cached(files, id);} - replacement in inflorescence/src/cursor.rs at line 108
Selection::ChangedFile {ix,path: path.clone(),diff_selected: false,}}pub fn log_selection(repo: &repo::State, ix: usize) -> Selection {let entry = repo.log.get(ix).unwrap();Selection::LogChange {ix,hash: entry.hash,message: entry.message.clone(),file: None,}}pub fn log_file_selection(log_entry: &repo::LogEntry,file_ix: usize,) -> LogChangeFileSelection {let path = log_entry.file_paths.get(file_ix).unwrap().clone();LogChangeFileSelection {ix: file_ix,path,diff_selected: false,}}fn select_down<M>(fn select_down( - edit in inflorescence/src/cursor.rs at line 111
repo: Option<&mut app::Repo>, - edit in inflorescence/src/cursor.rs at line 113
repo: Option<&mut app::Repo>, - replacement in inflorescence/src/cursor.rs at line 115
) -> Task<M> {) -> Task<crate::Msg> { - replacement in inflorescence/src/cursor.rs at line 137
if let Some(nav) = files_diffs.get_mut(&id_hash).and_then(|state| state.nav.as_mut()){if let Some(nav) = files_diffs.diffs_nav.as_mut().and_then(|(nav_id_hash, nav)| {(*nav_id_hash == id_hash).then_some(nav)},) { - replacement in inflorescence/src/cursor.rs at line 151
let selection =changed_file_selection(repo_state, ix, files);let task = iced_nav_scrollable::scroll_down_to_section(status_section_ix(repo_state,ix,StatusSectionKind::Changed,),changed_file_selection(repo_state, - replacement in inflorescence/src/cursor.rs at line 154
);(selection, task)ix,files,files_diffs,VertDir::Down,) - replacement in inflorescence/src/cursor.rs at line 161
let task = iced_nav_scrollable::scroll_down_to_section(status_section_ix(repo_state,ix,StatusSectionKind::Log,),log_selection( - replacement in inflorescence/src/cursor.rs at line 163
);(log_selection(repo_state, ix), task)logs,repo_state,ix,VertDir::Down,) - replacement in inflorescence/src/cursor.rs at line 170
let selection =untracked_file_selection(repo_state, ix, files);let task = iced_nav_scrollable::scroll_up_to_section(status_section_ix(repo_state,ix,StatusSectionKind::Untracked,),untracked_file_selection(repo_state, - replacement in inflorescence/src/cursor.rs at line 173
);(selection, task)ix,files,files_diffs,VertDir::Up,) - replacement in inflorescence/src/cursor.rs at line 181
let selection = untracked_file_selection(repo_state, ix, files);let task = iced_nav_scrollable::scroll_down_to_section(status_section_ix(repo_state,ix,StatusSectionKind::Untracked,),untracked_file_selection(repo_state, - replacement in inflorescence/src/cursor.rs at line 184
);(selection, task)ix,files,files_diffs,VertDir::Down,) - replacement in inflorescence/src/cursor.rs at line 205
if let Some(nav) = files_diffs.get_mut(&id_hash).and_then(|state| state.nav.as_mut()){if let Some(nav) = files_diffs.diffs_nav.as_mut().and_then(|(nav_id_hash, nav)| {(*nav_id_hash == id_hash).then_some(nav)},) { - replacement in inflorescence/src/cursor.rs at line 219
let task = iced_nav_scrollable::scroll_down_to_section(status_section_ix(repo_state,ix,StatusSectionKind::Log,),log_selection( - replacement in inflorescence/src/cursor.rs at line 221
);(log_selection(repo_state, ix), task)logs,repo_state,ix,VertDir::Down,) - replacement in inflorescence/src/cursor.rs at line 228
let selection =untracked_file_selection(repo_state, ix, files);let task = iced_nav_scrollable::scroll_up_to_section(status_section_ix(repo_state,ix,StatusSectionKind::Untracked,),untracked_file_selection(repo_state, - replacement in inflorescence/src/cursor.rs at line 231
);(selection, task)ix,files,files_diffs,VertDir::Up,) - replacement in inflorescence/src/cursor.rs at line 238
let selection =changed_file_selection(repo_state, ix, files);let task = iced_nav_scrollable::scroll_up_to_section(status_section_ix(repo_state,ix,StatusSectionKind::Changed,),changed_file_selection(repo_state, - replacement in inflorescence/src/cursor.rs at line 241
);(selection, task)ix,files,files_diffs,VertDir::Up,) - replacement in inflorescence/src/cursor.rs at line 249
let selection = changed_file_selection(repo_state, ix, files);let task = iced_nav_scrollable::scroll_down_to_section(status_section_ix(repo_state,ix,StatusSectionKind::Changed,),changed_file_selection(repo_state, - replacement in inflorescence/src/cursor.rs at line 252
);(selection, task)ix,files,files_diffs,VertDir::Down,) - replacement in inflorescence/src/cursor.rs at line 274
(Selection::LogChange {ix: log_ix,hash,message,file: Some(LogChangeFileSelection {ix: file_ix,path,diff_selected,}),},if let Some(nav) = logs.diffs.get_mut(&id_hash).and_then(|diff| diff.state.nav.as_mut()){iced_nav_scrollable::scroll_down(nav, delta)} else {Task::none()},)let selection = Selection::LogChange {ix: log_ix,hash,message,file: Some(LogChangeFileSelection {ix: file_ix,path,diff_selected,}),};let task = if let Some(nav) = logs.diffs_nav.as_mut().and_then(|(nav_id_hash, nav)| {(*nav_id_hash == id_hash).then_some(nav)}) {iced_nav_scrollable::scroll_down(nav, delta)} else {Task::none()};(selection, task) - edit in inflorescence/src/cursor.rs at line 306
let (file, selection_task) =log_file_selection(logs, log_entry, hash, file_ix); - replacement in inflorescence/src/cursor.rs at line 310
let file = log_file_selection(log_entry, file_ix);let scroll_task = if let Some((nav_changes_hash, nav)) =logs.changes_nav.as_ref()&& *nav_changes_hash == hash{iced_nav_scrollable::scroll_down_to_section(file_ix, nav,)} else {Task::none()}; - replacement in inflorescence/src/cursor.rs at line 321
(Selection::LogChange {ix: log_ix,hash,message,file: Some(file),},Task::none(),)let selection = Selection::LogChange {ix: log_ix,hash,message,file: Some(file),};(selection, Task::batch([selection_task, scroll_task])) - replacement in inflorescence/src/cursor.rs at line 335
let task =iced_nav_scrollable::scroll_up_to_section(status_section_ix(repo_state,ix,StatusSectionKind::Untracked,),status_nav,);(untracked_file_selection(repo_state, ix, files),task,untracked_file_selection(repo_state,status_nav,ix,files,files_diffs,VertDir::Up, - replacement in inflorescence/src/cursor.rs at line 345
let task =iced_nav_scrollable::scroll_up_to_section(status_section_ix(repo_state,ix,StatusSectionKind::Changed,),status_nav,);(changed_file_selection(repo_state, ix, files),task,changed_file_selection(repo_state,status_nav,ix,files,files_diffs,VertDir::Up, - replacement in inflorescence/src/cursor.rs at line 355
let task =iced_nav_scrollable::scroll_up_to_section(status_section_ix(repo_state,ix,StatusSectionKind::Log,),status_nav,);(log_selection(repo_state, ix), task)log_selection(status_nav,logs,repo_state,ix,VertDir::Up,) - replacement in inflorescence/src/cursor.rs at line 365
let task = iced_nav_scrollable::scroll_down_to_section(status_section_ix(repo_state,ix,StatusSectionKind::Log,),log_selection( - replacement in inflorescence/src/cursor.rs at line 367
);(log_selection(repo_state, ix), task)logs,repo_state,ix,VertDir::Down,) - replacement in inflorescence/src/cursor.rs at line 380
let selection =Some(untracked_file_selection(repo_state, ix, files));let task = iced_nav_scrollable::scroll_down_to_section(status_section_ix(repo_state,ix,StatusSectionKind::Untracked,),let (selection, task) = untracked_file_selection(repo_state, - edit in inflorescence/src/cursor.rs at line 383
ix,files,files_diffs,VertDir::Down, - replacement in inflorescence/src/cursor.rs at line 388
(selection, task)(Some(selection), task) - replacement in inflorescence/src/cursor.rs at line 391
let selection =Some(changed_file_selection(repo_state, ix, files));let task = iced_nav_scrollable::scroll_down_to_section(status_section_ix(repo_state,ix,StatusSectionKind::Changed,),let (selection, task) = changed_file_selection(repo_state, - edit in inflorescence/src/cursor.rs at line 394
ix,files,files_diffs,VertDir::Down, - replacement in inflorescence/src/cursor.rs at line 399
(selection, task)(Some(selection), task) - replacement in inflorescence/src/cursor.rs at line 402
let selection = log_selection(repo_state, ix);let task = iced_nav_scrollable::scroll_down_to_section(status_section_ix(repo_state, ix, StatusSectionKind::Log),let (selection, task) = log_selection( - edit in inflorescence/src/cursor.rs at line 404
logs,repo_state,ix,VertDir::Down, - replacement in inflorescence/src/cursor.rs at line 419
fn select_up<M>(fn select_up( - edit in inflorescence/src/cursor.rs at line 422
repo: Option<&mut app::Repo>, - edit in inflorescence/src/cursor.rs at line 424
repo: Option<&mut app::Repo>, - replacement in inflorescence/src/cursor.rs at line 426
) -> Task<M> {) -> Task<crate::Msg> { - replacement in inflorescence/src/cursor.rs at line 448
if let Some(nav) = files_diffs.get_mut(&id_hash).and_then(|state| state.nav.as_mut()){if let Some(nav) = files_diffs.diffs_nav.as_mut().and_then(|(nav_id_hash, nav)| {(*nav_id_hash == id_hash).then_some(nav)},) { - replacement in inflorescence/src/cursor.rs at line 462
let task = iced_nav_scrollable::scroll_down_to_section(status_section_ix(repo_state,ix,StatusSectionKind::Log,),log_selection( - replacement in inflorescence/src/cursor.rs at line 464
);(log_selection(repo_state, ix), task)logs,repo_state,ix,VertDir::Down,) - replacement in inflorescence/src/cursor.rs at line 471
let selection =changed_file_selection(repo_state, ix, files);let task = iced_nav_scrollable::scroll_down_to_section(status_section_ix(repo_state,ix,StatusSectionKind::Changed,),changed_file_selection(repo_state, - replacement in inflorescence/src/cursor.rs at line 474
);(selection, task)ix,files,files_diffs,VertDir::Down,) - replacement in inflorescence/src/cursor.rs at line 481
let selection =untracked_file_selection(repo_state, ix, files);let task = iced_nav_scrollable::scroll_down_to_section(status_section_ix(repo_state,ix,StatusSectionKind::Untracked,),untracked_file_selection(repo_state, - replacement in inflorescence/src/cursor.rs at line 484
);(selection, task)ix,files,files_diffs,VertDir::Down,) - replacement in inflorescence/src/cursor.rs at line 492
let selection = untracked_file_selection(repo_state, ix, files);let task = iced_nav_scrollable::scroll_up_to_section(status_section_ix(repo_state,ix,StatusSectionKind::Untracked,),untracked_file_selection(repo_state, - replacement in inflorescence/src/cursor.rs at line 495
);(selection, task)ix,files,files_diffs,VertDir::Up,) - replacement in inflorescence/src/cursor.rs at line 516
if let Some(nav) = files_diffs.get_mut(&id_hash).and_then(|state| state.nav.as_mut()){if let Some(nav) = files_diffs.diffs_nav.as_mut().and_then(|(nav_id_hash, nav)| {(*nav_id_hash == id_hash).then_some(nav)},) { - replacement in inflorescence/src/cursor.rs at line 530
let selection =untracked_file_selection(repo_state, ix, files);let task = iced_nav_scrollable::scroll_up_to_section(status_section_ix(repo_state,ix,StatusSectionKind::Untracked,),untracked_file_selection(repo_state, - replacement in inflorescence/src/cursor.rs at line 533
);(selection, task)ix,files,files_diffs,VertDir::Up,) - replacement in inflorescence/src/cursor.rs at line 540
let selection = log_selection(repo_state, ix);let task = iced_nav_scrollable::scroll_down_to_section(status_section_ix(repo_state,ix,StatusSectionKind::Log,),log_selection( - replacement in inflorescence/src/cursor.rs at line 542
);(selection, task)logs,repo_state,ix,VertDir::Down,) - replacement in inflorescence/src/cursor.rs at line 549
let selection =changed_file_selection(repo_state, ix, files);let task = iced_nav_scrollable::scroll_down_to_section(status_section_ix(repo_state,ix,StatusSectionKind::Changed,),changed_file_selection(repo_state, - replacement in inflorescence/src/cursor.rs at line 552
);(selection, task)ix,files,files_diffs,VertDir::Down,) - replacement in inflorescence/src/cursor.rs at line 560
let selection = changed_file_selection(repo_state, ix, files);let task = iced_nav_scrollable::scroll_up_to_section(status_section_ix(repo_state,ix,StatusSectionKind::Changed,),changed_file_selection(repo_state, - replacement in inflorescence/src/cursor.rs at line 563
);(selection, task)ix,files,files_diffs,VertDir::Up,) - replacement in inflorescence/src/cursor.rs at line 585[40.10632]→[40.10632:11430](∅→∅),[40.11430]→[35.36450:36487](∅→∅),[35.36450]→[35.36450:36487](∅→∅),[35.36487]→[40.11431:11533](∅→∅)
(Selection::LogChange {ix: log_ix,hash,message,file: Some(LogChangeFileSelection {ix: file_ix,path,diff_selected,}),},if let Some(nav) = logs.diffs.get_mut(&id_hash).and_then(|diff| diff.state.nav.as_mut()){iced_nav_scrollable::scroll_up(nav, delta)} else {Task::none()},)let selection = Selection::LogChange {ix: log_ix,hash,message,file: Some(LogChangeFileSelection {ix: file_ix,path,diff_selected,}),};let task = if let Some(nav) = logs.diffs_nav.as_mut().and_then(|(nav_id_hash, nav)| {(*nav_id_hash == id_hash).then_some(nav)}) {iced_nav_scrollable::scroll_up(nav, delta)} else {Task::none()};(selection, task) - replacement in inflorescence/src/cursor.rs at line 615
let file = log_file_selection(log_entry, file_ix);(Selection::LogChange {ix: log_ix,hash,message,file: Some(file),},Task::none(),)let (file, selection_task) =log_file_selection(logs, log_entry, hash, file_ix);let scroll_task = if let Some((nav_changes_hash, nav)) =logs.changes_nav.as_ref()&& *nav_changes_hash == hash{iced_nav_scrollable::scroll_up_to_section(file_ix, nav,)} else {Task::none()};let selection = Selection::LogChange {ix: log_ix,hash,message,file: Some(file),};(selection, Task::batch([selection_task, scroll_task])) - replacement in inflorescence/src/cursor.rs at line 643
let selection =changed_file_selection(repo_state, ix, files);let task =iced_nav_scrollable::scroll_up_to_section(status_section_ix(repo_state,ix,StatusSectionKind::Changed,),status_nav,);(selection, task)changed_file_selection(repo_state,status_nav,ix,files,files_diffs,VertDir::Up,) - replacement in inflorescence/src/cursor.rs at line 653
let selection =untracked_file_selection(repo_state, ix, files);let task =iced_nav_scrollable::scroll_up_to_section(status_section_ix(repo_state,ix,StatusSectionKind::Untracked,),status_nav,);(selection, task)untracked_file_selection(repo_state,status_nav,ix,files,files_diffs,VertDir::Up,) - replacement in inflorescence/src/cursor.rs at line 663
let selection = log_selection(repo_state, ix);let task =iced_nav_scrollable::scroll_down_to_section(status_section_ix(repo_state,ix,StatusSectionKind::Log,),status_nav,);(selection, task)log_selection(status_nav,logs,repo_state,ix,VertDir::Down,) - replacement in inflorescence/src/cursor.rs at line 673
let selection = log_selection(repo_state, ix);let task = iced_nav_scrollable::scroll_up_to_section(status_section_ix(repo_state,ix,StatusSectionKind::Log,),log_selection( - replacement in inflorescence/src/cursor.rs at line 675
);(selection, task)logs,repo_state,ix,VertDir::Up,) - replacement in inflorescence/src/cursor.rs at line 688
let selection = log_selection(repo_state, ix);let task = iced_nav_scrollable::scroll_up_to_section(status_section_ix(repo_state, ix, StatusSectionKind::Log),let (selection, task) = log_selection( - edit in inflorescence/src/cursor.rs at line 690
logs,repo_state,ix,VertDir::Up, - replacement in inflorescence/src/cursor.rs at line 698
let selection = changed_file_selection(repo_state, ix, files);let task = iced_nav_scrollable::scroll_up_to_section(status_section_ix(repo_state,ix,StatusSectionKind::Untracked,),let (selection, task) = changed_file_selection(repo_state, - edit in inflorescence/src/cursor.rs at line 701
ix,files,files_diffs,VertDir::Up, - replacement in inflorescence/src/cursor.rs at line 709
let selection = untracked_file_selection(repo_state, ix, files);let task = iced_nav_scrollable::scroll_up_to_section(status_section_ix(repo_state,ix,StatusSectionKind::Untracked,),let (selection, task) = untracked_file_selection(repo_state, - edit in inflorescence/src/cursor.rs at line 712
ix,files,files_diffs,VertDir::Up, - replacement in inflorescence/src/cursor.rs at line 741
if let Some(nav) = files_diffs.get_mut(&id_hash).and_then(|state| state.nav.as_mut())if let Some(nav) =files_diffs.diffs_nav.as_ref().and_then(|(nav_id_hash, nav)| {(*nav_id_hash == id_hash).then_some(nav)}) - replacement in inflorescence/src/cursor.rs at line 760
if let Some(nav) = files_diffs.get_mut(&id_hash).and_then(|state| state.nav.as_mut())if let Some(nav) =files_diffs.diffs_nav.as_ref().and_then(|(nav_id_hash, nav)| {(*nav_id_hash == id_hash).then_some(nav)}) - replacement in inflorescence/src/cursor.rs at line 785
if let Some(nav) = logs.diffs.get_mut(&id_hash).and_then(|diff| diff.state.nav.as_mut())if let Some(nav) =logs.diffs_nav.as_ref().and_then(|(nav_id_hash, nav)| {(*nav_id_hash == id_hash).then_some(nav)}) - replacement in inflorescence/src/cursor.rs at line 815
if let Some(nav) = files_diffs.get_mut(&id_hash).and_then(|state| state.nav.as_mut())if let Some(nav) =files_diffs.diffs_nav.as_ref().and_then(|(nav_id_hash, nav)| {(*nav_id_hash == id_hash).then_some(nav)}) - replacement in inflorescence/src/cursor.rs at line 834
if let Some(nav) = files_diffs.get_mut(&id_hash).and_then(|state| state.nav.as_mut())if let Some(nav) =files_diffs.diffs_nav.as_ref().and_then(|(nav_id_hash, nav)| {(*nav_id_hash == id_hash).then_some(nav)}) - replacement in inflorescence/src/cursor.rs at line 859
if let Some(nav) = logs.diffs.get_mut(&id_hash).and_then(|diff| diff.state.nav.as_mut())if let Some(nav) =logs.diffs_nav.as_ref().and_then(|(nav_id_hash, nav)| {(*nav_id_hash == id_hash).then_some(nav)}) - replacement in inflorescence/src/cursor.rs at line 876
fn select_left<M>(state: &mut State, repo: Option<&app::Repo>) -> Task<M> {let Some(_repo) = repo.as_ref() else {fn select_left(state: &mut State,repo: Option<&app::Repo>,) -> Task<crate::Msg> {let Some(app::Repo {state: _repo_state,status_nav,}) = repo.as_ref()else { - replacement in inflorescence/src/cursor.rs at line 887
let selection: Option<Selection> = match state.selection.take() {Some(Selection::LogChange {ix,hash,message,file:Some(LogChangeFileSelection {ix: file_ix,path,diff_selected,}),}) => {if diff_selected {Some(Selection::LogChange {ix,hash,message,file: Some(LogChangeFileSelection {let (selection, task): (Option<Selection>, Task<crate::Msg>) =match state.selection.take() {Some(Selection::LogChange {ix,hash,message,file:Some(LogChangeFileSelection { - replacement in inflorescence/src/cursor.rs at line 897
diff_selected: false,diff_selected, - replacement in inflorescence/src/cursor.rs at line 899
})} else {Some(Selection::LogChange {}) => {if diff_selected {(Some(Selection::LogChange {ix,hash,message,file: Some(LogChangeFileSelection {ix: file_ix,path,diff_selected: false,}),}),Task::none(),)} else {let selection = Selection::LogChange {ix,hash,message,file: None,};let task = iced_nav_scrollable::scroll_to_stored_offset(status_nav,);(Some(selection), task)}}Some(Selection::UntrackedFile {ix,path,diff_selected: true,}) => (Some(Selection::UntrackedFile { - replacement in inflorescence/src/cursor.rs at line 934[40.14817]→[40.14817:14923](∅→∅),[40.14923]→[35.39812:39826](∅→∅),[35.39812]→[35.39812:39826](∅→∅),[35.39826]→[40.14924:15594](∅→∅)
hash,message,file: None,})}}Some(Selection::UntrackedFile {ix,path,diff_selected: true,}) => Some(Selection::UntrackedFile {ix,path,diff_selected: false,}),Some(Selection::ChangedFile {ix,path,diff_selected: true,}) => Some(Selection::ChangedFile {ix,path,diff_selected: false,}),selection @ (Some(Selection::UntrackedFile { .. })| Some(Selection::ChangedFile { .. })| Some(Selection::LogChange { file: None, .. })| None) => selection,};path,diff_selected: false,}),Task::none(),),Some(Selection::ChangedFile {ix,path,diff_selected: true,}) => (Some(Selection::ChangedFile {ix,path,diff_selected: false,}),Task::none(),),selection @ (Some(Selection::UntrackedFile { .. })| Some(Selection::ChangedFile { .. })| Some(Selection::LogChange { file: None, .. })| None) => (selection, Task::none()),}; - replacement in inflorescence/src/cursor.rs at line 957
Task::none()task - replacement in inflorescence/src/cursor.rs at line 960
fn select_right<M>(fn select_right( - edit in inflorescence/src/cursor.rs at line 962
repo: Option<&app::Repo>, - replacement in inflorescence/src/cursor.rs at line 963
logs: &diff::LogFilesAndState,) -> Task<M> {logs: &mut diff::LogFilesAndState,repo: Option<&app::Repo>,) -> Task<crate::Msg> { - replacement in inflorescence/src/cursor.rs at line 973[40.15706]→[40.15706:15803](∅→∅),[40.15803]→[35.40969:41448](∅→∅),[35.40969]→[35.40969:41448](∅→∅),[35.41448]→[39.60:155](∅→∅),[39.155]→[35.41592:41693](∅→∅),[35.41592]→[35.41592:41693](∅→∅),[35.41693]→[39.156:244](∅→∅)
let (selection, task): (Option<Selection>, Task<M>) =match state.selection.take() {Some(Selection::UntrackedFile {ix,path,diff_selected: false,}) => {let id_hash = file::id_parts_hash(&path, file::Kind::Untracked);let diff_selected =diff::file_diff_needs_scrolling(files_diffs, id_hash);// If the selected file's diff is already loaded (it has an// attached state), scroll back to its last offsetlet task = if diff_selected&& let Some(nav) = files_diffs.get(&id_hash).and_then(|state| state.nav.as_ref()){iced_nav_scrollable::scroll_to_stored_offset(nav)let (selection, task): (Option<Selection>, Task<crate::Msg>) = match state.selection.take(){Some(Selection::UntrackedFile {ix,path,diff_selected: false,}) => {let id_hash = file::id_parts_hash(&path, file::Kind::Untracked);let diff_selected =diff::file_diff_needs_scrolling(files_diffs, id_hash);// If the selected file's diff is already loaded (it has an// attached state), scroll back to its last offsetlet task = if diff_selected&& let Some(nav) = files_diffs.diffs_nav.as_ref().and_then(|(nav_id_hash, nav)| {(*nav_id_hash == id_hash).then_some(nav)},) {iced_nav_scrollable::scroll_to_stored_offset(nav)} else {Task::none()};(Some(Selection::UntrackedFile {ix,path,diff_selected,}),task,)}Some(Selection::ChangedFile {ix,path,diff_selected: false,}) => {let id_hash = file::id_parts_hash(&path, file::Kind::Changed);let diff_selected =diff::file_diff_needs_scrolling(files_diffs, id_hash);// If the selected file's diff is already loaded (it has an// attached state), scroll back to its last offsetlet task = if diff_selected&& let Some(nav) = files_diffs.diffs_nav.as_ref().and_then(|(nav_id_hash, nav)| {(*nav_id_hash == id_hash).then_some(nav)},) {iced_nav_scrollable::scroll_to_stored_offset(nav)} else {Task::none()};(Some(Selection::ChangedFile {ix,path,diff_selected,}),task,)}Some(Selection::LogChange {ix,hash,message,file: None,}) => {let log_entry = repo_state.log.get(ix).unwrap();let (file, task) = if let Some(path) = log_entry.file_paths.first(){let id_hash = file::log_id_parts_hash(log_entry.hash, path);let task = if let Some(log) = logs.diffs.get(&id_hash) {// Init log diffs navlet contents_count = diff::contents_count(&log.file);let unchanged_sections =diff::unchanged_sections(&log.file);let (nav, tasks) = iced_nav_scrollable::init(contents_count,unchanged_sections,);logs.diffs_nav = Some((id_hash, nav));tasks.map(move |msg| crate::Msg::LogDiffNav {id_hash,msg: diff::Msg::DiffNav(msg),}) - edit in inflorescence/src/cursor.rs at line 1060
// If the log is not loaded yet, the nav will be initialized// once it's loaded (`repo::MsgOut::GotChangeDifs`) - edit in inflorescence/src/cursor.rs at line 1064
- replacement in inflorescence/src/cursor.rs at line 1066
Some(Selection::UntrackedFile {ix,path,diff_selected,Some(LogChangeFileSelection {ix: 0,path: path.clone(),diff_selected: false, - replacement in inflorescence/src/cursor.rs at line 1073[35.42189]→[35.42189:42678](∅→∅),[35.42678]→[39.245:340](∅→∅),[39.340]→[35.42822:42923](∅→∅),[35.42822]→[35.42822:42923](∅→∅),[35.42923]→[39.341:429](∅→∅),[39.429]→[35.43086:43259](∅→∅),[11.18858]→[35.43086:43259](∅→∅)
}Some(Selection::ChangedFile {ix,path,diff_selected: false,}) => {let id_hash = file::id_parts_hash(&path, file::Kind::Changed);let diff_selected =diff::file_diff_needs_scrolling(files_diffs, id_hash);// If the selected file's diff is already loaded (it has an// attached state), scroll back to its last offsetlet task = if diff_selected&& let Some(nav) = files_diffs.get(&id_hash).and_then(|state| state.nav.as_ref()){iced_nav_scrollable::scroll_to_stored_offset(nav)} else {Task::none()};(Some(Selection::ChangedFile {ix,} else {(None, Task::none())};(Some(Selection::LogChange {ix,hash,message,file,}),task,)}Some(Selection::LogChange {ix,hash,message,file:Some(LogChangeFileSelection {ix: file_ix,path,diff_selected: false,}),}) => {let id_hash = file::log_id_parts_hash(hash, &path);let diff_selected = diff::log_diff_needs_scrolling(logs, id_hash);// If the selected file's diff is already loaded (it has an// attached state), scroll back to its last offsetlet task = if diff_selected&& let Some(nav) =logs.diffs_nav.as_ref().and_then(|(nav_id_hash, nav)| {(*nav_id_hash == id_hash).then_some(nav)}) {iced_nav_scrollable::scroll_to_stored_offset(nav)} else {Task::none()};(Some(Selection::LogChange {ix,hash,message,file: Some(LogChangeFileSelection {ix: file_ix, - replacement in inflorescence/src/cursor.rs at line 1120[35.43352]→[35.43352:44060](∅→∅),[35.44060]→[39.430:518](∅→∅),[39.518]→[35.44197:44333](∅→∅),[35.44197]→[35.44197:44333](∅→∅),[35.44333]→[39.519:607](∅→∅),[39.607]→[35.44496:44554](∅→∅),[11.20251]→[35.44496:44554](∅→∅),[35.44554]→[11.20251:20270](∅→∅),[11.20251]→[11.20251:20270](∅→∅),[11.20270]→[35.44555:44986](∅→∅),[35.44986]→[11.20387:20401](∅→∅),[11.20387]→[11.20387:20401](∅→∅),[11.20401]→[35.44987:45142](∅→∅),[35.45142]→[44.17874:17939](∅→∅),[44.17939]→[35.45201:45536](∅→∅),[35.45201]→[35.45201:45536](∅→∅),[35.45536]→[25.765:839](∅→∅),[25.765]→[25.765:839](∅→∅),[25.839]→[35.45537:45637](∅→∅),[35.45637]→[25.1321:1344](∅→∅),[25.1321]→[25.1321:1344](∅→∅),[25.1344]→[35.45638:45970](∅→∅)
task,)}Some(Selection::LogChange {ix,hash,message,file:Some(LogChangeFileSelection {ix: file_ix,path,diff_selected: false,}),}) => {let id_hash = file::log_id_parts_hash(hash, &path);let diff_selected =diff::log_diff_needs_scrolling(logs, id_hash);// If the selected file's diff is already loaded (it has an// attached state), scroll back to its last offsetlet task = if diff_selected&& let Some(nav) = logs.diffs.get(&id_hash).and_then(|diff| diff.state.nav.as_ref()){iced_nav_scrollable::scroll_to_stored_offset(nav)} else {Task::none()};(Some(Selection::LogChange {ix,hash,message,file: Some(LogChangeFileSelection {ix: file_ix,path,diff_selected,}),}),task,)}Some(Selection::LogChange {ix,hash,message,file: None,}) => {let log_entry = repo_state.log.get(ix).unwrap();let (file, task) =if let Some(path) = log_entry.file_paths.first() {(Some(LogChangeFileSelection {ix: 0,path: path.clone(),diff_selected: false,}),Task::none(),)} else {(None, Task::none())};(Some(Selection::LogChange {ix,hash,message,file,}),task,)}selection => (selection, Task::none()),};}),task,)}selection => (selection, Task::none()),}; - replacement in inflorescence/src/cursor.rs at line 1134
log_diffs: &mut diff::LogFilesAndState,logs: &mut diff::LogFilesAndState, - replacement in inflorescence/src/cursor.rs at line 1148
if let Some(nav) = files_diffs.get_mut(&id_hash).and_then(|state| state.nav.as_mut()){if let Some(nav) = files_diffs.diffs_nav.as_mut().and_then(|(nav_id_hash, nav)| {(*nav_id_hash == id_hash).then_some(nav)},) { - replacement in inflorescence/src/cursor.rs at line 1163
if let Some(nav) = files_diffs.get_mut(&id_hash).and_then(|state| state.nav.as_mut()){if let Some(nav) = files_diffs.diffs_nav.as_mut().and_then(|(nav_id_hash, nav)| {(*nav_id_hash == id_hash).then_some(nav)},) { - replacement in inflorescence/src/cursor.rs at line 1183
if let Some(nav) = log_diffs.diffs.get_mut(&id_hash).and_then(|diff| diff.state.nav.as_mut()){if let Some(nav) = logs.diffs_nav.as_mut().and_then(|(nav_id_hash, nav)| {(*nav_id_hash == id_hash).then_some(nav)},) { - replacement in inflorescence/src/cursor.rs at line 1229[39.655]→[39.655:702](∅→∅),[39.702]→[35.46979:47072](∅→∅),[35.46979]→[35.46979:47072](∅→∅),[35.47072]→[39.703:717](∅→∅)
&& let Some(nav) = files_diffs.get(&id_hash).and_then(|state| state.nav.as_ref()){&& let Some(nav) = files_diffs.diffs_nav.as_ref().and_then(|(nav_id_hash, nav)| {(*nav_id_hash == id_hash).then_some(nav)},) { - replacement in inflorescence/src/cursor.rs at line 1263[39.947]→[39.947:994](∅→∅),[39.994]→[35.48340:48433](∅→∅),[35.48340]→[35.48340:48433](∅→∅),[35.48433]→[39.995:1009](∅→∅)
&& let Some(nav) = files_diffs.get(&id_hash).and_then(|state| state.nav.as_ref()){&& let Some(nav) = files_diffs.diffs_nav.as_ref().and_then(|(nav_id_hash, nav)| {(*nav_id_hash == id_hash).then_some(nav)},) { - replacement in inflorescence/src/cursor.rs at line 1304[39.1124]→[39.1124:1172](∅→∅),[39.1172]→[35.49833:49981](∅→∅),[35.49833]→[35.49833:49981](∅→∅),[35.49981]→[39.1173:1195](∅→∅)
&& let Some(nav) = logs.diffs.get(&id_hash).and_then(|diff| diff.state.nav.as_ref()){&& let Some(nav) = logs.diffs_nav.as_ref().and_then(|(nav_id_hash, nav)| {(*nav_id_hash == id_hash).then_some(nav)},) { - edit in inflorescence/src/cursor.rs at line 1355
}#[derive(Debug, Clone, Copy)]pub enum VertDir {Up,Down,}pub fn untracked_file_selection(repo: &repo::State,status_nav: &NavScrollable,ix: usize,files: &mut file::State,files_diffs: &mut diff::FilesState,dir: VertDir,) -> (Selection, Task<crate::Msg>) {let path = repo.untracked_files.iter().nth(ix).unwrap();let id_hash = file::id_parts_hash(path, file::Kind::Untracked);let nav_task = match file::try_get_src_file(files, id_hash) {Some(file_diff) => {// If the diff is already loaded init nav for itlet contents_count = diff::contents_count(file_diff);let unchanged_sections = diff::unchanged_sections(file_diff);let (nav, nav_task) =iced_nav_scrollable::init(contents_count, unchanged_sections);files_diffs.diffs_nav = Some((id_hash, nav));nav_task.map(move |msg| {crate::Msg::View(app::Msg::FileDiff {id_hash,msg: diff::Msg::DiffNav(msg),})})}None => {// Nav will be initialize once the diff is loaded// (`crate::Msg::File`)let id = file::Id {path: path.clone(),file_kind: file::Kind::Untracked,};file::load_src_file_if_not_cached(files, id);Task::none()}};let scroll_task = match dir {VertDir::Up => iced_nav_scrollable::scroll_up_to_section(status_section_ix(repo, ix, StatusSectionKind::Untracked),status_nav,),VertDir::Down => iced_nav_scrollable::scroll_down_to_section(status_section_ix(repo, ix, StatusSectionKind::Untracked),status_nav,),};let selection = Selection::UntrackedFile {ix,path: path.clone(),diff_selected: false,};(selection, Task::batch([nav_task, scroll_task]))}pub fn changed_file_selection(repo: &repo::State,status_nav: &NavScrollable,ix: usize,files: &mut file::State,files_diffs: &mut diff::FilesState,dir: VertDir,) -> (Selection, Task<crate::Msg>) {let (path, diffs) = repo.changed_files.iter().nth(ix).unwrap();let id_hash = file::id_parts_hash(path, file::Kind::Changed);let nav_task = match file::try_get_src_file(files, id_hash) {Some(file_diff) => {// If the diff is already loaded init nav for itlet contents_count = diff::contents_count(file_diff);let unchanged_sections = diff::unchanged_sections(file_diff);let (nav, nav_task) =iced_nav_scrollable::init(contents_count, unchanged_sections);files_diffs.diffs_nav = Some((id_hash, nav));nav_task.map(move |msg| {crate::Msg::View(app::Msg::FileDiff {id_hash,msg: diff::Msg::DiffNav(msg),})})}None => {// Nav will be initialize once the diff is loaded// (`crate::Msg::File`)let id = file::Id {path: path.clone(),file_kind: file::Kind::Changed,};if diff::any_diff_has_contents(diffs) {file::load_src_file_if_not_cached(files, id);}Task::none()}};let scroll_task = match dir {VertDir::Up => iced_nav_scrollable::scroll_up_to_section(status_section_ix(repo, ix, StatusSectionKind::Changed),status_nav,),VertDir::Down => iced_nav_scrollable::scroll_down_to_section(status_section_ix(repo, ix, StatusSectionKind::Changed),status_nav,),};let selection = Selection::ChangedFile {ix,path: path.clone(),diff_selected: false,};(selection, Task::batch([nav_task, scroll_task])) - edit in inflorescence/src/cursor.rs at line 1480[44.18661]
fn log_selection(status_nav: &NavScrollable,logs: &mut diff::LogFilesAndState,repo: &repo::State,ix: usize,dir: VertDir,) -> (Selection, Task<crate::Msg>) {let entry = repo.log.get(ix).unwrap();let hash = entry.hash;let nav_task = match logs.change_file_counts.get(&hash) {Some(contents_count) => {// Init log changes navlet (nav, tasks) =iced_nav_scrollable::init(*contents_count, HashSet::new());logs.changes_nav = Some((hash, nav));tasks.map(move |msg| {crate::Msg::View(app::Msg::LogNav { hash, msg })})}None => {// If the log is not loaded yet, the nav will be initialized once// it's loaded (`repo::MsgOut::GotChangeDifs`)Task::done(crate::Msg::View(app::Msg::ToRepo(repo::MsgIn::GetChangeDiffs { hash },)))}};let scroll_task = match dir {VertDir::Up => iced_nav_scrollable::scroll_up_to_section(status_section_ix(repo, ix, StatusSectionKind::Log),status_nav,),VertDir::Down => iced_nav_scrollable::scroll_down_to_section(status_section_ix(repo, ix, StatusSectionKind::Log),status_nav,),};let selection = Selection::LogChange {ix,hash,message: entry.message.clone(),file: None,};(selection, Task::batch([nav_task, scroll_task]))}fn log_file_selection(logs: &mut diff::LogFilesAndState,log_entry: &repo::LogEntry,hash: repo::ChangeHash,file_ix: usize,) -> (LogChangeFileSelection, Task<crate::Msg>) {let path = log_entry.file_paths.get(file_ix).unwrap().clone();let id_hash = file::log_id_parts_hash(hash, &path);let nav_task = match (logs.diffs.get(&id_hash), logs.diffs_nav.as_ref()) {(Some(diff), Some((nav_id_hash, _nav))) if *nav_id_hash != id_hash => {let contents_count = diff::contents_count(&diff.file);// Init log change diff navlet (nav, tasks) =iced_nav_scrollable::init(contents_count, HashSet::new());logs.diffs_nav = Some((id_hash, nav));tasks.map(move |msg| {crate::Msg::View(app::Msg::LogChangeFileDiff {id_hash,msg: diff::Msg::DiffNav(msg),})})}_ => {// If the log is not loaded yet, the nav will be initialized once// it's loaded (`repo::MsgOut::GotChangeDifs`)Task::none()}};(LogChangeFileSelection {ix: file_ix,path,diff_selected: false,},nav_task,)} - edit in iced_utils/src/task/wrappers.rs at line 9
/// Produces a [`Task`] that scrolls the [`scrollable::Scrollable`] with the/// given [`scrollable::Id`] by the provided [`scrollable::AbsoluteOffset`].pub fn scroll_by<T>(id: impl Into<scrollable::Id>,offset: scrollable::AbsoluteOffset,) -> Task<T> {#[cfg(not(any(test, feature = "testing")))]let task = scrollable::scroll_by(id, offset); - edit in iced_utils/src/task/wrappers.rs at line 19
#[cfg(any(test, feature = "testing"))]let task = {let _ = (id, offset);Task::none()};task} - replacement in iced_nav_scrollable/src/lib.rs at line 32
pub offset: f32,pub stored_offset: Option<f32>, - replacement in iced_nav_scrollable/src/lib.rs at line 123
offset: 0.0,stored_offset: None, - replacement in iced_nav_scrollable/src/lib.rs at line 219
nav.offset = viewport.absolute_offset().y;nav.stored_offset = Some(viewport.absolute_offset().y); - edit in iced_nav_scrollable/src/lib.rs at line 225
/// NOTE: call `into_iter()` on the children parameter to make it type-check/// with `ExactSizeIterator`. - replacement in iced_nav_scrollable/src/lib.rs at line 250
task::scroll_to(nav.id.clone(),scrollable::AbsoluteOffset {x: 0.0,y: nav.offset,},)if let Some(y) = nav.stored_offset {task::scroll_to(nav.id.clone(),scrollable::AbsoluteOffset { x: 0.0, y },)} else {Task::none()} - replacement in iced_nav_scrollable/src/lib.rs at line 274
nav.offset + nav.height,nav.stored_offset.unwrap_or_default() + nav.height, - replacement in iced_nav_scrollable/src/lib.rs at line 285
Some((nav.offset + offset_delta, Delay::Start))Some((nav.stored_offset.unwrap_or_default() + offset_delta,Delay::Start,)) - replacement in iced_nav_scrollable/src/lib.rs at line 352
let top_frame = nav.offset + VISIBLE_CONTEXT_HEIGHT;let top_frame = nav.stored_offset.unwrap_or_default()+ VISIBLE_CONTEXT_HEIGHT; - replacement in iced_nav_scrollable/src/lib.rs at line 363
saturating_sub(nav.offset, offset_delta),saturating_sub(nav.stored_offset.unwrap_or_default(),offset_delta,), - replacement in iced_nav_scrollable/src/lib.rs at line 434
nav: &mut NavScrollable,nav: &NavScrollable, - replacement in iced_nav_scrollable/src/lib.rs at line 442
let y = nav.offset + offset_delta;task::scroll_to(nav.id.clone(), scrollable::AbsoluteOffset { x: 0.0, y })task::scroll_by(nav.id.clone(),scrollable::AbsoluteOffset {x: 0.0,y: offset_delta,},) - replacement in iced_nav_scrollable/src/lib.rs at line 453
nav: &mut NavScrollable,nav: &NavScrollable, - replacement in iced_nav_scrollable/src/lib.rs at line 461
let y = saturating_sub(nav.offset, offset_delta);task::scroll_to(nav.id.clone(), scrollable::AbsoluteOffset { x: 0.0, y })task::scroll_by(nav.id.clone(),scrollable::AbsoluteOffset {x: 0.0,y: -offset_delta,},) - replacement in iced_nav_scrollable/src/lib.rs at line 472
nav: &mut NavScrollable,nav: &NavScrollable, - replacement in iced_nav_scrollable/src/lib.rs at line 484
let bottom_frame =saturating_sub(nav.offset + nav.height, VISIBLE_CONTEXT_HEIGHT);let top_frame = nav.offset + VISIBLE_CONTEXT_HEIGHT;let bottom_frame = saturating_sub(nav.stored_offset.unwrap_or_default() + nav.height,VISIBLE_CONTEXT_HEIGHT,);let top_frame =nav.stored_offset.unwrap_or_default() + VISIBLE_CONTEXT_HEIGHT; - replacement in iced_nav_scrollable/src/lib.rs at line 511
nav: &mut NavScrollable,nav: &NavScrollable, - replacement in iced_nav_scrollable/src/lib.rs at line 523
let bottom_frame =saturating_sub(nav.offset + nav.height, VISIBLE_CONTEXT_HEIGHT);let top_frame = nav.offset + VISIBLE_CONTEXT_HEIGHT;let bottom_frame = saturating_sub(nav.stored_offset.unwrap_or_default() + nav.height,VISIBLE_CONTEXT_HEIGHT,);let top_frame =nav.stored_offset.unwrap_or_default() + VISIBLE_CONTEXT_HEIGHT; - replacement in iced_nav_scrollable/src/lib.rs at line 599
if let Some(y) = nav.skip_sections.contains(&0).then(|| nav.section_offsets.get(1)).flatten()if let Some(y) =nav.section_offsets.iter().enumerate().find_map(|(ix, offset)| {(!nav.skip_sections.contains(&ix)).then_some(*offset)}) - replacement in iced_nav_scrollable/src/lib.rs at line 607
let y = saturating_sub(*y, VISIBLE_CONTEXT_HEIGHT);let y = saturating_sub(y, VISIBLE_CONTEXT_HEIGHT);