module Grep = Grep module Common = Common module Todos = Todos module Headlines = Headlines let start (tag : string) () = (* This is a rather funky state management that isn't maybe entirely functional. What we do is store a function for each view that restores it's state. Since the render function is void -> void This allows us to remember the state of the view and restore it as we travel between different views. It does create a rather funky, cyclical state though. *) if String.equal String.empty (String.trim Grep.execution_directory) then print_endline "Execution directory is not set. You will need to set environment variable \ STITCH_DIRECTORY to the absolute path of your notes. For example: \ STITCH_DIRECTORY='/home/you/notes'." else ( let term = Common.Term.create () in let restore_headline_state = ref (fun () -> ()) in let restore_done_state = ref (fun () -> ()) in let restore_todo_state = ref (fun () -> ()) in (* DONE *) let goto_todo_from_done new_done_state = restore_done_state := new_done_state; !restore_todo_state () in let goto_headlines_from_done new_done_state = restore_done_state := new_done_state; !restore_headline_state () in (restore_done_state := fun () -> let done_state = Done.init ~goto_headlines:goto_headlines_from_done ~goto_todo:goto_todo_from_done in Done.render term done_state); (* TODO *) let goto_done_from_todo new_todo_state = restore_todo_state := new_todo_state; !restore_done_state () in let goto_headline_from_todo new_todo_state = restore_todo_state := new_todo_state; !restore_headline_state () in (restore_todo_state := fun () -> let todo = Todos.init ~goto_headlines:goto_headline_from_todo ~goto_done:goto_done_from_todo in Todos.render term todo); let headline = Headlines.init ~goto_done_view:(fun new_state -> restore_headline_state := new_state; !restore_done_state ()) ~goto_todos_view:(fun new_state -> restore_headline_state := new_state; !restore_todo_state ()) ~regexp:tag in Headlines.render term headline)