diff --git a/Cargo.lock b/Cargo.lock index 3253e6cd3..360ebcfb0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -246,16 +246,6 @@ dependencies = [ "percent-encoding", ] -[[package]] -name = "futf" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df420e2e84819663797d1ec6544b13c5be84629e7bb00dc960d6917db2987843" -dependencies = [ - "mac", - "new_debug_unreachable", -] - [[package]] name = "futures-core" version = "0.3.21" @@ -383,7 +373,7 @@ dependencies = [ "similar", "slotmap", "smallvec", - "tendril", + "smartstring", "toml", "tree-sitter", "unicode-general-category", @@ -606,12 +596,6 @@ dependencies = [ "url", ] -[[package]] -name = "mac" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4" - [[package]] name = "matches" version = "0.1.9" @@ -655,12 +639,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "new_debug_unreachable" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54" - [[package]] name = "ntapi" version = "0.3.6" @@ -1010,6 +988,21 @@ version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83" +[[package]] +name = "smartstring" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31aa6a31c0c2b21327ce875f7e8952322acfcfd0c27569a6e18a647281352c9b" +dependencies = [ + "static_assertions", +] + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + [[package]] name = "str-buf" version = "1.0.5" @@ -1027,17 +1020,6 @@ dependencies = [ "unicode-xid", ] -[[package]] -name = "tendril" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9ef557cb397a4f0a5a3a628f06515f78563f2209e64d47055d9dc6052bf5e33" -dependencies = [ - "futf", - "mac", - "utf-8", -] - [[package]] name = "thiserror" version = "1.0.30" @@ -1212,12 +1194,6 @@ dependencies = [ "serde", ] -[[package]] -name = "utf-8" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" - [[package]] name = "version_check" version = "0.9.4" diff --git a/helix-core/Cargo.toml b/helix-core/Cargo.toml index 3a1f9b3e0..7ff91cfda 100644 --- a/helix-core/Cargo.toml +++ b/helix-core/Cargo.toml @@ -17,7 +17,7 @@ helix-syntax = { version = "0.6", path = "../helix-syntax" } ropey = "1.3" smallvec = "1.8" -tendril = "0.4.2" +smartstring = "0.2.9" unicode-segmentation = "1.9" unicode-width = "0.1" unicode-general-category = "0.5" diff --git a/helix-core/src/auto_pairs.rs b/helix-core/src/auto_pairs.rs index 408026803..f4359a342 100644 --- a/helix-core/src/auto_pairs.rs +++ b/helix-core/src/auto_pairs.rs @@ -214,7 +214,9 @@ fn handle_open( let change = match next_char { Some(ch) if !close_before.contains(ch) => { len_inserted = open.len_utf8(); - (cursor, cursor, Some(Tendril::from_char(open))) + let mut tendril = Tendril::new(); + tendril.push(open); + (cursor, cursor, Some(tendril)) } // None | Some(ch) if close_before.contains(ch) => {} _ => { @@ -252,7 +254,9 @@ fn handle_close(doc: &Rope, selection: &Selection, _open: char, close: char) -> (cursor, cursor, None) // no-op } else { len_inserted += close.len_utf8(); - (cursor, cursor, Some(Tendril::from_char(close))) + let mut tendril = Tendril::new(); + tendril.push(close); + (cursor, cursor, Some(tendril)) }; let next_range = get_next_range(doc, start_range, offs, close, len_inserted); @@ -290,15 +294,15 @@ fn handle_same( // return transaction that moves past close (cursor, cursor, None) // no-op } else { - let mut pair = Tendril::with_capacity(2 * token.len_utf8() as u32); - pair.push_char(token); + let mut pair = Tendril::new(); + pair.push(token); // for equal pairs, don't insert both open and close if either // side has a non-pair char if (next_char.is_none() || close_before.contains(next_char.unwrap())) && (prev_char.is_none() || open_before.contains(prev_char.unwrap())) { - pair.push_char(token); + pair.push(token); } len_inserted += pair.len(); diff --git a/helix-core/src/increment/date_time.rs b/helix-core/src/increment/date_time.rs index 1703c3baf..91fa59631 100644 --- a/helix-core/src/increment/date_time.rs +++ b/helix-core/src/increment/date_time.rs @@ -451,7 +451,7 @@ mod test { .unwrap() .increment(amount) .1, - expected.into() + Tendril::from(expected) ); } } diff --git a/helix-core/src/increment/number.rs b/helix-core/src/increment/number.rs index a19b7e754..57171f671 100644 --- a/helix-core/src/increment/number.rs +++ b/helix-core/src/increment/number.rs @@ -371,7 +371,7 @@ mod test { .unwrap() .increment(amount) .1, - expected.into() + Tendril::from(expected) ); } } @@ -398,7 +398,7 @@ mod test { .unwrap() .increment(amount) .1, - expected.into() + Tendril::from(expected) ); } } @@ -426,7 +426,7 @@ mod test { .unwrap() .increment(amount) .1, - expected.into() + Tendril::from(expected) ); } } @@ -472,7 +472,7 @@ mod test { .unwrap() .increment(amount) .1, - expected.into() + Tendril::from(expected) ); } } @@ -500,7 +500,7 @@ mod test { .unwrap() .increment(amount) .1, - expected.into() + Tendril::from(expected) ); } } diff --git a/helix-core/src/lib.rs b/helix-core/src/lib.rs index 7fd23b977..0b03ead8f 100644 --- a/helix-core/src/lib.rs +++ b/helix-core/src/lib.rs @@ -212,7 +212,10 @@ use etcetera::base_strategy::{choose_base_strategy, BaseStrategy}; pub use ropey::{Rope, RopeBuilder, RopeSlice}; -pub use tendril::StrTendril as Tendril; +// pub use tendril::StrTendril as Tendril; +pub use smartstring::SmartString; + +pub type Tendril = SmartString; #[doc(inline)] pub use {regex, tree_sitter}; diff --git a/helix-core/src/transaction.rs b/helix-core/src/transaction.rs index 30995e8ce..2e34a9864 100644 --- a/helix-core/src/transaction.rs +++ b/helix-core/src/transaction.rs @@ -85,7 +85,7 @@ impl ChangeSet { let new_last = match self.changes.as_mut_slice() { [.., Insert(prev)] | [.., Insert(prev), Delete(_)] => { - prev.push_tendril(&fragment); + prev.push_str(&fragment); return; } [.., last @ Delete(_)] => std::mem::replace(last, Insert(fragment)), @@ -189,7 +189,7 @@ impl ChangeSet { // TODO: cover this with a test // figure out the byte index of the truncated string end let (pos, _) = s.char_indices().nth(j).unwrap(); - s.pop_front(pos as u32); + s.replace_range(0..pos, ""); head_a = Some(Insert(s)); head_b = changes_b.next(); } @@ -211,9 +211,11 @@ impl ChangeSet { Ordering::Greater => { // figure out the byte index of the truncated string end let (pos, _) = s.char_indices().nth(j).unwrap(); - let pos = pos as u32; - changes.insert(s.subtendril(0, pos)); - head_a = Some(Insert(s.subtendril(pos, s.len() as u32 - pos))); + let mut before = s; + let after = before.split_off(pos); + + changes.insert(before); + head_a = Some(Insert(after)); head_b = changes_b.next(); } } @@ -277,7 +279,7 @@ impl ChangeSet { } Delete(n) => { let text = Cow::from(original_doc.slice(pos..pos + *n)); - changes.insert(Tendril::from_slice(&text)); + changes.insert(Tendril::from(text.as_ref())); pos += n; } Insert(s) => { @@ -710,19 +712,19 @@ mod test { #[test] fn optimized_composition() { let mut state = State::new("".into()); - let t1 = Transaction::insert(&state.doc, &state.selection, Tendril::from_char('h')); + let t1 = Transaction::insert(&state.doc, &state.selection, Tendril::from("h")); t1.apply(&mut state.doc); state.selection = state.selection.clone().map(t1.changes()); - let t2 = Transaction::insert(&state.doc, &state.selection, Tendril::from_char('e')); + let t2 = Transaction::insert(&state.doc, &state.selection, Tendril::from("e")); t2.apply(&mut state.doc); state.selection = state.selection.clone().map(t2.changes()); - let t3 = Transaction::insert(&state.doc, &state.selection, Tendril::from_char('l')); + let t3 = Transaction::insert(&state.doc, &state.selection, Tendril::from("l")); t3.apply(&mut state.doc); state.selection = state.selection.clone().map(t3.changes()); - let t4 = Transaction::insert(&state.doc, &state.selection, Tendril::from_char('l')); + let t4 = Transaction::insert(&state.doc, &state.selection, Tendril::from("l")); t4.apply(&mut state.doc); state.selection = state.selection.clone().map(t4.changes()); - let t5 = Transaction::insert(&state.doc, &state.selection, Tendril::from_char('o')); + let t5 = Transaction::insert(&state.doc, &state.selection, Tendril::from("o")); t5.apply(&mut state.doc); state.selection = state.selection.clone().map(t5.changes()); diff --git a/helix-lsp/src/client.rs b/helix-lsp/src/client.rs index c80f70b54..15cbca0eb 100644 --- a/helix-lsp/src/client.rs +++ b/helix-lsp/src/client.rs @@ -438,7 +438,7 @@ impl Client { changes.push(lsp::TextDocumentContentChangeEvent { range: Some(lsp::Range::new(start, end)), - text: s.into(), + text: s.to_string(), range_length: None, }); } diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index d08827285..9918d26c6 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -2769,7 +2769,7 @@ pub mod cmd { let mut fragments: Vec<_> = selection .fragments(text) - .map(|fragment| Tendril::from_slice(&fragment)) + .map(|fragment| Tendril::from(fragment.as_ref())) .collect(); fragments.sort_by(match reverse { @@ -3921,7 +3921,7 @@ fn try_restore_indent(doc: &mut Document, view_id: ViewId) { if let [Operation::Retain(move_pos), Operation::Insert(ref inserted_str), Operation::Retain(_)] = changes { - move_pos + inserted_str.len32() as usize == pos + move_pos + inserted_str.len() == pos && inserted_str.starts_with('\n') && inserted_str.chars().skip(1).all(char_is_whitespace) && pos == line_end_pos // ensure no characters exists after current position @@ -4513,7 +4513,8 @@ pub mod insert { #[allow(clippy::unnecessary_wraps)] // need to use Option<> because of the Hook signature fn insert(doc: &Rope, selection: &Selection, ch: char) -> Option { let cursors = selection.clone().cursors(doc.slice(..)); - let t = Tendril::from_char(ch); + let mut t = Tendril::new(); + t.push(ch); let transaction = Transaction::insert(doc, &cursors, t); Some(transaction) } @@ -5015,12 +5016,12 @@ fn replace_with_yanked(cx: &mut Context) { let repeat = std::iter::repeat( values .last() - .map(|value| Tendril::from_slice(&value.repeat(count))) + .map(|value| Tendril::from(&value.repeat(count))) .unwrap(), ); let mut values = values .iter() - .map(|value| Tendril::from_slice(&value.repeat(count))) + .map(|value| Tendril::from(&value.repeat(count))) .chain(repeat); let selection = doc.selection(view.id); let transaction = Transaction::change_by_selection(doc.text(), selection, |range| { @@ -5530,7 +5531,7 @@ fn rotate_selection_contents(cx: &mut Context, direction: Direction) { let selection = doc.selection(view.id); let mut fragments: Vec<_> = selection .fragments(text) - .map(|fragment| Tendril::from_slice(&fragment)) + .map(|fragment| Tendril::from(fragment.as_ref())) .collect(); let group = count @@ -5891,8 +5892,12 @@ fn surround_add(cx: &mut Context) { let mut changes = Vec::with_capacity(selection.len() * 2); for range in selection.iter() { - changes.push((range.from(), range.from(), Some(Tendril::from_char(open)))); - changes.push((range.to(), range.to(), Some(Tendril::from_char(close)))); + let mut o = Tendril::new(); + o.push(open); + let mut c = Tendril::new(); + c.push(close); + changes.push((range.from(), range.from(), Some(o))); + changes.push((range.to(), range.to(), Some(c))); } let transaction = Transaction::change(doc.text(), changes.into_iter()); @@ -5921,11 +5926,9 @@ fn surround_replace(cx: &mut Context) { let transaction = Transaction::change( doc.text(), change_pos.iter().enumerate().map(|(i, &pos)| { - ( - pos, - pos + 1, - Some(Tendril::from_char(if i % 2 == 0 { open } else { close })), - ) + let mut t = Tendril::new(); + t.push(if i % 2 == 0 { open } else { close }); + (pos, pos + 1, Some(t)) }), ); doc.apply(&transaction, view.id); @@ -6065,8 +6068,9 @@ fn shell_impl( log::error!("Shell error: {}", String::from_utf8_lossy(&output.stderr)); } - let tendril = Tendril::try_from_byte_slice(&output.stdout) + let str = std::str::from_utf8(&output.stdout) .map_err(|_| anyhow!("Process did not output valid UTF-8"))?; + let tendril = Tendril::from(str); Ok((tendril, output.status.success())) } diff --git a/xtask/src/main.rs b/xtask/src/main.rs index 7256653a3..d24a29cc4 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -120,7 +120,7 @@ pub mod md_gen { } fn md_table_row(cols: &[String]) -> String { - "| ".to_owned() + &cols.join(" | ") + " |\n" + format!("| {} |\n", cols.join(" | ")) } fn md_mono(s: &str) -> String {