Tab size is pulled properly from settings instead of hardcoded
This commit is contained in:
parent
866ffdd4ae
commit
1812480cbb
15 changed files with 128 additions and 87 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -3632,6 +3632,7 @@ dependencies = [
|
||||||
"rpc",
|
"rpc",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
"settings",
|
||||||
"sha2 0.10.2",
|
"sha2 0.10.2",
|
||||||
"similar",
|
"similar",
|
||||||
"smol",
|
"smol",
|
||||||
|
|
|
@ -12,6 +12,7 @@ use gpui::{
|
||||||
Entity, ModelContext, ModelHandle,
|
Entity, ModelContext, ModelHandle,
|
||||||
};
|
};
|
||||||
use language::{Point, Subscription as BufferSubscription};
|
use language::{Point, Subscription as BufferSubscription};
|
||||||
|
use settings::Settings;
|
||||||
use std::{any::TypeId, fmt::Debug, ops::Range, sync::Arc};
|
use std::{any::TypeId, fmt::Debug, ops::Range, sync::Arc};
|
||||||
use sum_tree::{Bias, TreeMap};
|
use sum_tree::{Bias, TreeMap};
|
||||||
use tab_map::TabMap;
|
use tab_map::TabMap;
|
||||||
|
@ -46,8 +47,6 @@ impl Entity for DisplayMap {
|
||||||
impl DisplayMap {
|
impl DisplayMap {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
buffer: ModelHandle<MultiBuffer>,
|
buffer: ModelHandle<MultiBuffer>,
|
||||||
// TODO - remove. read tab_size from settings inside
|
|
||||||
tab_size: usize,
|
|
||||||
font_id: FontId,
|
font_id: FontId,
|
||||||
font_size: f32,
|
font_size: f32,
|
||||||
wrap_width: Option<f32>,
|
wrap_width: Option<f32>,
|
||||||
|
@ -56,6 +55,8 @@ impl DisplayMap {
|
||||||
cx: &mut ModelContext<Self>,
|
cx: &mut ModelContext<Self>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let buffer_subscription = buffer.update(cx, |buffer, _| buffer.subscribe());
|
let buffer_subscription = buffer.update(cx, |buffer, _| buffer.subscribe());
|
||||||
|
|
||||||
|
let tab_size = Self::tab_size(&buffer, cx);
|
||||||
let (fold_map, snapshot) = FoldMap::new(buffer.read(cx).snapshot(cx));
|
let (fold_map, snapshot) = FoldMap::new(buffer.read(cx).snapshot(cx));
|
||||||
let (tab_map, snapshot) = TabMap::new(snapshot, tab_size);
|
let (tab_map, snapshot) = TabMap::new(snapshot, tab_size);
|
||||||
let (wrap_map, snapshot) = WrapMap::new(snapshot, font_id, font_size, wrap_width, cx);
|
let (wrap_map, snapshot) = WrapMap::new(snapshot, font_id, font_size, wrap_width, cx);
|
||||||
|
@ -78,8 +79,8 @@ impl DisplayMap {
|
||||||
let edits = self.buffer_subscription.consume().into_inner();
|
let edits = self.buffer_subscription.consume().into_inner();
|
||||||
let (folds_snapshot, edits) = self.fold_map.read(buffer_snapshot, edits);
|
let (folds_snapshot, edits) = self.fold_map.read(buffer_snapshot, edits);
|
||||||
|
|
||||||
// TODO: Pull tabsize out of cx and pass it to sync
|
let tab_size = Self::tab_size(&self.buffer, cx);
|
||||||
let (tabs_snapshot, edits) = self.tab_map.sync(folds_snapshot.clone(), edits);
|
let (tabs_snapshot, edits) = self.tab_map.sync(folds_snapshot.clone(), edits, tab_size);
|
||||||
let (wraps_snapshot, edits) = self
|
let (wraps_snapshot, edits) = self
|
||||||
.wrap_map
|
.wrap_map
|
||||||
.update(cx, |map, cx| map.sync(tabs_snapshot.clone(), edits, cx));
|
.update(cx, |map, cx| map.sync(tabs_snapshot.clone(), edits, cx));
|
||||||
|
@ -103,14 +104,15 @@ impl DisplayMap {
|
||||||
) {
|
) {
|
||||||
let snapshot = self.buffer.read(cx).snapshot(cx);
|
let snapshot = self.buffer.read(cx).snapshot(cx);
|
||||||
let edits = self.buffer_subscription.consume().into_inner();
|
let edits = self.buffer_subscription.consume().into_inner();
|
||||||
|
let tab_size = Self::tab_size(&self.buffer, cx);
|
||||||
let (mut fold_map, snapshot, edits) = self.fold_map.write(snapshot, edits);
|
let (mut fold_map, snapshot, edits) = self.fold_map.write(snapshot, edits);
|
||||||
let (snapshot, edits) = self.tab_map.sync(snapshot, edits);
|
let (snapshot, edits) = self.tab_map.sync(snapshot, edits, tab_size);
|
||||||
let (snapshot, edits) = self
|
let (snapshot, edits) = self
|
||||||
.wrap_map
|
.wrap_map
|
||||||
.update(cx, |map, cx| map.sync(snapshot, edits, cx));
|
.update(cx, |map, cx| map.sync(snapshot, edits, cx));
|
||||||
self.block_map.read(snapshot, edits);
|
self.block_map.read(snapshot, edits);
|
||||||
let (snapshot, edits) = fold_map.fold(ranges);
|
let (snapshot, edits) = fold_map.fold(ranges);
|
||||||
let (snapshot, edits) = self.tab_map.sync(snapshot, edits);
|
let (snapshot, edits) = self.tab_map.sync(snapshot, edits, tab_size);
|
||||||
let (snapshot, edits) = self
|
let (snapshot, edits) = self
|
||||||
.wrap_map
|
.wrap_map
|
||||||
.update(cx, |map, cx| map.sync(snapshot, edits, cx));
|
.update(cx, |map, cx| map.sync(snapshot, edits, cx));
|
||||||
|
@ -125,14 +127,15 @@ impl DisplayMap {
|
||||||
) {
|
) {
|
||||||
let snapshot = self.buffer.read(cx).snapshot(cx);
|
let snapshot = self.buffer.read(cx).snapshot(cx);
|
||||||
let edits = self.buffer_subscription.consume().into_inner();
|
let edits = self.buffer_subscription.consume().into_inner();
|
||||||
|
let tab_size = Self::tab_size(&self.buffer, cx);
|
||||||
let (mut fold_map, snapshot, edits) = self.fold_map.write(snapshot, edits);
|
let (mut fold_map, snapshot, edits) = self.fold_map.write(snapshot, edits);
|
||||||
let (snapshot, edits) = self.tab_map.sync(snapshot, edits);
|
let (snapshot, edits) = self.tab_map.sync(snapshot, edits, tab_size);
|
||||||
let (snapshot, edits) = self
|
let (snapshot, edits) = self
|
||||||
.wrap_map
|
.wrap_map
|
||||||
.update(cx, |map, cx| map.sync(snapshot, edits, cx));
|
.update(cx, |map, cx| map.sync(snapshot, edits, cx));
|
||||||
self.block_map.read(snapshot, edits);
|
self.block_map.read(snapshot, edits);
|
||||||
let (snapshot, edits) = fold_map.unfold(ranges, inclusive);
|
let (snapshot, edits) = fold_map.unfold(ranges, inclusive);
|
||||||
let (snapshot, edits) = self.tab_map.sync(snapshot, edits);
|
let (snapshot, edits) = self.tab_map.sync(snapshot, edits, tab_size);
|
||||||
let (snapshot, edits) = self
|
let (snapshot, edits) = self
|
||||||
.wrap_map
|
.wrap_map
|
||||||
.update(cx, |map, cx| map.sync(snapshot, edits, cx));
|
.update(cx, |map, cx| map.sync(snapshot, edits, cx));
|
||||||
|
@ -146,8 +149,9 @@ impl DisplayMap {
|
||||||
) -> Vec<BlockId> {
|
) -> Vec<BlockId> {
|
||||||
let snapshot = self.buffer.read(cx).snapshot(cx);
|
let snapshot = self.buffer.read(cx).snapshot(cx);
|
||||||
let edits = self.buffer_subscription.consume().into_inner();
|
let edits = self.buffer_subscription.consume().into_inner();
|
||||||
|
let tab_size = Self::tab_size(&self.buffer, cx);
|
||||||
let (snapshot, edits) = self.fold_map.read(snapshot, edits);
|
let (snapshot, edits) = self.fold_map.read(snapshot, edits);
|
||||||
let (snapshot, edits) = self.tab_map.sync(snapshot, edits);
|
let (snapshot, edits) = self.tab_map.sync(snapshot, edits, tab_size);
|
||||||
let (snapshot, edits) = self
|
let (snapshot, edits) = self
|
||||||
.wrap_map
|
.wrap_map
|
||||||
.update(cx, |map, cx| map.sync(snapshot, edits, cx));
|
.update(cx, |map, cx| map.sync(snapshot, edits, cx));
|
||||||
|
@ -162,8 +166,9 @@ impl DisplayMap {
|
||||||
pub fn remove_blocks(&mut self, ids: HashSet<BlockId>, cx: &mut ModelContext<Self>) {
|
pub fn remove_blocks(&mut self, ids: HashSet<BlockId>, cx: &mut ModelContext<Self>) {
|
||||||
let snapshot = self.buffer.read(cx).snapshot(cx);
|
let snapshot = self.buffer.read(cx).snapshot(cx);
|
||||||
let edits = self.buffer_subscription.consume().into_inner();
|
let edits = self.buffer_subscription.consume().into_inner();
|
||||||
|
let tab_size = Self::tab_size(&self.buffer, cx);
|
||||||
let (snapshot, edits) = self.fold_map.read(snapshot, edits);
|
let (snapshot, edits) = self.fold_map.read(snapshot, edits);
|
||||||
let (snapshot, edits) = self.tab_map.sync(snapshot, edits);
|
let (snapshot, edits) = self.tab_map.sync(snapshot, edits, tab_size);
|
||||||
let (snapshot, edits) = self
|
let (snapshot, edits) = self
|
||||||
.wrap_map
|
.wrap_map
|
||||||
.update(cx, |map, cx| map.sync(snapshot, edits, cx));
|
.update(cx, |map, cx| map.sync(snapshot, edits, cx));
|
||||||
|
@ -198,6 +203,11 @@ impl DisplayMap {
|
||||||
.update(cx, |map, cx| map.set_wrap_width(width, cx))
|
.update(cx, |map, cx| map.set_wrap_width(width, cx))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn tab_size(buffer: &ModelHandle<MultiBuffer>, cx: &mut ModelContext<Self>) -> u32 {
|
||||||
|
let language_name = buffer.read(cx).language(cx).map(|language| language.name());
|
||||||
|
cx.global::<Settings>().tab_size(language_name.as_deref())
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub fn is_rewrapping(&self, cx: &gpui::AppContext) -> bool {
|
pub fn is_rewrapping(&self, cx: &gpui::AppContext) -> bool {
|
||||||
self.wrap_map.read(cx).is_rewrapping()
|
self.wrap_map.read(cx).is_rewrapping()
|
||||||
|
@ -539,6 +549,8 @@ pub mod tests {
|
||||||
log::info!("tab size: {}", tab_size);
|
log::info!("tab size: {}", tab_size);
|
||||||
log::info!("wrap width: {:?}", wrap_width);
|
log::info!("wrap width: {:?}", wrap_width);
|
||||||
|
|
||||||
|
cx.update(|cx| cx.set_global(Settings::test(cx)));
|
||||||
|
|
||||||
let buffer = cx.update(|cx| {
|
let buffer = cx.update(|cx| {
|
||||||
if rng.gen() {
|
if rng.gen() {
|
||||||
let len = rng.gen_range(0..10);
|
let len = rng.gen_range(0..10);
|
||||||
|
@ -552,7 +564,6 @@ pub mod tests {
|
||||||
let map = cx.add_model(|cx| {
|
let map = cx.add_model(|cx| {
|
||||||
DisplayMap::new(
|
DisplayMap::new(
|
||||||
buffer.clone(),
|
buffer.clone(),
|
||||||
tab_size,
|
|
||||||
font_id,
|
font_id,
|
||||||
font_size,
|
font_size,
|
||||||
wrap_width,
|
wrap_width,
|
||||||
|
@ -762,27 +773,18 @@ pub mod tests {
|
||||||
|
|
||||||
let font_cache = cx.font_cache();
|
let font_cache = cx.font_cache();
|
||||||
|
|
||||||
let tab_size = 4;
|
|
||||||
let family_id = font_cache.load_family(&["Helvetica"]).unwrap();
|
let family_id = font_cache.load_family(&["Helvetica"]).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 = 12.0;
|
let font_size = 12.0;
|
||||||
let wrap_width = Some(64.);
|
let wrap_width = Some(64.);
|
||||||
|
cx.set_global(Settings::test(cx));
|
||||||
|
|
||||||
let text = "one two three four five\nsix seven eight";
|
let text = "one two three four five\nsix seven eight";
|
||||||
let buffer = MultiBuffer::build_simple(text, cx);
|
let buffer = MultiBuffer::build_simple(text, cx);
|
||||||
let map = cx.add_model(|cx| {
|
let map = cx.add_model(|cx| {
|
||||||
DisplayMap::new(
|
DisplayMap::new(buffer.clone(), font_id, font_size, wrap_width, 1, 1, cx)
|
||||||
buffer.clone(),
|
|
||||||
tab_size,
|
|
||||||
font_id,
|
|
||||||
font_size,
|
|
||||||
wrap_width,
|
|
||||||
1,
|
|
||||||
1,
|
|
||||||
cx,
|
|
||||||
)
|
|
||||||
});
|
});
|
||||||
|
|
||||||
let snapshot = map.update(cx, |map, cx| map.snapshot(cx));
|
let snapshot = map.update(cx, |map, cx| map.snapshot(cx));
|
||||||
|
@ -850,18 +852,17 @@ pub mod tests {
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
fn test_text_chunks(cx: &mut gpui::MutableAppContext) {
|
fn test_text_chunks(cx: &mut gpui::MutableAppContext) {
|
||||||
|
cx.set_global(Settings::test(cx));
|
||||||
let text = sample_text(6, 6, 'a');
|
let text = sample_text(6, 6, 'a');
|
||||||
let buffer = MultiBuffer::build_simple(&text, cx);
|
let buffer = MultiBuffer::build_simple(&text, cx);
|
||||||
let tab_size = 4;
|
|
||||||
let family_id = cx.font_cache().load_family(&["Helvetica"]).unwrap();
|
let family_id = cx.font_cache().load_family(&["Helvetica"]).unwrap();
|
||||||
let font_id = cx
|
let font_id = cx
|
||||||
.font_cache()
|
.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;
|
||||||
let map = cx.add_model(|cx| {
|
let map =
|
||||||
DisplayMap::new(buffer.clone(), tab_size, font_id, font_size, None, 1, 1, cx)
|
cx.add_model(|cx| DisplayMap::new(buffer.clone(), font_id, font_size, None, 1, 1, cx));
|
||||||
});
|
|
||||||
buffer.update(cx, |buffer, cx| {
|
buffer.update(cx, |buffer, cx| {
|
||||||
buffer.edit(
|
buffer.edit(
|
||||||
vec![
|
vec![
|
||||||
|
@ -926,12 +927,17 @@ pub mod tests {
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
);
|
);
|
||||||
language.set_theme(&theme);
|
language.set_theme(&theme);
|
||||||
|
cx.update(|cx| {
|
||||||
|
cx.set_global(Settings {
|
||||||
|
tab_size: 2,
|
||||||
|
..Settings::test(cx)
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
let buffer = cx.add_model(|cx| Buffer::new(0, text, cx).with_language(language, cx));
|
let buffer = cx.add_model(|cx| Buffer::new(0, text, cx).with_language(language, cx));
|
||||||
buffer.condition(&cx, |buf, _| !buf.is_parsing()).await;
|
buffer.condition(&cx, |buf, _| !buf.is_parsing()).await;
|
||||||
let buffer = cx.add_model(|cx| MultiBuffer::singleton(buffer, cx));
|
let buffer = cx.add_model(|cx| MultiBuffer::singleton(buffer, cx));
|
||||||
|
|
||||||
let tab_size = 2;
|
|
||||||
let font_cache = cx.font_cache();
|
let font_cache = cx.font_cache();
|
||||||
let family_id = font_cache.load_family(&["Helvetica"]).unwrap();
|
let family_id = font_cache.load_family(&["Helvetica"]).unwrap();
|
||||||
let font_id = font_cache
|
let font_id = font_cache
|
||||||
|
@ -939,8 +945,7 @@ pub mod tests {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let font_size = 14.0;
|
let font_size = 14.0;
|
||||||
|
|
||||||
let map = cx
|
let map = cx.add_model(|cx| DisplayMap::new(buffer, font_id, font_size, None, 1, 1, cx));
|
||||||
.add_model(|cx| DisplayMap::new(buffer, tab_size, font_id, font_size, None, 1, 1, cx));
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
cx.update(|cx| syntax_chunks(0..5, &map, &theme, cx)),
|
cx.update(|cx| syntax_chunks(0..5, &map, &theme, cx)),
|
||||||
vec![
|
vec![
|
||||||
|
@ -1014,22 +1019,22 @@ pub mod tests {
|
||||||
);
|
);
|
||||||
language.set_theme(&theme);
|
language.set_theme(&theme);
|
||||||
|
|
||||||
|
cx.update(|cx| cx.set_global(Settings::test(cx)));
|
||||||
|
|
||||||
let buffer = cx.add_model(|cx| Buffer::new(0, text, cx).with_language(language, cx));
|
let buffer = cx.add_model(|cx| Buffer::new(0, text, cx).with_language(language, cx));
|
||||||
buffer.condition(&cx, |buf, _| !buf.is_parsing()).await;
|
buffer.condition(&cx, |buf, _| !buf.is_parsing()).await;
|
||||||
let buffer = cx.add_model(|cx| MultiBuffer::singleton(buffer, cx));
|
let buffer = cx.add_model(|cx| MultiBuffer::singleton(buffer, cx));
|
||||||
|
|
||||||
let font_cache = cx.font_cache();
|
let font_cache = cx.font_cache();
|
||||||
|
|
||||||
let tab_size = 4;
|
|
||||||
let family_id = font_cache.load_family(&["Courier"]).unwrap();
|
let family_id = font_cache.load_family(&["Courier"]).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 = 16.0;
|
let font_size = 16.0;
|
||||||
|
|
||||||
let map = cx.add_model(|cx| {
|
let map =
|
||||||
DisplayMap::new(buffer, tab_size, font_id, font_size, Some(40.0), 1, 1, cx)
|
cx.add_model(|cx| DisplayMap::new(buffer, font_id, font_size, Some(40.0), 1, 1, cx));
|
||||||
});
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
cx.update(|cx| syntax_chunks(0..5, &map, &theme, cx)),
|
cx.update(|cx| syntax_chunks(0..5, &map, &theme, cx)),
|
||||||
[
|
[
|
||||||
|
@ -1061,6 +1066,7 @@ pub mod tests {
|
||||||
async fn test_chunks_with_text_highlights(cx: &mut gpui::TestAppContext) {
|
async fn test_chunks_with_text_highlights(cx: &mut gpui::TestAppContext) {
|
||||||
cx.foreground().set_block_on_ticks(usize::MAX..=usize::MAX);
|
cx.foreground().set_block_on_ticks(usize::MAX..=usize::MAX);
|
||||||
|
|
||||||
|
cx.update(|cx| cx.set_global(Settings::test(cx)));
|
||||||
let theme = SyntaxTheme::new(vec![
|
let theme = SyntaxTheme::new(vec![
|
||||||
("operator".to_string(), Color::red().into()),
|
("operator".to_string(), Color::red().into()),
|
||||||
("string".to_string(), Color::green().into()),
|
("string".to_string(), Color::green().into()),
|
||||||
|
@ -1093,14 +1099,12 @@ pub mod tests {
|
||||||
let buffer_snapshot = buffer.read_with(cx, |buffer, cx| buffer.snapshot(cx));
|
let buffer_snapshot = buffer.read_with(cx, |buffer, cx| buffer.snapshot(cx));
|
||||||
|
|
||||||
let font_cache = cx.font_cache();
|
let font_cache = cx.font_cache();
|
||||||
let tab_size = 4;
|
|
||||||
let family_id = font_cache.load_family(&["Courier"]).unwrap();
|
let family_id = font_cache.load_family(&["Courier"]).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 = 16.0;
|
let font_size = 16.0;
|
||||||
let map = cx
|
let map = cx.add_model(|cx| DisplayMap::new(buffer, font_id, font_size, None, 1, 1, cx));
|
||||||
.add_model(|cx| DisplayMap::new(buffer, tab_size, font_id, font_size, None, 1, 1, cx));
|
|
||||||
|
|
||||||
enum MyType {}
|
enum MyType {}
|
||||||
|
|
||||||
|
@ -1139,6 +1143,7 @@ pub mod tests {
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
fn test_clip_point(cx: &mut gpui::MutableAppContext) {
|
fn test_clip_point(cx: &mut gpui::MutableAppContext) {
|
||||||
|
cx.set_global(Settings::test(cx));
|
||||||
fn assert(text: &str, shift_right: bool, bias: Bias, cx: &mut gpui::MutableAppContext) {
|
fn assert(text: &str, shift_right: bool, bias: Bias, cx: &mut gpui::MutableAppContext) {
|
||||||
let (unmarked_snapshot, mut markers) = marked_display_snapshot(text, cx);
|
let (unmarked_snapshot, mut markers) = marked_display_snapshot(text, cx);
|
||||||
|
|
||||||
|
@ -1190,6 +1195,8 @@ pub mod tests {
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
fn test_clip_at_line_ends(cx: &mut gpui::MutableAppContext) {
|
fn test_clip_at_line_ends(cx: &mut gpui::MutableAppContext) {
|
||||||
|
cx.set_global(Settings::test(cx));
|
||||||
|
|
||||||
fn assert(text: &str, cx: &mut gpui::MutableAppContext) {
|
fn assert(text: &str, cx: &mut gpui::MutableAppContext) {
|
||||||
let (mut unmarked_snapshot, markers) = marked_display_snapshot(text, cx);
|
let (mut unmarked_snapshot, markers) = marked_display_snapshot(text, cx);
|
||||||
unmarked_snapshot.clip_at_line_ends = true;
|
unmarked_snapshot.clip_at_line_ends = true;
|
||||||
|
@ -1207,9 +1214,9 @@ pub mod tests {
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
fn test_tabs_with_multibyte_chars(cx: &mut gpui::MutableAppContext) {
|
fn test_tabs_with_multibyte_chars(cx: &mut gpui::MutableAppContext) {
|
||||||
|
cx.set_global(Settings::test(cx));
|
||||||
let text = "✅\t\tα\nβ\t\n🏀β\t\tγ";
|
let text = "✅\t\tα\nβ\t\n🏀β\t\tγ";
|
||||||
let buffer = MultiBuffer::build_simple(text, cx);
|
let buffer = MultiBuffer::build_simple(text, cx);
|
||||||
let tab_size = 4;
|
|
||||||
let font_cache = cx.font_cache();
|
let font_cache = cx.font_cache();
|
||||||
let family_id = font_cache.load_family(&["Helvetica"]).unwrap();
|
let family_id = font_cache.load_family(&["Helvetica"]).unwrap();
|
||||||
let font_id = font_cache
|
let font_id = font_cache
|
||||||
|
@ -1217,9 +1224,8 @@ pub mod tests {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let font_size = 14.0;
|
let font_size = 14.0;
|
||||||
|
|
||||||
let map = cx.add_model(|cx| {
|
let map =
|
||||||
DisplayMap::new(buffer.clone(), tab_size, font_id, font_size, None, 1, 1, cx)
|
cx.add_model(|cx| DisplayMap::new(buffer.clone(), font_id, font_size, None, 1, 1, cx));
|
||||||
});
|
|
||||||
let map = map.update(cx, |map, cx| map.snapshot(cx));
|
let map = map.update(cx, |map, cx| map.snapshot(cx));
|
||||||
assert_eq!(map.text(), "✅ α\nβ \n🏀β γ");
|
assert_eq!(map.text(), "✅ α\nβ \n🏀β γ");
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
@ -1267,17 +1273,16 @@ pub mod tests {
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
fn test_max_point(cx: &mut gpui::MutableAppContext) {
|
fn test_max_point(cx: &mut gpui::MutableAppContext) {
|
||||||
|
cx.set_global(Settings::test(cx));
|
||||||
let buffer = MultiBuffer::build_simple("aaa\n\t\tbbb", cx);
|
let buffer = MultiBuffer::build_simple("aaa\n\t\tbbb", cx);
|
||||||
let tab_size = 4;
|
|
||||||
let font_cache = cx.font_cache();
|
let font_cache = cx.font_cache();
|
||||||
let family_id = font_cache.load_family(&["Helvetica"]).unwrap();
|
let family_id = font_cache.load_family(&["Helvetica"]).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;
|
||||||
let map = cx.add_model(|cx| {
|
let map =
|
||||||
DisplayMap::new(buffer.clone(), tab_size, font_id, font_size, None, 1, 1, cx)
|
cx.add_model(|cx| DisplayMap::new(buffer.clone(), font_id, font_size, None, 1, 1, cx));
|
||||||
});
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
map.update(cx, |map, cx| map.snapshot(cx)).max_point(),
|
map.update(cx, |map, cx| map.snapshot(cx)).max_point(),
|
||||||
DisplayPoint::new(1, 11)
|
DisplayPoint::new(1, 11)
|
||||||
|
|
|
@ -1157,7 +1157,7 @@ mod tests {
|
||||||
|
|
||||||
let (folds_snapshot, fold_edits) =
|
let (folds_snapshot, fold_edits) =
|
||||||
fold_map.read(buffer_snapshot, subscription.consume().into_inner());
|
fold_map.read(buffer_snapshot, subscription.consume().into_inner());
|
||||||
let (tabs_snapshot, tab_edits) = tab_map.sync(folds_snapshot, fold_edits);
|
let (tabs_snapshot, tab_edits) = tab_map.sync(folds_snapshot, fold_edits, 4);
|
||||||
let (wraps_snapshot, wrap_edits) = wrap_map.update(cx, |wrap_map, cx| {
|
let (wraps_snapshot, wrap_edits) = wrap_map.update(cx, |wrap_map, cx| {
|
||||||
wrap_map.sync(tabs_snapshot, tab_edits, cx)
|
wrap_map.sync(tabs_snapshot, tab_edits, cx)
|
||||||
});
|
});
|
||||||
|
@ -1296,7 +1296,8 @@ mod tests {
|
||||||
|
|
||||||
let (folds_snapshot, fold_edits) =
|
let (folds_snapshot, fold_edits) =
|
||||||
fold_map.read(buffer_snapshot.clone(), vec![]);
|
fold_map.read(buffer_snapshot.clone(), vec![]);
|
||||||
let (tabs_snapshot, tab_edits) = tab_map.sync(folds_snapshot, fold_edits);
|
let (tabs_snapshot, tab_edits) =
|
||||||
|
tab_map.sync(folds_snapshot, fold_edits, tab_size);
|
||||||
let (wraps_snapshot, wrap_edits) = wrap_map.update(cx, |wrap_map, cx| {
|
let (wraps_snapshot, wrap_edits) = wrap_map.update(cx, |wrap_map, cx| {
|
||||||
wrap_map.sync(tabs_snapshot, tab_edits, cx)
|
wrap_map.sync(tabs_snapshot, tab_edits, cx)
|
||||||
});
|
});
|
||||||
|
@ -1318,7 +1319,8 @@ mod tests {
|
||||||
|
|
||||||
let (folds_snapshot, fold_edits) =
|
let (folds_snapshot, fold_edits) =
|
||||||
fold_map.read(buffer_snapshot.clone(), vec![]);
|
fold_map.read(buffer_snapshot.clone(), vec![]);
|
||||||
let (tabs_snapshot, tab_edits) = tab_map.sync(folds_snapshot, fold_edits);
|
let (tabs_snapshot, tab_edits) =
|
||||||
|
tab_map.sync(folds_snapshot, fold_edits, tab_size);
|
||||||
let (wraps_snapshot, wrap_edits) = wrap_map.update(cx, |wrap_map, cx| {
|
let (wraps_snapshot, wrap_edits) = wrap_map.update(cx, |wrap_map, cx| {
|
||||||
wrap_map.sync(tabs_snapshot, tab_edits, cx)
|
wrap_map.sync(tabs_snapshot, tab_edits, cx)
|
||||||
});
|
});
|
||||||
|
@ -1338,7 +1340,7 @@ mod tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
let (folds_snapshot, fold_edits) = fold_map.read(buffer_snapshot.clone(), buffer_edits);
|
let (folds_snapshot, fold_edits) = fold_map.read(buffer_snapshot.clone(), buffer_edits);
|
||||||
let (tabs_snapshot, tab_edits) = tab_map.sync(folds_snapshot, fold_edits);
|
let (tabs_snapshot, tab_edits) = tab_map.sync(folds_snapshot, fold_edits, tab_size);
|
||||||
let (wraps_snapshot, wrap_edits) = wrap_map.update(cx, |wrap_map, cx| {
|
let (wraps_snapshot, wrap_edits) = wrap_map.update(cx, |wrap_map, cx| {
|
||||||
wrap_map.sync(tabs_snapshot, tab_edits, cx)
|
wrap_map.sync(tabs_snapshot, tab_edits, cx)
|
||||||
});
|
});
|
||||||
|
|
|
@ -12,7 +12,7 @@ use text::Point;
|
||||||
pub struct TabMap(Mutex<TabSnapshot>);
|
pub struct TabMap(Mutex<TabSnapshot>);
|
||||||
|
|
||||||
impl TabMap {
|
impl TabMap {
|
||||||
pub fn new(input: FoldSnapshot, tab_size: usize) -> (Self, TabSnapshot) {
|
pub fn new(input: FoldSnapshot, tab_size: u32) -> (Self, TabSnapshot) {
|
||||||
let snapshot = TabSnapshot {
|
let snapshot = TabSnapshot {
|
||||||
fold_snapshot: input,
|
fold_snapshot: input,
|
||||||
tab_size,
|
tab_size,
|
||||||
|
@ -24,12 +24,13 @@ impl TabMap {
|
||||||
&self,
|
&self,
|
||||||
fold_snapshot: FoldSnapshot,
|
fold_snapshot: FoldSnapshot,
|
||||||
mut fold_edits: Vec<FoldEdit>,
|
mut fold_edits: Vec<FoldEdit>,
|
||||||
|
tab_size: u32,
|
||||||
) -> (TabSnapshot, Vec<TabEdit>) {
|
) -> (TabSnapshot, Vec<TabEdit>) {
|
||||||
let mut old_snapshot = self.0.lock();
|
let mut old_snapshot = self.0.lock();
|
||||||
let max_offset = old_snapshot.fold_snapshot.len();
|
let max_offset = old_snapshot.fold_snapshot.len();
|
||||||
let new_snapshot = TabSnapshot {
|
let new_snapshot = TabSnapshot {
|
||||||
fold_snapshot,
|
fold_snapshot,
|
||||||
tab_size: old_snapshot.tab_size,
|
tab_size,
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut tab_edits = Vec::with_capacity(fold_edits.len());
|
let mut tab_edits = Vec::with_capacity(fold_edits.len());
|
||||||
|
@ -87,7 +88,7 @@ impl TabMap {
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct TabSnapshot {
|
pub struct TabSnapshot {
|
||||||
pub fold_snapshot: FoldSnapshot,
|
pub fold_snapshot: FoldSnapshot,
|
||||||
pub tab_size: usize,
|
pub tab_size: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TabSnapshot {
|
impl TabSnapshot {
|
||||||
|
@ -234,7 +235,7 @@ impl TabSnapshot {
|
||||||
.to_buffer_point(&self.fold_snapshot)
|
.to_buffer_point(&self.fold_snapshot)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn expand_tabs(chars: impl Iterator<Item = char>, column: usize, tab_size: usize) -> usize {
|
fn expand_tabs(chars: impl Iterator<Item = char>, column: usize, tab_size: u32) -> usize {
|
||||||
let mut expanded_chars = 0;
|
let mut expanded_chars = 0;
|
||||||
let mut expanded_bytes = 0;
|
let mut expanded_bytes = 0;
|
||||||
let mut collapsed_bytes = 0;
|
let mut collapsed_bytes = 0;
|
||||||
|
@ -243,7 +244,7 @@ impl TabSnapshot {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if c == '\t' {
|
if c == '\t' {
|
||||||
let tab_len = tab_size - expanded_chars % tab_size;
|
let tab_len = tab_size as usize - expanded_chars % tab_size as usize;
|
||||||
expanded_bytes += tab_len;
|
expanded_bytes += tab_len;
|
||||||
expanded_chars += tab_len;
|
expanded_chars += tab_len;
|
||||||
} else {
|
} else {
|
||||||
|
@ -259,7 +260,7 @@ impl TabSnapshot {
|
||||||
mut chars: impl Iterator<Item = char>,
|
mut chars: impl Iterator<Item = char>,
|
||||||
column: usize,
|
column: usize,
|
||||||
bias: Bias,
|
bias: Bias,
|
||||||
tab_size: usize,
|
tab_size: u32,
|
||||||
) -> (usize, usize, usize) {
|
) -> (usize, usize, usize) {
|
||||||
let mut expanded_bytes = 0;
|
let mut expanded_bytes = 0;
|
||||||
let mut expanded_chars = 0;
|
let mut expanded_chars = 0;
|
||||||
|
@ -270,7 +271,7 @@ impl TabSnapshot {
|
||||||
}
|
}
|
||||||
|
|
||||||
if c == '\t' {
|
if c == '\t' {
|
||||||
let tab_len = tab_size - (expanded_chars % tab_size);
|
let tab_len = tab_size as usize - (expanded_chars % tab_size as usize);
|
||||||
expanded_chars += tab_len;
|
expanded_chars += tab_len;
|
||||||
expanded_bytes += tab_len;
|
expanded_bytes += tab_len;
|
||||||
if expanded_bytes > column {
|
if expanded_bytes > column {
|
||||||
|
@ -383,7 +384,7 @@ pub struct TabChunks<'a> {
|
||||||
column: usize,
|
column: usize,
|
||||||
output_position: Point,
|
output_position: Point,
|
||||||
max_output_position: Point,
|
max_output_position: Point,
|
||||||
tab_size: usize,
|
tab_size: u32,
|
||||||
skip_leading_tab: bool,
|
skip_leading_tab: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -415,16 +416,16 @@ impl<'a> Iterator for TabChunks<'a> {
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
self.chunk.text = &self.chunk.text[1..];
|
self.chunk.text = &self.chunk.text[1..];
|
||||||
let mut len = self.tab_size - self.column % self.tab_size;
|
let mut len = self.tab_size - self.column as u32 % self.tab_size;
|
||||||
let next_output_position = cmp::min(
|
let next_output_position = cmp::min(
|
||||||
self.output_position + Point::new(0, len as u32),
|
self.output_position + Point::new(0, len),
|
||||||
self.max_output_position,
|
self.max_output_position,
|
||||||
);
|
);
|
||||||
len = (next_output_position.column - self.output_position.column) as usize;
|
len = next_output_position.column - self.output_position.column;
|
||||||
self.column += len;
|
self.column += len as usize;
|
||||||
self.output_position = next_output_position;
|
self.output_position = next_output_position;
|
||||||
return Some(Chunk {
|
return Some(Chunk {
|
||||||
text: &SPACES[0..len],
|
text: &SPACES[0..len as usize],
|
||||||
..self.chunk
|
..self.chunk
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1104,7 +1104,8 @@ mod tests {
|
||||||
}
|
}
|
||||||
20..=39 => {
|
20..=39 => {
|
||||||
for (folds_snapshot, fold_edits) in fold_map.randomly_mutate(&mut rng) {
|
for (folds_snapshot, fold_edits) in fold_map.randomly_mutate(&mut rng) {
|
||||||
let (tabs_snapshot, tab_edits) = tab_map.sync(folds_snapshot, fold_edits);
|
let (tabs_snapshot, tab_edits) =
|
||||||
|
tab_map.sync(folds_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();
|
||||||
|
@ -1129,7 +1130,7 @@ mod tests {
|
||||||
"Unwrapped text (unexpanded tabs): {:?}",
|
"Unwrapped text (unexpanded tabs): {:?}",
|
||||||
folds_snapshot.text()
|
folds_snapshot.text()
|
||||||
);
|
);
|
||||||
let (tabs_snapshot, tab_edits) = tab_map.sync(folds_snapshot, fold_edits);
|
let (tabs_snapshot, tab_edits) = tab_map.sync(folds_snapshot, fold_edits, tab_size);
|
||||||
log::info!("Unwrapped text (expanded tabs): {:?}", tabs_snapshot.text());
|
log::info!("Unwrapped text (expanded tabs): {:?}", tabs_snapshot.text());
|
||||||
|
|
||||||
let unwrapped_text = tabs_snapshot.text();
|
let unwrapped_text = tabs_snapshot.text();
|
||||||
|
|
|
@ -1010,7 +1010,6 @@ impl Editor {
|
||||||
let style = build_style(&*settings, get_field_editor_theme, None, cx);
|
let style = build_style(&*settings, get_field_editor_theme, None, cx);
|
||||||
DisplayMap::new(
|
DisplayMap::new(
|
||||||
buffer.clone(),
|
buffer.clone(),
|
||||||
settings.tab_size,
|
|
||||||
style.text.font_id,
|
style.text.font_id,
|
||||||
style.text.font_size,
|
style.text.font_size,
|
||||||
None,
|
None,
|
||||||
|
@ -3006,13 +3005,14 @@ impl Editor {
|
||||||
)
|
)
|
||||||
.flat_map(str::chars)
|
.flat_map(str::chars)
|
||||||
.count();
|
.count();
|
||||||
let chars_to_next_tab_stop = tab_size - (char_column % tab_size);
|
let chars_to_next_tab_stop =
|
||||||
|
tab_size - (char_column as u32 % tab_size);
|
||||||
buffer.edit(
|
buffer.edit(
|
||||||
[selection.start..selection.start],
|
[selection.start..selection.start],
|
||||||
" ".repeat(chars_to_next_tab_stop),
|
" ".repeat(chars_to_next_tab_stop as usize),
|
||||||
cx,
|
cx,
|
||||||
);
|
);
|
||||||
selection.start.column += chars_to_next_tab_stop as u32;
|
selection.start.column += chars_to_next_tab_stop;
|
||||||
selection.end = selection.start;
|
selection.end = selection.start;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -3055,12 +3055,12 @@ impl Editor {
|
||||||
}
|
}
|
||||||
|
|
||||||
for row in start_row..end_row {
|
for row in start_row..end_row {
|
||||||
let indent_column = buffer.read(cx).indent_column_for_line(row) as usize;
|
let indent_column = buffer.read(cx).indent_column_for_line(row);
|
||||||
let columns_to_next_tab_stop = tab_size - (indent_column % tab_size);
|
let columns_to_next_tab_stop = tab_size - (indent_column % tab_size);
|
||||||
let row_start = Point::new(row, 0);
|
let row_start = Point::new(row, 0);
|
||||||
buffer.edit(
|
buffer.edit(
|
||||||
[row_start..row_start],
|
[row_start..row_start],
|
||||||
" ".repeat(columns_to_next_tab_stop),
|
" ".repeat(columns_to_next_tab_stop as usize),
|
||||||
cx,
|
cx,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -3101,11 +3101,11 @@ impl Editor {
|
||||||
}
|
}
|
||||||
|
|
||||||
for row in rows {
|
for row in rows {
|
||||||
let column = buffer.indent_column_for_line(row) as usize;
|
let column = buffer.indent_column_for_line(row);
|
||||||
if column > 0 {
|
if column > 0 {
|
||||||
let mut deletion_len = (column % tab_size) as u32;
|
let mut deletion_len = column % tab_size;
|
||||||
if deletion_len == 0 {
|
if deletion_len == 0 {
|
||||||
deletion_len = tab_size as u32;
|
deletion_len = tab_size;
|
||||||
}
|
}
|
||||||
deletion_ranges.push(Point::new(row, 0)..Point::new(row, deletion_len));
|
deletion_ranges.push(Point::new(row, 0)..Point::new(row, deletion_len));
|
||||||
last_outdent = Some(row);
|
last_outdent = Some(row);
|
||||||
|
|
|
@ -268,9 +268,11 @@ mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::{test::marked_display_snapshot, Buffer, DisplayMap, MultiBuffer};
|
use crate::{test::marked_display_snapshot, Buffer, DisplayMap, MultiBuffer};
|
||||||
use language::Point;
|
use language::Point;
|
||||||
|
use settings::Settings;
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
fn test_previous_word_start(cx: &mut gpui::MutableAppContext) {
|
fn test_previous_word_start(cx: &mut gpui::MutableAppContext) {
|
||||||
|
cx.set_global(Settings::test(cx));
|
||||||
fn assert(marked_text: &str, cx: &mut gpui::MutableAppContext) {
|
fn assert(marked_text: &str, cx: &mut gpui::MutableAppContext) {
|
||||||
let (snapshot, display_points) = marked_display_snapshot(marked_text, cx);
|
let (snapshot, display_points) = marked_display_snapshot(marked_text, cx);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
@ -297,6 +299,7 @@ mod tests {
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
fn test_previous_subword_start(cx: &mut gpui::MutableAppContext) {
|
fn test_previous_subword_start(cx: &mut gpui::MutableAppContext) {
|
||||||
|
cx.set_global(Settings::test(cx));
|
||||||
fn assert(marked_text: &str, cx: &mut gpui::MutableAppContext) {
|
fn assert(marked_text: &str, cx: &mut gpui::MutableAppContext) {
|
||||||
let (snapshot, display_points) = marked_display_snapshot(marked_text, cx);
|
let (snapshot, display_points) = marked_display_snapshot(marked_text, cx);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
@ -330,6 +333,7 @@ mod tests {
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
fn test_find_preceding_boundary(cx: &mut gpui::MutableAppContext) {
|
fn test_find_preceding_boundary(cx: &mut gpui::MutableAppContext) {
|
||||||
|
cx.set_global(Settings::test(cx));
|
||||||
fn assert(
|
fn assert(
|
||||||
marked_text: &str,
|
marked_text: &str,
|
||||||
cx: &mut gpui::MutableAppContext,
|
cx: &mut gpui::MutableAppContext,
|
||||||
|
@ -361,6 +365,7 @@ mod tests {
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
fn test_next_word_end(cx: &mut gpui::MutableAppContext) {
|
fn test_next_word_end(cx: &mut gpui::MutableAppContext) {
|
||||||
|
cx.set_global(Settings::test(cx));
|
||||||
fn assert(marked_text: &str, cx: &mut gpui::MutableAppContext) {
|
fn assert(marked_text: &str, cx: &mut gpui::MutableAppContext) {
|
||||||
let (snapshot, display_points) = marked_display_snapshot(marked_text, cx);
|
let (snapshot, display_points) = marked_display_snapshot(marked_text, cx);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
@ -384,6 +389,7 @@ mod tests {
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
fn test_next_subword_end(cx: &mut gpui::MutableAppContext) {
|
fn test_next_subword_end(cx: &mut gpui::MutableAppContext) {
|
||||||
|
cx.set_global(Settings::test(cx));
|
||||||
fn assert(marked_text: &str, cx: &mut gpui::MutableAppContext) {
|
fn assert(marked_text: &str, cx: &mut gpui::MutableAppContext) {
|
||||||
let (snapshot, display_points) = marked_display_snapshot(marked_text, cx);
|
let (snapshot, display_points) = marked_display_snapshot(marked_text, cx);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
@ -416,6 +422,7 @@ mod tests {
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
fn test_find_boundary(cx: &mut gpui::MutableAppContext) {
|
fn test_find_boundary(cx: &mut gpui::MutableAppContext) {
|
||||||
|
cx.set_global(Settings::test(cx));
|
||||||
fn assert(
|
fn assert(
|
||||||
marked_text: &str,
|
marked_text: &str,
|
||||||
cx: &mut gpui::MutableAppContext,
|
cx: &mut gpui::MutableAppContext,
|
||||||
|
@ -447,6 +454,7 @@ mod tests {
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
fn test_surrounding_word(cx: &mut gpui::MutableAppContext) {
|
fn test_surrounding_word(cx: &mut gpui::MutableAppContext) {
|
||||||
|
cx.set_global(Settings::test(cx));
|
||||||
fn assert(marked_text: &str, cx: &mut gpui::MutableAppContext) {
|
fn assert(marked_text: &str, cx: &mut gpui::MutableAppContext) {
|
||||||
let (snapshot, display_points) = marked_display_snapshot(marked_text, cx);
|
let (snapshot, display_points) = marked_display_snapshot(marked_text, cx);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
@ -467,6 +475,7 @@ mod tests {
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
fn test_move_up_and_down_with_excerpts(cx: &mut gpui::MutableAppContext) {
|
fn test_move_up_and_down_with_excerpts(cx: &mut gpui::MutableAppContext) {
|
||||||
|
cx.set_global(Settings::test(cx));
|
||||||
let family_id = cx.font_cache().load_family(&["Helvetica"]).unwrap();
|
let family_id = cx.font_cache().load_family(&["Helvetica"]).unwrap();
|
||||||
let font_id = cx
|
let font_id = cx
|
||||||
.font_cache()
|
.font_cache()
|
||||||
|
@ -487,7 +496,7 @@ mod tests {
|
||||||
multibuffer
|
multibuffer
|
||||||
});
|
});
|
||||||
let display_map =
|
let display_map =
|
||||||
cx.add_model(|cx| DisplayMap::new(multibuffer, 2, font_id, 14.0, None, 2, 2, cx));
|
cx.add_model(|cx| DisplayMap::new(multibuffer, font_id, 14.0, None, 2, 2, cx));
|
||||||
let snapshot = display_map.update(cx, |map, cx| map.snapshot(cx));
|
let snapshot = display_map.update(cx, |map, cx| map.snapshot(cx));
|
||||||
|
|
||||||
assert_eq!(snapshot.text(), "\n\nabc\ndefg\n\n\nhijkl\nmn");
|
assert_eq!(snapshot.text(), "\n\nabc\ndefg\n\n\nhijkl\nmn");
|
||||||
|
|
|
@ -20,7 +20,6 @@ pub fn marked_display_snapshot(
|
||||||
) -> (DisplaySnapshot, Vec<DisplayPoint>) {
|
) -> (DisplaySnapshot, Vec<DisplayPoint>) {
|
||||||
let (unmarked_text, markers) = marked_text(text);
|
let (unmarked_text, markers) = marked_text(text);
|
||||||
|
|
||||||
let tab_size = 4;
|
|
||||||
let family_id = cx.font_cache().load_family(&["Helvetica"]).unwrap();
|
let family_id = cx.font_cache().load_family(&["Helvetica"]).unwrap();
|
||||||
let font_id = cx
|
let font_id = cx
|
||||||
.font_cache()
|
.font_cache()
|
||||||
|
@ -30,7 +29,7 @@ pub fn marked_display_snapshot(
|
||||||
|
|
||||||
let buffer = MultiBuffer::build_simple(&unmarked_text, cx);
|
let buffer = MultiBuffer::build_simple(&unmarked_text, cx);
|
||||||
let display_map =
|
let display_map =
|
||||||
cx.add_model(|cx| DisplayMap::new(buffer, tab_size, font_id, font_size, None, 1, 1, cx));
|
cx.add_model(|cx| DisplayMap::new(buffer, font_id, font_size, None, 1, 1, cx));
|
||||||
let snapshot = display_map.update(cx, |map, cx| map.snapshot(cx));
|
let snapshot = display_map.update(cx, |map, cx| map.snapshot(cx));
|
||||||
let markers = markers
|
let markers = markers
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
|
|
@ -8,6 +8,7 @@ use gpui::{
|
||||||
ViewContext, ViewHandle, WeakViewHandle,
|
ViewContext, ViewHandle, WeakViewHandle,
|
||||||
};
|
};
|
||||||
use project::{Project, ProjectPath, WorktreeId};
|
use project::{Project, ProjectPath, WorktreeId};
|
||||||
|
use settings::Settings;
|
||||||
use std::{
|
use std::{
|
||||||
cmp,
|
cmp,
|
||||||
path::Path,
|
path::Path,
|
||||||
|
@ -21,7 +22,6 @@ use workspace::{
|
||||||
menu::{Confirm, SelectNext, SelectPrev},
|
menu::{Confirm, SelectNext, SelectPrev},
|
||||||
Workspace,
|
Workspace,
|
||||||
};
|
};
|
||||||
use settings::Settings;
|
|
||||||
|
|
||||||
pub struct FileFinder {
|
pub struct FileFinder {
|
||||||
handle: WeakViewHandle<Self>,
|
handle: WeakViewHandle<Self>,
|
||||||
|
|
|
@ -1019,7 +1019,10 @@ impl MutableAppContext {
|
||||||
.insert(TypeId::of::<A>(), handler)
|
.insert(TypeId::of::<A>(), handler)
|
||||||
.is_some()
|
.is_some()
|
||||||
{
|
{
|
||||||
panic!("registered multiple global handlers for the same action type");
|
panic!(
|
||||||
|
"registered multiple global handlers for {}",
|
||||||
|
type_name::<A>()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2355,11 +2358,11 @@ impl AppContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn global<T: 'static>(&self) -> &T {
|
pub fn global<T: 'static>(&self) -> &T {
|
||||||
self.globals
|
if let Some(global) = self.globals.get(&TypeId::of::<T>()) {
|
||||||
.get(&TypeId::of::<T>())
|
global.downcast_ref().unwrap()
|
||||||
.expect("no app state has been added for this type")
|
} else {
|
||||||
.downcast_ref()
|
panic!("no global has been added for {}", type_name::<T>());
|
||||||
.unwrap()
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@ gpui = { path = "../gpui" }
|
||||||
language = { path = "../language" }
|
language = { path = "../language" }
|
||||||
lsp = { path = "../lsp" }
|
lsp = { path = "../lsp" }
|
||||||
rpc = { path = "../rpc" }
|
rpc = { path = "../rpc" }
|
||||||
|
settings = { path = "../settings" }
|
||||||
sum_tree = { path = "../sum_tree" }
|
sum_tree = { path = "../sum_tree" }
|
||||||
util = { path = "../util" }
|
util = { path = "../util" }
|
||||||
aho-corasick = "0.7"
|
aho-corasick = "0.7"
|
||||||
|
|
|
@ -28,6 +28,7 @@ use parking_lot::Mutex;
|
||||||
use postage::watch;
|
use postage::watch;
|
||||||
use rand::prelude::*;
|
use rand::prelude::*;
|
||||||
use search::SearchQuery;
|
use search::SearchQuery;
|
||||||
|
use settings::Settings;
|
||||||
use sha2::{Digest, Sha256};
|
use sha2::{Digest, Sha256};
|
||||||
use similar::{ChangeTag, TextDiff};
|
use similar::{ChangeTag, TextDiff};
|
||||||
use std::{
|
use std::{
|
||||||
|
@ -2173,6 +2174,10 @@ impl Project {
|
||||||
lsp::Url::from_file_path(&buffer_abs_path).unwrap(),
|
lsp::Url::from_file_path(&buffer_abs_path).unwrap(),
|
||||||
);
|
);
|
||||||
let capabilities = &language_server.capabilities();
|
let capabilities = &language_server.capabilities();
|
||||||
|
let tab_size = cx.update(|cx| {
|
||||||
|
let language_name = buffer.read(cx).language().map(|language| language.name());
|
||||||
|
cx.global::<Settings>().tab_size(language_name.as_deref())
|
||||||
|
});
|
||||||
let lsp_edits = if capabilities
|
let lsp_edits = if capabilities
|
||||||
.document_formatting_provider
|
.document_formatting_provider
|
||||||
.as_ref()
|
.as_ref()
|
||||||
|
@ -2182,7 +2187,7 @@ impl Project {
|
||||||
.request::<lsp::request::Formatting>(lsp::DocumentFormattingParams {
|
.request::<lsp::request::Formatting>(lsp::DocumentFormattingParams {
|
||||||
text_document,
|
text_document,
|
||||||
options: lsp::FormattingOptions {
|
options: lsp::FormattingOptions {
|
||||||
tab_size: 4,
|
tab_size,
|
||||||
insert_spaces: true,
|
insert_spaces: true,
|
||||||
insert_final_newline: Some(true),
|
insert_final_newline: Some(true),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
|
|
|
@ -8,9 +8,9 @@ use gpui::{
|
||||||
};
|
};
|
||||||
use language::OffsetRangeExt;
|
use language::OffsetRangeExt;
|
||||||
use project::search::SearchQuery;
|
use project::search::SearchQuery;
|
||||||
|
use settings::Settings;
|
||||||
use std::ops::Range;
|
use std::ops::Range;
|
||||||
use workspace::{ItemHandle, Pane, ToolbarItemLocation, ToolbarItemView};
|
use workspace::{ItemHandle, Pane, ToolbarItemLocation, ToolbarItemView};
|
||||||
use settings::Settings;
|
|
||||||
|
|
||||||
action!(Deploy, bool);
|
action!(Deploy, bool);
|
||||||
action!(Dismiss);
|
action!(Dismiss);
|
||||||
|
|
|
@ -11,7 +11,7 @@ pub struct Settings {
|
||||||
pub buffer_font_family: FamilyId,
|
pub buffer_font_family: FamilyId,
|
||||||
pub buffer_font_size: f32,
|
pub buffer_font_size: f32,
|
||||||
pub vim_mode: bool,
|
pub vim_mode: bool,
|
||||||
pub tab_size: usize,
|
pub tab_size: u32,
|
||||||
pub soft_wrap: SoftWrap,
|
pub soft_wrap: SoftWrap,
|
||||||
pub preferred_line_length: u32,
|
pub preferred_line_length: u32,
|
||||||
pub language_overrides: HashMap<Arc<str>, LanguageOverride>,
|
pub language_overrides: HashMap<Arc<str>, LanguageOverride>,
|
||||||
|
@ -20,7 +20,7 @@ pub struct Settings {
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default, Deserialize, JsonSchema)]
|
#[derive(Clone, Debug, Default, Deserialize, JsonSchema)]
|
||||||
pub struct LanguageOverride {
|
pub struct LanguageOverride {
|
||||||
pub tab_size: Option<usize>,
|
pub tab_size: Option<u32>,
|
||||||
pub soft_wrap: Option<SoftWrap>,
|
pub soft_wrap: Option<SoftWrap>,
|
||||||
pub preferred_line_length: Option<u32>,
|
pub preferred_line_length: Option<u32>,
|
||||||
}
|
}
|
||||||
|
@ -81,7 +81,7 @@ impl Settings {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn tab_size(&self, language: Option<&str>) -> usize {
|
pub fn tab_size(&self, language: Option<&str>) -> u32 {
|
||||||
language
|
language
|
||||||
.and_then(|language| self.language_overrides.get(language))
|
.and_then(|language| self.language_overrides.get(language))
|
||||||
.and_then(|settings| settings.tab_size)
|
.and_then(|settings| settings.tab_size)
|
||||||
|
|
|
@ -48,6 +48,20 @@ fn main() {
|
||||||
soft_wrap: Some(settings::SoftWrap::PreferredLineLength),
|
soft_wrap: Some(settings::SoftWrap::PreferredLineLength),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
|
)
|
||||||
|
.with_overrides(
|
||||||
|
"Rust",
|
||||||
|
settings::LanguageOverride {
|
||||||
|
tab_size: Some(4),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.with_overrides(
|
||||||
|
"TypeScript",
|
||||||
|
settings::LanguageOverride {
|
||||||
|
tab_size: Some(2),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
);
|
);
|
||||||
let settings_file = load_settings_file(&app, fs.clone());
|
let settings_file = load_settings_file(&app, fs.clone());
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue