docs(comments): rewrite comments across all crates to the guidelines
Sweep every first-party crate source (1956 .rs files) to the project comment guidelines: delete redundant restatements, decorative banners, change narration, and end-of-line comments; keep and tighten the crucial ones (invariants, bug rationale, SAFETY blocks, ported-source attribution). No functional code changed. Every edit is proven comment-only against the prior tree by a comment-stripping lexer (string/char/raw-string aware) plus a separate doctest-fence check. Where removing a comment made rustfmt or clippy want to re-lay-out adjacent code, the minimal triggering comment is restored so code tokens stay byte-identical. Gates green: cargo fmt --all --check (0 diffs), cargo check and cargo clippy --workspace --all-targets (0 warnings). Adds scripts/check_codegen_comment_guidelines.py — the enforcement gate for these guidelines (flags banners, end-of-line comments, change narration, and commented-out code).
This commit is contained in:
1 parent
ff0fb56c67
commit
a02b555e66
1458 files changed
+10729
-21750
No files matched your search
@@ -22,7 +22,7 @@ use super::render_mermaid::RenderMermaid;
|
||||
use super::scroll_mode::ScrollMode;
|
||||
use super::text_selection::TextSelection;
|
||||
|
||||
// -- Defaults (asserted in tests to match UiConfig::default()) --------------
|
||||
// Defaults (asserted in tests to match UiConfig::default())
|
||||
|
||||
const COMPACT_DEFAULT: bool = false;
|
||||
const TIMESTAMPS_DEFAULT: bool = true;
|
||||
@@ -52,7 +52,7 @@ const SCROLL_LINES_UNSET: u8 = 0;
|
||||
const SCROLL_LINES_MIN: u8 = 1;
|
||||
const SCROLL_LINES_MAX: u8 = 10;
|
||||
|
||||
// -- Compact mode ------------------------------------------------------------
|
||||
// Compact mode
|
||||
|
||||
thread_local! {
|
||||
static COMPACT_CURRENT: Cell<bool> = const { Cell::new(COMPACT_DEFAULT) };
|
||||
@@ -75,13 +75,13 @@ pub fn load() -> bool {
|
||||
COMPACT_CURRENT.with(|c| c.get())
|
||||
}
|
||||
|
||||
/// Replace cached `compact_mode` (optimistic update or rollback).
|
||||
/// Replace cached `compact_mode` (optimistic write or rollback).
|
||||
pub fn set(enabled: bool) {
|
||||
COMPACT_CURRENT.with(|c| c.set(enabled));
|
||||
COMPACT_LOADED.with(|l| l.set(true));
|
||||
}
|
||||
|
||||
// -- Timestamps --------------------------------------------------------------
|
||||
// Timestamps
|
||||
|
||||
thread_local! {
|
||||
static TIMESTAMPS_CURRENT: Cell<bool> = const { Cell::new(TIMESTAMPS_DEFAULT) };
|
||||
@@ -108,7 +108,7 @@ pub fn set_timestamps(enabled: bool) {
|
||||
TIMESTAMPS_LOADED.with(|l| l.set(true));
|
||||
}
|
||||
|
||||
// -- Timeline sidebar ----------------------------------------------------------
|
||||
// Timeline sidebar
|
||||
|
||||
thread_local! {
|
||||
static TIMELINE_CURRENT: Cell<bool> = const { Cell::new(TIMELINE_DEFAULT) };
|
||||
@@ -135,7 +135,7 @@ pub fn set_show_timeline(enabled: bool) {
|
||||
TIMELINE_LOADED.with(|l| l.set(true));
|
||||
}
|
||||
|
||||
// -- Simple mode --------------------------------------------------------------
|
||||
// Simple mode
|
||||
|
||||
thread_local! {
|
||||
static SIMPLE_MODE_CURRENT: Cell<bool> = const { Cell::new(SIMPLE_MODE_DEFAULT) };
|
||||
@@ -162,7 +162,7 @@ pub fn set_simple_mode(enabled: bool) {
|
||||
SIMPLE_MODE_LOADED.with(|l| l.set(true));
|
||||
}
|
||||
|
||||
// -- Vim mode (scrollback) ---------------------------------------------------
|
||||
// Vim mode (scrollback)
|
||||
|
||||
thread_local! {
|
||||
static VIM_MODE_CURRENT: Cell<bool> = const { Cell::new(VIM_MODE_DEFAULT) };
|
||||
@@ -197,7 +197,7 @@ pub fn set_vim_mode(enabled: bool) {
|
||||
VIM_MODE_LOADED.with(|l| l.set(true));
|
||||
}
|
||||
|
||||
// -- Show thinking blocks ----------------------------------------------------
|
||||
// Show thinking blocks
|
||||
|
||||
thread_local! {
|
||||
static SHOW_THINKING_BLOCKS_CURRENT: Cell<bool> =
|
||||
@@ -228,7 +228,7 @@ pub fn set_show_thinking_blocks(enabled: bool) {
|
||||
SHOW_THINKING_BLOCKS_LOADED.with(|l| l.set(true));
|
||||
}
|
||||
|
||||
// -- Group tool verbs ---------------------------------------------------------
|
||||
// Group tool verbs
|
||||
|
||||
thread_local! {
|
||||
static GROUP_TOOL_VERBS_CURRENT: Cell<bool> =
|
||||
@@ -259,7 +259,7 @@ pub fn set_group_tool_verbs(enabled: bool) {
|
||||
GROUP_TOOL_VERBS_LOADED.with(|l| l.set(true));
|
||||
}
|
||||
|
||||
// -- Collapsed edit blocks -----------------------------------------------------
|
||||
// Collapsed edit blocks
|
||||
|
||||
thread_local! {
|
||||
static COLLAPSED_EDIT_BLOCKS_CURRENT: Cell<bool> =
|
||||
@@ -292,7 +292,7 @@ pub fn set_collapsed_edit_blocks(enabled: bool) {
|
||||
COLLAPSED_EDIT_BLOCKS_LOADED.with(|l| l.set(true));
|
||||
}
|
||||
|
||||
// -- Prompt suggestions (tab autocomplete) -----------------------------------
|
||||
// Prompt suggestions (tab autocomplete)
|
||||
|
||||
thread_local! {
|
||||
static PROMPT_SUGGESTIONS_CURRENT: Cell<bool> =
|
||||
@@ -324,7 +324,7 @@ pub fn set_prompt_suggestions(enabled: bool) {
|
||||
PROMPT_SUGGESTIONS_LOADED.with(|l| l.set(true));
|
||||
}
|
||||
|
||||
// -- keep_text_selection (`flash` | `hold`) ----------------------------------
|
||||
// keep_text_selection (`flash` | `hold`)
|
||||
|
||||
thread_local! {
|
||||
static KEEP_TEXT_SELECTION_CURRENT: Cell<TextSelection> =
|
||||
@@ -350,7 +350,7 @@ pub fn set_keep_text_selection(value: TextSelection) {
|
||||
KEEP_TEXT_SELECTION_LOADED.with(|l| l.set(true));
|
||||
}
|
||||
|
||||
// -- Scroll speed ------------------------------------------------------------
|
||||
// Scroll speed
|
||||
|
||||
thread_local! {
|
||||
static SCROLL_SPEED_CURRENT: Cell<u8> = const { Cell::new(SCROLL_SPEED_DEFAULT) };
|
||||
@@ -383,7 +383,7 @@ pub fn set_scroll_speed(speed: u8) {
|
||||
SCROLL_SPEED_LOADED.with(|l| l.set(true));
|
||||
}
|
||||
|
||||
// -- Scroll mode (auto | wheel | trackpad) -----------------------------------
|
||||
// Scroll mode (auto | wheel | trackpad)
|
||||
|
||||
thread_local! {
|
||||
static SCROLL_MODE_CURRENT: Cell<ScrollMode> = const { Cell::new(SCROLL_MODE_DEFAULT) };
|
||||
@@ -418,7 +418,7 @@ pub fn set_scroll_mode(value: ScrollMode) {
|
||||
SCROLL_MODE_LOADED.with(|l| l.set(true));
|
||||
}
|
||||
|
||||
// -- Invert scroll ------------------------------------------------------------
|
||||
// Invert scroll
|
||||
|
||||
thread_local! {
|
||||
static INVERT_SCROLL_CURRENT: Cell<bool> = const { Cell::new(INVERT_SCROLL_DEFAULT) };
|
||||
@@ -453,7 +453,7 @@ pub fn set_invert_scroll(enabled: bool) {
|
||||
INVERT_SCROLL_LOADED.with(|l| l.set(true));
|
||||
}
|
||||
|
||||
// -- Scroll lines ------------------------------------------------------------
|
||||
// Scroll lines
|
||||
|
||||
thread_local! {
|
||||
static SCROLL_LINES_CURRENT: Cell<u8> = const { Cell::new(SCROLL_LINES_UNSET) };
|
||||
@@ -494,7 +494,7 @@ pub fn set_scroll_lines(lines: u8) {
|
||||
SCROLL_LINES_LOADED.with(|l| l.set(true));
|
||||
}
|
||||
|
||||
// -- Render mermaid (auto | on | off) ---------------------------------------
|
||||
// Render mermaid (auto | on | off)
|
||||
|
||||
thread_local! {
|
||||
static RENDER_MERMAID_CURRENT: Cell<RenderMermaid> = const { Cell::new(RenderMermaid::Auto) };
|
||||
@@ -531,13 +531,13 @@ fn render_mermaid_from_config_str(value: Option<&str>) -> RenderMermaid {
|
||||
.unwrap_or_default()
|
||||
}
|
||||
|
||||
/// Replace cached `render_mermaid` (optimistic update from the settings modal).
|
||||
/// Replace cached `render_mermaid` (optimistic write from the settings modal).
|
||||
pub fn set_render_mermaid(value: RenderMermaid) {
|
||||
RENDER_MERMAID_CURRENT.with(|c| c.set(value));
|
||||
RENDER_MERMAID_LOADED.with(|l| l.set(true));
|
||||
}
|
||||
|
||||
// -- Prime + read path ------------------------------------------------------
|
||||
// Prime + read path
|
||||
|
||||
/// Seed all caches from the live `UiConfig` at startup so subsequent
|
||||
/// `load*()` calls never hit disk on the render hot path.
|
||||
@@ -643,7 +643,7 @@ fn load_str_from_effective_config(key: &str) -> Option<String> {
|
||||
.map(str::to_string)
|
||||
}
|
||||
|
||||
// -- Tests -------------------------------------------------------------------
|
||||
// Tests
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
@@ -915,7 +915,7 @@ mod tests {
|
||||
#[test]
|
||||
fn caches_are_independent() {
|
||||
std::thread::spawn(|| {
|
||||
// ── compact independent (the other two stay true) ──
|
||||
// compact independent (the other two stay true)
|
||||
set(false);
|
||||
set_timestamps(true);
|
||||
set_simple_mode(true);
|
||||
@@ -929,7 +929,7 @@ mod tests {
|
||||
"simple_mode must NOT toggle when compact changed"
|
||||
);
|
||||
|
||||
// ── timestamps independent ──
|
||||
// timestamps independent
|
||||
set(true);
|
||||
set_timestamps(false);
|
||||
set_simple_mode(true);
|
||||
@@ -940,7 +940,7 @@ mod tests {
|
||||
"simple_mode must NOT toggle when timestamps changed"
|
||||
);
|
||||
|
||||
// ── simple_mode independent ──
|
||||
// simple_mode independent
|
||||
set(true);
|
||||
set_timestamps(true);
|
||||
set_simple_mode(false);
|
||||
|
||||
@@ -10,9 +10,7 @@ use ratatui::style::Color;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use toml_edit::{DocumentMut, Item, RawString};
|
||||
|
||||
// ============================================================================
|
||||
// Runtime Config (used by render code)
|
||||
// ============================================================================
|
||||
|
||||
/// Background style for block content area.
|
||||
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash)]
|
||||
@@ -173,7 +171,8 @@ impl Default for ScrollbackDisplayConfig {
|
||||
line_under_last_entry: false,
|
||||
collapsed_accent_char: crate::glyphs::collapsed_accent().to_string(),
|
||||
dim_accent: 0.5,
|
||||
group_selection_split: true, // Mode B by default
|
||||
// Mode B by default
|
||||
group_selection_split: true,
|
||||
highlight_overlays_border: false,
|
||||
expandable_indicator: true,
|
||||
expandable_indicator_running: true,
|
||||
@@ -208,7 +207,8 @@ impl Default for LayoutConfig {
|
||||
outer_hpad_left: 2,
|
||||
outer_hpad_right: 2,
|
||||
block_pad_left: 2,
|
||||
block_pad_right: 2, // Match left padding for symmetry
|
||||
// Match left padding for symmetry
|
||||
block_pad_right: 2,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -289,8 +289,10 @@ impl Default for ScrollbarConfig {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
enabled: true,
|
||||
gap_left: 0, // Content adjacent to scrollbar
|
||||
gap_right: 0, // Scrollbar at screen edge
|
||||
// Content adjacent to scrollbar
|
||||
gap_left: 0,
|
||||
// Scrollbar at screen edge
|
||||
gap_right: 0,
|
||||
scrollbar_bg: None,
|
||||
scrollbar_fg: None,
|
||||
}
|
||||
@@ -587,8 +589,8 @@ pub struct ToolConfig {
|
||||
pub dim_details: bool,
|
||||
/// Bullet/icon character rendered before tool call headers.
|
||||
pub bullet: ToolBullet,
|
||||
// Note: bullet_accent and bullet_color were removed in the scrollback-v2 refactor.
|
||||
// Bullet color is now determined by BlockContent::bullet() — each block type
|
||||
// Note: bullet_accent and bullet_color are not configurable here.
|
||||
// Bullet color is determined by BlockContent::bullet() — each block type
|
||||
// decides its own bullet color based on state (accent color, error, default).
|
||||
// Dimming for collapsed+groupable blocks is handled by EntryRenderer.
|
||||
// TODO(dim_muted): add a dim factor for collapsed text styling (not just bullet/accent).
|
||||
@@ -658,7 +660,8 @@ pub struct ListDirConfig {
|
||||
impl Default for ListDirConfig {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
terminal_bg: true, // Default: dark background for output
|
||||
// Default: dark background for output
|
||||
terminal_bg: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -705,25 +708,12 @@ impl Default for ExecuteConfig {
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Raw Config (for TOML serde)
|
||||
// ============================================================================
|
||||
//
|
||||
// ╔═══════════════════════════════════════════════════════════════════════════╗
|
||||
// ║ MAINTAINER NOTE: When adding/changing fields or sections: ║
|
||||
// ║ ║
|
||||
// ║ 1. Add doc comments (///) to ALL fields in Raw* structs - they become ║
|
||||
// ║ TOML comments via the `DocumentedFields` derive macro. ║
|
||||
// ║ ║
|
||||
// ║ 2. If adding a new section (e.g., RawNewBlockConfig): ║
|
||||
// ║ - Add it to RawBlocksConfig (or appropriate parent) ║
|
||||
// ║ - Add corresponding runtime config (NewBlockConfig) ║
|
||||
// ║ - Add From<RawNewBlockConfig> for NewBlockConfig conversion ║
|
||||
// ║ - Add annotate_table call in to_toml_with_comments() below! ║
|
||||
// ║ ║
|
||||
// ║ 3. The to_toml_with_comments() method generates the default config file ║
|
||||
// ║ with comments. Update it when adding new sections. ║
|
||||
// ╚═══════════════════════════════════════════════════════════════════════════╝
|
||||
// MAINTAINER NOTE — when adding or changing fields or sections:
|
||||
// 1. Put `///` on every Raw* field (DocumentedFields emits TOML comments).
|
||||
// 2. For a new section: Raw* + runtime config + From impl + annotate_table.
|
||||
// 3. Keep to_toml_with_comments() in sync so the default file stays documented.
|
||||
|
||||
/// Root appearance configuration (TOML format).
|
||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, Documented, DocumentedFields)]
|
||||
@@ -1259,7 +1249,7 @@ pub struct RawToolConfig {
|
||||
/// "none", "dot" (·), "small-circle" (•), "circle" (●),
|
||||
/// "small-triangle" (▸), "triangle" (▶), "diamond" (◆).
|
||||
pub bullet: RawToolBullet,
|
||||
// Note: bullet_accent and bullet_color removed — see ToolConfig comment.
|
||||
// Note: bullet_accent and bullet_color are not configurable — see ToolConfig comment.
|
||||
}
|
||||
|
||||
impl Default for RawToolConfig {
|
||||
@@ -1284,7 +1274,8 @@ pub struct RawListDirConfig {
|
||||
impl Default for RawListDirConfig {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
terminal_bg: true, // Default: dark background for output
|
||||
// Default: dark background for output
|
||||
terminal_bg: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1364,9 +1355,7 @@ impl From<RawBlockBackground> for BlockBackground {
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Raw → Runtime Conversion
|
||||
// ============================================================================
|
||||
|
||||
impl From<RawAppearanceConfig> for AppearanceConfig {
|
||||
fn from(raw: RawAppearanceConfig) -> Self {
|
||||
@@ -1376,7 +1365,8 @@ impl From<RawAppearanceConfig> for AppearanceConfig {
|
||||
collapse_unfocused: raw.prompt.collapse_unfocused,
|
||||
mouse_hover: raw.prompt.mouse_hover,
|
||||
show_prefix: raw.prompt.show_prefix,
|
||||
compact: false, // runtime-only, not persisted in TOML
|
||||
// runtime-only, not persisted in TOML
|
||||
compact: false,
|
||||
},
|
||||
scrollback: ScrollbackConfig {
|
||||
layout: raw.scrollback.layout.into(),
|
||||
@@ -1426,7 +1416,8 @@ impl From<RawAppearanceConfig> for AppearanceConfig {
|
||||
badge_format: raw.todo.badge_format.into(),
|
||||
},
|
||||
turn_status: TurnStatusConfig::default(),
|
||||
show_timestamps: true, // runtime-only, loaded from config.toml via persist
|
||||
// runtime-only, loaded from config.toml via persist
|
||||
show_timestamps: true,
|
||||
// Single source: UiConfig::SHOW_TIMELINE_DEFAULT (loaded from config.toml via persist).
|
||||
show_timeline: UiConfig::SHOW_TIMELINE_DEFAULT,
|
||||
disable_plugins: raw.disable_plugins,
|
||||
@@ -1607,9 +1598,7 @@ impl From<RawThinkingConfig> for ThinkingConfig {
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Color Parsing
|
||||
// ============================================================================
|
||||
|
||||
/// An optional color that can be "none" or a color value.
|
||||
/// This allows TOML to represent None values explicitly.
|
||||
@@ -1719,47 +1708,48 @@ fn lookup_named_color(name: &str) -> Result<Color, String> {
|
||||
// `parse_color_string` → `quantize()` to match the terminal's capabilities.
|
||||
let color = match name.to_uppercase().as_str() {
|
||||
// Background colors
|
||||
"BG" | "BG_BASE" => Color::Rgb(20, 20, 20), // #141414
|
||||
"BG_LIGHT" | "BG_HIGHLIGHT" => Color::Rgb(30, 30, 30), // #1e1e1e
|
||||
"BG_DARK" => Color::Rgb(17, 17, 17), // #111111
|
||||
"BG_TERMINAL" | "BG_NIGHT" => Color::Rgb(10, 10, 10), // #0a0a0a
|
||||
"BG_VISUAL" => Color::Rgb(30, 32, 45), // blue-tinted selection
|
||||
"BG_SEARCH" => Color::Rgb(48, 48, 52), // #303034
|
||||
"BG" | "BG_BASE" => Color::Rgb(20, 20, 20),
|
||||
"BG_LIGHT" | "BG_HIGHLIGHT" => Color::Rgb(30, 30, 30),
|
||||
"BG_DARK" => Color::Rgb(17, 17, 17),
|
||||
"BG_TERMINAL" | "BG_NIGHT" => Color::Rgb(10, 10, 10),
|
||||
// blue-tinted selection
|
||||
"BG_VISUAL" => Color::Rgb(30, 32, 45),
|
||||
"BG_SEARCH" => Color::Rgb(48, 48, 52),
|
||||
|
||||
// Accent colors (TokyoNight Night)
|
||||
"BLUE" => Color::Rgb(77, 121, 255), // #4D79FF
|
||||
"BLUE0" => Color::Rgb(61, 89, 161), // #3d59a1
|
||||
"BLUE1" => Color::Rgb(42, 195, 222), // #2ac3de
|
||||
"BLUE2" => Color::Rgb(13, 185, 215), // #0db9d7
|
||||
"BLUE5" => Color::Rgb(137, 221, 255), // #89ddff
|
||||
"BLUE6" => Color::Rgb(180, 249, 248), // #b4f9f8
|
||||
"BLUE7" => Color::Rgb(57, 75, 112), // #394b70
|
||||
"CYAN" => Color::Rgb(125, 207, 255), // #7dcfff
|
||||
"GREEN" => Color::Rgb(36, 196, 116), // #24C474
|
||||
"GREEN1" => Color::Rgb(115, 218, 202), // #73daca
|
||||
"GREEN2" => Color::Rgb(65, 166, 181), // #41a6b5
|
||||
"YELLOW" => Color::Rgb(255, 219, 141), // #FFDB8D
|
||||
"ORANGE" => Color::Rgb(255, 158, 100), // #ff9e64
|
||||
"RED" => Color::Rgb(248, 114, 122), // #F8727A
|
||||
"RED1" => Color::Rgb(219, 75, 75), // #db4b4b
|
||||
"MAGENTA" => Color::Rgb(187, 154, 247), // #bb9af7
|
||||
"PURPLE" => Color::Rgb(131, 113, 211), // #8371D3
|
||||
"MAGENTA2" => Color::Rgb(255, 0, 124), // #ff007c
|
||||
"TEAL" | "HINT" => Color::Rgb(26, 188, 156), // #1abc9c
|
||||
"BLUE" => Color::Rgb(77, 121, 255),
|
||||
"BLUE0" => Color::Rgb(61, 89, 161),
|
||||
"BLUE1" => Color::Rgb(42, 195, 222),
|
||||
"BLUE2" => Color::Rgb(13, 185, 215),
|
||||
"BLUE5" => Color::Rgb(137, 221, 255),
|
||||
"BLUE6" => Color::Rgb(180, 249, 248),
|
||||
"BLUE7" => Color::Rgb(57, 75, 112),
|
||||
"CYAN" => Color::Rgb(125, 207, 255),
|
||||
"GREEN" => Color::Rgb(36, 196, 116),
|
||||
"GREEN1" => Color::Rgb(115, 218, 202),
|
||||
"GREEN2" => Color::Rgb(65, 166, 181),
|
||||
"YELLOW" => Color::Rgb(255, 219, 141),
|
||||
"ORANGE" => Color::Rgb(255, 158, 100),
|
||||
"RED" => Color::Rgb(248, 114, 122),
|
||||
"RED1" => Color::Rgb(219, 75, 75),
|
||||
"MAGENTA" => Color::Rgb(187, 154, 247),
|
||||
"PURPLE" => Color::Rgb(131, 113, 211),
|
||||
"MAGENTA2" => Color::Rgb(255, 0, 124),
|
||||
"TEAL" | "HINT" => Color::Rgb(26, 188, 156),
|
||||
|
||||
// Text colors
|
||||
"FG" | "TEXT" | "TEXT_PRIMARY" => Color::Rgb(243, 243, 243), // #f3f3f3
|
||||
"FG_DARK" | "TEXT_SECONDARY" => Color::Rgb(200, 200, 200), // #c8c8c8
|
||||
"FG_GUTTER" => Color::Rgb(65, 65, 65), // #414141
|
||||
"COMMENT" | "MUTED" | "TEXT_MUTED" => Color::Rgb(98, 98, 98), // #626262
|
||||
"DARK3" => Color::Rgb(90, 90, 90), // #5a5a5a
|
||||
"DARK5" | "TOOL" => Color::Rgb(120, 120, 120), // #787878
|
||||
"FG" | "TEXT" | "TEXT_PRIMARY" => Color::Rgb(243, 243, 243),
|
||||
"FG_DARK" | "TEXT_SECONDARY" => Color::Rgb(200, 200, 200),
|
||||
"FG_GUTTER" => Color::Rgb(65, 65, 65),
|
||||
"COMMENT" | "MUTED" | "TEXT_MUTED" => Color::Rgb(98, 98, 98),
|
||||
"DARK3" => Color::Rgb(90, 90, 90),
|
||||
"DARK5" | "TOOL" => Color::Rgb(120, 120, 120),
|
||||
|
||||
// Semantic colors
|
||||
"ERROR" => Color::Rgb(247, 118, 142), // RED
|
||||
"SUCCESS" => Color::Rgb(158, 206, 106), // GREEN
|
||||
"WARNING" => Color::Rgb(224, 175, 104), // YELLOW
|
||||
"INFO" => Color::Rgb(125, 207, 255), // CYAN
|
||||
"ERROR" => Color::Rgb(247, 118, 142),
|
||||
"SUCCESS" => Color::Rgb(158, 206, 106),
|
||||
"WARNING" => Color::Rgb(224, 175, 104),
|
||||
"INFO" => Color::Rgb(125, 207, 255),
|
||||
|
||||
// Basic colors
|
||||
"BLACK" => Color::Black,
|
||||
@@ -1771,9 +1761,7 @@ fn lookup_named_color(name: &str) -> Result<Color, String> {
|
||||
Ok(color)
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// TOML Generation with Comments
|
||||
// ============================================================================
|
||||
|
||||
impl RawAppearanceConfig {
|
||||
pub fn to_toml_with_comments() -> String {
|
||||
@@ -2025,9 +2013,7 @@ fn annotate_table<T: DocumentedFields>(table: &mut toml_edit::Table) {
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Tests
|
||||
// ============================================================================
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
@@ -2414,7 +2400,7 @@ gutter_bg = true
|
||||
);
|
||||
}
|
||||
|
||||
// ── Terminal config (alt_screen) parsing ─────────────────────
|
||||
// Terminal config (alt_screen) parsing
|
||||
|
||||
#[test]
|
||||
fn terminal_alt_screen_auto_default() {
|
||||
|
||||
@@ -33,7 +33,7 @@ pub use scroll_mode::ScrollMode;
|
||||
pub use text_selection::TextSelection;
|
||||
pub use watcher::ConfigWatcher;
|
||||
|
||||
// -- Global tab_width --------------------------------------------------------
|
||||
// Global tab_width
|
||||
//
|
||||
// Stored as an atomic so MarkdownContent can read the current value
|
||||
// without needing the AppearanceConfig threaded through its API.
|
||||
|
||||
@@ -62,7 +62,7 @@ impl DefaultSelectedPermission {
|
||||
}
|
||||
}
|
||||
|
||||
/// Display label for the settings picker and the change toast.
|
||||
/// Display label for the settings picker and the confirmation toast.
|
||||
/// `AllowCommandAlways` preselects the prompt-specific always-allow row
|
||||
/// (per-command / per-tool / per-domain / per-edit-session), never a
|
||||
/// global allow-everything — that is `AlwaysAllowAllSessions`.
|
||||
@@ -132,7 +132,7 @@ impl DefaultSelectedPermission {
|
||||
}
|
||||
}
|
||||
|
||||
// ── Configured value cache: `[ui].default_selected_permission` ──────────────
|
||||
// Configured value cache: `[ui].default_selected_permission`
|
||||
//
|
||||
// Read when queueing the first prompt of a session. Seeded by `prime` at
|
||||
// startup (and lazily on first read) so the path never hits disk mid-session.
|
||||
@@ -174,7 +174,7 @@ pub fn load_default_selected_permission() -> DefaultSelectedPermission {
|
||||
CONFIG_CURRENT.with(Cell::get)
|
||||
}
|
||||
|
||||
/// Replace the cached configured value (optimistic update from the settings
|
||||
/// Replace the cached configured value (optimistic write from the settings
|
||||
/// modal, or rollback on persist failure). The next prompt sees it without a
|
||||
/// restart.
|
||||
pub fn set_default_selected_permission(value: DefaultSelectedPermission) {
|
||||
@@ -188,7 +188,7 @@ pub fn prime() {
|
||||
let _ = load_default_selected_permission();
|
||||
}
|
||||
|
||||
// ── Sticky "last used" cursor target ────────────────────────────────────────
|
||||
// Sticky "last used" cursor target
|
||||
//
|
||||
// Process-wide ephemeral state: the kind the user most recently confirmed.
|
||||
// After the first prompt, `resolve_initial_cursor` prefers this over the
|
||||
@@ -215,7 +215,7 @@ pub fn set_last_used_permission(kind: DefaultSelectedPermission) {
|
||||
LAST_USED.with(|c| c.set(kind));
|
||||
}
|
||||
|
||||
// ── Resolution ──────────────────────────────────────────────────────────────
|
||||
// Resolution
|
||||
|
||||
/// Pick the initially-highlighted row for a freshly-queued permission prompt.
|
||||
///
|
||||
@@ -252,7 +252,7 @@ fn load_string_from_effective_config(key: &str) -> Option<String> {
|
||||
.map(std::string::ToString::to_string)
|
||||
}
|
||||
|
||||
// -- Tests -------------------------------------------------------------------
|
||||
// Tests
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
//!
|
||||
//! Fenced ` ```mermaid ` blocks are rendered inline as Unicode box-drawing art
|
||||
//! by the markdown renderer. This setting controls the full-fidelity affordance
|
||||
//! row layered beneath that art: `auto`/`on` add the clickable row
|
||||
//! row layered beneath that art: `auto`/`on` include the clickable row
|
||||
//! (`◇ mermaid [Open Image] [Copy Image Path] [Copy Source]`); `off` shows the
|
||||
//! inline art alone. The PNG render engine is always compiled in, and the PNG is
|
||||
//! never drawn as an inline image (it opens in the OS viewer), so the treatment
|
||||
|
||||
@@ -6,10 +6,9 @@
|
||||
//! `ScrollInputMode` when building its scroll config; this crate only owns
|
||||
//! the persisted value type and its cache.
|
||||
|
||||
/// Scroll input classification preference: auto-detect or force one kind.
|
||||
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash)]
|
||||
pub enum ScrollMode {
|
||||
/// Detect wheel vs trackpad per stream from event timing. Default.
|
||||
/// Detect wheel vs trackpad per stream from event timing.
|
||||
#[default]
|
||||
Auto,
|
||||
/// Always treat scroll input as a mouse wheel (fixed lines per tick).
|
||||
@@ -28,7 +27,6 @@ impl ScrollMode {
|
||||
}
|
||||
}
|
||||
|
||||
/// Parse a canonical string, returning `None` for unrecognized input.
|
||||
pub fn from_canonical(value: &str) -> Option<Self> {
|
||||
match value {
|
||||
"auto" => Some(Self::Auto),
|
||||
@@ -52,8 +50,8 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn junk_and_case_variants_are_rejected() {
|
||||
// Strict parse: unknown disk/env values must fall back to the default
|
||||
// at the caller (cache seed), never panic or mis-map.
|
||||
// Parsing is strict so a stray disk/env value falls back to the
|
||||
// default at the caller (cache seed) rather than mis-mapping.
|
||||
for junk in ["", "Auto", "WHEEL", "track pad", "mouse", "1"] {
|
||||
assert_eq!(ScrollMode::from_canonical(junk), None, "{junk:?}");
|
||||
}
|
||||
|
||||
@@ -1,18 +1,12 @@
|
||||
//! The `keep_text_selection` user setting (`flash` | `hold` | `word_select`).
|
||||
//!
|
||||
//! This is the single, unified control for scrollback text-selection behavior.
|
||||
//! It governs both how long an in-app selection highlight stays on screen and
|
||||
//! what a double/triple-click does, so the two can never drift out of sync:
|
||||
//!
|
||||
//! - `flash` — brief highlight on mouse-up, then clear; double-click toggles fold.
|
||||
//! - `hold` — selection stays until dismissed; double-click toggles fold.
|
||||
//! - `word_select` — selection stays until dismissed; double-click selects &
|
||||
//! copies a word, triple-click a line (terminal-like). Implies `hold`.
|
||||
//! One setting governs both how long an in-app selection highlight stays on
|
||||
//! screen and what a double/triple-click does, so the two can never drift out
|
||||
//! of sync.
|
||||
|
||||
/// Scrollback text-selection behavior: highlight lifetime + double-click action.
|
||||
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash)]
|
||||
pub enum TextSelection {
|
||||
/// Brief highlight on mouse-up, then clear; double-click toggles fold. Default.
|
||||
/// Brief highlight on mouse-up, then clear; double-click toggles fold.
|
||||
#[default]
|
||||
Flash,
|
||||
/// Stay visible until Esc/click/scroll; double-click toggles fold.
|
||||
@@ -32,7 +26,6 @@ impl TextSelection {
|
||||
}
|
||||
}
|
||||
|
||||
/// Parse a canonical string, returning `None` for unrecognized input.
|
||||
pub fn from_canonical(value: &str) -> Option<Self> {
|
||||
match value {
|
||||
"flash" => Some(Self::Flash),
|
||||
@@ -78,16 +71,14 @@ mod tests {
|
||||
assert_eq!(TextSelection::default().as_canonical(), "flash");
|
||||
}
|
||||
|
||||
/// The unified invariant: `word_select` always implies `holds()` (persistent
|
||||
/// highlight) and is the only mode that turns on double-click word select.
|
||||
/// `word_select` always implies `holds()`, and is the only mode that turns
|
||||
/// on double-click word select.
|
||||
#[test]
|
||||
fn word_select_implies_hold_and_word_select() {
|
||||
assert!(TextSelection::WordSelect.holds());
|
||||
assert!(TextSelection::WordSelect.selects_word());
|
||||
// Hold persists but leaves double-click as fold-toggle.
|
||||
assert!(TextSelection::Hold.holds());
|
||||
assert!(!TextSelection::Hold.selects_word());
|
||||
// Flash neither persists nor word-selects.
|
||||
assert!(!TextSelection::Flash.holds());
|
||||
assert!(!TextSelection::Flash.selects_word());
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user