auto_format.rs 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. use crate::{
  2. client::{extensions::InsertExt, util::is_whitespace},
  3. core::{Delta, DeltaIter},
  4. };
  5. pub struct AutoFormatExt {}
  6. impl InsertExt for AutoFormatExt {
  7. fn ext_name(&self) -> &str { "AutoFormatExt" }
  8. fn apply(&self, delta: &Delta, replace_len: usize, text: &str, index: usize) -> Option<Delta> {
  9. // enter whitespace to trigger auto format
  10. if !is_whitespace(text) {
  11. return None;
  12. }
  13. let mut iter = DeltaIter::new(delta);
  14. if let Some(prev) = iter.last_op_before_index(index) {
  15. match AutoFormat::parse(prev.get_data()) {
  16. None => {},
  17. Some(formatter) => {
  18. let mut new_attributes = prev.get_attributes();
  19. // format_len should not greater than index. The url crate will add "/" to the
  20. // end of input string that causes the format_len greater than the input string
  21. let format_len = min(index, formatter.format_len());
  22. let format_attributes = formatter.to_attributes();
  23. format_attributes.iter().for_each(|(k, v)| {
  24. if !new_attributes.contains_key(k) {
  25. new_attributes.insert(k.clone(), v.clone());
  26. }
  27. });
  28. let next_attributes = match iter.next_op() {
  29. None => Attributes::empty(),
  30. Some(op) => op.get_attributes(),
  31. };
  32. return Some(
  33. DeltaBuilder::new()
  34. .retain(index + replace_len - min(index, format_len))
  35. .retain_with_attributes(format_len, format_attributes)
  36. .insert_with_attributes(text, next_attributes)
  37. .build(),
  38. );
  39. },
  40. }
  41. }
  42. None
  43. }
  44. }
  45. use crate::core::{Attribute, AttributeBuilder, Attributes, DeltaBuilder, Operation};
  46. use bytecount::num_chars;
  47. use std::cmp::min;
  48. use url::Url;
  49. pub enum AutoFormatter {
  50. Url(Url),
  51. }
  52. impl AutoFormatter {
  53. pub fn to_attributes(&self) -> Attributes {
  54. match self {
  55. AutoFormatter::Url(url) => AttributeBuilder::new().link(url.as_str(), true).build(),
  56. }
  57. }
  58. pub fn format_len(&self) -> usize {
  59. let s = match self {
  60. AutoFormatter::Url(url) => url.to_string(),
  61. };
  62. num_chars(s.as_bytes())
  63. }
  64. }
  65. pub struct AutoFormat {}
  66. impl AutoFormat {
  67. fn parse(s: &str) -> Option<AutoFormatter> {
  68. if let Ok(url) = Url::parse(s) {
  69. return Some(AutoFormatter::Url(url));
  70. }
  71. None
  72. }
  73. }