mod prelude;
mod processor;
mod query;
mod state;
mod view;
use prelude::*;
pub fn start(vault: &Vault) -> Result<()> {
let mut state = State::SearchIdeas(
Query::new(vault.list_ideas().unwrap_or(vec![]))
);
let mut update_status: Option<UpdateStatus> = None; loop {
match update_status {
None => {
let mut stdin: Keys<AsyncReader> = termion::async_stdin().keys();
let stdout = io::stdout();
let mut term = init_term(stdout.lock())?;
term.clear()?;
term.hide_cursor()?;
let mut first_run = true;
loop {
let status = update(&mut stdin, &vault, &mut state)?;
update_status = Some(status.copy());
match status {
UpdateStatus::Changed => view::render(&mut term, &vault, &state)?,
UpdateStatus::Unchanged => if first_run {
first_run = false;
view::render(&mut term, &vault, &state)?;
}
UpdateStatus::Quit
| UpdateStatus::StartIdeaEditor(_)
| UpdateStatus::StartJournalEditor(_)
| UpdateStatus::StartNoteEditor(_, _)
| UpdateStatus::StartTaskEditor(_)
=> break,
}
sleep(Duration::from_millis(10));
}
term.clear()?;
},
Some(UpdateStatus::StartIdeaEditor(name)) => {
let saved = ideas::edit(&vault, name.to_owned())?;
if saved {
if let State::SearchIdeas(query) = &mut state {
query.results = vault.list_ideas().unwrap_or(vec![]);
for (i, (x, _)) in query.results.iter().enumerate() {
if x == &name {
query.selected_result_index = Some(i);
break;
}
}
query.input = String::from("");
}
}
update_status = None;
},
Some(UpdateStatus::StartJournalEditor(date)) => {
let saved = journals::edit(&vault, &date)?;
if saved {
if let State::SearchJournals(query) = &mut state {
let name = date.format();
query.results = vault.list_journals().unwrap_or(vec![]);
for (i, (x, _)) in query.results.iter().enumerate() {
if x == &name {
query.selected_result_index = Some(i);
break;
}
}
query.input = String::from("");
}
}
update_status = None;
},
Some(UpdateStatus::StartNoteEditor(category, name)) => {
let saved = notes::edit(&vault, &category, &name)?;
if saved {
if let State::SearchNotes(query) = &mut state {
query.results = vault.list_notes(true, &None).unwrap_or(vec![]);
let results = query.flatten_results();
for (i, (x, y, _, _)) in results.iter().enumerate() {
if x == &category && y == &name {
query.selected_result_index = Some(i);
break;
}
}
query.input = String::from("");
}
}
update_status = None;
},
Some(UpdateStatus::StartTaskEditor(project)) => {
let saved = tasks::edit(&vault, &project)?;
if saved {
if let State::SearchTasks(query) = &mut state {
query.results = vault.list_tasks(true, &None).unwrap_or(vec![]);
for (i, (x, _)) in query.results.iter().enumerate() {
if x == &project {
query.selected_result_index = Some(i);
break;
}
}
query.input = String::from("");
}
}
update_status = None;
},
Some(UpdateStatus::Quit) | _ => break,
}
}
Ok(())
}
fn init_term<'a>(stdout: io::StdoutLock<'a>) -> Result<Term<'a>> {
let raw_stdout = stdout.into_raw_mode()?;
let backend = TermionBackend::new(raw_stdout);
Ok(Terminal::new(backend)?)
}
fn update(stdin: &mut Keys<AsyncReader>, vault: &Vault, state: &mut State) -> Result<UpdateStatus> {
if let Some(key) = stdin.next() {
let key = key?;
Ok(process(vault, state, key))
} else {
Ok(UpdateStatus::Unchanged)
}
}