summaryrefslogtreecommitdiff
path: root/helix-tui/src/lib.rs
blob: 59327d7c348da3feb77ce39918c6045461a1ff35 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
//! [tui](https://github.com/fdehau/tui-rs) is a library used to build rich
//! terminal users interfaces and dashboards.
//!
//! ![](https://raw.githubusercontent.com/fdehau/tui-rs/master/assets/demo.gif)
//!
//! # Get started
//!
//! ## Adding `tui` as a dependency
//!
//! ```toml
//! [dependencies]
//! tui = "0.15"
//! crossterm = "0.19"
//! ```
//!
//! The same logic applies for all other available backends.
//!
//! ## Creating a `Terminal`
//!
//! Every application using `tui` should start by instantiating a `Terminal`. It is a light
//! abstraction over available backends that provides basic functionalities such as clearing the
//! screen, hiding the cursor, etc.
//!
//! ```rust,no_run
//! use std::io;
//! use helix_tui::Terminal;
//! use helix_tui::backend::CrosstermBackend;
//! use helix_view::editor::Config;
//!
//! fn main() -> Result<(), io::Error> {
//!     let stdout = io::stdout();
//!     let config = Config::default();
//!     let backend = CrosstermBackend::new(stdout, &config);
//!     let mut terminal = Terminal::new(backend)?;
//!     Ok(())
//! }
//! ```
//!
//! You may also refer to the examples to find out how to create a `Terminal` for each available
//! backend.
//!
//! ## Building a User Interface (UI)
//!
//! Every component of your interface will be implementing the `Widget` trait. The library comes
//! with a predefined set of widgets that should meet most of your use cases. You are also free to
//! implement your own.
//!
//! Each widget follows a builder pattern API providing a default configuration along with methods
//! to customize them. The widget is then rendered using the `Frame::render_widget` which take
//! your widget instance an area to draw to.
//!
//! The following example renders a block of the size of the terminal:
//!
//! ```rust,no_run
//! use std::io;
//! use crossterm::terminal;
//! use helix_tui::Terminal;
//! use helix_tui::backend::CrosstermBackend;
//! use helix_tui::widgets::{Widget, Block, Borders};
//! use helix_tui::layout::{Layout, Constraint, Direction};
//! use helix_view::editor::Config;
//!
//! fn main() -> Result<(), io::Error> {
//!     terminal::enable_raw_mode().unwrap();
//!     let stdout = io::stdout();
//!     let config = Config::default();
//!     let backend = CrosstermBackend::new(stdout, &config);
//!     let mut terminal = Terminal::new(backend)?;
//!     // terminal.draw(|f| {
//!     //     let size = f.size();
//!     //     let block = Block::default()
//!     //         .title("Block")
//!     //         .borders(Borders::ALL);
//!     //     f.render_widget(block, size);
//!     // })?;
//!     Ok(())
//! }
//! ```
//!
//! ## Layout
//!
//! The library comes with a basic yet useful layout management object called `Layout`. As you may
//! see below and in the examples, the library makes heavy use of the builder pattern to provide
//! full customization. And `Layout` is no exception:
//!
//! ```rust,no_run
//! use std::io;
//! use crossterm::terminal;
//! use helix_tui::Terminal;
//! use helix_tui::backend::CrosstermBackend;
//! use helix_tui::widgets::{Widget, Block, Borders};
//! use helix_tui::layout::{Layout, Constraint, Direction};
//! use helix_view::editor::Config;
//!
//! fn main() -> Result<(), io::Error> {
//!     terminal::enable_raw_mode().unwrap();
//!     let stdout = io::stdout();
//!     let config = Config::default();
//!     let backend = CrosstermBackend::new(stdout, &config);
//!     let mut terminal = Terminal::new(backend)?;
//!     // terminal.draw(|f| {
//!     //     let chunks = Layout::default()
//!     //         .direction(Direction::Vertical)
//!     //         .margin(1)
//!     //         .constraints(
//!     //             [
//!     //                 Constraint::Percentage(10),
//!     //                 Constraint::Percentage(80),
//!     //                 Constraint::Percentage(10)
//!     //             ].as_ref()
//!     //         )
//!     //         .split(f.size());
//!     //     let block = Block::default()
//!     //          .title("Block")
//!     //          .borders(Borders::ALL);
//!     //     f.render_widget(block, chunks[0]);
//!     //     let block = Block::default()
//!     //          .title("Block 2")
//!     //          .borders(Borders::ALL);
//!     //     f.render_widget(block, chunks[1]);
//!     // })?;
//!     Ok(())
//! }
//! ```
//!
//! This let you describe responsive terminal UI by nesting layouts. You should note that by
//! default the computed layout tries to fill the available space completely. So if for any reason
//! you might need a blank space somewhere, try to pass an additional constraint and don't use the
//! corresponding area.

pub mod backend;
pub mod buffer;
pub mod layout;
pub mod symbols;
pub mod terminal;
pub mod text;
pub mod widgets;

pub use self::terminal::{Terminal, TerminalOptions, Viewport};