diff options
author | Michael Davis | 2023-07-25 18:15:36 +0000 |
---|---|---|
committer | Blaž Hrastnik | 2023-07-27 02:50:19 +0000 |
commit | 98ef05d768d287fef2eb790e0a8a6e9a72832e00 (patch) | |
tree | 856fa79ea0924834f786a22a76ddfbe188301330 /helix-core | |
parent | f0b877e2588306882f71eaad45a3f3e604885a34 (diff) |
Prefer RopeSlice to &Rope in helix_core::syntax
Pascal and I discussed this and we think it's generally better to
take a 'RopeSlice' rather than a '&Rope'. The code block rendering
function in the markdown component module is a good example for how
this can be useful: we can remove an allocation of a rope and instead
directly turn a '&str' into a 'RopeSlice' which is very cheap.
A change to prefer 'RopeSlice' to '&Rope' whenever the rope isn't
modified would be nice, but it would be a very large diff (around 500+
500-). Starting off with just the syntax functions seems like a nice
middle-ground, and we can remove a Rope allocation because of it.
Co-authored-by: Pascal Kuthe <pascal.kuthe@semimod.de>
Diffstat (limited to 'helix-core')
-rw-r--r-- | helix-core/src/history.rs | 4 | ||||
-rw-r--r-- | helix-core/src/syntax.rs | 29 | ||||
-rw-r--r-- | helix-core/src/transaction.rs | 13 | ||||
-rw-r--r-- | helix-core/tests/indent.rs | 4 |
4 files changed, 27 insertions, 23 deletions
diff --git a/helix-core/src/history.rs b/helix-core/src/history.rs index 1aac38d9..28d6dd6e 100644 --- a/helix-core/src/history.rs +++ b/helix-core/src/history.rs @@ -72,8 +72,8 @@ impl Default for History { revisions: vec![Revision { parent: 0, last_child: None, - transaction: Transaction::from(ChangeSet::new(&Rope::new())), - inversion: Transaction::from(ChangeSet::new(&Rope::new())), + transaction: Transaction::from(ChangeSet::new("".into())), + inversion: Transaction::from(ChangeSet::new("".into())), timestamp: Instant::now(), }], current: 0, diff --git a/helix-core/src/syntax.rs b/helix-core/src/syntax.rs index 73d3f738..79fb52a7 100644 --- a/helix-core/src/syntax.rs +++ b/helix-core/src/syntax.rs @@ -4,7 +4,7 @@ use crate::{ diagnostic::Severity, regex::Regex, transaction::{ChangeSet, Operation}, - Rope, RopeSlice, Tendril, + RopeSlice, Tendril, }; use ahash::RandomState; @@ -818,7 +818,10 @@ impl Loader { // TODO: content_regex handling conflict resolution } - pub fn language_config_for_shebang(&self, source: &Rope) -> Option<Arc<LanguageConfiguration>> { + pub fn language_config_for_shebang( + &self, + source: RopeSlice, + ) -> Option<Arc<LanguageConfiguration>> { let line = Cow::from(source.line(0)); static SHEBANG_REGEX: Lazy<Regex> = Lazy::new(|| Regex::new(&["^", SHEBANG].concat()).unwrap()); @@ -928,7 +931,7 @@ fn byte_range_to_str(range: std::ops::Range<usize>, source: RopeSlice) -> Cow<st impl Syntax { pub fn new( - source: &Rope, + source: RopeSlice, config: Arc<HighlightConfiguration>, loader: Arc<Loader>, ) -> Option<Self> { @@ -967,8 +970,8 @@ impl Syntax { pub fn update( &mut self, - old_source: &Rope, - source: &Rope, + old_source: RopeSlice, + source: RopeSlice, changeset: &ChangeSet, ) -> Result<(), Error> { let mut queue = VecDeque::new(); @@ -1387,7 +1390,7 @@ impl LanguageLayer { self.tree.as_ref().unwrap() } - fn parse(&mut self, parser: &mut Parser, source: &Rope) -> Result<(), Error> { + fn parse(&mut self, parser: &mut Parser, source: RopeSlice) -> Result<(), Error> { parser .set_included_ranges(&self.ranges) .map_err(|_| Error::InvalidRanges)?; @@ -1418,7 +1421,7 @@ impl LanguageLayer { } pub(crate) fn generate_edits( - old_text: &Rope, + old_text: RopeSlice, changeset: &ChangeSet, ) -> Vec<tree_sitter::InputEdit> { use Operation::*; @@ -1434,7 +1437,7 @@ pub(crate) fn generate_edits( // TODO; this is a lot easier with Change instead of Operation. - fn point_at_pos(text: &Rope, pos: usize) -> (usize, Point) { + fn point_at_pos(text: RopeSlice, pos: usize) -> (usize, Point) { let byte = text.char_to_byte(pos); // <- attempted to index past end let line = text.char_to_line(pos); let line_start_byte = text.line_to_byte(line); @@ -2529,7 +2532,7 @@ mod test { let mut cursor = QueryCursor::new(); let config = HighlightConfiguration::new(language, "", "", "").unwrap(); - let syntax = Syntax::new(&source, Arc::new(config), Arc::new(loader)).unwrap(); + let syntax = Syntax::new(source.slice(..), Arc::new(config), Arc::new(loader)).unwrap(); let root = syntax.tree().root_node(); let mut test = |capture, range| { @@ -2603,7 +2606,7 @@ mod test { fn main() {} ", ); - let syntax = Syntax::new(&source, Arc::new(config), Arc::new(loader)).unwrap(); + let syntax = Syntax::new(source.slice(..), Arc::new(config), Arc::new(loader)).unwrap(); let tree = syntax.tree(); let root = tree.root_node(); assert_eq!(root.kind(), "source_file"); @@ -2630,7 +2633,7 @@ mod test { &doc, vec![(6, 11, Some("test".into())), (12, 17, None)].into_iter(), ); - let edits = generate_edits(&doc, transaction.changes()); + let edits = generate_edits(doc.slice(..), transaction.changes()); // transaction.apply(&mut state); assert_eq!( @@ -2659,7 +2662,7 @@ mod test { let mut doc = Rope::from("fn test() {}"); let transaction = Transaction::change(&doc, vec![(8, 8, Some("a: u32".into()))].into_iter()); - let edits = generate_edits(&doc, transaction.changes()); + let edits = generate_edits(doc.slice(..), transaction.changes()); transaction.apply(&mut doc); assert_eq!(doc, "fn test(a: u32) {}"); @@ -2693,7 +2696,7 @@ mod test { let language = get_language(language_name).unwrap(); let config = HighlightConfiguration::new(language, "", "", "").unwrap(); - let syntax = Syntax::new(&source, Arc::new(config), Arc::new(loader)).unwrap(); + let syntax = Syntax::new(source.slice(..), Arc::new(config), Arc::new(loader)).unwrap(); let root = syntax .tree() diff --git a/helix-core/src/transaction.rs b/helix-core/src/transaction.rs index 9d2a3e5c..fec62578 100644 --- a/helix-core/src/transaction.rs +++ b/helix-core/src/transaction.rs @@ -1,3 +1,4 @@ +use ropey::RopeSlice; use smallvec::SmallVec; use crate::{Range, Rope, Selection, Tendril}; @@ -42,7 +43,7 @@ impl ChangeSet { } #[must_use] - pub fn new(doc: &Rope) -> Self { + pub fn new(doc: RopeSlice) -> Self { let len = doc.len_chars(); Self { changes: Vec::new(), @@ -485,7 +486,7 @@ impl Transaction { /// Create a new, empty transaction. pub fn new(doc: &Rope) -> Self { Self { - changes: ChangeSet::new(doc), + changes: ChangeSet::new(doc.slice(..)), selection: None, } } @@ -946,9 +947,9 @@ mod test { #[test] fn combine_with_empty() { let empty = Rope::from(""); - let a = ChangeSet::new(&empty); + let a = ChangeSet::new(empty.slice(..)); - let mut b = ChangeSet::new(&empty); + let mut b = ChangeSet::new(empty.slice(..)); b.insert("a".into()); let changes = a.compose(b); @@ -962,9 +963,9 @@ mod test { const TEST_CASE: &str = "Hello, これはヘリックスエディターです!"; let empty = Rope::from(""); - let a = ChangeSet::new(&empty); + let a = ChangeSet::new(empty.slice(..)); - let mut b = ChangeSet::new(&empty); + let mut b = ChangeSet::new(empty.slice(..)); b.insert(TEST_CASE.into()); let changes = a.compose(b); diff --git a/helix-core/tests/indent.rs b/helix-core/tests/indent.rs index 409706bb..1dec9989 100644 --- a/helix-core/tests/indent.rs +++ b/helix-core/tests/indent.rs @@ -72,9 +72,9 @@ fn test_treesitter_indent(file_name: &str, lang_scope: &str) { let language_config = loader.language_config_for_scope(lang_scope).unwrap(); let highlight_config = language_config.highlight_config(&[]).unwrap(); - let syntax = Syntax::new(&doc, highlight_config, std::sync::Arc::new(loader)).unwrap(); - let indent_query = language_config.indent_query().unwrap(); let text = doc.slice(..); + let syntax = Syntax::new(text, highlight_config, std::sync::Arc::new(loader)).unwrap(); + let indent_query = language_config.indent_query().unwrap(); for i in 0..doc.len_lines() { let line = text.line(i); |