[go: up one dir, main page]

Struct ratatui::Terminal

source ·
pub struct Terminal<B>
where B: Backend,
{ /* private fields */ }
Expand description

An interface to interact and draw Frames on the user’s terminal.

This is the main entry point for Ratatui. It is responsible for drawing and maintaining the state of the buffers, cursor and viewport.

The Terminal is generic over a Backend implementation which is used to interface with the underlying terminal library. The Backend trait is implemented for three popular Rust terminal libraries: Crossterm, Termion and Termwiz. See the backend module for more information.

The Terminal struct maintains two buffers: the current and the previous. When the widgets are drawn, the changes are accumulated in the current buffer. At the end of each draw pass, the two buffers are compared, and only the changes between these buffers are written to the terminal, avoiding any redundant operations. After flushing these changes, the buffers are swapped to prepare for the next draw cycle./

The terminal also has a viewport which is the area of the terminal that is currently visible to the user. It can be either fullscreen, inline or fixed. See Viewport for more information.

Applications should detect terminal resizes and call Terminal::draw to redraw the application with the new size. This will automatically resize the internal buffers to match the new size for inline and fullscreen viewports. Fixed viewports are not resized automatically.

Examples

use std::io::stdout;
use ratatui::{prelude::*, widgets::Paragraph};

let backend = CrosstermBackend::new(stdout());
let mut terminal = Terminal::new(backend)?;
terminal.draw(|frame| {
    let area = frame.size();
    frame.render_widget(Paragraph::new("Hello World!"), area);
    frame.set_cursor(0, 0);
})?;

Implementations§

source§

impl<B> Terminal<B>
where B: Backend,

source

pub fn new(backend: B) -> Result<Terminal<B>>

Creates a new Terminal with the given Backend with a full screen viewport.

Example
let backend = CrosstermBackend::new(stdout());
let terminal = Terminal::new(backend)?;
Examples found in repository?
examples/colors_rgb.rs (line 37)
35
36
37
38
39
40
    pub fn new() -> Result<Self> {
        Ok(Self {
            terminal: Terminal::new(CrosstermBackend::new(stdout()))?,
            should_quit: false,
        })
    }
More examples
Hide additional examples
examples/canvas.rs (line 191)
188
189
190
191
192
fn init_terminal() -> io::Result<Terminal<CrosstermBackend<Stdout>>> {
    enable_raw_mode()?;
    stdout().execute(EnterAlternateScreen)?;
    Terminal::new(CrosstermBackend::new(stdout()))
}
examples/gauge.rs (line 173)
170
171
172
173
174
175
    pub fn start() -> io::Result<Term> {
        stdout().execute(EnterAlternateScreen)?;
        enable_raw_mode()?;
        let terminal = Terminal::new(CrosstermBackend::new(stdout()))?;
        Ok(Self { terminal })
    }
examples/block.rs (line 43)
38
39
40
41
42
43
44
45
fn setup_terminal() -> Result<Terminal> {
    enable_raw_mode()?;
    let mut stdout = stdout();
    execute!(stdout, EnterAlternateScreen)?;
    let backend = CrosstermBackend::new(stdout);
    let terminal = Terminal::new(backend)?;
    Ok(terminal)
}
examples/panic.rs (line 67)
61
62
63
64
65
66
67
68
69
70
71
fn init_terminal() -> Result<Terminal<CrosstermBackend<io::Stdout>>> {
    crossterm::execute!(io::stdout(), EnterAlternateScreen)?;
    enable_raw_mode()?;

    let backend = CrosstermBackend::new(io::stdout());

    let mut terminal = Terminal::new(backend)?;
    terminal.hide_cursor()?;

    Ok(terminal)
}
examples/hello_world.rs (line 36)
32
33
34
35
36
37
fn setup_terminal() -> Result<Terminal<CrosstermBackend<Stdout>>> {
    let mut stdout = io::stdout();
    enable_raw_mode().context("failed to enable raw mode")?;
    execute!(stdout, EnterAlternateScreen).context("unable to enter alternate screen")?;
    Terminal::new(CrosstermBackend::new(stdout)).context("creating terminal failed")
}
source

