···124124 # Set any environment variables for your dev shell
125125 env = {
126126 RUST_SRC_PATH = "${pkgs.rustToolchain}/lib/rustlib/src/rust/library";
127127+128128+ # project specific vars
127129 FIL_CONFIG = "./.config";
128130 FIL_DATA = "./.data";
131131+ FIL_LOG_LEVEL = "DEBUG";
129132 };
130133131134 # Add any shell logic you want executed any time the environment is activated
+4-4
src/cli/process.rs
···2424 Workspace::initialize(dir.clone()).await?;
25252626 // write config that sets the filaments directory to current dir!
2727- let config_kdl = dbg! {Config::generate(&dir)};
2727+ let config_str = dbg! {Config::generate(&dir)}?;
28282929 // create the config dir
3030 let config_dir = get_config_dir();
31313232 create_dir_all(config_dir).expect("creating the config dir should not error");
33333434- let mut config_file = File::create(get_config_dir().join("config.kdl"))
3434+ let mut config_file = File::create(get_config_dir().join("config.ron"))
3535 .context("Failed to create config file")?;
36363737- write!(config_file, "{config_kdl}")?;
3737+ write!(config_file, "{config_str}")?;
38383939 println!("wrote config to {config_file:#?}");
4040···44444545 Self::Zettel(zettel_sub_command) => {
4646 let conf = Config::parse()?;
4747- let ws = Workspace::instansiate(conf.app_config.workspace).await?;
4747+ let ws = Workspace::instansiate(conf.fil_dir).await?;
48484949 match zettel_sub_command {
5050 ZettelSubcommand::New { title } => {
-152
src/config.rs
···11-use color_eyre::eyre::Context;
22-use directories::ProjectDirs;
33-use kdl::KdlDocument;
44-use serde::Deserialize;
55-use std::{
66- env::{self, home_dir},
77- fmt::Debug,
88- fs::File,
99- io::Read,
1010- path::{Path, PathBuf},
1111- sync::LazyLock,
1212-};
1313-1414-use crate::tui::KeyMap;
1515-1616-/// Project Name: Filaments
1717-pub static PROJECT_NAME: LazyLock<String> =
1818- LazyLock::new(|| env!("CARGO_CRATE_NAME").to_uppercase());
1919-2020-/// The OS-agnostic data directory for the project.
2121-pub static DATA_DIRECTORY: LazyLock<Option<PathBuf>> = LazyLock::new(|| {
2222- env::var(format!("{}_DATA", PROJECT_NAME.clone()))
2323- .ok()
2424- .map(PathBuf::from)
2525-});
2626-2727-/// The OS-agnostic config directory for the project.
2828-pub static CONFIG_DIRECTORY: LazyLock<Option<PathBuf>> = LazyLock::new(|| {
2929- env::var(format!("{}_CONFIG", PROJECT_NAME.clone()))
3030- .ok()
3131- .map(PathBuf::from)
3232-});
3333-3434-const DEFAULT_CONFIG: &str = include_str!("../.config/config.kdl");
3535-3636-/// The App Config and Data locations.
3737-#[derive(Clone, Debug, Deserialize, Default)]
3838-#[expect(dead_code)]
3939-pub struct AppConfig {
4040- /// The directory where the single instance of the filaments exists.
4141- pub workspace: PathBuf,
4242- #[serde(default)]
4343- pub data: PathBuf,
4444- #[serde(default)]
4545- pub config: PathBuf,
4646-}
4747-4848-/// Configuration for the App
4949-#[derive(Debug, Clone)]
5050-pub struct Config {
5151- pub app_config: AppConfig,
5252- pub keymap: KeyMap,
5353- // pub styles: Styles,
5454-}
5555-5656-impl Config {
5757- /// generates a new config with the provided `filaments_dir`
5858- pub fn generate(filaments_dir: &Path) -> KdlDocument {
5959-6060-6161- let mut default_config: KdlDocument = DEFAULT_CONFIG
6262- .parse()
6363- .expect("Default config should always be a valid KDL document.");
6464-6565- if let Some(node) = default_config
6666- .nodes_mut()
6767- .iter_mut()
6868- .find(|n| n.name().value() == "filaments_dir")
6969- && let Some(entry) = node.entries_mut().get_mut(0)
7070- {
7171- *entry.value_mut() = kdl::KdlValue::String(filaments_dir.to_string_lossy().to_string());
7272- entry.clear_format();
7373- }
7474-7575- default_config
7676- }
7777-7878- /// Parse the config from `~/.config/filametns`
7979- ///
8080- /// # Errors
8181- ///
8282- /// Will error if the config doesn't exist or if there
8383- /// is a problem parsing it.
8484- pub fn parse() -> color_eyre::Result<Self> {
8585- let config: KdlDocument = {
8686- let file_path = get_config_dir().join("config.kdl");
8787-8888- let mut file = File::open(file_path).context("Failed to find file!")?;
8989-9090- let mut str = String::new();
9191-9292- file.read_to_string(&mut str)
9393- .context("Failed to read file!")?;
9494-9595- str.parse().context("Expected to be valid kdl")?
9696- };
9797-9898- let keymap = KeyMap::try_from(
9999- config
100100- .get("keymap")
101101- .expect("Keymap must exist in the config"),
102102- )
103103- .context("Keymap is not valid!")?;
104104-105105- let filaments_dir_str = config
106106- .get("filaments_dir")
107107- .expect("config should always have this specified")
108108- .get(0)
109109- .and_then(|arg| arg.as_string())
110110- .expect("filaments_dir must be a string");
111111-112112- let filaments_dir = PathBuf::from(filaments_dir_str)
113113- .canonicalize()
114114- .context("Filaments directory does not exist!")?;
115115-116116- Ok(Self {
117117- app_config: AppConfig {
118118- workspace: filaments_dir,
119119- data: get_data_dir(),
120120- config: get_config_dir(),
121121- },
122122- keymap,
123123- })
124124- }
125125-}
126126-127127-/// Returns the path to the OS-agnostic data directory.
128128-pub fn get_data_dir() -> PathBuf {
129129- DATA_DIRECTORY.clone().unwrap_or_else(|| {
130130- project_directory().map_or_else(
131131- || PathBuf::from(".").join(".data"),
132132- |proj_dirs| proj_dirs.data_local_dir().to_path_buf(),
133133- )
134134- })
135135-}
136136-137137-/// Returns the path to the OS-agnostic config directory.
138138-pub fn get_config_dir() -> PathBuf {
139139- CONFIG_DIRECTORY.clone().unwrap_or_else(|| {
140140- home_dir().map_or_else(
141141- || PathBuf::from(".").join(".config"),
142142- |mut path| {
143143- path.push(".config");
144144- path.push("filaments");
145145- path
146146- },
147147- )
148148- })
149149-}
150150-fn project_directory() -> Option<ProjectDirs> {
151151- ProjectDirs::from("com", "suri-codes", env!("CARGO_PKG_NAME"))
152152-}
···11+use color_eyre::eyre::{Result, eyre};
22+use crossterm::event::{KeyCode, KeyModifiers};
13use std::{
24 collections::HashMap,
35 ops::{Deref, DerefMut},
46};
55-66-use crossterm::event::{KeyCode, KeyEvent, KeyModifiers};
77-use kdl::KdlNode;
87use strum::IntoEnumIterator;
981010-use crate::tui::{Signal, app::Region};
99+use crossterm::event::KeyEvent;
11101111+use crate::{
1212+ config::file::RonConfig,
1313+ tui::{Region, Signal},
1414+};
1215#[derive(Debug, Clone)]
1316pub struct KeyMap(pub HashMap<Region, HashMap<Vec<KeyEvent>, Signal>>);
14171515-impl TryFrom<&KdlNode> for KeyMap {
1818+impl TryFrom<&RonConfig> for KeyMap {
1619 type Error = color_eyre::Report;
17201818- fn try_from(value: &KdlNode) -> std::result::Result<Self, Self::Error> {
1919- let mut all_binds = HashMap::new();
2121+ fn try_from(value: &RonConfig) -> Result<Self, Self::Error> {
2222+ let mut binds = HashMap::new();
20232124 for region in Region::iter() {
2225 let mut region_binds = HashMap::new();
2323- let Some(binds) = value
2424- .children()
2525- .expect("Keymap must have children.")
2626- .get(®ion.to_string())
2727- else {
2828- continue;
2626+2727+ let mut parse_and_insert = |str: &str, bind: &Signal| -> Result<()> {
2828+ let key_seq = parse_key_sequence(str).map_err(|e| {
2929+ eyre!(format!(
3030+ "Failed to parse the following keybind as valid keybind: {e}"
3131+ ))
3232+ })?;
3333+3434+ region_binds.insert(key_seq, bind.clone());
3535+ Ok(())
2936 };
30373131- // now we iter through the things children
3232- for child in binds.iter_children() {
3333- let key_combo_str = child.name().to_string();
3434- let key_combo_str = key_combo_str.trim();
3838+ // first thing we have to do is insert the global binds for this region
35393636- let signal_str = child
3737- .entries()
3838- .first()
3939- .expect("A bind must map to an entry")
4040- .to_string();
4141- let signal_str = signal_str.trim();
4242-4343- let signal: Signal = signal_str.parse().expect("Must be a \"bindable\" Signal");
4444- let key_combo = parse_key_sequence(key_combo_str).unwrap();
4040+ for (str, bind) in &value.global_key_binds {
4141+ parse_and_insert(str, bind)?;
4242+ }
45434646- let _ = region_binds.insert(key_combo, signal);
4444+ // now we insert the region specific binds
4545+ for (str, bind) in match region {
4646+ Region::Zk => value.zk.keybinds.iter(),
4747+ Region::Todo => value.todo.keybinds.iter(),
4848+ } {
4949+ parse_and_insert(str, bind)?;
4750 }
48514949- let _ = all_binds.insert(region, region_binds);
5252+ binds.insert(region, region_binds);
5053 }
51545252- Ok(Self(all_binds))
5555+ Ok(Self(binds))
5356 }
5457}
5558···170173171174#[cfg(test)]
172175mod test {
173173- use crossterm::event::{KeyEvent, KeyModifiers};
174174- use kdl::KdlNode;
176176+ // use crossterm::event::{KeyEvent, KeyModifiers};
177177+ // use kdl::KdlNode;
175178176176- use crate::tui::{KeyMap, Signal, app::Region};
179179+ // use crate::tui::{KeyMap, Region, Signal};
177180178181 #[test]
179182 fn test_quit_in_home_region() {
180180- let keymap_str = "
181181- keymap {
182182- Todo {
183183- q Quit
184184- <Ctrl-C> Quit
185185- }
186186- }
187187- ";
183183+ // let keymap_str = "
184184+ // keymap {
185185+ // Todo {
186186+ // q Quit
187187+ // <Ctrl-C> Quit
188188+ // }
189189+ // }
190190+ // ";
188191189189- let kdl: &KdlNode = &keymap_str
190190- .parse()
191191- .expect("Keymap_str should be a valid KDL document");
192192+ // let kdl: &KdlNode = &keymap_str
193193+ // .parse()
194194+ // .expect("Keymap_str should be a valid KDL document");
192195193193- let keymap: KeyMap = kdl.try_into().expect("Must be a valid keymap");
196196+ // let keymap: KeyMap = kdl.try_into().expect("Must be a valid keymap");
194197195195- let map = keymap
196196- .get(&Region::Todo)
197197- .expect("Home region must exist in keymap");
198198+ // let map = keymap
199199+ // .get(&Region::Todo)
200200+ // .expect("Home region must exist in keymap");
198201199199- let signal = map
200200- .get(&vec![KeyEvent::new_with_kind(
201201- crossterm::event::KeyCode::Char('q'),
202202- KeyModifiers::empty(),
203203- crossterm::event::KeyEventKind::Press,
204204- )])
205205- .expect("Must resolve to a signal");
202202+ // let signal = map
203203+ // .get(&vec![KeyEvent::new_with_kind(
204204+ // crossterm::event::KeyCode::Char('q'),
205205+ // KeyModifiers::empty(),
206206+ // crossterm::event::KeyEventKind::Press,
207207+ // )])
208208+ // .expect("Must resolve to a signal");
206209207207- assert_eq!(*signal, Signal::Quit);
210210+ // assert_eq!(*signal, Signal::Quit);
208211 }
209212}
+1-4
src/tui/mod.rs
···11/// The tui app
22mod app;
33pub use app::App as TuiApp;
44+pub use app::Region;
4556/// Tui components
67mod components;
···910mod raw_tui;
1011pub use raw_tui::Event;
1112pub use raw_tui::Tui;
1212-1313-/// Keymap for mapping keybinds to regions
1414-mod keymap;
1515-pub use keymap::KeyMap;
16131714/// Singals for commands needing to be processed
1815mod signal;
+17-1
src/types/kasten.rs
···99use rayon::iter::{ParallelBridge as _, ParallelIterator as _};
1010use std::{cmp::max, collections::HashMap, path::Path, sync::Arc};
1111use tokio::sync::RwLock;
1212+use tracing::{error, info};
12131314use crate::types::Workspace;
1415···5657 .map(|entry| entry.path())
5758 .collect::<Vec<_>>();
58596060+ info!(
6161+ "indexing the following paths {paths:#?} at root {:#?}",
6262+ ws.root
6363+ );
6464+5965 let zettel_tasks = paths
6066 .into_iter()
6167 .map(|path| {
···6874 let zettels = futures::future::join_all(zettel_tasks)
6975 .await
7076 .into_iter()
7171- .filter_map(|result| result.ok()?.ok())
7777+ .filter_map(|result| {
7878+ result
7979+ .inspect_err(|e| error!("Failed to join on zettel task parsing: {e:#?}"))
8080+ .ok()?
8181+ .inspect_err(|e| error!("Failed to parse file into zettel: {e:#?}"))
8282+ .ok()
8383+ })
7284 .collect::<Vec<Zettel>>();
8585+8686+ info!("zettels: {zettels:#?}");
73877488 // capacity!
7589 let mut graph: ZkGraph = ZkGraph::from(&StableGraph::with_capacity(
···96110 graph.add_edge(*src, *dst, link.clone());
97111 }
98112 }
113113+114114+ info!("parsed graph: {graph:#?}");
99115100116 Ok(Self {
101117 _private: (),