1use std::{borrow::Cow, path::Path, process::ExitCode};
2use clap::Parser;
3use clapx::styl::srctrait::*;
4use clapx::subcmd::cli::CliCommand;
5use srctrait_common_tomlx::starter::trim_starter_toml_file_comments;
6use tomlx::ToStarterToml;
7use crate::*;
8
9pub fn run() -> ExitCode {
10 match run_cli() {
11 Ok(_) => ExitCode::SUCCESS,
12 Err(e) => {
13 let source = e.source()
14 .map_or(String::new(), |s| format!("\n {s}"));
15
16 eprintln!("{STYL_ERROR}error:{STYL_ERROR:#} {e}{source}");
17 ExitCode::FAILURE
18 }
19 }
20}
21
22fn run_cli() -> anyhow::Result<()> {
23 let cli = Cli::parse();
24 match cli.command {
25 Command::Cli(cmd) => match cmd {
26 CliCommand::Config(_cmd) => run_config(),
27 CliCommand::Alias(_cmd) => todo!(),
28 },
29 Command::Today(cmd) => match &cmd.from {
30 Some(TodaySubCommand::From{when}) => run_today_from(when),
31 None => run_today()
32 },
33 Command::Yesterday => run_yesterday(),
34 Command::Day{when} => run_day(when),
35 Command::Idea{topic} => run_idea(topic),
36 Command::Todo{topic} => run_todo(topic),
37 Command::Plan{topic} => run_plan(topic),
38 Command::Pick{kind} => run_pick(kind),
39 }
40}
41
42fn init_user() -> anyhow::Result<(lib::NoteConfig, lib::NotesDir)> {
43 let config = user_notes_config()?;
44 let dir = user_notes_dir(&config)?;
45 dir.init()?;
46 Ok((config, dir))
47}
48
49fn run_config() -> anyhow::Result<()> {
50 let (config, _notes_dir) = init_user()?;
51 let config_file = note_config_file()?;
52 let first_run = !config_file.is_file();
53
54 if first_run {
55 config.to_starter_toml_file(&config_file, tomlx::starter::GENERIC_INTRO)?;
56 }
57
58 run_editor(&config, &config_file)?;
59
60 if first_run {
61 trim_starter_toml_file_comments(&config_file)?;
62 }
63
64 Ok(())
65}
66
67fn run_today() -> anyhow::Result<()> {
68 let (config, notes_dir) = init_user()?;
69 let note = lib::Note::new(lib::NoteType::Today(lib::Date::now()));
70 let note_file = lib::note_for_date(¬es_dir, ¬e, None)?;
71 run_editor(&config, ¬e_file)
72}
73
74fn run_today_from(when: &str) -> anyhow::Result<()> {
75 let (config, notes_dir) = init_user()?;
76 let today = lib::Date::now();
77 let when = today.from(when)?;
78 let note = lib::Note::new(lib::NoteType::Today(today));
79 let note_file = lib::note_for_date(¬es_dir, ¬e, Some(when))?;
80 run_editor(&config, ¬e_file)
81}
82
83fn run_day(when: String) -> anyhow::Result<()> {
84 let (config, notes_dir) = init_user()?;
85 let note = lib::Note::new(lib::NoteType::Today(lib::Date::now().from(&when)?));
86 let note_file = lib::note_for_date(¬es_dir, ¬e, None)?;
87 run_editor(&config, ¬e_file)
88}
89
90fn run_yesterday() -> anyhow::Result<()> {
91 let (config, notes_dir) = init_user()?;
92 let note = lib::Note::new(lib::NoteType::Today(lib::Date::now().from("yesterday")?));
93 let note_file = lib::note_for_date(¬es_dir, ¬e, None)?;
94 run_editor(&config, ¬e_file)
95}
96
97fn run_idea(topic: String) -> anyhow::Result<()> {
98 let (config, notes_dir) = init_user()?;
99 let note = lib::Note::new(lib::NoteType::Idea(topic.to_string()));
100 let note_file = lib::note_for_topic(¬es_dir, ¬e)?;
101 run_editor(&config, ¬e_file)
102}
103
104fn run_todo(topic: String) -> anyhow::Result<()> {
105 let (config, notes_dir) = init_user()?;
106 let note = lib::Note::new(lib::NoteType::Todo(topic.to_string()));
107 let note_file = lib::note_for_topic(¬es_dir, ¬e)?;
108 run_editor(&config, ¬e_file)
109}
110
111fn run_plan(topic: Option<String>) -> anyhow::Result<()> {
112 let (config, notes_dir) = init_user()?;
113 let note = lib::Note::new(lib::NoteType::Plan(topic));
114 let note_file = lib::note_for_optional_topic(¬es_dir, ¬e)?;
115 run_editor(&config, ¬e_file)
116}
117
118fn run_pick(kind: Option<CliNoteKind>) -> anyhow::Result<()> {
119 let (config, notes_dir) = init_user()?;
120 let kind: Option<lib::NoteKind> = kind.map(|k| k.into());
121 let dir: Cow<'_, Path> = if let Some(kind) = kind {
122 Cow::Owned(notes_dir.kind_dir(kind))
123 } else {
124 Cow::Borrowed(¬es_dir)
125 };
126
127 if let Some(note_path) = run_picker(&config, &dir)? {
128 lib::Note::from_filepath(¬es_dir, ¬e_path)?;
129 run_editor(&config, ¬e_path)
130 } else {
131 println!("Cancelled.");
132 Ok(())
133 }
134}