terminal.rs

 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
33                .new(|cx| Markdown::new(command.into(), Some(language_registry.clone()), None, cx)),
34            working_dir,
35            terminal,
36            started_at: Instant::now(),
37            output: None,
38        }
39    }
40
41    pub fn finish(
42        &mut self,
43        exit_status: Option<ExitStatus>,
44        original_content_len: usize,
45        truncated_content_len: usize,
46        content_line_count: usize,
47        finished_with_empty_output: bool,
48        cx: &mut Context<Self>,
49    ) {
50        self.output = Some(TerminalOutput {
51            ended_at: Instant::now(),
52            exit_status,
53            was_content_truncated: truncated_content_len < original_content_len,
54            original_content_len,
55            content_line_count,
56            finished_with_empty_output,
57        });
58        cx.notify();
59    }
60
61    pub fn command(&self) -> &Entity<Markdown> {
62        &self.command
63    }
64
65    pub fn working_dir(&self) -> &Option<PathBuf> {
66        &self.working_dir
67    }
68
69    pub fn started_at(&self) -> Instant {
70        self.started_at
71    }
72
73    pub fn output(&self) -> Option<&TerminalOutput> {
74        self.output.as_ref()
75    }
76
77    pub fn inner(&self) -> &Entity<terminal::Terminal> {
78        &self.terminal
79    }
80
81    pub fn to_markdown(&self, cx: &App) -> String {
82        format!(
83            "Terminal:\n```\n{}\n```\n",
84            self.terminal.read(cx).get_content()
85        )
86    }
87}