pub fn with_options(backend: B, options: TerminalOptions) -> Result<Terminal<B>>

Creates a new Terminal with the given Backend and TerminalOptions.

Example
let backend = CrosstermBackend::new(stdout());
let viewport = Viewport::Fixed(Rect::new(0, 0, 10, 10));
let terminal = Terminal::with_options(
    backend,
    TerminalOptions { viewport },
)?;
Examples found in repository?
examples/demo2/term.rs (line 29)
23
24
25
26
27
28
29
30
31
32
33
34
35
    pub fn start() -> Result<Self> {
        // this size is to match the size of the terminal when running the demo
        // using vhs in a 1280x640 sized window (github social preview size)
        let options = TerminalOptions {
            viewport: Viewport::Fixed(Rect::new(0, 0, 81, 18)),
        };
        let terminal = Terminal::with_options(CrosstermBackend::new(io::stdout()), options)?;
        enable_raw_mode().context("enable raw mode")?;
        stdout()
            .execute(EnterAlternateScreen)
            .context("enter alternate screen")?;
        Ok(Self { terminal })
    }
More examples
Hide additional examples
examples/inline.rs (lines 70-75)
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
fn main() -> Result<(), Box<dyn Error>> {
    crossterm::terminal::enable_raw_mode()?;
    let stdout = io::stdout();
    let backend = CrosstermBackend::new(stdout);
    let mut terminal = Terminal::with_options(
        backend,
        TerminalOptions {
            viewport: Viewport::Inline(8),
        },
    )?;

    let (tx, rx) = mpsc::channel();
    input_handling(tx.clone());
    let workers = workers(tx);
    let mut downloads = downloads();

    for w in &workers {
        let d = downloads.next(w.id).unwrap();
        w.tx.send(d).unwrap();
    }

    run_app(&mut terminal, workers, downloads, rx)?;

    crossterm::terminal::disable_raw_mode()?;
    terminal.clear()?;

    Ok(())
}
source

pub fn get_frame(&mut self) -> Frame<'_>

Get a Frame object which provides a consistent view into the terminal state for rendering.

source

pub fn current_buffer_mut(&mut self) -> &mut Buffer

Gets the current buffer as a mutable reference.

source

pub fn backend(&self) -> &B

Gets the backend

source

pub fn backend_mut(&mut self) -> &mut B

Gets the backend as a mutable reference

