The config folder now sets everything: config.toml the settings (now also `theme` and `editor`), keys.toml the keys, and themes/<name>.toml the theme, laid over the built-in one, so a theme only needs what it changes. Each file is applied again a second after it's saved; a mistake only drops its own line, and the status bar says what's wrong, naming the file. :config lists the three files with their folder; Enter hands the terminal to your editor (the editor setting, $VISUAL, $EDITOR, else notepad or vi), writing the file first if it's missing, with every option at its default behind a #, explained (keys.toml lists every command by name). :theme switches themes until cumulus quits, like :set. The built-in theme gets the named styles the user picked, each also put on by its tag: question (yellow, dashed), important (red, thick) and done (gray, its title faded); and link styles blocks and supports, whose label shows on a link without its own. Themes can also set [modes], [node], [root], [branch] and [link]. Co-Authored-By: Claude Opus 5.5 <[email protected]>
71 lines
2.6 KiB
Rust
71 lines
2.6 KiB
Rust
//! cumulus: brainstorm in the terminal.
|
|
//!
|
|
//! This file only reads the command line. Everything else lives in the
|
|
//! library: `src/lib.rs` lists the modules.
|
|
|
|
use std::path::PathBuf;
|
|
use std::process::ExitCode;
|
|
|
|
use cumulus::app::startup::{self, Startup};
|
|
use cumulus::app::{App, run};
|
|
use cumulus::config::Config;
|
|
use cumulus::config::paths::Paths;
|
|
|
|
const USAGE: &str = "\
|
|
cumulus: brainstorm in the terminal
|
|
|
|
Usage:
|
|
cumulus open ./ideas.cum, or ~/ideas.cum
|
|
cumulus <file|folder>... open those documents (a folder: its ideas.cum)
|
|
cumulus new [title] make a new document here: ./ideas.cum, or a
|
|
file named after the title
|
|
|
|
Options:
|
|
--paths show where cumulus keeps its settings and data
|
|
-h, --help show this help
|
|
-V, --version show the version
|
|
|
|
Inside cumulus, ? shows every key.";
|
|
|
|
fn main() -> ExitCode {
|
|
match start(std::env::args().skip(1).collect()) {
|
|
Ok(()) => ExitCode::SUCCESS,
|
|
Err(error) => {
|
|
eprintln!("cumulus: {error}");
|
|
ExitCode::FAILURE
|
|
}
|
|
}
|
|
}
|
|
|
|
fn start(args: Vec<String>) -> Result<(), String> {
|
|
let startup = match args.first().map(String::as_str) {
|
|
None => Startup::Default,
|
|
Some("-h" | "--help") => {
|
|
println!("{USAGE}");
|
|
return Ok(());
|
|
}
|
|
Some("-V" | "--version") => {
|
|
println!("{}", cumulus::version());
|
|
return Ok(());
|
|
}
|
|
Some("--paths") => {
|
|
let paths = Paths::locate().map_err(|error| error.to_string())?;
|
|
println!("config {} (config.toml, keys.toml, themes)", paths.config.display());
|
|
println!("data {} (where you left off, history, backups, locks)", paths.data.display());
|
|
return Ok(());
|
|
}
|
|
Some(option) if option.starts_with('-') => return Err(format!("unknown option {option}\n\n{USAGE}")),
|
|
// The title's words, quoted or not: `cumulus new Garden plans`.
|
|
Some("new") => Startup::New((args.len() > 1).then(|| args[1..].join(" "))),
|
|
Some(_) => Startup::Open(args.iter().map(PathBuf::from).collect()),
|
|
};
|
|
let paths = Paths::locate().map_err(|error| error.to_string())?;
|
|
// The config folder first: it names the document `cumulus` looks for.
|
|
let config = Config::load(&paths);
|
|
let here =
|
|
std::env::current_dir().map_err(|error| format!("can't tell which folder this is: {error}"))?;
|
|
let opening =
|
|
startup::open(&startup, &paths, &here, &config.settings).map_err(|error| error.to_string())?;
|
|
run(App::new(paths, config, opening)).map_err(|error| error.to_string())
|
|
}
|