Skip to content

Commit 7c56abd

Browse files
committed
fix(tui): Shift+Tab cycles permission modes, remove message divider
1. Shift+Tab now cycles: default β†’ acceptEdits β†’ plan β†’ default (matches CC's chat:cycleMode behavior) Permission mode shown in status bar: "deepseek-chat β”‚ default β”‚ 0 in Β· 0 out" 2. Remove turn separator divider line (────) on message submit CC doesn't show dividers between turns β€” just "❯ prompt" echo with blank lines for visual spacing
1 parent 5e01dd3 commit 7c56abd

1 file changed

Lines changed: 21 additions & 5 deletions

File tree

β€Žcrates/tui/src/app.rsβ€Ž

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,8 @@ pub struct App {
163163
pub input_mode: PromptInputMode,
164164
/// Timestamp of last Ctrl+C press for double-press detection.
165165
last_interrupt: Option<Instant>,
166+
/// Current permission mode (cycled via Shift+Tab).
167+
pub permission_mode: crab_core::permission::PermissionMode,
166168
}
167169

168170
impl App {
@@ -199,6 +201,7 @@ impl App {
199201
unseen_message_count: 0,
200202
input_mode: PromptInputMode::Prompt,
201203
last_interrupt: None,
204+
permission_mode: crab_core::permission::PermissionMode::Default,
202205
}
203206
}
204207

@@ -362,9 +365,19 @@ impl App {
362365
self.scroll_to_search_match();
363366
return AppAction::None;
364367
}
365-
// CycleMode: CC cycles permission modes. Needs agent integration.
368+
Action::CycleMode if self.state != AppState::Confirming => {
369+
// CC cycles: default β†’ acceptEdits β†’ plan β†’ default
370+
use crab_core::permission::PermissionMode;
371+
self.permission_mode = match self.permission_mode {
372+
PermissionMode::Default => PermissionMode::AcceptEdits,
373+
PermissionMode::AcceptEdits => PermissionMode::Plan,
374+
// All other modes cycle back to Default
375+
_ => PermissionMode::Default,
376+
};
377+
return AppAction::None;
378+
}
366379
// Redraw: handled by outer loop on next frame.
367-
Action::CycleMode | Action::Redraw => {
380+
Action::Redraw => {
368381
return AppAction::None;
369382
}
370383
// These actions are recognized but currently act as no-ops
@@ -492,9 +505,8 @@ impl App {
492505
if key.code == KeyCode::Enter && !key.modifiers.contains(KeyModifiers::SHIFT) {
493506
if !self.input.is_empty() {
494507
let text = self.input.submit();
495-
// Turn separator: show user prompt then divider
496-
let _ = writeln!(self.content_buffer, "❯ {text}");
497-
let _ = writeln!(self.content_buffer, "────────────────────────────────");
508+
// Show user prompt in content area (no divider β€” CC doesn't have one)
509+
let _ = writeln!(self.content_buffer, "\n❯ {text}\n");
498510
self.state = AppState::Processing;
499511
self.spinner.start_with_random_verb();
500512
return AppAction::Submit(text);
@@ -737,6 +749,7 @@ impl App {
737749
} else {
738750
render_status_line(
739751
&self.model_name,
752+
self.permission_mode,
740753
self.total_input_tokens,
741754
self.total_output_tokens,
742755
&self.thinking,
@@ -1230,6 +1243,7 @@ fn classify_tool_risk(tool_name: &str) -> RiskLevel {
12301243
/// Matches CC's `StatusLine` component showing operational data.
12311244
fn render_status_line(
12321245
model: &str,
1246+
perm_mode: crab_core::permission::PermissionMode,
12331247
input_tokens: u64,
12341248
output_tokens: u64,
12351249
thinking: &ThinkingState,
@@ -1243,6 +1257,8 @@ fn render_status_line(
12431257
let mut spans = vec![
12441258
Span::styled(model, Style::default().fg(Color::Cyan)),
12451259
Span::styled(" β”‚ ", Style::default().fg(Color::DarkGray)),
1260+
Span::styled(perm_mode.to_string(), Style::default().fg(Color::Yellow)),
1261+
Span::styled(" β”‚ ", Style::default().fg(Color::DarkGray)),
12461262
];
12471263

12481264
// Token counts

0 commit comments

Comments
Β (0)