Examples found in repository?
examples/block.rs (line 49)
47
48
49
50
51
fn restore_terminal(mut terminal: Terminal) -> Result<()> {
    disable_raw_mode()?;
    execute!(terminal.backend_mut(), LeaveAlternateScreen)?;
    Ok(())
}
More examples
Hide additional examples
examples/hello_world.rs (line 43)
41
42
43
44
45
46
fn restore_terminal(terminal: &mut Terminal<CrosstermBackend<Stdout>>) -> Result<()> {
    disable_raw_mode().context("failed to disable raw mode")?;
    execute!(terminal.backend_mut(), LeaveAlternateScreen)
        .context("unable to switch to main screen")?;
    terminal.show_cursor().context("unable to show cursor")
}
examples/custom_widget.rs (line 136)
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
fn main() -> Result<(), Box<dyn Error>> {
    // setup terminal
    enable_raw_mode()?;
    let mut stdout = io::stdout();
    execute!(stdout, EnterAlternateScreen, EnableMouseCapture)?;
    let backend = CrosstermBackend::new(stdout);
    let mut terminal = Terminal::new(backend)?;

    // create app and run it
    let res = run_app(&mut terminal);

    // restore terminal
    disable_raw_mode()?;
    execute!(
        terminal.backend_mut(),
        LeaveAlternateScreen,
        DisableMouseCapture
    )?;
    terminal.show_cursor()?;

    if let Err(err) = res {
        println!("{err:?}");
    }

    Ok(())
}
examples/layout.rs (line 25)
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
fn main() -> Result<(), Box<dyn Error>> {
    // setup terminal
    enable_raw_mode()?;
    let mut stdout = io::stdout();
    execute!(stdout, EnterAlternateScreen, EnableMouseCapture)?;
    let backend = CrosstermBackend::new(stdout);
    let mut terminal = Terminal::new(backend)?;

    // create app and run it
    let res = run_app(&mut terminal);

    // restore terminal
    disable_raw_mode()?;
    execute!(
        terminal.backend_mut(),
        LeaveAlternateScreen,
        DisableMouseCapture
    )?;
    terminal.show_cursor()?;

    if let Err(err) = res {
        println!("{err:?}");
    }

    Ok(())
}
examples/popup.rs (line 35)
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
fn main() -> Result<(), Box<dyn Error>> {
    // setup terminal
    enable_raw_mode()?;
    let mut stdout = io::stdout();
    execute!(stdout, EnterAlternateScreen, EnableMouseCapture)?;
    let backend = CrosstermBackend::new(stdout);
    let mut terminal = Terminal::new(backend)?;

    // create app and run it
    let app = App::new();
    let res = run_app(&mut terminal, app);

    // restore terminal
    disable_raw_mode()?;
    execute!(
        terminal.backend_mut(),
        LeaveAlternateScreen,
        DisableMouseCapture
    )?;
    terminal.show_cursor()?;

    if let Err(err) = res {
        println!("{err:?}");
    }

    Ok(())
}
examples/table.rs (line 86)
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
fn main() -> Result<(), Box<dyn Error>> {
    // setup terminal
    enable_raw_mode()?;
    let mut stdout = io::stdout();
    execute!(stdout, EnterAlternateScreen, EnableMouseCapture)?;
    let backend = CrosstermBackend::new(stdout);
    let mut terminal = Terminal::new(backend)?;

    // create app and run it
    let app = App::new();
    let res = run_app(&mut terminal, app);

    // restore terminal
    disable_raw_mode()?;
    execute!(
        terminal.backend_mut(),
        LeaveAlternateScreen,
        DisableMouseCapture
    )?;
    terminal.show_cursor()?;

    if let Err(err) = res {
        println!("{err:?}");
    }

    Ok(())
}
source

pub fn flush(&mut self) -> Result<()>

Obtains a difference between the previous and the current buffer and passes it to the current backend for drawing.

Examples found in repository?
examples/demo/termwiz.rs (line 21)
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
pub fn run(tick_rate: Duration, enhanced_graphics: bool) -> Result<(), Box<dyn Error>> {
    let backend = TermwizBackend::new()?;
    let mut terminal = Terminal::new(backend)?;
    terminal.hide_cursor()?;

    // create app and run it
    let app = App::new("Termwiz Demo", enhanced_graphics);
    let res = run_app(&mut terminal, app, tick_rate);

    terminal.show_cursor()?;
    terminal.flush()?;

    if let Err(err) = res {
        println!("{err:?}");
    }

    Ok(())
}
source

pub fn resize(&mut self, size: Rect) -> Result<()>

Updates the Terminal so that internal buffers match the requested size.

Requested size will be saved so the size can remain consistent when rendering. This leads to a full clear of the screen.

Examples found in repository?
examples/demo2/app.rs (line 53)
49
50
51
52
53
54
55
56
57
    fn handle_events(&mut self) -> Result<()> {
        match Term::next_event(Duration::from_millis(16))? {
            Some(Event::Key(key)) => self.handle_key_event(key),
            Some(Event::Resize(width, height)) => {
                Ok(self.term.resize(Rect::new(0, 0, width, height))?)
            }
            _ => Ok(()),
        }
    }
source

pub fn autoresize(&mut self) -> Result<()>

Queries the backend for size and resizes if it doesn’t match the previous size.

