#rope #data #edit #buffer

nightly any-rope

为 Rust 设计的快速且健壮的任意绳数据类型。基于 Ropey。

19 个稳定版本

1.2.5 2023年10月31日
1.2.4 2023年10月12日
1.2.3 2023年9月20日
1.1.2 2023年8月4日
1.0.6 2023年3月27日

#340数据结构

Download history 15/week @ 2024-04-08 14/week @ 2024-04-15 22/week @ 2024-04-22 14/week @ 2024-04-29 21/week @ 2024-05-06 20/week @ 2024-05-13 15/week @ 2024-05-20 15/week @ 2024-05-27 20/week @ 2024-06-03 23/week @ 2024-06-10 13/week @ 2024-06-17 23/week @ 2024-06-24 138/week @ 2024-07-08 5/week @ 2024-07-15 8/week @ 2024-07-22

每月下载量 155
3 个crate中使用(通过parsec-core

MIT 许可证

315KB
6.5K SLoC

AnyRope

CI Build Status Latest Release Documentation

AnyRope 是一个为 Rust 设计的任意数据类型绳数据结构,旨在执行类似绳的操作,但针对的是非文本数据类型。

示例用法

这种用法的一个例子是在文本编辑器中对文本进行标记,例如,可以将一个文本绳与一个标记绳相关联。

// The tags that will be assossiated with a piece of text, that could be a rope.
#[derive(Clone, Copy, PartialEq, Eq)]
enum Tag {
    PrintRed,
    Underline,
    Normal,
    Skip(usize)
}

use Tag::*;

impl any_rope::Measurable for Tag {
    type Measure = usize;

    fn measure(&self) -> Self::Measure {
        match self {
            // The zero here represents the fact that multiple tags may be placed
            // in the same character.
            PrintRed | Underline | Normal => 0,
            // Skip here is an amount of characters with no tags in them.
            Skip(amount) => *amount
        }
    }
}

// An `&str` that will be colored.
let my_str = "This word will be red!";

// Here's what this means:
// - Skip 5 characters;
// - Change the color to red;
// - Skip 4 characters;
// - Change the rendering back to normal.
let mut tags = any_rope::Rope::from_slice(&[Skip(5), PrintRed, Skip(4), Normal]);
// Do note that Tag::Skip only represents characters because we are also iterating
// over a `Chars` iterator, and have chosen to do so.

// An empty range, when used in an inclusive removal
// will remove all 0 width elements in that specific
// width. `Rope::remove_exclusive()` would keep them.
// In this case, that would be `Tag::PrintRed`
//
// The reason why we need to pass in a comparison
// function is because of the flexibility of the
// `Measurable::Measure` type. By passing various
// types of comparison functions, we can selectively
// choose what we are looking for. This is similar to
// what regular ropes do when searching within text,
// the end user can search by byte, char, line, etc.
tags.remove_inclusive(5..5, usize::cmp);
// In place of that `Tag::PrintRed`, we will insert `Tag::Underline`.
tags.insert(5, Underline, usize::cmp);

// The AnyRope iterator not only returns the element in question, but also the width
// where it starts.
let mut tags_iter = tags.iter().peekable();

for (cur_index, ch) in my_str.chars().enumerate() {
    // The while let loop here is a useful way to activate all tags within the same
    // character. For example, we could have a sequence of [Tag::UnderLine, Tag::PrintRed]
    // in the `Rope`, both of which have a width of 0, allowing one to execute multiple
    // `Tag`s in a single character.
    while let Some((index, tag)) = tags_iter.peek() {
        if *index == cur_index {
            activate_tag(tag);
            tags_iter.next();
        } else {
            break;
        }
    }
    print!("{}", ch);
}

何时使用 AnyRope?

到目前为止,我还没有在其他地方找到 AnyRope 的用途,除了文本编辑器,但我不会排除它可能在其他地方有用的可能性。

功能

宽度概念

实现 Measurable 的元素的宽度可以是最终用户想要的任何宽度,这使 AnyRope 能够以非常灵活的方式在多个方面发挥作用。

绳切片

AnyRope 有绳切片,允许您仅使用绳的一部分,使用全部绳的只读操作,包括迭代器和子切片。

灵活的 API 和低级访问

尽管 AnyRope 故意限制了范围,但它也提供了 API 以高效地访问和处理其内部切片块表示,允许客户端代码以最小的开销高效地实现附加功能。

线程安全

AnyRope 确保即使克隆共享内存,一切也都是线程安全的。克隆可以被发送到其他线程进行读写。

不安全代码

AnyRope 使用不安全代码来实现一些空间和性能特性。尽管已尽力将不安全代码隔离并使其正确,但在可能面临对抗性条件的软件中使用 AnyRope 时请谨慎。

许可证

AnyRope 根据 MIT 许可证授权(LICENSE.md 或 http://opensource.org/licenses/MIT

贡献

贡献绝对欢迎!然而,请开启一个issue或给我发邮件讨论较大的变更,以避免做很多可能被拒绝的工作。

除非你明确表示不同,否则你提交给AnyRope的任何贡献将按照上述方式授权,不附加任何额外条款或条件。

依赖项