MCPcopy Create free account
hub / github.com/GCWing/BitFun / render_message

Method render_message

src/apps/cli/src/ui/chat/render.rs:367–746  ·  view source on GitHub ↗

Render a single message into a list of owned ListItems. Returns owned items plus message-local clickable regions so results can be cached across frames.

(&mut self, message: &ChatMessage, available_width: u16)

Source from the content-addressed store, hash-verified

365 /// Render a single message into a list of owned ListItems.
366 /// Returns owned items plus message-local clickable regions so results can be cached across frames.
367 fn render_message(&mut self, message: &ChatMessage, available_width: u16) -> MessageRenderResult {
368 let mut items: Vec<ListItem<'static>> = Vec::new();
369 let mut plain_lines: Vec<String> = Vec::new();
370 let mut tool_regions: Vec<(String, u16, u16)> = Vec::new();
371 let mut thinking_regions: Vec<(String, u16, u16)> = Vec::new();
372 let mut thinking_block_index: usize = 0;
373
374 // Match opencode's TUI style: no explicit "You:" / "Assistant:" prefixes.
375 // Instead, differentiate user messages via background color (and a subtle left border).
376 let user_bg_style = Style::default().bg(self.theme.background_panel);
377 let user_border_style = self
378 .theme
379 .style(StyleKind::Success)
380 .add_modifier(Modifier::BOLD);
381
382 fn blank_line() -> ListItem<'static> {
383 ListItem::new(Line::from(Span::raw(String::new())))
384 }
385
386 fn user_padding_line(user_bg_style: Style, user_border_style: Style) -> ListItem<'static> {
387 ListItem::new(Line::from(vec![
388 Span::raw(" ".to_string()),
389 Span::styled("\u{258f}".to_string(), user_border_style), // ▏
390 Span::raw(" ".to_string()),
391 ]))
392 .style(user_bg_style)
393 }
394
395 fn close_user_bubble(
396 items: &mut Vec<ListItem<'static>>,
397 plain_lines: &mut Vec<String>,
398 open: &mut bool,
399 user_bg_style: Style,
400 user_border_style: Style,
401 ) {
402 if *open {
403 items.push(user_padding_line(user_bg_style, user_border_style));
404 plain_lines.push(" | ".to_string());
405 *open = false;
406 }
407 }
408
409 fn wrap_hard_display_width(s: &str, max_width: usize) -> Vec<String> {
410 if max_width == 0 {
411 return vec![String::new()];
412 }
413 if UnicodeWidthStr::width(s) <= max_width {
414 return vec![s.to_string()];
415 }
416
417 let mut lines: Vec<String> = Vec::new();
418 let mut current = String::new();
419 let mut current_width = 0usize;
420
421 for ch in s.chars() {
422 let ch_width = UnicodeWidthChar::width(ch).unwrap_or(0);
423
424 if !current.is_empty() && current_width + ch_width > max_width {

Callers 2

render_messagesMethod · 0.80
count_message_linesMethod · 0.80

Calls 13

render_tool_cardFunction · 0.85
styleMethod · 0.80
render_cachedMethod · 0.80
iterMethod · 0.80
collectMethod · 0.80
renderMethod · 0.65
pushMethod · 0.45
currentMethod · 0.45
is_emptyMethod · 0.45
containsMethod · 0.45
insertMethod · 0.45
cloneMethod · 0.45

Tested by

no test coverage detected