vtcode_commons/
modal_hints.rs1pub const APPROVAL_NAVIGATE_DENY: &str = "Use ↑↓ or Tab to navigate • Enter to select • Esc to deny";
10pub const APPROVAL_NAVIGATE_CANCEL: &str = "Use ↑↓ or Tab to navigate • Enter to select • Esc to cancel";
12pub const APPROVAL_NAVIGATE_STOP: &str = "Use ↑↓ or Tab to navigate • Enter to select • Esc to stop";
14
15pub const MODEL_PICKER_NAVIGATE_FILTER: &str =
17 "Use ↑↓ or Tab to navigate • Enter to select • Type to filter • Esc to cancel";
18pub const MODEL_PICKER_FOLLOW_UP_HINT: &str =
25 "Use ↑↓ or Tab to navigate • Enter to select • ← Back to model list • Esc cancels the picker";
26
27pub fn choose_handling_line(object: &str) -> String {
29 format!("Choose how to handle {object}:")
30}
31
32pub fn truncate_modal_text(text: &str, max_chars: usize) -> String {
35 if text.chars().count() <= max_chars {
36 return text.to_string();
37 }
38 let mut truncated = text.chars().take(max_chars.saturating_sub(1)).collect::<String>();
39 truncated.push('…');
40 truncated
41}
42
43#[cfg(test)]
44mod tests {
45 use super::*;
46
47 #[test]
48 fn approval_hints_share_navigation_prefix_but_differ_by_exit_verb() {
49 for hint in [APPROVAL_NAVIGATE_DENY, APPROVAL_NAVIGATE_CANCEL, APPROVAL_NAVIGATE_STOP] {
50 assert!(hint.starts_with("Use ↑↓ or Tab to navigate • Enter to select • Esc to "));
51 }
52 assert!(APPROVAL_NAVIGATE_DENY.ends_with("deny"));
53 assert!(APPROVAL_NAVIGATE_CANCEL.ends_with("cancel"));
54 assert!(APPROVAL_NAVIGATE_STOP.ends_with("stop"));
55 }
56
57 #[test]
58 fn model_picker_hints_share_navigation_prefix() {
59 for hint in [MODEL_PICKER_NAVIGATE_FILTER, MODEL_PICKER_FOLLOW_UP_HINT] {
60 assert!(hint.starts_with("Use ↑↓ or Tab to navigate • Enter to "));
61 }
62 assert!(MODEL_PICKER_NAVIGATE_FILTER.contains("Type to filter"));
63 assert!(MODEL_PICKER_FOLLOW_UP_HINT.contains("Back to model list"));
64 assert!(MODEL_PICKER_FOLLOW_UP_HINT.contains("Esc"));
65 }
66
67 #[test]
68 fn choose_handling_line_interpolates_object_as_sentence() {
69 assert_eq!(choose_handling_line("this tool"), "Choose how to handle this tool:");
70 assert_eq!(
71 choose_handling_line("workspace lifecycle hooks"),
72 "Choose how to handle workspace lifecycle hooks:"
73 );
74 }
75
76 #[test]
77 fn truncate_modal_text_marks_truncation_with_ellipsis_only_when_shortened() {
78 assert_eq!(truncate_modal_text("short", 10), "short");
79 assert_eq!(truncate_modal_text("exactly-ten", 11), "exactly-ten");
80 assert_eq!(truncate_modal_text("over the limit text", 10), "over the …");
81 }
82}