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:
1 parent
f6dc4564aa
commit
abe3dc1d84
26 files changed
+1683
-129
No files matched your search
@@ -59,8 +59,11 @@ impl Scene {
|
||||
}
|
||||
}
|
||||
}
|
||||
let title_style =
|
||||
if node.selected { Style::new().add_modifier(Modifier::BOLD) } else { Style::new() };
|
||||
let title_style = match (node.selected, node.faded) {
|
||||
(true, _) => Style::new().add_modifier(Modifier::BOLD),
|
||||
(false, true) => Style::new().fg(self.muted),
|
||||
(false, false) => Style::new(),
|
||||
};
|
||||
for (row, line) in (rect.top() + 1..).zip(lines) {
|
||||
painter.text(ScreenPos::new(rect.left() + 2, row), line, title_style, &mine);
|
||||
}
|
||||
@@ -93,7 +96,8 @@ impl Scene {
|
||||
if let Some(bullet) = chars.next() {
|
||||
painter.put(node.rect.pos, bullet, Style::new().fg(node.color));
|
||||
let rest = ScreenPos::new(node.rect.left() + 1, node.rect.top());
|
||||
painter.text(rest, chars.as_str(), Style::new(), |_| true);
|
||||
let style = if node.faded { Style::new().fg(self.muted) } else { Style::new() };
|
||||
painter.text(rest, chars.as_str(), style, |_| true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -44,6 +44,8 @@ pub struct SceneNode {
|
||||
pub shape: Shape,
|
||||
/// Its color: the border, bullet or dot.
|
||||
pub color: Color,
|
||||
/// Its title in the quiet color (the `done` style).
|
||||
pub faded: bool,
|
||||
/// Whether the cursor is on it.
|
||||
pub selected: bool,
|
||||
}
|
||||
@@ -118,7 +120,8 @@ impl Scene {
|
||||
Some(edit) => scene.draft(node, edit, badge, style.border, camera, max_width),
|
||||
None => shape(node, badge, style.border, camera, theme.glyphs, max_width),
|
||||
};
|
||||
scene.nodes.push(SceneNode { id, rect, shape, color: style.color, selected: id == cursor });
|
||||
let (color, faded, selected) = (style.color, style.faded, id == cursor);
|
||||
scene.nodes.push(SceneNode { id, rect, shape, color, faded, selected });
|
||||
}
|
||||
// The cursor's node goes last, on top of any it overlaps.
|
||||
if let Some(index) = scene.nodes.iter().position(|node| node.selected) {
|
||||
@@ -245,7 +248,7 @@ impl Scene {
|
||||
continue;
|
||||
};
|
||||
let style = theme.link_style(&link.look, self.nodes[start].color);
|
||||
let label = link.label.as_ref().map(|label| label.as_str());
|
||||
let label = theme.link_label(link);
|
||||
self.connect(start, end, Bend::Halfway, style, LineOwner::Link(link.key()), label);
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -174,7 +174,7 @@ impl NoteView {
|
||||
.map(|link| {
|
||||
let out = link.start() == id;
|
||||
let other = if out { link.end() } else { link.start() };
|
||||
(out, other, link.label.as_ref().map(ToString::to_string).unwrap_or_default())
|
||||
(out, other, theme.link_label(link).unwrap_or_default().to_string())
|
||||
})
|
||||
.collect();
|
||||
links.sort_by_key(|&(out, _, _)| !out);
|
||||
|
||||
+4
-1
@@ -164,7 +164,8 @@ impl OutlineView {
|
||||
let (doc, theme, glyphs) = (ctx.doc, ctx.theme, ctx.theme.glyphs);
|
||||
let Some(node) = doc.node(id) else { return };
|
||||
let top_level = lines.spans.is_empty();
|
||||
let color = theme.node_style(node, id == doc.root()).color;
|
||||
let style = theme.node_style(node, id == doc.root());
|
||||
let color = style.color;
|
||||
let has_children = !doc.children(id).is_empty();
|
||||
let folded = visible.hidden.contains_key(&id);
|
||||
let marker = if node.is_portal() {
|
||||
@@ -184,6 +185,8 @@ impl OutlineView {
|
||||
let muted = Style::new().fg(theme.muted);
|
||||
let title_style = if id == ctx.cursor {
|
||||
Style::new().fg(Color::Black).bg(theme.accent).add_modifier(Modifier::BOLD)
|
||||
} else if style.faded {
|
||||
muted
|
||||
} else {
|
||||
Style::new()
|
||||
};
|
||||
|
||||
Reference in new issue
Block a user