Examples found in repository?
examples/inline.rs (line 176)
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
fn run_app<B: Backend>(
    terminal: &mut Terminal<B>,
    workers: Vec<Worker>,
    mut downloads: Downloads,
    rx: mpsc::Receiver<Event>,
) -> Result<(), Box<dyn Error>> {
    let mut redraw = true;
    loop {
        if redraw {
            terminal.draw(|f| ui(f, &downloads))?;
        }
        redraw = true;

        match rx.recv()? {
            Event::Input(event) => {
                if event.code == crossterm::event::KeyCode::Char('q') {
                    break;
                }
            }
            Event::Resize => {
                terminal.autoresize()?;
            }
            Event::Tick => {}
            Event::DownloadUpdate(worker_id, _download_id, progress) => {
                let download = downloads.in_progress.get_mut(&worker_id).unwrap();
                download.progress = progress;
                redraw = false
            }
            Event::DownloadDone(worker_id, download_id) => {
                let download = downloads.in_progress.remove(&worker_id).unwrap();
                terminal.insert_before(1, |buf| {
                    Paragraph::new(Line::from(vec![
                        Span::from("Finished "),
                        Span::styled(
                            format!("download {download_id}"),
                            Style::default().add_modifier(Modifier::BOLD),
                        ),
                        Span::from(format!(
                            " in {}ms",
                            download.started_at.elapsed().as_millis()
                        )),
                    ]))
                    .render(buf.area, buf);
                })?;
                match downloads.next(worker_id) {
                    Some(d) => workers[worker_id].tx.send(d).unwrap(),
                    None => {
                        if downloads.in_progress.is_empty() {
                            terminal.insert_before(1, |buf| {
                                Paragraph::new("Done !").render(buf.area, buf);
                            })?;
                            break;
                        }
                    }
                };
            }
        };
    }
    Ok(())
}
source

