WIP
This commit is contained in:
parent
09efa017d4
commit
583c36e24b
21 changed files with 11815 additions and 11788 deletions
55
Cargo.lock
generated
55
Cargo.lock
generated
|
@ -2622,6 +2622,60 @@ dependencies = [
|
||||||
"workspace",
|
"workspace",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "editor2"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"aho-corasick",
|
||||||
|
"anyhow",
|
||||||
|
"client2",
|
||||||
|
"clock",
|
||||||
|
"collections",
|
||||||
|
"context_menu",
|
||||||
|
"convert_case 0.6.0",
|
||||||
|
"copilot2",
|
||||||
|
"ctor",
|
||||||
|
"db2",
|
||||||
|
"drag_and_drop",
|
||||||
|
"env_logger 0.9.3",
|
||||||
|
"futures 0.3.28",
|
||||||
|
"fuzzy2",
|
||||||
|
"git",
|
||||||
|
"gpui2",
|
||||||
|
"indoc",
|
||||||
|
"itertools 0.10.5",
|
||||||
|
"language2",
|
||||||
|
"lazy_static",
|
||||||
|
"log",
|
||||||
|
"lsp2",
|
||||||
|
"multi_buffer",
|
||||||
|
"ordered-float 2.10.0",
|
||||||
|
"parking_lot 0.11.2",
|
||||||
|
"postage",
|
||||||
|
"project2",
|
||||||
|
"rand 0.8.5",
|
||||||
|
"rich_text",
|
||||||
|
"rpc2",
|
||||||
|
"schemars",
|
||||||
|
"serde",
|
||||||
|
"serde_derive",
|
||||||
|
"settings2",
|
||||||
|
"smallvec",
|
||||||
|
"smol",
|
||||||
|
"snippet",
|
||||||
|
"sqlez",
|
||||||
|
"sum_tree",
|
||||||
|
"text2",
|
||||||
|
"theme2",
|
||||||
|
"tree-sitter",
|
||||||
|
"tree-sitter-html",
|
||||||
|
"tree-sitter-rust",
|
||||||
|
"tree-sitter-typescript",
|
||||||
|
"unindent",
|
||||||
|
"util",
|
||||||
|
"workspace2",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "either"
|
name = "either"
|
||||||
version = "1.9.0"
|
version = "1.9.0"
|
||||||
|
@ -11071,6 +11125,7 @@ dependencies = [
|
||||||
"copilot2",
|
"copilot2",
|
||||||
"ctor",
|
"ctor",
|
||||||
"db2",
|
"db2",
|
||||||
|
"editor2",
|
||||||
"env_logger 0.9.3",
|
"env_logger 0.9.3",
|
||||||
"feature_flags2",
|
"feature_flags2",
|
||||||
"fs2",
|
"fs2",
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
[package]
|
[package]
|
||||||
name = "editor"
|
name = "editor2"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
publish = false
|
publish = false
|
||||||
|
@ -23,30 +23,30 @@ test-support = [
|
||||||
]
|
]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
client = { path = "../client" }
|
client = { package = "client2", path = "../client2" }
|
||||||
clock = { path = "../clock" }
|
clock = { path = "../clock" }
|
||||||
copilot = { path = "../copilot" }
|
copilot = { package="copilot2", path = "../copilot2" }
|
||||||
db = { path = "../db" }
|
db = { package="db2", path = "../db2" }
|
||||||
drag_and_drop = { path = "../drag_and_drop" }
|
drag_and_drop = { path = "../drag_and_drop" }
|
||||||
collections = { path = "../collections" }
|
collections = { path = "../collections" }
|
||||||
context_menu = { path = "../context_menu" }
|
context_menu = { path = "../context_menu" }
|
||||||
fuzzy = { path = "../fuzzy" }
|
fuzzy = { package = "fuzzy2", path = "../fuzzy2" }
|
||||||
git = { path = "../git" }
|
git = { path = "../git" }
|
||||||
gpui = { path = "../gpui" }
|
gpui = { package = "gpui2", path = "../gpui2" }
|
||||||
language = { path = "../language" }
|
language = { package = "language2", path = "../language2" }
|
||||||
lsp = { path = "../lsp" }
|
lsp = { package = "lsp2", path = "../lsp2" }
|
||||||
multi_buffer = { path = "../multi_buffer" }
|
multi_buffer = { path = "../multi_buffer" }
|
||||||
project = { path = "../project" }
|
project = { package = "project2", path = "../project2" }
|
||||||
rpc = { path = "../rpc" }
|
rpc = { package = "rpc2", path = "../rpc2" }
|
||||||
rich_text = { path = "../rich_text" }
|
rich_text = { path = "../rich_text" }
|
||||||
settings = { path = "../settings" }
|
settings = { package="settings2", path = "../settings2" }
|
||||||
snippet = { path = "../snippet" }
|
snippet = { path = "../snippet" }
|
||||||
sum_tree = { path = "../sum_tree" }
|
sum_tree = { path = "../sum_tree" }
|
||||||
text = { path = "../text" }
|
text = { package="text2", path = "../text2" }
|
||||||
theme = { path = "../theme" }
|
theme = { package="theme2", path = "../theme2" }
|
||||||
util = { path = "../util" }
|
util = { path = "../util" }
|
||||||
sqlez = { path = "../sqlez" }
|
sqlez = { path = "../sqlez" }
|
||||||
workspace = { path = "../workspace" }
|
workspace = { package="workspace2", path = "../workspace2" }
|
||||||
|
|
||||||
aho-corasick = "1.1"
|
aho-corasick = "1.1"
|
||||||
anyhow.workspace = true
|
anyhow.workspace = true
|
||||||
|
@ -71,15 +71,15 @@ tree-sitter-html = { workspace = true, optional = true }
|
||||||
tree-sitter-typescript = { workspace = true, optional = true }
|
tree-sitter-typescript = { workspace = true, optional = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
copilot = { path = "../copilot", features = ["test-support"] }
|
copilot = { package="copilot2", path = "../copilot2", features = ["test-support"] }
|
||||||
text = { path = "../text", features = ["test-support"] }
|
text = { package="text2", path = "../text2", features = ["test-support"] }
|
||||||
language = { path = "../language", features = ["test-support"] }
|
language = { package="language2", path = "../language2", features = ["test-support"] }
|
||||||
lsp = { path = "../lsp", features = ["test-support"] }
|
lsp = { package = "lsp2", path = "../lsp2", features = ["test-support"] }
|
||||||
gpui = { path = "../gpui", features = ["test-support"] }
|
gpui = { package = "gpui2", path = "../gpui2", features = ["test-support"] }
|
||||||
util = { path = "../util", features = ["test-support"] }
|
util = { path = "../util", features = ["test-support"] }
|
||||||
project = { path = "../project", features = ["test-support"] }
|
project = { package = "project2", path = "../project2", features = ["test-support"] }
|
||||||
settings = { path = "../settings", features = ["test-support"] }
|
settings = { package = "settings2", path = "../settings2", features = ["test-support"] }
|
||||||
workspace = { path = "../workspace", features = ["test-support"] }
|
workspace = { package = "workspace2", path = "../workspace2", features = ["test-support"] }
|
||||||
multi_buffer = { path = "../multi_buffer", features = ["test-support"] }
|
multi_buffer = { path = "../multi_buffer", features = ["test-support"] }
|
||||||
|
|
||||||
ctor.workspace = true
|
ctor.workspace = true
|
||||||
|
|
|
@ -61,7 +61,7 @@ impl BlinkManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn blink_cursors(&mut self, epoch: usize, cx: &mut ModelContext<Self>) {
|
fn blink_cursors(&mut self, epoch: usize, cx: &mut ModelContext<Self>) {
|
||||||
if settings::get::<EditorSettings>(cx).cursor_blink {
|
if EditorSettings::get_global(cx).cursor_blink {
|
||||||
if epoch == self.blink_epoch && self.enabled && !self.blinking_paused {
|
if epoch == self.blink_epoch && self.enabled && !self.blinking_paused {
|
||||||
self.visible = !self.visible;
|
self.visible = !self.visible;
|
||||||
cx.notify();
|
cx.notify();
|
||||||
|
@ -107,7 +107,3 @@ impl BlinkManager {
|
||||||
self.visible
|
self.visible
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Entity for BlinkManager {
|
|
||||||
type Event = ();
|
|
||||||
}
|
|
||||||
|
|
|
@ -12,10 +12,9 @@ pub use block_map::{BlockMap, BlockPoint};
|
||||||
use collections::{BTreeMap, HashMap, HashSet};
|
use collections::{BTreeMap, HashMap, HashSet};
|
||||||
use fold_map::FoldMap;
|
use fold_map::FoldMap;
|
||||||
use gpui::{
|
use gpui::{
|
||||||
color::Color,
|
|
||||||
fonts::{FontId, HighlightStyle, Underline},
|
fonts::{FontId, HighlightStyle, Underline},
|
||||||
text_layout::{Line, RunStyle},
|
text_layout::{Line, RunStyle},
|
||||||
Entity, ModelContext, ModelHandle,
|
Entity, Hsla, Model, ModelContext,
|
||||||
};
|
};
|
||||||
use inlay_map::InlayMap;
|
use inlay_map::InlayMap;
|
||||||
use language::{
|
use language::{
|
||||||
|
@ -49,12 +48,12 @@ type TextHighlights = TreeMap<Option<TypeId>, Arc<(HighlightStyle, Vec<Range<Anc
|
||||||
type InlayHighlights = BTreeMap<TypeId, HashMap<InlayId, (HighlightStyle, InlayHighlight)>>;
|
type InlayHighlights = BTreeMap<TypeId, HashMap<InlayId, (HighlightStyle, InlayHighlight)>>;
|
||||||
|
|
||||||
pub struct DisplayMap {
|
pub struct DisplayMap {
|
||||||
buffer: ModelHandle<MultiBuffer>,
|
buffer: Model<MultiBuffer>,
|
||||||
buffer_subscription: BufferSubscription,
|
buffer_subscription: BufferSubscription,
|
||||||
fold_map: FoldMap,
|
fold_map: FoldMap,
|
||||||
inlay_map: InlayMap,
|
inlay_map: InlayMap,
|
||||||
tab_map: TabMap,
|
tab_map: TabMap,
|
||||||
wrap_map: ModelHandle<WrapMap>,
|
wrap_map: Model<WrapMap>,
|
||||||
block_map: BlockMap,
|
block_map: BlockMap,
|
||||||
text_highlights: TextHighlights,
|
text_highlights: TextHighlights,
|
||||||
inlay_highlights: InlayHighlights,
|
inlay_highlights: InlayHighlights,
|
||||||
|
@ -67,7 +66,7 @@ impl Entity for DisplayMap {
|
||||||
|
|
||||||
impl DisplayMap {
|
impl DisplayMap {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
buffer: ModelHandle<MultiBuffer>,
|
buffer: Model<MultiBuffer>,
|
||||||
font_id: FontId,
|
font_id: FontId,
|
||||||
font_size: f32,
|
font_size: f32,
|
||||||
wrap_width: Option<f32>,
|
wrap_width: Option<f32>,
|
||||||
|
@ -1015,7 +1014,7 @@ pub mod tests {
|
||||||
movement,
|
movement,
|
||||||
test::{editor_test_context::EditorTestContext, marked_display_snapshot},
|
test::{editor_test_context::EditorTestContext, marked_display_snapshot},
|
||||||
};
|
};
|
||||||
use gpui::{color::Color, elements::*, test::observe, AppContext};
|
use gpui::{elements::*, test::observe, AppContext, Hsla};
|
||||||
use language::{
|
use language::{
|
||||||
language_settings::{AllLanguageSettings, AllLanguageSettingsContent},
|
language_settings::{AllLanguageSettings, AllLanguageSettingsContent},
|
||||||
Buffer, Language, LanguageConfig, SelectionGoal,
|
Buffer, Language, LanguageConfig, SelectionGoal,
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -3,7 +3,7 @@ use super::{
|
||||||
Highlights,
|
Highlights,
|
||||||
};
|
};
|
||||||
use crate::{Anchor, AnchorRangeExt, MultiBufferSnapshot, ToOffset};
|
use crate::{Anchor, AnchorRangeExt, MultiBufferSnapshot, ToOffset};
|
||||||
use gpui::{color::Color, fonts::HighlightStyle};
|
use gpui::{fonts::HighlightStyle, Hsla};
|
||||||
use language::{Chunk, Edit, Point, TextSummary};
|
use language::{Chunk, Edit, Point, TextSummary};
|
||||||
use std::{
|
use std::{
|
||||||
any::TypeId,
|
any::TypeId,
|
||||||
|
@ -174,7 +174,7 @@ impl<'a> FoldMapWriter<'a> {
|
||||||
|
|
||||||
pub struct FoldMap {
|
pub struct FoldMap {
|
||||||
snapshot: FoldSnapshot,
|
snapshot: FoldSnapshot,
|
||||||
ellipses_color: Option<Color>,
|
ellipses_color: Option<Hsla>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FoldMap {
|
impl FoldMap {
|
||||||
|
|
|
@ -1890,6 +1890,6 @@ mod tests {
|
||||||
|
|
||||||
fn init_test(cx: &mut AppContext) {
|
fn init_test(cx: &mut AppContext) {
|
||||||
cx.set_global(SettingsStore::test(cx));
|
cx.set_global(SettingsStore::test(cx));
|
||||||
theme::init((), cx);
|
theme::init(cx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,9 +4,7 @@ use super::{
|
||||||
Highlights,
|
Highlights,
|
||||||
};
|
};
|
||||||
use crate::MultiBufferSnapshot;
|
use crate::MultiBufferSnapshot;
|
||||||
use gpui::{
|
use gpui::{AppContext, Entity, Model, ModelContext, Task};
|
||||||
fonts::FontId, text_layout::LineWrapper, AppContext, Entity, ModelContext, ModelHandle, Task,
|
|
||||||
};
|
|
||||||
use language::{Chunk, Point};
|
use language::{Chunk, Point};
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
use smol::future::yield_now;
|
use smol::future::yield_now;
|
||||||
|
@ -27,10 +25,6 @@ pub struct WrapMap {
|
||||||
font: (FontId, f32),
|
font: (FontId, f32),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Entity for WrapMap {
|
|
||||||
type Event = ();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct WrapSnapshot {
|
pub struct WrapSnapshot {
|
||||||
tab_snapshot: TabSnapshot,
|
tab_snapshot: TabSnapshot,
|
||||||
|
@ -78,7 +72,7 @@ impl WrapMap {
|
||||||
font_size: f32,
|
font_size: f32,
|
||||||
wrap_width: Option<f32>,
|
wrap_width: Option<f32>,
|
||||||
cx: &mut AppContext,
|
cx: &mut AppContext,
|
||||||
) -> (ModelHandle<Self>, WrapSnapshot) {
|
) -> (Model<Self>, WrapSnapshot) {
|
||||||
let handle = cx.add_model(|cx| {
|
let handle = cx.add_model(|cx| {
|
||||||
let mut this = Self {
|
let mut this = Self {
|
||||||
font: (font_id, font_size),
|
font: (font_id, font_size),
|
||||||
|
@ -1019,337 +1013,337 @@ fn consolidate_wrap_edits(edits: &mut Vec<WrapEdit>) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
// #[cfg(test)]
|
||||||
mod tests {
|
// mod tests {
|
||||||
use super::*;
|
// use super::*;
|
||||||
use crate::{
|
// use crate::{
|
||||||
display_map::{fold_map::FoldMap, inlay_map::InlayMap, tab_map::TabMap},
|
// display_map::{fold_map::FoldMap, inlay_map::InlayMap, tab_map::TabMap},
|
||||||
MultiBuffer,
|
// MultiBuffer,
|
||||||
};
|
// };
|
||||||
use gpui::test::observe;
|
// use gpui::test::observe;
|
||||||
use rand::prelude::*;
|
// use rand::prelude::*;
|
||||||
use settings::SettingsStore;
|
// use settings::SettingsStore;
|
||||||
use smol::stream::StreamExt;
|
// use smol::stream::StreamExt;
|
||||||
use std::{cmp, env, num::NonZeroU32};
|
// use std::{cmp, env, num::NonZeroU32};
|
||||||
use text::Rope;
|
// use text::Rope;
|
||||||
|
|
||||||
#[gpui::test(iterations = 100)]
|
// #[gpui::test(iterations = 100)]
|
||||||
async fn test_random_wraps(cx: &mut gpui::TestAppContext, mut rng: StdRng) {
|
// async fn test_random_wraps(cx: &mut gpui::TestAppContext, mut rng: StdRng) {
|
||||||
init_test(cx);
|
// init_test(cx);
|
||||||
|
|
||||||
cx.foreground().set_block_on_ticks(0..=50);
|
// cx.foreground().set_block_on_ticks(0..=50);
|
||||||
let operations = env::var("OPERATIONS")
|
// let operations = env::var("OPERATIONS")
|
||||||
.map(|i| i.parse().expect("invalid `OPERATIONS` variable"))
|
// .map(|i| i.parse().expect("invalid `OPERATIONS` variable"))
|
||||||
.unwrap_or(10);
|
// .unwrap_or(10);
|
||||||
|
|
||||||
let font_cache = cx.font_cache().clone();
|
// let font_cache = cx.font_cache().clone();
|
||||||
let font_system = cx.platform().fonts();
|
// let font_system = cx.platform().fonts();
|
||||||
let mut wrap_width = if rng.gen_bool(0.1) {
|
// let mut wrap_width = if rng.gen_bool(0.1) {
|
||||||
None
|
// None
|
||||||
} else {
|
// } else {
|
||||||
Some(rng.gen_range(0.0..=1000.0))
|
// Some(rng.gen_range(0.0..=1000.0))
|
||||||
};
|
// };
|
||||||
let tab_size = NonZeroU32::new(rng.gen_range(1..=4)).unwrap();
|
// let tab_size = NonZeroU32::new(rng.gen_range(1..=4)).unwrap();
|
||||||
let family_id = font_cache
|
// let family_id = font_cache
|
||||||
.load_family(&["Helvetica"], &Default::default())
|
// .load_family(&["Helvetica"], &Default::default())
|
||||||
.unwrap();
|
// .unwrap();
|
||||||
let font_id = font_cache
|
// let font_id = font_cache
|
||||||
.select_font(family_id, &Default::default())
|
// .select_font(family_id, &Default::default())
|
||||||
.unwrap();
|
// .unwrap();
|
||||||
let font_size = 14.0;
|
// let font_size = 14.0;
|
||||||
|
|
||||||
log::info!("Tab size: {}", tab_size);
|
// log::info!("Tab size: {}", tab_size);
|
||||||
log::info!("Wrap width: {:?}", wrap_width);
|
// log::info!("Wrap width: {:?}", wrap_width);
|
||||||
|
|
||||||
let buffer = cx.update(|cx| {
|
// let buffer = cx.update(|cx| {
|
||||||
if rng.gen() {
|
// if rng.gen() {
|
||||||
MultiBuffer::build_random(&mut rng, cx)
|
// MultiBuffer::build_random(&mut rng, cx)
|
||||||
} else {
|
// } else {
|
||||||
let len = rng.gen_range(0..10);
|
// let len = rng.gen_range(0..10);
|
||||||
let text = util::RandomCharIter::new(&mut rng)
|
// let text = util::RandomCharIter::new(&mut rng)
|
||||||
.take(len)
|
// .take(len)
|
||||||
.collect::<String>();
|
// .collect::<String>();
|
||||||
MultiBuffer::build_simple(&text, cx)
|
// MultiBuffer::build_simple(&text, cx)
|
||||||
}
|
// }
|
||||||
});
|
// });
|
||||||
let mut buffer_snapshot = buffer.read_with(cx, |buffer, cx| buffer.snapshot(cx));
|
// let mut buffer_snapshot = buffer.read_with(cx, |buffer, cx| buffer.snapshot(cx));
|
||||||
log::info!("Buffer text: {:?}", buffer_snapshot.text());
|
// log::info!("Buffer text: {:?}", buffer_snapshot.text());
|
||||||
let (mut inlay_map, inlay_snapshot) = InlayMap::new(buffer_snapshot.clone());
|
// let (mut inlay_map, inlay_snapshot) = InlayMap::new(buffer_snapshot.clone());
|
||||||
log::info!("InlayMap text: {:?}", inlay_snapshot.text());
|
// log::info!("InlayMap text: {:?}", inlay_snapshot.text());
|
||||||
let (mut fold_map, fold_snapshot) = FoldMap::new(inlay_snapshot.clone());
|
// let (mut fold_map, fold_snapshot) = FoldMap::new(inlay_snapshot.clone());
|
||||||
log::info!("FoldMap text: {:?}", fold_snapshot.text());
|
// log::info!("FoldMap text: {:?}", fold_snapshot.text());
|
||||||
let (mut tab_map, _) = TabMap::new(fold_snapshot.clone(), tab_size);
|
// let (mut tab_map, _) = TabMap::new(fold_snapshot.clone(), tab_size);
|
||||||
let tabs_snapshot = tab_map.set_max_expansion_column(32);
|
// let tabs_snapshot = tab_map.set_max_expansion_column(32);
|
||||||
log::info!("TabMap text: {:?}", tabs_snapshot.text());
|
// log::info!("TabMap text: {:?}", tabs_snapshot.text());
|
||||||
|
|
||||||
let mut line_wrapper = LineWrapper::new(font_id, font_size, font_system);
|
// let mut line_wrapper = LineWrapper::new(font_id, font_size, font_system);
|
||||||
let unwrapped_text = tabs_snapshot.text();
|
// let unwrapped_text = tabs_snapshot.text();
|
||||||
let expected_text = wrap_text(&unwrapped_text, wrap_width, &mut line_wrapper);
|
// let expected_text = wrap_text(&unwrapped_text, wrap_width, &mut line_wrapper);
|
||||||
|
|
||||||
let (wrap_map, _) =
|
// let (wrap_map, _) =
|
||||||
cx.update(|cx| WrapMap::new(tabs_snapshot.clone(), font_id, font_size, wrap_width, cx));
|
// cx.update(|cx| WrapMap::new(tabs_snapshot.clone(), font_id, font_size, wrap_width, cx));
|
||||||
let mut notifications = observe(&wrap_map, cx);
|
// let mut notifications = observe(&wrap_map, cx);
|
||||||
|
|
||||||
if wrap_map.read_with(cx, |map, _| map.is_rewrapping()) {
|
// if wrap_map.read_with(cx, |map, _| map.is_rewrapping()) {
|
||||||
notifications.next().await.unwrap();
|
// notifications.next().await.unwrap();
|
||||||
}
|
// }
|
||||||
|
|
||||||
let (initial_snapshot, _) = wrap_map.update(cx, |map, cx| {
|
// let (initial_snapshot, _) = wrap_map.update(cx, |map, cx| {
|
||||||
assert!(!map.is_rewrapping());
|
// assert!(!map.is_rewrapping());
|
||||||
map.sync(tabs_snapshot.clone(), Vec::new(), cx)
|
// map.sync(tabs_snapshot.clone(), Vec::new(), cx)
|
||||||
});
|
// });
|
||||||
|
|
||||||
let actual_text = initial_snapshot.text();
|
// let actual_text = initial_snapshot.text();
|
||||||
assert_eq!(
|
// assert_eq!(
|
||||||
actual_text, expected_text,
|
// actual_text, expected_text,
|
||||||
"unwrapped text is: {:?}",
|
// "unwrapped text is: {:?}",
|
||||||
unwrapped_text
|
// unwrapped_text
|
||||||
);
|
// );
|
||||||
log::info!("Wrapped text: {:?}", actual_text);
|
// log::info!("Wrapped text: {:?}", actual_text);
|
||||||
|
|
||||||
let mut next_inlay_id = 0;
|
// let mut next_inlay_id = 0;
|
||||||
let mut edits = Vec::new();
|
// let mut edits = Vec::new();
|
||||||
for _i in 0..operations {
|
// for _i in 0..operations {
|
||||||
log::info!("{} ==============================================", _i);
|
// log::info!("{} ==============================================", _i);
|
||||||
|
|
||||||
let mut buffer_edits = Vec::new();
|
// let mut buffer_edits = Vec::new();
|
||||||
match rng.gen_range(0..=100) {
|
// match rng.gen_range(0..=100) {
|
||||||
0..=19 => {
|
// 0..=19 => {
|
||||||
wrap_width = if rng.gen_bool(0.2) {
|
// wrap_width = if rng.gen_bool(0.2) {
|
||||||
None
|
// None
|
||||||
} else {
|
// } else {
|
||||||
Some(rng.gen_range(0.0..=1000.0))
|
// Some(rng.gen_range(0.0..=1000.0))
|
||||||
};
|
// };
|
||||||
log::info!("Setting wrap width to {:?}", wrap_width);
|
// log::info!("Setting wrap width to {:?}", wrap_width);
|
||||||
wrap_map.update(cx, |map, cx| map.set_wrap_width(wrap_width, cx));
|
// wrap_map.update(cx, |map, cx| map.set_wrap_width(wrap_width, cx));
|
||||||
}
|
// }
|
||||||
20..=39 => {
|
// 20..=39 => {
|
||||||
for (fold_snapshot, fold_edits) in fold_map.randomly_mutate(&mut rng) {
|
// for (fold_snapshot, fold_edits) in fold_map.randomly_mutate(&mut rng) {
|
||||||
let (tabs_snapshot, tab_edits) =
|
// let (tabs_snapshot, tab_edits) =
|
||||||
tab_map.sync(fold_snapshot, fold_edits, tab_size);
|
// tab_map.sync(fold_snapshot, fold_edits, tab_size);
|
||||||
let (mut snapshot, wrap_edits) =
|
// let (mut snapshot, wrap_edits) =
|
||||||
wrap_map.update(cx, |map, cx| map.sync(tabs_snapshot, tab_edits, cx));
|
// wrap_map.update(cx, |map, cx| map.sync(tabs_snapshot, tab_edits, cx));
|
||||||
snapshot.check_invariants();
|
// snapshot.check_invariants();
|
||||||
snapshot.verify_chunks(&mut rng);
|
// snapshot.verify_chunks(&mut rng);
|
||||||
edits.push((snapshot, wrap_edits));
|
// edits.push((snapshot, wrap_edits));
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
40..=59 => {
|
// 40..=59 => {
|
||||||
let (inlay_snapshot, inlay_edits) =
|
// let (inlay_snapshot, inlay_edits) =
|
||||||
inlay_map.randomly_mutate(&mut next_inlay_id, &mut rng);
|
// inlay_map.randomly_mutate(&mut next_inlay_id, &mut rng);
|
||||||
let (fold_snapshot, fold_edits) = fold_map.read(inlay_snapshot, inlay_edits);
|
// let (fold_snapshot, fold_edits) = fold_map.read(inlay_snapshot, inlay_edits);
|
||||||
let (tabs_snapshot, tab_edits) =
|
// let (tabs_snapshot, tab_edits) =
|
||||||
tab_map.sync(fold_snapshot, fold_edits, tab_size);
|
// tab_map.sync(fold_snapshot, fold_edits, tab_size);
|
||||||
let (mut snapshot, wrap_edits) =
|
// let (mut snapshot, wrap_edits) =
|
||||||
wrap_map.update(cx, |map, cx| map.sync(tabs_snapshot, tab_edits, cx));
|
// wrap_map.update(cx, |map, cx| map.sync(tabs_snapshot, tab_edits, cx));
|
||||||
snapshot.check_invariants();
|
// snapshot.check_invariants();
|
||||||
snapshot.verify_chunks(&mut rng);
|
// snapshot.verify_chunks(&mut rng);
|
||||||
edits.push((snapshot, wrap_edits));
|
// edits.push((snapshot, wrap_edits));
|
||||||
}
|
// }
|
||||||
_ => {
|
// _ => {
|
||||||
buffer.update(cx, |buffer, cx| {
|
// buffer.update(cx, |buffer, cx| {
|
||||||
let subscription = buffer.subscribe();
|
// let subscription = buffer.subscribe();
|
||||||
let edit_count = rng.gen_range(1..=5);
|
// let edit_count = rng.gen_range(1..=5);
|
||||||
buffer.randomly_mutate(&mut rng, edit_count, cx);
|
// buffer.randomly_mutate(&mut rng, edit_count, cx);
|
||||||
buffer_snapshot = buffer.snapshot(cx);
|
// buffer_snapshot = buffer.snapshot(cx);
|
||||||
buffer_edits.extend(subscription.consume());
|
// buffer_edits.extend(subscription.consume());
|
||||||
});
|
// });
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
log::info!("Buffer text: {:?}", buffer_snapshot.text());
|
// log::info!("Buffer text: {:?}", buffer_snapshot.text());
|
||||||
let (inlay_snapshot, inlay_edits) =
|
// let (inlay_snapshot, inlay_edits) =
|
||||||
inlay_map.sync(buffer_snapshot.clone(), buffer_edits);
|
// inlay_map.sync(buffer_snapshot.clone(), buffer_edits);
|
||||||
log::info!("InlayMap text: {:?}", inlay_snapshot.text());
|
// log::info!("InlayMap text: {:?}", inlay_snapshot.text());
|
||||||
let (fold_snapshot, fold_edits) = fold_map.read(inlay_snapshot, inlay_edits);
|
// let (fold_snapshot, fold_edits) = fold_map.read(inlay_snapshot, inlay_edits);
|
||||||
log::info!("FoldMap text: {:?}", fold_snapshot.text());
|
// log::info!("FoldMap text: {:?}", fold_snapshot.text());
|
||||||
let (tabs_snapshot, tab_edits) = tab_map.sync(fold_snapshot, fold_edits, tab_size);
|
// let (tabs_snapshot, tab_edits) = tab_map.sync(fold_snapshot, fold_edits, tab_size);
|
||||||
log::info!("TabMap text: {:?}", tabs_snapshot.text());
|
// log::info!("TabMap text: {:?}", tabs_snapshot.text());
|
||||||
|
|
||||||
let unwrapped_text = tabs_snapshot.text();
|
// let unwrapped_text = tabs_snapshot.text();
|
||||||
let expected_text = wrap_text(&unwrapped_text, wrap_width, &mut line_wrapper);
|
// let expected_text = wrap_text(&unwrapped_text, wrap_width, &mut line_wrapper);
|
||||||
let (mut snapshot, wrap_edits) =
|
// let (mut snapshot, wrap_edits) =
|
||||||
wrap_map.update(cx, |map, cx| map.sync(tabs_snapshot.clone(), tab_edits, cx));
|
// wrap_map.update(cx, |map, cx| map.sync(tabs_snapshot.clone(), tab_edits, cx));
|
||||||
snapshot.check_invariants();
|
// snapshot.check_invariants();
|
||||||
snapshot.verify_chunks(&mut rng);
|
// snapshot.verify_chunks(&mut rng);
|
||||||
edits.push((snapshot, wrap_edits));
|
// edits.push((snapshot, wrap_edits));
|
||||||
|
|
||||||
if wrap_map.read_with(cx, |map, _| map.is_rewrapping()) && rng.gen_bool(0.4) {
|
// if wrap_map.read_with(cx, |map, _| map.is_rewrapping()) && rng.gen_bool(0.4) {
|
||||||
log::info!("Waiting for wrapping to finish");
|
// log::info!("Waiting for wrapping to finish");
|
||||||
while wrap_map.read_with(cx, |map, _| map.is_rewrapping()) {
|
// while wrap_map.read_with(cx, |map, _| map.is_rewrapping()) {
|
||||||
notifications.next().await.unwrap();
|
// notifications.next().await.unwrap();
|
||||||
}
|
// }
|
||||||
wrap_map.read_with(cx, |map, _| assert!(map.pending_edits.is_empty()));
|
// wrap_map.read_with(cx, |map, _| assert!(map.pending_edits.is_empty()));
|
||||||
}
|
// }
|
||||||
|
|
||||||
if !wrap_map.read_with(cx, |map, _| map.is_rewrapping()) {
|
// if !wrap_map.read_with(cx, |map, _| map.is_rewrapping()) {
|
||||||
let (mut wrapped_snapshot, wrap_edits) =
|
// let (mut wrapped_snapshot, wrap_edits) =
|
||||||
wrap_map.update(cx, |map, cx| map.sync(tabs_snapshot, Vec::new(), cx));
|
// wrap_map.update(cx, |map, cx| map.sync(tabs_snapshot, Vec::new(), cx));
|
||||||
let actual_text = wrapped_snapshot.text();
|
// let actual_text = wrapped_snapshot.text();
|
||||||
let actual_longest_row = wrapped_snapshot.longest_row();
|
// let actual_longest_row = wrapped_snapshot.longest_row();
|
||||||
log::info!("Wrapping finished: {:?}", actual_text);
|
// log::info!("Wrapping finished: {:?}", actual_text);
|
||||||
wrapped_snapshot.check_invariants();
|
// wrapped_snapshot.check_invariants();
|
||||||
wrapped_snapshot.verify_chunks(&mut rng);
|
// wrapped_snapshot.verify_chunks(&mut rng);
|
||||||
edits.push((wrapped_snapshot.clone(), wrap_edits));
|
// edits.push((wrapped_snapshot.clone(), wrap_edits));
|
||||||
assert_eq!(
|
// assert_eq!(
|
||||||
actual_text, expected_text,
|
// actual_text, expected_text,
|
||||||
"unwrapped text is: {:?}",
|
// "unwrapped text is: {:?}",
|
||||||
unwrapped_text
|
// unwrapped_text
|
||||||
);
|
// );
|
||||||
|
|
||||||
let mut summary = TextSummary::default();
|
// let mut summary = TextSummary::default();
|
||||||
for (ix, item) in wrapped_snapshot
|
// for (ix, item) in wrapped_snapshot
|
||||||
.transforms
|
// .transforms
|
||||||
.items(&())
|
// .items(&())
|
||||||
.into_iter()
|
// .into_iter()
|
||||||
.enumerate()
|
// .enumerate()
|
||||||
{
|
// {
|
||||||
summary += &item.summary.output;
|
// summary += &item.summary.output;
|
||||||
log::info!("{} summary: {:?}", ix, item.summary.output,);
|
// log::info!("{} summary: {:?}", ix, item.summary.output,);
|
||||||
}
|
// }
|
||||||
|
|
||||||
if tab_size.get() == 1
|
// if tab_size.get() == 1
|
||||||
|| !wrapped_snapshot
|
// || !wrapped_snapshot
|
||||||
.tab_snapshot
|
// .tab_snapshot
|
||||||
.fold_snapshot
|
// .fold_snapshot
|
||||||
.text()
|
// .text()
|
||||||
.contains('\t')
|
// .contains('\t')
|
||||||
{
|
// {
|
||||||
let mut expected_longest_rows = Vec::new();
|
// let mut expected_longest_rows = Vec::new();
|
||||||
let mut longest_line_len = -1;
|
// let mut longest_line_len = -1;
|
||||||
for (row, line) in expected_text.split('\n').enumerate() {
|
// for (row, line) in expected_text.split('\n').enumerate() {
|
||||||
let line_char_count = line.chars().count() as isize;
|
// let line_char_count = line.chars().count() as isize;
|
||||||
if line_char_count > longest_line_len {
|
// if line_char_count > longest_line_len {
|
||||||
expected_longest_rows.clear();
|
// expected_longest_rows.clear();
|
||||||
longest_line_len = line_char_count;
|
// longest_line_len = line_char_count;
|
||||||
}
|
// }
|
||||||
if line_char_count >= longest_line_len {
|
// if line_char_count >= longest_line_len {
|
||||||
expected_longest_rows.push(row as u32);
|
// expected_longest_rows.push(row as u32);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
assert!(
|
// assert!(
|
||||||
expected_longest_rows.contains(&actual_longest_row),
|
// expected_longest_rows.contains(&actual_longest_row),
|
||||||
"incorrect longest row {}. expected {:?} with length {}",
|
// "incorrect longest row {}. expected {:?} with length {}",
|
||||||
actual_longest_row,
|
// actual_longest_row,
|
||||||
expected_longest_rows,
|
// expected_longest_rows,
|
||||||
longest_line_len,
|
// longest_line_len,
|
||||||
)
|
// )
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
let mut initial_text = Rope::from(initial_snapshot.text().as_str());
|
// let mut initial_text = Rope::from(initial_snapshot.text().as_str());
|
||||||
for (snapshot, patch) in edits {
|
// for (snapshot, patch) in edits {
|
||||||
let snapshot_text = Rope::from(snapshot.text().as_str());
|
// let snapshot_text = Rope::from(snapshot.text().as_str());
|
||||||
for edit in &patch {
|
// for edit in &patch {
|
||||||
let old_start = initial_text.point_to_offset(Point::new(edit.new.start, 0));
|
// let old_start = initial_text.point_to_offset(Point::new(edit.new.start, 0));
|
||||||
let old_end = initial_text.point_to_offset(cmp::min(
|
// let old_end = initial_text.point_to_offset(cmp::min(
|
||||||
Point::new(edit.new.start + edit.old.len() as u32, 0),
|
// Point::new(edit.new.start + edit.old.len() as u32, 0),
|
||||||
initial_text.max_point(),
|
// initial_text.max_point(),
|
||||||
));
|
// ));
|
||||||
let new_start = snapshot_text.point_to_offset(Point::new(edit.new.start, 0));
|
// let new_start = snapshot_text.point_to_offset(Point::new(edit.new.start, 0));
|
||||||
let new_end = snapshot_text.point_to_offset(cmp::min(
|
// let new_end = snapshot_text.point_to_offset(cmp::min(
|
||||||
Point::new(edit.new.end, 0),
|
// Point::new(edit.new.end, 0),
|
||||||
snapshot_text.max_point(),
|
// snapshot_text.max_point(),
|
||||||
));
|
// ));
|
||||||
let new_text = snapshot_text
|
// let new_text = snapshot_text
|
||||||
.chunks_in_range(new_start..new_end)
|
// .chunks_in_range(new_start..new_end)
|
||||||
.collect::<String>();
|
// .collect::<String>();
|
||||||
|
|
||||||
initial_text.replace(old_start..old_end, &new_text);
|
// initial_text.replace(old_start..old_end, &new_text);
|
||||||
}
|
// }
|
||||||
assert_eq!(initial_text.to_string(), snapshot_text.to_string());
|
// assert_eq!(initial_text.to_string(), snapshot_text.to_string());
|
||||||
}
|
// }
|
||||||
|
|
||||||
if wrap_map.read_with(cx, |map, _| map.is_rewrapping()) {
|
// if wrap_map.read_with(cx, |map, _| map.is_rewrapping()) {
|
||||||
log::info!("Waiting for wrapping to finish");
|
// log::info!("Waiting for wrapping to finish");
|
||||||
while wrap_map.read_with(cx, |map, _| map.is_rewrapping()) {
|
// while wrap_map.read_with(cx, |map, _| map.is_rewrapping()) {
|
||||||
notifications.next().await.unwrap();
|
// notifications.next().await.unwrap();
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
wrap_map.read_with(cx, |map, _| assert!(map.pending_edits.is_empty()));
|
// wrap_map.read_with(cx, |map, _| assert!(map.pending_edits.is_empty()));
|
||||||
}
|
// }
|
||||||
|
|
||||||
fn init_test(cx: &mut gpui::TestAppContext) {
|
// fn init_test(cx: &mut gpui::TestAppContext) {
|
||||||
cx.foreground().forbid_parking();
|
// cx.foreground().forbid_parking();
|
||||||
cx.update(|cx| {
|
// cx.update(|cx| {
|
||||||
cx.set_global(SettingsStore::test(cx));
|
// cx.set_global(SettingsStore::test(cx));
|
||||||
theme::init((), cx);
|
// theme::init((), cx);
|
||||||
});
|
// });
|
||||||
}
|
// }
|
||||||
|
|
||||||
fn wrap_text(
|
// fn wrap_text(
|
||||||
unwrapped_text: &str,
|
// unwrapped_text: &str,
|
||||||
wrap_width: Option<f32>,
|
// wrap_width: Option<f32>,
|
||||||
line_wrapper: &mut LineWrapper,
|
// line_wrapper: &mut LineWrapper,
|
||||||
) -> String {
|
// ) -> String {
|
||||||
if let Some(wrap_width) = wrap_width {
|
// if let Some(wrap_width) = wrap_width {
|
||||||
let mut wrapped_text = String::new();
|
// let mut wrapped_text = String::new();
|
||||||
for (row, line) in unwrapped_text.split('\n').enumerate() {
|
// for (row, line) in unwrapped_text.split('\n').enumerate() {
|
||||||
if row > 0 {
|
// if row > 0 {
|
||||||
wrapped_text.push('\n')
|
// wrapped_text.push('\n')
|
||||||
}
|
// }
|
||||||
|
|
||||||
let mut prev_ix = 0;
|
// let mut prev_ix = 0;
|
||||||
for boundary in line_wrapper.wrap_line(line, wrap_width) {
|
// for boundary in line_wrapper.wrap_line(line, wrap_width) {
|
||||||
wrapped_text.push_str(&line[prev_ix..boundary.ix]);
|
// wrapped_text.push_str(&line[prev_ix..boundary.ix]);
|
||||||
wrapped_text.push('\n');
|
// wrapped_text.push('\n');
|
||||||
wrapped_text.push_str(&" ".repeat(boundary.next_indent as usize));
|
// wrapped_text.push_str(&" ".repeat(boundary.next_indent as usize));
|
||||||
prev_ix = boundary.ix;
|
// prev_ix = boundary.ix;
|
||||||
}
|
// }
|
||||||
wrapped_text.push_str(&line[prev_ix..]);
|
// wrapped_text.push_str(&line[prev_ix..]);
|
||||||
}
|
// }
|
||||||
wrapped_text
|
// wrapped_text
|
||||||
} else {
|
// } else {
|
||||||
unwrapped_text.to_string()
|
// unwrapped_text.to_string()
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
impl WrapSnapshot {
|
// impl WrapSnapshot {
|
||||||
pub fn text(&self) -> String {
|
// pub fn text(&self) -> String {
|
||||||
self.text_chunks(0).collect()
|
// self.text_chunks(0).collect()
|
||||||
}
|
// }
|
||||||
|
|
||||||
pub fn text_chunks(&self, wrap_row: u32) -> impl Iterator<Item = &str> {
|
// pub fn text_chunks(&self, wrap_row: u32) -> impl Iterator<Item = &str> {
|
||||||
self.chunks(
|
// self.chunks(
|
||||||
wrap_row..self.max_point().row() + 1,
|
// wrap_row..self.max_point().row() + 1,
|
||||||
false,
|
// false,
|
||||||
Highlights::default(),
|
// Highlights::default(),
|
||||||
)
|
// )
|
||||||
.map(|h| h.text)
|
// .map(|h| h.text)
|
||||||
}
|
// }
|
||||||
|
|
||||||
fn verify_chunks(&mut self, rng: &mut impl Rng) {
|
// fn verify_chunks(&mut self, rng: &mut impl Rng) {
|
||||||
for _ in 0..5 {
|
// for _ in 0..5 {
|
||||||
let mut end_row = rng.gen_range(0..=self.max_point().row());
|
// let mut end_row = rng.gen_range(0..=self.max_point().row());
|
||||||
let start_row = rng.gen_range(0..=end_row);
|
// let start_row = rng.gen_range(0..=end_row);
|
||||||
end_row += 1;
|
// end_row += 1;
|
||||||
|
|
||||||
let mut expected_text = self.text_chunks(start_row).collect::<String>();
|
// let mut expected_text = self.text_chunks(start_row).collect::<String>();
|
||||||
if expected_text.ends_with('\n') {
|
// if expected_text.ends_with('\n') {
|
||||||
expected_text.push('\n');
|
// expected_text.push('\n');
|
||||||
}
|
// }
|
||||||
let mut expected_text = expected_text
|
// let mut expected_text = expected_text
|
||||||
.lines()
|
// .lines()
|
||||||
.take((end_row - start_row) as usize)
|
// .take((end_row - start_row) as usize)
|
||||||
.collect::<Vec<_>>()
|
// .collect::<Vec<_>>()
|
||||||
.join("\n");
|
// .join("\n");
|
||||||
if end_row <= self.max_point().row() {
|
// if end_row <= self.max_point().row() {
|
||||||
expected_text.push('\n');
|
// expected_text.push('\n');
|
||||||
}
|
// }
|
||||||
|
|
||||||
let actual_text = self
|
// let actual_text = self
|
||||||
.chunks(start_row..end_row, true, Highlights::default())
|
// .chunks(start_row..end_row, true, Highlights::default())
|
||||||
.map(|c| c.text)
|
// .map(|c| c.text)
|
||||||
.collect::<String>();
|
// .collect::<String>();
|
||||||
assert_eq!(
|
// assert_eq!(
|
||||||
expected_text,
|
// expected_text,
|
||||||
actual_text,
|
// actual_text,
|
||||||
"chunks != highlighted_chunks for rows {:?}",
|
// "chunks != highlighted_chunks for rows {:?}",
|
||||||
start_row..end_row
|
// start_row..end_row
|
||||||
);
|
// );
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,6 +1,6 @@
|
||||||
|
use gpui::Settings;
|
||||||
use schemars::JsonSchema;
|
use schemars::JsonSchema;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use settings::Setting;
|
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
pub struct EditorSettings {
|
pub struct EditorSettings {
|
||||||
|
@ -47,7 +47,7 @@ pub struct ScrollbarContent {
|
||||||
pub selections: Option<bool>,
|
pub selections: Option<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Setting for EditorSettings {
|
impl Settings for EditorSettings {
|
||||||
const KEY: Option<&'static str> = None;
|
const KEY: Option<&'static str> = None;
|
||||||
|
|
||||||
type FileContent = EditorSettingsContent;
|
type FileContent = EditorSettingsContent;
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -9,7 +9,7 @@ use gpui::{
|
||||||
actions,
|
actions,
|
||||||
elements::{Flex, MouseEventHandler, Padding, ParentElement, Text},
|
elements::{Flex, MouseEventHandler, Padding, ParentElement, Text},
|
||||||
platform::{CursorStyle, MouseButton},
|
platform::{CursorStyle, MouseButton},
|
||||||
AnyElement, AppContext, Element, ModelHandle, Task, ViewContext, WeakViewHandle,
|
AnyElement, AppContext, Element, Model, Task, ViewContext, WeakViewHandle,
|
||||||
};
|
};
|
||||||
use language::{
|
use language::{
|
||||||
markdown, Bias, DiagnosticEntry, DiagnosticSeverity, Language, LanguageRegistry, ParsedMarkdown,
|
markdown, Bias, DiagnosticEntry, DiagnosticSeverity, Language, LanguageRegistry, ParsedMarkdown,
|
||||||
|
|
|
@ -11,7 +11,7 @@ use crate::{
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use clock::Global;
|
use clock::Global;
|
||||||
use futures::future;
|
use futures::future;
|
||||||
use gpui::{ModelContext, ModelHandle, Task, ViewContext};
|
use gpui::{Model, ModelContext, Task, ViewContext};
|
||||||
use language::{language_settings::InlayHintKind, Buffer, BufferSnapshot};
|
use language::{language_settings::InlayHintKind, Buffer, BufferSnapshot};
|
||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
use project::{InlayHint, ResolveState};
|
use project::{InlayHint, ResolveState};
|
||||||
|
@ -3244,7 +3244,7 @@ all hints should be invalidated and requeried for all of its visible excerpts"
|
||||||
|
|
||||||
cx.update(|cx| {
|
cx.update(|cx| {
|
||||||
cx.set_global(SettingsStore::test(cx));
|
cx.set_global(SettingsStore::test(cx));
|
||||||
theme::init((), cx);
|
theme::init(cx);
|
||||||
client::init_settings(cx);
|
client::init_settings(cx);
|
||||||
language::init(cx);
|
language::init(cx);
|
||||||
Project::init_settings(cx);
|
Project::init_settings(cx);
|
||||||
|
|
|
@ -7,10 +7,8 @@ use anyhow::{Context, Result};
|
||||||
use collections::HashSet;
|
use collections::HashSet;
|
||||||
use futures::future::try_join_all;
|
use futures::future::try_join_all;
|
||||||
use gpui::{
|
use gpui::{
|
||||||
elements::*,
|
point, AnyElement, AppContext, AsyncAppContext, Entity, Model, Pixels, Subscription, Task,
|
||||||
geometry::vector::{vec2f, Vector2F},
|
View, ViewContext, WeakView,
|
||||||
AppContext, AsyncAppContext, Entity, ModelHandle, Subscription, Task, View, ViewContext,
|
|
||||||
ViewHandle, WeakViewHandle,
|
|
||||||
};
|
};
|
||||||
use language::{
|
use language::{
|
||||||
proto::serialize_anchor as serialize_text_anchor, Bias, Buffer, OffsetRangeExt, Point,
|
proto::serialize_anchor as serialize_text_anchor, Bias, Buffer, OffsetRangeExt, Point,
|
||||||
|
@ -49,12 +47,12 @@ impl FollowableItem for Editor {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn from_state_proto(
|
fn from_state_proto(
|
||||||
pane: ViewHandle<workspace::Pane>,
|
pane: View<workspace::Pane>,
|
||||||
workspace: ViewHandle<Workspace>,
|
workspace: View<Workspace>,
|
||||||
remote_id: ViewId,
|
remote_id: ViewId,
|
||||||
state: &mut Option<proto::view::Variant>,
|
state: &mut Option<proto::view::Variant>,
|
||||||
cx: &mut AppContext,
|
cx: &mut AppContext,
|
||||||
) -> Option<Task<Result<ViewHandle<Self>>>> {
|
) -> Option<Task<Result<View<Self>>>> {
|
||||||
let project = workspace.read(cx).project().to_owned();
|
let project = workspace.read(cx).project().to_owned();
|
||||||
let Some(proto::view::Variant::Editor(_)) = state else {
|
let Some(proto::view::Variant::Editor(_)) = state else {
|
||||||
return None;
|
return None;
|
||||||
|
@ -286,7 +284,7 @@ impl FollowableItem for Editor {
|
||||||
|
|
||||||
fn apply_update_proto(
|
fn apply_update_proto(
|
||||||
&mut self,
|
&mut self,
|
||||||
project: &ModelHandle<Project>,
|
project: &Model<Project>,
|
||||||
message: update_view::Variant,
|
message: update_view::Variant,
|
||||||
cx: &mut ViewContext<Self>,
|
cx: &mut ViewContext<Self>,
|
||||||
) -> Task<Result<()>> {
|
) -> Task<Result<()>> {
|
||||||
|
@ -312,8 +310,8 @@ impl FollowableItem for Editor {
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn update_editor_from_message(
|
async fn update_editor_from_message(
|
||||||
this: WeakViewHandle<Editor>,
|
this: WeakView<Editor>,
|
||||||
project: ModelHandle<Project>,
|
project: Model<Project>,
|
||||||
message: proto::update_view::Editor,
|
message: proto::update_view::Editor,
|
||||||
cx: &mut AsyncAppContext,
|
cx: &mut AsyncAppContext,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
|
@ -353,7 +351,7 @@ async fn update_editor_from_message(
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
let buffer_id = excerpt.buffer_id;
|
let buffer_id = excerpt.buffer_id;
|
||||||
let Some(buffer) = project.read(cx).buffer_for_id(buffer_id, cx) else {
|
let Some(buffer) = project.read(cx).buffer_for_id(buffer_id) else {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -430,7 +428,7 @@ async fn update_editor_from_message(
|
||||||
editor.set_scroll_anchor_remote(
|
editor.set_scroll_anchor_remote(
|
||||||
ScrollAnchor {
|
ScrollAnchor {
|
||||||
anchor: scroll_top_anchor,
|
anchor: scroll_top_anchor,
|
||||||
offset: vec2f(message.scroll_x, message.scroll_y),
|
offset: point(message.scroll_x, message.scroll_y),
|
||||||
},
|
},
|
||||||
cx,
|
cx,
|
||||||
);
|
);
|
||||||
|
@ -573,29 +571,26 @@ impl Item for Editor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tab_content<T: 'static>(
|
fn tab_content<T: 'static>(&self, detail: Option<usize>, cx: &AppContext) -> AnyElement<T> {
|
||||||
&self,
|
todo!();
|
||||||
detail: Option<usize>,
|
|
||||||
style: &theme::Tab,
|
// Flex::row()
|
||||||
cx: &AppContext,
|
// .with_child(Label::new(self.title(cx).to_string(), style.label.clone()).into_any())
|
||||||
) -> AnyElement<T> {
|
// .with_children(detail.and_then(|detail| {
|
||||||
Flex::row()
|
// let path = path_for_buffer(&self.buffer, detail, false, cx)?;
|
||||||
.with_child(Label::new(self.title(cx).to_string(), style.label.clone()).into_any())
|
// let description = path.to_string_lossy();
|
||||||
.with_children(detail.and_then(|detail| {
|
// Some(
|
||||||
let path = path_for_buffer(&self.buffer, detail, false, cx)?;
|
// Label::new(
|
||||||
let description = path.to_string_lossy();
|
// util::truncate_and_trailoff(&description, MAX_TAB_TITLE_LEN),
|
||||||
Some(
|
// style.description.text.clone(),
|
||||||
Label::new(
|
// )
|
||||||
util::truncate_and_trailoff(&description, MAX_TAB_TITLE_LEN),
|
// .contained()
|
||||||
style.description.text.clone(),
|
// .with_style(style.description.container)
|
||||||
)
|
// .aligned(),
|
||||||
.contained()
|
// )
|
||||||
.with_style(style.description.container)
|
// }))
|
||||||
.aligned(),
|
// .align_children_center()
|
||||||
)
|
// .into_any()
|
||||||
}))
|
|
||||||
.align_children_center()
|
|
||||||
.into_any()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn for_each_project_item(&self, cx: &AppContext, f: &mut dyn FnMut(usize, &dyn project::Item)) {
|
fn for_each_project_item(&self, cx: &AppContext, f: &mut dyn FnMut(usize, &dyn project::Item)) {
|
||||||
|
@ -646,11 +641,7 @@ impl Item for Editor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn save(
|
fn save(&mut self, project: Model<Project>, cx: &mut ViewContext<Self>) -> Task<Result<()>> {
|
||||||
&mut self,
|
|
||||||
project: ModelHandle<Project>,
|
|
||||||
cx: &mut ViewContext<Self>,
|
|
||||||
) -> Task<Result<()>> {
|
|
||||||
self.report_editor_event("save", None, cx);
|
self.report_editor_event("save", None, cx);
|
||||||
let format = self.perform_format(project.clone(), FormatTrigger::Save, cx);
|
let format = self.perform_format(project.clone(), FormatTrigger::Save, cx);
|
||||||
let buffers = self.buffer().clone().read(cx).all_buffers();
|
let buffers = self.buffer().clone().read(cx).all_buffers();
|
||||||
|
@ -690,7 +681,7 @@ impl Item for Editor {
|
||||||
|
|
||||||
fn save_as(
|
fn save_as(
|
||||||
&mut self,
|
&mut self,
|
||||||
project: ModelHandle<Project>,
|
project: Model<Project>,
|
||||||
abs_path: PathBuf,
|
abs_path: PathBuf,
|
||||||
cx: &mut ViewContext<Self>,
|
cx: &mut ViewContext<Self>,
|
||||||
) -> Task<Result<()>> {
|
) -> Task<Result<()>> {
|
||||||
|
@ -710,11 +701,7 @@ impl Item for Editor {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reload(
|
fn reload(&mut self, project: Model<Project>, cx: &mut ViewContext<Self>) -> Task<Result<()>> {
|
||||||
&mut self,
|
|
||||||
project: ModelHandle<Project>,
|
|
||||||
cx: &mut ViewContext<Self>,
|
|
||||||
) -> Task<Result<()>> {
|
|
||||||
let buffer = self.buffer().clone();
|
let buffer = self.buffer().clone();
|
||||||
let buffers = self.buffer.read(cx).all_buffers();
|
let buffers = self.buffer.read(cx).all_buffers();
|
||||||
let reload_buffers =
|
let reload_buffers =
|
||||||
|
@ -761,11 +748,11 @@ impl Item for Editor {
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_searchable(&self, handle: &ViewHandle<Self>) -> Option<Box<dyn SearchableItemHandle>> {
|
fn as_searchable(&self, handle: &View<Self>) -> Option<Box<dyn SearchableItemHandle>> {
|
||||||
Some(Box::new(handle.clone()))
|
Some(Box::new(handle.clone()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pixel_position_of_cursor(&self, _: &AppContext) -> Option<Vector2F> {
|
fn pixel_position_of_cursor(&self, _: &AppContext) -> Option<gpui::Point<Pixels>> {
|
||||||
self.pixel_position_of_newest_cursor
|
self.pixel_position_of_newest_cursor
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -773,35 +760,36 @@ impl Item for Editor {
|
||||||
ToolbarItemLocation::PrimaryLeft { flex: None }
|
ToolbarItemLocation::PrimaryLeft { flex: None }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn breadcrumbs(&self, theme: &theme::Theme, cx: &AppContext) -> Option<Vec<BreadcrumbText>> {
|
fn breadcrumbs(&self, cx: &AppContext) -> Option<Vec<BreadcrumbText>> {
|
||||||
let cursor = self.selections.newest_anchor().head();
|
todo!();
|
||||||
let multibuffer = &self.buffer().read(cx);
|
// let cursor = self.selections.newest_anchor().head();
|
||||||
let (buffer_id, symbols) =
|
// let multibuffer = &self.buffer().read(cx);
|
||||||
multibuffer.symbols_containing(cursor, Some(&theme.editor.syntax), cx)?;
|
// let (buffer_id, symbols) =
|
||||||
let buffer = multibuffer.buffer(buffer_id)?;
|
// multibuffer.symbols_containing(cursor, Some(&theme.editor.syntax), cx)?;
|
||||||
|
// let buffer = multibuffer.buffer(buffer_id)?;
|
||||||
|
|
||||||
let buffer = buffer.read(cx);
|
// let buffer = buffer.read(cx);
|
||||||
let filename = buffer
|
// let filename = buffer
|
||||||
.snapshot()
|
// .snapshot()
|
||||||
.resolve_file_path(
|
// .resolve_file_path(
|
||||||
cx,
|
// cx,
|
||||||
self.project
|
// self.project
|
||||||
.as_ref()
|
// .as_ref()
|
||||||
.map(|project| project.read(cx).visible_worktrees(cx).count() > 1)
|
// .map(|project| project.read(cx).visible_worktrees(cx).count() > 1)
|
||||||
.unwrap_or_default(),
|
// .unwrap_or_default(),
|
||||||
)
|
// )
|
||||||
.map(|path| path.to_string_lossy().to_string())
|
// .map(|path| path.to_string_lossy().to_string())
|
||||||
.unwrap_or_else(|| "untitled".to_string());
|
// .unwrap_or_else(|| "untitled".to_string());
|
||||||
|
|
||||||
let mut breadcrumbs = vec![BreadcrumbText {
|
// let mut breadcrumbs = vec![BreadcrumbText {
|
||||||
text: filename,
|
// text: filename,
|
||||||
highlights: None,
|
// highlights: None,
|
||||||
}];
|
// }];
|
||||||
breadcrumbs.extend(symbols.into_iter().map(|symbol| BreadcrumbText {
|
// breadcrumbs.extend(symbols.into_iter().map(|symbol| BreadcrumbText {
|
||||||
text: symbol.text,
|
// text: symbol.text,
|
||||||
highlights: Some(symbol.highlight_ranges),
|
// highlights: Some(symbol.highlight_ranges),
|
||||||
}));
|
// }));
|
||||||
Some(breadcrumbs)
|
// Some(breadcrumbs)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn added_to_workspace(&mut self, workspace: &mut Workspace, cx: &mut ViewContext<Self>) {
|
fn added_to_workspace(&mut self, workspace: &mut Workspace, cx: &mut ViewContext<Self>) {
|
||||||
|
@ -810,7 +798,7 @@ impl Item for Editor {
|
||||||
self.workspace = Some((workspace.weak_handle(), workspace.database_id()));
|
self.workspace = Some((workspace.weak_handle(), workspace.database_id()));
|
||||||
|
|
||||||
fn serialize(
|
fn serialize(
|
||||||
buffer: ModelHandle<Buffer>,
|
buffer: Model<Buffer>,
|
||||||
workspace_id: WorkspaceId,
|
workspace_id: WorkspaceId,
|
||||||
item_id: ItemId,
|
item_id: ItemId,
|
||||||
cx: &mut AppContext,
|
cx: &mut AppContext,
|
||||||
|
@ -847,12 +835,12 @@ impl Item for Editor {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize(
|
fn deserialize(
|
||||||
project: ModelHandle<Project>,
|
project: Model<Project>,
|
||||||
_workspace: WeakViewHandle<Workspace>,
|
_workspace: WeakView<Workspace>,
|
||||||
workspace_id: workspace::WorkspaceId,
|
workspace_id: workspace::WorkspaceId,
|
||||||
item_id: ItemId,
|
item_id: ItemId,
|
||||||
cx: &mut ViewContext<Pane>,
|
cx: &mut ViewContext<Pane>,
|
||||||
) -> Task<Result<ViewHandle<Self>>> {
|
) -> Task<Result<View<Self>>> {
|
||||||
let project_item: Result<_> = project.update(cx, |project, cx| {
|
let project_item: Result<_> = project.update(cx, |project, cx| {
|
||||||
// Look up the path with this key associated, create a self with that path
|
// Look up the path with this key associated, create a self with that path
|
||||||
let path = DB
|
let path = DB
|
||||||
|
@ -894,8 +882,8 @@ impl ProjectItem for Editor {
|
||||||
type Item = Buffer;
|
type Item = Buffer;
|
||||||
|
|
||||||
fn for_project_item(
|
fn for_project_item(
|
||||||
project: ModelHandle<Project>,
|
project: Model<Project>,
|
||||||
buffer: ModelHandle<Buffer>,
|
buffer: Model<Buffer>,
|
||||||
cx: &mut ViewContext<Self>,
|
cx: &mut ViewContext<Self>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self::for_buffer(buffer, Some(project), cx)
|
Self::for_buffer(buffer, Some(project), cx)
|
||||||
|
@ -1134,89 +1122,89 @@ pub struct CursorPosition {
|
||||||
_observe_active_editor: Option<Subscription>,
|
_observe_active_editor: Option<Subscription>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for CursorPosition {
|
// impl Default for CursorPosition {
|
||||||
fn default() -> Self {
|
// fn default() -> Self {
|
||||||
Self::new()
|
// Self::new()
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
impl CursorPosition {
|
// impl CursorPosition {
|
||||||
pub fn new() -> Self {
|
// pub fn new() -> Self {
|
||||||
Self {
|
// Self {
|
||||||
position: None,
|
// position: None,
|
||||||
selected_count: 0,
|
// selected_count: 0,
|
||||||
_observe_active_editor: None,
|
// _observe_active_editor: None,
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
fn update_position(&mut self, editor: ViewHandle<Editor>, cx: &mut ViewContext<Self>) {
|
// fn update_position(&mut self, editor: View<Editor>, cx: &mut ViewContext<Self>) {
|
||||||
let editor = editor.read(cx);
|
// let editor = editor.read(cx);
|
||||||
let buffer = editor.buffer().read(cx).snapshot(cx);
|
// let buffer = editor.buffer().read(cx).snapshot(cx);
|
||||||
|
|
||||||
self.selected_count = 0;
|
// self.selected_count = 0;
|
||||||
let mut last_selection: Option<Selection<usize>> = None;
|
// let mut last_selection: Option<Selection<usize>> = None;
|
||||||
for selection in editor.selections.all::<usize>(cx) {
|
// for selection in editor.selections.all::<usize>(cx) {
|
||||||
self.selected_count += selection.end - selection.start;
|
// self.selected_count += selection.end - selection.start;
|
||||||
if last_selection
|
// if last_selection
|
||||||
.as_ref()
|
// .as_ref()
|
||||||
.map_or(true, |last_selection| selection.id > last_selection.id)
|
// .map_or(true, |last_selection| selection.id > last_selection.id)
|
||||||
{
|
// {
|
||||||
last_selection = Some(selection);
|
// last_selection = Some(selection);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
self.position = last_selection.map(|s| s.head().to_point(&buffer));
|
// self.position = last_selection.map(|s| s.head().to_point(&buffer));
|
||||||
|
|
||||||
cx.notify();
|
// cx.notify();
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
impl Entity for CursorPosition {
|
// impl Entity for CursorPosition {
|
||||||
type Event = ();
|
// type Event = ();
|
||||||
}
|
// }
|
||||||
|
|
||||||
impl View for CursorPosition {
|
// impl View for CursorPosition {
|
||||||
fn ui_name() -> &'static str {
|
// fn ui_name() -> &'static str {
|
||||||
"CursorPosition"
|
// "CursorPosition"
|
||||||
}
|
// }
|
||||||
|
|
||||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
|
// fn render(&mut self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
|
||||||
if let Some(position) = self.position {
|
// if let Some(position) = self.position {
|
||||||
let theme = &theme::current(cx).workspace.status_bar;
|
// let theme = &theme::current(cx).workspace.status_bar;
|
||||||
let mut text = format!(
|
// let mut text = format!(
|
||||||
"{}{FILE_ROW_COLUMN_DELIMITER}{}",
|
// "{}{FILE_ROW_COLUMN_DELIMITER}{}",
|
||||||
position.row + 1,
|
// position.row + 1,
|
||||||
position.column + 1
|
// position.column + 1
|
||||||
);
|
// );
|
||||||
if self.selected_count > 0 {
|
// if self.selected_count > 0 {
|
||||||
write!(text, " ({} selected)", self.selected_count).unwrap();
|
// write!(text, " ({} selected)", self.selected_count).unwrap();
|
||||||
}
|
// }
|
||||||
Label::new(text, theme.cursor_position.clone()).into_any()
|
// Label::new(text, theme.cursor_position.clone()).into_any()
|
||||||
} else {
|
// } else {
|
||||||
Empty::new().into_any()
|
// Empty::new().into_any()
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
impl StatusItemView for CursorPosition {
|
// impl StatusItemView for CursorPosition {
|
||||||
fn set_active_pane_item(
|
// fn set_active_pane_item(
|
||||||
&mut self,
|
// &mut self,
|
||||||
active_pane_item: Option<&dyn ItemHandle>,
|
// active_pane_item: Option<&dyn ItemHandle>,
|
||||||
cx: &mut ViewContext<Self>,
|
// cx: &mut ViewContext<Self>,
|
||||||
) {
|
// ) {
|
||||||
if let Some(editor) = active_pane_item.and_then(|item| item.act_as::<Editor>(cx)) {
|
// if let Some(editor) = active_pane_item.and_then(|item| item.act_as::<Editor>(cx)) {
|
||||||
self._observe_active_editor = Some(cx.observe(&editor, Self::update_position));
|
// self._observe_active_editor = Some(cx.observe(&editor, Self::update_position));
|
||||||
self.update_position(editor, cx);
|
// self.update_position(editor, cx);
|
||||||
} else {
|
// } else {
|
||||||
self.position = None;
|
// self.position = None;
|
||||||
self._observe_active_editor = None;
|
// self._observe_active_editor = None;
|
||||||
}
|
// }
|
||||||
|
|
||||||
cx.notify();
|
// cx.notify();
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
fn path_for_buffer<'a>(
|
fn path_for_buffer<'a>(
|
||||||
buffer: &ModelHandle<MultiBuffer>,
|
buffer: &Model<MultiBuffer>,
|
||||||
height: usize,
|
height: usize,
|
||||||
include_filename: bool,
|
include_filename: bool,
|
||||||
cx: &'a AppContext,
|
cx: &'a AppContext,
|
||||||
|
|
|
@ -919,7 +919,7 @@ mod tests {
|
||||||
|
|
||||||
fn init_test(cx: &mut gpui::AppContext) {
|
fn init_test(cx: &mut gpui::AppContext) {
|
||||||
cx.set_global(SettingsStore::test(cx));
|
cx.set_global(SettingsStore::test(cx));
|
||||||
theme::init((), cx);
|
theme::init(cx);
|
||||||
language::init(cx);
|
language::init(cx);
|
||||||
crate::init(cx);
|
crate::init(cx);
|
||||||
Project::init_settings(cx);
|
Project::init_settings(cx);
|
||||||
|
|
|
@ -1,152 +1,148 @@
|
||||||
use gpui::{actions, geometry::vector::Vector2F, AppContext, Axis, ViewContext};
|
use gpui::AppContext;
|
||||||
use language::Bias;
|
|
||||||
|
|
||||||
use crate::{Editor, EditorMode};
|
// actions!(
|
||||||
|
// editor,
|
||||||
use super::{autoscroll::Autoscroll, scroll_amount::ScrollAmount, ScrollAnchor};
|
// [
|
||||||
|
// LineDown,
|
||||||
actions!(
|
// LineUp,
|
||||||
editor,
|
// HalfPageDown,
|
||||||
[
|
// HalfPageUp,
|
||||||
LineDown,
|
// PageDown,
|
||||||
LineUp,
|
// PageUp,
|
||||||
HalfPageDown,
|
// NextScreen,
|
||||||
HalfPageUp,
|
// ScrollCursorTop,
|
||||||
PageDown,
|
// ScrollCursorCenter,
|
||||||
PageUp,
|
// ScrollCursorBottom,
|
||||||
NextScreen,
|
// ]
|
||||||
ScrollCursorTop,
|
// );
|
||||||
ScrollCursorCenter,
|
|
||||||
ScrollCursorBottom,
|
|
||||||
]
|
|
||||||
);
|
|
||||||
|
|
||||||
pub fn init(cx: &mut AppContext) {
|
pub fn init(cx: &mut AppContext) {
|
||||||
cx.add_action(Editor::next_screen);
|
/// todo!()
|
||||||
cx.add_action(Editor::scroll_cursor_top);
|
// cx.add_action(Editor::next_screen);
|
||||||
cx.add_action(Editor::scroll_cursor_center);
|
// cx.add_action(Editor::scroll_cursor_top);
|
||||||
cx.add_action(Editor::scroll_cursor_bottom);
|
// cx.add_action(Editor::scroll_cursor_center);
|
||||||
cx.add_action(|this: &mut Editor, _: &LineDown, cx| {
|
// cx.add_action(Editor::scroll_cursor_bottom);
|
||||||
this.scroll_screen(&ScrollAmount::Line(1.), cx)
|
// cx.add_action(|this: &mut Editor, _: &LineDown, cx| {
|
||||||
});
|
// this.scroll_screen(&ScrollAmount::Line(1.), cx)
|
||||||
cx.add_action(|this: &mut Editor, _: &LineUp, cx| {
|
// });
|
||||||
this.scroll_screen(&ScrollAmount::Line(-1.), cx)
|
// cx.add_action(|this: &mut Editor, _: &LineUp, cx| {
|
||||||
});
|
// this.scroll_screen(&ScrollAmount::Line(-1.), cx)
|
||||||
cx.add_action(|this: &mut Editor, _: &HalfPageDown, cx| {
|
// });
|
||||||
this.scroll_screen(&ScrollAmount::Page(0.5), cx)
|
// cx.add_action(|this: &mut Editor, _: &HalfPageDown, cx| {
|
||||||
});
|
// this.scroll_screen(&ScrollAmount::Page(0.5), cx)
|
||||||
cx.add_action(|this: &mut Editor, _: &HalfPageUp, cx| {
|
// });
|
||||||
this.scroll_screen(&ScrollAmount::Page(-0.5), cx)
|
// cx.add_action(|this: &mut Editor, _: &HalfPageUp, cx| {
|
||||||
});
|
// this.scroll_screen(&ScrollAmount::Page(-0.5), cx)
|
||||||
cx.add_action(|this: &mut Editor, _: &PageDown, cx| {
|
// });
|
||||||
this.scroll_screen(&ScrollAmount::Page(1.), cx)
|
// cx.add_action(|this: &mut Editor, _: &PageDown, cx| {
|
||||||
});
|
// this.scroll_screen(&ScrollAmount::Page(1.), cx)
|
||||||
cx.add_action(|this: &mut Editor, _: &PageUp, cx| {
|
// });
|
||||||
this.scroll_screen(&ScrollAmount::Page(-1.), cx)
|
// cx.add_action(|this: &mut Editor, _: &PageUp, cx| {
|
||||||
});
|
// this.scroll_screen(&ScrollAmount::Page(-1.), cx)
|
||||||
|
// });
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Editor {
|
// impl Editor {
|
||||||
pub fn next_screen(&mut self, _: &NextScreen, cx: &mut ViewContext<Editor>) -> Option<()> {
|
// pub fn next_screen(&mut self, _: &NextScreen, cx: &mut ViewContext<Editor>) -> Option<()> {
|
||||||
if self.take_rename(true, cx).is_some() {
|
// if self.take_rename(true, cx).is_some() {
|
||||||
return None;
|
// return None;
|
||||||
}
|
// }
|
||||||
|
|
||||||
if self.mouse_context_menu.read(cx).visible() {
|
// if self.mouse_context_menu.read(cx).visible() {
|
||||||
return None;
|
// return None;
|
||||||
}
|
// }
|
||||||
|
|
||||||
if matches!(self.mode, EditorMode::SingleLine) {
|
// if matches!(self.mode, EditorMode::SingleLine) {
|
||||||
cx.propagate_action();
|
// cx.propagate_action();
|
||||||
return None;
|
// return None;
|
||||||
}
|
// }
|
||||||
self.request_autoscroll(Autoscroll::Next, cx);
|
// self.request_autoscroll(Autoscroll::Next, cx);
|
||||||
Some(())
|
// Some(())
|
||||||
}
|
// }
|
||||||
|
|
||||||
pub fn scroll(
|
// pub fn scroll(
|
||||||
&mut self,
|
// &mut self,
|
||||||
scroll_position: Vector2F,
|
// scroll_position: Vector2F,
|
||||||
axis: Option<Axis>,
|
// axis: Option<Axis>,
|
||||||
cx: &mut ViewContext<Self>,
|
// cx: &mut ViewContext<Self>,
|
||||||
) {
|
// ) {
|
||||||
self.scroll_manager.update_ongoing_scroll(axis);
|
// self.scroll_manager.update_ongoing_scroll(axis);
|
||||||
self.set_scroll_position(scroll_position, cx);
|
// self.set_scroll_position(scroll_position, cx);
|
||||||
}
|
// }
|
||||||
|
|
||||||
fn scroll_cursor_top(editor: &mut Editor, _: &ScrollCursorTop, cx: &mut ViewContext<Editor>) {
|
// fn scroll_cursor_top(editor: &mut Editor, _: &ScrollCursorTop, cx: &mut ViewContext<Editor>) {
|
||||||
let snapshot = editor.snapshot(cx).display_snapshot;
|
// let snapshot = editor.snapshot(cx).display_snapshot;
|
||||||
let scroll_margin_rows = editor.vertical_scroll_margin() as u32;
|
// let scroll_margin_rows = editor.vertical_scroll_margin() as u32;
|
||||||
|
|
||||||
let mut new_screen_top = editor.selections.newest_display(cx).head();
|
// let mut new_screen_top = editor.selections.newest_display(cx).head();
|
||||||
*new_screen_top.row_mut() = new_screen_top.row().saturating_sub(scroll_margin_rows);
|
// *new_screen_top.row_mut() = new_screen_top.row().saturating_sub(scroll_margin_rows);
|
||||||
*new_screen_top.column_mut() = 0;
|
// *new_screen_top.column_mut() = 0;
|
||||||
let new_screen_top = new_screen_top.to_offset(&snapshot, Bias::Left);
|
// let new_screen_top = new_screen_top.to_offset(&snapshot, Bias::Left);
|
||||||
let new_anchor = snapshot.buffer_snapshot.anchor_before(new_screen_top);
|
// let new_anchor = snapshot.buffer_snapshot.anchor_before(new_screen_top);
|
||||||
|
|
||||||
editor.set_scroll_anchor(
|
// editor.set_scroll_anchor(
|
||||||
ScrollAnchor {
|
// ScrollAnchor {
|
||||||
anchor: new_anchor,
|
// anchor: new_anchor,
|
||||||
offset: Default::default(),
|
// offset: Default::default(),
|
||||||
},
|
// },
|
||||||
cx,
|
// cx,
|
||||||
)
|
// )
|
||||||
}
|
// }
|
||||||
|
|
||||||
fn scroll_cursor_center(
|
// fn scroll_cursor_center(
|
||||||
editor: &mut Editor,
|
// editor: &mut Editor,
|
||||||
_: &ScrollCursorCenter,
|
// _: &ScrollCursorCenter,
|
||||||
cx: &mut ViewContext<Editor>,
|
// cx: &mut ViewContext<Editor>,
|
||||||
) {
|
// ) {
|
||||||
let snapshot = editor.snapshot(cx).display_snapshot;
|
// let snapshot = editor.snapshot(cx).display_snapshot;
|
||||||
let visible_rows = if let Some(visible_rows) = editor.visible_line_count() {
|
// let visible_rows = if let Some(visible_rows) = editor.visible_line_count() {
|
||||||
visible_rows as u32
|
// visible_rows as u32
|
||||||
} else {
|
// } else {
|
||||||
return;
|
// return;
|
||||||
};
|
// };
|
||||||
|
|
||||||
let mut new_screen_top = editor.selections.newest_display(cx).head();
|
// let mut new_screen_top = editor.selections.newest_display(cx).head();
|
||||||
*new_screen_top.row_mut() = new_screen_top.row().saturating_sub(visible_rows / 2);
|
// *new_screen_top.row_mut() = new_screen_top.row().saturating_sub(visible_rows / 2);
|
||||||
*new_screen_top.column_mut() = 0;
|
// *new_screen_top.column_mut() = 0;
|
||||||
let new_screen_top = new_screen_top.to_offset(&snapshot, Bias::Left);
|
// let new_screen_top = new_screen_top.to_offset(&snapshot, Bias::Left);
|
||||||
let new_anchor = snapshot.buffer_snapshot.anchor_before(new_screen_top);
|
// let new_anchor = snapshot.buffer_snapshot.anchor_before(new_screen_top);
|
||||||
|
|
||||||
editor.set_scroll_anchor(
|
// editor.set_scroll_anchor(
|
||||||
ScrollAnchor {
|
// ScrollAnchor {
|
||||||
anchor: new_anchor,
|
// anchor: new_anchor,
|
||||||
offset: Default::default(),
|
// offset: Default::default(),
|
||||||
},
|
// },
|
||||||
cx,
|
// cx,
|
||||||
)
|
// )
|
||||||
}
|
// }
|
||||||
|
|
||||||
fn scroll_cursor_bottom(
|
// fn scroll_cursor_bottom(
|
||||||
editor: &mut Editor,
|
// editor: &mut Editor,
|
||||||
_: &ScrollCursorBottom,
|
// _: &ScrollCursorBottom,
|
||||||
cx: &mut ViewContext<Editor>,
|
// cx: &mut ViewContext<Editor>,
|
||||||
) {
|
// ) {
|
||||||
let snapshot = editor.snapshot(cx).display_snapshot;
|
// let snapshot = editor.snapshot(cx).display_snapshot;
|
||||||
let scroll_margin_rows = editor.vertical_scroll_margin() as u32;
|
// let scroll_margin_rows = editor.vertical_scroll_margin() as u32;
|
||||||
let visible_rows = if let Some(visible_rows) = editor.visible_line_count() {
|
// let visible_rows = if let Some(visible_rows) = editor.visible_line_count() {
|
||||||
visible_rows as u32
|
// visible_rows as u32
|
||||||
} else {
|
// } else {
|
||||||
return;
|
// return;
|
||||||
};
|
// };
|
||||||
|
|
||||||
let mut new_screen_top = editor.selections.newest_display(cx).head();
|
// let mut new_screen_top = editor.selections.newest_display(cx).head();
|
||||||
*new_screen_top.row_mut() = new_screen_top
|
// *new_screen_top.row_mut() = new_screen_top
|
||||||
.row()
|
// .row()
|
||||||
.saturating_sub(visible_rows.saturating_sub(scroll_margin_rows));
|
// .saturating_sub(visible_rows.saturating_sub(scroll_margin_rows));
|
||||||
*new_screen_top.column_mut() = 0;
|
// *new_screen_top.column_mut() = 0;
|
||||||
let new_screen_top = new_screen_top.to_offset(&snapshot, Bias::Left);
|
// let new_screen_top = new_screen_top.to_offset(&snapshot, Bias::Left);
|
||||||
let new_anchor = snapshot.buffer_snapshot.anchor_before(new_screen_top);
|
// let new_anchor = snapshot.buffer_snapshot.anchor_before(new_screen_top);
|
||||||
|
|
||||||
editor.set_scroll_anchor(
|
// editor.set_scroll_anchor(
|
||||||
ScrollAnchor {
|
// ScrollAnchor {
|
||||||
anchor: new_anchor,
|
// anchor: new_anchor,
|
||||||
offset: Default::default(),
|
// offset: Default::default(),
|
||||||
},
|
// },
|
||||||
cx,
|
// cx,
|
||||||
)
|
// )
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
|
@ -6,7 +6,7 @@ use std::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use collections::HashMap;
|
use collections::HashMap;
|
||||||
use gpui::{AppContext, ModelHandle};
|
use gpui::{AppContext, Model};
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use language::{Bias, Point, Selection, SelectionGoal, TextDimension, ToPoint};
|
use language::{Bias, Point, Selection, SelectionGoal, TextDimension, ToPoint};
|
||||||
use util::post_inc;
|
use util::post_inc;
|
||||||
|
|
|
@ -6,7 +6,7 @@ use crate::{
|
||||||
DisplayPoint, Editor, EditorMode, MultiBuffer,
|
DisplayPoint, Editor, EditorMode, MultiBuffer,
|
||||||
};
|
};
|
||||||
|
|
||||||
use gpui::{ModelHandle, ViewContext};
|
use gpui::{Model, ViewContext};
|
||||||
|
|
||||||
use project::Project;
|
use project::Project;
|
||||||
use util::test::{marked_text_offsets, marked_text_ranges};
|
use util::test::{marked_text_offsets, marked_text_ranges};
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
pub use crate::{
|
pub use crate::{
|
||||||
diagnostic_set::DiagnosticSet,
|
diagnostic_set::DiagnosticSet,
|
||||||
highlight_map::{HighlightId, HighlightMap},
|
highlight_map::{HighlightId, HighlightMap},
|
||||||
|
markdown::ParsedMarkdown,
|
||||||
proto, BracketPair, Grammar, Language, LanguageConfig, LanguageRegistry, PLAIN_TEXT,
|
proto, BracketPair, Grammar, Language, LanguageConfig, LanguageRegistry, PLAIN_TEXT,
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
|
|
|
@ -13,9 +13,12 @@ mod status_bar;
|
||||||
mod toolbar;
|
mod toolbar;
|
||||||
mod workspace_settings;
|
mod workspace_settings;
|
||||||
|
|
||||||
use crate::persistence::model::{
|
pub use crate::persistence::{
|
||||||
DockData, DockStructure, SerializedItem, SerializedPane, SerializedPaneGroup,
|
model::{
|
||||||
SerializedWorkspace,
|
DockData, DockStructure, ItemId, SerializedItem, SerializedPane, SerializedPaneGroup,
|
||||||
|
SerializedWorkspace,
|
||||||
|
},
|
||||||
|
WorkspaceDb,
|
||||||
};
|
};
|
||||||
use anyhow::{anyhow, Context as _, Result};
|
use anyhow::{anyhow, Context as _, Result};
|
||||||
use call2::ActiveCall;
|
use call2::ActiveCall;
|
||||||
|
@ -44,15 +47,13 @@ use node_runtime::NodeRuntime;
|
||||||
use notifications::{simple_message_notification::MessageNotification, NotificationHandle};
|
use notifications::{simple_message_notification::MessageNotification, NotificationHandle};
|
||||||
pub use pane::*;
|
pub use pane::*;
|
||||||
pub use pane_group::*;
|
pub use pane_group::*;
|
||||||
use persistence::{
|
use persistence::{model::WorkspaceLocation, DB};
|
||||||
model::{ItemId, WorkspaceLocation},
|
|
||||||
DB,
|
|
||||||
};
|
|
||||||
use postage::stream::Stream;
|
use postage::stream::Stream;
|
||||||
use project2::{Project, ProjectEntryId, ProjectPath, Worktree};
|
use project2::{Project, ProjectEntryId, ProjectPath, Worktree};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use settings2::Settings;
|
use settings2::Settings;
|
||||||
use status_bar::StatusBar;
|
use status_bar::StatusBar;
|
||||||
|
pub use status_bar::StatusItemView;
|
||||||
use std::{
|
use std::{
|
||||||
any::TypeId,
|
any::TypeId,
|
||||||
borrow::Cow,
|
borrow::Cow,
|
||||||
|
|
|
@ -34,7 +34,7 @@ copilot = { package = "copilot2", path = "../copilot2" }
|
||||||
# copilot_button = { path = "../copilot_button" }
|
# copilot_button = { path = "../copilot_button" }
|
||||||
# diagnostics = { path = "../diagnostics" }
|
# diagnostics = { path = "../diagnostics" }
|
||||||
db = { package = "db2", path = "../db2" }
|
db = { package = "db2", path = "../db2" }
|
||||||
# editor = { path = "../editor" }
|
editor = { package="editor2", path = "../editor2" }
|
||||||
# feedback = { path = "../feedback" }
|
# feedback = { path = "../feedback" }
|
||||||
# file_finder = { path = "../file_finder" }
|
# file_finder = { path = "../file_finder" }
|
||||||
# search = { path = "../search" }
|
# search = { path = "../search" }
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue