123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687 |
- use crate::{
- client::{extensions::InsertExt, util::is_whitespace},
- core::{Delta, DeltaIter},
- };
- pub struct AutoFormatExt {}
- impl InsertExt for AutoFormatExt {
- fn ext_name(&self) -> &str { "AutoFormatExt" }
- fn apply(&self, delta: &Delta, replace_len: usize, text: &str, index: usize) -> Option<Delta> {
- // enter whitespace to trigger auto format
- if !is_whitespace(text) {
- return None;
- }
- let mut iter = DeltaIter::new(delta);
- if let Some(prev) = iter.last_op_before_index(index) {
- match AutoFormat::parse(prev.get_data()) {
- None => {},
- Some(formatter) => {
- let mut new_attributes = prev.get_attributes();
- // format_len should not greater than index. The url crate will add "/" to the
- // end of input string that causes the format_len greater than the input string
- let format_len = min(index, formatter.format_len());
- let format_attributes = formatter.to_attributes();
- format_attributes.iter().for_each(|(k, v)| {
- if !new_attributes.contains_key(k) {
- new_attributes.insert(k.clone(), v.clone());
- }
- });
- let next_attributes = match iter.next_op() {
- None => Attributes::empty(),
- Some(op) => op.get_attributes(),
- };
- return Some(
- DeltaBuilder::new()
- .retain(index + replace_len - min(index, format_len))
- .retain_with_attributes(format_len, format_attributes)
- .insert_with_attributes(text, next_attributes)
- .build(),
- );
- },
- }
- }
- None
- }
- }
- use crate::core::{Attribute, AttributeBuilder, Attributes, DeltaBuilder, Operation};
- use bytecount::num_chars;
- use std::cmp::min;
- use url::Url;
- pub enum AutoFormatter {
- Url(Url),
- }
- impl AutoFormatter {
- pub fn to_attributes(&self) -> Attributes {
- match self {
- AutoFormatter::Url(url) => AttributeBuilder::new().link(url.as_str(), true).build(),
- }
- }
- pub fn format_len(&self) -> usize {
- let s = match self {
- AutoFormatter::Url(url) => url.to_string(),
- };
- num_chars(s.as_bytes())
- }
- }
- pub struct AutoFormat {}
- impl AutoFormat {
- fn parse(s: &str) -> Option<AutoFormatter> {
- if let Ok(url) = Url::parse(s) {
- return Some(AutoFormatter::Url(url));
- }
- None
- }
- }
|