on master help sign in
Refactor a little bit.
a106be9Blaž Hrastnik
Cargo.toml+4
@@ -4,3 +4,7 @@ members = [
4 "helix-term",
4 "helix-term",
5 "helix-syntax",
5 "helix-syntax",
6]
6]
7+
8+# Build helix-syntax in release mode to make the code path faster in development.
9+[profile.dev.package."helix-syntax"]
10+opt-level = 3
TODO.mdnew file+17
@@ -0,0 +1,17 @@
1+- Implement backspace/delete
2+- Implement marks
3+- Implement style configs, tab settings
4+- Visual tab width
5+- Refactor tree-sitter-highlight to work like the atom one, recomputing partial tree updates.
6+- Only render highlights on screen
7+- proper selection rendering
8+- Undo tree
9+- selection mode
10+- key sequence shortcuts (gg etc)
11+- syntax errors highlight query
12+
13+- UI work: command line
14+- UI work: tab popup on command line
15+- UI work: completion popup
16+- UI work: floating pane
17+
helix-core/src/lib.rs+1−1
@@ -1,7 +1,7 @@
1#![allow(unused)]
1#![allow(unused)]
2pub mod commands;
2pub mod commands;
3pub mod graphemes;
3pub mod graphemes;
4−pub mod language_mode;
4+pub mod syntax;
5mod selection;
5mod selection;
6pub mod state;
6pub mod state;
7mod transaction;
7mod transaction;
helix-core/src/language_mode.rs → helix-core/src/syntax.rsrenamed+32−11
@@ -65,6 +65,32 @@ impl LanguageLayer {
65// -- refactored from tree-sitter-highlight to be able to retain state
65// -- refactored from tree-sitter-highlight to be able to retain state
66// TODO: add seek() to iter
66// TODO: add seek() to iter
67
67
68+// problem: any time a layer is updated it must update it's injections on the parent (potentially
69+// removing some from use)
70+// can't modify to vec and exist in it at the same time since that would violate borrows
71+// maybe we can do with an arena
72+// maybe just caching on the top layer and nevermind the injections for now?
73+//
74+// Grammar {
75+// layers: Vec<Box<Layer>> to prevent memory moves when vec is modified
76+// }
77+// injections tracked by marker:
78+// if marker areas match it's fine and update
79+// if not found add new layer
80+// if length 0 then area got removed, clean up the layer
81+//
82+// layer update:
83+// if range.len = 0 then remove the layer
84+// for change in changes { tree.edit(change) }
85+// tree = parser.parse(.., tree, ..)
86+// calculate affected range and update injections
87+// injection update:
88+// look for existing injections
89+// if present, range = (first injection start, last injection end)
90+//
91+// For now cheat and just throw out non-root layers if they exist. This should still improve
92+// parsing in majority of cases.
93+
68use std::sync::atomic::{AtomicUsize, Ordering};
94use std::sync::atomic::{AtomicUsize, Ordering};
69use std::{iter, mem, ops, str, usize};
95use std::{iter, mem, ops, str, usize};
70use tree_sitter::{
96use tree_sitter::{
@@ -73,8 +99,6 @@ use tree_sitter::{
73};
99};
74
100
75const CANCELLATION_CHECK_INTERVAL: usize = 100;
101const CANCELLATION_CHECK_INTERVAL: usize = 100;
76−const BUFFER_HTML_RESERVE_CAPACITY: usize = 10 * 1024;
77−const BUFFER_LINES_RESERVE_CAPACITY: usize = 1000;
78
102
79/// Indicates which highlight should be applied to a region of source code.
103/// Indicates which highlight should be applied to a region of source code.
80#[derive(Copy, Clone, Debug, PartialEq, Eq)]
104#[derive(Copy, Clone, Debug, PartialEq, Eq)]
@@ -207,7 +231,7 @@ impl Highlighter {
207 cancellation_flag,
231 cancellation_flag,
208 highlighter: self,
232 highlighter: self,
209 iter_count: 0,
233 iter_count: 0,
210− layers: layers,
234+ layers,
211 next_event: None,
235 next_event: None,
212 last_highlight_range: None,
236 last_highlight_range: None,
213 };
237 };
@@ -405,7 +429,7 @@ impl<'a> HighlightIterLayer<'a> {
405 .parse(source, None)
429 .parse(source, None)
406 .ok_or(Error::Cancelled)?;
430 .ok_or(Error::Cancelled)?;
407 unsafe { highlighter.parser.set_cancellation_flag(None) };
431 unsafe { highlighter.parser.set_cancellation_flag(None) };
408− let mut cursor = highlighter.cursors.pop().unwrap_or(QueryCursor::new());
432+ let mut cursor = highlighter.cursors.pop().unwrap_or_else(QueryCursor::new);
409
433
410 // Process combined injections.
434 // Process combined injections.
411 if let Some(combined_injections_query) = &config.combined_injections_query {
435 if let Some(combined_injections_query) = &config.combined_injections_query {
@@ -642,7 +666,7 @@ where
642 break;
666 break;
643 }
667 }
644 if i > 0 {
668 if i > 0 {
645− &self.layers[0..(i + 1)].rotate_left(1);
669+ self.layers[0..(i + 1)].rotate_left(1);
646 }
670 }
647 break;
671 break;
648 } else {
672 } else {
@@ -802,12 +826,9 @@ where
802 local_defs: Vec::new(),
826 local_defs: Vec::new(),
803 };
827 };
804 for prop in layer.config.query.property_settings(match_.pattern_index) {
828 for prop in layer.config.query.property_settings(match_.pattern_index) {
805− match prop.key.as_ref() {
806− "local.scope-inherits" => {
829+ if let "local.scope-inherits" = prop.key.as_ref() {
807− scope.inherits =
830+ scope.inherits =
808− prop.value.as_ref().map_or(true, |r| r.as_ref() == "true");
831+ prop.value.as_ref().map_or(true, |r| r.as_ref() == "true");
809− }
810− _ => {}
811 }
832 }
812 }
833 }
813 layer.scope_stack.push(scope);
834 layer.scope_stack.push(scope);
helix-term/Cargo.toml−3
@@ -11,9 +11,6 @@ name = "hx"
11path = "src/main.rs"
11path = "src/main.rs"
12
12
13[dependencies]
13[dependencies]
14−# termwiz = { git = "https://github.com/wez/wezterm", features = ["widgets"] }
15−# termwiz = { path = "../../wezterm/termwiz", default-features = false, features = ["widgets"] }
16−
17helix-syntax = { path = "../helix-syntax" }
14helix-syntax = { path = "../helix-syntax" }
18
15
19anyhow = "1"
16anyhow = "1"
helix-term/src/editor.rs+5−36
@@ -1,6 +1,6 @@
1use crate::{keymap, theme::Theme, Args};
1use crate::{keymap, theme::Theme, Args};
2use helix_core::{
2use helix_core::{
3− language_mode::{HighlightConfiguration, HighlightEvent, Highlighter},
3+ syntax::{HighlightConfiguration, HighlightEvent, Highlighter},
4 state::coords_at_pos,
4 state::coords_at_pos,
5 state::Mode,
5 state::Mode,
6 State,
6 State,
@@ -40,7 +40,6 @@ pub struct Editor {
40 theme: Theme,
40 theme: Theme,
41 highlighter: Highlighter,
41 highlighter: Highlighter,
42 highlight_config: HighlightConfiguration,
42 highlight_config: HighlightConfiguration,
43− highlight_names: Vec<String>,
44}
43}
45
44
46impl Editor {
45impl Editor {
@@ -51,36 +50,7 @@ impl Editor {
51 let size = terminal::size().unwrap();
50 let size = terminal::size().unwrap();
52 let area = Rect::new(0, 0, size.0, size.1);
51 let area = Rect::new(0, 0, size.0, size.1);
53
52
54− let highlight_names: Vec<String> = [
53+ let theme = Theme::default();
55− "attribute",
56− "constant.builtin",
57− "constant",
58− "function.builtin",
59− "function.macro",
60− "function",
61− "keyword",
62− "operator",
63− "property",
64− "punctuation",
65− "comment",
66− "escape",
67− "label",
68− // "punctuation.bracket",
69− "punctuation.delimiter",
70− "string",
71− "string.special",
72− "tag",
73− "type",
74− "type.builtin",
75− "constructor",
76− "variable",
77− "variable.builtin",
78− "variable.parameter",
79− "path",
80− ]
81− .iter()
82− .map(|s| s.to_string())
83− .collect();
84
54
85 // let mut parser = tree_sitter::Parser::new();
55 // let mut parser = tree_sitter::Parser::new();
86 // parser.set_language(language).unwrap();
56 // parser.set_language(language).unwrap();
@@ -104,7 +74,7 @@ impl Editor {
104 )
74 )
105 .unwrap();
75 .unwrap();
106
76
107− highlight_config.configure(&highlight_names);
77+ highlight_config.configure(theme.scopes());
108
78
109 let mut editor = Editor {
79 let mut editor = Editor {
110 terminal,
80 terminal,
@@ -112,11 +82,10 @@ impl Editor {
112 first_line: 0,
82 first_line: 0,
113 size,
83 size,
114 surface: Surface::empty(area),
84 surface: Surface::empty(area),
115− theme: Theme::default(),
85+ theme,
116 // TODO; move to state
86 // TODO; move to state
117 highlighter,
87 highlighter,
118 highlight_config,
88 highlight_config,
119− highlight_names,
120 };
89 };
121
90
122 if let Some(file) = args.files.pop() {
91 if let Some(file) = args.files.pop() {
@@ -178,7 +147,7 @@ impl Editor {
178 use tui::style::Color;
147 use tui::style::Color;
179
148
180 let style = match spans.first() {
149 let style = match spans.first() {
181− Some(span) => self.theme.get(self.highlight_names[span.0].as_str()),
150+ Some(span) => self.theme.get(self.theme.scopes()[span.0].as_str()),
182 None => Style::default().fg(Color::Rgb(164, 160, 232)), // lavender
151 None => Style::default().fg(Color::Rgb(164, 160, 232)), // lavender
183 };
152 };
184
153
helix-term/src/theme.rs+36−1
@@ -3,9 +3,38 @@ use tui::style::{Color, Style};
3
3
4/// Color theme for syntax highlighting.
4/// Color theme for syntax highlighting.
5pub struct Theme {
5pub struct Theme {
6+ scopes: Vec<String>,
6 mapping: HashMap<&'static str, Style>,
7 mapping: HashMap<&'static str, Style>,
7}
8}
8
9
10+// let highlight_names: Vec<String> = [
11+// "attribute",
12+// "constant.builtin",
13+// "constant",
14+// "function.builtin",
15+// "function.macro",
16+// "function",
17+// "keyword",
18+// "operator",
19+// "property",
20+// "punctuation",
21+// "comment",
22+// "escape",
23+// "label",
24+// // "punctuation.bracket",
25+// "punctuation.delimiter",
26+// "string",
27+// "string.special",
28+// "tag",
29+// "type",
30+// "type.builtin",
31+// "constructor",
32+// "variable",
33+// "variable.builtin",
34+// "variable.parameter",
35+// "path",
36+// ];
37+
9impl Default for Theme {
38impl Default for Theme {
10 fn default() -> Self {
39 fn default() -> Self {
11 let mapping = hashmap! {
40 let mapping = hashmap! {
@@ -45,7 +74,9 @@ impl Default for Theme {
45 "function.builtin" => Style::default().fg(Color::Rgb(255, 0, 0)), // white
74 "function.builtin" => Style::default().fg(Color::Rgb(255, 0, 0)), // white
46 };
75 };
47
76
77+ let scopes = mapping.keys().map(ToString::to_string).collect();
78+
48− Self { mapping }
79+ Self { mapping, scopes }
49 }
80 }
50}
81}
51
82
@@ -56,4 +87,8 @@ impl Theme {
56 .copied()
87 .copied()
57 .unwrap_or_else(|| Style::default().fg(Color::Rgb(0, 0, 255)))
88 .unwrap_or_else(|| Style::default().fg(Color::Rgb(0, 0, 255)))
58 }
89 }
90+
91+ pub fn scopes(&self) -> &[String] {
92+ &self.scopes
93+ }
59}
94}
helix-term/test.txtdeleted−3
@@ -1,3 +0,0 @@
1−aaa
2−bbb
3−ccc