on master help sign in
More work on the UI.
3859f69Blaž Hrastnik
Cargo.lock+87−36
@@ -73,9 +73,9 @@ dependencies = [
73
73
74[[package]]
74[[package]]
75name = "async-executor"
75name = "async-executor"
76−version = "1.0.0"
76+version = "1.1.1"
77source = "registry+https://github.com/rust-lang/crates.io-index"
77source = "registry+https://github.com/rust-lang/crates.io-index"
78−checksum = "62f049075ec7a47ee59ed2e3013026e26e66b7430b1f2276c1e6ad9d5cfbff8f"
78+checksum = "a831e74aa1937d3bbd3a356f34c23dbc6b6f0abc5160bd5484a9f75d5e76aea8"
79dependencies = [
79dependencies = [
80 "async-task",
80 "async-task",
81 "concurrent-queue",
81 "concurrent-queue",
@@ -86,9 +86,9 @@ dependencies = [
86
86
87[[package]]
87[[package]]
88name = "async-fs"
88name = "async-fs"
89−version = "1.2.1"
89+version = "1.3.0"
90source = "registry+https://github.com/rust-lang/crates.io-index"
90source = "registry+https://github.com/rust-lang/crates.io-index"
91−checksum = "3361d088d288026af2cb21b9d9b8444bf0ba73bce56a4fc4b5742ba88f82ee74"
91+checksum = "e3572236ba37147ca2b674a0bd5afd20aec0cd925ab125ab6fad6543960f9002"
92dependencies = [
92dependencies = [
93 "blocking",
93 "blocking",
94 "futures-lite",
94 "futures-lite",
@@ -96,31 +96,27 @@ dependencies = [
96
96
97[[package]]
97[[package]]
98name = "async-io"
98name = "async-io"
99−version = "1.0.1"
99+version = "1.1.2"
100source = "registry+https://github.com/rust-lang/crates.io-index"
100source = "registry+https://github.com/rust-lang/crates.io-index"
101−checksum = "016a7f0eda7091ef24ad8562d6503ad8da47af8c432d4d3fa440eea9e89055fe"
101+checksum = "64c629684e697f58c0e99e5e2d84a840e3b336afbcfdbac7b44c3b1e222c2fd8"
102dependencies = [
102dependencies = [
103− "cfg-if",
104 "concurrent-queue",
103 "concurrent-queue",
105 "fastrand",
104 "fastrand",
106 "futures-lite",
105 "futures-lite",
107− "libc",
108 "log",
106 "log",
107+ "nb-connect",
109 "once_cell",
108 "once_cell",
110 "parking",
109 "parking",
111 "polling",
110 "polling",
112− "socket2",
113 "vec-arena",
111 "vec-arena",
114 "waker-fn",
112 "waker-fn",
115− "wepoll-sys-stjepang",
116− "winapi",
117]
113]
118
114
119[[package]]
115[[package]]
120name = "async-lock"
116name = "async-lock"
121−version = "2.1.2"
117+version = "2.1.3"
122source = "registry+https://github.com/rust-lang/crates.io-index"
118source = "registry+https://github.com/rust-lang/crates.io-index"
123−checksum = "2b123db9bf64e4c4840d5b1985fdb4f69fbe50a4fc95e895d11ff49931ce9802"
119+checksum = "ab3ad7fb4345397e57c19566844b0eba274b92e5d2d2791bb0664cc441697b95"
124dependencies = [
120dependencies = [
125 "async-barrier",
121 "async-barrier",
126 "async-mutex",
122 "async-mutex",
@@ -139,9 +135,9 @@ dependencies = [
139
135
140[[package]]
136[[package]]
141name = "async-net"
137name = "async-net"
142−version = "1.2.0"
138+version = "1.3.0"
143source = "registry+https://github.com/rust-lang/crates.io-index"
139source = "registry+https://github.com/rust-lang/crates.io-index"
144−checksum = "f9c1d358c27ba114eab4330c50d21879ad0e6af192f01dba6fec1ab3b1e03d90"
140+checksum = "a48af5438be856056bdeb6c5d895148a715be5915fccee49d1e5b50851dc9b8b"
145dependencies = [
141dependencies = [
146 "async-io",
142 "async-io",
147 "blocking",
143 "blocking",
@@ -229,9 +225,9 @@ checksum = "df8670b8c7b9dae1793364eafadf7239c40d669904660c5960d74cfd80b46a53"
229
225
230[[package]]
226[[package]]
231name = "cc"
227name = "cc"
232−version = "1.0.59"
228+version = "1.0.60"
233source = "registry+https://github.com/rust-lang/crates.io-index"
229source = "registry+https://github.com/rust-lang/crates.io-index"
234−checksum = "66120af515773fb005778dc07c261bd201ec8ce50bd6e7144c927753fe013381"
230+checksum = "ef611cc68ff783f18535d77ddd080185275713d852c4f5cbb6122c462a7a825c"
235dependencies = [
231dependencies = [
236 "jobserver",
232 "jobserver",
237]
233]
@@ -262,13 +258,13 @@ dependencies = [
262
258
263[[package]]
259[[package]]
264name = "crossterm"
260name = "crossterm"
265−version = "0.17.8"
261+version = "0.17.7"
266source = "registry+https://github.com/rust-lang/crates.io-index"
262source = "registry+https://github.com/rust-lang/crates.io-index"
267−checksum = "858085e389f71d31a6909f2b55a56b87d1cb8b168c0f513dcbed5e66a3e1039c"
263+checksum = "6f4919d60f26ae233e14233cc39746c8c8bb8cd7b05840ace83604917b51b6c7"
268dependencies = [
264dependencies = [
269 "bitflags",
265 "bitflags",
270 "crossterm_winapi",
266 "crossterm_winapi",
271− "futures-core",
267+ "futures-util",
272 "lazy_static",
268 "lazy_static",
273 "libc",
269 "libc",
274 "mio",
270 "mio",
@@ -342,9 +338,9 @@ checksum = "de27142b013a8e869c14957e6d2edeef89e97c289e69d042ee3a49acd8b51789"
342
338
343[[package]]
339[[package]]
344name = "futures-lite"
340name = "futures-lite"
345−version = "1.3.0"
341+version = "1.7.0"
346source = "registry+https://github.com/rust-lang/crates.io-index"
342source = "registry+https://github.com/rust-lang/crates.io-index"
347−checksum = "4fc6854fcb40c6446abf6043e82604e42567dcf3d652a5ff4e997fc36876414c"
343+checksum = "5b77e08e656f472d8ea84c472fa8b0a7a917883048e1cf2d4e34a323cd0aaf63"
348dependencies = [
344dependencies = [
349 "fastrand",
345 "fastrand",
350 "futures-core",
346 "futures-core",
@@ -355,6 +351,24 @@ dependencies = [
355 "waker-fn",
351 "waker-fn",
356]
352]
357
353
354+[[package]]
355+name = "futures-task"
356+version = "0.3.5"
357+source = "registry+https://github.com/rust-lang/crates.io-index"
358+checksum = "bdb66b5f09e22019b1ab0830f7785bcea8e7a42148683f99214f73f8ec21a626"
359+
360+[[package]]
361+name = "futures-util"
362+version = "0.3.5"
363+source = "registry+https://github.com/rust-lang/crates.io-index"
364+checksum = "8764574ff08b701a084482c3c7031349104b07ac897393010494beaa18ce32c6"
365+dependencies = [
366+ "futures-core",
367+ "futures-task",
368+ "pin-project",
369+ "pin-utils",
370+]
371+
358[[package]]
372[[package]]
359name = "heck"
373name = "heck"
360version = "0.3.1"
374version = "0.3.1"
@@ -370,6 +384,7 @@ version = "0.1.0"
370dependencies = [
384dependencies = [
371 "anyhow",
385 "anyhow",
372 "helix-syntax",
386 "helix-syntax",
387+ "once_cell",
373 "ropey",
388 "ropey",
374 "smallvec",
389 "smallvec",
375 "tendril",
390 "tendril",
@@ -427,9 +442,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
427
442
428[[package]]
443[[package]]
429name = "libc"
444name = "libc"
430−version = "0.2.76"
445+version = "0.2.77"
431source = "registry+https://github.com/rust-lang/crates.io-index"
446source = "registry+https://github.com/rust-lang/crates.io-index"
432−checksum = "755456fae044e6fa1ebbbd1b3e902ae19e73097ed4ed87bb79934a867c007bc3"
447+checksum = "f2f96b10ec2560088a8e76961b00d47107b3a625fecb76dedb29ee7ccbf98235"
433
448
434[[package]]
449[[package]]
435name = "lock_api"
450name = "lock_api"
@@ -485,6 +500,16 @@ dependencies = [
485 "winapi",
500 "winapi",
486]
501]
487
502
503+[[package]]
504+name = "nb-connect"
505+version = "1.0.0"
506+source = "registry+https://github.com/rust-lang/crates.io-index"
507+checksum = "e847c76b390f44529c2071ef06d0b52fbb4bdb04cc8987a5cfa63954c000abca"
508+dependencies = [
509+ "libc",
510+ "winapi",
511+]
512+
488[[package]]
513[[package]]
489name = "new_debug_unreachable"
514name = "new_debug_unreachable"
490version = "1.0.4"
515version = "1.0.4"
@@ -546,17 +571,43 @@ dependencies = [
546 "winapi",
571 "winapi",
547]
572]
548
573
574+[[package]]
575+name = "pin-project"
576+version = "0.4.23"
577+source = "registry+https://github.com/rust-lang/crates.io-index"
578+checksum = "ca4433fff2ae79342e497d9f8ee990d174071408f28f726d6d83af93e58e48aa"
579+dependencies = [
580+ "pin-project-internal",
581+]
582+
583+[[package]]
584+name = "pin-project-internal"
585+version = "0.4.23"
586+source = "registry+https://github.com/rust-lang/crates.io-index"
587+checksum = "2c0e815c3ee9a031fdf5af21c10aa17c573c9c6a566328d99e3936c34e36461f"
588+dependencies = [
589+ "proc-macro2",
590+ "quote",
591+ "syn",
592+]
593+
549[[package]]
594[[package]]
550name = "pin-project-lite"
595name = "pin-project-lite"
551version = "0.1.7"
596version = "0.1.7"
552source = "registry+https://github.com/rust-lang/crates.io-index"
597source = "registry+https://github.com/rust-lang/crates.io-index"
553checksum = "282adbf10f2698a7a77f8e983a74b2d18176c19a7fd32a45446139ae7b02b715"
598checksum = "282adbf10f2698a7a77f8e983a74b2d18176c19a7fd32a45446139ae7b02b715"
554
599
600+[[package]]
601+name = "pin-utils"
602+version = "0.1.0"
603+source = "registry+https://github.com/rust-lang/crates.io-index"
604+checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
605+
555[[package]]
606[[package]]
556name = "polling"
607name = "polling"
557−version = "1.0.1"
608+version = "1.0.3"
558source = "registry+https://github.com/rust-lang/crates.io-index"
609source = "registry+https://github.com/rust-lang/crates.io-index"
559−checksum = "0835fa5f9af34c170eb38638ae6bc88e1b11ecdd0b968c9d9de8e343450385eb"
610+checksum = "0307b8c7f438902536321f63c28cab0362f6ee89f1c7da47e3642ff956641c8b"
560dependencies = [
611dependencies = [
561 "cfg-if",
612 "cfg-if",
562 "libc",
613 "libc",
@@ -567,9 +618,9 @@ dependencies = [
567
618
568[[package]]
619[[package]]
569name = "proc-macro2"
620name = "proc-macro2"
570−version = "1.0.20"
621+version = "1.0.21"
571source = "registry+https://github.com/rust-lang/crates.io-index"
622source = "registry+https://github.com/rust-lang/crates.io-index"
572−checksum = "175c513d55719db99da20232b06cda8bab6b83ec2d04e3283edf0213c37c1a29"
623+checksum = "36e28516df94f3dd551a587da5357459d9b36d945a7c37c3557928c1c2ff2a2c"
573dependencies = [
624dependencies = [
574 "unicode-xid",
625 "unicode-xid",
575]
626]
@@ -651,9 +702,9 @@ checksum = "fbee7696b84bbf3d89a1c2eccff0850e3047ed46bfcd2e92c29a2d074d57e252"
651
702
652[[package]]
703[[package]]
653name = "smol"
704name = "smol"
654−version = "1.0.0"
705+version = "1.0.1"
655source = "registry+https://github.com/rust-lang/crates.io-index"
706source = "registry+https://github.com/rust-lang/crates.io-index"
656−checksum = "1ee895b9f862d88d6bad9d82f6ce727710d177338e697057a691ea684800d4a6"
707+checksum = "712d02afa6ac9e7b8c777fd181aff476d009280b54b8c28703d10fa5d7e80d83"
657dependencies = [
708dependencies = [
658 "async-channel",
709 "async-channel",
659 "async-executor",
710 "async-executor",
@@ -669,9 +720,9 @@ dependencies = [
669
720
670[[package]]
721[[package]]
671name = "socket2"
722name = "socket2"
672−version = "0.3.12"
723+version = "0.3.15"
673source = "registry+https://github.com/rust-lang/crates.io-index"
724source = "registry+https://github.com/rust-lang/crates.io-index"
674−checksum = "03088793f677dce356f3ccc2edb1b314ad191ab702a5de3faf49304f7e104918"
725+checksum = "b1fa70dc5c8104ec096f4fe7ede7a221d35ae13dcd19ba1ad9a81d2cab9a1c44"
675dependencies = [
726dependencies = [
676 "cfg-if",
727 "cfg-if",
677 "libc",
728 "libc",
@@ -681,9 +732,9 @@ dependencies = [
681
732
682[[package]]
733[[package]]
683name = "syn"
734name = "syn"
684−version = "1.0.40"
735+version = "1.0.41"
685source = "registry+https://github.com/rust-lang/crates.io-index"
736source = "registry+https://github.com/rust-lang/crates.io-index"
686−checksum = "963f7d3cc59b59b9325165add223142bbf1df27655d07789f109896d353d8350"
737+checksum = "6690e3e9f692504b941dc6c3b188fd28df054f7fb8469ab40680df52fdcc842b"
687dependencies = [
738dependencies = [
688 "proc-macro2",
739 "proc-macro2",
689 "quote",
740 "quote",
@@ -770,9 +821,9 @@ checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca"
770
821
771[[package]]
822[[package]]
772name = "wepoll-sys-stjepang"
823name = "wepoll-sys-stjepang"
773−version = "1.0.6"
824+version = "1.0.8"
774source = "registry+https://github.com/rust-lang/crates.io-index"
825source = "registry+https://github.com/rust-lang/crates.io-index"
775−checksum = "6fd319e971980166b53e17b1026812ad66c6b54063be879eb182342b55284694"
826+checksum = "1fdfbb03f290ca0b27922e8d48a0997b4ceea12df33269b9f75e713311eb178d"
776dependencies = [
827dependencies = [
777 "cc",
828 "cc",
778]
829]
helix-core/src/state.rs+5
@@ -102,6 +102,11 @@ impl State {
102 self.mode
102 self.mode
103 }
103 }
104
104
105+ #[inline]
106+ pub fn path(&self) -> Option<&PathBuf> {
107+ self.path.as_ref()
108+ }
109+
105 // pub fn doc<R>(&self, range: R) -> RopeSlice
110 // pub fn doc<R>(&self, range: R) -> RopeSlice
106 // where
111 // where
107 // R: std::ops::RangeBounds<usize>,
112 // R: std::ops::RangeBounds<usize>,
helix-core/src/syntax.rs+1−1
@@ -173,7 +173,7 @@ impl LanguageLayer {
173 self.tree.as_ref().unwrap()
173 self.tree.as_ref().unwrap()
174 }
174 }
175
175
176− fn parse<'a>(
176+ fn parse(
177 &mut self,
177 &mut self,
178 parser: &mut Parser,
178 parser: &mut Parser,
179 config: &HighlightConfiguration,
179 config: &HighlightConfiguration,
helix-core/src/transaction.rs+2−2
@@ -243,13 +243,13 @@ impl ChangeSet {
243 let old_end = old_pos + len;
243 let old_end = old_pos + len;
244
244
245 match change {
245 match change {
246− Retain(_len) => {
246+ Retain(_) => {
247 if old_end > pos {
247 if old_end > pos {
248 return new_pos + (pos - old_pos);
248 return new_pos + (pos - old_pos);
249 }
249 }
250 new_pos += len;
250 new_pos += len;
251 }
251 }
252− Delete(_len) => {
252+ Delete(_) => {
253 // a subsequent ins means a replace, consume it
253 // a subsequent ins means a replace, consume it
254 let ins = if let Some(Insert(s)) = iter.peek() {
254 let ins = if let Some(Insert(s)) = iter.peek() {
255 iter.next();
255 iter.next();
helix-term/src/editor.rs+49−21
@@ -80,6 +80,8 @@ impl Editor {
80 }
80 }
81
81
82 fn render(&mut self) {
82 fn render(&mut self) {
83+ use tui::backend::Backend;
84+ use tui::style::Color;
83 // TODO: ideally not mut but highlights require it because of cursor cache
85 // TODO: ideally not mut but highlights require it because of cursor cache
84 match &mut self.state {
86 match &mut self.state {
85 Some(state) => {
87 Some(state) => {
@@ -87,9 +89,21 @@ impl Editor {
87 let mut stdout = stdout();
89 let mut stdout = stdout();
88 self.surface.reset(); // reset is faster than allocating new empty surface
90 self.surface.reset(); // reset is faster than allocating new empty surface
89
91
92+ // clear with background color
93+ self.surface
94+ .set_style(area, self.theme.get("ui.background"));
95+
96+ let offset = 5 + 1; // 5 linenr + 1 gutter
97+ let viewport = Rect::new(offset, 0, self.size.0, self.size.1 - 1); // - 1 for statusline
98+
90 // TODO: inefficient, should feed chunks.iter() to tree_sitter.parse_with(|offset, pos|)
99 // TODO: inefficient, should feed chunks.iter() to tree_sitter.parse_with(|offset, pos|)
91 let source_code = state.doc().to_string();
100 let source_code = state.doc().to_string();
92
101
102+ let last_line = std::cmp::min(
103+ (self.first_line + viewport.height - 1) as usize,
104+ state.doc().len_lines() - 1,
105+ );
106+
93 // TODO: cache highlight results
107 // TODO: cache highlight results
94 // TODO: only recalculate when state.doc is actually modified
108 // TODO: only recalculate when state.doc is actually modified
95 let highlights: Vec<_> = state
109 let highlights: Vec<_> = state
@@ -102,12 +116,10 @@ impl Editor {
102
116
103 let mut spans = Vec::new();
117 let mut spans = Vec::new();
104
118
105− let offset = 2;
106−
107 let mut visual_x = 0;
119 let mut visual_x = 0;
108− let mut line = 0;
120+ let mut line = 0u16;
109
121
110− for event in highlights {
122+ 'outer: for event in highlights {
111 match event.unwrap() {
123 match event.unwrap() {
112 HighlightEvent::HighlightStart(span) => {
124 HighlightEvent::HighlightStart(span) => {
113 spans.push(span);
125 spans.push(span);
@@ -125,8 +137,6 @@ impl Editor {
125
137
126 use helix_core::graphemes::{grapheme_width, RopeGraphemes};
138 use helix_core::graphemes::{grapheme_width, RopeGraphemes};
127
139
128− use tui::style::Color;
129−
130 let style = match spans.first() {
140 let style = match spans.first() {
131 Some(span) => self.theme.get(self.theme.scopes()[span.0].as_str()),
141 Some(span) => self.theme.get(self.theme.scopes()[span.0].as_str()),
132 None => Style::default().fg(Color::Rgb(164, 160, 232)), // lavender
142 None => Style::default().fg(Color::Rgb(164, 160, 232)), // lavender
@@ -143,6 +153,11 @@ impl Editor {
143 if grapheme == "\n" {
153 if grapheme == "\n" {
144 visual_x = 0;
154 visual_x = 0;
145 line += 1;
155 line += 1;
156+
157+ // TODO: with proper iter this shouldn't be necessary
158+ if line >= viewport.height {
159+ break 'outer;
160+ }
146 } else {
161 } else {
147 // Cow will prevent allocations if span contained in a single slice
162 // Cow will prevent allocations if span contained in a single slice
148 // which should really be the majority case
163 // which should really be the majority case
@@ -163,7 +178,13 @@ impl Editor {
163 }
178 }
164 }
179 }
165
180
166− //
181+ let mut line = 0;
182+ let style = self.theme.get("ui.linenr");
183+ for i in self.first_line..(last_line as u16) {
184+ self.surface
185+ .set_stringn(0, line, format!("{:>5}", i + 1), 5, style); // lavender
186+ line += 1;
187+ }
167
188
168 // let lines = state
189 // let lines = state
169 // .doc
190 // .doc
@@ -190,19 +211,23 @@ impl Editor {
190 // // TODO: don't highlight next char in append mode
211 // // TODO: don't highlight next char in append mode
191 // }
212 // }
192
213
214+ // statusline
193− // let mode = match state.mode {
215+ let mode = match state.mode() {
194− // Mode::Insert => "INS",
216+ Mode::Insert => "INS",
195− // Mode::Normal => "NOR",
217+ Mode::Normal => "NOR",
196− // };
218+ };
197−
219+ self.surface.set_style(
198− // execute!(
220+ Rect::new(0, self.size.1 - 1, self.size.0, 1),
199− // stdout,
221+ self.theme.get("ui.statusline"),
200− // SetForegroundColor(Color::Reset),
222+ );
201− // cursor::MoveTo(0, self.size.1),
223+ // TODO: unfocused one with different color
202− // Print(mode)
224+ let text_color = Style::default().fg(Color::Rgb(219, 191, 239)); // lilac
203− // );
225+ self.surface
204−
226+ .set_string(1, self.size.1 - 1, mode, text_color);
205− use tui::backend::Backend;
227+ if let Some(path) = state.path() {
228+ self.surface
229+ .set_string(6, self.size.1 - 1, path.to_string_lossy(), text_color);
230+ }
206
231
207 self.terminal
232 self.terminal
208 .backend_mut()
233 .backend_mut()
@@ -221,7 +246,10 @@ impl Editor {
221 let coords = coords_at_pos(&state.doc().slice(..), pos);
246 let coords = coords_at_pos(&state.doc().slice(..), pos);
222 execute!(
247 execute!(
223 stdout,
248 stdout,
224− cursor::MoveTo((coords.col + 2) as u16, coords.row as u16)
249+ cursor::MoveTo(
250+ coords.col as u16 + viewport.x,
251+ coords.row as u16 - self.first_line + viewport.y,
252+ )
225 );
253 );
226 }
254 }
227 None => (),
255 None => (),
helix-term/src/theme.rs+4
@@ -72,6 +72,10 @@ impl Default for Theme {
72 "module" => Style::default().fg(Color::Rgb(255, 0, 0)), // white
72 "module" => Style::default().fg(Color::Rgb(255, 0, 0)), // white
73 "variable" => Style::default().fg(Color::Rgb(255, 0, 0)), // white
73 "variable" => Style::default().fg(Color::Rgb(255, 0, 0)), // white
74 "function.builtin" => Style::default().fg(Color::Rgb(255, 0, 0)), // white
74 "function.builtin" => Style::default().fg(Color::Rgb(255, 0, 0)), // white
75+
76+ "ui.background" => Style::default().bg(Color::Rgb(59, 34, 76)), // midnight
77+ "ui.linenr" => Style::default().fg(Color::Rgb(90, 89, 119)), // comet
78+ "ui.statusline" => Style::default().bg(Color::Rgb(40, 23, 51)), // revolver
75 };
79 };
76
80
77 let scopes = mapping.keys().map(ToString::to_string).collect();
81 let scopes = mapping.keys().map(ToString::to_string).collect();