Read config.toml, keys.toml and themes, and open them with :config (stage 8b)

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]>
This commit is contained in:
skkeyeandClaude Opus 5.5 committed 2026-10-01 23:55:11 -04:00
1 parent f6dc4564aa
commit abe3dc1d84
26 files changed
+1683 -129

No files matched your search

+17 -4
View File
@@ -22,6 +22,7 @@ pub mod action;
pub mod buffer;
pub mod calls;
pub mod commands;
mod configure;
pub mod documents;
mod files;
mod input;
@@ -35,6 +36,7 @@ mod terminal;
pub mod text_edit;
mod update;
use std::path::PathBuf;
use std::time::Instant;
use ratatui::layout::Rect;
@@ -43,6 +45,7 @@ pub use files::{Loaded, OpenError, create, load};
pub use terminal::run;
use crate::command::history::History as CommandHistory;
use crate::config::Config;
use crate::config::paths::Paths;
use crate::config::settings::Settings;
use crate::input::bindings::Context;
@@ -86,6 +89,11 @@ pub struct App {
dragging: Option<PaneId>,
/// When the files were last checked for changes made outside cumulus.
watched: Instant,
/// The config files as they were last read, to apply them again when
/// they change.
config_stamps: configure::ConfigStamps,
/// A file `:config` wants opened in the editor: the main loop does it.
edit_request: Option<PathBuf>,
quit: bool,
}
@@ -147,11 +155,13 @@ struct Screen {
}
impl App {
/// cumulus with the documents of `opening` open, the first one shown.
pub fn new(paths: Paths, settings: Settings, keymap: Keymap, opening: Opening) -> App {
/// cumulus with its config, and the documents of `opening` open, the
/// first one shown.
pub fn new(paths: Paths, config: Config, opening: Opening) -> App {
let memory = Memory::load(&paths.memory());
let Opening { first, others, message } = opening;
let theme = Theme { glyphs: settings.glyphs, ..Theme::default() };
let Config { settings, keymap, theme, problems } = config;
let config_stamps = configure::ConfigStamps::read(&paths, &settings.theme);
let view = ViewSettings { max_node_width: settings.max_node_width, ..ViewSettings::default() };
let (docs, first_said) = files::open_first(first, &paths);
let first = docs.at(0);
@@ -170,13 +180,16 @@ impl App {
screen: Screen::default(),
dragging: None,
watched: Instant::now(),
config_stamps,
edit_request: None,
quit: false,
};
app.came_back_to(first);
if let Some(camera) = app.shared.docs.get(first).camera {
app.panes.current_mut().view.set_camera(camera);
}
let mut said: Vec<Message> = message.into_iter().chain(first_said).collect();
let config_said = problems.into_iter().map(Message::problem);
let mut said: Vec<Message> = config_said.chain(message).chain(first_said).collect();
for loaded in others {
said.extend(app.add_document(loaded).1);
}