mirror of
https://github.com/zed-industries/zed.git
synced 2024-11-07 20:39:04 +03:00
WIP
This commit is contained in:
parent
b0859d4265
commit
b51ae1f668
3
Cargo.lock
generated
3
Cargo.lock
generated
@ -2705,8 +2705,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "tree-sitter"
|
name = "tree-sitter"
|
||||||
version = "0.19.5"
|
version = "0.19.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "git+https://github.com/tree-sitter/tree-sitter?rev=8c3d1466ecae2a22a9625d1456ffaae84b13fd3e#8c3d1466ecae2a22a9625d1456ffaae84b13fd3e"
|
||||||
checksum = "ad726ec26496bf4c083fff0f43d4eb3a2ad1bba305323af5ff91383c0b6ecac0"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cc",
|
"cc",
|
||||||
"regex",
|
"regex",
|
||||||
|
@ -3,6 +3,7 @@ members = ["zed", "gpui", "gpui_macros", "fsevent", "scoped_pool"]
|
|||||||
|
|
||||||
[patch.crates-io]
|
[patch.crates-io]
|
||||||
async-task = {git = "https://github.com/zed-industries/async-task", rev = "341b57d6de98cdfd7b418567b8de2022ca993a6e"}
|
async-task = {git = "https://github.com/zed-industries/async-task", rev = "341b57d6de98cdfd7b418567b8de2022ca993a6e"}
|
||||||
|
tree-sitter = {git = "https://github.com/tree-sitter/tree-sitter", rev = "8c3d1466ecae2a22a9625d1456ffaae84b13fd3e"}
|
||||||
|
|
||||||
# TODO - Remove when a version is released with this PR: https://github.com/servo/core-foundation-rs/pull/457
|
# TODO - Remove when a version is released with this PR: https://github.com/servo/core-foundation-rs/pull/457
|
||||||
cocoa = {git = "https://github.com/servo/core-foundation-rs", rev = "025dcb3c0d1ef01530f57ef65f3b1deb948f5737"}
|
cocoa = {git = "https://github.com/servo/core-foundation-rs", rev = "025dcb3c0d1ef01530f57ef65f3b1deb948f5737"}
|
||||||
|
@ -4,13 +4,12 @@ pub mod rope;
|
|||||||
mod selection;
|
mod selection;
|
||||||
|
|
||||||
pub use anchor::*;
|
pub use anchor::*;
|
||||||
use parking_lot::Mutex;
|
|
||||||
pub use point::*;
|
pub use point::*;
|
||||||
pub use rope::{ChunksIter, Rope, TextSummary};
|
pub use rope::{ChunksIter, Rope, TextSummary};
|
||||||
use seahash::SeaHasher;
|
use seahash::SeaHasher;
|
||||||
pub use selection::*;
|
pub use selection::*;
|
||||||
use similar::{ChangeTag, TextDiff};
|
use similar::{ChangeTag, TextDiff};
|
||||||
use tree_sitter::{InputEdit, Parser};
|
use tree_sitter::{InputEdit, Parser, QueryCursor};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
editor::Bias,
|
editor::Bias,
|
||||||
@ -77,9 +76,10 @@ pub struct Buffer {
|
|||||||
history: History,
|
history: History,
|
||||||
file: Option<FileHandle>,
|
file: Option<FileHandle>,
|
||||||
language: Option<Arc<Language>>,
|
language: Option<Arc<Language>>,
|
||||||
tree: Mutex<Option<(Tree, time::Global)>>,
|
tree: Option<(Tree, time::Global)>,
|
||||||
is_parsing: bool,
|
is_parsing: bool,
|
||||||
selections: HashMap<SelectionSetId, Arc<[Selection]>>,
|
selections: HashMap<SelectionSetId, Arc<[Selection]>>,
|
||||||
|
cursor: QueryCursor,
|
||||||
pub selections_last_update: SelectionsVersion,
|
pub selections_last_update: SelectionsVersion,
|
||||||
deferred_ops: OperationQueue<Operation>,
|
deferred_ops: OperationQueue<Operation>,
|
||||||
deferred_replicas: HashSet<ReplicaId>,
|
deferred_replicas: HashSet<ReplicaId>,
|
||||||
@ -487,8 +487,9 @@ impl Buffer {
|
|||||||
undo_map: Default::default(),
|
undo_map: Default::default(),
|
||||||
history,
|
history,
|
||||||
file,
|
file,
|
||||||
tree: Mutex::new(None),
|
tree: None,
|
||||||
is_parsing: false,
|
is_parsing: false,
|
||||||
|
cursor: QueryCursor::new(),
|
||||||
language,
|
language,
|
||||||
saved_mtime,
|
saved_mtime,
|
||||||
selections: HashMap::default(),
|
selections: HashMap::default(),
|
||||||
@ -549,8 +550,8 @@ impl Buffer {
|
|||||||
ctx.emit(Event::Saved);
|
ctx.emit(Event::Saved);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn syntax_tree(&self) -> Option<Tree> {
|
pub fn syntax_tree(&mut self) -> Option<Tree> {
|
||||||
if let Some((tree, tree_version)) = self.tree.lock().as_mut() {
|
if let Some((mut tree, tree_version)) = self.tree.take() {
|
||||||
let mut delta = 0_isize;
|
let mut delta = 0_isize;
|
||||||
for Edit {
|
for Edit {
|
||||||
old_range,
|
old_range,
|
||||||
@ -572,8 +573,9 @@ impl Buffer {
|
|||||||
});
|
});
|
||||||
delta += new_bytes as isize - old_bytes as isize;
|
delta += new_bytes as isize - old_bytes as isize;
|
||||||
}
|
}
|
||||||
*tree_version = self.version();
|
let result = tree.clone();
|
||||||
Some(tree.clone())
|
self.tree = Some((tree, self.version()));
|
||||||
|
Some(result)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
@ -581,7 +583,6 @@ impl Buffer {
|
|||||||
|
|
||||||
fn should_reparse(&self) -> bool {
|
fn should_reparse(&self) -> bool {
|
||||||
self.tree
|
self.tree
|
||||||
.lock()
|
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map_or(true, |(_, tree_version)| *tree_version != self.version)
|
.map_or(true, |(_, tree_version)| *tree_version != self.version)
|
||||||
}
|
}
|
||||||
@ -613,7 +614,7 @@ impl Buffer {
|
|||||||
.await;
|
.await;
|
||||||
|
|
||||||
handle.update(&mut ctx, |this, ctx| {
|
handle.update(&mut ctx, |this, ctx| {
|
||||||
*this.tree.lock() = Some((new_tree, new_version));
|
this.tree = Some((new_tree, new_version));
|
||||||
ctx.emit(Event::Reparsed);
|
ctx.emit(Event::Reparsed);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -750,6 +751,36 @@ impl Buffer {
|
|||||||
self.visible_text.chunks_in_range(start..end)
|
self.visible_text.chunks_in_range(start..end)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn highlighted_text_for_range<'a, T: ToOffset>(
|
||||||
|
&'a mut self,
|
||||||
|
range: Range<T>,
|
||||||
|
) -> impl Iterator<Item = (&'a str, usize)> {
|
||||||
|
if let (Some(language), Some((tree, _))) = (&self.language, self.tree.as_ref()) {
|
||||||
|
let visible_text = &self.visible_text;
|
||||||
|
let start = range.start.to_offset(self);
|
||||||
|
let end = range.end.to_offset(self);
|
||||||
|
self.cursor.set_byte_range(start, end);
|
||||||
|
let chunks = self.visible_text.chunks_in_range(start..end);
|
||||||
|
let captures = self.cursor.captures(
|
||||||
|
&language.highlight_query,
|
||||||
|
tree.root_node(),
|
||||||
|
move |node: tree_sitter::Node| {
|
||||||
|
visible_text
|
||||||
|
.chunks_in_range(node.byte_range())
|
||||||
|
.map(str::as_bytes)
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
HighlightedChunksIter {
|
||||||
|
captures,
|
||||||
|
chunks,
|
||||||
|
stack: Default::default(),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn chars(&self) -> impl Iterator<Item = char> + '_ {
|
pub fn chars(&self) -> impl Iterator<Item = char> + '_ {
|
||||||
self.chars_at(0)
|
self.chars_at(0)
|
||||||
}
|
}
|
||||||
@ -2003,8 +2034,9 @@ impl Clone for Buffer {
|
|||||||
selections_last_update: self.selections_last_update.clone(),
|
selections_last_update: self.selections_last_update.clone(),
|
||||||
deferred_ops: self.deferred_ops.clone(),
|
deferred_ops: self.deferred_ops.clone(),
|
||||||
file: self.file.clone(),
|
file: self.file.clone(),
|
||||||
|
cursor: tree_sitter::QueryCursor::new(),
|
||||||
language: self.language.clone(),
|
language: self.language.clone(),
|
||||||
tree: Mutex::new(self.tree.lock().clone()),
|
tree: self.tree.clone(),
|
||||||
is_parsing: false,
|
is_parsing: false,
|
||||||
deferred_replicas: self.deferred_replicas.clone(),
|
deferred_replicas: self.deferred_replicas.clone(),
|
||||||
replica_id: self.replica_id,
|
replica_id: self.replica_id,
|
||||||
@ -2135,6 +2167,25 @@ impl<'a, F: Fn(&FragmentSummary) -> bool> Iterator for Edits<'a, F> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct HighlightedChunksIter<'a, T: tree_sitter::TextProvider<'a>> {
|
||||||
|
chunks: ChunksIter<'a>,
|
||||||
|
captures: tree_sitter::QueryCaptures<'a, 'a, T>,
|
||||||
|
stack: Vec<(usize, usize)>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, T: tree_sitter::TextProvider<'a>> Iterator for HighlightedChunksIter<'a, T> {
|
||||||
|
type Item = (&'a str, usize);
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
if let Some((mat, capture_ix)) = self.captures.next() {
|
||||||
|
let capture = mat.captures[capture_ix as usize];
|
||||||
|
let range = capture.node.range();
|
||||||
|
}
|
||||||
|
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Ord, PartialOrd, Eq, PartialEq, Clone, Debug)]
|
#[derive(Ord, PartialOrd, Eq, PartialEq, Clone, Debug)]
|
||||||
struct FragmentId(Arc<[u16]>);
|
struct FragmentId(Arc<[u16]>);
|
||||||
|
|
||||||
@ -3276,7 +3327,7 @@ mod tests {
|
|||||||
|
|
||||||
let buffer = Buffer::from_history(0, History::new(text.into()), None, rust_lang, ctx);
|
let buffer = Buffer::from_history(0, History::new(text.into()), None, rust_lang, ctx);
|
||||||
assert!(buffer.is_parsing);
|
assert!(buffer.is_parsing);
|
||||||
assert!(buffer.syntax_tree().is_none());
|
assert!(buffer.tree.is_none());
|
||||||
buffer
|
buffer
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -3390,7 +3441,7 @@ mod tests {
|
|||||||
|
|
||||||
fn get_tree_sexp(buffer: &ModelHandle<Buffer>, ctx: &gpui::TestAppContext) -> String {
|
fn get_tree_sexp(buffer: &ModelHandle<Buffer>, ctx: &gpui::TestAppContext) -> String {
|
||||||
buffer.read_with(ctx, |buffer, _| {
|
buffer.read_with(ctx, |buffer, _| {
|
||||||
buffer.syntax_tree().unwrap().root_node().to_sexp()
|
buffer.tree.as_ref().unwrap().0.root_node().to_sexp()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user