pub fn draw<F>(&mut self, f: F) -> Result<CompletedFrame<'_>>
where F: FnOnce(&mut Frame<'_>),

Synchronizes terminal size, calls the rendering closure, flushes the current internal state and prepares for the next draw call.

This is the main entry point for drawing to the terminal.

Examples
let backend = CrosstermBackend::new(stdout());
let mut terminal = Terminal::new(backend)?;
terminal.draw(|frame| {
    let area = frame.size();
    frame.render_widget(Paragraph::new("Hello World!"), area);
    frame.set_cursor(0, 0);
})?;
Examples found in repository?
examples/gauge.rs (line 184)
183
184
185
186
    fn draw(&mut self, frame: impl FnOnce(&mut Frame)) -> Result<()> {
        self.terminal.draw(frame)?;
        Ok(())
    }
More examples
Hide additional examples
examples/colors_rgb.rs (lines 54-56)
53
54
55
56
57
58
    fn draw(&mut self) -> Result<()> {
        self.terminal.draw(|frame| {
            frame.render_widget(RgbColors, frame.size());
        })?;
        Ok(())
    }
examples/block.rs (line 55)
53
54
55
56
57
58
59
60
fn run(terminal: &mut Terminal) -> Result<()> {
    loop {
        terminal.draw(ui)?;
        if handle_events()?.is_break() {
            return Ok(());
        }
    }
}
examples/hello_world.rs (line 54)
52
53
54
55
56
57
58
59
60
fn run(terminal: &mut Terminal<CrosstermBackend<Stdout>>) -> Result<()> {
    loop {
        terminal.draw(crate::render_app)?;
        if should_quit()? {
            break;
        }
    }
    Ok(())
}
examples/demo2/app.rs (line 44)
42
43
44
45
46
47
    fn draw(&mut self) -> Result<()> {
        self.term
            .draw(|frame| frame.render_widget(Root::new(&self.context), frame.size()))
            .context("terminal.draw")?;
        Ok(())
    }
examples/layout.rs (line 40)
38
39
40
41
42
43
44
45
46
47
48
fn run_app<B: Backend>(terminal: &mut Terminal<B>) -> io::Result<()> {
    loop {
        terminal.draw(ui)?;

        if let Event::Key(key) = event::read()? {
            if let KeyCode::Char('q') = key.code {
                return Ok(());
            }
        }
    }
}
source

pub fn hide_cursor(&mut self) -> Result<()>

Hides the cursor.

Examples found in repository?
examples/panic.rs (line 68)
61
62
63
64
65
66
67
68
69
70
71
fn init_terminal() -> Result<Terminal<CrosstermBackend<io::Stdout>>> {
    crossterm::execute!(io::stdout(), EnterAlternateScreen)?;
    enable_raw_mode()?;

    let backend = CrosstermBackend::new(io::stdout());

    let mut terminal = Terminal::new(backend)?;
    terminal.hide_cursor()?;

    Ok(terminal)
}
More examples
Hide additional examples
examples/demo/termwiz.rs (line 14)
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
pub fn run(tick_rate: Duration, enhanced_graphics: bool) -> Result<(), Box<dyn Error>> {
    let backend = TermwizBackend::new()?;
    let mut terminal = Terminal::new(backend)?;
    terminal.hide_cursor()?;

    // create app and run it
    let app = App::new("Termwiz Demo", enhanced_graphics);
    let res = run_app(&mut terminal, app, tick_rate);

    terminal.show_cursor()?;
    terminal.flush()?;

    if let Err(err) = res {
        println!("{err:?}");
    }

    Ok(())
}
source

pub fn show_cursor(&mut self) -> Result<()>

Shows the cursor.

Examples found in repository?
examples/hello_world.rs (line 45)
41
42
43
44
45
46
fn restore_terminal(terminal: &mut Terminal<CrosstermBackend<Stdout>>) -> Result<()> {
    disable_raw_mode().context("failed to disable raw mode")?;
    execute!(terminal.backend_mut(), LeaveAlternateScreen)
        .context("unable to switch to main screen")?;
    terminal.show_cursor().context("unable to show cursor")
}
More examples
Hide additional examples
examples/demo/termwiz.rs (line 20)
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
pub fn run(tick_rate: Duration, enhanced_graphics: bool) -> Result<(), Box<dyn Error>> {
    let backend = TermwizBackend::new()?;
    let mut terminal = Terminal::new(backend)?;
    terminal.hide_cursor()?;

    // create app and run it
    let app = App::new("Termwiz Demo", enhanced_graphics);
    let res = run_app(&mut terminal, app, tick_rate);

    terminal.show_cursor()?;
    terminal.flush()?;

    if let Err(err) = res {
        println!("{err:?}");
    }

    Ok(())
}
examples/custom_widget.rs (line 140)
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
fn main() -> Result<(), Box<dyn Error>> {
    // setup terminal
    enable_raw_mode()?;
    let mut stdout = io::stdout();
    execute!(stdout, EnterAlternateScreen, EnableMouseCapture)?;
    let backend = CrosstermBackend::new(stdout);
    let mut terminal = Terminal::new(backend)?;

    // create app and run it
    let res = run_app(&mut terminal);

    // restore terminal
    disable_raw_mode()?;
    execute!(
        terminal.backend_mut(),
        LeaveAlternateScreen,
        DisableMouseCapture
    )?;
    terminal.show_cursor()?;

    if let Err(err) = res {
        println!("{err:?}");
    }

    Ok(())
}
examples/layout.rs (line 29)
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
fn main() -> Result<(), Box<dyn Error>> {
    // setup terminal
    enable_raw_mode()?;
    let mut stdout = io::stdout();
    execute!(stdout, EnterAlternateScreen, EnableMouseCapture)?;
    let backend = CrosstermBackend::new(stdout);
    let mut terminal = Terminal::new(backend)?;

    // create app and run it
    let res = run_app(&mut terminal);

    // restore terminal
    disable_raw_mode()?;
    execute!(
        terminal.backend_mut(),
        LeaveAlternateScreen,
        DisableMouseCapture
    )?;
    terminal.show_cursor()?;

    if let Err(err) = res {
        println!("{err:?}");
    }

    Ok(())
}
examples/popup.rs (line 39)
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
fn main() -> Result<(), Box<dyn Error>> {
    // setup terminal
    enable_raw_mode()?;
    let mut stdout = io::stdout();
    execute!(stdout, EnterAlternateScreen, EnableMouseCapture)?;
    let backend = CrosstermBackend::new(stdout);
    let mut terminal = Terminal::new(backend)?;

    // create app and run it
    let app = App::new();
    let res = run_app(&mut terminal, app);

    // restore terminal
    disable_raw_mode()?;
    execute!(
        terminal.backend_mut(),
        LeaveAlternateScreen,
        DisableMouseCapture
    )?;
    terminal.show_cursor()?;

    if let Err(err) = res {
        println!("{err:?}");
    }

    Ok(())
}
examples/table.rs (line 90)
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
fn main() -> Result<(), Box<dyn Error>> {
    // setup terminal
    enable_raw_mode()?;
    let mut stdout = io::stdout();
    execute!(stdout, EnterAlternateScreen, EnableMouseCapture)?;
    let backend = CrosstermBackend::new(stdout);
    let mut terminal = Terminal::new(backend)?;

    // create app and run it
    let app = App::new();
    let res = run_app(&mut terminal, app);

    // restore terminal
    disable_raw_mode()?;
    execute!(
        terminal.backend_mut(),
        LeaveAlternateScreen,
        DisableMouseCapture
    )?;
    terminal.show_cursor()?;

    if let Err(err) = res {
        println!("{err:?}");
    }

    Ok(())
}
source

pub fn get_cursor(&mut self) -> Result<(u16, u16)>

Gets the current cursor position.

This is the position of the cursor after the last draw call and is returned as a tuple of (x, y) coordinates.

source

pub fn set_cursor(&mut self, x: u16, y: u16) -> Result<()>

Sets the cursor position.

source

pub fn clear(&mut self) -> Result<()>

Clear the terminal and force a full redraw on the next draw call.

Examples found in repository?
examples/colors_rgb.rs (line 44)
42
43
44
45
46
47
48
49
50
51
    pub fn run(mut self) -> Result<()> {
        init_terminal()?;
        self.terminal.clear()?;
        while !self.should_quit {
            self.draw()?;
            self.handle_events()?;
        }
        restore_terminal()?;
        Ok(())
    }
More examples
Hide additional examples
examples/inline.rs (line 90)
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
fn main() -> Result<(), Box<dyn Error>> {
    crossterm::terminal::enable_raw_mode()?;
    let stdout = io::stdout();
    let backend = CrosstermBackend::new(stdout);
    let mut terminal = Terminal::with_options(
        backend,
        TerminalOptions {
            viewport: Viewport::Inline(8),
        },
    )?;

    let (tx, rx) = mpsc::channel();
    input_handling(tx.clone());
    let workers = workers(tx);
    let mut downloads = downloads();

    for w in &workers {
        let d = downloads.next(w.id).unwrap();
        w.tx.send(d).unwrap();
    }

    run_app(&mut terminal, workers, downloads, rx)?;

    crossterm::terminal::disable_raw_mode()?;
    terminal.clear()?;

    Ok(())
}
source

pub fn swap_buffers(&mut self)

Clears the inactive buffer and swaps it with the current buffer

source

pub fn size(&self) -> Result<Rect>

Queries the real size of the backend.

source

pub fn insert_before<F>(&mut self, height: u16, draw_fn: F) -> Result<()>
where F: FnOnce(&mut Buffer),

Insert some content before the current inline viewport. This has no effect when the viewport is fullscreen.

This function scrolls down the current viewport by the given height. The newly freed space is then made available to the draw_fn closure through a writable Buffer.

Before:

+-------------------+
|                   |
|      viewport     |
|                   |
+-------------------+

After:

+-------------------+
|      buffer       |
+-------------------+
+-------------------+
|                   |
|      viewport     |
|                   |
+-------------------+
Examples
Insert a single line before the current viewport
terminal.insert_before(1, |buf| {
    Paragraph::new(Line::from(vec![
        Span::raw("This line will be added "),
        Span::styled("before", Style::default().fg(Color::Blue)),
        Span::raw(" the current viewport")
    ])).render(buf.area, buf);
});
Examples found in repository?
examples/inline.rs (lines 186-199)
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
fn run_app<B: Backend>(
    terminal: &mut Terminal<B>,
    workers: Vec<Worker>,
    mut downloads: Downloads,
    rx: mpsc::Receiver<Event>,
) -> Result<(), Box<dyn Error>> {
    let mut redraw = true;
    loop {
        if redraw {
            terminal.draw(|f| ui(f, &downloads))?;
        }
        redraw = true;

        match rx.recv()? {
            Event::Input(event) => {
                if event.code == crossterm::event::KeyCode::Char('q') {
                    break;
                }
            }
            Event::Resize => {
                terminal.autoresize()?;
            }
            Event::Tick => {}
            Event::DownloadUpdate(worker_id, _download_id, progress) => {
                let download = downloads.in_progress.get_mut(&worker_id).unwrap();
                download.progress = progress;
                redraw = false
            }
            Event::DownloadDone(worker_id, download_id) => {
                let download = downloads.in_progress.remove(&worker_id).unwrap();
                terminal.insert_before(1, |buf| {
                    Paragraph::new(Line::from(vec![
                        Span::from("Finished "),
                        Span::styled(
                            format!("download {download_id}"),
                            Style::default().add_modifier(Modifier::BOLD),
                        ),
                        Span::from(format!(
                            " in {}ms",
                            download.started_at.elapsed().as_millis()
                        )),
                    ]))
                    .render(buf.area, buf);
                })?;
                match downloads.next(worker_id) {
                    Some(d) => workers[worker_id].tx.send(d).unwrap(),
                    None => {
                        if downloads.in_progress.is_empty() {
                            terminal.insert_before(1, |buf| {
                                Paragraph::new("Done !").render(buf.area, buf);
                            })?;
                            break;
                        }
                    }
                };
            }
        };
    }
    Ok(())
}

Trait Implementations§

source§

impl<B> Clone for Terminal<B>
where B: Backend + Clone,

source§

fn clone(&self) -> Terminal<B>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<B> Debug for Terminal<B>
where B: Backend + Debug,

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<B> Default for Terminal<B>
where B: Backend + Default,

source§

fn default() -> Terminal<B>

Returns the “default value” for a type. Read more
source§

impl<B> Drop for Terminal<B>
where B: Backend,

source§

fn drop(&mut self)

Executes the destructor for this type. Read more
source§

impl<B> Hash for Terminal<B>
where B: Backend + Hash,

source§

fn hash<__H: Hasher>(&self, state: &mut __H)

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where H: Hasher, Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
source§

impl<B> PartialEq for Terminal<B>
where B: Backend + PartialEq,

source§

fn eq(&self, other: &Terminal<B>) -> bool

This method tests for self and other values to be equal, and is used by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
source§

impl<B> Eq for Terminal<B>
where B: Backend + Eq,

source§

impl<B> StructuralEq for Terminal<B>
where B: Backend,

source§

impl<B> StructuralPartialEq for Terminal<B>
where B: Backend,

Auto Trait Implementations§

§

impl<B> RefUnwindSafe for Terminal<B>
where B: RefUnwindSafe,

§

impl<B> Send for Terminal<B>
where B: Send,

§

impl<B> Sync for Terminal<B>
where B: Sync,

§

impl<B> Unpin for Terminal<B>
where B: Unpin,

§

impl<B> UnwindSafe for Terminal<B>
where B: UnwindSafe,

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.