convert changed file diffs and load src only if any needs it

[?]
Apr 22, 2025, 7:12 PM
Y5ATDI2HRWTTYJAVUR7SVWQVB4ZKKDZF3UVE4JJQFZ7RX7H7VPJQC

Dependencies

  • [2] IQDCHWCP load a pijul repo
  • [3] WT3GA27P add cursor with selection
  • [4] EC3TVL4X add untracked files
  • [5] YBJRDOTC make all repo actions async
  • [6] 4WO3ZJM2 show untracked files' contents
  • [7] BJXUYQ2Y show untracked file contents in read-only text editor
  • [8] CFYW3HGZ wip: display changed files
  • [9] AMPZ2BXK show changed files diffs (only Edit atm)
  • [10] NOB64XMR fmt and clippy
  • [11] AXSXZQDG fix updating changed file contents, styling
  • [12] RPCIGCNS add replacement diff details
  • [13] V55EAIWQ add src file LRU cache
  • [14] NRCUG4R2 load changed files src when selected
  • [15] SWWE2R6M display basic repo stuff
  • [16] W7IUT3ZV start recording impl
  • [17] D7A7MSIH allow to defer or abandon record, add buttons
  • [18] 6YZAVBWU Initial commit
  • [19] PTFDJ567 add untracked files encoding
  • [20] KT5UYXGK fix selection after adding file, add changed file diffs
  • [21] S2NVIFXR allow to enter record msg

