More work on the UI.

pull/1/head
Blaž Hrastnik 4 years ago
parent eb477ec442
commit 3859f6963d

123
Cargo.lock generated

@ -73,9 +73,9 @@ dependencies = [
[[package]] [[package]]
name = "async-executor" name = "async-executor"
version = "1.0.0" version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62f049075ec7a47ee59ed2e3013026e26e66b7430b1f2276c1e6ad9d5cfbff8f" checksum = "a831e74aa1937d3bbd3a356f34c23dbc6b6f0abc5160bd5484a9f75d5e76aea8"
dependencies = [ dependencies = [
"async-task", "async-task",
"concurrent-queue", "concurrent-queue",
@ -86,9 +86,9 @@ dependencies = [
[[package]] [[package]]
name = "async-fs" name = "async-fs"
version = "1.2.1" version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3361d088d288026af2cb21b9d9b8444bf0ba73bce56a4fc4b5742ba88f82ee74" checksum = "e3572236ba37147ca2b674a0bd5afd20aec0cd925ab125ab6fad6543960f9002"
dependencies = [ dependencies = [
"blocking", "blocking",
"futures-lite", "futures-lite",
@ -96,31 +96,27 @@ dependencies = [
[[package]] [[package]]
name = "async-io" name = "async-io"
version = "1.0.1" version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "016a7f0eda7091ef24ad8562d6503ad8da47af8c432d4d3fa440eea9e89055fe" checksum = "64c629684e697f58c0e99e5e2d84a840e3b336afbcfdbac7b44c3b1e222c2fd8"
dependencies = [ dependencies = [
"cfg-if",
"concurrent-queue", "concurrent-queue",
"fastrand", "fastrand",
"futures-lite", "futures-lite",
"libc",
"log", "log",
"nb-connect",
"once_cell", "once_cell",
"parking", "parking",
"polling", "polling",
"socket2",
"vec-arena", "vec-arena",
"waker-fn", "waker-fn",
"wepoll-sys-stjepang",
"winapi",
] ]
[[package]] [[package]]
name = "async-lock" name = "async-lock"
version = "2.1.2" version = "2.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b123db9bf64e4c4840d5b1985fdb4f69fbe50a4fc95e895d11ff49931ce9802" checksum = "ab3ad7fb4345397e57c19566844b0eba274b92e5d2d2791bb0664cc441697b95"
dependencies = [ dependencies = [
"async-barrier", "async-barrier",
"async-mutex", "async-mutex",
@ -139,9 +135,9 @@ dependencies = [
[[package]] [[package]]
name = "async-net" name = "async-net"
version = "1.2.0" version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f9c1d358c27ba114eab4330c50d21879ad0e6af192f01dba6fec1ab3b1e03d90" checksum = "a48af5438be856056bdeb6c5d895148a715be5915fccee49d1e5b50851dc9b8b"
dependencies = [ dependencies = [
"async-io", "async-io",
"blocking", "blocking",
@ -229,9 +225,9 @@ checksum = "df8670b8c7b9dae1793364eafadf7239c40d669904660c5960d74cfd80b46a53"
[[package]] [[package]]
name = "cc" name = "cc"
version = "1.0.59" version = "1.0.60"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "66120af515773fb005778dc07c261bd201ec8ce50bd6e7144c927753fe013381" checksum = "ef611cc68ff783f18535d77ddd080185275713d852c4f5cbb6122c462a7a825c"
dependencies = [ dependencies = [
"jobserver", "jobserver",
] ]
@ -262,13 +258,13 @@ dependencies = [
[[package]] [[package]]
name = "crossterm" name = "crossterm"
version = "0.17.8" version = "0.17.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "858085e389f71d31a6909f2b55a56b87d1cb8b168c0f513dcbed5e66a3e1039c" checksum = "6f4919d60f26ae233e14233cc39746c8c8bb8cd7b05840ace83604917b51b6c7"
dependencies = [ dependencies = [
"bitflags", "bitflags",
"crossterm_winapi", "crossterm_winapi",
"futures-core", "futures-util",
"lazy_static", "lazy_static",
"libc", "libc",
"mio", "mio",
@ -342,9 +338,9 @@ checksum = "de27142b013a8e869c14957e6d2edeef89e97c289e69d042ee3a49acd8b51789"
[[package]] [[package]]
name = "futures-lite" name = "futures-lite"
version = "1.3.0" version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4fc6854fcb40c6446abf6043e82604e42567dcf3d652a5ff4e997fc36876414c" checksum = "5b77e08e656f472d8ea84c472fa8b0a7a917883048e1cf2d4e34a323cd0aaf63"
dependencies = [ dependencies = [
"fastrand", "fastrand",
"futures-core", "futures-core",
@ -355,6 +351,24 @@ dependencies = [
"waker-fn", "waker-fn",
] ]
[[package]]
name = "futures-task"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bdb66b5f09e22019b1ab0830f7785bcea8e7a42148683f99214f73f8ec21a626"
[[package]]
name = "futures-util"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8764574ff08b701a084482c3c7031349104b07ac897393010494beaa18ce32c6"
dependencies = [
"futures-core",
"futures-task",
"pin-project",
"pin-utils",
]
[[package]] [[package]]
name = "heck" name = "heck"
version = "0.3.1" version = "0.3.1"
@ -370,6 +384,7 @@ version = "0.1.0"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"helix-syntax", "helix-syntax",
"once_cell",
"ropey", "ropey",
"smallvec", "smallvec",
"tendril", "tendril",
@ -427,9 +442,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.76" version = "0.2.77"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "755456fae044e6fa1ebbbd1b3e902ae19e73097ed4ed87bb79934a867c007bc3" checksum = "f2f96b10ec2560088a8e76961b00d47107b3a625fecb76dedb29ee7ccbf98235"
[[package]] [[package]]
name = "lock_api" name = "lock_api"
@ -485,6 +500,16 @@ dependencies = [
"winapi", "winapi",
] ]
[[package]]
name = "nb-connect"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e847c76b390f44529c2071ef06d0b52fbb4bdb04cc8987a5cfa63954c000abca"
dependencies = [
"libc",
"winapi",
]
[[package]] [[package]]
name = "new_debug_unreachable" name = "new_debug_unreachable"
version = "1.0.4" version = "1.0.4"
@ -546,17 +571,43 @@ dependencies = [
"winapi", "winapi",
] ]
[[package]]
name = "pin-project"
version = "0.4.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca4433fff2ae79342e497d9f8ee990d174071408f28f726d6d83af93e58e48aa"
dependencies = [
"pin-project-internal",
]
[[package]]
name = "pin-project-internal"
version = "0.4.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2c0e815c3ee9a031fdf5af21c10aa17c573c9c6a566328d99e3936c34e36461f"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]] [[package]]
name = "pin-project-lite" name = "pin-project-lite"
version = "0.1.7" version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "282adbf10f2698a7a77f8e983a74b2d18176c19a7fd32a45446139ae7b02b715" checksum = "282adbf10f2698a7a77f8e983a74b2d18176c19a7fd32a45446139ae7b02b715"
[[package]]
name = "pin-utils"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
[[package]] [[package]]
name = "polling" name = "polling"
version = "1.0.1" version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0835fa5f9af34c170eb38638ae6bc88e1b11ecdd0b968c9d9de8e343450385eb" checksum = "0307b8c7f438902536321f63c28cab0362f6ee89f1c7da47e3642ff956641c8b"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"libc", "libc",
@ -567,9 +618,9 @@ dependencies = [
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.20" version = "1.0.21"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "175c513d55719db99da20232b06cda8bab6b83ec2d04e3283edf0213c37c1a29" checksum = "36e28516df94f3dd551a587da5357459d9b36d945a7c37c3557928c1c2ff2a2c"
dependencies = [ dependencies = [
"unicode-xid", "unicode-xid",
] ]
@ -651,9 +702,9 @@ checksum = "fbee7696b84bbf3d89a1c2eccff0850e3047ed46bfcd2e92c29a2d074d57e252"
[[package]] [[package]]
name = "smol" name = "smol"
version = "1.0.0" version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ee895b9f862d88d6bad9d82f6ce727710d177338e697057a691ea684800d4a6" checksum = "712d02afa6ac9e7b8c777fd181aff476d009280b54b8c28703d10fa5d7e80d83"
dependencies = [ dependencies = [
"async-channel", "async-channel",
"async-executor", "async-executor",
@ -669,9 +720,9 @@ dependencies = [
[[package]] [[package]]
name = "socket2" name = "socket2"
version = "0.3.12" version = "0.3.15"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03088793f677dce356f3ccc2edb1b314ad191ab702a5de3faf49304f7e104918" checksum = "b1fa70dc5c8104ec096f4fe7ede7a221d35ae13dcd19ba1ad9a81d2cab9a1c44"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"libc", "libc",
@ -681,9 +732,9 @@ dependencies = [
[[package]] [[package]]
name = "syn" name = "syn"
version = "1.0.40" version = "1.0.41"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "963f7d3cc59b59b9325165add223142bbf1df27655d07789f109896d353d8350" checksum = "6690e3e9f692504b941dc6c3b188fd28df054f7fb8469ab40680df52fdcc842b"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -770,9 +821,9 @@ checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca"
[[package]] [[package]]
name = "wepoll-sys-stjepang" name = "wepoll-sys-stjepang"
version = "1.0.6" version = "1.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6fd319e971980166b53e17b1026812ad66c6b54063be879eb182342b55284694" checksum = "1fdfbb03f290ca0b27922e8d48a0997b4ceea12df33269b9f75e713311eb178d"
dependencies = [ dependencies = [
"cc", "cc",
] ]

@ -102,6 +102,11 @@ impl State {
self.mode self.mode
} }
#[inline]
pub fn path(&self) -> Option<&PathBuf> {
self.path.as_ref()
}
// pub fn doc<R>(&self, range: R) -> RopeSlice // pub fn doc<R>(&self, range: R) -> RopeSlice
// where // where
// R: std::ops::RangeBounds<usize>, // R: std::ops::RangeBounds<usize>,

@ -173,7 +173,7 @@ impl LanguageLayer {
self.tree.as_ref().unwrap() self.tree.as_ref().unwrap()
} }
fn parse<'a>( fn parse(
&mut self, &mut self,
parser: &mut Parser, parser: &mut Parser,
config: &HighlightConfiguration, config: &HighlightConfiguration,

@ -243,13 +243,13 @@ impl ChangeSet {
let old_end = old_pos + len; let old_end = old_pos + len;
match change { match change {
Retain(_len) => { Retain(_) => {
if old_end > pos { if old_end > pos {
return new_pos + (pos - old_pos); return new_pos + (pos - old_pos);
} }
new_pos += len; new_pos += len;
} }
Delete(_len) => { Delete(_) => {
// a subsequent ins means a replace, consume it // a subsequent ins means a replace, consume it
let ins = if let Some(Insert(s)) = iter.peek() { let ins = if let Some(Insert(s)) = iter.peek() {
iter.next(); iter.next();

@ -80,6 +80,8 @@ impl Editor {
} }
fn render(&mut self) { fn render(&mut self) {
use tui::backend::Backend;
use tui::style::Color;
// TODO: ideally not mut but highlights require it because of cursor cache // TODO: ideally not mut but highlights require it because of cursor cache
match &mut self.state { match &mut self.state {
Some(state) => { Some(state) => {
@ -87,9 +89,21 @@ impl Editor {
let mut stdout = stdout(); let mut stdout = stdout();
self.surface.reset(); // reset is faster than allocating new empty surface self.surface.reset(); // reset is faster than allocating new empty surface
// clear with background color
self.surface
.set_style(area, self.theme.get("ui.background"));
let offset = 5 + 1; // 5 linenr + 1 gutter
let viewport = Rect::new(offset, 0, self.size.0, self.size.1 - 1); // - 1 for statusline
// TODO: inefficient, should feed chunks.iter() to tree_sitter.parse_with(|offset, pos|) // TODO: inefficient, should feed chunks.iter() to tree_sitter.parse_with(|offset, pos|)
let source_code = state.doc().to_string(); let source_code = state.doc().to_string();
let last_line = std::cmp::min(
(self.first_line + viewport.height - 1) as usize,
state.doc().len_lines() - 1,
);
// TODO: cache highlight results // TODO: cache highlight results
// TODO: only recalculate when state.doc is actually modified // TODO: only recalculate when state.doc is actually modified
let highlights: Vec<_> = state let highlights: Vec<_> = state
@ -102,12 +116,10 @@ impl Editor {
let mut spans = Vec::new(); let mut spans = Vec::new();
let offset = 2;
let mut visual_x = 0; let mut visual_x = 0;
let mut line = 0; let mut line = 0u16;
for event in highlights { 'outer: for event in highlights {
match event.unwrap() { match event.unwrap() {
HighlightEvent::HighlightStart(span) => { HighlightEvent::HighlightStart(span) => {
spans.push(span); spans.push(span);
@ -125,8 +137,6 @@ impl Editor {
use helix_core::graphemes::{grapheme_width, RopeGraphemes}; use helix_core::graphemes::{grapheme_width, RopeGraphemes};
use tui::style::Color;
let style = match spans.first() { let style = match spans.first() {
Some(span) => self.theme.get(self.theme.scopes()[span.0].as_str()), Some(span) => self.theme.get(self.theme.scopes()[span.0].as_str()),
None => Style::default().fg(Color::Rgb(164, 160, 232)), // lavender None => Style::default().fg(Color::Rgb(164, 160, 232)), // lavender
@ -143,6 +153,11 @@ impl Editor {
if grapheme == "\n" { if grapheme == "\n" {
visual_x = 0; visual_x = 0;
line += 1; line += 1;
// TODO: with proper iter this shouldn't be necessary
if line >= viewport.height {
break 'outer;
}
} else { } else {
// Cow will prevent allocations if span contained in a single slice // Cow will prevent allocations if span contained in a single slice
// which should really be the majority case // which should really be the majority case
@ -163,7 +178,13 @@ impl Editor {
} }
} }
// let mut line = 0;
let style = self.theme.get("ui.linenr");
for i in self.first_line..(last_line as u16) {
self.surface
.set_stringn(0, line, format!("{:>5}", i + 1), 5, style); // lavender
line += 1;
}
// let lines = state // let lines = state
// .doc // .doc
@ -190,19 +211,23 @@ impl Editor {
// // TODO: don't highlight next char in append mode // // TODO: don't highlight next char in append mode
// } // }
// let mode = match state.mode { // statusline
// Mode::Insert => "INS", let mode = match state.mode() {
// Mode::Normal => "NOR", Mode::Insert => "INS",
// }; Mode::Normal => "NOR",
};
// execute!( self.surface.set_style(
// stdout, Rect::new(0, self.size.1 - 1, self.size.0, 1),
// SetForegroundColor(Color::Reset), self.theme.get("ui.statusline"),
// cursor::MoveTo(0, self.size.1), );
// Print(mode) // TODO: unfocused one with different color
// ); let text_color = Style::default().fg(Color::Rgb(219, 191, 239)); // lilac
self.surface
use tui::backend::Backend; .set_string(1, self.size.1 - 1, mode, text_color);
if let Some(path) = state.path() {
self.surface
.set_string(6, self.size.1 - 1, path.to_string_lossy(), text_color);
}
self.terminal self.terminal
.backend_mut() .backend_mut()
@ -221,7 +246,10 @@ impl Editor {
let coords = coords_at_pos(&state.doc().slice(..), pos); let coords = coords_at_pos(&state.doc().slice(..), pos);
execute!( execute!(
stdout, stdout,
cursor::MoveTo((coords.col + 2) as u16, coords.row as u16) cursor::MoveTo(
coords.col as u16 + viewport.x,
coords.row as u16 - self.first_line + viewport.y,
)
); );
} }
None => (), None => (),

@ -72,6 +72,10 @@ impl Default for Theme {
"module" => Style::default().fg(Color::Rgb(255, 0, 0)), // white "module" => Style::default().fg(Color::Rgb(255, 0, 0)), // white
"variable" => Style::default().fg(Color::Rgb(255, 0, 0)), // white "variable" => Style::default().fg(Color::Rgb(255, 0, 0)), // white
"function.builtin" => Style::default().fg(Color::Rgb(255, 0, 0)), // white "function.builtin" => Style::default().fg(Color::Rgb(255, 0, 0)), // white
"ui.background" => Style::default().bg(Color::Rgb(59, 34, 76)), // midnight
"ui.linenr" => Style::default().fg(Color::Rgb(90, 89, 119)), // comet
"ui.statusline" => Style::default().bg(Color::Rgb(40, 23, 51)), // revolver
}; };
let scopes = mapping.keys().map(ToString::to_string).collect(); let scopes = mapping.keys().map(ToString::to_string).collect();

Loading…
Cancel
Save