mirror of
https://github.com/zed-industries/zed.git
synced 2024-09-19 18:41:56 +03:00
Provide editor styling information separately from editor settings
* Since regular editors' font sizes and families are controlled by the settings and not the theme, don't store a dummy text style in the theme. Instead, only store a font color, and synthesize the text style for regular editors using both the theme and the settings. * Style single-line and auto-height editors (now called "field editors") using a single function that takes the entire theme and selects a relevant sub-object. Co-Authored-By: Nathan Sobo <nathan@zed.dev>
This commit is contained in:
parent
39ebaebd83
commit
47b654063e
@ -2,7 +2,7 @@ use client::{
|
|||||||
channel::{Channel, ChannelEvent, ChannelList, ChannelMessage},
|
channel::{Channel, ChannelEvent, ChannelList, ChannelMessage},
|
||||||
Client,
|
Client,
|
||||||
};
|
};
|
||||||
use editor::{Editor, EditorSettings};
|
use editor::Editor;
|
||||||
use gpui::{
|
use gpui::{
|
||||||
action,
|
action,
|
||||||
elements::*,
|
elements::*,
|
||||||
@ -16,7 +16,7 @@ use postage::{prelude::Stream, watch};
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use time::{OffsetDateTime, UtcOffset};
|
use time::{OffsetDateTime, UtcOffset};
|
||||||
use util::{ResultExt, TryFutureExt};
|
use util::{ResultExt, TryFutureExt};
|
||||||
use workspace::Settings;
|
use workspace::{settings::SoftWrap, Settings};
|
||||||
|
|
||||||
const MESSAGE_LOADING_THRESHOLD: usize = 50;
|
const MESSAGE_LOADING_THRESHOLD: usize = 50;
|
||||||
|
|
||||||
@ -52,21 +52,14 @@ impl ChatPanel {
|
|||||||
cx: &mut ViewContext<Self>,
|
cx: &mut ViewContext<Self>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let input_editor = cx.add_view(|cx| {
|
let input_editor = cx.add_view(|cx| {
|
||||||
Editor::auto_height(
|
let mut editor = Editor::auto_height(
|
||||||
4,
|
4,
|
||||||
{
|
settings.clone(),
|
||||||
let settings = settings.clone();
|
Some(|theme| theme.chat_panel.input_editor.clone()),
|
||||||
Arc::new(move |_| {
|
|
||||||
let settings = settings.borrow();
|
|
||||||
EditorSettings {
|
|
||||||
tab_size: settings.tab_size,
|
|
||||||
style: settings.theme.chat_panel.input_editor.as_editor(),
|
|
||||||
soft_wrap: editor::SoftWrap::EditorWidth,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
cx,
|
cx,
|
||||||
)
|
);
|
||||||
|
editor.set_soft_wrap_mode(SoftWrap::EditorWidth, cx);
|
||||||
|
editor
|
||||||
});
|
});
|
||||||
let channel_select = cx.add_view(|cx| {
|
let channel_select = cx.add_view(|cx| {
|
||||||
let channel_list = channel_list.clone();
|
let channel_list = channel_list.clone();
|
||||||
|
@ -7,7 +7,7 @@ use editor::{
|
|||||||
display_map::{BlockDisposition, BlockId, BlockProperties, RenderBlock},
|
display_map::{BlockDisposition, BlockId, BlockProperties, RenderBlock},
|
||||||
highlight_diagnostic_message,
|
highlight_diagnostic_message,
|
||||||
items::BufferItemHandle,
|
items::BufferItemHandle,
|
||||||
Autoscroll, BuildSettings, Editor, ExcerptId, MultiBuffer, ToOffset,
|
Autoscroll, Editor, ExcerptId, MultiBuffer, ToOffset,
|
||||||
};
|
};
|
||||||
use gpui::{
|
use gpui::{
|
||||||
action, elements::*, fonts::TextStyle, keymap::Binding, AnyViewHandle, AppContext, Entity,
|
action, elements::*, fonts::TextStyle, keymap::Binding, AnyViewHandle, AppContext, Entity,
|
||||||
@ -62,7 +62,6 @@ struct ProjectDiagnosticsEditor {
|
|||||||
excerpts: ModelHandle<MultiBuffer>,
|
excerpts: ModelHandle<MultiBuffer>,
|
||||||
path_states: Vec<PathState>,
|
path_states: Vec<PathState>,
|
||||||
paths_to_update: BTreeSet<ProjectPath>,
|
paths_to_update: BTreeSet<ProjectPath>,
|
||||||
build_settings: BuildSettings,
|
|
||||||
settings: watch::Receiver<workspace::Settings>,
|
settings: watch::Receiver<workspace::Settings>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,12 +141,11 @@ impl ProjectDiagnosticsEditor {
|
|||||||
.detach();
|
.detach();
|
||||||
|
|
||||||
let excerpts = cx.add_model(|cx| MultiBuffer::new(project.read(cx).replica_id()));
|
let excerpts = cx.add_model(|cx| MultiBuffer::new(project.read(cx).replica_id()));
|
||||||
let build_settings = editor::settings_builder(excerpts.downgrade(), settings.clone());
|
|
||||||
let editor = cx.add_view(|cx| {
|
let editor = cx.add_view(|cx| {
|
||||||
let mut editor = Editor::for_buffer(
|
let mut editor = Editor::for_buffer(
|
||||||
excerpts.clone(),
|
excerpts.clone(),
|
||||||
build_settings.clone(),
|
|
||||||
Some(project.clone()),
|
Some(project.clone()),
|
||||||
|
settings.clone(),
|
||||||
cx,
|
cx,
|
||||||
);
|
);
|
||||||
editor.set_vertical_scroll_margin(5, cx);
|
editor.set_vertical_scroll_margin(5, cx);
|
||||||
@ -164,7 +162,6 @@ impl ProjectDiagnosticsEditor {
|
|||||||
workspace,
|
workspace,
|
||||||
excerpts,
|
excerpts,
|
||||||
editor,
|
editor,
|
||||||
build_settings,
|
|
||||||
settings,
|
settings,
|
||||||
path_states: Default::default(),
|
path_states: Default::default(),
|
||||||
paths_to_update,
|
paths_to_update,
|
||||||
@ -360,7 +357,7 @@ impl ProjectDiagnosticsEditor {
|
|||||||
height: 2,
|
height: 2,
|
||||||
render: diagnostic_header_renderer(
|
render: diagnostic_header_renderer(
|
||||||
primary,
|
primary,
|
||||||
self.build_settings.clone(),
|
self.settings.clone(),
|
||||||
),
|
),
|
||||||
disposition: BlockDisposition::Above,
|
disposition: BlockDisposition::Above,
|
||||||
});
|
});
|
||||||
@ -382,7 +379,7 @@ impl ProjectDiagnosticsEditor {
|
|||||||
render: diagnostic_block_renderer(
|
render: diagnostic_block_renderer(
|
||||||
diagnostic,
|
diagnostic,
|
||||||
true,
|
true,
|
||||||
self.build_settings.clone(),
|
self.settings.clone(),
|
||||||
),
|
),
|
||||||
disposition: BlockDisposition::Below,
|
disposition: BlockDisposition::Below,
|
||||||
});
|
});
|
||||||
@ -644,20 +641,21 @@ impl workspace::ItemView for ProjectDiagnosticsEditor {
|
|||||||
|
|
||||||
fn diagnostic_header_renderer(
|
fn diagnostic_header_renderer(
|
||||||
diagnostic: Diagnostic,
|
diagnostic: Diagnostic,
|
||||||
build_settings: BuildSettings,
|
settings: watch::Receiver<workspace::Settings>,
|
||||||
) -> RenderBlock {
|
) -> RenderBlock {
|
||||||
let (message, highlights) = highlight_diagnostic_message(&diagnostic.message);
|
let (message, highlights) = highlight_diagnostic_message(&diagnostic.message);
|
||||||
Arc::new(move |cx| {
|
Arc::new(move |cx| {
|
||||||
let settings = build_settings(cx);
|
let settings = settings.borrow();
|
||||||
let style = &settings.style.diagnostic_header;
|
let theme = &settings.theme.editor;
|
||||||
let font_size = (style.text_scale_factor * settings.style.text.font_size).round();
|
let style = &theme.diagnostic_header;
|
||||||
|
let font_size = (style.text_scale_factor * settings.buffer_font_size).round();
|
||||||
let icon_width = cx.em_width * style.icon_width_factor;
|
let icon_width = cx.em_width * style.icon_width_factor;
|
||||||
let icon = if diagnostic.severity == DiagnosticSeverity::ERROR {
|
let icon = if diagnostic.severity == DiagnosticSeverity::ERROR {
|
||||||
Svg::new("icons/diagnostic-error-10.svg")
|
Svg::new("icons/diagnostic-error-10.svg")
|
||||||
.with_color(settings.style.error_diagnostic.message.text.color)
|
.with_color(theme.error_diagnostic.message.text.color)
|
||||||
} else {
|
} else {
|
||||||
Svg::new("icons/diagnostic-warning-10.svg")
|
Svg::new("icons/diagnostic-warning-10.svg")
|
||||||
.with_color(settings.style.warning_diagnostic.message.text.color)
|
.with_color(theme.warning_diagnostic.message.text.color)
|
||||||
};
|
};
|
||||||
|
|
||||||
Flex::row()
|
Flex::row()
|
||||||
|
@ -14,6 +14,7 @@ test-support = [
|
|||||||
"gpui/test-support",
|
"gpui/test-support",
|
||||||
"project/test-support",
|
"project/test-support",
|
||||||
"util/test-support",
|
"util/test-support",
|
||||||
|
"workspace/test-support",
|
||||||
]
|
]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
@ -50,6 +51,7 @@ lsp = { path = "../lsp", features = ["test-support"] }
|
|||||||
gpui = { path = "../gpui", features = ["test-support"] }
|
gpui = { path = "../gpui", features = ["test-support"] }
|
||||||
util = { path = "../util", features = ["test-support"] }
|
util = { path = "../util", features = ["test-support"] }
|
||||||
project = { path = "../project", features = ["test-support"] }
|
project = { path = "../project", features = ["test-support"] }
|
||||||
|
workspace = { path = "../workspace", features = ["test-support"] }
|
||||||
ctor = "0.1"
|
ctor = "0.1"
|
||||||
env_logger = "0.8"
|
env_logger = "0.8"
|
||||||
rand = "0.8"
|
rand = "0.8"
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,9 +1,9 @@
|
|||||||
use super::{
|
use super::{
|
||||||
display_map::{BlockContext, ToDisplayPoint},
|
display_map::{BlockContext, ToDisplayPoint},
|
||||||
Anchor, DisplayPoint, Editor, EditorMode, EditorSettings, EditorSnapshot, EditorStyle, Input,
|
Anchor, DisplayPoint, Editor, EditorMode, EditorSnapshot, Input, Scroll, Select, SelectPhase,
|
||||||
Scroll, Select, SelectPhase, SoftWrap, ToPoint, MAX_LINE_LEN,
|
SoftWrap, ToPoint, MAX_LINE_LEN,
|
||||||
};
|
};
|
||||||
use crate::display_map::TransformBlock;
|
use crate::{display_map::TransformBlock, EditorStyle};
|
||||||
use clock::ReplicaId;
|
use clock::ReplicaId;
|
||||||
use collections::{BTreeMap, HashMap};
|
use collections::{BTreeMap, HashMap};
|
||||||
use gpui::{
|
use gpui::{
|
||||||
@ -31,12 +31,12 @@ use std::{
|
|||||||
|
|
||||||
pub struct EditorElement {
|
pub struct EditorElement {
|
||||||
view: WeakViewHandle<Editor>,
|
view: WeakViewHandle<Editor>,
|
||||||
settings: EditorSettings,
|
style: EditorStyle,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EditorElement {
|
impl EditorElement {
|
||||||
pub fn new(view: WeakViewHandle<Editor>, settings: EditorSettings) -> Self {
|
pub fn new(view: WeakViewHandle<Editor>, style: EditorStyle) -> Self {
|
||||||
Self { view, settings }
|
Self { view, style }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn view<'a>(&self, cx: &'a AppContext) -> &'a Editor {
|
fn view<'a>(&self, cx: &'a AppContext) -> &'a Editor {
|
||||||
@ -209,16 +209,15 @@ impl EditorElement {
|
|||||||
let bounds = gutter_bounds.union_rect(text_bounds);
|
let bounds = gutter_bounds.union_rect(text_bounds);
|
||||||
let scroll_top = layout.snapshot.scroll_position().y() * layout.line_height;
|
let scroll_top = layout.snapshot.scroll_position().y() * layout.line_height;
|
||||||
let editor = self.view(cx.app);
|
let editor = self.view(cx.app);
|
||||||
let style = &self.settings.style;
|
|
||||||
cx.scene.push_quad(Quad {
|
cx.scene.push_quad(Quad {
|
||||||
bounds: gutter_bounds,
|
bounds: gutter_bounds,
|
||||||
background: Some(style.gutter_background),
|
background: Some(self.style.gutter_background),
|
||||||
border: Border::new(0., Color::transparent_black()),
|
border: Border::new(0., Color::transparent_black()),
|
||||||
corner_radius: 0.,
|
corner_radius: 0.,
|
||||||
});
|
});
|
||||||
cx.scene.push_quad(Quad {
|
cx.scene.push_quad(Quad {
|
||||||
bounds: text_bounds,
|
bounds: text_bounds,
|
||||||
background: Some(style.background),
|
background: Some(self.style.background),
|
||||||
border: Border::new(0., Color::transparent_black()),
|
border: Border::new(0., Color::transparent_black()),
|
||||||
corner_radius: 0.,
|
corner_radius: 0.,
|
||||||
});
|
});
|
||||||
@ -245,7 +244,7 @@ impl EditorElement {
|
|||||||
);
|
);
|
||||||
cx.scene.push_quad(Quad {
|
cx.scene.push_quad(Quad {
|
||||||
bounds: RectF::new(origin, size),
|
bounds: RectF::new(origin, size),
|
||||||
background: Some(style.active_line_background),
|
background: Some(self.style.active_line_background),
|
||||||
border: Border::default(),
|
border: Border::default(),
|
||||||
corner_radius: 0.,
|
corner_radius: 0.,
|
||||||
});
|
});
|
||||||
@ -264,7 +263,7 @@ impl EditorElement {
|
|||||||
);
|
);
|
||||||
cx.scene.push_quad(Quad {
|
cx.scene.push_quad(Quad {
|
||||||
bounds: RectF::new(origin, size),
|
bounds: RectF::new(origin, size),
|
||||||
background: Some(style.highlighted_line_background),
|
background: Some(self.style.highlighted_line_background),
|
||||||
border: Border::default(),
|
border: Border::default(),
|
||||||
corner_radius: 0.,
|
corner_radius: 0.,
|
||||||
});
|
});
|
||||||
@ -308,7 +307,7 @@ impl EditorElement {
|
|||||||
cx: &mut PaintContext,
|
cx: &mut PaintContext,
|
||||||
) {
|
) {
|
||||||
let view = self.view(cx.app);
|
let view = self.view(cx.app);
|
||||||
let style = &self.settings.style;
|
let style = &self.style;
|
||||||
let local_replica_id = view.replica_id(cx);
|
let local_replica_id = view.replica_id(cx);
|
||||||
let scroll_position = layout.snapshot.scroll_position();
|
let scroll_position = layout.snapshot.scroll_position();
|
||||||
let start_row = scroll_position.y() as u32;
|
let start_row = scroll_position.y() as u32;
|
||||||
@ -498,7 +497,7 @@ impl EditorElement {
|
|||||||
|
|
||||||
fn max_line_number_width(&self, snapshot: &EditorSnapshot, cx: &LayoutContext) -> f32 {
|
fn max_line_number_width(&self, snapshot: &EditorSnapshot, cx: &LayoutContext) -> f32 {
|
||||||
let digit_count = (snapshot.max_buffer_row() as f32).log10().floor() as usize + 1;
|
let digit_count = (snapshot.max_buffer_row() as f32).log10().floor() as usize + 1;
|
||||||
let style = &self.settings.style;
|
let style = &self.style;
|
||||||
|
|
||||||
cx.text_layout_cache
|
cx.text_layout_cache
|
||||||
.layout_str(
|
.layout_str(
|
||||||
@ -523,7 +522,7 @@ impl EditorElement {
|
|||||||
snapshot: &EditorSnapshot,
|
snapshot: &EditorSnapshot,
|
||||||
cx: &LayoutContext,
|
cx: &LayoutContext,
|
||||||
) -> Vec<Option<text_layout::Line>> {
|
) -> Vec<Option<text_layout::Line>> {
|
||||||
let style = &self.settings.style;
|
let style = &self.style;
|
||||||
let include_line_numbers = snapshot.mode == EditorMode::Full;
|
let include_line_numbers = snapshot.mode == EditorMode::Full;
|
||||||
let mut line_number_layouts = Vec::with_capacity(rows.len());
|
let mut line_number_layouts = Vec::with_capacity(rows.len());
|
||||||
let mut line_number = String::new();
|
let mut line_number = String::new();
|
||||||
@ -576,7 +575,11 @@ impl EditorElement {
|
|||||||
|
|
||||||
// When the editor is empty and unfocused, then show the placeholder.
|
// When the editor is empty and unfocused, then show the placeholder.
|
||||||
if snapshot.is_empty() && !snapshot.is_focused() {
|
if snapshot.is_empty() && !snapshot.is_focused() {
|
||||||
let placeholder_style = self.settings.style.placeholder_text();
|
let placeholder_style = self
|
||||||
|
.style
|
||||||
|
.placeholder_text
|
||||||
|
.as_ref()
|
||||||
|
.unwrap_or_else(|| &self.style.text);
|
||||||
let placeholder_text = snapshot.placeholder_text();
|
let placeholder_text = snapshot.placeholder_text();
|
||||||
let placeholder_lines = placeholder_text
|
let placeholder_lines = placeholder_text
|
||||||
.as_ref()
|
.as_ref()
|
||||||
@ -601,7 +604,7 @@ impl EditorElement {
|
|||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
} else {
|
} else {
|
||||||
let style = &self.settings.style;
|
let style = &self.style;
|
||||||
let chunks = snapshot.chunks(rows.clone(), true).map(|chunk| {
|
let chunks = snapshot.chunks(rows.clone(), true).map(|chunk| {
|
||||||
let highlight_style = chunk
|
let highlight_style = chunk
|
||||||
.highlight_id
|
.highlight_id
|
||||||
@ -688,10 +691,9 @@ impl EditorElement {
|
|||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
if *starts_new_buffer {
|
if *starts_new_buffer {
|
||||||
let style = &self.settings.style.diagnostic_path_header;
|
let style = &self.style.diagnostic_path_header;
|
||||||
let font_size = (style.text_scale_factor
|
let font_size =
|
||||||
* self.settings.style.text.font_size)
|
(style.text_scale_factor * self.style.text.font_size).round();
|
||||||
.round();
|
|
||||||
|
|
||||||
let mut filename = None;
|
let mut filename = None;
|
||||||
let mut parent_path = None;
|
let mut parent_path = None;
|
||||||
@ -729,7 +731,7 @@ impl EditorElement {
|
|||||||
.expanded()
|
.expanded()
|
||||||
.named("path header block")
|
.named("path header block")
|
||||||
} else {
|
} else {
|
||||||
let text_style = self.settings.style.text.clone();
|
let text_style = self.style.text.clone();
|
||||||
Label::new("…".to_string(), text_style)
|
Label::new("…".to_string(), text_style)
|
||||||
.contained()
|
.contained()
|
||||||
.with_padding_left(gutter_padding + scroll_x * em_width)
|
.with_padding_left(gutter_padding + scroll_x * em_width)
|
||||||
@ -766,7 +768,7 @@ impl Element for EditorElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let snapshot = self.snapshot(cx.app);
|
let snapshot = self.snapshot(cx.app);
|
||||||
let style = self.settings.style.clone();
|
let style = self.style.clone();
|
||||||
let line_height = style.text.line_height(cx.font_cache);
|
let line_height = style.text.line_height(cx.font_cache);
|
||||||
|
|
||||||
let gutter_padding;
|
let gutter_padding;
|
||||||
@ -786,12 +788,15 @@ impl Element for EditorElement {
|
|||||||
let em_width = style.text.em_width(cx.font_cache);
|
let em_width = style.text.em_width(cx.font_cache);
|
||||||
let em_advance = style.text.em_advance(cx.font_cache);
|
let em_advance = style.text.em_advance(cx.font_cache);
|
||||||
let overscroll = vec2f(em_width, 0.);
|
let overscroll = vec2f(em_width, 0.);
|
||||||
let wrap_width = match self.settings.soft_wrap {
|
|
||||||
SoftWrap::None => None,
|
|
||||||
SoftWrap::EditorWidth => Some(text_width - gutter_margin - overscroll.x() - em_width),
|
|
||||||
SoftWrap::Column(column) => Some(column as f32 * em_advance),
|
|
||||||
};
|
|
||||||
let snapshot = self.update_view(cx.app, |view, cx| {
|
let snapshot = self.update_view(cx.app, |view, cx| {
|
||||||
|
let wrap_width = match view.soft_wrap_mode(cx) {
|
||||||
|
SoftWrap::None => None,
|
||||||
|
SoftWrap::EditorWidth => {
|
||||||
|
Some(text_width - gutter_margin - overscroll.x() - em_width)
|
||||||
|
}
|
||||||
|
SoftWrap::Column(column) => Some(column as f32 * em_advance),
|
||||||
|
};
|
||||||
|
|
||||||
if view.set_wrap_width(wrap_width, cx) {
|
if view.set_wrap_width(wrap_width, cx) {
|
||||||
view.snapshot(cx)
|
view.snapshot(cx)
|
||||||
} else {
|
} else {
|
||||||
@ -907,7 +912,7 @@ impl Element for EditorElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let style = self.settings.style.clone();
|
let style = self.style.clone();
|
||||||
let longest_line_width = layout_line(
|
let longest_line_width = layout_line(
|
||||||
snapshot.longest_row(),
|
snapshot.longest_row(),
|
||||||
&snapshot,
|
&snapshot,
|
||||||
@ -951,12 +956,14 @@ impl Element for EditorElement {
|
|||||||
.to_display_point(&snapshot);
|
.to_display_point(&snapshot);
|
||||||
|
|
||||||
if (start_row..end_row).contains(&newest_selection_head.row()) {
|
if (start_row..end_row).contains(&newest_selection_head.row()) {
|
||||||
|
let style = view.style(cx);
|
||||||
if view.context_menu_visible() {
|
if view.context_menu_visible() {
|
||||||
context_menu = view.render_context_menu(newest_selection_head, cx);
|
context_menu =
|
||||||
|
view.render_context_menu(newest_selection_head, style.clone(), cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
code_actions_indicator = view
|
code_actions_indicator = view
|
||||||
.render_code_actions_indicator(cx)
|
.render_code_actions_indicator(&style, cx)
|
||||||
.map(|indicator| (newest_selection_head.row(), indicator));
|
.map(|indicator| (newest_selection_head.row(), indicator));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -1370,26 +1377,19 @@ fn scale_horizontal_mouse_autoscroll_delta(delta: f32) -> f32 {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::{Editor, EditorSettings, MultiBuffer};
|
use crate::{Editor, MultiBuffer};
|
||||||
use std::sync::Arc;
|
use postage::watch;
|
||||||
use util::test::sample_text;
|
use util::test::sample_text;
|
||||||
|
use workspace::Settings;
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
fn test_layout_line_numbers(cx: &mut gpui::MutableAppContext) {
|
fn test_layout_line_numbers(cx: &mut gpui::MutableAppContext) {
|
||||||
let settings = EditorSettings::test(cx);
|
let settings = watch::channel_with(Settings::test(cx));
|
||||||
let buffer = MultiBuffer::build_simple(&sample_text(6, 6, 'a'), cx);
|
let buffer = MultiBuffer::build_simple(&sample_text(6, 6, 'a'), cx);
|
||||||
let (window_id, editor) = cx.add_window(Default::default(), |cx| {
|
let (window_id, editor) = cx.add_window(Default::default(), |cx| {
|
||||||
Editor::for_buffer(
|
Editor::new(EditorMode::Full, buffer, None, settings.1, None, cx)
|
||||||
buffer,
|
|
||||||
{
|
|
||||||
let settings = settings.clone();
|
|
||||||
Arc::new(move |_| settings.clone())
|
|
||||||
},
|
|
||||||
None,
|
|
||||||
cx,
|
|
||||||
)
|
|
||||||
});
|
});
|
||||||
let element = EditorElement::new(editor.downgrade(), settings);
|
let element = EditorElement::new(editor.downgrade(), editor.read(cx).style(cx));
|
||||||
|
|
||||||
let layouts = editor.update(cx, |editor, cx| {
|
let layouts = editor.update(cx, |editor, cx| {
|
||||||
let snapshot = editor.snapshot(cx);
|
let snapshot = editor.snapshot(cx);
|
||||||
|
@ -56,12 +56,11 @@ impl ItemHandle for BufferItemHandle {
|
|||||||
cx: &mut MutableAppContext,
|
cx: &mut MutableAppContext,
|
||||||
) -> Box<dyn ItemViewHandle> {
|
) -> Box<dyn ItemViewHandle> {
|
||||||
let buffer = cx.add_model(|cx| MultiBuffer::singleton(self.0.clone(), cx));
|
let buffer = cx.add_model(|cx| MultiBuffer::singleton(self.0.clone(), cx));
|
||||||
let weak_buffer = buffer.downgrade();
|
|
||||||
Box::new(cx.add_view(window_id, |cx| {
|
Box::new(cx.add_view(window_id, |cx| {
|
||||||
let mut editor = Editor::for_buffer(
|
let mut editor = Editor::for_buffer(
|
||||||
buffer,
|
buffer,
|
||||||
crate::settings_builder(weak_buffer, workspace.settings()),
|
|
||||||
Some(workspace.project().clone()),
|
Some(workspace.project().clone()),
|
||||||
|
workspace.settings(),
|
||||||
cx,
|
cx,
|
||||||
);
|
);
|
||||||
editor.nav_history = Some(ItemNavHistory::new(nav_history, &cx.handle()));
|
editor.nav_history = Some(ItemNavHistory::new(nav_history, &cx.handle()));
|
||||||
@ -101,12 +100,11 @@ impl ItemHandle for MultiBufferItemHandle {
|
|||||||
nav_history: Rc<RefCell<NavHistory>>,
|
nav_history: Rc<RefCell<NavHistory>>,
|
||||||
cx: &mut MutableAppContext,
|
cx: &mut MutableAppContext,
|
||||||
) -> Box<dyn ItemViewHandle> {
|
) -> Box<dyn ItemViewHandle> {
|
||||||
let weak_buffer = self.0.downgrade();
|
|
||||||
Box::new(cx.add_view(window_id, |cx| {
|
Box::new(cx.add_view(window_id, |cx| {
|
||||||
let mut editor = Editor::for_buffer(
|
let mut editor = Editor::for_buffer(
|
||||||
self.0.clone(),
|
self.0.clone(),
|
||||||
crate::settings_builder(weak_buffer, workspace.settings()),
|
|
||||||
Some(workspace.project().clone()),
|
Some(workspace.project().clone()),
|
||||||
|
workspace.settings(),
|
||||||
cx,
|
cx,
|
||||||
);
|
);
|
||||||
editor.nav_history = Some(ItemNavHistory::new(nav_history, &cx.handle()));
|
editor.nav_history = Some(ItemNavHistory::new(nav_history, &cx.handle()));
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use editor::{Editor, EditorSettings};
|
use editor::Editor;
|
||||||
use fuzzy::PathMatch;
|
use fuzzy::PathMatch;
|
||||||
use gpui::{
|
use gpui::{
|
||||||
action,
|
action,
|
||||||
@ -266,17 +266,8 @@ impl FileFinder {
|
|||||||
|
|
||||||
let query_editor = cx.add_view(|cx| {
|
let query_editor = cx.add_view(|cx| {
|
||||||
Editor::single_line(
|
Editor::single_line(
|
||||||
{
|
settings.clone(),
|
||||||
let settings = settings.clone();
|
Some(|theme| theme.selector.input_editor.clone()),
|
||||||
Arc::new(move |_| {
|
|
||||||
let settings = settings.borrow();
|
|
||||||
EditorSettings {
|
|
||||||
style: settings.theme.selector.input_editor.as_editor(),
|
|
||||||
tab_size: settings.tab_size,
|
|
||||||
soft_wrap: editor::SoftWrap::None,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
cx,
|
cx,
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
@ -2,8 +2,7 @@ use aho_corasick::AhoCorasickBuilder;
|
|||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use collections::HashMap;
|
use collections::HashMap;
|
||||||
use editor::{
|
use editor::{
|
||||||
char_kind, display_map::ToDisplayPoint, Anchor, Autoscroll, Bias, Editor, EditorSettings,
|
char_kind, display_map::ToDisplayPoint, Anchor, Autoscroll, Bias, Editor, MultiBufferSnapshot,
|
||||||
MultiBufferSnapshot,
|
|
||||||
};
|
};
|
||||||
use gpui::{
|
use gpui::{
|
||||||
action, elements::*, keymap::Binding, platform::CursorStyle, Entity, MutableAppContext,
|
action, elements::*, keymap::Binding, platform::CursorStyle, Entity, MutableAppContext,
|
||||||
@ -15,7 +14,6 @@ use smol::future::yield_now;
|
|||||||
use std::{
|
use std::{
|
||||||
cmp::{self, Ordering},
|
cmp::{self, Ordering},
|
||||||
ops::Range,
|
ops::Range,
|
||||||
sync::Arc,
|
|
||||||
};
|
};
|
||||||
use workspace::{ItemViewHandle, Pane, Settings, Toolbar, Workspace};
|
use workspace::{ItemViewHandle, Pane, Settings, Toolbar, Workspace};
|
||||||
|
|
||||||
@ -179,17 +177,8 @@ impl FindBar {
|
|||||||
let query_editor = cx.add_view(|cx| {
|
let query_editor = cx.add_view(|cx| {
|
||||||
Editor::auto_height(
|
Editor::auto_height(
|
||||||
2,
|
2,
|
||||||
{
|
settings.clone(),
|
||||||
let settings = settings.clone();
|
Some(|theme| theme.find.editor.input.clone()),
|
||||||
Arc::new(move |_| {
|
|
||||||
let settings = settings.borrow();
|
|
||||||
EditorSettings {
|
|
||||||
style: settings.theme.find.editor.input.as_editor(),
|
|
||||||
tab_size: settings.tab_size,
|
|
||||||
soft_wrap: editor::SoftWrap::None,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
cx,
|
cx,
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
@ -645,7 +634,7 @@ async fn regex_search(
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use editor::{DisplayPoint, Editor, EditorSettings, MultiBuffer};
|
use editor::{DisplayPoint, Editor, MultiBuffer};
|
||||||
use gpui::{color::Color, TestAppContext};
|
use gpui::{color::Color, TestAppContext};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use unindent::Unindent as _;
|
use unindent::Unindent as _;
|
||||||
@ -656,6 +645,7 @@ mod tests {
|
|||||||
let mut theme = gpui::fonts::with_font_cache(fonts.clone(), || theme::Theme::default());
|
let mut theme = gpui::fonts::with_font_cache(fonts.clone(), || theme::Theme::default());
|
||||||
theme.find.match_background = Color::red();
|
theme.find.match_background = Color::red();
|
||||||
let settings = Settings::new("Courier", &fonts, Arc::new(theme)).unwrap();
|
let settings = Settings::new("Courier", &fonts, Arc::new(theme)).unwrap();
|
||||||
|
let settings = watch::channel_with(settings).1;
|
||||||
|
|
||||||
let buffer = cx.update(|cx| {
|
let buffer = cx.update(|cx| {
|
||||||
MultiBuffer::build_simple(
|
MultiBuffer::build_simple(
|
||||||
@ -670,11 +660,11 @@ mod tests {
|
|||||||
)
|
)
|
||||||
});
|
});
|
||||||
let editor = cx.add_view(Default::default(), |cx| {
|
let editor = cx.add_view(Default::default(), |cx| {
|
||||||
Editor::new(buffer.clone(), Arc::new(EditorSettings::test), None, cx)
|
Editor::for_buffer(buffer.clone(), None, settings.clone(), cx)
|
||||||
});
|
});
|
||||||
|
|
||||||
let find_bar = cx.add_view(Default::default(), |cx| {
|
let find_bar = cx.add_view(Default::default(), |cx| {
|
||||||
let mut find_bar = FindBar::new(watch::channel_with(settings).1, cx);
|
let mut find_bar = FindBar::new(settings, cx);
|
||||||
find_bar.active_item_changed(Some(Box::new(editor.clone())), cx);
|
find_bar.active_item_changed(Some(Box::new(editor.clone())), cx);
|
||||||
find_bar
|
find_bar
|
||||||
});
|
});
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
use editor::{display_map::ToDisplayPoint, Autoscroll, DisplayPoint, Editor, EditorSettings};
|
use editor::{display_map::ToDisplayPoint, Autoscroll, DisplayPoint, Editor};
|
||||||
use gpui::{
|
use gpui::{
|
||||||
action, elements::*, geometry::vector::Vector2F, keymap::Binding, Axis, Entity,
|
action, elements::*, geometry::vector::Vector2F, keymap::Binding, Axis, Entity,
|
||||||
MutableAppContext, RenderContext, View, ViewContext, ViewHandle,
|
MutableAppContext, RenderContext, View, ViewContext, ViewHandle,
|
||||||
};
|
};
|
||||||
use postage::watch;
|
use postage::watch;
|
||||||
use std::sync::Arc;
|
|
||||||
use text::{Bias, Point};
|
use text::{Bias, Point};
|
||||||
use workspace::{Settings, Workspace};
|
use workspace::{Settings, Workspace};
|
||||||
|
|
||||||
@ -42,17 +41,8 @@ impl GoToLine {
|
|||||||
) -> Self {
|
) -> Self {
|
||||||
let line_editor = cx.add_view(|cx| {
|
let line_editor = cx.add_view(|cx| {
|
||||||
Editor::single_line(
|
Editor::single_line(
|
||||||
{
|
settings.clone(),
|
||||||
let settings = settings.clone();
|
Some(|theme| theme.selector.input_editor.clone()),
|
||||||
Arc::new(move |_| {
|
|
||||||
let settings = settings.borrow();
|
|
||||||
EditorSettings {
|
|
||||||
tab_size: settings.tab_size,
|
|
||||||
style: settings.theme.selector.input_editor.as_editor(),
|
|
||||||
soft_wrap: editor::SoftWrap::None,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
cx,
|
cx,
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use editor::{
|
use editor::{
|
||||||
combine_syntax_and_fuzzy_match_highlights, display_map::ToDisplayPoint, Anchor, AnchorRangeExt,
|
combine_syntax_and_fuzzy_match_highlights, display_map::ToDisplayPoint, Anchor, AnchorRangeExt,
|
||||||
Autoscroll, DisplayPoint, Editor, EditorSettings, ToPoint,
|
Autoscroll, DisplayPoint, Editor, ToPoint,
|
||||||
};
|
};
|
||||||
use fuzzy::StringMatch;
|
use fuzzy::StringMatch;
|
||||||
use gpui::{
|
use gpui::{
|
||||||
@ -14,10 +14,7 @@ use gpui::{
|
|||||||
use language::Outline;
|
use language::Outline;
|
||||||
use ordered_float::OrderedFloat;
|
use ordered_float::OrderedFloat;
|
||||||
use postage::watch;
|
use postage::watch;
|
||||||
use std::{
|
use std::cmp::{self, Reverse};
|
||||||
cmp::{self, Reverse},
|
|
||||||
sync::Arc,
|
|
||||||
};
|
|
||||||
use workspace::{
|
use workspace::{
|
||||||
menu::{Confirm, SelectFirst, SelectLast, SelectNext, SelectPrev},
|
menu::{Confirm, SelectFirst, SelectLast, SelectNext, SelectPrev},
|
||||||
Settings, Workspace,
|
Settings, Workspace,
|
||||||
@ -107,17 +104,8 @@ impl OutlineView {
|
|||||||
) -> Self {
|
) -> Self {
|
||||||
let query_editor = cx.add_view(|cx| {
|
let query_editor = cx.add_view(|cx| {
|
||||||
Editor::single_line(
|
Editor::single_line(
|
||||||
{
|
settings.clone(),
|
||||||
let settings = settings.clone();
|
Some(|theme| theme.selector.input_editor.clone()),
|
||||||
Arc::new(move |_| {
|
|
||||||
let settings = settings.borrow();
|
|
||||||
EditorSettings {
|
|
||||||
style: settings.theme.selector.input_editor.as_editor(),
|
|
||||||
tab_size: settings.tab_size,
|
|
||||||
soft_wrap: editor::SoftWrap::None,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
cx,
|
cx,
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use editor::{
|
use editor::{
|
||||||
combine_syntax_and_fuzzy_match_highlights, items::BufferItemHandle, styled_runs_for_code_label,
|
combine_syntax_and_fuzzy_match_highlights, items::BufferItemHandle, styled_runs_for_code_label,
|
||||||
Autoscroll, Bias, Editor, EditorSettings,
|
Autoscroll, Bias, Editor,
|
||||||
};
|
};
|
||||||
use fuzzy::{StringMatch, StringMatchCandidate};
|
use fuzzy::{StringMatch, StringMatchCandidate};
|
||||||
use gpui::{
|
use gpui::{
|
||||||
@ -16,7 +16,6 @@ use project::{Project, Symbol};
|
|||||||
use std::{
|
use std::{
|
||||||
borrow::Cow,
|
borrow::Cow,
|
||||||
cmp::{self, Reverse},
|
cmp::{self, Reverse},
|
||||||
sync::Arc,
|
|
||||||
};
|
};
|
||||||
use util::ResultExt;
|
use util::ResultExt;
|
||||||
use workspace::{
|
use workspace::{
|
||||||
@ -105,17 +104,8 @@ impl ProjectSymbolsView {
|
|||||||
) -> Self {
|
) -> Self {
|
||||||
let query_editor = cx.add_view(|cx| {
|
let query_editor = cx.add_view(|cx| {
|
||||||
Editor::single_line(
|
Editor::single_line(
|
||||||
{
|
settings.clone(),
|
||||||
let settings = settings.clone();
|
Some(|theme| theme.selector.input_editor.clone()),
|
||||||
Arc::new(move |_| {
|
|
||||||
let settings = settings.borrow();
|
|
||||||
EditorSettings {
|
|
||||||
style: settings.theme.selector.input_editor.as_editor(),
|
|
||||||
tab_size: settings.tab_size,
|
|
||||||
soft_wrap: editor::SoftWrap::None,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
cx,
|
cx,
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
@ -1177,8 +1177,8 @@ mod tests {
|
|||||||
EstablishConnectionError, UserStore,
|
EstablishConnectionError, UserStore,
|
||||||
},
|
},
|
||||||
editor::{
|
editor::{
|
||||||
self, ConfirmCodeAction, ConfirmCompletion, ConfirmRename, Editor, EditorSettings,
|
self, ConfirmCodeAction, ConfirmCompletion, ConfirmRename, Editor, Input, MultiBuffer,
|
||||||
Input, MultiBuffer, Redo, Rename, ToOffset, ToggleCodeActions, Undo,
|
Redo, Rename, ToOffset, ToggleCodeActions, Undo,
|
||||||
},
|
},
|
||||||
fs::{FakeFs, Fs as _},
|
fs::{FakeFs, Fs as _},
|
||||||
language::{
|
language::{
|
||||||
@ -1187,7 +1187,7 @@ mod tests {
|
|||||||
},
|
},
|
||||||
lsp,
|
lsp,
|
||||||
project::{DiagnosticSummary, Project, ProjectPath},
|
project::{DiagnosticSummary, Project, ProjectPath},
|
||||||
workspace::{Workspace, WorkspaceParams},
|
workspace::{Settings, Workspace, WorkspaceParams},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
@ -1298,7 +1298,12 @@ mod tests {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let editor_b = cx_b.add_view(window_b, |cx| {
|
let editor_b = cx_b.add_view(window_b, |cx| {
|
||||||
Editor::for_buffer(buffer_b, Arc::new(|cx| EditorSettings::test(cx)), None, cx)
|
Editor::for_buffer(
|
||||||
|
buffer_b,
|
||||||
|
None,
|
||||||
|
watch::channel_with(Settings::test(cx)).1,
|
||||||
|
cx,
|
||||||
|
)
|
||||||
});
|
});
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
@ -2330,8 +2335,8 @@ mod tests {
|
|||||||
let editor_b = cx_b.add_view(window_b, |cx| {
|
let editor_b = cx_b.add_view(window_b, |cx| {
|
||||||
Editor::for_buffer(
|
Editor::for_buffer(
|
||||||
cx.add_model(|cx| MultiBuffer::singleton(buffer_b.clone(), cx)),
|
cx.add_model(|cx| MultiBuffer::singleton(buffer_b.clone(), cx)),
|
||||||
Arc::new(|cx| EditorSettings::test(cx)),
|
|
||||||
Some(project_b.clone()),
|
Some(project_b.clone()),
|
||||||
|
watch::channel_with(Settings::test(cx)).1,
|
||||||
cx,
|
cx,
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
@ -23,7 +23,7 @@ pub struct Theme {
|
|||||||
pub contacts_panel: ContactsPanel,
|
pub contacts_panel: ContactsPanel,
|
||||||
pub project_panel: ProjectPanel,
|
pub project_panel: ProjectPanel,
|
||||||
pub selector: Selector,
|
pub selector: Selector,
|
||||||
pub editor: EditorStyle,
|
pub editor: Editor,
|
||||||
pub find: Find,
|
pub find: Find,
|
||||||
pub project_diagnostics: ProjectDiagnostics,
|
pub project_diagnostics: ProjectDiagnostics,
|
||||||
}
|
}
|
||||||
@ -112,7 +112,7 @@ pub struct Find {
|
|||||||
#[derive(Clone, Deserialize, Default)]
|
#[derive(Clone, Deserialize, Default)]
|
||||||
pub struct FindEditor {
|
pub struct FindEditor {
|
||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
pub input: InputEditorStyle,
|
pub input: FieldEditor,
|
||||||
pub max_width: f32,
|
pub max_width: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -151,7 +151,7 @@ pub struct ChatPanel {
|
|||||||
pub message: ChatMessage,
|
pub message: ChatMessage,
|
||||||
pub pending_message: ChatMessage,
|
pub pending_message: ChatMessage,
|
||||||
pub channel_select: ChannelSelect,
|
pub channel_select: ChannelSelect,
|
||||||
pub input_editor: InputEditorStyle,
|
pub input_editor: FieldEditor,
|
||||||
pub sign_in_prompt: TextStyle,
|
pub sign_in_prompt: TextStyle,
|
||||||
pub hovered_sign_in_prompt: TextStyle,
|
pub hovered_sign_in_prompt: TextStyle,
|
||||||
}
|
}
|
||||||
@ -236,7 +236,7 @@ pub struct Selector {
|
|||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
pub container: ContainerStyle,
|
pub container: ContainerStyle,
|
||||||
pub empty: ContainedLabel,
|
pub empty: ContainedLabel,
|
||||||
pub input_editor: InputEditorStyle,
|
pub input_editor: FieldEditor,
|
||||||
pub item: ContainedLabel,
|
pub item: ContainedLabel,
|
||||||
pub active_item: ContainedLabel,
|
pub active_item: ContainedLabel,
|
||||||
}
|
}
|
||||||
@ -269,10 +269,9 @@ pub struct ProjectDiagnostics {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Deserialize, Default)]
|
#[derive(Clone, Deserialize, Default)]
|
||||||
pub struct EditorStyle {
|
pub struct Editor {
|
||||||
pub text: TextStyle,
|
pub text_color: Color,
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub placeholder_text: Option<TextStyle>,
|
|
||||||
pub background: Color,
|
pub background: Color,
|
||||||
pub selection: SelectionStyle,
|
pub selection: SelectionStyle,
|
||||||
pub gutter_background: Color,
|
pub gutter_background: Color,
|
||||||
@ -345,7 +344,7 @@ pub struct SelectionStyle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Deserialize, Default)]
|
#[derive(Clone, Deserialize, Default)]
|
||||||
pub struct InputEditorStyle {
|
pub struct FieldEditor {
|
||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
pub container: ContainerStyle,
|
pub container: ContainerStyle,
|
||||||
pub text: TextStyle,
|
pub text: TextStyle,
|
||||||
@ -354,11 +353,7 @@ pub struct InputEditorStyle {
|
|||||||
pub selection: SelectionStyle,
|
pub selection: SelectionStyle,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EditorStyle {
|
impl Editor {
|
||||||
pub fn placeholder_text(&self) -> &TextStyle {
|
|
||||||
self.placeholder_text.as_ref().unwrap_or(&self.text)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn replica_selection_style(&self, replica_id: u16) -> &SelectionStyle {
|
pub fn replica_selection_style(&self, replica_id: u16) -> &SelectionStyle {
|
||||||
let style_ix = replica_id as usize % (self.guest_selections.len() + 1);
|
let style_ix = replica_id as usize % (self.guest_selections.len() + 1);
|
||||||
if style_ix == 0 {
|
if style_ix == 0 {
|
||||||
@ -369,72 +364,6 @@ impl EditorStyle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl InputEditorStyle {
|
|
||||||
pub fn as_editor(&self) -> EditorStyle {
|
|
||||||
let default_diagnostic_style = DiagnosticStyle {
|
|
||||||
message: self.text.clone().into(),
|
|
||||||
header: Default::default(),
|
|
||||||
text_scale_factor: 1.,
|
|
||||||
};
|
|
||||||
EditorStyle {
|
|
||||||
text: self.text.clone(),
|
|
||||||
placeholder_text: self.placeholder_text.clone(),
|
|
||||||
background: self
|
|
||||||
.container
|
|
||||||
.background_color
|
|
||||||
.unwrap_or(Color::transparent_black()),
|
|
||||||
selection: self.selection,
|
|
||||||
gutter_background: Default::default(),
|
|
||||||
gutter_padding_factor: Default::default(),
|
|
||||||
active_line_background: Default::default(),
|
|
||||||
highlighted_line_background: Default::default(),
|
|
||||||
document_highlight_read_background: Default::default(),
|
|
||||||
document_highlight_write_background: Default::default(),
|
|
||||||
diff_background_deleted: Default::default(),
|
|
||||||
diff_background_inserted: Default::default(),
|
|
||||||
line_number: Default::default(),
|
|
||||||
line_number_active: Default::default(),
|
|
||||||
guest_selections: Default::default(),
|
|
||||||
syntax: Default::default(),
|
|
||||||
diagnostic_path_header: DiagnosticPathHeader {
|
|
||||||
container: Default::default(),
|
|
||||||
filename: ContainedText {
|
|
||||||
container: Default::default(),
|
|
||||||
text: self.text.clone(),
|
|
||||||
},
|
|
||||||
path: ContainedText {
|
|
||||||
container: Default::default(),
|
|
||||||
text: self.text.clone(),
|
|
||||||
},
|
|
||||||
text_scale_factor: 1.,
|
|
||||||
},
|
|
||||||
diagnostic_header: DiagnosticHeader {
|
|
||||||
container: Default::default(),
|
|
||||||
message: ContainedLabel {
|
|
||||||
container: Default::default(),
|
|
||||||
label: self.text.clone().into(),
|
|
||||||
},
|
|
||||||
code: ContainedText {
|
|
||||||
container: Default::default(),
|
|
||||||
text: self.text.clone(),
|
|
||||||
},
|
|
||||||
icon_width_factor: Default::default(),
|
|
||||||
text_scale_factor: 1.,
|
|
||||||
},
|
|
||||||
error_diagnostic: default_diagnostic_style.clone(),
|
|
||||||
invalid_error_diagnostic: default_diagnostic_style.clone(),
|
|
||||||
warning_diagnostic: default_diagnostic_style.clone(),
|
|
||||||
invalid_warning_diagnostic: default_diagnostic_style.clone(),
|
|
||||||
information_diagnostic: default_diagnostic_style.clone(),
|
|
||||||
invalid_information_diagnostic: default_diagnostic_style.clone(),
|
|
||||||
hint_diagnostic: default_diagnostic_style.clone(),
|
|
||||||
invalid_hint_diagnostic: default_diagnostic_style.clone(),
|
|
||||||
autocomplete: Default::default(),
|
|
||||||
code_actions_indicator: Default::default(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct SyntaxTheme {
|
pub struct SyntaxTheme {
|
||||||
pub highlights: Vec<(String, HighlightStyle)>,
|
pub highlights: Vec<(String, HighlightStyle)>,
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use editor::{Editor, EditorSettings};
|
use editor::Editor;
|
||||||
use fuzzy::{match_strings, StringMatch, StringMatchCandidate};
|
use fuzzy::{match_strings, StringMatch, StringMatchCandidate};
|
||||||
use gpui::{
|
use gpui::{
|
||||||
action,
|
action,
|
||||||
@ -63,17 +63,8 @@ impl ThemeSelector {
|
|||||||
) -> Self {
|
) -> Self {
|
||||||
let query_editor = cx.add_view(|cx| {
|
let query_editor = cx.add_view(|cx| {
|
||||||
Editor::single_line(
|
Editor::single_line(
|
||||||
{
|
settings.clone(),
|
||||||
let settings = settings.clone();
|
Some(|theme| theme.selector.input_editor.clone()),
|
||||||
Arc::new(move |_| {
|
|
||||||
let settings = settings.borrow();
|
|
||||||
EditorSettings {
|
|
||||||
tab_size: settings.tab_size,
|
|
||||||
style: settings.theme.selector.input_editor.as_editor(),
|
|
||||||
soft_wrap: editor::SoftWrap::None,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
cx,
|
cx,
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
@ -72,4 +72,17 @@ impl Settings {
|
|||||||
.and_then(|settings| settings.preferred_line_length)
|
.and_then(|settings| settings.preferred_line_length)
|
||||||
.unwrap_or(self.preferred_line_length)
|
.unwrap_or(self.preferred_line_length)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(any(test, feature = "test-support"))]
|
||||||
|
pub fn test(cx: &gpui::AppContext) -> Settings {
|
||||||
|
Settings {
|
||||||
|
buffer_font_family: cx.font_cache().load_family(&["Monaco"]).unwrap(),
|
||||||
|
buffer_font_size: 14.,
|
||||||
|
tab_size: 4,
|
||||||
|
soft_wrap: SoftWrap::None,
|
||||||
|
preferred_line_length: 80,
|
||||||
|
overrides: Default::default(),
|
||||||
|
theme: gpui::fonts::with_font_cache(cx.font_cache().clone(), || Default::default()),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -243,7 +243,7 @@ background = "$state.hover"
|
|||||||
text = "$text.0"
|
text = "$text.0"
|
||||||
|
|
||||||
[editor]
|
[editor]
|
||||||
text = "$text.1"
|
text_color = "$text.1.color"
|
||||||
background = "$surface.1"
|
background = "$surface.1"
|
||||||
gutter_background = "$surface.1"
|
gutter_background = "$surface.1"
|
||||||
gutter_padding_factor = 2.5
|
gutter_padding_factor = 2.5
|
||||||
@ -282,8 +282,8 @@ header.border = { width = 1, top = true, color = "$border.0" }
|
|||||||
text_scale_factor = 0.857
|
text_scale_factor = 0.857
|
||||||
|
|
||||||
[editor.error_diagnostic.message]
|
[editor.error_diagnostic.message]
|
||||||
text = { extends = "$editor.text", size = 14, color = "$status.bad" }
|
text = { extends = "$text.1", size = 14, color = "$status.bad" }
|
||||||
highlight_text = { extends = "$editor.text", size = 14, color = "$status.bad", weight = "bold" }
|
highlight_text = { extends = "$text.1", size = 14, color = "$status.bad", weight = "bold" }
|
||||||
|
|
||||||
[editor.warning_diagnostic]
|
[editor.warning_diagnostic]
|
||||||
extends = "$editor.error_diagnostic"
|
extends = "$editor.error_diagnostic"
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
use crate::{assets::Assets, build_window_options, build_workspace, AppState};
|
use crate::{assets::Assets, build_window_options, build_workspace, AppState};
|
||||||
use client::{test::FakeHttpClient, ChannelList, Client, UserStore};
|
use client::{test::FakeHttpClient, ChannelList, Client, UserStore};
|
||||||
use gpui::{AssetSource, MutableAppContext};
|
use gpui::MutableAppContext;
|
||||||
use language::LanguageRegistry;
|
use language::LanguageRegistry;
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
use postage::watch;
|
use postage::watch;
|
||||||
use project::fs::FakeFs;
|
use project::fs::FakeFs;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use theme::{Theme, ThemeRegistry, DEFAULT_THEME_NAME};
|
use theme::ThemeRegistry;
|
||||||
use workspace::Settings;
|
use workspace::Settings;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
@ -20,7 +20,7 @@ fn init_logger() {
|
|||||||
pub fn test_app_state(cx: &mut MutableAppContext) -> Arc<AppState> {
|
pub fn test_app_state(cx: &mut MutableAppContext) -> Arc<AppState> {
|
||||||
let mut path_openers = Vec::new();
|
let mut path_openers = Vec::new();
|
||||||
editor::init(cx, &mut path_openers);
|
editor::init(cx, &mut path_openers);
|
||||||
let (settings_tx, settings) = watch::channel_with(build_settings(cx));
|
let (settings_tx, settings) = watch::channel_with(Settings::test(cx));
|
||||||
let themes = ThemeRegistry::new(Assets, cx.font_cache().clone());
|
let themes = ThemeRegistry::new(Assets, cx.font_cache().clone());
|
||||||
let http = FakeHttpClient::with_404_response();
|
let http = FakeHttpClient::with_404_response();
|
||||||
let client = Client::new(http.clone());
|
let client = Client::new(http.clone());
|
||||||
@ -48,27 +48,3 @@ pub fn test_app_state(cx: &mut MutableAppContext) -> Arc<AppState> {
|
|||||||
build_workspace: &build_workspace,
|
build_workspace: &build_workspace,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_settings(cx: &gpui::AppContext) -> Settings {
|
|
||||||
lazy_static::lazy_static! {
|
|
||||||
static ref DEFAULT_THEME: parking_lot::Mutex<Option<Arc<Theme>>> = Default::default();
|
|
||||||
static ref FONTS: Vec<Arc<Vec<u8>>> = vec![
|
|
||||||
Assets.load("fonts/zed-sans/zed-sans-regular.ttf").unwrap().to_vec().into()
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
cx.platform().fonts().add_fonts(&FONTS).unwrap();
|
|
||||||
|
|
||||||
let mut theme_guard = DEFAULT_THEME.lock();
|
|
||||||
let theme = if let Some(theme) = theme_guard.as_ref() {
|
|
||||||
theme.clone()
|
|
||||||
} else {
|
|
||||||
let theme = ThemeRegistry::new(Assets, cx.font_cache().clone())
|
|
||||||
.get(DEFAULT_THEME_NAME)
|
|
||||||
.expect("failed to load default theme in tests");
|
|
||||||
*theme_guard = Some(theme.clone());
|
|
||||||
theme
|
|
||||||
};
|
|
||||||
|
|
||||||
Settings::new("Zed Sans", cx.font_cache(), theme).unwrap()
|
|
||||||
}
|
|
||||||
|
@ -133,9 +133,11 @@ fn quit(_: &Quit, cx: &mut gpui::MutableAppContext) {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
use crate::assets::Assets;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use editor::{DisplayPoint, Editor};
|
use editor::{DisplayPoint, Editor};
|
||||||
use gpui::{MutableAppContext, TestAppContext, ViewHandle};
|
use gpui::{AssetSource, MutableAppContext, TestAppContext, ViewHandle};
|
||||||
use project::{Fs, ProjectPath};
|
use project::{Fs, ProjectPath};
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
use std::{
|
use std::{
|
||||||
@ -143,7 +145,7 @@ mod tests {
|
|||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
};
|
};
|
||||||
use test::test_app_state;
|
use test::test_app_state;
|
||||||
use theme::DEFAULT_THEME_NAME;
|
use theme::{Theme, ThemeRegistry, DEFAULT_THEME_NAME};
|
||||||
use util::test::temp_tree;
|
use util::test::temp_tree;
|
||||||
use workspace::{
|
use workspace::{
|
||||||
open_paths, pane, ItemView, ItemViewHandle, OpenNew, Pane, SplitDirection, WorkspaceHandle,
|
open_paths, pane, ItemView, ItemViewHandle, OpenNew, Pane, SplitDirection, WorkspaceHandle,
|
||||||
@ -862,10 +864,20 @@ mod tests {
|
|||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
fn test_bundled_themes(cx: &mut MutableAppContext) {
|
fn test_bundled_themes(cx: &mut MutableAppContext) {
|
||||||
let app_state = test_app_state(cx);
|
let themes = ThemeRegistry::new(Assets, cx.font_cache().clone());
|
||||||
|
|
||||||
|
lazy_static::lazy_static! {
|
||||||
|
static ref DEFAULT_THEME: parking_lot::Mutex<Option<Arc<Theme>>> = Default::default();
|
||||||
|
static ref FONTS: Vec<Arc<Vec<u8>>> = vec![
|
||||||
|
Assets.load("fonts/zed-sans/zed-sans-regular.ttf").unwrap().to_vec().into()
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
cx.platform().fonts().add_fonts(&FONTS).unwrap();
|
||||||
|
|
||||||
let mut has_default_theme = false;
|
let mut has_default_theme = false;
|
||||||
for theme_name in app_state.themes.list() {
|
for theme_name in themes.list() {
|
||||||
let theme = app_state.themes.get(&theme_name).unwrap();
|
let theme = themes.get(&theme_name).unwrap();
|
||||||
if theme.name == DEFAULT_THEME_NAME {
|
if theme.name == DEFAULT_THEME_NAME {
|
||||||
has_default_theme = true;
|
has_default_theme = true;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user