mirror of
https://github.com/helix-editor/helix.git
synced 2024-11-24 18:36:18 +04:00
Experiment with TUI so we can render selections.
This commit is contained in:
parent
67017e5336
commit
9ad40bc40b
20
Cargo.lock
generated
20
Cargo.lock
generated
@ -212,6 +212,12 @@ version = "1.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "631ae5198c9be5e753e5cc215e1bd73c2b466a3565173db433f52bb9d3e66dba"
|
||||
|
||||
[[package]]
|
||||
name = "cassowary"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "df8670b8c7b9dae1793364eafadf7239c40d669904660c5960d74cfd80b46a53"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.59"
|
||||
@ -420,6 +426,7 @@ dependencies = [
|
||||
"helix-core",
|
||||
"num_cpus",
|
||||
"smol",
|
||||
"tui",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -738,6 +745,19 @@ dependencies = [
|
||||
"utf-8",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tui"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a977b0bb2e2033a6fef950f218f13622c3c34e59754b704ce3492dedab1dfe95"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cassowary",
|
||||
"crossterm",
|
||||
"unicode-segmentation",
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-segmentation"
|
||||
version = "1.6.0"
|
||||
|
@ -22,6 +22,5 @@ crossterm = { version = "0.17.7", features = ["event-stream"] }
|
||||
smol = "0.4"
|
||||
futures = { version = "0.3.5", default-features = false, features = ["std", "async-await"] }
|
||||
num_cpus = "1.13.0"
|
||||
tui = { version = "0.10.0", default-features = false, features = ["crossterm"] }
|
||||
# futures-timer = "3.0.2"
|
||||
|
||||
# tui = { version = "0.9.5", default-features = false }
|
||||
|
@ -14,9 +14,17 @@
|
||||
use std::path::PathBuf;
|
||||
use std::time::Duration;
|
||||
|
||||
use tui::backend::CrosstermBackend;
|
||||
use tui::buffer::Buffer as Surface;
|
||||
use tui::layout::Rect;
|
||||
use tui::style::Style;
|
||||
|
||||
type Terminal = tui::Terminal<CrosstermBackend<std::io::Stdout>>;
|
||||
|
||||
static EX: smol::Executor = smol::Executor::new();
|
||||
|
||||
pub struct Editor {
|
||||
terminal: Terminal,
|
||||
state: Option<State>,
|
||||
first_line: u16,
|
||||
size: (u16, u16),
|
||||
@ -24,7 +32,12 @@ pub struct Editor {
|
||||
|
||||
impl Editor {
|
||||
pub fn new(mut args: Args) -> Result<Self, Error> {
|
||||
let backend = CrosstermBackend::new(stdout());
|
||||
|
||||
let mut terminal = Terminal::new(backend)?;
|
||||
|
||||
let mut editor = Editor {
|
||||
terminal,
|
||||
state: None,
|
||||
first_line: 0,
|
||||
size: terminal::size().unwrap(),
|
||||
@ -45,6 +58,9 @@ pub fn open(&mut self, path: PathBuf) -> Result<(), Error> {
|
||||
fn render(&mut self) {
|
||||
match &self.state {
|
||||
Some(state) => {
|
||||
let area = Rect::new(0, 0, self.size.0, self.size.1);
|
||||
let mut surface = Surface::empty(area);
|
||||
|
||||
let lines = state
|
||||
.doc
|
||||
.lines_at(self.first_line as usize)
|
||||
@ -60,12 +76,33 @@ fn render(&mut self) {
|
||||
cursor::MoveTo(0, n as u16),
|
||||
Print((n + 1).to_string())
|
||||
);
|
||||
execute!(
|
||||
stdout,
|
||||
SetForegroundColor(Color::Reset),
|
||||
cursor::MoveTo(2, n as u16),
|
||||
Print(line)
|
||||
|
||||
surface.set_string(2, n as u16, line, Style::default());
|
||||
// execute!(
|
||||
// stdout,
|
||||
// SetForegroundColor(Color::Reset),
|
||||
// cursor::MoveTo(2, n as u16),
|
||||
// Print(line)
|
||||
// );
|
||||
}
|
||||
|
||||
// iterate over selections and render them
|
||||
let select = Style::default().bg(tui::style::Color::LightBlue);
|
||||
let text = state.doc.slice(..);
|
||||
for range in state.selection.ranges() {
|
||||
// get terminal coords for x,y for each range pos
|
||||
// TODO: this won't work with multiline
|
||||
let (y1, x1) = coords_at_pos(&text, range.from());
|
||||
let (y2, x2) = coords_at_pos(&text, range.to());
|
||||
let area = Rect::new(
|
||||
(x1 + 2) as u16,
|
||||
y1 as u16,
|
||||
(x2 - x1 + 1) as u16,
|
||||
(y2 - y1 + 1) as u16,
|
||||
);
|
||||
surface.set_style(area, select);
|
||||
|
||||
// TODO: don't highlight next char in append mode
|
||||
}
|
||||
|
||||
let mode = match state.mode {
|
||||
@ -80,6 +117,13 @@ fn render(&mut self) {
|
||||
Print(mode)
|
||||
);
|
||||
|
||||
use tui::backend::Backend;
|
||||
// TODO: double buffer and diff here
|
||||
let empty = Surface::empty(area);
|
||||
self.terminal
|
||||
.backend_mut()
|
||||
.draw(empty.diff(&surface).into_iter());
|
||||
|
||||
// set cursor shape
|
||||
match state.mode {
|
||||
Mode::Insert => write!(stdout, "\x1B[6 q"),
|
||||
|
Loading…
Reference in New Issue
Block a user