write 0.5.0

A fullscreen, distraction-free, write-only Markdown editor that fades text away to silence the writer's inner editor.
mod app;

use clap::{Parser, Subcommand};
use eframe::egui;

/// A fullscreen, distraction-free, write-only Markdown editor that fades text away.
#[derive(Parser)]
#[command(version, about)]
struct Cli {
    #[command(subcommand)]
    command: Option<Command>,
}

#[derive(Subcommand)]
enum Command {
    /// Open today's session file in your editor ($VISUAL/$EDITOR/vi).
    Edit,
    /// Print today's session file to stdout verbatim (nothing if it doesn't exist).
    Show,
}

fn main() -> eframe::Result {
    // Subcommands run without ever launching the fading TUI (and without taking the
    // session lock or flashing a window).
    match Cli::parse().command {
        Some(Command::Edit) => {
            if let Err(e) = app::run_edit() {
                eprintln!("write: {e}");
                std::process::exit(1);
            }
            return Ok(());
        }
        Some(Command::Show) => {
            if let Err(e) = app::run_show() {
                eprintln!("write: {e}");
                std::process::exit(1);
            }
            return Ok(());
        }
        None => {}
    }

    // Acquire today's session file + lock before opening a window. If another
    // `write` is already running today, exit quietly without flashing a window.
    let (file, seed_words, boot_size) = match app::open_session_file() {
        Ok(Some(triple)) => triple,
        Ok(None) => {
            eprintln!("write: another session already holds today's file; exiting.");
            return Ok(());
        }
        Err(e) => {
            eprintln!("write: {e}");
            std::process::exit(1);
        }
    };

    let native_options = eframe::NativeOptions {
        // Don't request fullscreen at build time: a bare `cargo run` binary isn't the
        // foreground app yet during window creation, so native fullscreen races, the
        // Space collapses, and focus bounces to Finder. Instead launch as a maximized,
        // chrome-hidden (but titled) window and enter fullscreen from `WriteApp::ui`
        // once the window actually has focus.
        viewport: egui::ViewportBuilder::default()
            .with_titlebar_shown(false)
            .with_title_shown(false)
            .with_fullsize_content_view(true)
            .with_maximized(true),
        ..Default::default()
    };
    eframe::run_native(
        "write",
        native_options,
        Box::new(move |cc| {
            Ok(Box::new(app::WriteApp::new(
                cc, file, seed_words, boot_size,
            )))
        }),
    )
}