feat: run shell commands asynchronously from command mode
This commit is contained in:
@@ -15354,3 +15354,93 @@ fn draw(
|
||||
frame, editor, workspace, workspace, top, left, syntax, document, panels,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shell_output_popup_routes_wheels_and_hides_document_cursor() {
|
||||
let mut session = EditorSession::open(None, vec![], None).unwrap();
|
||||
session.editor_mut().set_message("");
|
||||
let source = session.editor().lines().to_vec();
|
||||
let cursor = session.editor().cursor();
|
||||
session.editor_mut().show_command_output(
|
||||
"printf output".into(),
|
||||
Err((0..40)
|
||||
.map(|row| format!("OUTPUT {row} {}", "wide ".repeat(30)))
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n")),
|
||||
);
|
||||
let area = Rect::new(3, 2, 80, 16);
|
||||
let mut terminal = Terminal::with_options(
|
||||
ratatui::backend::TestBackend::new(90, 22),
|
||||
ratatui::TerminalOptions {
|
||||
viewport: ratatui::Viewport::Fixed(area),
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
let mut views = BufferViewports::default();
|
||||
terminal
|
||||
.draw(|frame| views.draw_session(frame, &mut session))
|
||||
.unwrap();
|
||||
let text = screen_text(&terminal);
|
||||
assert!(text.contains("printf output"));
|
||||
assert!(text.contains("OUTPUT 0"));
|
||||
assert!(text.contains("Enter/Esc close"));
|
||||
assert!(!terminal.backend().cursor_visible());
|
||||
let offsets = views.offsets.clone();
|
||||
assert!(views.scroll(
|
||||
&mut session,
|
||||
document_wheel(MouseEventKind::ScrollDown, area.x, area.y)
|
||||
));
|
||||
assert_eq!(session.editor().command_output().unwrap().content.top, 3);
|
||||
assert!(views.scroll(
|
||||
&mut session,
|
||||
document_wheel(MouseEventKind::ScrollRight, area.x, area.y)
|
||||
));
|
||||
assert_eq!(session.editor().command_output().unwrap().content.left, 3);
|
||||
assert_eq!(views.offsets, offsets);
|
||||
assert_eq!(session.editor().lines(), source.as_slice());
|
||||
assert_eq!(session.editor().cursor(), cursor);
|
||||
session.handle(Input::Escape);
|
||||
terminal
|
||||
.draw(|frame| views.draw_session(frame, &mut session))
|
||||
.unwrap();
|
||||
assert!(session.editor().command_output().is_none());
|
||||
assert!(terminal.backend().cursor_visible());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shell_output_panel_clips_sanitized_content_in_offset_and_tiny_areas() {
|
||||
let mut editor = Editor::open(None, vec![]).unwrap();
|
||||
editor.show_command_output(
|
||||
"shell title".into(),
|
||||
Err("SKIPPED\nabcdVISIBLE\u{1b} tail".into()),
|
||||
);
|
||||
editor.handle(Input::Down);
|
||||
for _ in 0..4 {
|
||||
editor.handle(Input::Right);
|
||||
}
|
||||
let diagnostic = &editor.command_output().unwrap().content;
|
||||
for (width, height) in [(50, 12), (3, 2), (1, 1), (0, 1), (1, 0)] {
|
||||
let area = Rect::new(3, 2, width, height);
|
||||
let mut terminal = Terminal::with_options(
|
||||
ratatui::backend::TestBackend::new(60, 18),
|
||||
ratatui::TerminalOptions {
|
||||
viewport: ratatui::Viewport::Fixed(area),
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
terminal
|
||||
.draw(|frame| {
|
||||
draw_diagnostic_panel(frame, diagnostic, area, "shell title", false);
|
||||
})
|
||||
.unwrap();
|
||||
assert!(!terminal.backend().cursor_visible());
|
||||
let text = screen_text(&terminal);
|
||||
assert!(!text.contains("SKIPPED"));
|
||||
assert!(!text.contains('\u{1b}'));
|
||||
if width == 50 {
|
||||
assert!(text.contains("shell title"));
|
||||
assert!(text.contains("VISIBLE"));
|
||||
assert!(!text.contains("abcd"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user