vtcode_core/ui/
tui_compat.rs1use crate::config::KeyboardProtocolConfig;
7use crate::config::loader::VTCodeConfig;
8use crate::config::types::ReasoningEffortLevel;
9use crate::ui::slash::SlashCommandInfo;
10use crate::ui::theme::ThemeStyles;
11use crate::ui::tui::{
12 InlineTheme, KeyboardProtocolSettings, LayoutModeOverride, ReasoningDisplayMode, SessionSurface, SlashCommandItem,
13 UiMode,
14};
15#[cfg(feature = "tui")]
16use vtcode_ui::tui::ui::theme::ThemeStyles as TuiThemeStyles;
17
18#[cfg(feature = "tui")]
19use crate::ui::tui::{FullscreenInteractionSettings, SessionAppearanceConfig};
20
21#[cfg(not(feature = "tui"))]
22use crate::ui::tui::SessionAppearanceConfig;
23
24pub fn reasoning_to_selection_string(level: ReasoningEffortLevel) -> String {
27 level.as_str().to_owned()
28}
29
30pub fn reasoning_from_selection_string(s: &str) -> ReasoningEffortLevel {
32 ReasoningEffortLevel::parse(s).unwrap_or_default()
33}
34
35pub fn to_tui_surface(preference: crate::config::types::UiSurfacePreference) -> SessionSurface {
37 match preference {
38 crate::config::types::UiSurfacePreference::Auto => SessionSurface::Auto,
39 crate::config::types::UiSurfacePreference::Alternate => SessionSurface::Alternate,
40 crate::config::types::UiSurfacePreference::Inline => SessionSurface::Inline,
41 }
42}
43
44pub fn to_tui_keyboard_protocol(keyboard: KeyboardProtocolConfig) -> KeyboardProtocolSettings {
46 KeyboardProtocolSettings {
47 enabled: keyboard.enabled,
48 mode: keyboard.mode.as_str().to_owned(),
49 disambiguate_escape_codes: keyboard.disambiguate_escape_codes,
50 report_event_types: keyboard.report_event_types,
51 report_alternate_keys: keyboard.report_alternate_keys,
52 report_all_keys: keyboard.report_all_keys,
53 }
54}
55
56#[cfg(feature = "tui")]
58pub fn to_tui_fullscreen(config: &VTCodeConfig) -> FullscreenInteractionSettings {
59 FullscreenInteractionSettings {
60 mouse_capture: config.ui.fullscreen.mouse_capture,
61 copy_on_select: config.ui.fullscreen.copy_on_select,
62 scroll_speed: config.ui.fullscreen.scroll_speed,
63 }
64}
65
66pub fn inline_theme_from_core_styles(styles: &ThemeStyles) -> InlineTheme {
68 crate::ui::tui::theme_from_color_fields(
69 styles.foreground,
70 styles.background,
71 styles.primary,
72 styles.secondary,
73 styles.tool,
74 styles.tool_detail,
75 styles.pty_output,
76 styles.error,
77 styles.warning,
78 )
79}
80
81#[cfg(feature = "tui")]
83pub fn tui_theme_styles_from_core(styles: &ThemeStyles) -> TuiThemeStyles {
84 TuiThemeStyles {
85 info: styles.info,
86 error: styles.error,
87 warning: styles.warning,
88 output: styles.output,
89 response: styles.response,
90 reasoning: styles.reasoning,
91 tool: styles.tool,
92 tool_detail: styles.tool_detail,
93 tool_output: styles.tool_output,
94 pty_output: styles.pty_output,
95 status: styles.status,
96 mcp: styles.mcp,
97 user: styles.user,
98 primary: styles.primary,
99 secondary: styles.secondary,
100 foreground: styles.foreground,
101 background: styles.background,
102 }
103}
104
105#[cfg(not(feature = "tui"))]
107pub fn tui_theme_styles_from_core(styles: &ThemeStyles) -> ThemeStyles {
108 styles.clone()
109}
110
111pub fn to_tui_slash_commands(commands: &[SlashCommandInfo]) -> Vec<SlashCommandItem> {
113 commands
114 .iter()
115 .map(|cmd| SlashCommandItem::new(cmd.name, cmd.description))
116 .collect()
117}
118
119pub fn to_tui_appearance(config: &VTCodeConfig) -> SessionAppearanceConfig {
121 let reduce_motion_mode = config.ui.reduce_motion_mode || matches!(config.tui.animations, Some(false));
122 SessionAppearanceConfig {
123 theme: config.agent.theme.clone(),
124 ui_mode: match config.ui.display_mode {
125 crate::config::UiDisplayMode::Full => UiMode::Full,
126 crate::config::UiDisplayMode::Minimal | crate::config::UiDisplayMode::Unknown => UiMode::Minimal,
127 crate::config::UiDisplayMode::Focused => UiMode::Focused,
128 },
129 show_sidebar: config.ui.show_sidebar,
130 min_content_width: 40,
131 min_navigation_width: 20,
132 navigation_width_percent: 25,
133 transcript_bottom_padding: 0,
134 dim_completed_todos: config.ui.dim_completed_todos,
135 show_task_panel: config.ui.show_task_panel,
136 message_block_spacing: if config.ui.message_block_spacing { 1 } else { 0 },
137 layout_mode: match config.ui.layout_mode {
138 crate::config::LayoutModeOverride::Auto | crate::config::LayoutModeOverride::Unknown => {
139 LayoutModeOverride::Auto
140 }
141 crate::config::LayoutModeOverride::Compact => LayoutModeOverride::Compact,
142 crate::config::LayoutModeOverride::Standard => LayoutModeOverride::Standard,
143 crate::config::LayoutModeOverride::Wide => LayoutModeOverride::Wide,
144 },
145 reasoning_display_mode: match config.ui.reasoning_display_mode {
146 crate::config::ReasoningDisplayMode::Always => ReasoningDisplayMode::Always,
147 crate::config::ReasoningDisplayMode::Toggle | crate::config::ReasoningDisplayMode::Unknown => {
148 ReasoningDisplayMode::Toggle
149 }
150 crate::config::ReasoningDisplayMode::Hidden => ReasoningDisplayMode::Hidden,
151 },
152 reasoning_visible_default: config.ui.reasoning_visible_default,
153 thinking_display: config.ui.thinking_display,
154 vim_mode: config.ui.vim_mode,
155 readline_mode: false,
156 screen_reader_mode: config.ui.screen_reader_mode,
157 reduce_motion_mode,
158 reduce_motion_keep_progress_animation: config.ui.reduce_motion_keep_progress_animation,
159 hide_header: config.ui.hide_header,
160 show_transcript_review_hints: config.ui.transcript_review.show_hints,
161 show_transcript_review_shortcut_guide: config.ui.transcript_review.show_shortcut_guide,
162 show_transcript_review_close_button: config.ui.transcript_review.show_close_button,
163 diff_preview_mode: config.ui.diff_preview_mode,
164 customization: Default::default(),
165 }
166}