1use gpui::{App, AppContext, Context, Entity};
2use language::LanguageRegistry;
3use markdown::Markdown;
4use std::{path::PathBuf, process::ExitStatus, sync::Arc, time::Instant};
5
6pub struct Terminal {
7 command: Entity<Markdown>,
8 working_dir: Option<PathBuf>,
9 terminal: Entity<terminal::Terminal>,
10 started_at: Instant,
11 output: Option<TerminalOutput>,
12}
13
14pub struct TerminalOutput {
15 pub ended_at: Instant,
16 pub exit_status: Option<ExitStatus>,
17 pub was_content_truncated: bool,
18 pub original_content_len: usize,
19 pub content_line_count: usize,
20 pub finished_with_empty_output: bool,
21}
22
23impl Terminal {
24 pub fn new(
25 command: String,
26 working_dir: Option<PathBuf>,
27 terminal: Entity<terminal::Terminal>,
28 language_registry: Arc<LanguageRegistry>,
29 cx: &mut Context<Self>,
30 ) -> Self {
31 Self {
32 command: cx.new(|cx| {
33 Markdown::new(
34 format!("```\n{}\n```", command).into(),
35 Some(language_registry.clone()),
36 None,
37 cx,
38 )
39 }),
40 working_dir,
41 terminal,
42 started_at: Instant::now(),
43 output: None,
44 }
45 }
46
47 pub fn finish(
48 &mut self,
49 exit_status: Option<ExitStatus>,
50 original_content_len: usize,
51 truncated_content_len: usize,
52 content_line_count: usize,
53 finished_with_empty_output: bool,
54 cx: &mut Context<Self>,
55 ) {
56 self.output = Some(TerminalOutput {
57 ended_at: Instant::now(),
58 exit_status,
59 was_content_truncated: truncated_content_len < original_content_len,
60 original_content_len,
61 content_line_count,
62 finished_with_empty_output,
63 });
64 cx.notify();
65 }
66
67 pub fn command(&self) -> &Entity<Markdown> {
68 &self.command
69 }
70
71 pub fn working_dir(&self) -> &Option<PathBuf> {
72 &self.working_dir
73 }
74
75 pub fn started_at(&self) -> Instant {
76 self.started_at
77 }
78
79 pub fn output(&self) -> Option<&TerminalOutput> {
80 self.output.as_ref()
81 }
82
83 pub fn inner(&self) -> &Entity<terminal::Terminal> {
84 &self.terminal
85 }
86
87 pub fn to_markdown(&self, cx: &App) -> String {
88 format!(
89 "Terminal:\n```\n{}\n```\n",
90 self.terminal.read(cx).get_content()
91 )
92 }
93}