2021-08-11 23:34:35 +08:00
|
|
|
use crate::{
|
2021-08-15 21:11:48 +08:00
|
|
|
client::view::{util::find_newline, FormatExt, NEW_LINE},
|
2021-08-13 14:13:31 +08:00
|
|
|
core::{
|
|
|
|
|
Attribute,
|
2021-08-14 16:44:39 +08:00
|
|
|
AttributeKey,
|
2021-08-13 14:13:31 +08:00
|
|
|
AttributeScope,
|
|
|
|
|
Attributes,
|
|
|
|
|
CharMetric,
|
|
|
|
|
Delta,
|
|
|
|
|
DeltaBuilder,
|
|
|
|
|
DeltaIter,
|
|
|
|
|
Interval,
|
|
|
|
|
Operation,
|
|
|
|
|
},
|
2021-08-11 23:34:35 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
pub struct FormatLinkAtCaretPositionExt {}
|
|
|
|
|
|
|
|
|
|
impl FormatExt for FormatLinkAtCaretPositionExt {
|
2021-08-15 21:11:48 +08:00
|
|
|
fn ext_name(&self) -> &str { "FormatLinkAtCaretPositionExt" }
|
|
|
|
|
|
2021-08-11 23:34:35 +08:00
|
|
|
fn apply(&self, delta: &Delta, interval: Interval, attribute: &Attribute) -> Option<Delta> {
|
2021-08-14 16:44:39 +08:00
|
|
|
if attribute.key != AttributeKey::Link || interval.size() != 0 {
|
|
|
|
|
return None;
|
|
|
|
|
}
|
|
|
|
|
|
2021-08-12 13:57:41 +08:00
|
|
|
let mut iter = DeltaIter::new(delta);
|
2021-08-13 14:13:31 +08:00
|
|
|
iter.seek::<CharMetric>(interval.start);
|
2021-08-14 16:44:39 +08:00
|
|
|
|
2021-08-15 21:36:03 +08:00
|
|
|
let (before, after) = (iter.next_op_before(interval.size()), iter.next());
|
2021-08-14 16:44:39 +08:00
|
|
|
let mut start = interval.end;
|
2021-08-12 13:57:41 +08:00
|
|
|
let mut retain = 0;
|
|
|
|
|
|
|
|
|
|
if let Some(before) = before {
|
|
|
|
|
if before.contain_attribute(attribute) {
|
|
|
|
|
start -= before.length();
|
|
|
|
|
retain += before.length();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if let Some(after) = after {
|
|
|
|
|
if after.contain_attribute(attribute) {
|
|
|
|
|
if retain != 0 {
|
|
|
|
|
retain += after.length();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if retain == 0 {
|
|
|
|
|
return None;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Some(
|
|
|
|
|
DeltaBuilder::new()
|
2021-08-15 00:05:18 +08:00
|
|
|
.retain(start)
|
|
|
|
|
.retain_with_attributes(retain, (attribute.clone()).into())
|
2021-08-12 13:57:41 +08:00
|
|
|
.build(),
|
|
|
|
|
)
|
2021-08-11 23:34:35 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-08-15 21:11:48 +08:00
|
|
|
pub struct ResolveBlockFormatExt {}
|
|
|
|
|
impl FormatExt for ResolveBlockFormatExt {
|
|
|
|
|
fn ext_name(&self) -> &str { "ResolveBlockFormatExt" }
|
|
|
|
|
|
2021-08-11 23:34:35 +08:00
|
|
|
fn apply(&self, delta: &Delta, interval: Interval, attribute: &Attribute) -> Option<Delta> {
|
2021-08-12 13:57:41 +08:00
|
|
|
if attribute.scope != AttributeScope::Block {
|
|
|
|
|
return None;
|
|
|
|
|
}
|
|
|
|
|
|
2021-08-15 21:11:48 +08:00
|
|
|
let mut new_delta = DeltaBuilder::new().retain(interval.start).build();
|
2021-08-12 13:57:41 +08:00
|
|
|
let mut iter = DeltaIter::new(delta);
|
2021-08-13 14:13:31 +08:00
|
|
|
iter.seek::<CharMetric>(interval.start);
|
2021-08-15 21:11:48 +08:00
|
|
|
let mut start = 0;
|
|
|
|
|
let end = interval.size();
|
|
|
|
|
while start < end && iter.has_next() {
|
2021-08-15 21:36:03 +08:00
|
|
|
let next_op = iter.next_op_before(end - start).unwrap();
|
2021-08-15 21:11:48 +08:00
|
|
|
match find_newline(next_op.get_data()) {
|
|
|
|
|
None => new_delta.retain(next_op.length(), Attributes::empty()),
|
|
|
|
|
Some(_) => {
|
|
|
|
|
let tmp_delta = line_break(&next_op, attribute, AttributeScope::Block);
|
|
|
|
|
new_delta.extend(tmp_delta);
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
start += next_op.length();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
while iter.has_next() {
|
|
|
|
|
let op = iter
|
|
|
|
|
.next_op()
|
|
|
|
|
.expect("Unexpected None, iter.has_next() must return op");
|
|
|
|
|
|
|
|
|
|
match find_newline(op.get_data()) {
|
|
|
|
|
None => new_delta.retain(op.length(), Attributes::empty()),
|
|
|
|
|
Some(line_break) => {
|
|
|
|
|
debug_assert_eq!(line_break, 0);
|
|
|
|
|
new_delta.retain(1, attribute.clone().into());
|
|
|
|
|
break;
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-08-12 13:57:41 +08:00
|
|
|
|
2021-08-15 21:11:48 +08:00
|
|
|
Some(new_delta)
|
2021-08-11 23:34:35 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub struct ResolveInlineFormatExt {}
|
|
|
|
|
impl FormatExt for ResolveInlineFormatExt {
|
2021-08-15 21:11:48 +08:00
|
|
|
fn ext_name(&self) -> &str { "ResolveInlineFormatExt" }
|
|
|
|
|
|
2021-08-11 23:34:35 +08:00
|
|
|
fn apply(&self, delta: &Delta, interval: Interval, attribute: &Attribute) -> Option<Delta> {
|
2021-08-13 14:13:31 +08:00
|
|
|
if attribute.scope != AttributeScope::Inline {
|
|
|
|
|
return None;
|
|
|
|
|
}
|
2021-08-15 00:05:18 +08:00
|
|
|
let mut new_delta = DeltaBuilder::new().retain(interval.start).build();
|
2021-08-13 14:13:31 +08:00
|
|
|
let mut iter = DeltaIter::new(delta);
|
|
|
|
|
iter.seek::<CharMetric>(interval.start);
|
|
|
|
|
|
2021-08-15 21:11:48 +08:00
|
|
|
let mut start = 0;
|
|
|
|
|
let end = interval.size();
|
|
|
|
|
|
|
|
|
|
while start < end && iter.has_next() {
|
2021-08-15 21:36:03 +08:00
|
|
|
let next_op = iter.next_op_before(end - start).unwrap();
|
2021-08-15 21:11:48 +08:00
|
|
|
match find_newline(next_op.get_data()) {
|
|
|
|
|
None => new_delta.retain(next_op.length(), attribute.clone().into()),
|
|
|
|
|
Some(_) => {
|
|
|
|
|
let tmp_delta = line_break(&next_op, attribute, AttributeScope::Inline);
|
|
|
|
|
new_delta.extend(tmp_delta);
|
|
|
|
|
},
|
2021-08-13 14:13:31 +08:00
|
|
|
}
|
|
|
|
|
|
2021-08-15 21:11:48 +08:00
|
|
|
start += next_op.length();
|
2021-08-13 14:13:31 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Some(new_delta)
|
2021-08-11 23:34:35 +08:00
|
|
|
}
|
|
|
|
|
}
|
2021-08-15 21:11:48 +08:00
|
|
|
|
|
|
|
|
fn line_break(op: &Operation, attribute: &Attribute, scope: AttributeScope) -> Delta {
|
|
|
|
|
let mut new_delta = Delta::new();
|
|
|
|
|
let mut start = 0;
|
|
|
|
|
let end = op.length();
|
|
|
|
|
let mut s = op.get_data();
|
|
|
|
|
|
|
|
|
|
while let Some(line_break) = find_newline(s) {
|
|
|
|
|
match scope {
|
|
|
|
|
AttributeScope::Inline => {
|
|
|
|
|
new_delta.retain(line_break - start, attribute.clone().into());
|
|
|
|
|
new_delta.retain(1, Attributes::empty());
|
|
|
|
|
},
|
|
|
|
|
AttributeScope::Block => {
|
|
|
|
|
new_delta.retain(line_break - start, Attributes::empty());
|
|
|
|
|
new_delta.retain(1, attribute.clone().into());
|
|
|
|
|
},
|
|
|
|
|
_ => {
|
|
|
|
|
log::error!("Unsupported parser line break for {:?}", scope);
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
start = line_break + 1;
|
|
|
|
|
s = &s[start..s.len()];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if start < end {
|
|
|
|
|
match scope {
|
|
|
|
|
AttributeScope::Inline => new_delta.retain(end - start, attribute.clone().into()),
|
|
|
|
|
AttributeScope::Block => new_delta.retain(end - start, Attributes::empty()),
|
|
|
|
|
_ => log::error!("Unsupported parser line break for {:?}", scope),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
new_delta
|
|
|
|
|
}
|