Skip to content

Commit 8f8a74a

Browse files
Henry MichaelsonHenry Michaelson
authored andcommitted
Fix copy button not working for REPL error output
- Fixed copy button functionality in REPL error output section - Ensured both stdout/stderr and error sections have working copy buttons Fixes #40207
1 parent 59b87d5 commit 8f8a74a

File tree

3 files changed

+71
-10
lines changed

3 files changed

+71
-10
lines changed

crates/repl/src/outputs.rs

Lines changed: 69 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ use language::Buffer;
3939
use runtimelib::{ExecutionState, JupyterMessageContent, MimeBundle, MimeType};
4040
use ui::{
4141
CommonAnimationExt, Context, IntoElement, Styled, Tooltip, Window, div, prelude::*, v_flex,
42+
IconButton, IconName, ButtonStyle, h_flex,
4243
};
4344

4445
mod image;
@@ -146,13 +147,13 @@ impl Output {
146147
IconButton::new(ElementId::Name("copy-output".into()), IconName::Copy)
147148
.style(ButtonStyle::Transparent)
148149
.tooltip(Tooltip::text("Copy Output"))
149-
.on_click(cx.listener(move |_, _, window, cx| {
150+
.on_click(move |_, window, cx| {
150151
let clipboard_content = v.clipboard_content(window, cx);
151152

152153
if let Some(clipboard_content) = clipboard_content.as_ref() {
153154
cx.write_to_clipboard(clipboard_content.clone());
154155
}
155-
})),
156+
}),
156157
)
157158
})
158159
.when(v.has_buffer_content(window, cx), |el| {
@@ -164,10 +165,9 @@ impl Output {
164165
)
165166
.style(ButtonStyle::Transparent)
166167
.tooltip(Tooltip::text("Open in Buffer"))
167-
.on_click(cx.listener({
168+
.on_click({
168169
let workspace = workspace.clone();
169-
170-
move |_, _, window, cx| {
170+
move |_, window, cx| {
171171
let buffer_content =
172172
v.update(cx, |item, cx| item.buffer_content(window, cx));
173173

@@ -193,7 +193,7 @@ impl Output {
193193
.ok();
194194
}
195195
}
196-
})),
196+
}),
197197
)
198198
})
199199
.into_any_element(),
@@ -237,7 +237,69 @@ impl Output {
237237
Self::render_output_controls(content.clone(), workspace, window, cx)
238238
}
239239
Self::ErrorOutput(err) => {
240-
Self::render_output_controls(err.traceback.clone(), workspace, window, cx)
240+
// Add buttons for the traceback section
241+
Some(
242+
h_flex()
243+
.pl_1()
244+
.child(
245+
IconButton::new(ElementId::Name("copy-full-error-traceback".into()), IconName::Copy)
246+
.style(ButtonStyle::Transparent)
247+
.tooltip(Tooltip::text("Copy Full Error"))
248+
.on_click({
249+
let ename = err.ename.clone();
250+
let evalue = err.evalue.clone();
251+
let traceback = err.traceback.clone();
252+
move |_, _window, cx| {
253+
let traceback_text = traceback.read(cx).full_text();
254+
let full_error = format!("{}: {}\n{}", ename, evalue, traceback_text);
255+
let clipboard_content = ClipboardItem::new_string(full_error);
256+
cx.write_to_clipboard(clipboard_content);
257+
}
258+
}),
259+
)
260+
.child(
261+
IconButton::new(
262+
ElementId::Name("open-full-error-in-buffer-traceback".into()),
263+
IconName::FileTextOutlined,
264+
)
265+
.style(ButtonStyle::Transparent)
266+
.tooltip(Tooltip::text("Open Full Error in Buffer"))
267+
.on_click({
268+
let ename = err.ename.clone();
269+
let evalue = err.evalue.clone();
270+
let traceback = err.traceback.clone();
271+
let workspace = workspace.clone();
272+
move |_, window, cx| {
273+
if let Some(workspace) = workspace.upgrade() {
274+
let traceback_text = traceback.read(cx).full_text();
275+
let full_error = format!("{}: {}\n{}", ename, evalue, traceback_text);
276+
let buffer = cx.new(|cx| {
277+
let mut buffer = Buffer::local(full_error, cx)
278+
.with_language(language::PLAIN_TEXT.clone(), cx);
279+
buffer.set_capability(language::Capability::ReadOnly, cx);
280+
buffer
281+
});
282+
let editor = Box::new(cx.new(|cx| {
283+
let multibuffer = cx.new(|cx| {
284+
let mut multi_buffer =
285+
MultiBuffer::singleton(buffer.clone(), cx);
286+
multi_buffer.set_title("Full Error".to_string(), cx);
287+
multi_buffer
288+
});
289+
Editor::for_multibuffer(multibuffer, None, window, cx)
290+
}));
291+
workspace
292+
.update(cx, |workspace, cx| {
293+
workspace.add_item_to_active_pane(
294+
editor, None, true, window, cx,
295+
);
296+
});
297+
}
298+
}
299+
}),
300+
)
301+
.into_any_element()
302+
)
241303
}
242304
Self::Message(_) => None,
243305
Self::Table { content, .. } => {

crates/repl/src/outputs/plain.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ impl TerminalOutput {
197197
}
198198
}
199199

200-
fn full_text(&self) -> String {
200+
pub fn full_text(&self) -> String {
201201
let mut full_text = String::new();
202202

203203
// Get the total number of lines, including history

crates/repl/src/outputs/user_error.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use ui::{Label, h_flex, prelude::*, v_flex};
44
use crate::outputs::plain::TerminalOutput;
55

66
/// Userspace error from the kernel
7+
#[derive(Clone)]
78
pub struct ErrorView {
89
pub ename: String,
910
pub evalue: String,
@@ -24,13 +25,11 @@ impl ErrorView {
2425
.font_buffer(cx)
2526
.child(
2627
Label::new(format!("{}: ", self.ename.clone()))
27-
// .size(LabelSize::Large)
2828
.color(Color::Error)
2929
.weight(FontWeight::BOLD),
3030
)
3131
.child(
3232
Label::new(self.evalue.clone())
33-
// .size(LabelSize::Large)
3433
.weight(FontWeight::BOLD),
3534
),
3635
)

0 commit comments

Comments
 (0)