Flip the dependency between editor and theme
Co-Authored-By: Nathan Sobo <nathan@zed.dev> Co-Authored-By: Max Brunsfeld <max@zed.dev>
This commit is contained in:
parent
f09798c4a7
commit
f70e3878b6
12 changed files with 94 additions and 94 deletions
3
Cargo.lock
generated
3
Cargo.lock
generated
|
@ -760,6 +760,7 @@ dependencies = [
|
||||||
"similar",
|
"similar",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
"sum_tree",
|
"sum_tree",
|
||||||
|
"theme",
|
||||||
"tree-sitter",
|
"tree-sitter",
|
||||||
"tree-sitter-rust",
|
"tree-sitter-rust",
|
||||||
"unindent",
|
"unindent",
|
||||||
|
@ -1631,6 +1632,7 @@ dependencies = [
|
||||||
"smallvec",
|
"smallvec",
|
||||||
"smol",
|
"smol",
|
||||||
"sum_tree",
|
"sum_tree",
|
||||||
|
"theme",
|
||||||
"tree-sitter",
|
"tree-sitter",
|
||||||
"tree-sitter-rust",
|
"tree-sitter-rust",
|
||||||
"unindent",
|
"unindent",
|
||||||
|
@ -5316,7 +5318,6 @@ name = "theme"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"editor",
|
|
||||||
"gpui",
|
"gpui",
|
||||||
"indexmap",
|
"indexmap",
|
||||||
"parking_lot",
|
"parking_lot",
|
||||||
|
|
|
@ -11,7 +11,7 @@ clock = { path = "../clock" }
|
||||||
gpui = { path = "../gpui" }
|
gpui = { path = "../gpui" }
|
||||||
rpc = { path = "../rpc" }
|
rpc = { path = "../rpc" }
|
||||||
sum_tree = { path = "../sum_tree" }
|
sum_tree = { path = "../sum_tree" }
|
||||||
|
theme = { path = "../theme" }
|
||||||
anyhow = "1.0.38"
|
anyhow = "1.0.38"
|
||||||
arrayvec = "0.7.1"
|
arrayvec = "0.7.1"
|
||||||
lazy_static = "1.4"
|
lazy_static = "1.4"
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use crate::syntax_theme::SyntaxTheme;
|
use gpui::fonts::HighlightStyle;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
use theme::SyntaxTheme;
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct HighlightMap(Arc<[HighlightId]>);
|
pub struct HighlightMap(Arc<[HighlightId]>);
|
||||||
|
@ -49,6 +50,20 @@ impl HighlightMap {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl HighlightId {
|
||||||
|
pub fn style(&self, theme: &SyntaxTheme) -> Option<HighlightStyle> {
|
||||||
|
theme
|
||||||
|
.highlights
|
||||||
|
.get(self.0 as usize)
|
||||||
|
.map(|entry| entry.1.clone())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(any(test, feature = "test-support"))]
|
||||||
|
pub fn name<'a>(&self, theme: &'a SyntaxTheme) -> Option<&'a str> {
|
||||||
|
theme.highlights.get(self.0 as usize).map(|e| e.0.as_str())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Default for HighlightMap {
|
impl Default for HighlightMap {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self(Arc::new([]))
|
Self(Arc::new([]))
|
||||||
|
@ -89,8 +104,8 @@ mod tests {
|
||||||
];
|
];
|
||||||
|
|
||||||
let map = HighlightMap::new(capture_names, &theme);
|
let map = HighlightMap::new(capture_names, &theme);
|
||||||
assert_eq!(theme.highlight_name(map.get(0)), Some("function"));
|
assert_eq!(map.get(0).name(&theme), Some("function"));
|
||||||
assert_eq!(theme.highlight_name(map.get(1)), Some("function.async"));
|
assert_eq!(map.get(1).name(&theme), Some("function.async"));
|
||||||
assert_eq!(theme.highlight_name(map.get(2)), Some("variable.builtin"));
|
assert_eq!(map.get(2).name(&theme), Some("variable.builtin"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
use crate::{HighlightMap, SyntaxTheme};
|
use crate::{HighlightMap};
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use std::{path::Path, str, sync::Arc};
|
use std::{path::Path, str, sync::Arc};
|
||||||
use tree_sitter::{Language as Grammar, Query};
|
use tree_sitter::{Language as Grammar, Query};
|
||||||
pub use tree_sitter::{Parser, Tree};
|
pub use tree_sitter::{Parser, Tree};
|
||||||
|
use theme::SyntaxTheme;
|
||||||
|
|
||||||
#[derive(Default, Deserialize)]
|
#[derive(Default, Deserialize)]
|
||||||
pub struct LanguageConfig {
|
pub struct LanguageConfig {
|
||||||
|
|
|
@ -7,7 +7,6 @@ mod point;
|
||||||
pub mod random_char_iter;
|
pub mod random_char_iter;
|
||||||
pub mod rope;
|
pub mod rope;
|
||||||
mod selection;
|
mod selection;
|
||||||
mod syntax_theme;
|
|
||||||
|
|
||||||
pub use anchor::*;
|
pub use anchor::*;
|
||||||
use anyhow::{anyhow, Result};
|
use anyhow::{anyhow, Result};
|
||||||
|
@ -42,7 +41,6 @@ use std::{
|
||||||
time::{Duration, Instant, SystemTime, UNIX_EPOCH},
|
time::{Duration, Instant, SystemTime, UNIX_EPOCH},
|
||||||
};
|
};
|
||||||
use sum_tree::{Bias, FilterCursor, SumTree};
|
use sum_tree::{Bias, FilterCursor, SumTree};
|
||||||
pub use syntax_theme::SyntaxTheme;
|
|
||||||
use tree_sitter::{InputEdit, Parser, QueryCursor};
|
use tree_sitter::{InputEdit, Parser, QueryCursor};
|
||||||
|
|
||||||
pub trait File {
|
pub trait File {
|
||||||
|
|
|
@ -1,50 +0,0 @@
|
||||||
use std::collections::HashMap;
|
|
||||||
|
|
||||||
use crate::HighlightId;
|
|
||||||
use gpui::fonts::HighlightStyle;
|
|
||||||
use serde::Deserialize;
|
|
||||||
|
|
||||||
#[derive(Default)]
|
|
||||||
pub struct SyntaxTheme {
|
|
||||||
pub(crate) highlights: Vec<(String, HighlightStyle)>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SyntaxTheme {
|
|
||||||
pub fn new(highlights: Vec<(String, HighlightStyle)>) -> Self {
|
|
||||||
Self { highlights }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn highlight_style(&self, id: HighlightId) -> Option<HighlightStyle> {
|
|
||||||
self.highlights
|
|
||||||
.get(id.0 as usize)
|
|
||||||
.map(|entry| entry.1.clone())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(any(test, feature = "test-support"))]
|
|
||||||
pub fn highlight_name(&self, id: HighlightId) -> Option<&str> {
|
|
||||||
self.highlights.get(id.0 as usize).map(|e| e.0.as_str())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'de> Deserialize<'de> for SyntaxTheme {
|
|
||||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
|
||||||
where
|
|
||||||
D: serde::Deserializer<'de>,
|
|
||||||
{
|
|
||||||
let syntax_data: HashMap<String, HighlightStyle> = Deserialize::deserialize(deserializer)?;
|
|
||||||
|
|
||||||
let mut result = Self::new(Vec::new());
|
|
||||||
for (key, style) in syntax_data {
|
|
||||||
match result
|
|
||||||
.highlights
|
|
||||||
.binary_search_by(|(needle, _)| needle.cmp(&key))
|
|
||||||
{
|
|
||||||
Ok(i) | Err(i) => {
|
|
||||||
result.highlights.insert(i, (key, style));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(result)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -11,6 +11,7 @@ buffer = { path = "../buffer" }
|
||||||
clock = { path = "../clock" }
|
clock = { path = "../clock" }
|
||||||
gpui = { path = "../gpui" }
|
gpui = { path = "../gpui" }
|
||||||
sum_tree = { path = "../sum_tree" }
|
sum_tree = { path = "../sum_tree" }
|
||||||
|
theme = { path = "../theme" }
|
||||||
util = { path = "../util" }
|
util = { path = "../util" }
|
||||||
anyhow = "1.0"
|
anyhow = "1.0"
|
||||||
lazy_static = "1.4"
|
lazy_static = "1.4"
|
||||||
|
|
|
@ -358,10 +358,11 @@ impl ToDisplayPoint for Anchor {
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::{movement, test::*};
|
use crate::{movement, test::*};
|
||||||
use buffer::{History, Language, LanguageConfig, RandomCharIter, SelectionGoal, SyntaxTheme};
|
use buffer::{History, Language, LanguageConfig, RandomCharIter, SelectionGoal};
|
||||||
use gpui::{color::Color, MutableAppContext};
|
use gpui::{color::Color, MutableAppContext};
|
||||||
use rand::{prelude::StdRng, Rng};
|
use rand::{prelude::StdRng, Rng};
|
||||||
use std::{env, sync::Arc};
|
use std::{env, sync::Arc};
|
||||||
|
use theme::SyntaxTheme;
|
||||||
use Bias::*;
|
use Bias::*;
|
||||||
|
|
||||||
#[gpui::test(iterations = 100)]
|
#[gpui::test(iterations = 100)]
|
||||||
|
@ -976,7 +977,7 @@ mod tests {
|
||||||
let mut snapshot = map.update(cx, |map, cx| map.snapshot(cx));
|
let mut snapshot = map.update(cx, |map, cx| map.snapshot(cx));
|
||||||
let mut chunks: Vec<(String, Option<&str>)> = Vec::new();
|
let mut chunks: Vec<(String, Option<&str>)> = Vec::new();
|
||||||
for (chunk, style_id) in snapshot.highlighted_chunks_for_rows(rows) {
|
for (chunk, style_id) in snapshot.highlighted_chunks_for_rows(rows) {
|
||||||
let style_name = theme.highlight_name(style_id);
|
let style_name = style_id.name(theme);
|
||||||
if let Some((last_chunk, last_style_name)) = chunks.last_mut() {
|
if let Some((last_chunk, last_style_name)) = chunks.last_mut() {
|
||||||
if style_name == *last_style_name {
|
if style_name == *last_style_name {
|
||||||
last_chunk.push_str(chunk);
|
last_chunk.push_str(chunk);
|
||||||
|
|
|
@ -513,9 +513,8 @@ impl EditorElement {
|
||||||
}
|
}
|
||||||
|
|
||||||
if !line_chunk.is_empty() && !line_exceeded_max_len {
|
if !line_chunk.is_empty() && !line_exceeded_max_len {
|
||||||
let highlight_style = style
|
let highlight_style = style_ix
|
||||||
.syntax
|
.style(&style.syntax)
|
||||||
.highlight_style(style_ix)
|
|
||||||
.unwrap_or(style.text.clone().into());
|
.unwrap_or(style.text.clone().into());
|
||||||
// Avoid a lookup if the font properties match the previous ones.
|
// Avoid a lookup if the font properties match the previous ones.
|
||||||
let font_id = if highlight_style.font_properties == prev_font_properties {
|
let font_id = if highlight_style.font_properties == prev_font_properties {
|
||||||
|
|
|
@ -28,6 +28,7 @@ use std::{
|
||||||
time::Duration,
|
time::Duration,
|
||||||
};
|
};
|
||||||
use sum_tree::Bias;
|
use sum_tree::Bias;
|
||||||
|
use theme::EditorStyle;
|
||||||
use util::post_inc;
|
use util::post_inc;
|
||||||
|
|
||||||
const CURSOR_BLINK_INTERVAL: Duration = Duration::from_millis(500);
|
const CURSOR_BLINK_INTERVAL: Duration = Duration::from_millis(500);
|
||||||
|
@ -283,27 +284,6 @@ pub struct EditorSettings {
|
||||||
pub style: EditorStyle,
|
pub style: EditorStyle,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Deserialize, Default)]
|
|
||||||
pub struct EditorStyle {
|
|
||||||
pub text: TextStyle,
|
|
||||||
#[serde(default)]
|
|
||||||
pub placeholder_text: Option<TextStyle>,
|
|
||||||
pub background: Color,
|
|
||||||
pub selection: SelectionStyle,
|
|
||||||
pub gutter_background: Color,
|
|
||||||
pub active_line_background: Color,
|
|
||||||
pub line_number: Color,
|
|
||||||
pub line_number_active: Color,
|
|
||||||
pub guest_selections: Vec<SelectionStyle>,
|
|
||||||
pub syntax: Arc<SyntaxTheme>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Copy, Default, Deserialize)]
|
|
||||||
pub struct SelectionStyle {
|
|
||||||
pub cursor: Color,
|
|
||||||
pub selection: Color,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Editor {
|
pub struct Editor {
|
||||||
handle: WeakViewHandle<Self>,
|
handle: WeakViewHandle<Self>,
|
||||||
buffer: ModelHandle<Buffer>,
|
buffer: ModelHandle<Buffer>,
|
||||||
|
@ -2448,12 +2428,6 @@ impl Snapshot {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EditorStyle {
|
|
||||||
fn placeholder_text(&self) -> &TextStyle {
|
|
||||||
self.placeholder_text.as_ref().unwrap_or(&self.text)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl EditorSettings {
|
impl EditorSettings {
|
||||||
#[cfg(any(test, feature = "test-support"))]
|
#[cfg(any(test, feature = "test-support"))]
|
||||||
pub fn test(cx: &AppContext) -> Self {
|
pub fn test(cx: &AppContext) -> Self {
|
||||||
|
|
|
@ -4,7 +4,6 @@ version = "0.1.0"
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
editor = { path = "../editor" }
|
|
||||||
gpui = { path = "../gpui" }
|
gpui = { path = "../gpui" }
|
||||||
anyhow = "1.0.38"
|
anyhow = "1.0.38"
|
||||||
indexmap = "1.6.2"
|
indexmap = "1.6.2"
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
mod resolution;
|
mod resolution;
|
||||||
mod theme_registry;
|
mod theme_registry;
|
||||||
|
|
||||||
use editor::{EditorStyle, SelectionStyle};
|
|
||||||
use gpui::{
|
use gpui::{
|
||||||
color::Color,
|
color::Color,
|
||||||
elements::{ContainerStyle, ImageStyle, LabelStyle},
|
elements::{ContainerStyle, ImageStyle, LabelStyle},
|
||||||
fonts::TextStyle,
|
fonts::{HighlightStyle, TextStyle},
|
||||||
Border,
|
Border,
|
||||||
};
|
};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
use std::{collections::HashMap, sync::Arc};
|
||||||
|
|
||||||
pub use theme_registry::*;
|
pub use theme_registry::*;
|
||||||
|
|
||||||
|
@ -201,6 +201,27 @@ pub struct ContainedLabel {
|
||||||
pub label: LabelStyle,
|
pub label: LabelStyle,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Deserialize, Default)]
|
||||||
|
pub struct EditorStyle {
|
||||||
|
pub text: TextStyle,
|
||||||
|
#[serde(default)]
|
||||||
|
pub placeholder_text: Option<TextStyle>,
|
||||||
|
pub background: Color,
|
||||||
|
pub selection: SelectionStyle,
|
||||||
|
pub gutter_background: Color,
|
||||||
|
pub active_line_background: Color,
|
||||||
|
pub line_number: Color,
|
||||||
|
pub line_number_active: Color,
|
||||||
|
pub guest_selections: Vec<SelectionStyle>,
|
||||||
|
pub syntax: Arc<SyntaxTheme>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Default, Deserialize)]
|
||||||
|
pub struct SelectionStyle {
|
||||||
|
pub cursor: Color,
|
||||||
|
pub selection: Color,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Deserialize, Default)]
|
#[derive(Clone, Deserialize, Default)]
|
||||||
pub struct InputEditorStyle {
|
pub struct InputEditorStyle {
|
||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
|
@ -211,6 +232,12 @@ pub struct InputEditorStyle {
|
||||||
pub selection: SelectionStyle,
|
pub selection: SelectionStyle,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl EditorStyle {
|
||||||
|
pub fn placeholder_text(&self) -> &TextStyle {
|
||||||
|
self.placeholder_text.as_ref().unwrap_or(&self.text)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl InputEditorStyle {
|
impl InputEditorStyle {
|
||||||
pub fn as_editor(&self) -> EditorStyle {
|
pub fn as_editor(&self) -> EditorStyle {
|
||||||
EditorStyle {
|
EditorStyle {
|
||||||
|
@ -230,3 +257,37 @@ impl InputEditorStyle {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct SyntaxTheme {
|
||||||
|
pub highlights: Vec<(String, HighlightStyle)>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SyntaxTheme {
|
||||||
|
pub fn new(highlights: Vec<(String, HighlightStyle)>) -> Self {
|
||||||
|
Self { highlights }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'de> Deserialize<'de> for SyntaxTheme {
|
||||||
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
|
where
|
||||||
|
D: serde::Deserializer<'de>,
|
||||||
|
{
|
||||||
|
let syntax_data: HashMap<String, HighlightStyle> = Deserialize::deserialize(deserializer)?;
|
||||||
|
|
||||||
|
let mut result = Self::new(Vec::new());
|
||||||
|
for (key, style) in syntax_data {
|
||||||
|
match result
|
||||||
|
.highlights
|
||||||
|
.binary_search_by(|(needle, _)| needle.cmp(&key))
|
||||||
|
{
|
||||||
|
Ok(i) | Err(i) => {
|
||||||
|
result.highlights.insert(i, (key, style));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue