My personal-knowledge-system, with deeply integrated task tracking and long term goal planning capabilities.
2
fork

Configure Feed

Select the types of activity you want to include in your feed.

fix: creation of zettel's indexes properly

+67 -21
+15 -2
src/tui/app.rs
··· 1 1 use std::{process::Command, thread::spawn}; 2 2 3 - use color_eyre::eyre::Result; 3 + use color_eyre::eyre::{Context, Result}; 4 4 use crossterm::event::KeyEvent; 5 5 use ratatui::layout::Rect; 6 6 use serde::{Deserialize, Serialize}; ··· 192 192 // once we get out of the edit, we need to update the zettel for this 193 193 // path and then update the db and the kasten for this stuff 194 194 195 - self.kh.write().await.process_path(&path).await?; 195 + self.kh 196 + .write() 197 + .await 198 + .process_path(&path) 199 + .await 200 + .with_context(|| { 201 + format!( 202 + "Failed to process the path 203 + for this zettel: {}", 204 + path.display() 205 + ) 206 + })?; 207 + 208 + debug!("successfully processed path: {}", path.display()); 196 209 197 210 self.signal_tx.send(Signal::ClosedZettel)?; 198 211
+12 -9
src/tui/components/zk/mod.rs
··· 1 1 use async_trait::async_trait; 2 - use color_eyre::eyre::{ContextCompat, Result}; 2 + use color_eyre::eyre::{Context as _, ContextCompat, Result}; 3 3 use crossterm::event::KeyEvent; 4 4 use dto::{QueryOrder, TagEntity, ZettelColumns, ZettelEntity}; 5 5 use ratatui::{prelude::*, widgets::ListState}; ··· 243 243 let mut kt = self.kh.write().await; 244 244 245 245 // we create the zettel with the query as the 246 - let z = Zettel::new(self.search.query(), &mut kt).await?; 246 + let z = Zettel::new(self.search.query(), &mut kt) 247 + .await 248 + .with_context(|| "Failed to create a new Zettel!")?; 249 + 247 250 let path = z.absolute_path(&kt.index).to_path_buf(); 248 251 249 252 drop(kt); ··· 258 261 .selected() 259 262 .expect("This must be the zettel we just edited"); 260 263 264 + // regenerate a fresh zettel list 265 + self.zettel_list = ZettelList::new( 266 + self.get_zettels_by_current_query().await?, 267 + self.zettel_list.state, 268 + self.zettel_list.width, 269 + ); 270 + 261 271 let Some(zid) = self.zettel_list.id_list.get(selected) else { 262 272 return Ok(None); 263 273 }; ··· 271 281 // reset the state of the component 272 282 self.search.clear_query(); 273 283 self.zettel_list.state.select_first(); 274 - 275 - // regenerate a fresh zettel list 276 - self.zettel_list = ZettelList::new( 277 - self.get_zettels_by_current_query().await?, 278 - self.zettel_list.state, 279 - self.zettel_list.width, 280 - ); 281 284 282 285 self.zettel_view = ZettelView::from(&zettel); 283 286 self.preview = Preview::from(zettel.content(&kt.index).clone());
+8 -3
src/types/index.rs
··· 49 49 let id: ZettelId = path.as_path().try_into()?; 50 50 let (fm, body) = FrontMatter::extract_from_file(&path)?; 51 51 52 - Ok((id, ZettelOnDisk { fm, body, path })) 52 + Ok(( 53 + id, 54 + ZettelOnDisk { 55 + fm, 56 + body, 57 + path: path.canonicalize()?, 58 + }, 59 + )) 53 60 }) 54 61 .collect::<Result<Vec<_>>>()? 55 62 .into_iter() ··· 165 172 } 166 173 Ok(()) 167 174 } 168 - 169 - //TODO:need to process 170 175 171 176 pub fn get_zod(&self, zid: &ZettelId) -> &ZettelOnDisk { 172 177 self.zods.get(zid).expect("Invariant broken. Any zid we lookup must exist in the index, otherwise the db is corrupt or not sync'd.")
+16 -4
src/types/kasten.rs
··· 11 11 }; 12 12 use tracing::debug; 13 13 14 - use crate::types::{Index, ZettelId}; 14 + use crate::types::{FrontMatter, Index, ZettelId, index::ZettelOnDisk}; 15 15 16 16 #[derive(Debug, Clone)] 17 17 pub struct Kasten { ··· 91 91 //NOTE: need to clone to get around borrowing rules but 92 92 // ideally we dont have to do this, kind of cringe imo. 93 93 94 - let path = path.as_ref(); 95 - let zid = ZettelId::try_from(path)?; 94 + let path = path.as_ref().canonicalize()?; 95 + let zid = ZettelId::try_from(path.as_path())?; 96 + 97 + if !self.index.zods.contains_key(&zid) { 98 + let (fm, body) = FrontMatter::extract_from_file(&path)?; 99 + self.index.zods.insert( 100 + zid.clone(), 101 + ZettelOnDisk { 102 + fm, 103 + body, 104 + path: path.clone(), 105 + }, 106 + ); 107 + } 96 108 97 109 // incase the path of the zettel changed 98 - self.index.update_path_for_zid(&zid, path.to_path_buf()); 110 + self.index.update_path_for_zid(&zid, path.clone()); 99 111 // let the index process the zettel, basically update the internal state of the zod 100 112 self.index.process_zid(&zid)?; 101 113 // and then we sync tags
+16 -3
src/types/zettel/mod.rs
··· 4 4 DatabaseConnection, DateTime, TagEntity, ZettelActiveModel, ZettelEntity, ZettelModelEx, 5 5 }; 6 6 7 - use color_eyre::eyre::Result; 7 + use color_eyre::eyre::{Context, Result}; 8 8 use dto::NanoId; 9 9 use tokio::{fs::File, io::AsyncWriteExt}; 10 10 ··· 53 53 54 54 let local_file_path = format!("{nano_id}.md"); 55 55 56 + let absolute_file_path = kt.root.clone().join(&local_file_path); 57 + 56 58 // now we have to create the file 57 - let mut file = File::create_new(kt.root.clone().join(&local_file_path)).await?; 59 + let mut file = File::create_new(&absolute_file_path) 60 + .await 61 + .with_context(|| { 62 + format!("Failed to create file at local file path: {local_file_path}") 63 + })?; 58 64 59 65 let inserted = ZettelActiveModel::builder() 60 66 .set_title(title.clone()) ··· 79 85 80 86 file.write_all(front_matter.to_string().as_bytes()).await?; 81 87 82 - kt.process_path(zettel.file_path.clone()).await?; 88 + kt.process_path(&absolute_file_path) 89 + .await 90 + .with_context(|| { 91 + format!( 92 + "Kasten fails to process new Zettel at path: {}", 93 + absolute_file_path.display(), 94 + ) 95 + })?; 83 96 84 97 Ok(zettel.into()) 85 98 }