Refactor a little bit.

pull/1/head
Blaž Hrastnik 4 years ago
parent b17a77b8b8
commit a106be94f1

@ -4,3 +4,7 @@ members = [
"helix-term", "helix-term",
"helix-syntax", "helix-syntax",
] ]
# Build helix-syntax in release mode to make the code path faster in development.
[profile.dev.package."helix-syntax"]
opt-level = 3

@ -0,0 +1,17 @@
- Implement backspace/delete
- Implement marks
- Implement style configs, tab settings
- Visual tab width
- Refactor tree-sitter-highlight to work like the atom one, recomputing partial tree updates.
- Only render highlights on screen
- proper selection rendering
- Undo tree
- selection mode
- key sequence shortcuts (gg etc)
- syntax errors highlight query
- UI work: command line
- UI work: tab popup on command line
- UI work: completion popup
- UI work: floating pane

@ -1,7 +1,7 @@
#![allow(unused)] #![allow(unused)]
pub mod commands; pub mod commands;
pub mod graphemes; pub mod graphemes;
pub mod language_mode; pub mod syntax;
mod selection; mod selection;
pub mod state; pub mod state;
mod transaction; mod transaction;

@ -65,6 +65,32 @@ impl LanguageLayer {
// -- refactored from tree-sitter-highlight to be able to retain state // -- refactored from tree-sitter-highlight to be able to retain state
// TODO: add seek() to iter // TODO: add seek() to iter
// problem: any time a layer is updated it must update it's injections on the parent (potentially
// removing some from use)
// can't modify to vec and exist in it at the same time since that would violate borrows
// maybe we can do with an arena
// maybe just caching on the top layer and nevermind the injections for now?
//
// Grammar {
// layers: Vec<Box<Layer>> to prevent memory moves when vec is modified
// }
// injections tracked by marker:
// if marker areas match it's fine and update
// if not found add new layer
// if length 0 then area got removed, clean up the layer
//
// layer update:
// if range.len = 0 then remove the layer
// for change in changes { tree.edit(change) }
// tree = parser.parse(.., tree, ..)
// calculate affected range and update injections
// injection update:
// look for existing injections
// if present, range = (first injection start, last injection end)
//
// For now cheat and just throw out non-root layers if they exist. This should still improve
// parsing in majority of cases.
use std::sync::atomic::{AtomicUsize, Ordering}; use std::sync::atomic::{AtomicUsize, Ordering};
use std::{iter, mem, ops, str, usize}; use std::{iter, mem, ops, str, usize};
use tree_sitter::{ use tree_sitter::{
@ -73,8 +99,6 @@ use tree_sitter::{
}; };
const CANCELLATION_CHECK_INTERVAL: usize = 100; const CANCELLATION_CHECK_INTERVAL: usize = 100;
const BUFFER_HTML_RESERVE_CAPACITY: usize = 10 * 1024;
const BUFFER_LINES_RESERVE_CAPACITY: usize = 1000;
/// Indicates which highlight should be applied to a region of source code. /// Indicates which highlight should be applied to a region of source code.
#[derive(Copy, Clone, Debug, PartialEq, Eq)] #[derive(Copy, Clone, Debug, PartialEq, Eq)]
@ -207,7 +231,7 @@ impl Highlighter {
cancellation_flag, cancellation_flag,
highlighter: self, highlighter: self,
iter_count: 0, iter_count: 0,
layers: layers, layers,
next_event: None, next_event: None,
last_highlight_range: None, last_highlight_range: None,
}; };
@ -405,7 +429,7 @@ impl<'a> HighlightIterLayer<'a> {
.parse(source, None) .parse(source, None)
.ok_or(Error::Cancelled)?; .ok_or(Error::Cancelled)?;
unsafe { highlighter.parser.set_cancellation_flag(None) }; unsafe { highlighter.parser.set_cancellation_flag(None) };
let mut cursor = highlighter.cursors.pop().unwrap_or(QueryCursor::new()); let mut cursor = highlighter.cursors.pop().unwrap_or_else(QueryCursor::new);
// Process combined injections. // Process combined injections.
if let Some(combined_injections_query) = &config.combined_injections_query { if let Some(combined_injections_query) = &config.combined_injections_query {
@ -642,7 +666,7 @@ where
break; break;
} }
if i > 0 { if i > 0 {
&self.layers[0..(i + 1)].rotate_left(1); self.layers[0..(i + 1)].rotate_left(1);
} }
break; break;
} else { } else {
@ -802,12 +826,9 @@ where
local_defs: Vec::new(), local_defs: Vec::new(),
}; };
for prop in layer.config.query.property_settings(match_.pattern_index) { for prop in layer.config.query.property_settings(match_.pattern_index) {
match prop.key.as_ref() { if let "local.scope-inherits" = prop.key.as_ref() {
"local.scope-inherits" => { scope.inherits =
scope.inherits = prop.value.as_ref().map_or(true, |r| r.as_ref() == "true");
prop.value.as_ref().map_or(true, |r| r.as_ref() == "true");
}
_ => {}
} }
} }
layer.scope_stack.push(scope); layer.scope_stack.push(scope);