Change contents

  • replacement in crates/flowers_ui/src/main.rs at line 143
    [13.1195][13.1195:1242]()
    let key_weight = key.as_bytes().len();
    [13.1195]
    [13.1242]
    let key_weight = key.len();
  • replacement in crates/flowers_ui/src/main.rs at line 147
    [13.1398][13.1398:1647]()
    FileEditorContent::Decoded(content) => {
    content.text().as_bytes().len()
    }
    FileEditorContent::ShortBase64(string) => {
    string.as_bytes().len()
    }
    [13.1398]
    [13.1647]
    FileEditorContent::Decoded(content) => content.text().len(),
    FileEditorContent::ShortBase64(string) => string.len(),
  • replacement in crates/flowers_ui/src/main.rs at line 168
    [14.75][14.75:134]()
    type ChangedFileContents = Vec<Option<FileEditorContent>>;
    [14.75]
    [14.134]
    type ChangedFileContents = Vec<ChangedFileDiff>;
    #[derive(Debug)]
    enum ChangedFileDiff {
    WithContents(ChangedFileDiffWithContents),
    WithoutContents(ChangedFileDiffWithoutContents),
    }
  • replacement in crates/flowers_ui/src/main.rs at line 182
    [13.1908][13.1908:1944]()
    content: FileEditorContent,
    [13.1908]
    [13.1944]
    contents: FileEditorContent,
  • replacement in crates/flowers_ui/src/main.rs at line 265
    [5.6557][14.175:615]()
    let changed_file_selection = |repo: &repo::State,
    ix: usize,
    src_files_cache: &mut SrcFilesCache,
    src_file_load_tx: &watch::Sender<String>|
    -> cursor::Selection {
    let path = repo
    .changed_files
    .iter()
    .nth(ix)
    .map(|(k, _v)| k)
    .unwrap()
    .clone();
    [5.6557]
    [14.615]
    let changed_file_selection =
    |changed_files_contents: &ChangedFilesContents,
    ix: usize,
    src_files_cache: &mut SrcFilesCache,
    src_file_load_tx: &watch::Sender<String>|
    -> cursor::Selection {
    let (path, diffs) = changed_files_contents.iter().nth(ix).unwrap();
  • replacement in crates/flowers_ui/src/main.rs at line 273
    [14.616][14.616:695]()
    load_src_file_if_not_cached(src_files_cache, src_file_load_tx, &path);
    [14.616]
    [4.2511]
    if any_diff_has_contents(diffs) {
    load_src_file_if_not_cached(
    src_files_cache,
    src_file_load_tx,
    path,
    );
    }
  • replacement in crates/flowers_ui/src/main.rs at line 281
    [4.2512][14.696:755]()
    cursor::Selection::ChangedFile { ix, path }
    };
    [4.2512]
    [14.755]
    cursor::Selection::ChangedFile {
    ix,
    path: path.clone(),
    }
    };
  • replacement in crates/flowers_ui/src/main.rs at line 324
    [14.817][14.817:863]()
    repo,
    [14.817]
    [14.863]
    &state.changed_files_contents,
  • replacement in crates/flowers_ui/src/main.rs at line 351
    [14.1135][14.1135:1177]()
    repo,
    [14.1135]
    [14.1177]
    &state.changed_files_contents,
  • replacement in crates/flowers_ui/src/main.rs at line 368
    [14.1429][14.1429:1467]()
    repo,
    [14.1429]
    [14.1467]
    &state.changed_files_contents,
  • replacement in crates/flowers_ui/src/main.rs at line 383
    [14.1712][14.1712:1754]()
    repo,
    [14.1712]
    [14.1754]
    &state.changed_files_contents,
  • replacement in crates/flowers_ui/src/main.rs at line 419
    [14.2011][14.2011:2053]()
    repo,
    [14.2011]
    [14.2053]
    &state.changed_files_contents,
  • replacement in crates/flowers_ui/src/main.rs at line 441
    [14.2309][14.2309:2351]()
    repo,
    [14.2309]
    [14.2351]
    &state.changed_files_contents,
  • replacement in crates/flowers_ui/src/main.rs at line 458
    [14.2603][14.2603:2641]()
    repo,
    [14.2603]
    [14.2641]
    &state.changed_files_contents,
  • replacement in crates/flowers_ui/src/main.rs at line 482
    [14.2882][14.2882:2920]()
    repo,
    [14.2882]
    [14.2920]
    &state.changed_files_contents,
  • replacement in crates/flowers_ui/src/main.rs at line 503
    [14.3391][13.4041:4244](),[6.5889][13.4041:4244]()
    load_src_file_if_not_cached(
    &mut state.src_files_cache,
    &state.src_file_load_tx,
    path,
    );
    [14.3391]
    [6.6157]
    let diffs = state.changed_files_contents.get(path).unwrap();
    if any_diff_has_contents(diffs) {
    load_src_file_if_not_cached(
    &mut state.src_files_cache,
    &state.src_file_load_tx,
    path,
    );
    }
  • replacement in crates/flowers_ui/src/main.rs at line 593
    [14.3453][14.3453:3495]()
    repo,
    [14.3453]
    [14.3495]
    &state.changed_files_contents,
  • replacement in crates/flowers_ui/src/main.rs at line 746
    [9.2313][9.2313:2705]()
    if let Some(content) = contents.get_mut(ix) {
    match content {
    Some(FileEditorContent::Decoded(content)) => {
    content.perform(action);
    }
    _ => panic!("Unexpected content: {content:?}"),
    }
    }
    [9.2313]
    [7.1071]
    todo!()
    // if let Some(content) = contents.get_mut(ix) {
    // match content {
    // Some(FileEditorContent::Decoded(content)) => {
    // content.perform(action);
    // }
    // _ => panic!("Unexpected content: {content:?}"),
    // }
    // }
  • replacement in crates/flowers_ui/src/main.rs at line 823
    [13.5472][13.5472:5507]()
    &path,
    [13.5472]
    [13.5507]
    path,
  • replacement in crates/flowers_ui/src/main.rs at line 838
    [14.3768][14.3768:3992]()
    load_src_file_if_not_cached(
    &mut state.src_files_cache,
    &state.src_file_load_tx,
    &path,
    );
    [14.3768]
    [14.3992]
    let diffs =
    state.changed_files_contents.get(path).unwrap();
    if any_diff_has_contents(diffs) {
    load_src_file_if_not_cached(
    &mut state.src_files_cache,
    &state.src_file_load_tx,
    path,
    );
    }
  • replacement in crates/flowers_ui/src/main.rs at line 875
    [9.3090][9.3090:3784](),[9.3784][12.1410:1714](),[12.1714][9.3848:4229](),[9.3848][9.3848:4229]()
    let contents = diffs
    .iter()
    .map(|diff| match diff {
    repo::ChangedFileDiff::Move => None,
    repo::ChangedFileDiff::Del => None,
    repo::ChangedFileDiff::Undel => None,
    repo::ChangedFileDiff::Add => None,
    repo::ChangedFileDiff::SolveNameConflict => None,
    repo::ChangedFileDiff::UnsolveNameConflict => None,
    repo::ChangedFileDiff::Edit {
    line: _,
    deleted: _,
    contents,
    } => Some(contents_to_file_editor_content(contents)),
    // TODO: there are 2 contents! Maybe make the `ChangedFileContents` an enum
    repo::ChangedFileDiff::Replacement {
    line: _,
    change_contents,
    replacement_contents,
    } => None,
    repo::ChangedFileDiff::SolveOrderConflict => None,
    repo::ChangedFileDiff::UnsolveOrderConflict => None,
    repo::ChangedFileDiff::ResurrectZombines => None,
    repo::ChangedFileDiff::AddRoot => None,
    repo::ChangedFileDiff::DelRoot => None,
    })
    .collect();
    [9.3090]
    [9.4229]
    let contents =
    diffs.iter().map(changed_file_diff_from_repo).collect();
  • edit in crates/flowers_ui/src/main.rs at line 882
    [9.4299]
    [9.4299]
    fn changed_file_diff_from_repo(
    value: &repo::ChangedFileDiff,
    ) -> ChangedFileDiff {
    match value {
    repo::ChangedFileDiff::Move => ChangedFileDiff::WithoutContents(
    ChangedFileDiffWithoutContents::Move,
    ),
    repo::ChangedFileDiff::Del => ChangedFileDiff::WithoutContents(
    ChangedFileDiffWithoutContents::Del,
    ),
    repo::ChangedFileDiff::Undel => ChangedFileDiff::WithoutContents(
    ChangedFileDiffWithoutContents::Undel,
    ),
    repo::ChangedFileDiff::Add => {
    ChangedFileDiff::WithContents(ChangedFileDiffWithContents::Add)
    }
    repo::ChangedFileDiff::SolveNameConflict => {
    ChangedFileDiff::WithoutContents(
    ChangedFileDiffWithoutContents::SolveNameConflict,
    )
    }
    repo::ChangedFileDiff::UnsolveNameConflict => {
    ChangedFileDiff::WithoutContents(
    ChangedFileDiffWithoutContents::UnsolveNameConflict,
    )
    }
    repo::ChangedFileDiff::Edit {
    line,
    deleted,
    contents,
    } => ChangedFileDiff::WithContents(ChangedFileDiffWithContents::Edit {
    line: *line,
    deleted: *deleted,
    contents: contents_to_file_editor_content(contents),
    }),
    repo::ChangedFileDiff::Replacement {
    line,
    change_contents,
    replacement_contents,
    } => ChangedFileDiff::WithContents(
    ChangedFileDiffWithContents::Replacement {
    line: *line,
    change_contents: contents_to_file_editor_content(
    change_contents,
    ),
    replacement_contents: contents_to_file_editor_content(
    replacement_contents,
    ),
    },
    ),
    repo::ChangedFileDiff::SolveOrderConflict => {
    ChangedFileDiff::WithoutContents(
    ChangedFileDiffWithoutContents::SolveOrderConflict,
    )
    }
    repo::ChangedFileDiff::UnsolveOrderConflict => {
    ChangedFileDiff::WithoutContents(
    ChangedFileDiffWithoutContents::UnsolveOrderConflict,
    )
    }
    repo::ChangedFileDiff::ResurrectZombines => {
    ChangedFileDiff::WithoutContents(
    ChangedFileDiffWithoutContents::ResurrectZombines,
    )
    }
    repo::ChangedFileDiff::AddRoot => ChangedFileDiff::WithoutContents(
    ChangedFileDiffWithoutContents::AddRoot,
    ),
    repo::ChangedFileDiff::DelRoot => ChangedFileDiff::WithoutContents(
    ChangedFileDiffWithoutContents::DelRoot,
    ),
    }
    }
  • edit in crates/flowers_ui/src/main.rs at line 1048
    [13.6468]
    [2.1456]
    /// Returns true if any of the changed file's diffs has contents
    fn any_diff_has_contents(changed_file: &ChangedFileContents) -> bool {
    changed_file
    .iter()
    .any(|diff| matches!(diff, ChangedFileDiff::WithContents(_)))
    }
  • replacement in crates/flowers_ui/src/main.rs at line 1141
    [6.9353][8.23:90](),[8.90][9.4765:5261]()
    Some(cursor::Selection::ChangedFile { path, ix }) => {
    let (file_name, diffs) =
    repo.changed_files.iter().nth(*ix).unwrap();
    let file_editor_contents =
    state.changed_files_contents.get(file_name).unwrap();
    let diffs = diffs.iter().enumerate().map(|(ix, diff)| {
    let file_editor_content =
    file_editor_contents.get(ix).unwrap();
    view_diff(diff, file_editor_content, file_name, ix)
    });
    [6.9353]
    [8.364]
    Some(cursor::Selection::ChangedFile { path, ix: _ }) => {
    let diffs = state.changed_files_contents.get(path).unwrap();
    let _src_file_contents: Option<text_editor::Content> =
    if any_diff_has_contents(diffs) {
    // TODO: load file contents from cache
    None
    } else {
    None
    };
    let diffs = [el(text("TODO"))];
  • edit in crates/flowers_ui/src/main.rs at line 1184
    [3.4175][9.5597:5696](),[9.5696][10.332:351](),[10.351][9.5718:5761](),[9.5718][9.5718:5761](),[9.5761][11.612:686](),[11.686][9.5781:5975](),[9.5781][9.5781:5975](),[9.5975][10.352:395](),[10.395][9.6015:6297](),[9.6015][9.6015:6297](),[9.6297][11.687:743](),[11.743][9.6303:6306](),[9.6303][9.6303:6306]()
    fn view_diff<'a>(
    diff: &'a repo::ChangedFileDiff,
    content: &'a Option<FileEditorContent>,
    file: &'a str,
    ix: usize,
    ) -> Element<'a, Message> {
    let change_type = diff.to_string();
    let content = match content {
    Some(content) => match content {
    FileEditorContent::Decoded(content) => el(text_editor(content)
    .on_action(move |action| Message::ChangedFileContentsAction {
    file: file.to_owned(),
    ix,
    action,
    })),
    FileEditorContent::ShortBase64(short) => el(text(short)),
    FileEditorContent::UnknownEncoding => el(text(format!("{diff:?}"))),
    },
    None => el(text(format!("{diff:?}"))),
    };
    el(column([el(text(change_type)), content]))
    }