diff --git a/Cargo.lock b/Cargo.lock index 408758f7ad..ebf2d4376c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1045,6 +1045,7 @@ dependencies = [ "editor", "env_logger", "envy", + "fs", "futures", "git", "gpui", @@ -1060,6 +1061,7 @@ dependencies = [ "prometheus", "rand 0.8.5", "reqwest", + "rope", "rpc", "scrypt", "serde", @@ -1551,6 +1553,7 @@ dependencies = [ "language", "postage", "project", + "rope", "serde_json", "settings", "smallvec", @@ -1704,6 +1707,7 @@ dependencies = [ "postage", "project", "rand 0.8.5", + "rope", "rpc", "serde", "settings", @@ -1993,10 +1997,18 @@ dependencies = [ "collections", "fsevent", "futures", - "git", + "git2", + "gpui", + "lazy_static", + "libc", + "log", + "lsp", "parking_lot 0.11.2", + "regex", + "rope", + "serde", + "serde_json", "smol", - "text", "util", ] @@ -2250,6 +2262,7 @@ dependencies = [ "lazy_static", "log", "parking_lot 0.11.2", + "rope", "smol", "sum_tree", "text", @@ -2297,6 +2310,7 @@ dependencies = [ "gpui", "menu", "postage", + "rope", "settings", "text", "workspace", @@ -2884,6 +2898,7 @@ dependencies = [ "collections", "ctor", "env_logger", + "fs", "futures", "fuzzy", "git", @@ -2895,6 +2910,7 @@ dependencies = [ "postage", "rand 0.8.5", "regex", + "rope", "rpc", "serde", "serde_json", @@ -4028,6 +4044,7 @@ dependencies = [ "clock", "collections", "db", + "fs", "fsevent", "futures", "fuzzy", @@ -4036,7 +4053,6 @@ dependencies = [ "ignore", "language", "lazy_static", - "libc", "log", "lsp", "parking_lot 0.11.2", @@ -4045,6 +4061,7 @@ dependencies = [ "rand 0.8.5", "regex", "rocksdb", + "rope", "rpc", "serde", "serde_json", @@ -4531,6 +4548,20 @@ dependencies = [ "librocksdb-sys", ] +[[package]] +name = "rope" +version = "0.1.0" +dependencies = [ + "arrayvec 0.7.2", + "bromberg_sl2", + "gpui", + "log", + "rand 0.8.5", + "smallvec", + "sum_tree", + "util", +] + [[package]] name = "roxmltree" version = "0.14.1" @@ -5588,13 +5619,12 @@ name = "text" version = "0.1.0" dependencies = [ "anyhow", - "arrayvec 0.7.2", - "bromberg_sl2", "clock", "collections", "ctor", "digest 0.9.0", "env_logger", + "fs", "gpui", "lazy_static", "log", @@ -5602,6 +5632,7 @@ dependencies = [ "postage", "rand 0.8.5", "regex", + "rope", "smallvec", "sum_tree", "util", @@ -6504,6 +6535,7 @@ dependencies = [ "language", "log", "project", + "rope", "search", "serde", "settings", @@ -7192,6 +7224,7 @@ dependencies = [ "collections", "context_menu", "drag_and_drop", + "fs", "futures", "gpui", "language", @@ -7275,6 +7308,7 @@ dependencies = [ "editor", "env_logger", "file_finder", + "fs", "fsevent", "futures", "fuzzy", diff --git a/Cargo.toml b/Cargo.toml index b64df300c0..8d2a3fcc40 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,6 +6,7 @@ resolver = "2" [workspace.dependencies] serde = { version = "1.0", features = ["derive", "rc"] } serde_json = { version = "1.0", features = ["preserve_order", "raw_value"] } +rand = { version = "0.8" } [patch.crates-io] tree-sitter = { git = "https://github.com/tree-sitter/tree-sitter", rev = "366210ae925d7ea0891bc7a0c738f60c77c04d7b" } diff --git a/crates/collab/Cargo.toml b/crates/collab/Cargo.toml index 840199c2bb..cf6b7f8b68 100644 --- a/crates/collab/Cargo.toml +++ b/crates/collab/Cargo.toml @@ -16,7 +16,8 @@ required-features = ["seed-support"] collections = { path = "../collections" } rpc = { path = "../rpc" } util = { path = "../util" } - +fs = { path = "../fs" } +rope = { path = "../rope" } anyhow = "1.0.40" async-trait = "0.1.50" async-tungstenite = "0.16" diff --git a/crates/collab/src/integration_tests.rs b/crates/collab/src/integration_tests.rs index bdd240fda8..a0a6f5feea 100644 --- a/crates/collab/src/integration_tests.rs +++ b/crates/collab/src/integration_tests.rs @@ -15,6 +15,7 @@ use editor::{ self, ConfirmCodeAction, ConfirmCompletion, ConfirmRename, Editor, Redo, Rename, ToOffset, ToggleCodeActions, Undo, }; +use fs::{FakeFs, Fs as _, LineEnding}; use futures::{channel::mpsc, Future, StreamExt as _}; use gpui::{ executor::{self, Deterministic}, @@ -24,17 +25,16 @@ use gpui::{ }; use language::{ range_to_lsp, tree_sitter_rust, Diagnostic, DiagnosticEntry, FakeLspAdapter, Language, - LanguageConfig, LanguageRegistry, LineEnding, OffsetRangeExt, Point, Rope, + LanguageConfig, LanguageRegistry, OffsetRangeExt, Rope, }; use lsp::{self, FakeLanguageServer}; use parking_lot::Mutex; use project::{ - fs::{FakeFs, Fs as _}, - search::SearchQuery, - worktree::WorktreeHandle, - DiagnosticSummary, Project, ProjectPath, ProjectStore, WorktreeId, + search::SearchQuery, worktree::WorktreeHandle, DiagnosticSummary, Project, ProjectPath, + ProjectStore, WorktreeId, }; use rand::prelude::*; +use rope::point::Point; use rpc::PeerId; use serde_json::json; use settings::{Formatter, Settings}; diff --git a/crates/diagnostics/Cargo.toml b/crates/diagnostics/Cargo.toml index 616f69117f..c4b851917e 100644 --- a/crates/diagnostics/Cargo.toml +++ b/crates/diagnostics/Cargo.toml @@ -15,6 +15,7 @@ editor = { path = "../editor" } language = { path = "../language" } gpui = { path = "../gpui" } project = { path = "../project" } +rope = { path = "../rope" } settings = { path = "../settings" } theme = { path = "../theme" } util = { path = "../util" } diff --git a/crates/diagnostics/src/diagnostics.rs b/crates/diagnostics/src/diagnostics.rs index 3111d7a9f1..608b333d0d 100644 --- a/crates/diagnostics/src/diagnostics.rs +++ b/crates/diagnostics/src/diagnostics.rs @@ -14,10 +14,10 @@ use gpui::{ ViewHandle, WeakViewHandle, }; use language::{ - Anchor, Bias, Buffer, Diagnostic, DiagnosticEntry, DiagnosticSeverity, Point, Selection, - SelectionGoal, + Anchor, Bias, Buffer, Diagnostic, DiagnosticEntry, DiagnosticSeverity, Selection, SelectionGoal, }; use project::{DiagnosticSummary, Project, ProjectPath}; +use rope::point::Point; use serde_json::json; use settings::Settings; use smallvec::SmallVec; @@ -738,7 +738,8 @@ mod tests { DisplayPoint, }; use gpui::TestAppContext; - use language::{Diagnostic, DiagnosticEntry, DiagnosticSeverity, PointUtf16}; + use language::{Diagnostic, DiagnosticEntry, DiagnosticSeverity}; + use rope::point_utf16::PointUtf16; use serde_json::json; use unindent::Unindent as _; use workspace::AppState; diff --git a/crates/editor/Cargo.toml b/crates/editor/Cargo.toml index db634376d0..4e0a10b70d 100644 --- a/crates/editor/Cargo.toml +++ b/crates/editor/Cargo.toml @@ -30,6 +30,7 @@ gpui = { path = "../gpui" } language = { path = "../language" } lsp = { path = "../lsp" } project = { path = "../project" } +rope = { path = "../rope" } rpc = { path = "../rpc" } settings = { path = "../settings" } snippet = { path = "../snippet" } diff --git a/crates/editor/src/display_map.rs b/crates/editor/src/display_map.rs index 58fc2e4fe7..525af0d599 100644 --- a/crates/editor/src/display_map.rs +++ b/crates/editor/src/display_map.rs @@ -11,7 +11,8 @@ use gpui::{ fonts::{FontId, HighlightStyle}, Entity, ModelContext, ModelHandle, }; -use language::{OffsetUtf16, Point, Subscription as BufferSubscription}; +use language::Subscription as BufferSubscription; +use rope::{offset_utf16::OffsetUtf16, point::Point}; use settings::Settings; use std::{any::TypeId, fmt::Debug, num::NonZeroU32, ops::Range, sync::Arc}; use sum_tree::{Bias, TreeMap}; @@ -565,7 +566,7 @@ pub mod tests { use super::*; use crate::{movement, test::marked_display_snapshot}; use gpui::{color::Color, elements::*, test::observe, MutableAppContext}; - use language::{Buffer, Language, LanguageConfig, RandomCharIter, SelectionGoal}; + use language::{Buffer, Language, LanguageConfig, SelectionGoal}; use rand::{prelude::*, Rng}; use smol::stream::StreamExt; use std::{env, sync::Arc}; @@ -609,7 +610,9 @@ pub mod tests { let buffer = cx.update(|cx| { if rng.gen() { let len = rng.gen_range(0..10); - let text = RandomCharIter::new(&mut rng).take(len).collect::(); + let text = util::RandomCharIter::new(&mut rng) + .take(len) + .collect::(); MultiBuffer::build_simple(&text, cx) } else { MultiBuffer::build_random(&mut rng, cx) diff --git a/crates/editor/src/display_map/block_map.rs b/crates/editor/src/display_map/block_map.rs index 210daccac2..f0f2720f1a 100644 --- a/crates/editor/src/display_map/block_map.rs +++ b/crates/editor/src/display_map/block_map.rs @@ -7,6 +7,7 @@ use collections::{Bound, HashMap, HashSet}; use gpui::{ElementBox, RenderContext}; use language::{BufferSnapshot, Chunk, Patch}; use parking_lot::Mutex; +use rope::point::Point; use std::{ cell::RefCell, cmp::{self, Ordering}, @@ -18,7 +19,7 @@ use std::{ }, }; use sum_tree::{Bias, SumTree}; -use text::{Edit, Point}; +use text::Edit; const NEWLINES: &[u8] = &[b'\n'; u8::MAX as usize]; @@ -42,7 +43,7 @@ pub struct BlockSnapshot { pub struct BlockId(usize); #[derive(Copy, Clone, Debug, Default, Eq, Ord, PartialOrd, PartialEq)] -pub struct BlockPoint(pub super::Point); +pub struct BlockPoint(pub Point); #[derive(Copy, Clone, Debug, Default, Eq, Ord, PartialOrd, PartialEq)] struct BlockRow(u32); @@ -994,7 +995,7 @@ mod tests { use rand::prelude::*; use settings::Settings; use std::env; - use text::RandomCharIter; + use util::RandomCharIter; #[gpui::test] fn test_offset_for_row() { diff --git a/crates/editor/src/display_map/fold_map.rs b/crates/editor/src/display_map/fold_map.rs index c17cfa39f2..5bd1670542 100644 --- a/crates/editor/src/display_map/fold_map.rs +++ b/crates/editor/src/display_map/fold_map.rs @@ -5,8 +5,9 @@ use crate::{ }; use collections::BTreeMap; use gpui::fonts::HighlightStyle; -use language::{Chunk, Edit, Point, TextSummary}; +use language::{Chunk, Edit, TextSummary}; use parking_lot::Mutex; +use rope::point::Point; use std::{ any::TypeId, cmp::{self, Ordering}, @@ -18,11 +19,11 @@ use std::{ use sum_tree::{Bias, Cursor, FilterCursor, SumTree}; #[derive(Copy, Clone, Debug, Default, Eq, Ord, PartialOrd, PartialEq)] -pub struct FoldPoint(pub super::Point); +pub struct FoldPoint(pub Point); impl FoldPoint { pub fn new(row: u32, column: u32) -> Self { - Self(super::Point::new(row, column)) + Self(Point::new(row, column)) } pub fn row(self) -> u32 { @@ -1196,8 +1197,8 @@ mod tests { use settings::Settings; use std::{cmp::Reverse, env, mem, sync::Arc}; use sum_tree::TreeMap; - use text::RandomCharIter; use util::test::sample_text; + use util::RandomCharIter; use Bias::{Left, Right}; #[gpui::test] diff --git a/crates/editor/src/display_map/tab_map.rs b/crates/editor/src/display_map/tab_map.rs index 4d89767a19..b7d8fac770 100644 --- a/crates/editor/src/display_map/tab_map.rs +++ b/crates/editor/src/display_map/tab_map.rs @@ -3,11 +3,12 @@ use super::{ TextHighlights, }; use crate::MultiBufferSnapshot; -use language::{rope, Chunk}; +use language::Chunk; use parking_lot::Mutex; +use rope; +use rope::point::Point; use std::{cmp, mem, num::NonZeroU32, ops::Range}; use sum_tree::Bias; -use text::Point; pub struct TabMap(Mutex); @@ -332,11 +333,11 @@ impl TabSnapshot { } #[derive(Copy, Clone, Debug, Default, Eq, Ord, PartialOrd, PartialEq)] -pub struct TabPoint(pub super::Point); +pub struct TabPoint(pub Point); impl TabPoint { pub fn new(row: u32, column: u32) -> Self { - Self(super::Point::new(row, column)) + Self(Point::new(row, column)) } pub fn zero() -> Self { @@ -352,8 +353,8 @@ impl TabPoint { } } -impl From for TabPoint { - fn from(point: super::Point) -> Self { +impl From for TabPoint { + fn from(point: Point) -> Self { Self(point) } } @@ -362,7 +363,7 @@ pub type TabEdit = text::Edit; #[derive(Clone, Debug, Default, Eq, PartialEq)] pub struct TextSummary { - pub lines: super::Point, + pub lines: Point, pub first_line_chars: u32, pub last_line_chars: u32, pub longest_row: u32, @@ -485,7 +486,6 @@ mod tests { use super::*; use crate::{display_map::fold_map::FoldMap, MultiBuffer}; use rand::{prelude::StdRng, Rng}; - use text::{RandomCharIter, Rope}; #[test] fn test_expand_tabs() { @@ -508,7 +508,9 @@ mod tests { let tab_size = NonZeroU32::new(rng.gen_range(1..=4)).unwrap(); let len = rng.gen_range(0..30); let buffer = if rng.gen() { - let text = RandomCharIter::new(&mut rng).take(len).collect::(); + let text = util::RandomCharIter::new(&mut rng) + .take(len) + .collect::(); MultiBuffer::build_simple(&text, cx) } else { MultiBuffer::build_random(&mut rng, cx) @@ -522,7 +524,7 @@ mod tests { log::info!("FoldMap text: {:?}", folds_snapshot.text()); let (_, tabs_snapshot) = TabMap::new(folds_snapshot.clone(), tab_size); - let text = Rope::from(tabs_snapshot.text().as_str()); + let text = rope::Rope::from(tabs_snapshot.text().as_str()); log::info!( "TabMap text (tab size: {}): {:?}", tab_size, diff --git a/crates/editor/src/display_map/wrap_map.rs b/crates/editor/src/display_map/wrap_map.rs index ee6ce2860d..42156b905f 100644 --- a/crates/editor/src/display_map/wrap_map.rs +++ b/crates/editor/src/display_map/wrap_map.rs @@ -3,13 +3,14 @@ use super::{ tab_map::{self, TabEdit, TabPoint, TabSnapshot}, TextHighlights, }; -use crate::{MultiBufferSnapshot, Point}; +use crate::MultiBufferSnapshot; use gpui::{ fonts::FontId, text_layout::LineWrapper, Entity, ModelContext, ModelHandle, MutableAppContext, Task, }; use language::Chunk; use lazy_static::lazy_static; +use rope::point::Point; use smol::future::yield_now; use std::{cmp, collections::VecDeque, mem, ops::Range, time::Duration}; use sum_tree::{Bias, Cursor, SumTree}; @@ -52,7 +53,7 @@ struct TransformSummary { } #[derive(Copy, Clone, Debug, Default, Eq, Ord, PartialOrd, PartialEq)] -pub struct WrapPoint(pub super::Point); +pub struct WrapPoint(pub Point); pub struct WrapChunks<'a> { input_chunks: tab_map::TabChunks<'a>, @@ -959,7 +960,7 @@ impl SumTreeExt for SumTree { impl WrapPoint { pub fn new(row: u32, column: u32) -> Self { - Self(super::Point::new(row, column)) + Self(Point::new(row, column)) } pub fn row(self) -> u32 { @@ -1029,7 +1030,6 @@ mod tests { MultiBuffer, }; use gpui::test::observe; - use language::RandomCharIter; use rand::prelude::*; use settings::Settings; use smol::stream::StreamExt; @@ -1067,7 +1067,9 @@ mod tests { MultiBuffer::build_random(&mut rng, cx) } else { let len = rng.gen_range(0..10); - let text = RandomCharIter::new(&mut rng).take(len).collect::(); + let text = util::RandomCharIter::new(&mut rng) + .take(len) + .collect::(); MultiBuffer::build_simple(&text, cx) } }); diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index d1dfed3c85..5f424cd20b 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -43,8 +43,8 @@ pub use items::MAX_TAB_TITLE_LEN; pub use language::{char_kind, CharKind}; use language::{ AutoindentMode, BracketPair, Buffer, CodeAction, CodeLabel, Completion, Diagnostic, - DiagnosticSeverity, IndentKind, IndentSize, Language, OffsetRangeExt, OffsetUtf16, Point, - Selection, SelectionGoal, TransactionId, + DiagnosticSeverity, IndentKind, IndentSize, Language, OffsetRangeExt, Selection, SelectionGoal, + TransactionId, }; use link_go_to_definition::{hide_link_definition, LinkGoToDefinitionState}; pub use multi_buffer::{ @@ -54,6 +54,7 @@ pub use multi_buffer::{ use multi_buffer::{MultiBufferChunks, ToOffsetUtf16}; use ordered_float::OrderedFloat; use project::{FormatTrigger, LocationLink, Project, ProjectPath, ProjectTransaction}; +use rope::{offset_utf16::OffsetUtf16, point::Point}; use selections_collection::{resolve_multiple, MutableSelectionsCollection, SelectionsCollection}; use serde::{Deserialize, Serialize}; use settings::Settings; diff --git a/crates/editor/src/editor_tests.rs b/crates/editor/src/editor_tests.rs index 063dcf6098..e152c85e4e 100644 --- a/crates/editor/src/editor_tests.rs +++ b/crates/editor/src/editor_tests.rs @@ -11,9 +11,9 @@ use gpui::{ use indoc::indoc; use language::{FakeLspAdapter, LanguageConfig, LanguageRegistry}; use project::FakeFs; +use rope::point::Point; use settings::EditorSettings; use std::{cell::RefCell, rc::Rc, time::Instant}; -use text::Point; use unindent::Unindent; use util::{ assert_set_eq, diff --git a/crates/editor/src/element.rs b/crates/editor/src/element.rs index a3b5ad43f6..114a1d72c9 100644 --- a/crates/editor/src/element.rs +++ b/crates/editor/src/element.rs @@ -35,8 +35,9 @@ use gpui::{ WeakViewHandle, }; use json::json; -use language::{Bias, DiagnosticSeverity, OffsetUtf16, Selection}; +use language::{Bias, DiagnosticSeverity, Selection}; use project::ProjectPath; +use rope::offset_utf16::OffsetUtf16; use settings::{GitGutter, Settings}; use smallvec::SmallVec; use std::{ diff --git a/crates/editor/src/items.rs b/crates/editor/src/items.rs index c1082020e5..727ee1f094 100644 --- a/crates/editor/src/items.rs +++ b/crates/editor/src/items.rs @@ -11,6 +11,7 @@ use gpui::{ }; use language::{Bias, Buffer, File as _, OffsetRangeExt, SelectionGoal}; use project::{File, FormatTrigger, Project, ProjectEntryId, ProjectPath}; +use rope::point::Point; use rpc::proto::{self, update_view}; use settings::Settings; use smallvec::SmallVec; @@ -21,7 +22,7 @@ use std::{ ops::Range, path::{Path, PathBuf}, }; -use text::{Point, Selection}; +use text::Selection; use util::TryFutureExt; use workspace::{ searchable::{Direction, SearchEvent, SearchableItem, SearchableItemHandle}, diff --git a/crates/editor/src/movement.rs b/crates/editor/src/movement.rs index 0db5cc0812..79d041fbab 100644 --- a/crates/editor/src/movement.rs +++ b/crates/editor/src/movement.rs @@ -1,6 +1,7 @@ +use rope::point::Point; + use super::{Bias, DisplayPoint, DisplaySnapshot, SelectionGoal, ToDisplayPoint}; use crate::{char_kind, CharKind, ToPoint}; -use language::Point; use std::ops::Range; pub fn left(map: &DisplaySnapshot, mut point: DisplayPoint) -> DisplayPoint { @@ -273,7 +274,7 @@ pub fn surrounding_word(map: &DisplaySnapshot, position: DisplayPoint) -> Range< mod tests { use super::*; use crate::{test::marked_display_snapshot, Buffer, DisplayMap, ExcerptRange, MultiBuffer}; - use language::Point; + use rope::point::Point; use settings::Settings; #[gpui::test] diff --git a/crates/editor/src/multi_buffer.rs b/crates/editor/src/multi_buffer.rs index a0eedb850c..23ee7df657 100644 --- a/crates/editor/src/multi_buffer.rs +++ b/crates/editor/src/multi_buffer.rs @@ -12,6 +12,7 @@ use language::{ DiagnosticEntry, Event, File, IndentSize, Language, OffsetRangeExt, Outline, OutlineItem, Selection, ToOffset as _, ToOffsetUtf16 as _, ToPoint as _, ToPointUtf16 as _, TransactionId, }; +use rope::{offset_utf16::OffsetUtf16, point::Point, point_utf16::PointUtf16, TextDimension}; use smallvec::SmallVec; use std::{ borrow::Cow, @@ -27,9 +28,8 @@ use std::{ use sum_tree::{Bias, Cursor, SumTree}; use text::{ locator::Locator, - rope::TextDimension, subscription::{Subscription, Topic}, - Edit, OffsetUtf16, Point, PointUtf16, TextSummary, + Edit, TextSummary, }; use theme::SyntaxTheme; use util::post_inc; @@ -168,7 +168,7 @@ struct ExcerptChunks<'a> { } struct ExcerptBytes<'a> { - content_bytes: language::rope::Bytes<'a>, + content_bytes: rope::Bytes<'a>, footer_height: usize, } @@ -1412,7 +1412,7 @@ impl MultiBuffer { edit_count: usize, cx: &mut ModelContext, ) { - use text::RandomCharIter; + use util::RandomCharIter; let snapshot = self.read(cx); let mut edits: Vec<(Range, Arc)> = Vec::new(); @@ -1451,7 +1451,7 @@ impl MultiBuffer { ) { use rand::prelude::*; use std::env; - use text::RandomCharIter; + use util::RandomCharIter; let max_excerpts = env::var("MAX_EXCERPTS") .map(|i| i.parse().expect("invalid `MAX_EXCERPTS` variable")) @@ -3337,7 +3337,7 @@ mod tests { use rand::prelude::*; use settings::Settings; use std::{env, rc::Rc}; - use text::{Point, RandomCharIter}; + use util::test::sample_text; #[gpui::test] @@ -3955,7 +3955,9 @@ mod tests { } _ => { let buffer_handle = if buffers.is_empty() || rng.gen_bool(0.4) { - let base_text = RandomCharIter::new(&mut rng).take(10).collect::(); + let base_text = util::RandomCharIter::new(&mut rng) + .take(10) + .collect::(); buffers.push(cx.add_model(|cx| Buffer::new(0, base_text, cx))); buffers.last().unwrap() } else { diff --git a/crates/editor/src/multi_buffer/anchor.rs b/crates/editor/src/multi_buffer/anchor.rs index cb8a1692b9..b30e4b5780 100644 --- a/crates/editor/src/multi_buffer/anchor.rs +++ b/crates/editor/src/multi_buffer/anchor.rs @@ -1,10 +1,10 @@ use super::{ExcerptId, MultiBufferSnapshot, ToOffset, ToOffsetUtf16, ToPoint}; +use rope::{offset_utf16::OffsetUtf16, point::Point, TextDimension}; use std::{ cmp::Ordering, ops::{Range, Sub}, }; use sum_tree::Bias; -use text::{rope::TextDimension, OffsetUtf16, Point}; #[derive(Clone, Eq, PartialEq, Debug, Hash)] pub struct Anchor { diff --git a/crates/editor/src/selections_collection.rs b/crates/editor/src/selections_collection.rs index 9d6450f8ec..ed983d22d9 100644 --- a/crates/editor/src/selections_collection.rs +++ b/crates/editor/src/selections_collection.rs @@ -8,7 +8,8 @@ use std::{ use collections::HashMap; use gpui::{AppContext, ModelHandle, MutableAppContext}; use itertools::Itertools; -use language::{rope::TextDimension, Bias, Point, Selection, SelectionGoal, ToPoint}; +use language::{Bias, Selection, SelectionGoal, ToPoint}; +use rope::{point::Point, TextDimension}; use util::post_inc; use crate::{ diff --git a/crates/fs/Cargo.toml b/crates/fs/Cargo.toml index 1a4e325fa4..182d13894d 100644 --- a/crates/fs/Cargo.toml +++ b/crates/fs/Cargo.toml @@ -8,11 +8,23 @@ path = "src/fs.rs" [dependencies] collections = { path = "../collections" } -fsevent = { path = "../fsevent" } +gpui = { path = "../gpui" } +lsp = { path = "../lsp" } +rope = { path = "../rope" } +util = { path = "../util" } anyhow = "1.0.57" async-trait = "0.1" futures = "0.3" +fsevent = { path = "../fsevent" } +lazy_static = "1.4.0" parking_lot = "0.11.1" smol = "1.2.5" -text = { path = "../text" } -util = { path = "../util" } +regex = "1.5" +git2 = { version = "0.15", default-features = false } +serde = { workspace = true } +serde_json = { workspace = true } +log = { version = "0.4.16", features = ["kv_unstable_serde"] } +libc = "0.2" + +[features] +test-support = [] diff --git a/crates/fs/src/fs.rs b/crates/fs/src/fs.rs index c24387844c..26045f2776 100644 --- a/crates/fs/src/fs.rs +++ b/crates/fs/src/fs.rs @@ -3,8 +3,15 @@ pub mod repository; use anyhow::{anyhow, Result}; use fsevent::EventStream; use futures::{future::BoxFuture, Stream, StreamExt}; +use git2::Repository as LibGitRepository; +use lazy_static::lazy_static; use parking_lot::Mutex as SyncMutex; +use regex::Regex; +use repository::GitRepository; +use rope::Rope; use smol::io::{AsyncReadExt, AsyncWriteExt}; +use std::borrow::Cow; +use std::cmp; use std::sync::Arc; use std::{ io, @@ -13,7 +20,6 @@ use std::{ pin::Pin, time::{Duration, SystemTime}, }; -use text::Rope; use util::ResultExt; #[cfg(any(test, feature = "test-support"))] @@ -21,10 +27,14 @@ use collections::{btree_map, BTreeMap}; #[cfg(any(test, feature = "test-support"))] use futures::lock::Mutex; #[cfg(any(test, feature = "test-support"))] -use git::repository::FakeGitRepositoryState; +use repository::FakeGitRepositoryState; #[cfg(any(test, feature = "test-support"))] use std::sync::Weak; +lazy_static! { + static ref CARRIAGE_RETURNS_REGEX: Regex = Regex::new("\r\n|\r").unwrap(); +} + #[derive(Clone, Copy, Debug, PartialEq)] pub enum LineEnding { Unix, @@ -72,7 +82,7 @@ impl LineEnding { } } - fn normalize_arc(text: Arc) -> Arc { + pub fn normalize_arc(text: Arc) -> Arc { if let Cow::Owned(replaced) = CARRIAGE_RETURNS_REGEX.replace_all(&text, "\n") { replaced.into() } else { @@ -141,6 +151,33 @@ pub struct Metadata { pub is_dir: bool, } +impl From for CreateOptions { + fn from(options: lsp::CreateFileOptions) -> Self { + Self { + overwrite: options.overwrite.unwrap_or(false), + ignore_if_exists: options.ignore_if_exists.unwrap_or(false), + } + } +} + +impl From for RenameOptions { + fn from(options: lsp::RenameFileOptions) -> Self { + Self { + overwrite: options.overwrite.unwrap_or(false), + ignore_if_exists: options.ignore_if_exists.unwrap_or(false), + } + } +} + +impl From for RemoveOptions { + fn from(options: lsp::DeleteFileOptions) -> Self { + Self { + recursive: options.recursive.unwrap_or(false), + ignore_if_not_exists: options.ignore_if_not_exists.unwrap_or(false), + } + } +} + pub struct RealFs; #[async_trait::async_trait] @@ -340,7 +377,7 @@ enum FakeFsEntry { inode: u64, mtime: SystemTime, entries: BTreeMap>>, - git_repo_state: Option>>, + git_repo_state: Option>>, }, Symlink { target: PathBuf, @@ -952,7 +989,7 @@ impl Fs for FakeFs { Arc::new(SyncMutex::new(FakeGitRepositoryState::default())) }) .clone(); - Some(git::repository::FakeGitRepository::open(state)) + Some(repository::FakeGitRepository::open(state)) } else { None } diff --git a/crates/git/Cargo.toml b/crates/git/Cargo.toml index b8f3aac0b9..1d15c2b123 100644 --- a/crates/git/Cargo.toml +++ b/crates/git/Cargo.toml @@ -9,7 +9,7 @@ path = "src/git.rs" [dependencies] anyhow = "1.0.38" clock = { path = "../clock" } -git2 = { version = "0.15", default-features = false } +rope = { path = "../rope" } lazy_static = "1.4.0" sum_tree = { path = "../sum_tree" } text = { path = "../text" } @@ -20,6 +20,7 @@ smol = "1.2" parking_lot = "0.11.1" async-trait = "0.1" futures = "0.3" +git2 = { version = "0.15", default-features = false } [dev-dependencies] unindent = "0.1.7" diff --git a/crates/git/src/diff.rs b/crates/git/src/diff.rs index 4191e5d260..7f3f6101ce 100644 --- a/crates/git/src/diff.rs +++ b/crates/git/src/diff.rs @@ -1,7 +1,8 @@ use std::ops::Range; +use rope::point::Point; use sum_tree::SumTree; -use text::{Anchor, BufferSnapshot, OffsetRangeExt, Point}; +use text::{Anchor, BufferSnapshot, OffsetRangeExt}; pub use git2 as libgit; use libgit::{DiffLineType as GitDiffLineType, DiffOptions as GitOptions, Patch as GitPatch}; diff --git a/crates/git/src/git.rs b/crates/git/src/git.rs index 36f54e706a..b1b885eca2 100644 --- a/crates/git/src/git.rs +++ b/crates/git/src/git.rs @@ -4,7 +4,6 @@ pub use git2 as libgit; pub use lazy_static::lazy_static; pub mod diff; -pub mod repository; lazy_static! { pub static ref DOT_GIT: &'static OsStr = OsStr::new(".git"); diff --git a/crates/go_to_line/Cargo.toml b/crates/go_to_line/Cargo.toml index 93ae96f93e..d69b1f239c 100644 --- a/crates/go_to_line/Cargo.toml +++ b/crates/go_to_line/Cargo.toml @@ -13,5 +13,6 @@ gpui = { path = "../gpui" } menu = { path = "../menu" } settings = { path = "../settings" } text = { path = "../text" } +rope = { path = "../rope" } workspace = { path = "../workspace" } postage = { version = "0.4", features = ["futures-traits"] } diff --git a/crates/go_to_line/src/go_to_line.rs b/crates/go_to_line/src/go_to_line.rs index 3ca50cee42..51ff87a943 100644 --- a/crates/go_to_line/src/go_to_line.rs +++ b/crates/go_to_line/src/go_to_line.rs @@ -4,8 +4,9 @@ use gpui::{ MutableAppContext, RenderContext, View, ViewContext, ViewHandle, }; use menu::{Cancel, Confirm}; +use rope::point::Point; use settings::Settings; -use text::{Bias, Point}; +use text::Bias; use workspace::Workspace; actions!(go_to_line, [Toggle]); diff --git a/crates/language/Cargo.toml b/crates/language/Cargo.toml index e5b6f4c79b..54d2147929 100644 --- a/crates/language/Cargo.toml +++ b/crates/language/Cargo.toml @@ -25,9 +25,11 @@ client = { path = "../client" } clock = { path = "../clock" } collections = { path = "../collections" } fuzzy = { path = "../fuzzy" } +fs = { path = "../fs" } git = { path = "../git" } gpui = { path = "../gpui" } lsp = { path = "../lsp" } +rope = { path = "../rope" } rpc = { path = "../rpc" } settings = { path = "../settings" } sum_tree = { path = "../sum_tree" } diff --git a/crates/language/src/buffer.rs b/crates/language/src/buffer.rs index a3c0c54d01..56aad18ead 100644 --- a/crates/language/src/buffer.rs +++ b/crates/language/src/buffer.rs @@ -13,9 +13,11 @@ use crate::{ }; use anyhow::{anyhow, Result}; use clock::ReplicaId; +use fs::LineEnding; use futures::FutureExt as _; use gpui::{fonts::HighlightStyle, AppContext, Entity, ModelContext, MutableAppContext, Task}; use parking_lot::Mutex; +use rope::point::Point; use settings::Settings; use similar::{ChangeTag, TextDiff}; use smol::future::yield_now; @@ -38,7 +40,7 @@ use sum_tree::TreeMap; use text::operation_queue::OperationQueue; pub use text::{Buffer as TextBuffer, BufferSnapshot as TextBufferSnapshot, Operation as _, *}; use theme::SyntaxTheme; -use util::TryFutureExt as _; +use util::{RandomCharIter, TryFutureExt as _}; #[cfg(any(test, feature = "test-support"))] pub use {tree_sitter_rust, tree_sitter_typescript}; @@ -368,7 +370,7 @@ impl Buffer { file, ); this.text.set_line_ending(proto::deserialize_line_ending( - proto::LineEnding::from_i32(message.line_ending) + rpc::proto::LineEnding::from_i32(message.line_ending) .ok_or_else(|| anyhow!("missing line_ending"))?, )); Ok(this) @@ -1633,9 +1635,7 @@ impl Buffer { last_end = Some(range.end); let new_text_len = rng.gen_range(0..10); - let new_text: String = crate::random_char_iter::RandomCharIter::new(&mut *rng) - .take(new_text_len) - .collect(); + let new_text: String = RandomCharIter::new(&mut *rng).take(new_text_len).collect(); edits.push((range, new_text)); } diff --git a/crates/language/src/buffer_tests.rs b/crates/language/src/buffer_tests.rs index 3cfddce71f..313c843b02 100644 --- a/crates/language/src/buffer_tests.rs +++ b/crates/language/src/buffer_tests.rs @@ -1,9 +1,11 @@ use super::*; use clock::ReplicaId; use collections::BTreeMap; +use fs::LineEnding; use gpui::{ModelHandle, MutableAppContext}; use proto::deserialize_operation; use rand::prelude::*; +use rope::point::Point; use settings::Settings; use std::{ cell::RefCell, @@ -14,7 +16,7 @@ use std::{ }; use text::network::Network; use unindent::Unindent as _; -use util::{post_inc, test::marked_text_ranges}; +use util::{post_inc, test::marked_text_ranges, RandomCharIter}; #[cfg(test)] #[ctor::ctor] diff --git a/crates/language/src/diagnostic_set.rs b/crates/language/src/diagnostic_set.rs index b52327cac0..dfbc32149c 100644 --- a/crates/language/src/diagnostic_set.rs +++ b/crates/language/src/diagnostic_set.rs @@ -1,12 +1,13 @@ use crate::Diagnostic; use collections::HashMap; +use rope::point_utf16::PointUtf16; use std::{ cmp::{Ordering, Reverse}, iter, ops::Range, }; use sum_tree::{self, Bias, SumTree}; -use text::{Anchor, FromAnchor, PointUtf16, ToOffset}; +use text::{Anchor, FromAnchor, ToOffset}; #[derive(Clone, Debug, Default)] pub struct DiagnosticSet { diff --git a/crates/language/src/language.rs b/crates/language/src/language.rs index bb75edbc32..4f8615606c 100644 --- a/crates/language/src/language.rs +++ b/crates/language/src/language.rs @@ -22,6 +22,7 @@ use lazy_static::lazy_static; use parking_lot::{Mutex, RwLock}; use postage::watch; use regex::Regex; +use rope::point_utf16::PointUtf16; use serde::{de, Deserialize, Deserializer}; use serde_json::Value; use std::{ diff --git a/crates/language/src/proto.rs b/crates/language/src/proto.rs index fddfb7961f..9e3ee7d46b 100644 --- a/crates/language/src/proto.rs +++ b/crates/language/src/proto.rs @@ -8,19 +8,19 @@ use rpc::proto; use std::{ops::Range, sync::Arc}; use text::*; -pub use proto::{BufferState, LineEnding, Operation, SelectionSet}; +pub use proto::{BufferState, Operation, SelectionSet}; -pub fn deserialize_line_ending(message: proto::LineEnding) -> text::LineEnding { +pub fn deserialize_line_ending(message: proto::LineEnding) -> fs::LineEnding { match message { - LineEnding::Unix => text::LineEnding::Unix, - LineEnding::Windows => text::LineEnding::Windows, + proto::LineEnding::Unix => fs::LineEnding::Unix, + proto::LineEnding::Windows => fs::LineEnding::Windows, } } -pub fn serialize_line_ending(message: text::LineEnding) -> proto::LineEnding { +pub fn serialize_line_ending(message: fs::LineEnding) -> proto::LineEnding { match message { - text::LineEnding::Unix => proto::LineEnding::Unix, - text::LineEnding::Windows => proto::LineEnding::Windows, + fs::LineEnding::Unix => proto::LineEnding::Unix, + fs::LineEnding::Windows => proto::LineEnding::Windows, } } diff --git a/crates/language/src/syntax_map.rs b/crates/language/src/syntax_map.rs index 64145e535b..3992d41081 100644 --- a/crates/language/src/syntax_map.rs +++ b/crates/language/src/syntax_map.rs @@ -1,6 +1,7 @@ use crate::{Grammar, InjectionConfig, Language, LanguageRegistry}; use lazy_static::lazy_static; use parking_lot::Mutex; +use rope::point::Point; use std::{ borrow::Cow, cell::RefCell, @@ -10,7 +11,7 @@ use std::{ sync::Arc, }; use sum_tree::{Bias, SeekTarget, SumTree}; -use text::{rope, Anchor, BufferSnapshot, OffsetRangeExt, Point, Rope, ToOffset, ToPoint}; +use text::{Anchor, BufferSnapshot, OffsetRangeExt, Rope, ToOffset, ToPoint}; use tree_sitter::{ Node, Parser, Query, QueryCapture, QueryCaptures, QueryCursor, QueryMatches, Tree, }; @@ -1242,7 +1243,7 @@ mod tests { use crate::LanguageConfig; use rand::rngs::StdRng; use std::env; - use text::{Buffer, Point}; + use text::Buffer; use unindent::Unindent as _; use util::test::marked_text_ranges; diff --git a/crates/project/Cargo.toml b/crates/project/Cargo.toml index 1e45e3c6ed..7a41318b86 100644 --- a/crates/project/Cargo.toml +++ b/crates/project/Cargo.toml @@ -22,12 +22,14 @@ client = { path = "../client" } clock = { path = "../clock" } collections = { path = "../collections" } db = { path = "../db" } +fs = { path = "../fs" } fsevent = { path = "../fsevent" } fuzzy = { path = "../fuzzy" } git = { path = "../git" } gpui = { path = "../gpui" } language = { path = "../language" } lsp = { path = "../lsp" } +rope = { path = "../rope" } rpc = { path = "../rpc" } settings = { path = "../settings" } sum_tree = { path = "../sum_tree" } @@ -38,7 +40,6 @@ async-trait = "0.1" futures = "0.3" ignore = "0.4" lazy_static = "1.4.0" -libc = "0.2" log = { version = "0.4.16", features = ["kv_unstable_serde"] } parking_lot = "0.11.1" postage = { version = "0.4.1", features = ["futures-traits"] } @@ -58,6 +59,7 @@ rocksdb = "0.18" client = { path = "../client", features = ["test-support"] } collections = { path = "../collections", features = ["test-support"] } db = { path = "../db", features = ["test-support"] } +fs = { path = "../fs", features = ["test-support"] } gpui = { path = "../gpui", features = ["test-support"] } language = { path = "../language", features = ["test-support"] } lsp = { path = "../lsp", features = ["test-support"] } diff --git a/crates/project/src/lsp_command.rs b/crates/project/src/lsp_command.rs index 37f6e76340..42098d2e8b 100644 --- a/crates/project/src/lsp_command.rs +++ b/crates/project/src/lsp_command.rs @@ -8,10 +8,11 @@ use gpui::{AppContext, AsyncAppContext, ModelHandle}; use language::{ point_from_lsp, point_to_lsp, proto::{deserialize_anchor, deserialize_version, serialize_anchor, serialize_version}, - range_from_lsp, Anchor, Bias, Buffer, CachedLspAdapter, PointUtf16, ToPointUtf16, + range_from_lsp, Anchor, Bias, Buffer, CachedLspAdapter, ToPointUtf16, }; use lsp::{DocumentHighlightKind, LanguageServer, ServerCapabilities}; use pulldown_cmark::{CodeBlockKind, Event, Options, Parser, Tag}; +use rope::point_utf16::PointUtf16; use std::{cmp::Reverse, ops::Range, path::Path, sync::Arc}; #[async_trait(?Send)] diff --git a/crates/project/src/project.rs b/crates/project/src/project.rs index 84f45070fd..11792bcf1e 100644 --- a/crates/project/src/project.rs +++ b/crates/project/src/project.rs @@ -1,4 +1,3 @@ -pub mod fs; mod ignore; mod lsp_command; pub mod search; @@ -25,9 +24,8 @@ use language::{ }, range_from_lsp, range_to_lsp, Anchor, Bias, Buffer, CachedLspAdapter, CharKind, CodeAction, CodeLabel, Completion, Diagnostic, DiagnosticEntry, DiagnosticSet, Event as BufferEvent, - File as _, Language, LanguageRegistry, LanguageServerName, LineEnding, LocalFile, - OffsetRangeExt, Operation, Patch, PointUtf16, TextBufferSnapshot, ToOffset, ToPointUtf16, - Transaction, + File as _, Language, LanguageRegistry, LanguageServerName, LocalFile, OffsetRangeExt, + Operation, Patch, TextBufferSnapshot, ToOffset, ToPointUtf16, Transaction, }; use lsp::{ DiagnosticSeverity, DiagnosticTag, DocumentHighlightKind, LanguageServer, LanguageString, @@ -37,6 +35,7 @@ use lsp_command::*; use parking_lot::Mutex; use postage::watch; use rand::prelude::*; +use rope::point_utf16::PointUtf16; use search::SearchQuery; use serde::Serialize; use settings::{FormatOnSave, Formatter, Settings}; @@ -6019,33 +6018,6 @@ impl> From<(WorktreeId, P)> for ProjectPath { } } -impl From for fs::CreateOptions { - fn from(options: lsp::CreateFileOptions) -> Self { - Self { - overwrite: options.overwrite.unwrap_or(false), - ignore_if_exists: options.ignore_if_exists.unwrap_or(false), - } - } -} - -impl From for fs::RenameOptions { - fn from(options: lsp::RenameFileOptions) -> Self { - Self { - overwrite: options.overwrite.unwrap_or(false), - ignore_if_exists: options.ignore_if_exists.unwrap_or(false), - } - } -} - -impl From for fs::RemoveOptions { - fn from(options: lsp::DeleteFileOptions) -> Self { - Self { - recursive: options.recursive.unwrap_or(false), - ignore_if_not_exists: options.ignore_if_not_exists.unwrap_or(false), - } - } -} - fn serialize_symbol(symbol: &Symbol) -> proto::Symbol { proto::Symbol { language_server_name: symbol.language_server_name.0.to_string(), diff --git a/crates/project/src/project_tests.rs b/crates/project/src/project_tests.rs index ceb5d033a7..12da0a75db 100644 --- a/crates/project/src/project_tests.rs +++ b/crates/project/src/project_tests.rs @@ -1,12 +1,14 @@ use crate::{worktree::WorktreeHandle, Event, *}; -use fs::RealFs; +use fs::LineEnding; +use fs::{FakeFs, RealFs}; use futures::{future, StreamExt}; use gpui::{executor::Deterministic, test::subscribe}; use language::{ tree_sitter_rust, tree_sitter_typescript, Diagnostic, FakeLspAdapter, LanguageConfig, - LineEnding, OffsetRangeExt, Point, ToPoint, + OffsetRangeExt, ToPoint, }; use lsp::Url; +use rope::point::Point; use serde_json::json; use std::{cell::RefCell, os::unix, rc::Rc, task::Poll}; use unindent::Unindent as _; diff --git a/crates/project/src/worktree.rs b/crates/project/src/worktree.rs index 968c2d4bc7..3073392a52 100644 --- a/crates/project/src/worktree.rs +++ b/crates/project/src/worktree.rs @@ -1,14 +1,12 @@ -use super::{ - fs::{self, Fs}, - ignore::IgnoreStack, - DiagnosticSummary, -}; +use super::{ignore::IgnoreStack, DiagnosticSummary}; use crate::{copy_recursive, ProjectEntryId, RemoveOptions}; use ::ignore::gitignore::{Gitignore, GitignoreBuilder}; use anyhow::{anyhow, Context, Result}; use client::{proto, Client}; use clock::ReplicaId; use collections::{HashMap, VecDeque}; +use fs::LineEnding; +use fs::{repository::GitRepository, Fs}; use futures::{ channel::{ mpsc::{self, UnboundedSender}, @@ -17,7 +15,6 @@ use futures::{ Stream, StreamExt, }; use fuzzy::CharBag; -use git::repository::GitRepository; use git::{DOT_GIT, GITIGNORE}; use gpui::{ executor, AppContext, AsyncAppContext, Entity, ModelContext, ModelHandle, MutableAppContext, @@ -25,13 +22,14 @@ use gpui::{ }; use language::{ proto::{deserialize_version, serialize_line_ending, serialize_version}, - Buffer, DiagnosticEntry, LineEnding, PointUtf16, Rope, + Buffer, DiagnosticEntry, Rope, }; use parking_lot::Mutex; use postage::{ prelude::{Sink as _, Stream as _}, watch, }; +use rope::point_utf16::PointUtf16; use smol::channel::{self, Sender}; use std::{ @@ -2970,11 +2968,10 @@ async fn send_worktree_update(client: &Arc, update: proto::UpdateWorktre #[cfg(test)] mod tests { use super::*; - use crate::fs::FakeFs; use anyhow::Result; use client::test::FakeHttpClient; - use fs::RealFs; - use git::repository::FakeGitRepository; + use fs::repository::FakeGitRepository; + use fs::{FakeFs, RealFs}; use gpui::{executor::Deterministic, TestAppContext}; use rand::prelude::*; use serde_json::json; diff --git a/crates/rope/Cargo.toml b/crates/rope/Cargo.toml new file mode 100644 index 0000000000..0f754c1fb3 --- /dev/null +++ b/crates/rope/Cargo.toml @@ -0,0 +1,20 @@ +[package] +name = "rope" +version = "0.1.0" +edition = "2021" + +[lib] +path = "src/rope.rs" + +[dependencies] +bromberg_sl2 = "0.6" +smallvec = { version = "1.6", features = ["union"] } +sum_tree = { path = "../sum_tree" } +arrayvec = "0.7.1" +log = { version = "0.4.16", features = ["kv_unstable_serde"] } + + +[dev-dependencies] +rand = "0.8.3" +util = { path = "../util", features = ["test-support"] } +gpui = { path = "../gpui", features = ["test-support"] } diff --git a/crates/text/src/offset_utf16.rs b/crates/rope/src/offset_utf16.rs similarity index 100% rename from crates/text/src/offset_utf16.rs rename to crates/rope/src/offset_utf16.rs diff --git a/crates/text/src/point.rs b/crates/rope/src/point.rs similarity index 100% rename from crates/text/src/point.rs rename to crates/rope/src/point.rs diff --git a/crates/text/src/point_utf16.rs b/crates/rope/src/point_utf16.rs similarity index 100% rename from crates/text/src/point_utf16.rs rename to crates/rope/src/point_utf16.rs diff --git a/crates/text/src/rope.rs b/crates/rope/src/rope.rs similarity index 99% rename from crates/text/src/rope.rs rename to crates/rope/src/rope.rs index e148c048bb..39dc9dc049 100644 --- a/crates/text/src/rope.rs +++ b/crates/rope/src/rope.rs @@ -1,7 +1,12 @@ -use super::Point; -use crate::{OffsetUtf16, PointUtf16}; +pub mod offset_utf16; +pub mod point; +pub mod point_utf16; + use arrayvec::ArrayString; use bromberg_sl2::{DigestString, HashMatrix}; +use offset_utf16::OffsetUtf16; +use point::Point; +use point_utf16::PointUtf16; use smallvec::SmallVec; use std::{cmp, fmt, io, mem, ops::Range, str}; use sum_tree::{Bias, Dimension, SumTree}; @@ -1073,9 +1078,9 @@ fn find_split_ix(text: &str) -> usize { #[cfg(test)] mod tests { use super::*; - use crate::random_char_iter::RandomCharIter; use rand::prelude::*; use std::{cmp::Ordering, env, io::Read}; + use util::RandomCharIter; use Bias::{Left, Right}; #[test] diff --git a/crates/text/Cargo.toml b/crates/text/Cargo.toml index 0d47525021..ad960ec93e 100644 --- a/crates/text/Cargo.toml +++ b/crates/text/Cargo.toml @@ -14,23 +14,23 @@ test-support = ["rand"] clock = { path = "../clock" } collections = { path = "../collections" } fs = { path = "../fs" } +rope = { path = "../rope" } sum_tree = { path = "../sum_tree" } anyhow = "1.0.38" -arrayvec = "0.7.1" digest = { version = "0.9", features = ["std"] } -bromberg_sl2 = "0.6" lazy_static = "1.4" log = { version = "0.4.16", features = ["kv_unstable_serde"] } parking_lot = "0.11" postage = { version = "0.4.1", features = ["futures-traits"] } rand = { version = "0.8.3", optional = true } -regex = "1.5" smallvec = { version = "1.6", features = ["union"] } +util = { path = "../util" } +regex = "1.5" + [dev-dependencies] collections = { path = "../collections", features = ["test-support"] } gpui = { path = "../gpui", features = ["test-support"] } -util = { path = "../util", features = ["test-support"] } ctor = "0.1" env_logger = "0.9" rand = "0.8.3" diff --git a/crates/text/src/anchor.rs b/crates/text/src/anchor.rs index 9f70ae1cc7..024c7e643b 100644 --- a/crates/text/src/anchor.rs +++ b/crates/text/src/anchor.rs @@ -1,9 +1,10 @@ -use super::{Point, ToOffset}; -use crate::{rope::TextDimension, BufferSnapshot, PointUtf16, ToPoint, ToPointUtf16}; use anyhow::Result; +use rope::{point::Point, point_utf16::PointUtf16, TextDimension}; use std::{cmp::Ordering, fmt::Debug, ops::Range}; use sum_tree::Bias; +use crate::{BufferSnapshot, ToOffset, ToPoint, ToPointUtf16}; + #[derive(Copy, Clone, Eq, PartialEq, Debug, Hash, Default)] pub struct Anchor { pub timestamp: clock::Local, diff --git a/crates/text/src/random_char_iter.rs b/crates/text/src/random_char_iter.rs deleted file mode 100644 index 04cdcd3524..0000000000 --- a/crates/text/src/random_char_iter.rs +++ /dev/null @@ -1,36 +0,0 @@ -use rand::prelude::*; - -pub struct RandomCharIter(T); - -impl RandomCharIter { - pub fn new(rng: T) -> Self { - Self(rng) - } -} - -impl Iterator for RandomCharIter { - type Item = char; - - fn next(&mut self) -> Option { - if std::env::var("SIMPLE_TEXT").map_or(false, |v| !v.is_empty()) { - return if self.0.gen_range(0..100) < 5 { - Some('\n') - } else { - Some(self.0.gen_range(b'a'..b'z' + 1).into()) - }; - } - - match self.0.gen_range(0..100) { - // whitespace - 0..=19 => [' ', '\n', '\r', '\t'].choose(&mut self.0).copied(), - // two-byte greek letters - 20..=32 => char::from_u32(self.0.gen_range(('α' as u32)..('ω' as u32 + 1))), - // // three-byte characters - 33..=45 => ['✋', '✅', '❌', '❎', '⭐'].choose(&mut self.0).copied(), - // // four-byte characters - 46..=58 => ['🍐', '🏀', '🍗', '🎉'].choose(&mut self.0).copied(), - // ascii letters - _ => Some(self.0.gen_range(b'a'..b'z' + 1).into()), - } - } -} diff --git a/crates/text/src/selection.rs b/crates/text/src/selection.rs index e5acbd21bc..881fc8c432 100644 --- a/crates/text/src/selection.rs +++ b/crates/text/src/selection.rs @@ -1,5 +1,7 @@ -use crate::Anchor; -use crate::{rope::TextDimension, BufferSnapshot}; +use rope::TextDimension; + +use crate::{Anchor, BufferSnapshot}; + use std::cmp::Ordering; use std::ops::Range; diff --git a/crates/text/src/text.rs b/crates/text/src/text.rs index 52859b7515..2196e870f2 100644 --- a/crates/text/src/text.rs +++ b/crates/text/src/text.rs @@ -2,14 +2,8 @@ mod anchor; pub mod locator; #[cfg(any(test, feature = "test-support"))] pub mod network; -mod offset_utf16; pub mod operation_queue; mod patch; -mod point; -mod point_utf16; -#[cfg(any(test, feature = "test-support"))] -pub mod random_char_iter; -pub mod rope; mod selection; pub mod subscription; #[cfg(test)] @@ -20,22 +14,15 @@ pub use anchor::*; use anyhow::Result; use clock::ReplicaId; use collections::{HashMap, HashSet}; -use lazy_static::lazy_static; +use fs::LineEnding; use locator::Locator; -pub use offset_utf16::*; use operation_queue::OperationQueue; pub use patch::Patch; -pub use point::*; -pub use point_utf16::*; use postage::{barrier, oneshot, prelude::*}; -#[cfg(any(test, feature = "test-support"))] -pub use random_char_iter::*; -use regex::Regex; -use rope::TextDimension; +use rope::{offset_utf16::OffsetUtf16, point::Point, point_utf16::PointUtf16, TextDimension}; pub use rope::{Chunks, Rope, TextSummary}; pub use selection::*; use std::{ - borrow::Cow, cmp::{self, Ordering, Reverse}, future::Future, iter::Iterator, @@ -49,9 +36,8 @@ pub use sum_tree::Bias; use sum_tree::{FilterCursor, SumTree, TreeMap}; use undo_map::UndoMap; -lazy_static! { - static ref CARRIAGE_RETURNS_REGEX: Regex = Regex::new("\r\n|\r").unwrap(); -} +#[cfg(any(test, feature = "test-support"))] +use util::RandomCharIter; pub type TransactionId = clock::Local; @@ -1458,9 +1444,7 @@ impl Buffer { last_end = Some(range.end); let new_text_len = rng.gen_range(0..10); - let new_text: String = crate::random_char_iter::RandomCharIter::new(&mut *rng) - .take(new_text_len) - .collect(); + let new_text: String = RandomCharIter::new(&mut *rng).take(new_text_len).collect(); edits.push((range, new_text.into())); } diff --git a/crates/util/Cargo.toml b/crates/util/Cargo.toml index 78416aa5b5..c083137156 100644 --- a/crates/util/Cargo.toml +++ b/crates/util/Cargo.toml @@ -7,21 +7,20 @@ edition = "2021" doctest = false [features] -test-support = ["rand", "serde_json", "tempdir", "git2"] +test-support = ["serde_json", "tempdir", "git2"] [dependencies] anyhow = "1.0.38" futures = "0.3" log = { version = "0.4.16", features = ["kv_unstable_serde"] } lazy_static = "1.4.0" -rand = { version = "0.8", optional = true } +rand = { workspace = true } tempdir = { version = "0.3.7", optional = true } serde_json = { version = "1.0", features = ["preserve_order"], optional = true } git2 = { version = "0.15", default-features = false, optional = true } [dev-dependencies] -rand = { version = "0.8" } tempdir = { version = "0.3.7" } serde_json = { version = "1.0", features = ["preserve_order"] } git2 = { version = "0.15", default-features = false } diff --git a/crates/util/src/lib.rs b/crates/util/src/lib.rs index 97f409f410..e35f2df7d4 100644 --- a/crates/util/src/lib.rs +++ b/crates/util/src/lib.rs @@ -2,6 +2,7 @@ pub mod test; use futures::Future; +use rand::{seq::SliceRandom, Rng}; use std::{ cmp::Ordering, ops::AddAssign, @@ -155,6 +156,41 @@ pub fn defer(f: F) -> impl Drop { Defer(Some(f)) } +pub struct RandomCharIter(T); + +impl RandomCharIter { + pub fn new(rng: T) -> Self { + Self(rng) + } +} + +impl Iterator for RandomCharIter { + type Item = char; + + fn next(&mut self) -> Option { + if std::env::var("SIMPLE_TEXT").map_or(false, |v| !v.is_empty()) { + return if self.0.gen_range(0..100) < 5 { + Some('\n') + } else { + Some(self.0.gen_range(b'a'..b'z' + 1).into()) + }; + } + + match self.0.gen_range(0..100) { + // whitespace + 0..=19 => [' ', '\n', '\r', '\t'].choose(&mut self.0).copied(), + // two-byte greek letters + 20..=32 => char::from_u32(self.0.gen_range(('α' as u32)..('ω' as u32 + 1))), + // // three-byte characters + 33..=45 => ['✋', '✅', '❌', '❎', '⭐'].choose(&mut self.0).copied(), + // // four-byte characters + 46..=58 => ['🍐', '🏀', '🍗', '🎉'].choose(&mut self.0).copied(), + // ascii letters + _ => Some(self.0.gen_range(b'a'..b'z' + 1).into()), + } + } +} + #[cfg(test)] mod tests { use super::*; diff --git a/crates/vim/Cargo.toml b/crates/vim/Cargo.toml index 5bc32cd5bd..bf094c30fa 100644 --- a/crates/vim/Cargo.toml +++ b/crates/vim/Cargo.toml @@ -14,6 +14,7 @@ command_palette = { path = "../command_palette" } editor = { path = "../editor" } gpui = { path = "../gpui" } language = { path = "../language" } +rope = { path = "../rope" } search = { path = "../search" } serde = { version = "1.0", features = ["derive", "rc"] } settings = { path = "../settings" } diff --git a/crates/vim/src/normal.rs b/crates/vim/src/normal.rs index db5583b4ce..a06bcc54da 100644 --- a/crates/vim/src/normal.rs +++ b/crates/vim/src/normal.rs @@ -13,7 +13,8 @@ use change::init as change_init; use collections::HashSet; use editor::{Autoscroll, Bias, ClipboardSelection, DisplayPoint}; use gpui::{actions, MutableAppContext, ViewContext}; -use language::{AutoindentMode, Point, SelectionGoal}; +use language::{AutoindentMode, SelectionGoal}; +use rope::point::Point; use workspace::Workspace; use self::{change::change_over, delete::delete_over, yank::yank_over}; diff --git a/crates/workspace/Cargo.toml b/crates/workspace/Cargo.toml index 2fd43b7bcb..c0cb2e9edd 100644 --- a/crates/workspace/Cargo.toml +++ b/crates/workspace/Cargo.toml @@ -21,6 +21,7 @@ client = { path = "../client" } collections = { path = "../collections" } context_menu = { path = "../context_menu" } drag_and_drop = { path = "../drag_and_drop" } +fs = { path = "../fs" } gpui = { path = "../gpui" } language = { path = "../language" } menu = { path = "../menu" } diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index 705823003f..e11cd80f09 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -32,7 +32,8 @@ use log::{error, warn}; pub use pane::*; pub use pane_group::*; use postage::prelude::Stream; -use project::{fs, Fs, Project, ProjectEntryId, ProjectPath, ProjectStore, Worktree, WorktreeId}; +use fs::{self, Fs}; +use project::{Project, ProjectEntryId, ProjectPath, ProjectStore, Worktree, WorktreeId}; use searchable::SearchableItemHandle; use serde::Deserialize; use settings::{Autosave, DockAnchor, Settings}; diff --git a/crates/zed/Cargo.toml b/crates/zed/Cargo.toml index d0b41b08f1..6c92dd9bef 100644 --- a/crates/zed/Cargo.toml +++ b/crates/zed/Cargo.toml @@ -32,6 +32,7 @@ diagnostics = { path = "../diagnostics" } editor = { path = "../editor" } file_finder = { path = "../file_finder" } search = { path = "../search" } +fs = { path = "../fs" } fsevent = { path = "../fsevent" } fuzzy = { path = "../fuzzy" } go_to_line = { path = "../go_to_line" } diff --git a/crates/zed/src/main.rs b/crates/zed/src/main.rs index f48f8b723e..6c93ff5ba6 100644 --- a/crates/zed/src/main.rs +++ b/crates/zed/src/main.rs @@ -14,7 +14,6 @@ use client::{ http::{self, HttpClient}, UserStore, ZED_SECRET_CLIENT_TOKEN, }; -use fs::OpenOptions; use futures::{ channel::{mpsc, oneshot}, FutureExt, SinkExt, StreamExt, @@ -28,16 +27,16 @@ use project::{Fs, ProjectStore}; use serde_json::json; use settings::{self, KeymapFileContent, Settings, SettingsFileContent, WorkingDirectory}; use smol::process::Command; -use std::{env, ffi::OsStr, fs, panic, path::PathBuf, sync::Arc, thread, time::Duration}; +use std::fs::OpenOptions; +use std::{env, ffi::OsStr, panic, path::PathBuf, sync::Arc, thread, time::Duration}; use terminal::terminal_container_view::{get_working_directory, TerminalContainer}; +use fs::RealFs; use theme::ThemeRegistry; use util::{ResultExt, TryFutureExt}; use workspace::{self, AppState, ItemHandle, NewFile, OpenPaths, Workspace}; use zed::{ - self, build_window_options, - fs::RealFs, - initialize_workspace, languages, menus, + self, build_window_options, initialize_workspace, languages, menus, settings_file::{watch_keymap_file, watch_settings_file, WatchedJsonFile}, }; @@ -200,23 +199,23 @@ fn main() { } fn init_paths() { - fs::create_dir_all(&*zed::paths::CONFIG_DIR).expect("could not create config path"); - fs::create_dir_all(&*zed::paths::LANGUAGES_DIR).expect("could not create languages path"); - fs::create_dir_all(&*zed::paths::DB_DIR).expect("could not create database path"); - fs::create_dir_all(&*zed::paths::LOGS_DIR).expect("could not create logs path"); + std::fs::create_dir_all(&*zed::paths::CONFIG_DIR).expect("could not create config path"); + std::fs::create_dir_all(&*zed::paths::LANGUAGES_DIR).expect("could not create languages path"); + std::fs::create_dir_all(&*zed::paths::DB_DIR).expect("could not create database path"); + std::fs::create_dir_all(&*zed::paths::LOGS_DIR).expect("could not create logs path"); // Copy setting files from legacy locations. TODO: remove this after a few releases. thread::spawn(|| { - if fs::metadata(&*zed::paths::legacy::SETTINGS).is_ok() - && fs::metadata(&*zed::paths::SETTINGS).is_err() + if std::fs::metadata(&*zed::paths::legacy::SETTINGS).is_ok() + && std::fs::metadata(&*zed::paths::SETTINGS).is_err() { - fs::copy(&*zed::paths::legacy::SETTINGS, &*zed::paths::SETTINGS).log_err(); + std::fs::copy(&*zed::paths::legacy::SETTINGS, &*zed::paths::SETTINGS).log_err(); } - if fs::metadata(&*zed::paths::legacy::KEYMAP).is_ok() - && fs::metadata(&*zed::paths::KEYMAP).is_err() + if std::fs::metadata(&*zed::paths::legacy::KEYMAP).is_ok() + && std::fs::metadata(&*zed::paths::KEYMAP).is_err() { - fs::copy(&*zed::paths::legacy::KEYMAP, &*zed::paths::KEYMAP).log_err(); + std::fs::copy(&*zed::paths::legacy::KEYMAP, &*zed::paths::KEYMAP).log_err(); } }); } @@ -231,9 +230,10 @@ fn init_logger() { const KIB: u64 = 1024; const MIB: u64 = 1024 * KIB; const MAX_LOG_BYTES: u64 = MIB; - if fs::metadata(&*zed::paths::LOG).map_or(false, |metadata| metadata.len() > MAX_LOG_BYTES) + if std::fs::metadata(&*zed::paths::LOG) + .map_or(false, |metadata| metadata.len() > MAX_LOG_BYTES) { - let _ = fs::rename(&*zed::paths::LOG, &*zed::paths::OLD_LOG); + let _ = std::fs::rename(&*zed::paths::LOG, &*zed::paths::OLD_LOG); } let log_file = OpenOptions::new() @@ -289,7 +289,7 @@ fn init_panic_hook(app_version: String, http: Arc, background: A .body(body.into())?; let response = http.send(request).await.context("error sending panic")?; if response.status().is_success() { - fs::remove_file(child_path) + std::fs::remove_file(child_path) .context("error removing panic after sending it successfully") .log_err(); } else { @@ -338,7 +338,7 @@ fn init_panic_hook(app_version: String, http: Arc, background: A }; let panic_filename = chrono::Utc::now().format("%Y_%m_%d %H_%M_%S").to_string(); - fs::write( + std::fs::write( zed::paths::LOGS_DIR.join(format!("zed-{}-{}.panic", app_version, panic_filename)), &message, ) @@ -395,7 +395,7 @@ fn stdout_is_a_pty() -> bool { fn collect_path_args() -> Vec { env::args() .skip(1) - .filter_map(|arg| match fs::canonicalize(arg) { + .filter_map(|arg| match std::fs::canonicalize(arg) { Ok(path) => Some(path), Err(error) => { log::error!("error parsing path argument: {}", error); diff --git a/crates/zed/src/zed.rs b/crates/zed/src/zed.rs index 6210242c51..a2857f01dc 100644 --- a/crates/zed/src/zed.rs +++ b/crates/zed/src/zed.rs @@ -1,8 +1,8 @@ mod feedback; pub mod languages; pub mod menus; -pub mod settings_file; pub mod paths; +pub mod settings_file; #[cfg(any(test, feature = "test-support"))] pub mod test; @@ -14,6 +14,7 @@ use collab_ui::CollabTitlebarItem; use collections::VecDeque; pub use editor; use editor::{Editor, MultiBuffer}; + use gpui::{ actions, geometry::vector::vec2f, @@ -23,7 +24,7 @@ use gpui::{ }; use language::Rope; pub use lsp; -pub use project::{self, fs}; +pub use project; use project_panel::ProjectPanel; use search::{BufferSearchBar, ProjectSearchBar}; use serde::Deserialize;