on master help sign in
Experiment with TUI so we can render selections.
commit9ad40bc40b57f88d2c81a5dc55373bd6e31a6c21 authorBlaž Hrastnik <blaz@mxxn.io> dateMon 7 Sep 2020, 18:10 (6 years ago) parent67017e5
3 files changed+70−7
Cargo.lock+20 helix-term/Cargo.toml+1−2 helix-term/src/editor.rs+49−5
Cargo.lock+20
@@ -212,6 +212,12 @@ version = "1.1.1"
212212source = "registry+https://github.com/rust-lang/crates.io-index"
213213checksum = "631ae5198c9be5e753e5cc215e1bd73c2b466a3565173db433f52bb9d3e66dba"
214214
215+[[package]]
216+name = "cassowary"
217+version = "0.3.0"
218+source = "registry+https://github.com/rust-lang/crates.io-index"
219+checksum = "df8670b8c7b9dae1793364eafadf7239c40d669904660c5960d74cfd80b46a53"
220+
215221[[package]]
216222name = "cc"
217223version = "1.0.59"
@@ -420,6 +426,7 @@ dependencies = [
420426 "helix-core",
421427 "num_cpus",
422428 "smol",
429+ "tui",
423430]
424431
425432[[package]]
@@ -738,6 +745,19 @@ dependencies = [
738745 "utf-8",
739746]
740747
748+[[package]]
749+name = "tui"
750+version = "0.10.0"
751+source = "registry+https://github.com/rust-lang/crates.io-index"
752+checksum = "a977b0bb2e2033a6fef950f218f13622c3c34e59754b704ce3492dedab1dfe95"
753+dependencies = [
754+ "bitflags",
755+ "cassowary",
756+ "crossterm",
757+ "unicode-segmentation",
758+ "unicode-width",
759+]
760+
741761[[package]]
742762name = "unicode-segmentation"
743763version = "1.6.0"
helix-term/Cargo.toml+1−2
@@ -22,6 +22,5 @@ crossterm = { version = "0.17.7", features = ["event-stream"] }
2222smol = "0.4"
2323futures = { version = "0.3.5", default-features = false, features = ["std", "async-await"] }
2424num_cpus = "1.13.0"
25+tui = { version = "0.10.0", default-features = false, features = ["crossterm"] }
2526# futures-timer = "3.0.2"
26−
27−# tui = { version = "0.9.5", default-features = false }
helix-term/src/editor.rs+49−5
@@ -14,9 +14,17 @@ use std::io::{self, stdout, Write};
1414use std::path::PathBuf;
1515use std::time::Duration;
1616
17+use tui::backend::CrosstermBackend;
18+use tui::buffer::Buffer as Surface;
19+use tui::layout::Rect;
20+use tui::style::Style;
21+
22+type Terminal = tui::Terminal<CrosstermBackend<std::io::Stdout>>;
23+
1724static EX: smol::Executor = smol::Executor::new();
1825
1926pub struct Editor {
27+ terminal: Terminal,
2028 state: Option<State>,
2129 first_line: u16,
2230 size: (u16, u16),
@@ -24,7 +32,12 @@ pub struct Editor {
2432
2533impl Editor {
2634 pub fn new(mut args: Args) -> Result<Self, Error> {
35+ let backend = CrosstermBackend::new(stdout());
36+
37+ let mut terminal = Terminal::new(backend)?;
38+
2739 let mut editor = Editor {
40+ terminal,
2841 state: None,
2942 first_line: 0,
3043 size: terminal::size().unwrap(),
@@ -45,6 +58,9 @@ impl Editor {
4558 fn render(&mut self) {
4659 match &self.state {
4760 Some(state) => {
61+ let area = Rect::new(0, 0, self.size.0, self.size.1);
62+ let mut surface = Surface::empty(area);
63+
4864 let lines = state
4965 .doc
5066 .lines_at(self.first_line as usize)
@@ -60,12 +76,33 @@ impl Editor {
6076 cursor::MoveTo(0, n as u16),
6177 Print((n + 1).to_string())
6278 );
63− execute!(
64− stdout,
65− SetForegroundColor(Color::Reset),
66− cursor::MoveTo(2, n as u16),
67− Print(line)
79+
80+ surface.set_string(2, n as u16, line, Style::default());
81+ // execute!(
82+ // stdout,
83+ // SetForegroundColor(Color::Reset),
84+ // cursor::MoveTo(2, n as u16),
85+ // Print(line)
86+ // );
87+ }
88+
89+ // iterate over selections and render them
90+ let select = Style::default().bg(tui::style::Color::LightBlue);
91+ let text = state.doc.slice(..);
92+ for range in state.selection.ranges() {
93+ // get terminal coords for x,y for each range pos
94+ // TODO: this won't work with multiline
95+ let (y1, x1) = coords_at_pos(&text, range.from());
96+ let (y2, x2) = coords_at_pos(&text, range.to());
97+ let area = Rect::new(
98+ (x1 + 2) as u16,
99+ y1 as u16,
100+ (x2 - x1 + 1) as u16,
101+ (y2 - y1 + 1) as u16,
68102 );
103+ surface.set_style(area, select);
104+
105+ // TODO: don't highlight next char in append mode
69106 }
70107
71108 let mode = match state.mode {
@@ -80,6 +117,13 @@ impl Editor {
80117 Print(mode)
81118 );
82119
120+ use tui::backend::Backend;
121+ // TODO: double buffer and diff here
122+ let empty = Surface::empty(area);
123+ self.terminal
124+ .backend_mut()
125+ .draw(empty.diff(&surface).into_iter());
126+
83127 // set cursor shape
84128 match state.mode {
85129 Mode::Insert => write!(stdout, "\x1B[6 q"),