woot contents_diff
[?]
May 1, 2025, 7:27 AM
ZVI4AWERNOTDJ3765HJXRBZT57XPNKVONQ6TGOGNPOL2VN42KMJQCDependencies
- [2]
WT3GA27Padd cursor with selection - [3]
UB2ITZJSrefresh changed files on FS changes - [4]
EC3TVL4Xadd untracked files - [5]
KT5UYXGKfix selection after adding file, add changed file diffs - [6]
ELG3UDT6allow to rm added files - [7]
S2NVIFXRallow to enter record msg - [8]
W7IUT3ZVstart recording impl - [9]
YBJRDOTCmake all repo actions async - [10]
KM5PSZ4Awatch repo once loaded - [11]
2VUX5BTDload identity - [12]
D7A7MSIHallow to defer or abandon record, add buttons - [13]
4WO3ZJM2show untracked files' contents - [14]
BJXUYQ2Yshow untracked file contents in read-only text editor - [15]
W4LFX7IHgroup diffs by file name - [16]
PTFDJ567add untracked files encoding - [17]
AMPZ2BXKshow changed files diffs (only Edit atm) - [18]
NOB64XMRfmt and clippy - [19]
AXSXZQDGfix updating changed file contents, styling - [20]
V55EAIWQadd src file LRU cache - [21]
NRCUG4R2load changed files src when selected - [22]
Y5ATDI2Hconvert changed file diffs and load src only if any needs it - [23]
YBLPPHZNshow contents for move, del and undel - [24]
UMO6U2ZTpartition the change files diffs on whether they have content - [25]
B4RMW5AEadd syntax highlighter to untracked files contents - [26]
MJDGPSHGWIP contents diff - [27]
A5YBC77Vrecord! - [28]
FDDPOH5Radd arrow controls - [29]
SWWE2R6Mdisplay basic repo stuff - [30]
ZONPDYO7wrap untracked files' contents on word or glyph - [31]
IQDCHWCPload a pijul repo - [32]
UCBNZULEmake changed files paths optional (no path for root) - [33]
6YZAVBWUInitial commit - [34]
DVKSPF7Rtrack selected file path together with an index - [35]
CFYW3HGZwip: display changed files
Change contents
- replacement in crates/libflowers_client/src/repo.rs at line 79
diff_line(self).zip(diff_line(other)).map(|(left, right)| left.cmp(&right))Some(self.cmp(other)) - edit in crates/inflorescence/src/main.rs at line 5
use std::collections::BTreeMap; - replacement in crates/inflorescence/src/main.rs at line 8
use std::{cmp, ffi};use std::{cmp, mem}; - edit in crates/inflorescence/src/main.rs at line 12
use libflowers_client::repo::MAX_LEN_BASE64_DISPLAY; - replacement in crates/inflorescence/src/main.rs at line 17
font, highlighter, Border, Color, Element, Font, Length, Subscription,Task, Theme,font, Border, Color, Element, Font, Length, Subscription, Task, Theme, - replacement in crates/inflorescence/src/main.rs at line 75
let (src_file_load_tx, src_file_load_rx) = watch::channel("".to_string());let untracked_file_load_rx = WatchStream::from_changes(src_file_load_rx);let (src_file_load_tx, src_file_load_rx) = watch::channel((FileId {path: "".to_string(),file_kind: FileKind::Untracked,},0,));let src_file_load_rx = WatchStream::from_changes(src_file_load_rx); - replacement in crates/inflorescence/src/main.rs at line 84
let untracked_file_load_task = Task::run(untracked_file_load_rx.map(move |file_path| (repo_path_clone.clone(), file_path)).then(|(repo_path, file_path)| async {load_src_file(repo_path, file_path).awaitlet src_file_load_task = Task::run(src_file_load_rx.map(move |(id, cache_counter): (FileId, usize)| {(repo_path_clone.clone(), id, cache_counter)}).then(|(repo_path, id, cache_counter)| async move {load_src_file(repo_path, id, cache_counter).await - edit in crates/inflorescence/src/main.rs at line 97
let diffs_cache = DiffsCache {counter: 0,inner: DiffsCacheInner::with_scale(src_files_cache_capacity,DiffsCacheWeight,),}; - replacement in crates/inflorescence/src/main.rs at line 109
untracked_file_load_task,src_file_load_task, - edit in crates/inflorescence/src/main.rs at line 111
- edit in crates/inflorescence/src/main.rs at line 121
src_files_cache: CLruCache::with_scale(src_files_cache_capacity,SrcFileCacheWeight,), - replacement in crates/inflorescence/src/main.rs at line 122
changed_files_contents: BTreeMap::default(),diffs_cache, - replacement in crates/inflorescence/src/main.rs at line 137
src_files_cache: SrcFilesCache,src_file_load_tx: watch::Sender<String>,/// Keyed by file name matching `repo::ChangedFiles`changed_files_contents: ChangedFilesContents,src_file_load_tx: watch::Sender<(FileId, usize)>,diffs_cache: DiffsCache, - edit in crates/inflorescence/src/main.rs at line 140
type SrcFilesCache =CLruCache<String, SrcFile, std::hash::RandomState, SrcFileCacheWeight>; - replacement in crates/inflorescence/src/main.rs at line 142
enum SrcFile {Loading,Loaded(FileEditorContent),struct DiffsCache {/// Used to prevent race-conditions between file loading and clearing cachecounter: usize,inner: DiffsCacheInner, - replacement in crates/inflorescence/src/main.rs at line 148
#[derive(Debug)]struct SrcFileCacheWeight;type DiffsCacheInner =CLruCache<FileId, FileDiff, std::hash::RandomState, DiffsCacheWeight>; - replacement in crates/inflorescence/src/main.rs at line 151[20.1073]→[20.1073:1195](∅→∅),[20.1195]→[22.22:58](∅→∅),[22.58]→[20.1242:1398](∅→∅),[20.1242]→[20.1242:1398](∅→∅),[20.1398]→[22.59:208](∅→∅),[22.208]→[20.1647:1770](∅→∅),[20.1647]→[20.1647:1770](∅→∅)
impl WeightScale<String, SrcFile> for SrcFileCacheWeight {fn weight(&self, key: &String, value: &SrcFile) -> usize {let key_weight = key.len();let value_weight = match value {SrcFile::Loading => 0,SrcFile::Loaded(file_editor_content) => match file_editor_content {FileEditorContent::Decoded(content) => content.text().len(),FileEditorContent::ShortBase64(string) => string.len(),FileEditorContent::UnknownEncoding => 0,},};key_weight + value_weight}#[derive(Debug)]enum FileDiff {Loading,Loaded(contents_diff::File), - replacement in crates/inflorescence/src/main.rs at line 157[20.1773]→[20.1773:1790](∅→∅),[13.2723]→[16.262:322](∅→∅),[16.322]→[18.160:297](∅→∅),[18.297]→[16.459:505](∅→∅),[16.459]→[16.459:505](∅→∅)
#[derive(Debug)]enum FileEditorContent {Decoded(text_editor::Content),/// Short byte sequence of unknown encoding encoded with base64 for/// display. Must be shorter than [`MAX_LEN_BASE64_DISPLAY`]ShortBase64(String),UnknownEncoding,#[derive(Debug, Clone, Hash, PartialEq, Eq)]struct FileId {path: String,file_kind: FileKind, - edit in crates/inflorescence/src/main.rs at line 162
type ChangedFilesContents = BTreeMap<String, ChangedFileContents>; - replacement in crates/inflorescence/src/main.rs at line 164
struct ChangedFileContents {with_contents: Vec<ChangedFileDiffWithContents>,without_contents: Vec<ChangedFileDiffWithoutContents>,}struct DiffsCacheWeight; - replacement in crates/inflorescence/src/main.rs at line 166[21.135]→[20.1792:1908](∅→∅),[20.1792]→[20.1792:1908](∅→∅),[20.1908]→[22.402:439](∅→∅),[22.439]→[20.1944:2139](∅→∅),[20.1944]→[20.1944:2139](∅→∅),[20.2139]→[23.22:42](∅→∅)
#[derive(Debug)]enum ChangedFileDiffWithContents {Add,Edit {line: usize,deleted: bool,contents: FileEditorContent,},Replacement {line: usize,/// Deleted linechange_contents: FileEditorContent,/// Added linesreplacement_contents: FileEditorContent,},Del,Undel,impl WeightScale<FileId, FileDiff> for DiffsCacheWeight {fn weight(&self, key: &FileId, value: &FileDiff) -> usize {let key_weight = key.path.len();let val_weight = match value {FileDiff::Loading => 0,FileDiff::Loaded(file) => match file {contents_diff::File::Decoded(contents_diff::DecodedFile {combined:contents_diff::Combined {sections,max_line_num: _,},diffs_without_contents,}) => {mem::size_of_val(sections)+ mem::size_of::<usize>()+ mem::size_of_val(diffs_without_contents)}contents_diff::File::Undecodable(contents_diff::UndecodableFile {diffs_with_contents,diffs_without_contents,},) => {mem::size_of_val(diffs_with_contents)+ mem::size_of_val(diffs_without_contents)}},};key_weight + val_weight} - replacement in crates/inflorescence/src/main.rs at line 199[20.2142]→[20.2142:2159](∅→∅),[20.2159]→[21.136:174](∅→∅),[21.174]→[26.1341:1351](∅→∅),[26.1351]→[20.2231:2378](∅→∅),[20.2231]→[20.2231:2378](∅→∅)
#[derive(Debug)]enum ChangedFileDiffWithoutContents {Move,SolveNameConflict,UnsolveNameConflict,SolveOrderConflict,UnsolveOrderConflict,ResurrectZombines,AddRoot,DelRoot,#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]enum FileKind {Untracked,Changed, - replacement in crates/inflorescence/src/main.rs at line 224
CursorSelect(cursor::Selection),CursorSelect(cursor::Select), - replacement in crates/inflorescence/src/main.rs at line 233
path: String,/// The cache counter value when the file was requestedcache_counter: usize,id: FileId, - edit in crates/inflorescence/src/main.rs at line 238
},UntrackedFileContentsAction {path: String,action: text_editor::Action, - replacement in crates/inflorescence/src/main.rs at line 239
ChangedFileContentsAction {file: String,ix: usize,action: text_editor::Action,FileDiffsContentsAction {id: FileId,action: contents_diff::Msg, - replacement in crates/inflorescence/src/main.rs at line 246
let untracked_file_selection = |repo: &repo::State,ix: usize,src_files_cache: &mut SrcFilesCache,src_file_load_tx: &watch::Sender<String,>|-> cursor::Selection {let path = repo.untracked_files.iter().nth(ix).unwrap().clone();let untracked_file_selection =|repo: &repo::State,ix: usize,diffs_cache: &mut DiffsCache,src_file_load_tx: &watch::Sender<(FileId, usize)>|-> cursor::Selection {let path = repo.untracked_files.iter().nth(ix).unwrap().clone(); - replacement in crates/inflorescence/src/main.rs at line 254
load_src_file_if_not_cached(src_files_cache, src_file_load_tx, &path);let id = FileId {path: path.clone(),file_kind: FileKind::Untracked,};load_src_file_if_not_cached(diffs_cache, src_file_load_tx, id); - replacement in crates/inflorescence/src/main.rs at line 260
cursor::Selection::UntrackedFile { ix, path }};cursor::Selection::UntrackedFile {ix,path,diffs: contents_diff::State::default(),}}; - replacement in crates/inflorescence/src/main.rs at line 268
|changed_files_contents: &ChangedFilesContents,|repo: &repo::State, - replacement in crates/inflorescence/src/main.rs at line 270
src_files_cache: &mut SrcFilesCache,src_file_load_tx: &watch::Sender<String>|diffs_cache: &mut DiffsCache,src_file_load_tx: &watch::Sender<(FileId, usize)>| - replacement in crates/inflorescence/src/main.rs at line 273
let (path, diffs) = changed_files_contents.iter().nth(ix).unwrap();let (path, diffs) = repo.changed_files.iter().nth(ix).unwrap(); - replacement in crates/inflorescence/src/main.rs at line 276
load_src_file_if_not_cached(src_files_cache,src_file_load_tx,path,);let id = FileId {path: path.clone(),file_kind: FileKind::Changed,};load_src_file_if_not_cached(diffs_cache, src_file_load_tx, id); - edit in crates/inflorescence/src/main.rs at line 286
diffs: contents_diff::State::default(), - replacement in crates/inflorescence/src/main.rs at line 310
state.cursor.selection = match state.cursor.selection.as_ref() {Some(cursor::Selection::UntrackedFile { ix, path: _ }) => {let new_selection =if repo.untracked_files.len().saturating_sub(1)== *ix{if repo.changed_files.is_empty() {let ix = 0;state.cursor.selection =match state.cursor.selection.as_ref() {Some(cursor::Selection::UntrackedFile {ix,path: _,diffs: _,}) => {let new_selection =if repo.untracked_files.len().saturating_sub(1)== *ix{if repo.changed_files.is_empty() {let ix = 0;untracked_file_selection(repo,ix,&mut state.diffs_cache,&state.src_file_load_tx,)} else {let ix = 0;changed_file_selection(repo,ix,&mut state.diffs_cache,&state.src_file_load_tx,)}} else {let ix = ix + 1; - replacement in crates/inflorescence/src/main.rs at line 343
&mut state.src_files_cache,&mut state.diffs_cache, - edit in crates/inflorescence/src/main.rs at line 346
};Some(new_selection)}Some(cursor::Selection::ChangedFile {ix,path: _,diffs: _,}) => {let new_selection =if repo.changed_files.len().saturating_sub(1)== *ix{if repo.untracked_files.is_empty() {let ix = 0;changed_file_selection(repo,ix,&mut state.diffs_cache,&state.src_file_load_tx,)} else {let ix = 0;untracked_file_selection(repo,ix,&mut state.diffs_cache,&state.src_file_load_tx,)} - replacement in crates/inflorescence/src/main.rs at line 376
let ix = 0;let ix = ix + 1; - replacement in crates/inflorescence/src/main.rs at line 378
&state.changed_files_contents,repo, - replacement in crates/inflorescence/src/main.rs at line 380
&mut state.src_files_cache,&mut state.diffs_cache, - edit in crates/inflorescence/src/main.rs at line 383
};Some(new_selection)}None => {if repo.untracked_files.is_empty() {if repo.changed_files.is_empty() {None} else {let ix = 0;Some(changed_file_selection(repo,ix,&mut state.diffs_cache,&state.src_file_load_tx,)) - edit in crates/inflorescence/src/main.rs at line 400[9.7861]→[9.7861:7910](∅→∅),[9.7910]→[13.3592:3732](∅→∅),[13.3732]→[20.3175:3300](∅→∅),[20.3300]→[13.3871:3905](∅→∅),[13.3871]→[13.3871:3905](∅→∅),[13.3905]→[9.7977:8329](∅→∅),[9.7977]→[9.7977:8329](∅→∅),[9.8329]→[4.4037:4098](∅→∅),[4.4037]→[4.4037:4098](∅→∅),[4.4098]→[9.8330:8395](∅→∅)
let ix = ix + 1;untracked_file_selection(repo,ix,&mut state.src_files_cache,&state.src_file_load_tx,)};Some(new_selection)}Some(cursor::Selection::ChangedFile { ix, path: _ }) => {let new_selection = if repo.changed_files.len().saturating_sub(1)== *ix{if repo.untracked_files.is_empty() { - replacement in crates/inflorescence/src/main.rs at line 401[4.4211]→[21.1079:1135](∅→∅),[21.1135]→[22.1184:1251](∅→∅),[22.1251]→[21.1177:1376](∅→∅),[21.1177]→[21.1177:1376](∅→∅),[21.1376]→[4.4272:4353](∅→∅),[5.5426]→[4.4272:4353](∅→∅),[9.8461]→[4.4272:4353](∅→∅),[4.4272]→[4.4272:4353](∅→∅),[4.4353]→[13.3906:3964](∅→∅)
changed_file_selection(&state.changed_files_contents,ix,&mut state.src_files_cache,&state.src_file_load_tx,)} else {let ix = 0;untracked_file_selection(Some(untracked_file_selection( - edit in crates/inflorescence/src/main.rs at line 403[13.4006]→[13.4006:4046](∅→∅),[13.4046]→[20.3301:3426](∅→∅),[20.3426]→[13.4185:4219](∅→∅),[13.4185]→[13.4185:4219](∅→∅),[13.4219]→[4.4412:4442](∅→∅),[5.5493]→[4.4412:4442](∅→∅),[9.8529]→[4.4412:4442](∅→∅),[4.4412]→[4.4412:4442](∅→∅),[4.4442]→[2.1067:1100](∅→∅),[2.1067]→[2.1067:1100](∅→∅),[2.1100]→[4.4443:4488](∅→∅),[4.4488]→[21.1377:1429](∅→∅),[21.1429]→[22.1252:1315](∅→∅),[22.1315]→[21.1467:1650](∅→∅),[21.1467]→[21.1467:1650](∅→∅),[21.1650]→[4.4545:4572](∅→∅),[5.5558]→[4.4545:4572](∅→∅),[9.8591]→[4.4545:4572](∅→∅),[4.4545]→[4.4545:4572](∅→∅),[4.4572]→[9.8592:8849](∅→∅),[5.5625]→[4.4919:5000](∅→∅),[9.8849]→[4.4919:5000](∅→∅),[4.4919]→[4.4919:5000](∅→∅),[4.5000]→[21.1651:1712](∅→∅),[21.1712]→[22.1316:1383](∅→∅)
ix,&mut state.src_files_cache,&state.src_file_load_tx,)}} else {let ix = ix + 1;changed_file_selection(&state.changed_files_contents,ix,&mut state.src_files_cache,&state.src_file_load_tx,)};Some(new_selection)}None => {if repo.untracked_files.is_empty() {if repo.changed_files.is_empty() {None} else {let ix = 0;Some(changed_file_selection(&state.changed_files_contents, - replacement in crates/inflorescence/src/main.rs at line 404
&mut state.src_files_cache,&mut state.diffs_cache, - edit in crates/inflorescence/src/main.rs at line 408[4.5419]→[4.5419:5492](∅→∅),[4.5492]→[13.4220:4353](∅→∅),[13.4353]→[20.3427:3544](∅→∅),[20.3544]→[13.4484:4515](∅→∅),[13.4484]→[13.4484:4515](∅→∅)
} else {let ix = 0;Some(untracked_file_selection(repo,ix,&mut state.src_files_cache,&state.src_file_load_tx,)) - replacement in crates/inflorescence/src/main.rs at line 409[4.5678]→[2.1573:1595](∅→∅),[5.5893]→[2.1573:1595](∅→∅),[2.1573]→[2.1573:1595](∅→∅),[2.1595]→[9.8992:9011](∅→∅)
}};}; - replacement in crates/inflorescence/src/main.rs at line 416
Some(cursor::Selection::UntrackedFile { ix, path: _ }) => {Some(cursor::Selection::UntrackedFile {ix,path: _,diffs: _,}) => { - replacement in crates/inflorescence/src/main.rs at line 427
&mut state.src_files_cache,&mut state.diffs_cache, - replacement in crates/inflorescence/src/main.rs at line 433
&state.changed_files_contents,repo, - replacement in crates/inflorescence/src/main.rs at line 435
&mut state.src_files_cache,&mut state.diffs_cache, - replacement in crates/inflorescence/src/main.rs at line 444
&mut state.src_files_cache,&mut state.diffs_cache, - replacement in crates/inflorescence/src/main.rs at line 450
Some(cursor::Selection::ChangedFile { ix, path: _ }) => {Some(cursor::Selection::ChangedFile {ix,path: _,diffs: _,}) => { - replacement in crates/inflorescence/src/main.rs at line 459
&state.changed_files_contents,repo, - replacement in crates/inflorescence/src/main.rs at line 461
&mut state.src_files_cache,&mut state.diffs_cache, - replacement in crates/inflorescence/src/main.rs at line 469
&mut state.src_files_cache,&mut state.diffs_cache, - replacement in crates/inflorescence/src/main.rs at line 476
&state.changed_files_contents,repo, - replacement in crates/inflorescence/src/main.rs at line 478
&mut state.src_files_cache,&mut state.diffs_cache, - replacement in crates/inflorescence/src/main.rs at line 493
&mut state.src_files_cache,&mut state.diffs_cache, - replacement in crates/inflorescence/src/main.rs at line 500
&state.changed_files_contents,repo, - replacement in crates/inflorescence/src/main.rs at line 502
&mut state.src_files_cache,&mut state.diffs_cache, - replacement in crates/inflorescence/src/main.rs at line 511
Message::CursorSelect(selection) => {match &selection {cursor::Selection::UntrackedFile { path, .. } => {Message::CursorSelect(select) => {let selection = match select {cursor::Select::UntrackedFile { ix, path } => { - replacement in crates/inflorescence/src/main.rs at line 515
&mut state.src_files_cache,&mut state.diffs_cache, - replacement in crates/inflorescence/src/main.rs at line 517
path,FileId {path: path.clone(),file_kind: FileKind::Untracked,}, - edit in crates/inflorescence/src/main.rs at line 522
cursor::Selection::UntrackedFile {ix,path,diffs: contents_diff::State::default(),} - replacement in crates/inflorescence/src/main.rs at line 528
cursor::Selection::ChangedFile { path, .. } => {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,);cursor::Select::ChangedFile { ix, path } => {if let Some(diffs) = state.repo.as_ref().and_then(|repo| repo.changed_files.get(&path)){if any_diff_has_contents(diffs) {load_src_file_if_not_cached(&mut state.diffs_cache,&state.src_file_load_tx,FileId {path: path.clone(),file_kind: FileKind::Changed,},);}}cursor::Selection::ChangedFile {ix,path,diffs: contents_diff::State::default(), - replacement in crates/inflorescence/src/main.rs at line 551
}}; - replacement in crates/inflorescence/src/main.rs at line 557
if let Some(cursor::Selection::UntrackedFile { ix, path }) =state.cursor.selection.as_ref()if let Some(cursor::Selection::UntrackedFile {ix,path,diffs: _,}) = state.cursor.selection.as_ref() - edit in crates/inflorescence/src/main.rs at line 580
state.changed_files_contents =changed_files_contents(&repo.changed_files); - replacement in crates/inflorescence/src/main.rs at line 589
&mut state.src_files_cache,&mut state.diffs_cache, - replacement in crates/inflorescence/src/main.rs at line 599
if let Some(cursor::Selection::ChangedFile { ix, path }) =state.cursor.selection.as_ref()if let Some(cursor::Selection::ChangedFile {ix,path,diffs: _,}) = state.cursor.selection.as_ref() - edit in crates/inflorescence/src/main.rs at line 619
state.changed_files_contents.remove(path); - replacement in crates/inflorescence/src/main.rs at line 635
&state.changed_files_contents,repo, - replacement in crates/inflorescence/src/main.rs at line 637
&mut state.src_files_cache,&mut state.diffs_cache, - edit in crates/inflorescence/src/main.rs at line 700
state.changed_files_contents = BTreeMap::default(); - replacement in crates/inflorescence/src/main.rs at line 730
path,cache_counter,id, - replacement in crates/inflorescence/src/main.rs at line 735
let content = match encoding {Some(encoding) => {let decoded = encoding.decode(&data);FileEditorContent::Decoded(text_editor::Content::with_text(&decoded,))}None => {if data.len() <= MAX_LEN_BASE64_DISPLAY {let encoded =format!("b{}", data_encoding::BASE64.encode(&data));FileEditorContent::ShortBase64(encoded)} else {FileEditorContent::UnknownEncodingif state.diffs_cache.counter == cache_counter {let file_content = match encoding {Some(encoding) => {let decoded = encoding.decode(&data);contents_diff::FileContent::Decoded(decoded) - replacement in crates/inflorescence/src/main.rs at line 741[16.1433]→[16.1433:1466](∅→∅),[16.1466]→[20.4389:4703](∅→∅),[20.4703]→[13.7310:7355](∅→∅),[13.7310]→[13.7310:7355](∅→∅),[13.7355]→[14.663:712](∅→∅),[14.712]→[20.4704:4771](∅→∅),[20.4771]→[14.770:830](∅→∅),[14.770]→[14.770:830](∅→∅),[14.830]→[20.4772:4956](∅→∅),[20.4956]→[14.1003:1021](∅→∅),[14.1003]→[14.1003:1021](∅→∅),[14.1021]→[16.1651:1696](∅→∅),[16.1696]→[20.4957:5181](∅→∅)
}};match state.src_files_cache.get(&path) {Some(SrcFile::Loading | SrcFile::Loaded(_)) => {src_files_cache_put(&mut state.src_files_cache,path,SrcFile::Loaded(content),);}None => {}}Task::none()}Message::UntrackedFileContentsAction { path, action } => {// Read-onlyif !action.is_edit() {if let Some(SrcFile::Loaded(FileEditorContent::Decoded(mut content),..,)) = state.src_files_cache.pop(&path){content.perform(action);src_files_cache_put(&mut state.src_files_cache,path,SrcFile::Loaded(FileEditorContent::Decoded(content)),);None => contents_diff::FileContent::UnknownEncoding,};match id.file_kind {FileKind::Untracked => {let file_diff: contents_diff::File =contents_diff::init_file(file_content, None);diffs_cache_put(&mut state.diffs_cache,id,FileDiff::Loaded(file_diff),);}FileKind::Changed => {if let Some(repo) = state.repo.as_ref() {let changed_file = repo.changed_files.get(&id.path);let file_diff: contents_diff::File =contents_diff::init_file(file_content,changed_file,);diffs_cache_put(&mut state.diffs_cache,id,FileDiff::Loaded(file_diff),);}} - edit in crates/inflorescence/src/main.rs at line 771
- replacement in crates/inflorescence/src/main.rs at line 774
Message::ChangedFileContentsAction { file, ix, action } => {// Read-onlyif !action.is_edit() {if let Some(contents) =state.changed_files_contents.get_mut(&file){todo!()// if let Some(content) = contents.get_mut(ix) {// match content {// Some(FileEditorContent::Decoded(content)) => {// content.perform(action);// }// _ => panic!("Unexpected content: {content:?}"),// }// }Message::FileDiffsContentsAction { id, action } => {if let Some(selection) = state.cursor.selection.as_mut() {match (selection, id.file_kind) {(cursor::Selection::UntrackedFile { ix: _, path, diffs },FileKind::Untracked,) if path == &id.path => {contents_diff::update(diffs, action);}(cursor::Selection::ChangedFile { ix: _, path, diffs },FileKind::Changed,) if path == &id.path => {contents_diff::update(diffs, action);}_ => {// Selection has changed} - edit in crates/inflorescence/src/main.rs at line 802
state.changed_files_contents =changed_files_contents(&repo.changed_files); - replacement in crates/inflorescence/src/main.rs at line 803
src_files_cache_clear(&mut state.src_files_cache);diffs_cache_clear(&mut state.diffs_cache); - edit in crates/inflorescence/src/main.rs at line 842
state.changed_files_contents =changed_files_contents(&changed_files); - replacement in crates/inflorescence/src/main.rs at line 845
src_files_cache_clear(&mut state.src_files_cache);diffs_cache_clear(&mut state.diffs_cache); - replacement in crates/inflorescence/src/main.rs at line 852
cursor::Selection::UntrackedFile { ix: _, path } => {cursor::Selection::UntrackedFile {ix: _,path,diffs: _,} => { - replacement in crates/inflorescence/src/main.rs at line 858
&mut state.src_files_cache,&mut state.diffs_cache, - replacement in crates/inflorescence/src/main.rs at line 860
path,FileId {path: path.clone(),file_kind: FileKind::Untracked,}, - edit in crates/inflorescence/src/main.rs at line 874
diffs: contents_diff::State::default(), - replacement in crates/inflorescence/src/main.rs at line 878
cursor::Selection::ChangedFile { ix: _, path } => {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,);cursor::Selection::ChangedFile {ix: _,path,diffs: _,} => {if let Some(diffs) = repo.changed_files.get(path) {if any_diff_has_contents(diffs) {load_src_file_if_not_cached(&mut state.diffs_cache,&state.src_file_load_tx,FileId {path: path.clone(),file_kind: FileKind::Changed,},);} - edit in crates/inflorescence/src/main.rs at line 906
diffs: contents_diff::State::default(), - edit in crates/inflorescence/src/main.rs at line 916[17.2927]→[17.2927:3059](∅→∅),[17.3059]→[24.283:408](∅→∅),[24.408]→[17.4266:4296](∅→∅),[17.4266]→[17.4266:4296](∅→∅)
}fn changed_files_contents(changed_files: &repo::ChangedFiles,) -> ChangedFilesContents {changed_files.iter().map(|(path, diffs)| {let contents = changed_file_contents(diffs);(path.clone(), contents)}).collect() - edit in crates/inflorescence/src/main.rs at line 918[17.4299]→[24.409:699](∅→∅),[24.699]→[26.1352:1427](∅→∅),[26.1427]→[24.768:1942](∅→∅),[24.768]→[24.768:1942](∅→∅),[24.1942]→[22.4772:4809](∅→∅),[22.4772]→[22.4772:4809](∅→∅),[22.4899]→[22.4899:4941](∅→∅),[22.4941]→[24.1943:3250](∅→∅),[24.3250]→[22.5847:5856](∅→∅),[22.5847]→[22.5847:5856](∅→∅),[22.5856]→[17.4299:4539](∅→∅),[17.4299]→[17.4299:4539](∅→∅),[17.4539]→[9.16466:16476](∅→∅),[9.16466]→[9.16466:16476](∅→∅),[9.16476]→[17.4540:4764](∅→∅),[7.1290]→[2.2657:2666](∅→∅),[6.2051]→[2.2657:2666](∅→∅),[8.2149]→[2.2657:2666](∅→∅),[17.4764]→[2.2657:2666](∅→∅),[5.7537]→[2.2657:2666](∅→∅),[9.16476]→[2.2657:2666](∅→∅),[2.2657]→[2.2657:2666](∅→∅)
fn changed_file_contents(diffs: &repo::ChangedFile) -> ChangedFileContents {let (with_contents, without_contents) = diffs.iter().fold((vec![], vec![]),|(mut acc_with, mut acc_without), diff| {match diff {repo::ChangedFileDiff::Move => {acc_without.push(ChangedFileDiffWithoutContents::Move)}repo::ChangedFileDiff::Del => {acc_with.push(ChangedFileDiffWithContents::Del)}repo::ChangedFileDiff::Undel => {acc_with.push(ChangedFileDiffWithContents::Undel)}repo::ChangedFileDiff::Add => {acc_with.push(ChangedFileDiffWithContents::Add)}repo::ChangedFileDiff::SolveNameConflict => acc_without.push(ChangedFileDiffWithoutContents::SolveNameConflict),repo::ChangedFileDiff::UnsolveNameConflict => acc_without.push(ChangedFileDiffWithoutContents::UnsolveNameConflict),repo::ChangedFileDiff::Edit {line,deleted,contents,} => acc_with.push(ChangedFileDiffWithContents::Edit {line: *line,deleted: *deleted,contents: contents_to_file_editor_content(contents),}),repo::ChangedFileDiff::Replacement {line,change_contents,replacement_contents,} => acc_with.push(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 => acc_without.push(ChangedFileDiffWithoutContents::SolveOrderConflict),repo::ChangedFileDiff::UnsolveOrderConflict => acc_without.push(ChangedFileDiffWithoutContents::UnsolveOrderConflict),repo::ChangedFileDiff::ResurrectZombines => acc_without.push(ChangedFileDiffWithoutContents::ResurrectZombines),repo::ChangedFileDiff::AddRoot => {acc_without.push(ChangedFileDiffWithoutContents::AddRoot)}repo::ChangedFileDiff::DelRoot => {acc_without.push(ChangedFileDiffWithoutContents::DelRoot)}};(acc_with, acc_without)},);ChangedFileContents {with_contents,without_contents,}}fn contents_to_file_editor_content(contents: &repo::Contents,) -> FileEditorContent {match contents {repo::Contents::Decoded(content) => {FileEditorContent::Decoded(text_editor::Content::with_text(content))}repo::Contents::ShortBase64(short) => {FileEditorContent::ShortBase64(short.clone())}repo::Contents::UnknownEncoding(_vec) => {FileEditorContent::UnknownEncoding}}} - replacement in crates/inflorescence/src/main.rs at line 954
async fn load_src_file(repo_path: PathBuf, file_path: String) -> Message {async fn load_src_file(repo_path: PathBuf,id: FileId,cache_counter: usize,) -> Message { - replacement in crates/inflorescence/src/main.rs at line 960
path.push(&file_path);path.push(&id.path); - replacement in crates/inflorescence/src/main.rs at line 964
path: file_path,id, - edit in crates/inflorescence/src/main.rs at line 967
cache_counter, - replacement in crates/inflorescence/src/main.rs at line 975
cache: &mut SrcFilesCache,load_tx: &watch::Sender<String>,path: &str,cache: &mut DiffsCache,load_tx: &watch::Sender<(FileId, usize)>,id: FileId, - replacement in crates/inflorescence/src/main.rs at line 979
if !cache.contains(path) {src_files_cache_put(cache, path.to_string(), SrcFile::Loading);load_tx.send(path.to_string()).unwrap();if !cache.inner.contains(&id) {diffs_cache_put(cache, id.clone(), FileDiff::Loading);load_tx.send((id, cache.counter)).unwrap(); - replacement in crates/inflorescence/src/main.rs at line 985
fn src_files_cache_put(cache: &mut SrcFilesCache, key: String, value: SrcFile) {if let Err((key, value)) = cache.put_with_weight(key, value) {let kv_weight = SrcFileCacheWeight.weight(&key, &value);info!("Source file cache is too small to hold {key}. Resizing cache to to {kv_weight} fit it.");cache.resize(NonZero::new(kv_weight).unwrap());let res = cache.put_with_weight(key, value);fn diffs_cache_put(cache: &mut DiffsCache, key: FileId, value: FileDiff) {if let Err((key, value)) = cache.inner.put_with_weight(key, value) {let kv_weight = DiffsCacheWeight.weight(&key, &value);info!("Source file cache is too small to hold {}. Resizing cache to to {kv_weight} fit it.", key.path);cache.inner.resize(NonZero::new(kv_weight).unwrap());let res = cache.inner.put_with_weight(key, value); - replacement in crates/inflorescence/src/main.rs at line 995
fn src_files_cache_clear(cache: &mut SrcFilesCache) {cache.clear();fn diffs_cache_clear(cache: &mut DiffsCache) {cache.inner.clear();cache.counter += 1; - replacement in crates/inflorescence/src/main.rs at line 1001
fn any_diff_has_contents(changed_file: &ChangedFileContents) -> bool {!changed_file.with_contents.is_empty()fn any_diff_has_contents(changed_file: &repo::ChangedFile) -> bool {let (with_contents, _without_contents) =contents_diff::diffs_from_repo_diffs(changed_file);!with_contents.is_empty() - replacement in crates/inflorescence/src/main.rs at line 1022
Some(cursor::Selection::UntrackedFile{ix: selected_ix, path:_}) if &ix == selected_ixSome(cursor::Selection::UntrackedFile{ix: selected_ix, path:_, diffs: _}) if &ix == selected_ix - replacement in crates/inflorescence/src/main.rs at line 1027
cursor::Selection::UntrackedFile{ix, path: path.clone()},cursor::Select::UntrackedFile{ix, path: path.clone()}, - replacement in crates/inflorescence/src/main.rs at line 1038
Some(cursor::Selection::ChangedFile{ix: selected_ix, path:_}) if &ix == selected_ixSome(cursor::Selection::ChangedFile{ix: selected_ix, path:_, diffs:_}) if &ix == selected_ix - replacement in crates/inflorescence/src/main.rs at line 1044
cursor::Selection::ChangedFile{ix, path: file_path.clone()},cursor::Select::ChangedFile{ix, path: file_path.clone()}, - replacement in crates/inflorescence/src/main.rs at line 1073[13.8559]→[13.8559:8696](∅→∅),[13.8696]→[25.323:324](∅→∅),[25.324]→[20.6469:6608](∅→∅),[13.8696]→[20.6469:6608](∅→∅),[20.6608]→[25.325:1204](∅→∅),[25.1204]→[16.2021:2326](∅→∅),[20.6720]→[16.2021:2326](∅→∅),[14.1281]→[16.2021:2326](∅→∅),[16.2326]→[20.6721:6889](∅→∅)
Some(cursor::Selection::UntrackedFile { path, .. }) => {debug_assert!(repo.untracked_files.contains(path));let diff = match &state.src_files_cache.peek(path) {Some(SrcFile::Loaded(content)) => match content {FileEditorContent::Decoded(content) => {let path_buf = PathBuf::from(path);let file_ext = path_buf.extension().and_then(ffi::OsStr::to_str);let editor = text_editor(content).wrapping(text::Wrapping::WordOrGlyph).on_action(|action|Message::UntrackedFileContentsAction{path: path.clone(), action});if let Some(file_ext) = file_ext {el(editor.highlight(file_ext, highlighter::Theme::SolarizedDark))} else {el(editor)}},FileEditorContent::ShortBase64(content) => {el(text(content))}FileEditorContent::UnknownEncoding => {el("Unknown encoding")}},Some(SrcFile::Loading) => el(text("Loading...")),None => panic!("Unexpectedly, the src file {path} is not even being loaded"),Some(cursor::Selection::UntrackedFile {ix: _,path,diffs: selection_state,}) => {let id = FileId {path: path.clone(),file_kind: FileKind::Untracked,};let diffs = match state.diffs_cache.inner.peek(&id) {Some(FileDiff::Loaded(file)) => {contents_diff::view(selection_state, file).map(move |msg| Message::FileDiffsContentsAction {id: id.clone(),action: msg,},)}None | Some(FileDiff::Loading) => el(text("loading...")), - replacement in crates/inflorescence/src/main.rs at line 1093
el(column([view_diff_header(format!("{path} diff:")), diff]))el(column([view_diff_header(format!("{path} diff:")),el(scrollable(diffs)),])) - replacement in crates/inflorescence/src/main.rs at line 1098
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 cacheNone} else {None};match state.src_files_cache.peek(path) {Some(SrcFile::Loaded(content)) => {let file_content = match content {FileEditorContent::Decoded(content) => {content.text()}FileEditorContent::ShortBase64(_) => todo!(),FileEditorContent::UnknownEncoding => todo!(),};let with_contents = diffs.with_contents.iter().map(|change| match dbg!(change) {ChangedFileDiffWithContents::Add => {contents_diff::ChangedFileDiffWithContents::Add}ChangedFileDiffWithContents::Edit {line,deleted,contents,} => contents_diff::ChangedFileDiffWithContents::Edit {line: *line,deleted: *deleted,contents: match contents {FileEditorContent::Decoded(content) => contents_diff::ChangeContents::Decoded(content.text()) ,FileEditorContent::ShortBase64(_) => todo!(),FileEditorContent::UnknownEncoding => todo!(),Some(cursor::Selection::ChangedFile {path,ix: _,diffs: selection_state,}) => {let id = FileId {path: path.clone(),file_kind: FileKind::Changed,};let diffs = match state.diffs_cache.inner.peek(&id) {Some(FileDiff::Loaded(file)) => {contents_diff::view(selection_state, file).map(move |msg| Message::FileDiffsContentsAction {id: id.clone(),action: msg, - replacement in crates/inflorescence/src/main.rs at line 1114
},ChangedFileDiffWithContents::Replacement {line,change_contents,replacement_contents,} => contents_diff::ChangedFileDiffWithContents::Replacement {line:*line ,change_contents: match change_contents {FileEditorContent::Decoded(content) => contents_diff::ChangeContents::Decoded(content.text()) ,FileEditorContent::ShortBase64(_) => todo!(),FileEditorContent::UnknownEncoding => todo!(),},replacement_contents: match replacement_contents {FileEditorContent::Decoded(content) => contents_diff::ChangeContents::Decoded(content.text()) ,FileEditorContent::ShortBase64(_) => todo!(),FileEditorContent::UnknownEncoding => todo!(),}},ChangedFileDiffWithContents::Del => contents_diff::ChangedFileDiffWithContents::Del,ChangedFileDiffWithContents::Undel => contents_diff::ChangedFileDiffWithContents::Undel,}).collect::<Vec<_>>();let state =contents_diff::init(&file_content, &with_contents);let diffs =contents_diff::view(state).map(|msg| todo!());el(column([view_diff_header(format!("{path} diff:")),el(scrollable(diffs)),]))) - replacement in crates/inflorescence/src/main.rs at line 1116
Some(SrcFile::Loading) => el(text("loading...")),None => todo!(),}None | Some(FileDiff::Loading) => el(text("loading...")),};el(column([view_diff_header(format!("{path} diff:")),el(scrollable(diffs)),])) - edit in crates/inflorescence/src/cursor.rs at line 1
use crate::contents_diff; - replacement in crates/inflorescence/src/cursor.rs at line 8
#[derive(Debug, Clone)]#[derive(Debug)] - edit in crates/inflorescence/src/cursor.rs at line 10
UntrackedFile {ix: usize,path: String,diffs: contents_diff::State,},ChangedFile {ix: usize,path: String,diffs: contents_diff::State,},}#[derive(Debug, Clone)]pub enum Select { - edit in crates/inflorescence/src/contents_diff.rs at line 3
use std::borrow::Cow; - edit in crates/inflorescence/src/contents_diff.rs at line 8
use libflowers_client::repo; - replacement in crates/inflorescence/src/contents_diff.rs at line 13
pub enum ChangedFileDiffWithContents {Add,Edit {line: usize,deleted: bool,contents: ChangeContents,},Replacement {line: usize,/// Deleted linechange_contents: ChangeContents,/// Added linesreplacement_contents: ChangeContents,},Del,Undel,pub enum File {Decoded(DecodedFile),Undecodable(UndecodableFile),}#[derive(Debug)]pub struct DecodedFile {pub combined: Combined,pub diffs_without_contents: Vec<DiffWithoutContents>, - replacement in crates/inflorescence/src/contents_diff.rs at line 25
pub enum ChangeContents {Decoded(String),/// Short byte sequence of unknown encoding encoded with base64 for/// display. Must be shorter than [`MAX_LEN_BASE64_DISPLAY`]ShortBase64(String),UnknownEncoding,pub struct UndecodableFile {pub diffs_with_contents: Vec<DiffWithContents>,pub diffs_without_contents: Vec<DiffWithoutContents>, - edit in crates/inflorescence/src/contents_diff.rs at line 30
/// A file combined with its diffs into sections - replacement in crates/inflorescence/src/contents_diff.rs at line 32
pub struct State {pub struct Combined { - replacement in crates/inflorescence/src/contents_diff.rs at line 38
pub enum Section {Unchanged(Lines),/// `deleted` and `added` are together because for/// `ChangedFileDiffWithContents::Replacement` they begin on the same line/// numberChanged {deleted: Lines,added: Lines,},pub enum FileContent<'a> {Decoded(Cow<'a, str>),UnknownEncoding,}pub fn init_file(file_content: FileContent<'_>,changed_file: Option<&repo::ChangedFile>,) -> File {let (diffs_with_contents, diffs_without_contents) = changed_file.map(diffs_from_repo_diffs).unwrap_or((vec![], vec![]));match file_content {FileContent::Decoded(file_content) => {let combined =combine_decoded_contents(&file_content, diffs_with_contents);File::Decoded(DecodedFile {combined,diffs_without_contents,})}FileContent::UnknownEncoding => File::Undecodable(UndecodableFile {diffs_with_contents,diffs_without_contents,}),} - replacement in crates/inflorescence/src/contents_diff.rs at line 67
pub fn init(file_contents: &str,changes: &[ChangedFileDiffWithContents],) -> State {let changes_len = changes.len();let mut file_lines = file_contents.split('\n');let mut sections = Vec::with_capacity(changes.len());pub fn combine_decoded_contents(file_content: &str,diffs_with_contents: Vec<DiffWithContents>,) -> Combined {let changes_len = diffs_with_contents.len();let mut file_lines = file_content.split('\n');let mut sections = Vec::with_capacity(diffs_with_contents.len()); - replacement in crates/inflorescence/src/contents_diff.rs at line 77
for change in changes {for change in diffs_with_contents { - replacement in crates/inflorescence/src/contents_diff.rs at line 79
ChangedFileDiffWithContents::Add| ChangedFileDiffWithContents::Undel => {DiffWithContents::Add | DiffWithContents::Undel => { - replacement in crates/inflorescence/src/contents_diff.rs at line 87
return State {return Combined { - replacement in crates/inflorescence/src/contents_diff.rs at line 92
ChangedFileDiffWithContents::Del => {DiffWithContents::Del => { - replacement in crates/inflorescence/src/contents_diff.rs at line 100
return State {return Combined { - replacement in crates/inflorescence/src/contents_diff.rs at line 105
ChangedFileDiffWithContents::Edit {DiffWithContents::Edit { - replacement in crates/inflorescence/src/contents_diff.rs at line 112
current_line = *line;current_line = line; - replacement in crates/inflorescence/src/contents_diff.rs at line 119
if *deleted {let deleted = contents_to_lines(contents);if deleted {let deleted = contents_to_lines(&contents); - replacement in crates/inflorescence/src/contents_diff.rs at line 128
let added = contents_to_lines(contents);let added = contents_to_lines(&contents); - replacement in crates/inflorescence/src/contents_diff.rs at line 139
ChangedFileDiffWithContents::Replacement {DiffWithContents::Replacement { - replacement in crates/inflorescence/src/contents_diff.rs at line 146
current_line = *line;current_line = line; - replacement in crates/inflorescence/src/contents_diff.rs at line 153
let added = contents_to_lines(replacement_contents);let deleted = contents_to_lines(change_contents);let added = contents_to_lines(&replacement_contents);let deleted = contents_to_lines(&change_contents); - replacement in crates/inflorescence/src/contents_diff.rs at line 170
State {Combined { - replacement in crates/inflorescence/src/contents_diff.rs at line 176
fn contents_to_lines(contents: &ChangeContents) -> Lines {match contents {ChangeContents::Decoded(string) => {string.split('\n').map(str::to_string).collect()}ChangeContents::ShortBase64(_) => todo!(),ChangeContents::UnknownEncoding => todo!(),}pub fn diffs_from_repo_diffs(changed_file: &repo::ChangedFile,) -> (Vec<DiffWithContents>, Vec<DiffWithoutContents>) {changed_file.iter().fold((vec![], vec![]), |(mut with, mut without), diff| {match diff {repo::ChangedFileDiff::Move => {without.push(DiffWithoutContents::Move);},repo::ChangedFileDiff::Del => {with.push(DiffWithContents::Del);},repo::ChangedFileDiff::Undel => {with.push(DiffWithContents::Undel);},repo::ChangedFileDiff::Add => {with.push(DiffWithContents::Add);},repo::ChangedFileDiff::SolveNameConflict => {without.push(DiffWithoutContents::Move);},repo::ChangedFileDiff::UnsolveNameConflict => {without.push(DiffWithoutContents::Move);},repo::ChangedFileDiff::Edit { line, deleted, contents } => match contents{repo::Contents::Decoded(lines) => {with.push(DiffWithContents::Edit {line: *line,deleted: *deleted,contents: lines.clone(),});},repo::Contents::ShortBase64(short) => {without.push(DiffWithoutContents::Edit {line: *line,deleted: *deleted,contents: UndecodableContents::ShortBase64(short.clone()),});},repo::Contents::UnknownEncoding(_bytes) => {without.push(DiffWithoutContents::Edit {line: *line,deleted: *deleted,contents: UndecodableContents::UnknownEncoding,});},},repo::ChangedFileDiff::Replacement { line, change_contents, replacement_contents } => match (change_contents, replacement_contents) {(repo::Contents::Decoded(change), repo::Contents::Decoded(replacement)) => {with.push(DiffWithContents::Replacement {line: *line,change_contents: change.clone(),replacement_contents: replacement.clone(),});},(repo::Contents::ShortBase64(change), repo::Contents::ShortBase64(replacement)) => {without.push(DiffWithoutContents::Replacement {line: *line,change_contents: UndecodableContents::ShortBase64(change.clone()),replacement_contents: UndecodableContents::ShortBase64(replacement.clone()),});},(repo::Contents::UnknownEncoding(_change), repo::Contents::UnknownEncoding(_replacement)) => {without.push(DiffWithoutContents::Replacement {line: *line,change_contents: UndecodableContents::UnknownEncoding,replacement_contents: UndecodableContents::UnknownEncoding,});},_ => {unimplemented!("The change and replacement have different encoding!");}},repo::ChangedFileDiff::SolveOrderConflict => {without.push(DiffWithoutContents::SolveOrderConflict);},repo::ChangedFileDiff::UnsolveOrderConflict => {without.push(DiffWithoutContents::UnsolveOrderConflict);},repo::ChangedFileDiff::ResurrectZombines => {without.push(DiffWithoutContents::ResurrectZombines);},repo::ChangedFileDiff::AddRoot => {without.push(DiffWithoutContents::AddRoot);},repo::ChangedFileDiff::DelRoot => {without.push(DiffWithoutContents::DelRoot);},};(with, without)})}#[derive(Debug)]pub enum DiffWithContents {Add,Edit {line: usize,deleted: bool,contents: String,},Replacement {line: usize,/// Deleted linechange_contents: String,/// Added linesreplacement_contents: String,},Del,Undel,}#[allow(dead_code)] // TODO rm once `view_undecodable` is implemented#[derive(Debug)]pub enum DiffWithoutContents {// _________________________________________________________________________// Cases that never have contents:Move,SolveNameConflict,UnsolveNameConflict,SolveOrderConflict,UnsolveOrderConflict,ResurrectZombines,AddRoot,DelRoot,// _________________________________________________________________________// Cases that normally have contents, but in these cases the contents are// not decodable:Edit {line: usize,deleted: bool,contents: UndecodableContents,},Replacement {line: usize,/// Deleted linechange_contents: UndecodableContents,/// Added linesreplacement_contents: UndecodableContents,},}#[allow(dead_code)] // TODO rm once `view_undecodable` is implemented#[derive(Debug)]pub enum UndecodableContents {/// Short byte sequence of unknown encoding encoded with base64 for/// display. Must be shorter than [`crate::repo::MAX_LEN_BASE64_DISPLAY`]ShortBase64(String),UnknownEncoding, - edit in crates/inflorescence/src/contents_diff.rs at line 326
#[allow(dead_code)] // TODO rm once `view_decoded` is fully implemented#[derive(Debug, Default)]pub struct State {pub selected_sections: Vec<usize>,pub expanded_unchanged_sections: Vec<usize>,pub collapsed_changed_sections: Vec<usize>,}#[derive(Debug)]pub enum Section {Unchanged(Lines),/// `deleted` and `added` are together because for/// `ChangedFileDiffWithContents::Replacement` they begin on the same line/// numberChanged {deleted: Lines,added: Lines,},}fn contents_to_lines(contents: &str) -> Lines {contents.split('\n').map(str::to_string).collect()} - replacement in crates/inflorescence/src/contents_diff.rs at line 368
#[derive(Debug)]#[derive(Debug, Clone)] - replacement in crates/inflorescence/src/contents_diff.rs at line 371
pub fn update(state: &mut State, msg: Msg) {}pub fn update(_state: &mut State, _msg: Msg) {}pub fn view<'a>(state: &'a State, file: &'a File) -> Element<'a, Msg> {match file {File::Decoded(decoded_file) => view_decoded(state, decoded_file),File::Undecodable(undecodable_file) => {view_undecodable(state, undecodable_file)}}} - replacement in crates/inflorescence/src/contents_diff.rs at line 382
pub fn view(state: State) -> Element<'static, Msg> {pub fn view_decoded<'a>(_state: &'a State,file: &'a DecodedFile,) -> Element<'a, Msg> {// TODO use state to display selection, and control section expansion - replacement in crates/inflorescence/src/contents_diff.rs at line 388
let line_num_digits = state.max_line_num.to_string().len();let sections_view = statelet line_num_digits = file.combined.max_line_num.to_string().len();let sections_view = file.combined - edit in crates/inflorescence/src/contents_diff.rs at line 448
}pub fn view_undecodable<'a>(_state: &'a State,file: &'a UndecodableFile,) -> Element<'a, Msg> {// TODO implement proper viewel(code(format!("{file:#?}")))