make all repo actions async
[?]
Feb 23, 2025, 11:36 AM
YBJRDOTCX3ZRDB5EVXJBR55FX3CADCSIGMYWNYVC2PD5W3GXR3DQCDependencies
- [2]
6YZAVBWUInitial commit - [3]
KLR5FRIBadd fs state read/write of repos - [4]
IQDCHWCPload a pijul repo - [5]
SWWE2R6Mdisplay basic repo stuff - [6]
WT3GA27Padd cursor with selection - [7]
DVKSPF7Rtrack selected file path together with an index - [8]
UB2ITZJSrefresh changed files on FS changes - [9]
EC3TVL4Xadd untracked files - [10]
KT5UYXGKfix selection after adding file, add changed file diffs - [11]
ELG3UDT6allow to rm added files - [12]
S2NVIFXRallow to enter record msg - [13]
W7IUT3ZVstart recording impl
Change contents
- replacement in crates/libflowers_client/src/repo.rs at line 3
use std::ops::Deref;use std::ops::{Deref, DerefMut}; - edit in crates/libflowers_client/src/repo.rs at line 13
use tokio::sync::mpsc;use tokio::task::spawn_blocking;#[derive(Clone, Debug)]pub struct State {pub dir_name: String,pub channel: String,pub untracked_files: BTreeSet<String>,pub changed_files: BTreeSet<ChangedFile>,} - replacement in crates/libflowers_client/src/repo.rs at line 26
pub struct State {pub struct InternalState { - edit in crates/libflowers_client/src/repo.rs at line 54
}#[derive(Debug, Clone, strum::Display)]pub enum MsgIn {RefreshChangedAndUntrackedFiles,AddUntrackedFile { path: String },RmAddedFile { path: String },Record { msg: String }, - edit in crates/libflowers_client/src/repo.rs at line 63
#[derive(Debug, Clone, strum::Display)]pub enum MsgOut {Init(State),RefreshedChangedAndUntrackedFiles {untracked_files: BTreeSet<String>,changed_files: BTreeSet<ChangedFile>,},}pub type Diff = LocalChange<Hunk<Option<Hash>, Local>, Author>; - replacement in crates/libflowers_client/src/repo.rs at line 75
impl Deref for State {type Target = pijul::Repository;/// Run an async repo task to manage all actions sent via the other side of the/// receiver.pub async fn manage(path: PathBuf,mut msg_in_rx: mpsc::UnboundedReceiver<MsgIn>,msg_out_tx: mpsc::UnboundedSender<MsgOut>,) {let mut state = spawn_blocking(move || load(path)).await.unwrap();// dbg!(diff(&state.repo));let dir_name = dir_name(&state.repo).to_string();let channel = current_channel(&state.repo);let untracked_files = state.untracked_files.clone();let changed_files = state.changed_files.clone(); - replacement in crates/libflowers_client/src/repo.rs at line 90
fn deref(&self) -> &Self::Target {&self.repolet _ = msg_out_tx.send(MsgOut::Init(State {dir_name,channel,untracked_files,changed_files,}));loop {if let Some(msg) = msg_in_rx.recv().await {info!("Repo received msg {msg}");state = update(state, msg, &msg_out_tx).await;} else {break;} - replacement in crates/libflowers_client/src/repo.rs at line 107
pub type Diff = LocalChange<Hunk<Option<Hash>, Local>, Author>;async fn update<'a>(mut state: InternalState,msg_in: MsgIn,msg_out_tx: &mpsc::UnboundedSender<MsgOut>,) -> InternalState {match msg_in {MsgIn::RefreshChangedAndUntrackedFiles => {state = spawn_blocking(move || {refresh(&mut state);state}).await.unwrap();let untracked_files = state.untracked_files.clone();let changed_files = state.changed_files.clone();let _ =msg_out_tx.send(MsgOut::RefreshedChangedAndUntrackedFiles {untracked_files,changed_files,});}MsgIn::AddUntrackedFile { path } => {state = spawn_blocking(move || {add(&mut state, &path);state}).await.unwrap();}MsgIn::RmAddedFile { path } => {state = spawn_blocking(move || {rm(&mut state, &path);state}).await.unwrap();}MsgIn::Record { msg } => {state = spawn_blocking(move || {record(&mut state, msg);state}).await.unwrap();}}state} - replacement in crates/libflowers_client/src/repo.rs at line 156
pub fn load(path: PathBuf) -> State {fn load(path: PathBuf) -> InternalState { - replacement in crates/libflowers_client/src/repo.rs at line 161
State {InternalState { - replacement in crates/libflowers_client/src/repo.rs at line 168
pub fn refresh(state: &mut State) {fn refresh(state: &mut InternalState) { - replacement in crates/libflowers_client/src/repo.rs at line 175
pub fn dir_name(repo: &pijul::Repository) -> Cow<'_, str> {fn dir_name(repo: &pijul::Repository) -> Cow<'_, str> { - replacement in crates/libflowers_client/src/repo.rs at line 179
pub fn current_channel(repo: &pijul::Repository) -> String {fn current_channel(repo: &pijul::Repository) -> String { - replacement in crates/libflowers_client/src/repo.rs at line 188
pub async fn record(state: &State, msg: String) {fn record(state: &InternalState, msg: String) { - replacement in crates/libflowers_client/src/repo.rs at line 217
pub fn diff(repo: &pijul::Repository) -> Diff {fn diff(repo: &pijul::Repository) -> Diff { - replacement in crates/libflowers_client/src/repo.rs at line 278
pub fn add(repo: &mut pijul::Repository, path_str: &str) {/// The `file_path_str` must not contain the repo's path prefix.fn add(repo: &mut pijul::Repository, file_path_str: &str) { - replacement in crates/libflowers_client/src/repo.rs at line 284
p.push(path_str);p.push(file_path_str); - replacement in crates/libflowers_client/src/repo.rs at line 294
println!("Won't add ignored file {path_str}");return;panic!("Cannot add ignored file \"{file_path_str}\""); - replacement in crates/libflowers_client/src/repo.rs at line 298
let path_str = path_slash::PathExt::to_slash_lossy(path.as_path());// NOTE: This has to be the file path without the repo's path prefixlet file_path = PathBuf::from(file_path_str);let path_str = path_slash::PathExt::to_slash_lossy(file_path.as_path()); - replacement in crates/libflowers_client/src/repo.rs at line 305
eprintln!("Failed to add {}", e);panic!("Failed to track file with: {}", e); - edit in crates/libflowers_client/src/repo.rs at line 307
} else {panic!("Won't add file \"{path_str}\" as it's already tracked"); - replacement in crates/libflowers_client/src/repo.rs at line 314
pub fn rm(repo: &mut pijul::Repository, path_str: &str) {/// The `file_path_str` must not contain the repo's path prefix.fn rm(repo: &mut pijul::Repository, file_path_str: &str) {info!("Removing tracked {file_path_str}"); - replacement in crates/libflowers_client/src/repo.rs at line 318
let full_path = {let mut p = repo.path.clone();p.push(path_str);p};let path = full_path.canonicalize().unwrap();let path_str = path_slash::PathExt::to_slash_lossy(path.as_path());let file_path = PathBuf::from(file_path_str);let path_str = path_slash::PathExt::to_slash_lossy(file_path.as_path()); - edit in crates/libflowers_client/src/repo.rs at line 464[5.4751]
impl Deref for InternalState {type Target = pijul::Repository;fn deref(&self) -> &Self::Target {&self.repo}}impl DerefMut for InternalState {fn deref_mut(&mut self) -> &mut Self::Target {&mut self.repo}} - edit in crates/libflowers_client/Cargo.toml at line 25
workspace = true[dependencies.tokio] - edit in crates/libflowers/src/prelude.rs at line 7
#[doc(inline)]pub use tracing::{debug, error, info, warn}; - edit in crates/libflowers/Cargo.toml at line 35[4.916]
[dependencies.tracing]workspace = true - edit in crates/flowers_ui/src/main.rs at line 11
use std::collections::BTreeSet; - replacement in crates/flowers_ui/src/main.rs at line 13
use tokio::sync::watch;use tokio::sync::{mpsc, watch}; - replacement in crates/flowers_ui/src/main.rs at line 15
use tokio_stream::wrappers::WatchStream;use tokio_stream::wrappers::{UnboundedReceiverStream, WatchStream}; - edit in crates/flowers_ui/src/main.rs at line 18
use std::str::FromStr;use tracing_subscriber::EnvFilter;const LOG_ENV: &str = "RUST_LOG";let filter = std::env::var(LOG_ENV).map(|env| {dbg!(&env);EnvFilter::from_str(&env).unwrap_or_else(|err| {panic!("invalid `{}` environment variable {}", LOG_ENV, err)})}).unwrap_or_else(|_| EnvFilter::new("flowers=info,libflowers=info"));tracing_subscriber::fmt().with_env_filter(filter).init(); - edit in crates/flowers_ui/src/main.rs at line 41
// TODO: start watch once loaded? - replacement in crates/flowers_ui/src/main.rs at line 67
let task = Task::run(fs_watch_rx, |()| Message::FilesChanged);let watch_task = Task::run(fs_watch_rx, |()| {Message::ToRepo(repo::MsgIn::RefreshChangedAndUntrackedFiles)}); - edit in crates/flowers_ui/src/main.rs at line 71
let repo = repo::load(repo_path);// dbg!(repo::diff(&repo)); - edit in crates/flowers_ui/src/main.rs at line 72
let (repo_tx_in, repo_rx_in) = mpsc::unbounded_channel::<repo::MsgIn>();let (repo_tx_out, repo_rx_out) = mpsc::unbounded_channel::<repo::MsgOut>();let repo_task = Task::future(async move {repo::manage(repo_path, repo_rx_in, repo_tx_out).await;Message::RepoTaskExited});let repo_rx_out = UnboundedReceiverStream::new(repo_rx_out);let repo_msg_out_task = Task::run(repo_rx_out, Message::FromRepo); - edit in crates/flowers_ui/src/main.rs at line 82
let tasks = Task::batch([watch_task, repo_task, repo_msg_out_task]); - replacement in crates/flowers_ui/src/main.rs at line 86
repo,repo_tx_in,repo: None, // This is loaded by `repo_task` - replacement in crates/flowers_ui/src/main.rs at line 91
task,tasks, - replacement in crates/flowers_ui/src/main.rs at line 98
repo: repo::State,repo_tx_in: mpsc::UnboundedSender<repo::MsgIn>,repo: Option<repo::State>, - replacement in crates/flowers_ui/src/main.rs at line 110
FilesChanged,RepoTaskExited,FromRepo(repo::MsgOut),ToRepo(repo::MsgIn), - edit in crates/flowers_ui/src/main.rs at line 121
MadeRecord, - replacement in crates/flowers_ui/src/main.rs at line 123[2.3099]→[13.1206:1272](∅→∅),[13.1272]→[10.4638:4764](∅→∅),[4.1455]→[10.4638:4764](∅→∅),[10.4764]→[9.2167:2300](∅→∅),[9.2167]→[9.2167:2300](∅→∅),[9.2504]→[9.2504:2511](∅→∅)
fn update(state: &mut State, message: Message) -> Task<Message> {let untracked_file_selection = |state: &State,ix: usize|-> cursor::Selection {let path = state.repo.untracked_files.iter().nth(ix).unwrap().clone();cursor::Selection::UntrackedFile { ix, path }};fn update(state: &mut State, msg: Message) -> Task<Message> {let untracked_file_selection =|repo: &repo::State, ix: usize| -> cursor::Selection {let path = repo.untracked_files.iter().nth(ix).unwrap().clone();cursor::Selection::UntrackedFile { ix, path }}; - replacement in crates/flowers_ui/src/main.rs at line 131
|state: &State, ix: usize| -> cursor::Selection {let path = state.repo.changed_files.iter().nth(ix).unwrap().path.clone();|repo: &repo::State, ix: usize| -> cursor::Selection {let path = repo.changed_files.iter().nth(ix).unwrap().path.clone(); - replacement in crates/flowers_ui/src/main.rs at line 136[7.160]→[6.738:758](∅→∅),[9.2512]→[6.738:758](∅→∅),[4.1455]→[6.738:758](∅→∅),[6.758]→[8.1635:1670](∅→∅),[8.1670]→[10.5129:5163](∅→∅),[10.5163]→[8.1670:1714](∅→∅),[8.1670]→[8.1670:1714](∅→∅),[8.1714]→[9.2513:3480](∅→∅),[9.3480]→[10.5164:5303](∅→∅),[10.5303]→[9.3624:3656](∅→∅),[9.3624]→[9.3624:3656](∅→∅),[9.3656]→[10.5304:5357](∅→∅),[10.5357]→[9.3704:3765](∅→∅),[9.3704]→[9.3704:3765](∅→∅)
match message {Message::FilesChanged => {dbg!("FilesChanged");repo::refresh(&mut state.repo);// Re-index cursor selectionif let Some(selection) = state.cursor.selection.as_ref() {// Try to find the file with the same name. If not found, remove// selectionstate.cursor.selection = match selection {cursor::Selection::UntrackedFile { ix: _, path } => state.repo.untracked_files.iter().enumerate().find(|(_ix, file_path)| *file_path == path).map(|(ix, path)| cursor::Selection::UntrackedFile {ix,path: path.clone(),}),cursor::Selection::ChangedFile { ix: _, path } => state.repo.changed_files.iter().enumerate().find(|(_ix, file)| &file.path == path).map(|(ix, file)| cursor::Selection::ChangedFile {ix,path: file.path.clone(),}),};}match msg {Message::RepoTaskExited => {error!("Repo task exited");Task::none()}Message::FromRepo(msg) => {info!("Repo sent msg {msg}");update_from_repo(state, msg)}Message::ToRepo(msg) => {let _ = state.repo_tx_in.send(msg); - replacement in crates/flowers_ui/src/main.rs at line 150
state.cursor.selection = match state.cursor.selection.as_ref() {Some(cursor::Selection::UntrackedFile { ix, path: _ }) => {let new_selection =if state.repo.untracked_files.len().saturating_sub(1)if let Some(repo) = state.repo.as_ref() {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;untracked_file_selection(repo, ix)} else {let ix = 0;changed_file_selection(repo, ix)}} else {let ix = ix + 1;untracked_file_selection(repo, ix)};Some(new_selection)}Some(cursor::Selection::ChangedFile { ix, path: _ }) => {let new_selection = if repo.changed_files.len().saturating_sub(1) - replacement in crates/flowers_ui/src/main.rs at line 177
if state.repo.changed_files.is_empty() {if repo.untracked_files.is_empty() { - replacement in crates/flowers_ui/src/main.rs at line 179
untracked_file_selection(state, ix)changed_file_selection(repo, ix) - replacement in crates/flowers_ui/src/main.rs at line 182
changed_file_selection(state, ix)untracked_file_selection(repo, ix) - replacement in crates/flowers_ui/src/main.rs at line 186
untracked_file_selection(state, ix)changed_file_selection(repo, ix) - replacement in crates/flowers_ui/src/main.rs at line 188[9.4572]→[9.4572:4744](∅→∅),[7.400]→[6.1262:1399](∅→∅),[9.4744]→[6.1262:1399](∅→∅),[6.1262]→[6.1262:1399](∅→∅),[6.1399]→[9.4745:4860](∅→∅),[9.4860]→[10.5559:5625](∅→∅)
Some(new_selection)}Some(cursor::Selection::ChangedFile { ix, path: _ }) => {let new_selection =if state.repo.changed_files.len().saturating_sub(1)== *ix{if state.repo.untracked_files.is_empty() {let ix = 0;changed_file_selection(state, ix)Some(new_selection)}None => {if repo.untracked_files.is_empty() {if repo.changed_files.is_empty() {None - replacement in crates/flowers_ui/src/main.rs at line 196
untracked_file_selection(state, ix)Some(changed_file_selection(repo, ix)) - edit in crates/flowers_ui/src/main.rs at line 198[9.5091]→[6.1454:1487](∅→∅),[6.1454]→[6.1454:1487](∅→∅),[6.1487]→[7.401:446](∅→∅),[7.446]→[10.5695:5757](∅→∅),[10.5757]→[9.5147:5419](∅→∅),[9.5147]→[9.5147:5419](∅→∅)
} else {let ix = ix + 1;changed_file_selection(state, ix)};Some(new_selection)}None => {if state.repo.untracked_files.is_empty() {if state.repo.changed_files.is_empty() {None - replacement in crates/flowers_ui/src/main.rs at line 200
Some(changed_file_selection(state, ix))Some(untracked_file_selection(repo, ix)) - edit in crates/flowers_ui/src/main.rs at line 202
} else {let ix = 0;Some(untracked_file_selection(state, ix)) - replacement in crates/flowers_ui/src/main.rs at line 203
}};};} - replacement in crates/flowers_ui/src/main.rs at line 208[6.1711]→[9.5712:5919](∅→∅),[9.5919]→[6.1874:1939](∅→∅),[6.1874]→[6.1874:1939](∅→∅),[6.1939]→[9.5920:5995](∅→∅),[9.5995]→[10.5894:5958](∅→∅)
state.cursor.selection = match state.cursor.selection.as_ref() {Some(cursor::Selection::UntrackedFile { ix, path: _ }) => {let new_selection = if 0 == *ix {if state.repo.changed_files.is_empty() {let ix = state.repo.untracked_files.len() - 1;untracked_file_selection(state, ix)if let Some(repo) = state.repo.as_ref() {state.cursor.selection = match state.cursor.selection.as_ref() {Some(cursor::Selection::UntrackedFile { ix, path: _ }) => {let new_selection = if 0 == *ix {if repo.changed_files.is_empty() {let ix = repo.untracked_files.len() - 1;untracked_file_selection(repo, ix)} else {let ix = repo.changed_files.len() - 1;changed_file_selection(repo, ix)} - replacement in crates/flowers_ui/src/main.rs at line 220[6.2027]→[7.574:647](∅→∅),[7.647]→[10.5959:6021](∅→∅),[7.774]→[6.2178:2204](∅→∅),[10.6021]→[6.2178:2204](∅→∅),[9.6108]→[6.2178:2204](∅→∅),[6.2178]→[6.2178:2204](∅→∅),[6.2204]→[9.6109:6179](∅→∅),[9.6179]→[10.6022:6082](∅→∅),[10.6082]→[9.6232:6581](∅→∅),[9.6232]→[9.6232:6581](∅→∅),[9.6581]→[10.6083:6145](∅→∅)
let ix = state.repo.changed_files.len() - 1;changed_file_selection(state, ix)}} else {let ix = ix - 1;untracked_file_selection(state, ix)};Some(new_selection)}Some(cursor::Selection::ChangedFile { ix, path: _ }) => {let new_selection = if 0 == *ix {if state.repo.untracked_files.is_empty() {let ix = state.repo.changed_files.len() - 1;changed_file_selection(state, ix)let ix = ix - 1;untracked_file_selection(repo, ix)};Some(new_selection)}Some(cursor::Selection::ChangedFile { ix, path: _ }) => {let new_selection = if 0 == *ix {if repo.untracked_files.is_empty() {let ix = repo.changed_files.len() - 1;changed_file_selection(repo, ix)} else {let ix = repo.untracked_files.len() - 1;untracked_file_selection(repo, ix)} - replacement in crates/flowers_ui/src/main.rs at line 235[6.2411]→[9.6637:6712](∅→∅),[9.6712]→[10.6146:6210](∅→∅),[10.6210]→[9.6769:6865](∅→∅),[9.6769]→[9.6769:6865](∅→∅),[9.6865]→[10.6211:6269](∅→∅),[10.6269]→[9.6916:7184](∅→∅),[9.6916]→[9.6916:7184](∅→∅)
let ix = state.repo.untracked_files.len() - 1;untracked_file_selection(state, ix)}} else {let ix = ix - 1;changed_file_selection(state, ix)};Some(new_selection)}None => {if state.repo.changed_files.is_empty() {if state.repo.untracked_files.is_empty() {Nonelet ix = ix - 1;changed_file_selection(repo, ix)};Some(new_selection)}None => {if repo.changed_files.is_empty() {if repo.untracked_files.is_empty() {None} else {let ix = repo.untracked_files.len() - 1;Some(untracked_file_selection(repo, ix))} - replacement in crates/flowers_ui/src/main.rs at line 249
let ix = state.repo.untracked_files.len() - 1;Some(untracked_file_selection(state, ix))let ix = repo.changed_files.len() - 1;Some(changed_file_selection(repo, ix)) - edit in crates/flowers_ui/src/main.rs at line 252
} else {let ix = state.repo.changed_files.len() - 1;Some(changed_file_selection(state, ix)) - replacement in crates/flowers_ui/src/main.rs at line 253
}};};} - replacement in crates/flowers_ui/src/main.rs at line 262[10.6445]→[10.6445:6580](∅→∅),[10.6580]→[13.1461:1516](∅→∅),[13.1516]→[10.6636:7252](∅→∅),[10.6636]→[10.6636:7252](∅→∅)
if let Some(cursor::Selection::UntrackedFile { ix, path }) =state.cursor.selection.as_ref(){repo::add(&mut state.repo.repo, path);let removed = state.repo.untracked_files.remove(path);debug_assert!(removed,"{:?}, path: {path}",state.repo.untracked_files);let file = repo::ChangedFile {path: path.clone(),diff: repo::ChangedFileDiff::Add,};state.repo.changed_files.insert(file);// Select the next untracked file, if anystate.cursor.selection =if state.repo.untracked_files.is_empty() {if let Some(repo) = state.repo.as_mut() {if let Some(cursor::Selection::UntrackedFile { ix, path }) =state.cursor.selection.as_ref(){let _ =state.repo_tx_in.send(repo::MsgIn::AddUntrackedFile {path: path.clone(),});let removed = repo.untracked_files.remove(path);debug_assert!(removed,"{:?}, path: {path}",repo.untracked_files);let file = repo::ChangedFile {path: path.clone(),diff: repo::ChangedFileDiff::Add,};repo.changed_files.insert(file);// Select the next untracked file, if anystate.cursor.selection = if repo.untracked_files.is_empty(){ - replacement in crates/flowers_ui/src/main.rs at line 287
let ix =cmp::min(*ix, state.repo.untracked_files.len() - 1);Some(untracked_file_selection(state, ix))let ix = cmp::min(*ix, repo.untracked_files.len() - 1);Some(untracked_file_selection(repo, ix)) - edit in crates/flowers_ui/src/main.rs at line 290
} - replacement in crates/flowers_ui/src/main.rs at line 295[11.684]→[11.684:960](∅→∅),[11.960]→[13.1543:1601](∅→∅),[13.1601]→[11.1019:2009](∅→∅),[11.1019]→[11.1019:2009](∅→∅)
if let Some(cursor::Selection::ChangedFile { ix, path }) =state.cursor.selection.as_ref(){let file = state.repo.changed_files.iter().nth(*ix).unwrap();if let repo::ChangedFileDiff::Add = &file.diff {repo::rm(&mut state.repo.repo, path);let file = file.clone();// Remove from changed fileslet removed = state.repo.changed_files.remove(&file);debug_assert!(removed,"{:?} not found in {:?}",file, state.repo.changed_files);// Update untracked filesstate.repo.untracked_files.insert(file.path);// Select the next changed file, if anystate.cursor.selection =if state.repo.changed_files.is_empty() {None} else {let ix = cmp::min(*ix,state.repo.changed_files.len() - 1,);Some(changed_file_selection(state, ix))};if let Some(repo) = state.repo.as_mut() {if let Some(cursor::Selection::ChangedFile { ix, path }) =state.cursor.selection.as_ref(){let file = repo.changed_files.iter().nth(*ix).unwrap();if let repo::ChangedFileDiff::Add = &file.diff {let _ =state.repo_tx_in.send(repo::MsgIn::RmAddedFile {path: path.clone(),});let file = file.clone();// Remove from changed fileslet removed = repo.changed_files.remove(&file);debug_assert!(removed,"{:?} not found in {:?}",file, repo.changed_files);// Update untracked filesrepo.untracked_files.insert(file.path);// Select the next changed file, if anystate.cursor.selection =if repo.changed_files.is_empty() {None} else {let ix =cmp::min(*ix, repo.changed_files.len() - 1);Some(changed_file_selection(repo, ix))};} - replacement in crates/flowers_ui/src/main.rs at line 331
if state.record_msg.is_some() {println!("Already recording");} else if state.repo.changed_files.is_empty() {println!("Trying to record with no changed file");} else {state.record_msg = Some(text_editor::Content::new());if let Some(repo) = state.repo.as_ref() {if state.record_msg.is_some() {info!("Requested to record, but already recording");} else if repo.changed_files.is_empty() {info!("Trying to record with no changed files");} else {state.record_msg = Some(text_editor::Content::new());} - replacement in crates/flowers_ui/src/main.rs at line 348[12.782]→[12.782:906](∅→∅),[12.906]→[13.1680:1709](∅→∅),[13.1709]→[12.906:954](∅→∅),[12.906]→[12.906:954](∅→∅)
Message::Save => match state.record_msg.as_ref() {None => {println!("Not recording");Task::none()}Some(record_msg) => {Message::Save => {if let Some(record_msg) = state.record_msg.as_ref() { - replacement in crates/flowers_ui/src/main.rs at line 352
println!("Message cannot be empty");Task::none()info!("Cannot record with an empty message"); - replacement in crates/flowers_ui/src/main.rs at line 355
// TODO: Make a record// Task::future(async move {// repo::record(&state.repo, msg).await;// Message::MadeRecord// })todo!()state.repo.as_mut().unwrap().changed_files =BTreeSet::new();let _ = state.repo_tx_in.send(repo::MsgIn::Record { msg }); - replacement in crates/flowers_ui/src/main.rs at line 360
},Message::MadeRecord => todo!(),Task::none()}}}fn update_from_repo(state: &mut State, msg: repo::MsgOut) -> Task<Message> {match msg {repo::MsgOut::Init(repo) => {state.repo = Some(repo);Task::none()}repo::MsgOut::RefreshedChangedAndUntrackedFiles {untracked_files,changed_files,} => {let repo = state.repo.as_mut().unwrap();repo.untracked_files = untracked_files;repo.changed_files = changed_files;// Re-index cursor selectionif let Some(selection) = state.cursor.selection.as_ref() {// Try to find the file with the same name. If not found, remove// selectionstate.cursor.selection = match selection {cursor::Selection::UntrackedFile { ix: _, path } => repo.untracked_files.iter().enumerate().find(|(_ix, file_path)| *file_path == path).map(|(ix, path)| cursor::Selection::UntrackedFile {ix,path: path.clone(),}),cursor::Selection::ChangedFile { ix: _, path } => repo.changed_files.iter().enumerate().find(|(_ix, file)| &file.path == path).map(|(ix, file)| cursor::Selection::ChangedFile {ix,path: file.path.clone(),}),};}Task::none()} - replacement in crates/flowers_ui/src/main.rs at line 439[4.1501]→[5.5140:5242](∅→∅),[6.3313]→[5.5242:5356](∅→∅),[5.5242]→[5.5242:5356](∅→∅),[5.5356]→[6.3314:3337](∅→∅),[6.3337]→[9.7545:7648](∅→∅),[9.7648]→[6.3518:3529](∅→∅),[6.3518]→[6.3518:3529](∅→∅),[6.3529]→[5.5394:5403](∅→∅),[5.5394]→[5.5394:5403](∅→∅)
let dir_name = repo::dir_name(&state.repo);let channel = repo::current_channel(&state.repo);let repo_info = Element::from(row([Element::from(text(dir_name)),Element::from(text(": ")),Element::from(button(text(channel)), /* TODO* .on_press(Message) */),]));if let Some(repo) = state.repo.as_ref() {let repo_info = Element::from(row([Element::from(text(&repo.dir_name)),Element::from(text(": ")),Element::from(button(text(&repo.channel)), /* TODO* .on_press(Message) */),])); - replacement in crates/flowers_ui/src/main.rs at line 449
let untracked_files =Element::from(column(state.repo.untracked_files.iter().enumerate().map(let untracked_files =Element::from(column(repo.untracked_files.iter().enumerate().map( - replacement in crates/flowers_ui/src/main.rs at line 465
let changed_files =Element::from(column(state.repo.changed_files.iter().enumerate().map(let changed_files =Element::from(column(repo.changed_files.iter().enumerate().map( - replacement in crates/flowers_ui/src/main.rs at line 481
let log = Element::from(column(["todo: commits"].iter().map(|hash| Element::from(text(*hash))),));let log = Element::from(column(["todo: commits"].iter().map(|hash| Element::from(text(*hash))),));let record_msg_editor =if let Some(record_msg) = state.record_msg.as_ref() {Element::from(text_editor(record_msg).placeholder("Type something here...").on_action(Message::EditRecordMsg),)} else {Element::from(row([]))}; - replacement in crates/flowers_ui/src/main.rs at line 498
let record_msg_editor = if let Some(record_msg) = state.record_msg.as_ref(){Element::from(text_editor(record_msg).placeholder("Type something here...").on_action(Message::EditRecordMsg),)Element::from(row([Element::from(column([repo_info,Element::from(horizontal_rule(1)),Element::from(text("Untracked:")),untracked_files,Element::from(horizontal_rule(1)),Element::from(text("Changed:")),changed_files,Element::from(horizontal_rule(1)),log,]).width(Length::FillPortion(1)),),Element::from(column([record_msg_editor]).width(Length::FillPortion(1)),),])) - replacement in crates/flowers_ui/src/main.rs at line 518[12.1953]→[12.1953:1992](∅→∅),[12.1992]→[5.5731:5826](∅→∅),[6.4171]→[5.5731:5826](∅→∅),[5.5731]→[5.5731:5826](∅→∅),[5.5826]→[9.8532:8667](∅→∅),[9.8667]→[5.5826:5877](∅→∅),[5.5826]→[5.5826:5877](∅→∅),[5.5877]→[9.8668:8717](∅→∅),[9.8717]→[5.5877:6050](∅→∅),[5.5877]→[5.5877:6050](∅→∅),[5.6050]→[12.1993:2098](∅→∅),[12.2098]→[5.6115:6123](∅→∅),[5.6115]→[5.6115:6123](∅→∅)
Element::from(row([]))};Element::from(row([Element::from(column([repo_info,Element::from(horizontal_rule(1)),Element::from(text("Untracked:")),untracked_files,Element::from(horizontal_rule(1)),Element::from(text("Changed:")),changed_files,Element::from(horizontal_rule(1)),log,]).width(Length::FillPortion(1)),),Element::from(column([record_msg_editor]).width(Length::FillPortion(1)),),]))Element::from(text("Loading repo..."))} - edit in crates/flowers_ui/Cargo.toml at line 27
workspace = true[dependencies.tracing] - edit in crates/flowers_ui/Cargo.toml at line 30[8.1864]
[dependencies.tracing-subscriber]workspace = true - edit in Cargo.toml at line 32
features = ["tokio"] - edit in Cargo.toml at line 61[3.6285]
[workspace.dependencies.tracing]version = "0.1"[workspace.dependencies.tracing-subscriber]version = "0.3"features = ["env-filter"][profile.dev]opt-level = 1 # Async seems to have big performance hit without this - edit in Cargo.lock at line 1361
"tracing","tracing-subscriber", - replacement in Cargo.lock at line 1628
"regex-automata","regex-syntax","regex-automata 0.4.9","regex-syntax 0.8.5", - edit in Cargo.lock at line 1867
"tokio", - replacement in Cargo.lock at line 1992
"regex-automata","regex-automata 0.4.9", - edit in Cargo.lock at line 2166
"tracing", - edit in Cargo.lock at line 2178
"tokio", - edit in Cargo.lock at line 2318
][[package]]name = "matchers"version = "0.1.0"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558"dependencies = ["regex-automata 0.1.10", - edit in Cargo.lock at line 2516
[[package]]name = "nu-ansi-term"version = "0.46.0"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84"dependencies = ["overload","winapi",] - edit in Cargo.lock at line 2834
[[package]]name = "overload"version = "0.1.1"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" - replacement in Cargo.lock at line 3350
"regex-automata","regex-syntax","regex-automata 0.4.9","regex-syntax 0.8.5",][[package]]name = "regex-automata"version = "0.1.10"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132"dependencies = ["regex-syntax 0.6.29", - replacement in Cargo.lock at line 3371
"regex-syntax","regex-syntax 0.8.5", - edit in Cargo.lock at line 3373
[[package]]name = "regex-syntax"version = "0.6.29"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" - edit in Cargo.lock at line 3626
][[package]]name = "sharded-slab"version = "0.1.7"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6"dependencies = ["lazy_static", - edit in Cargo.lock at line 3976
][[package]]name = "thread_local"version = "1.1.8"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c"dependencies = ["cfg-if","once_cell", - edit in Cargo.lock at line 4172
dependencies = ["once_cell","valuable",][[package]]name = "tracing-log"version = "0.2.0"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3"dependencies = ["log","once_cell","tracing-core",][[package]]name = "tracing-subscriber"version = "0.3.19"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008" - edit in Cargo.lock at line 4194
"matchers","nu-ansi-term", - edit in Cargo.lock at line 4197
"regex","sharded-slab","smallvec","thread_local","tracing","tracing-core","tracing-log", - edit in Cargo.lock at line 4319
name = "valuable"version = "0.1.1"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65"[[package]]