@ -11,9 +11,6 @@ name = "hx"
path = "src/main.rs" path = "src/main.rs"
[dependencies] [dependencies]
# termwiz = { git = "https://github.com/wez/wezterm", features = ["widgets"] }
# termwiz = { path = "../../wezterm/termwiz", default-features = false, features = ["widgets"] }
helix-syntax = { path = "../helix-syntax" } helix-syntax = { path = "../helix-syntax" }
anyhow = "1" anyhow = "1"

@ -1,6 +1,6 @@
use crate::{keymap, theme::Theme, Args}; use crate::{keymap, theme::Theme, Args};
use helix_core::{ use helix_core::{
language_mode::{HighlightConfiguration, HighlightEvent, Highlighter}, syntax::{HighlightConfiguration, HighlightEvent, Highlighter},
state::coords_at_pos, state::coords_at_pos,
state::Mode, state::Mode,
State, State,
@ -40,7 +40,6 @@ pub struct Editor {
theme: Theme, theme: Theme,
highlighter: Highlighter, highlighter: Highlighter,
highlight_config: HighlightConfiguration, highlight_config: HighlightConfiguration,
highlight_names: Vec<String>,
} }
impl Editor { impl Editor {
@ -51,36 +50,7 @@ impl Editor {
let size = terminal::size().unwrap(); let size = terminal::size().unwrap();
let area = Rect::new(0, 0, size.0, size.1); let area = Rect::new(0, 0, size.0, size.1);
let highlight_names: Vec<String> = [ let theme = Theme::default();
"attribute",
"constant.builtin",
"constant",
"function.builtin",
"function.macro",
"function",
"keyword",
"operator",
"property",
"punctuation",
"comment",
"escape",
"label",
// "punctuation.bracket",
"punctuation.delimiter",
"string",
"string.special",
"tag",
"type",
"type.builtin",
"constructor",
"variable",
"variable.builtin",
"variable.parameter",
"path",
]
.iter()
.map(|s| s.to_string())
.collect();
// let mut parser = tree_sitter::Parser::new(); // let mut parser = tree_sitter::Parser::new();
// parser.set_language(language).unwrap(); // parser.set_language(language).unwrap();
@ -104,7 +74,7 @@ impl Editor {
) )
.unwrap(); .unwrap();
highlight_config.configure(&highlight_names); highlight_config.configure(theme.scopes());
let mut editor = Editor { let mut editor = Editor {
terminal, terminal,
@ -112,11 +82,10 @@ impl Editor {
first_line: 0, first_line: 0,
size, size,
surface: Surface::empty(area), surface: Surface::empty(area),
theme: Theme::default(), theme,
// TODO; move to state // TODO; move to state
highlighter, highlighter,
highlight_config, highlight_config,
highlight_names,
}; };
if let Some(file) = args.files.pop() { if let Some(file) = args.files.pop() {
@ -178,7 +147,7 @@ impl Editor {
use tui::style::Color; use tui::style::Color;
let style = match spans.first() { let style = match spans.first() {
Some(span) => self.theme.get(self.highlight_names[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
}; };

@ -3,9 +3,38 @@ use tui::style::{Color, Style};
/// Color theme for syntax highlighting. /// Color theme for syntax highlighting.
pub struct Theme { pub struct Theme {
scopes: Vec<String>,
mapping: HashMap<&'static str, Style>, mapping: HashMap<&'static str, Style>,
} }
// let highlight_names: Vec<String> = [
// "attribute",
// "constant.builtin",
// "constant",
// "function.builtin",
// "function.macro",
// "function",
// "keyword",
// "operator",
// "property",
// "punctuation",
// "comment",
// "escape",
// "label",
// // "punctuation.bracket",
// "punctuation.delimiter",
// "string",
// "string.special",
// "tag",
// "type",
// "type.builtin",
// "constructor",
// "variable",
// "variable.builtin",
// "variable.parameter",
// "path",
// ];
impl Default for Theme { impl Default for Theme {
fn default() -> Self { fn default() -> Self {
let mapping = hashmap! { let mapping = hashmap! {
@ -45,7 +74,9 @@ impl Default for Theme {
"function.builtin" => Style::default().fg(Color::Rgb(255, 0, 0)), // white "function.builtin" => Style::default().fg(Color::Rgb(255, 0, 0)), // white
}; };
Self { mapping } let scopes = mapping.keys().map(ToString::to_string).collect();
Self { mapping, scopes }
} }
} }
@ -56,4 +87,8 @@ impl Theme {
.copied() .copied()
.unwrap_or_else(|| Style::default().fg(Color::Rgb(0, 0, 255))) .unwrap_or_else(|| Style::default().fg(Color::Rgb(0, 0, 255)))
} }
pub fn scopes(&self) -> &[String] {
&self.scopes
}
} }

@ -1,3 +0,0 @@
aaa
bbb
ccc
Loading…
Cancel
Save