Files
oak-gpui/crates/repl/src/outputs/user_error.rs
T
h-michaelson20 4778d61bdd Fix copy button not working for REPL error output (#40669)
## Description

Fixes the copy button functionality in REPL interactive mode error
output sections.

When executing Python code that produces errors in the REPL (e.g.,
`NameError`), the copy button in the error output section was
unresponsive. The stdout/stderr copy button worked correctly, but the
error traceback section copy button had no effect when clicked.

Fixes #40207

## Changes

Modified the following:
src/outputs.rs: Fixed context issues in render_output_controls by
replacing cx.listener() with simple closures, and added custom button
implementation for ErrorOutput that copies/opens the complete error
(name + message + traceback)
src/outputs/plain.rs: Made full_text() method public to allow access
from button handlers
src/outputs/user_error.rs: Added Clone derive to ErrorView struct and
removed a couple pieces of commented code

## Why This Matters

The copy button was clearly broken and it is useful to have for REPL
workflows. Users could potentially need to copy error messages for a
variety of reasons.

## Testing

See attached demo for proof that the fix is working as intended. (this
is my first ever commit, if there are additional test cases I need to
write or run, please let me know!)


https://github.com/user-attachments/assets/da158205-4119-47eb-a271-196ef8d196e4

Release Notes:

- Fixed copy button not working for REPL error output
2025-10-28 06:52:53 +00:00

46 lines
1.4 KiB
Rust

use gpui::{AnyElement, App, Entity, FontWeight, Window};
use ui::{Label, h_flex, prelude::*, v_flex};
use crate::outputs::plain::TerminalOutput;
/// Userspace error from the kernel
#[derive(Clone)]
pub struct ErrorView {
pub ename: String,
pub evalue: String,
pub traceback: Entity<TerminalOutput>,
}
impl ErrorView {
pub fn render(&self, window: &mut Window, cx: &mut App) -> Option<AnyElement> {
let theme = cx.theme();
let padding = window.line_height() / 2.;
Some(
v_flex()
.gap_3()
.child(
h_flex()
.font_buffer(cx)
.child(
Label::new(format!("{}: ", self.ename.clone()))
.color(Color::Error)
.weight(FontWeight::BOLD),
)
.child(Label::new(self.evalue.clone()).weight(FontWeight::BOLD)),
)
.child(
div()
.w_full()
.px(padding)
.py(padding)
.border_l_1()
.border_color(theme.status().error_border)
.child(self.traceback.clone()),
)
.into_any_element(),
)
}
}