parent
1936ba5e30
commit
7f6bb3d1eb
15 changed files with 347 additions and 213 deletions
80
crates/multi_buffer/Cargo.toml
Normal file
80
crates/multi_buffer/Cargo.toml
Normal file
|
@ -0,0 +1,80 @@
|
|||
[package]
|
||||
name = "multi_buffer"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
publish = false
|
||||
|
||||
[lib]
|
||||
path = "src/multi_buffer.rs"
|
||||
doctest = false
|
||||
|
||||
[features]
|
||||
test-support = [
|
||||
"copilot/test-support",
|
||||
"text/test-support",
|
||||
"language/test-support",
|
||||
"gpui/test-support",
|
||||
"util/test-support",
|
||||
"tree-sitter-rust",
|
||||
"tree-sitter-typescript"
|
||||
]
|
||||
|
||||
[dependencies]
|
||||
client = { path = "../client" }
|
||||
clock = { path = "../clock" }
|
||||
collections = { path = "../collections" }
|
||||
context_menu = { path = "../context_menu" }
|
||||
git = { path = "../git" }
|
||||
gpui = { path = "../gpui" }
|
||||
language = { path = "../language" }
|
||||
lsp = { path = "../lsp" }
|
||||
rich_text = { path = "../rich_text" }
|
||||
settings = { path = "../settings" }
|
||||
snippet = { path = "../snippet" }
|
||||
sum_tree = { path = "../sum_tree" }
|
||||
text = { path = "../text" }
|
||||
theme = { path = "../theme" }
|
||||
util = { path = "../util" }
|
||||
|
||||
aho-corasick = "1.1"
|
||||
anyhow.workspace = true
|
||||
convert_case = "0.6.0"
|
||||
futures.workspace = true
|
||||
indoc = "1.0.4"
|
||||
itertools = "0.10"
|
||||
lazy_static.workspace = true
|
||||
log.workspace = true
|
||||
ordered-float.workspace = true
|
||||
parking_lot.workspace = true
|
||||
postage.workspace = true
|
||||
pulldown-cmark = { version = "0.9.2", default-features = false }
|
||||
rand.workspace = true
|
||||
schemars.workspace = true
|
||||
serde.workspace = true
|
||||
serde_derive.workspace = true
|
||||
smallvec.workspace = true
|
||||
smol.workspace = true
|
||||
|
||||
tree-sitter-rust = { workspace = true, optional = true }
|
||||
tree-sitter-html = { workspace = true, optional = true }
|
||||
tree-sitter-typescript = { workspace = true, optional = true }
|
||||
|
||||
[dev-dependencies]
|
||||
copilot = { path = "../copilot", features = ["test-support"] }
|
||||
text = { path = "../text", features = ["test-support"] }
|
||||
language = { path = "../language", features = ["test-support"] }
|
||||
lsp = { path = "../lsp", features = ["test-support"] }
|
||||
gpui = { path = "../gpui", features = ["test-support"] }
|
||||
util = { path = "../util", features = ["test-support"] }
|
||||
project = { path = "../project", features = ["test-support"] }
|
||||
settings = { path = "../settings", features = ["test-support"] }
|
||||
workspace = { path = "../workspace", features = ["test-support"] }
|
||||
|
||||
ctor.workspace = true
|
||||
env_logger.workspace = true
|
||||
rand.workspace = true
|
||||
unindent.workspace = true
|
||||
tree-sitter.workspace = true
|
||||
tree-sitter-rust.workspace = true
|
||||
tree-sitter-html.workspace = true
|
||||
tree-sitter-typescript.workspace = true
|
138
crates/multi_buffer/src/anchor.rs
Normal file
138
crates/multi_buffer/src/anchor.rs
Normal file
|
@ -0,0 +1,138 @@
|
|||
use super::{ExcerptId, MultiBufferSnapshot, ToOffset, ToOffsetUtf16, ToPoint};
|
||||
use language::{OffsetUtf16, Point, TextDimension};
|
||||
use std::{
|
||||
cmp::Ordering,
|
||||
ops::{Range, Sub},
|
||||
};
|
||||
use sum_tree::Bias;
|
||||
|
||||
#[derive(Clone, Copy, Eq, PartialEq, Debug, Hash)]
|
||||
pub struct Anchor {
|
||||
pub buffer_id: Option<u64>,
|
||||
pub excerpt_id: ExcerptId,
|
||||
pub text_anchor: text::Anchor,
|
||||
}
|
||||
|
||||
impl Anchor {
|
||||
pub fn min() -> Self {
|
||||
Self {
|
||||
buffer_id: None,
|
||||
excerpt_id: ExcerptId::min(),
|
||||
text_anchor: text::Anchor::MIN,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn max() -> Self {
|
||||
Self {
|
||||
buffer_id: None,
|
||||
excerpt_id: ExcerptId::max(),
|
||||
text_anchor: text::Anchor::MAX,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn cmp(&self, other: &Anchor, snapshot: &MultiBufferSnapshot) -> Ordering {
|
||||
let excerpt_id_cmp = self.excerpt_id.cmp(&other.excerpt_id, snapshot);
|
||||
if excerpt_id_cmp.is_eq() {
|
||||
if self.excerpt_id == ExcerptId::min() || self.excerpt_id == ExcerptId::max() {
|
||||
Ordering::Equal
|
||||
} else if let Some(excerpt) = snapshot.excerpt(self.excerpt_id) {
|
||||
self.text_anchor.cmp(&other.text_anchor, &excerpt.buffer)
|
||||
} else {
|
||||
Ordering::Equal
|
||||
}
|
||||
} else {
|
||||
excerpt_id_cmp
|
||||
}
|
||||
}
|
||||
|
||||
pub fn bias(&self) -> Bias {
|
||||
self.text_anchor.bias
|
||||
}
|
||||
|
||||
pub fn bias_left(&self, snapshot: &MultiBufferSnapshot) -> Anchor {
|
||||
if self.text_anchor.bias != Bias::Left {
|
||||
if let Some(excerpt) = snapshot.excerpt(self.excerpt_id) {
|
||||
return Self {
|
||||
buffer_id: self.buffer_id,
|
||||
excerpt_id: self.excerpt_id.clone(),
|
||||
text_anchor: self.text_anchor.bias_left(&excerpt.buffer),
|
||||
};
|
||||
}
|
||||
}
|
||||
self.clone()
|
||||
}
|
||||
|
||||
pub fn bias_right(&self, snapshot: &MultiBufferSnapshot) -> Anchor {
|
||||
if self.text_anchor.bias != Bias::Right {
|
||||
if let Some(excerpt) = snapshot.excerpt(self.excerpt_id) {
|
||||
return Self {
|
||||
buffer_id: self.buffer_id,
|
||||
excerpt_id: self.excerpt_id.clone(),
|
||||
text_anchor: self.text_anchor.bias_right(&excerpt.buffer),
|
||||
};
|
||||
}
|
||||
}
|
||||
self.clone()
|
||||
}
|
||||
|
||||
pub fn summary<D>(&self, snapshot: &MultiBufferSnapshot) -> D
|
||||
where
|
||||
D: TextDimension + Ord + Sub<D, Output = D>,
|
||||
{
|
||||
snapshot.summary_for_anchor(self)
|
||||
}
|
||||
|
||||
pub fn is_valid(&self, snapshot: &MultiBufferSnapshot) -> bool {
|
||||
if *self == Anchor::min() || *self == Anchor::max() {
|
||||
true
|
||||
} else if let Some(excerpt) = snapshot.excerpt(self.excerpt_id) {
|
||||
excerpt.contains(self)
|
||||
&& (self.text_anchor == excerpt.range.context.start
|
||||
|| self.text_anchor == excerpt.range.context.end
|
||||
|| self.text_anchor.is_valid(&excerpt.buffer))
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ToOffset for Anchor {
|
||||
fn to_offset(&self, snapshot: &MultiBufferSnapshot) -> usize {
|
||||
self.summary(snapshot)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToOffsetUtf16 for Anchor {
|
||||
fn to_offset_utf16(&self, snapshot: &MultiBufferSnapshot) -> OffsetUtf16 {
|
||||
self.summary(snapshot)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToPoint for Anchor {
|
||||
fn to_point<'a>(&self, snapshot: &MultiBufferSnapshot) -> Point {
|
||||
self.summary(snapshot)
|
||||
}
|
||||
}
|
||||
|
||||
pub trait AnchorRangeExt {
|
||||
fn cmp(&self, b: &Range<Anchor>, buffer: &MultiBufferSnapshot) -> Ordering;
|
||||
fn to_offset(&self, content: &MultiBufferSnapshot) -> Range<usize>;
|
||||
fn to_point(&self, content: &MultiBufferSnapshot) -> Range<Point>;
|
||||
}
|
||||
|
||||
impl AnchorRangeExt for Range<Anchor> {
|
||||
fn cmp(&self, other: &Range<Anchor>, buffer: &MultiBufferSnapshot) -> Ordering {
|
||||
match self.start.cmp(&other.start, buffer) {
|
||||
Ordering::Equal => other.end.cmp(&self.end, buffer),
|
||||
ord => ord,
|
||||
}
|
||||
}
|
||||
|
||||
fn to_offset(&self, content: &MultiBufferSnapshot) -> Range<usize> {
|
||||
self.start.to_offset(content)..self.end.to_offset(content)
|
||||
}
|
||||
|
||||
fn to_point(&self, content: &MultiBufferSnapshot) -> Range<Point> {
|
||||
self.start.to_point(content)..self.end.to_point(content)
|
||||
}
|
||||
}
|
5386
crates/multi_buffer/src/multi_buffer.rs
Normal file
5386
crates/multi_buffer/src/multi_buffer.rs
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue