on master help sign in
Prefer RopeSlice to &Rope in helix_core::syntax
98ef05dMichael Davis
helix-core/src/history.rs+2−2
@@ -72,8 +72,8 @@ impl Default for History {
72 revisions: vec![Revision {
72 revisions: vec![Revision {
73 parent: 0,
73 parent: 0,
74 last_child: None,
74 last_child: None,
75− transaction: Transaction::from(ChangeSet::new(&Rope::new())),
75+ transaction: Transaction::from(ChangeSet::new("".into())),
76− inversion: Transaction::from(ChangeSet::new(&Rope::new())),
76+ inversion: Transaction::from(ChangeSet::new("".into())),
77 timestamp: Instant::now(),
77 timestamp: Instant::now(),
78 }],
78 }],
79 current: 0,
79 current: 0,
helix-core/src/syntax.rs+16−13
@@ -4,7 +4,7 @@ use crate::{
4 diagnostic::Severity,
4 diagnostic::Severity,
5 regex::Regex,
5 regex::Regex,
6 transaction::{ChangeSet, Operation},
6 transaction::{ChangeSet, Operation},
7− Rope, RopeSlice, Tendril,
7+ RopeSlice, Tendril,
8};
8};
9
9
10use ahash::RandomState;
10use ahash::RandomState;
@@ -818,7 +818,10 @@ impl Loader {
818 // TODO: content_regex handling conflict resolution
818 // TODO: content_regex handling conflict resolution
819 }
819 }
820
820
821− pub fn language_config_for_shebang(&self, source: &Rope) -> Option<Arc<LanguageConfiguration>> {
821+ pub fn language_config_for_shebang(
822+ &self,
823+ source: RopeSlice,
824+ ) -> Option<Arc<LanguageConfiguration>> {
822 let line = Cow::from(source.line(0));
825 let line = Cow::from(source.line(0));
823 static SHEBANG_REGEX: Lazy<Regex> =
826 static SHEBANG_REGEX: Lazy<Regex> =
824 Lazy::new(|| Regex::new(&["^", SHEBANG].concat()).unwrap());
827 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
928
931
929impl Syntax {
932impl Syntax {
930 pub fn new(
933 pub fn new(
931− source: &Rope,
934+ source: RopeSlice,
932 config: Arc<HighlightConfiguration>,
935 config: Arc<HighlightConfiguration>,
933 loader: Arc<Loader>,
936 loader: Arc<Loader>,
934 ) -> Option<Self> {
937 ) -> Option<Self> {
@@ -967,8 +970,8 @@ impl Syntax {
967
970
968 pub fn update(
971 pub fn update(
969 &mut self,
972 &mut self,
970− old_source: &Rope,
973+ old_source: RopeSlice,
971− source: &Rope,
974+ source: RopeSlice,
972 changeset: &ChangeSet,
975 changeset: &ChangeSet,
973 ) -> Result<(), Error> {
976 ) -> Result<(), Error> {
974 let mut queue = VecDeque::new();
977 let mut queue = VecDeque::new();
@@ -1387,7 +1390,7 @@ impl LanguageLayer {
1387 self.tree.as_ref().unwrap()
1390 self.tree.as_ref().unwrap()
1388 }
1391 }
1389
1392
1390− fn parse(&mut self, parser: &mut Parser, source: &Rope) -> Result<(), Error> {
1393+ fn parse(&mut self, parser: &mut Parser, source: RopeSlice) -> Result<(), Error> {
1391 parser
1394 parser
1392 .set_included_ranges(&self.ranges)
1395 .set_included_ranges(&self.ranges)
1393 .map_err(|_| Error::InvalidRanges)?;
1396 .map_err(|_| Error::InvalidRanges)?;
@@ -1418,7 +1421,7 @@ impl LanguageLayer {
1418}
1421}
1419
1422
1420pub(crate) fn generate_edits(
1423pub(crate) fn generate_edits(
1421− old_text: &Rope,
1424+ old_text: RopeSlice,
1422 changeset: &ChangeSet,
1425 changeset: &ChangeSet,
1423) -> Vec<tree_sitter::InputEdit> {
1426) -> Vec<tree_sitter::InputEdit> {
1424 use Operation::*;
1427 use Operation::*;
@@ -1434,7 +1437,7 @@ pub(crate) fn generate_edits(
1434
1437
1435 // TODO; this is a lot easier with Change instead of Operation.
1438 // TODO; this is a lot easier with Change instead of Operation.
1436
1439
1437− fn point_at_pos(text: &Rope, pos: usize) -> (usize, Point) {
1440+ fn point_at_pos(text: RopeSlice, pos: usize) -> (usize, Point) {
1438 let byte = text.char_to_byte(pos); // <- attempted to index past end
1441 let byte = text.char_to_byte(pos); // <- attempted to index past end
1439 let line = text.char_to_line(pos);
1442 let line = text.char_to_line(pos);
1440 let line_start_byte = text.line_to_byte(line);
1443 let line_start_byte = text.line_to_byte(line);
@@ -2529,7 +2532,7 @@ mod test {
2529 let mut cursor = QueryCursor::new();
2532 let mut cursor = QueryCursor::new();
2530
2533
2531 let config = HighlightConfiguration::new(language, "", "", "").unwrap();
2534 let config = HighlightConfiguration::new(language, "", "", "").unwrap();
2532− let syntax = Syntax::new(&source, Arc::new(config), Arc::new(loader)).unwrap();
2535+ let syntax = Syntax::new(source.slice(..), Arc::new(config), Arc::new(loader)).unwrap();
2533
2536
2534 let root = syntax.tree().root_node();
2537 let root = syntax.tree().root_node();
2535 let mut test = |capture, range| {
2538 let mut test = |capture, range| {
@@ -2603,7 +2606,7 @@ mod test {
2603 fn main() {}
2606 fn main() {}
2604 ",
2607 ",
2605 );
2608 );
2606− let syntax = Syntax::new(&source, Arc::new(config), Arc::new(loader)).unwrap();
2609+ let syntax = Syntax::new(source.slice(..), Arc::new(config), Arc::new(loader)).unwrap();
2607 let tree = syntax.tree();
2610 let tree = syntax.tree();
2608 let root = tree.root_node();
2611 let root = tree.root_node();
2609 assert_eq!(root.kind(), "source_file");
2612 assert_eq!(root.kind(), "source_file");
@@ -2630,7 +2633,7 @@ mod test {
2630 &doc,
2633 &doc,
2631 vec![(6, 11, Some("test".into())), (12, 17, None)].into_iter(),
2634 vec![(6, 11, Some("test".into())), (12, 17, None)].into_iter(),
2632 );
2635 );
2633− let edits = generate_edits(&doc, transaction.changes());
2636+ let edits = generate_edits(doc.slice(..), transaction.changes());
2634 // transaction.apply(&mut state);
2637 // transaction.apply(&mut state);
2635
2638
2636 assert_eq!(
2639 assert_eq!(
@@ -2659,7 +2662,7 @@ mod test {
2659 let mut doc = Rope::from("fn test() {}");
2662 let mut doc = Rope::from("fn test() {}");
2660 let transaction =
2663 let transaction =
2661 Transaction::change(&doc, vec![(8, 8, Some("a: u32".into()))].into_iter());
2664 Transaction::change(&doc, vec![(8, 8, Some("a: u32".into()))].into_iter());
2662− let edits = generate_edits(&doc, transaction.changes());
2665+ let edits = generate_edits(doc.slice(..), transaction.changes());
2663 transaction.apply(&mut doc);
2666 transaction.apply(&mut doc);
2664
2667
2665 assert_eq!(doc, "fn test(a: u32) {}");
2668 assert_eq!(doc, "fn test(a: u32) {}");
@@ -2693,7 +2696,7 @@ mod test {
2693 let language = get_language(language_name).unwrap();
2696 let language = get_language(language_name).unwrap();
2694
2697
2695 let config = HighlightConfiguration::new(language, "", "", "").unwrap();
2698 let config = HighlightConfiguration::new(language, "", "", "").unwrap();
2696− let syntax = Syntax::new(&source, Arc::new(config), Arc::new(loader)).unwrap();
2699+ let syntax = Syntax::new(source.slice(..), Arc::new(config), Arc::new(loader)).unwrap();
2697
2700
2698 let root = syntax
2701 let root = syntax
2699 .tree()
2702 .tree()
helix-core/src/transaction.rs+7−6
@@ -1,3 +1,4 @@
1+use ropey::RopeSlice;
1use smallvec::SmallVec;
2use smallvec::SmallVec;
2
3
3use crate::{Range, Rope, Selection, Tendril};
4use crate::{Range, Rope, Selection, Tendril};
@@ -42,7 +43,7 @@ impl ChangeSet {
42 }
43 }
43
44
44 #[must_use]
45 #[must_use]
45− pub fn new(doc: &Rope) -> Self {
46+ pub fn new(doc: RopeSlice) -> Self {
46 let len = doc.len_chars();
47 let len = doc.len_chars();
47 Self {
48 Self {
48 changes: Vec::new(),
49 changes: Vec::new(),
@@ -485,7 +486,7 @@ impl Transaction {
485 /// Create a new, empty transaction.
486 /// Create a new, empty transaction.
486 pub fn new(doc: &Rope) -> Self {
487 pub fn new(doc: &Rope) -> Self {
487 Self {
488 Self {
488− changes: ChangeSet::new(doc),
489+ changes: ChangeSet::new(doc.slice(..)),
489 selection: None,
490 selection: None,
490 }
491 }
491 }
492 }
@@ -946,9 +947,9 @@ mod test {
946 #[test]
947 #[test]
947 fn combine_with_empty() {
948 fn combine_with_empty() {
948 let empty = Rope::from("");
949 let empty = Rope::from("");
949− let a = ChangeSet::new(&empty);
950+ let a = ChangeSet::new(empty.slice(..));
950
951
951− let mut b = ChangeSet::new(&empty);
952+ let mut b = ChangeSet::new(empty.slice(..));
952 b.insert("a".into());
953 b.insert("a".into());
953
954
954 let changes = a.compose(b);
955 let changes = a.compose(b);
@@ -962,9 +963,9 @@ mod test {
962 const TEST_CASE: &str = "Hello, これはヘリックスエディターです!";
963 const TEST_CASE: &str = "Hello, これはヘリックスエディターです!";
963
964
964 let empty = Rope::from("");
965 let empty = Rope::from("");
965− let a = ChangeSet::new(&empty);
966+ let a = ChangeSet::new(empty.slice(..));
966
967
967− let mut b = ChangeSet::new(&empty);
968+ let mut b = ChangeSet::new(empty.slice(..));
968 b.insert(TEST_CASE.into());
969 b.insert(TEST_CASE.into());
969
970
970 let changes = a.compose(b);
971 let changes = a.compose(b);
helix-core/tests/indent.rs+2−2
@@ -72,9 +72,9 @@ fn test_treesitter_indent(file_name: &str, lang_scope: &str) {
72
72
73 let language_config = loader.language_config_for_scope(lang_scope).unwrap();
73 let language_config = loader.language_config_for_scope(lang_scope).unwrap();
74 let highlight_config = language_config.highlight_config(&[]).unwrap();
74 let highlight_config = language_config.highlight_config(&[]).unwrap();
75− let syntax = Syntax::new(&doc, highlight_config, std::sync::Arc::new(loader)).unwrap();
76− let indent_query = language_config.indent_query().unwrap();
77 let text = doc.slice(..);
75 let text = doc.slice(..);
76+ let syntax = Syntax::new(text, highlight_config, std::sync::Arc::new(loader)).unwrap();
77+ let indent_query = language_config.indent_query().unwrap();
78
78
79 for i in 0..doc.len_lines() {
79 for i in 0..doc.len_lines() {
80 let line = text.line(i);
80 let line = text.line(i);
helix-term/src/ui/markdown.rs+4−4
@@ -10,7 +10,7 @@ use pulldown_cmark::{CodeBlockKind, Event, HeadingLevel, Options, Parser, Tag};
10
10
11use helix_core::{
11use helix_core::{
12 syntax::{self, HighlightEvent, InjectionLanguageMarker, Syntax},
12 syntax::{self, HighlightEvent, InjectionLanguageMarker, Syntax},
13− Rope,
13+ RopeSlice,
14};
14};
15use helix_view::{
15use helix_view::{
16 graphics::{Margin, Rect, Style},
16 graphics::{Margin, Rect, Style},
@@ -45,13 +45,13 @@ pub fn highlighted_code_block<'a>(
45 None => return styled_multiline_text(text, code_style),
45 None => return styled_multiline_text(text, code_style),
46 };
46 };
47
47
48− let rope = Rope::from(text.as_ref());
48+ let ropeslice = RopeSlice::from(text);
49 let syntax = config_loader
49 let syntax = config_loader
50 .language_configuration_for_injection_string(&InjectionLanguageMarker::Name(
50 .language_configuration_for_injection_string(&InjectionLanguageMarker::Name(
51 language.into(),
51 language.into(),
52 ))
52 ))
53 .and_then(|config| config.highlight_config(theme.scopes()))
53 .and_then(|config| config.highlight_config(theme.scopes()))
54− .and_then(|config| Syntax::new(&rope, config, Arc::clone(&config_loader)));
54+ .and_then(|config| Syntax::new(ropeslice, config, Arc::clone(&config_loader)));
55
55
56 let syntax = match syntax {
56 let syntax = match syntax {
57 Some(s) => s,
57 Some(s) => s,
@@ -59,7 +59,7 @@ pub fn highlighted_code_block<'a>(
59 };
59 };
60
60
61 let highlight_iter = syntax
61 let highlight_iter = syntax
62− .highlight_iter(rope.slice(..), None, None)
62+ .highlight_iter(ropeslice, None, None)
63 .map(|e| e.unwrap());
63 .map(|e| e.unwrap());
64 let highlight_iter: Box<dyn Iterator<Item = HighlightEvent>> =
64 let highlight_iter: Box<dyn Iterator<Item = HighlightEvent>> =
65 if let Some(spans) = additional_highlight_spans {
65 if let Some(spans) = additional_highlight_spans {
helix-term/src/ui/picker.rs+3−3
@@ -453,9 +453,9 @@ impl<T: Item + 'static> Picker<T> {
453 let text = doc.text().clone();
453 let text = doc.text().clone();
454 let loader = cx.editor.syn_loader.clone();
454 let loader = cx.editor.syn_loader.clone();
455 let job = tokio::task::spawn_blocking(move || {
455 let job = tokio::task::spawn_blocking(move || {
456− let syntax = language_config
457− .highlight_config(&loader.scopes())
456+ let syntax = language_config.highlight_config(&loader.scopes()).and_then(
458− .and_then(|highlight_config| Syntax::new(&text, highlight_config, loader));
457+ |highlight_config| Syntax::new(text.slice(..), highlight_config, loader),
458+ );
459 let callback = move |editor: &mut Editor, compositor: &mut Compositor| {
459 let callback = move |editor: &mut Editor, compositor: &mut Compositor| {
460 let Some(syntax) = syntax else {
460 let Some(syntax) = syntax else {
461 log::info!("highlighting picker item failed");
461 log::info!("highlighting picker item failed");
helix-view/src/document.rs+11−7
@@ -642,7 +642,7 @@ impl Document {
642 ) -> Self {
642 ) -> Self {
643 let (encoding, has_bom) = encoding_with_bom_info.unwrap_or((encoding::UTF_8, false));
643 let (encoding, has_bom) = encoding_with_bom_info.unwrap_or((encoding::UTF_8, false));
644 let line_ending = config.load().default_line_ending.into();
644 let line_ending = config.load().default_line_ending.into();
645− let changes = ChangeSet::new(&text);
645+ let changes = ChangeSet::new(text.slice(..));
646 let old_state = None;
646 let old_state = None;
647
647
648 Self {
648 Self {
@@ -938,7 +938,7 @@ impl Document {
938 ) -> Option<Arc<helix_core::syntax::LanguageConfiguration>> {
938 ) -> Option<Arc<helix_core::syntax::LanguageConfiguration>> {
939 config_loader
939 config_loader
940 .language_config_for_file_name(self.path.as_ref()?)
940 .language_config_for_file_name(self.path.as_ref()?)
941− .or_else(|| config_loader.language_config_for_shebang(self.text()))
941+ .or_else(|| config_loader.language_config_for_shebang(self.text().slice(..)))
942 }
942 }
943
943
944 /// Detect the indentation used in the file, or otherwise defaults to the language indentation
944 /// Detect the indentation used in the file, or otherwise defaults to the language indentation
@@ -1030,7 +1030,7 @@ impl Document {
1030 ) {
1030 ) {
1031 if let (Some(language_config), Some(loader)) = (language_config, loader) {
1031 if let (Some(language_config), Some(loader)) = (language_config, loader) {
1032 if let Some(highlight_config) = language_config.highlight_config(&loader.scopes()) {
1032 if let Some(highlight_config) = language_config.highlight_config(&loader.scopes()) {
1033− self.syntax = Syntax::new(&self.text, highlight_config, loader);
1033+ self.syntax = Syntax::new(self.text.slice(..), highlight_config, loader);
1034 }
1034 }
1035
1035
1036 self.language = Some(language_config);
1036 self.language = Some(language_config);
@@ -1165,7 +1165,11 @@ impl Document {
1165 // update tree-sitter syntax tree
1165 // update tree-sitter syntax tree
1166 if let Some(syntax) = &mut self.syntax {
1166 if let Some(syntax) = &mut self.syntax {
1167 // TODO: no unwrap
1167 // TODO: no unwrap
1168− let res = syntax.update(&old_doc, &self.text, transaction.changes());
1168+ let res = syntax.update(
1169+ old_doc.slice(..),
1170+ self.text.slice(..),
1171+ transaction.changes(),
1172+ );
1169 if res.is_err() {
1173 if res.is_err() {
1170 log::error!("TS parser failed, disabeling TS for the current buffer: {res:?}");
1174 log::error!("TS parser failed, disabeling TS for the current buffer: {res:?}");
1171 self.syntax = None;
1175 self.syntax = None;
@@ -1288,7 +1292,7 @@ impl Document {
1288
1292
1289 if success {
1293 if success {
1290 // reset changeset to fix len
1294 // reset changeset to fix len
1291− self.changes = ChangeSet::new(self.text());
1295+ self.changes = ChangeSet::new(self.text().slice(..));
1292 // Sync with changes with the jumplist selections.
1296 // Sync with changes with the jumplist selections.
1293 view.sync_changes(self);
1297 view.sync_changes(self);
1294 }
1298 }
@@ -1371,7 +1375,7 @@ impl Document {
1371 }
1375 }
1372 if success {
1376 if success {
1373 // reset changeset to fix len
1377 // reset changeset to fix len
1374− self.changes = ChangeSet::new(self.text());
1378+ self.changes = ChangeSet::new(self.text().slice(..));
1375 // Sync with changes with the jumplist selections.
1379 // Sync with changes with the jumplist selections.
1376 view.sync_changes(self);
1380 view.sync_changes(self);
1377 }
1381 }
@@ -1394,7 +1398,7 @@ impl Document {
1394 return;
1398 return;
1395 }
1399 }
1396
1400
1397− let new_changeset = ChangeSet::new(self.text());
1401+ let new_changeset = ChangeSet::new(self.text().slice(..));
1398 let changes = std::mem::replace(&mut self.changes, new_changeset);
1402 let changes = std::mem::replace(&mut self.changes, new_changeset);
1399 // Instead of doing this messy merge we could always commit, and based on transaction
1403 // Instead of doing this messy merge we could always commit, and based on transaction
1400 // annotations either add a new layer or compose into the previous one.
1404 // annotations either add a new layer or compose into the previous one.