Port multi_buffer to gpui2 (#3193)

Release Notes:

- N/A
This commit is contained in:
Julia 2023-11-01 11:45:44 -04:00 committed by GitHub
commit b7625d81e8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 5658 additions and 1 deletions

47
Cargo.lock generated
View File

@ -5035,6 +5035,53 @@ dependencies = [
"workspace",
]
[[package]]
name = "multi_buffer2"
version = "0.1.0"
dependencies = [
"aho-corasick",
"anyhow",
"client2",
"clock",
"collections",
"convert_case 0.6.0",
"copilot2",
"ctor",
"env_logger 0.9.3",
"futures 0.3.28",
"git",
"gpui2",
"indoc",
"itertools 0.10.5",
"language2",
"lazy_static",
"log",
"lsp2",
"ordered-float 2.10.0",
"parking_lot 0.11.2",
"postage",
"project2",
"pulldown-cmark",
"rand 0.8.5",
"rich_text",
"schemars",
"serde",
"serde_derive",
"settings2",
"smallvec",
"smol",
"snippet",
"sum_tree",
"text",
"theme2",
"tree-sitter",
"tree-sitter-html",
"tree-sitter-rust",
"tree-sitter-typescript",
"unindent",
"util",
]
[[package]]
name = "multimap"
version = "0.8.3"

View File

@ -61,6 +61,7 @@ members = [
"crates/menu",
"crates/menu2",
"crates/multi_buffer",
"crates/multi_buffer2",
"crates/node_runtime",
"crates/notifications",
"crates/outline",

View File

@ -47,8 +47,8 @@ where
subscribers.remove(&subscriber_id);
if subscribers.is_empty() {
lock.subscribers.remove(&emitter_key);
return;
}
return;
}
// We didn't manage to remove the subscription, which means it was dropped

View File

@ -0,0 +1,78 @@
[package]
name = "multi_buffer2"
version = "0.1.0"
edition = "2021"
publish = false
[lib]
path = "src/multi_buffer2.rs"
doctest = false
[features]
test-support = [
"copilot2/test-support",
"text/test-support",
"language2/test-support",
"gpui2/test-support",
"util/test-support",
"tree-sitter-rust",
"tree-sitter-typescript"
]
[dependencies]
client2 = { path = "../client2" }
clock = { path = "../clock" }
collections = { path = "../collections" }
git = { path = "../git" }
gpui2 = { path = "../gpui2" }
language2 = { path = "../language2" }
lsp2 = { path = "../lsp2" }
rich_text = { path = "../rich_text" }
settings2 = { path = "../settings2" }
snippet = { path = "../snippet" }
sum_tree = { path = "../sum_tree" }
text = { path = "../text" }
theme2 = { path = "../theme2" }
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]
copilot2 = { path = "../copilot2", features = ["test-support"] }
text = { path = "../text", features = ["test-support"] }
language2 = { path = "../language2", features = ["test-support"] }
lsp2 = { path = "../lsp2", features = ["test-support"] }
gpui2 = { path = "../gpui2", features = ["test-support"] }
util = { path = "../util", features = ["test-support"] }
project2 = { path = "../project2", features = ["test-support"] }
settings2 = { path = "../settings2", 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

View File

@ -0,0 +1,138 @@
use super::{ExcerptId, MultiBufferSnapshot, ToOffset, ToOffsetUtf16, ToPoint};
use language2::{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)
}
}

File diff suppressed because it is too large Load Diff